This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 93509
Collapse All | Expand All

(-)apichanges.xml (+20 lines)
Lines 81-86 Link Here
81
    <!-- ACTUAL CHANGES BEGIN HERE: -->
81
    <!-- ACTUAL CHANGES BEGIN HERE: -->
82
82
83
    <changes>
83
    <changes>
84
85
        <change id="build-extender">
86
            <api name="general"/>
87
            <summary>Support for externally extending the project's build script</summary>
88
            <version major="1" minor="16"/>
89
            <date day="10" month="4" year="2007"/>
90
            <author login="mkleint"/>
91
            <compatibility addition="yes"/>
92
            <description>
93
                <p>
94
                  Add framework for extending the project's build script with 3rd party snippets,
95
                  allowing automated extensions to the build process. 
96
                </p>
97
            </description>
98
            <class package="org.netbeans.api.project.ant" name="AntBuildExtender"/>
99
            <class package="org.netbeans.spi.project.support.ant" name="GeneratedFileHelper"/>
100
            <class package="org.netbeans.spi.project.ant" name="AntBuildExtenderImplementation"/>
101
            <class package="org.netbeans.spi.project.support.ant" name="AntBuildExtenderSupport"/>
102
            <issue number="93509"/>
103
        </change>
84
        
104
        
85
        <change id="includes-excludes.ant">
105
        <change id="includes-excludes.ant">
86
            <api name="general"/>
106
            <api name="general"/>
(-)manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.project.ant/1
2
OpenIDE-Module: org.netbeans.modules.project.ant/1
3
OpenIDE-Module-Specification-Version: 1.15
3
OpenIDE-Module-Specification-Version: 1.16
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/ant/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/ant/Bundle.properties
5
OpenIDE-Module-Install: org/netbeans/modules/project/ant/AntProjectModule.class
5
OpenIDE-Module-Install: org/netbeans/modules/project/ant/AntProjectModule.class
6
6
(-)nbproject/project.xml (+1 lines)
Lines 170-174 Link Here
170
                <built-to>build/tasks.jar</built-to>
170
                <built-to>build/tasks.jar</built-to>
171
            </extra-compilation-unit>
171
            </extra-compilation-unit>
172
        </data>
172
        </data>
173
        <junit-version xmlns="http://www.netbeans.org/ns/junit/1" value="junit3"/>
173
    </configuration>
174
    </configuration>
174
</project>
175
</project>
(-)src/org/netbeans/api/project/ant/AntBuildExtender.java (+307 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.api.project.ant;
21
22
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
23
import java.util.ArrayList;
24
import java.util.Collection;
25
import java.util.Collections;
26
import java.util.HashMap;
27
import java.util.HashSet;
28
import java.util.List;
29
import java.util.Map;
30
import java.util.Set;
31
import java.util.TreeMap;
32
import javax.xml.parsers.DocumentBuilder;
33
import javax.xml.parsers.DocumentBuilderFactory;
34
import javax.xml.parsers.ParserConfigurationException;
35
import org.netbeans.api.project.FileOwnerQuery;
36
import org.netbeans.spi.project.AuxiliaryConfiguration;
37
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
38
import org.netbeans.spi.project.support.ant.AntProjectHelper;
39
import org.openide.filesystems.FileObject;
40
import org.openide.filesystems.FileUtil;
41
import org.w3c.dom.Document;
42
import org.w3c.dom.Element;
43
import org.w3c.dom.NodeList;
44
45
/**
46
 * Allows extending the project's build script with 3rd party additions.
47
 * Check the Project's lookup to see if the feature is supported by a given Ant project type.
48
 * Typical usage:
49
 * <ul>
50
 *    <li>Lookup the instance of AntBuildExtender in the project at hand</li>
51
 *    <li>Create the external build script file with your targets and configuration</li>
52
 *    <li>Use the AntBuildExtender to wire your script and targets into the main build lifecycle</li>
53
 *    <li>Call {@link org.netbeans.api.project.ProjectManager#saveProject} to persist the changes and
54
 *        regenerate the main build script</li>
55
 * </ul>
56
 * 
57
 * Please note that it's easy to break the build script functionality and any script extensions
58
 * shall be done with care. A few rules to follow:
59
 * <ul>
60
 *   <li>Pick a reasonably unique extension id</li>
61
 *   <li>Prefix target names and properties you define in your extension with the extension id to prevent clashes.</li>
62
 * </ul>
63
 * @author mkleint
64
 * @since org.netbeans.modules.project.ant 1.16
65
 */
66
public final class AntBuildExtender {
67
    private HashMap<String, Extension> extensions;
68
    private AntBuildExtenderImplementation implementation;
69
    
70
    static {
71
        AntBuildExtenderAccessorImpl.createAccesor();
72
    }
73
74
    AntBuildExtender(AntBuildExtenderImplementation implementation) {
75
        this.implementation = implementation;
76
    }
77
    
78
    /**
79
     * Get a list of target names in the main build script that are allowed to be 
80
     * extended by adding the "depends" attribute definition to them.
81
     * @return list of target names
82
     */
83
    public List<String> getExtensibleTargets() {
84
        List<String> targets = new ArrayList<String>();
85
        targets.addAll(implementation.getExtensibleTargets());
86
        targets = Collections.unmodifiableList(targets);
87
        return targets;
88
    }
89
    
90
    /**
91
     * Adds a new build script extension.
92
     * @param id identification of the extension
93
     * @param extensionXml fileobject referencing the build script for the extension, 
94
     * needs to be located in nbproject directory or below.
95
     * @return the newly created extension.
96
     */
97
    public synchronized Extension addExtension(String id, FileObject extensionXml) {
98
        assert extensionXml != null;
99
        assert extensionXml.isValid() && extensionXml.isData();
100
        //TODO assert the owner is the same as the owner of this instance of entender.
101
        assert FileOwnerQuery.getOwner(extensionXml) == implementation.getOwningProject();
102
        FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
103
        assert FileUtil.isParentOf(nbproj, extensionXml);
104
        if (extensions == null) {
105
            readProjectMetadata();
106
        }
107
        if (extensions.get(id) != null) {
108
            throw new IllegalStateException("Extension with id '" + id + "' already exists.");
109
        }
110
        Extension ex = new Extension(id, extensionXml, FileUtil.getRelativePath(nbproj, extensionXml));
111
        extensions.put(id, ex);
112
        updateProjectMetadata();
113
        return ex;
114
    }
115
    /**
116
     * Remove an existing build script extension. Make sure to remove the extension's script file
117
     * before/after removing the extension.
118
     * @param id identification of the extension
119
     */
120
    public synchronized void removeExtension(String id) {
121
        if (extensions == null) {
122
            readProjectMetadata();
123
        }
124
        if (extensions.get(id) == null) {
125
            // oh well, just ignore.
126
            return;
127
        }
128
        extensions.remove(id);
129
        updateProjectMetadata();
130
    }
131
    
132
    /**
133
     * Get an extension by the id.
134
     * @param id identification token
135
     * @return Extention with the given id or null if not found.
136
     */
137
    public synchronized Extension getExtension(String id) {
138
        if (extensions == null) {
139
            readProjectMetadata();
140
        }
141
        return extensions.get(id);
142
    }
143
144
145
    synchronized Set<Extension> getExtensions() {
146
        Set<Extension> ext =  new HashSet<Extension>();
147
        if (extensions == null) {
148
            readProjectMetadata();
149
        }
150
        ext.addAll(extensions.values());
151
        return ext;
152
    }
153
    
154
    private static final DocumentBuilder db;
155
    static {
156
        try {
157
            db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
158
        } catch (ParserConfigurationException e) {
159
            throw new AssertionError(e);
160
        }
161
    }
162
    private static Document createNewDocument() {
163
        // #50198: for thread safety, use a separate document.
164
        // Using XMLUtil.createDocument is much too slow.
165
        synchronized (db) {
166
            return db.newDocument();
167
        }
168
    }
169
    
170
    
171
    private void updateProjectMetadata() {
172
        Document doc = createNewDocument();
173
        Element root = doc.createElementNS(AntBuildExtenderImplementation.AUX_NAMESPACE, 
174
                                           AntBuildExtenderImplementation.ELEMENT_ROOT);
175
        if (extensions  != null) {
176
            FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
177
            for (Extension ext : extensions.values()) {
178
                Element child = doc.createElement(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
179
                child.setAttribute(AntBuildExtenderImplementation.ATTR_ID, ext.id);
180
                String relPath = FileUtil.getRelativePath(nbproj, ext.file);
181
                assert relPath != null;
182
                child.setAttribute(AntBuildExtenderImplementation.ATTR_FILE, relPath);
183
                root.appendChild(child);
184
                for (String target : ext.dependencies.keySet()) {
185
                    for (String depTarget : ext.dependencies.get(target)) {
186
                        Element dep = doc.createElement(AntBuildExtenderImplementation.ELEMENT_DEPENDENCY);
187
                        dep.setAttribute(AntBuildExtenderImplementation.ATTR_TARGET, target);
188
                        dep.setAttribute(AntBuildExtenderImplementation.ATTR_DEPENDSON, depTarget);
189
                        child.appendChild(dep);
190
                    }
191
                }
192
            }
193
        }
194
        AuxiliaryConfiguration config = implementation.getOwningProject().getLookup().lookup(AuxiliaryConfiguration.class);
195
        config.putConfigurationFragment(root, true);
196
    }
197
    
198
    private void readProjectMetadata() {
199
        AuxiliaryConfiguration config = implementation.getOwningProject().getLookup().lookup(AuxiliaryConfiguration.class);
200
        Element cfgEl = config.getConfigurationFragment(AntBuildExtenderImplementation.ELEMENT_ROOT, AntBuildExtenderImplementation.AUX_NAMESPACE, true);
201
        FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
202
        extensions = new HashMap<String, Extension>();
203
        if (cfgEl != null) {
204
            String namespace = cfgEl.getNamespaceURI();
205
            NodeList roots = cfgEl.getElementsByTagNameNS(namespace, AntBuildExtenderImplementation.ELEMENT_EXTENSION);
206
            for (int i=0; i <roots.getLength(); i++) {
207
                Element root = (Element) roots.item(i);
208
                String id = root.getAttribute(AntBuildExtenderImplementation.ATTR_ID);
209
                assert id.length() > 0 : "Illegal project.xml";
210
                String value = root.getAttribute(AntBuildExtenderImplementation.ATTR_FILE);
211
                FileObject script = nbproj.getFileObject(value);
212
                assert script != null : "Missing file " + script;
213
                Extension ext = new Extension(id, script, value);
214
                extensions.put(id, ext);
215
                NodeList deps = root.getElementsByTagNameNS(namespace, AntBuildExtenderImplementation.ELEMENT_DEPENDENCY);
216
                for (int j = 0; j < deps.getLength(); j++) {
217
                    Element dep = (Element)deps.item(j);
218
                    String target = dep.getAttribute(AntBuildExtenderImplementation.ATTR_TARGET);
219
                    String dependsOn = dep.getAttribute(AntBuildExtenderImplementation.ATTR_DEPENDSON);
220
                    assert target != null;
221
                    assert dependsOn != null;
222
                    ext.loadDependency(target, dependsOn);
223
                }
224
            }
225
        }
226
    }
227
    
228
    /**
229
     * Describes and allows to manipulate the build script extension and it's links to the main build script
230
     * of the project.
231
     */
232
    public final class Extension {
233
        String id;
234
        FileObject file;
235
        String path;
236
        TreeMap<String, Collection<String>> dependencies;
237
        
238
        Extension(String id, FileObject script, String relPath) {
239
            this.id = id;
240
            file = script;
241
            path = relPath;
242
            dependencies = new TreeMap<String, Collection<String>>();
243
        }
244
245
        String getPath() {
246
            return path;
247
        }
248
        
249
        /**
250
         * Add a dependency of a main build script target on the target in the extension's script.
251
         * @param mainBuildTarget name of target in the main build script (see {@link org.netbeans.api.project.ant.AntBuildExtender#getExtendableTargets})
252
         * @param extensionTarget name of target in the extention script
253
         */
254
        public void addDependency(String mainBuildTarget, String extensionTarget) {
255
            assert implementation.getExtensibleTargets().contains(mainBuildTarget) : 
256
                "The target '" + mainBuildTarget + "' is not designated by the project type as extensible.";
257
            synchronized (AntBuildExtender.class) {
258
                loadDependency(mainBuildTarget, extensionTarget);
259
                updateProjectMetadata();
260
            }
261
        }
262
        
263
        private void loadDependency(String mainBuildTarget, String extensionTarget) {
264
            synchronized (AntBuildExtender.class) {
265
                Collection<String> tars = dependencies.get(mainBuildTarget);
266
                if (tars == null) {
267
                    tars = new ArrayList<String>();
268
                    dependencies.put(mainBuildTarget, tars);
269
                }
270
                if (!tars.contains(extensionTarget)) {
271
                    tars.add(extensionTarget);
272
                } else {
273
                    //log?
274
                }
275
            }
276
        }
277
        
278
        
279
        /**
280
         * Remove a dependency of a main build script target on the target in the extension's script.
281
         * 
282
         * @param mainBuildTarget name of target in the main build script (see {@link org.netbeans.api.project.ant.AntBuildExtender#getExtendableTargets})
283
         * @param extensionTarget name of target in the extention script
284
         */
285
        public void removeDependency(String mainBuildTarget, String extensionTarget) {
286
            Collection<String> str = dependencies.get(mainBuildTarget);
287
            if (str != null) {
288
                str.remove(extensionTarget);
289
                updateProjectMetadata();
290
            } else {
291
                //oh well, just ignore, nothing to update anyway..
292
            }
293
        }
294
295
        Map<String, Collection<String>> getDependencies() {
296
            TreeMap<String, Collection<String>> toRet = new TreeMap<String, Collection<String>>();
297
            synchronized (AntBuildExtender.class) {
298
                for (String str : dependencies.keySet()) {
299
                    ArrayList<String> col = new ArrayList<String>();
300
                    col.addAll(dependencies.get(str));
301
                    toRet.put(str, col);
302
                }
303
            }
304
            return toRet;
305
        }
306
    }
307
}
(-)src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java (+61 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 * 
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 * 
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 * 
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
package org.netbeans.api.project.ant;
20
21
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
22
import java.util.Collection;
23
import java.util.Map;
24
import java.util.Set;
25
import org.netbeans.api.project.ant.AntBuildExtender.Extension;
26
import org.netbeans.modules.project.ant.AntBuildExtenderAccessor;
27
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
28
29
/**
30
 *
31
 * @author mkleint
32
 */
33
class AntBuildExtenderAccessorImpl extends  AntBuildExtenderAccessor {
34
35
    static void createAccesor() {
36
        if (DEFAULT == null) {
37
            DEFAULT= new AntBuildExtenderAccessorImpl();
38
        }
39
    }
40
    
41
    private AntBuildExtenderAccessorImpl() {
42
    }
43
    
44
45
    public AntBuildExtender createExtender(AntBuildExtenderImplementation impl) {
46
        return new AntBuildExtender(impl);
47
    }
48
49
    public Set<Extension> getExtensions(AntBuildExtender ext) {
50
        return ext.getExtensions();
51
    }
52
53
    public String getPath(Extension extension) {
54
        return extension.getPath();
55
    }
56
57
    public Map<String, Collection<String>> getDependencies(Extension extension) {
58
        return extension.getDependencies();
59
    }
60
61
}
(-)src/org/netbeans/modules/project/ant/AntBuildExtenderAccessor.java (+57 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.modules.project.ant;
21
22
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
23
import java.util.Collection;
24
import java.util.Map;
25
import java.util.Set;
26
import org.netbeans.api.project.ant.AntBuildExtender;
27
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
28
29
30
/**
31
 * @author  mkleint
32
 */
33
public abstract class AntBuildExtenderAccessor {
34
35
    public static AntBuildExtenderAccessor DEFAULT = null;
36
37
    static {
38
        // invokes static initializer of Item.class
39
        // that will assign value to the DEFAULT field above
40
        Class c = AntBuildExtender.class;
41
        try {
42
            Class.forName(c.getName(), true, c.getClassLoader());
43
        } catch (Exception ex) {
44
            ex.printStackTrace();
45
        }
46
    }    
47
    
48
    public abstract AntBuildExtender createExtender(AntBuildExtenderImplementation impl);
49
    
50
    public abstract Set<AntBuildExtender.Extension> getExtensions(AntBuildExtender ext);
51
    
52
    public abstract String getPath(AntBuildExtender.Extension extension);
53
54
    public abstract Map<String, Collection<String>> getDependencies(AntBuildExtender.Extension extension);
55
56
    
57
}
(-)src/org/netbeans/spi/project/ant/AntBuildExtenderImplementation.java (+85 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.spi.project.ant;
21
22
import java.util.List;
23
import org.netbeans.api.project.Project;
24
25
/**
26
 * A project type's spi for {@link org.netbeans.api.project.ant.AntBuildExtender}'s wiring.
27
 * A typical setup in the project type includes:
28
 * <ul>
29
 * <li>Provide an instance of {@link org.netbeans.api.project.ant.AntBuildExtender} in project's lookup for use by 3rd
30
 * party modules.</<li>
31
 * <li>Use the new {@link org.netbeans.spi.project.support.ant.GeneratedFilesHelper#GeneratedFilesHelper(AntProjectHelper,AntBuildExtender)} constructor to
32
 *  create the helper for generating build related files.</<li>
33
 * </ul>
34
 * @author mkleint
35
 * @since org.netbeans.modules.project.ant 1.16
36
 */
37
public interface AntBuildExtenderImplementation {
38
    
39
    String AUX_NAMESPACE        = "http://www.netbeans.org/ns/ant-build-extender/1"; //NOI18N
40
    /**
41
     * 
42
     */
43
    String ELEMENT_ROOT         = "buildExtensions"; //NOI18N
44
    
45
    /**
46
     * 
47
     */
48
    String ELEMENT_EXTENSION    = "extension"; //NOI18N
49
    
50
    /**
51
     * 
52
     */
53
    String ELEMENT_DEPENDENCY   = "dependency"; //NOI18N
54
    
55
    /**
56
     * 
57
     */
58
    String ATTR_TARGET      = "target";
59
    /**
60
     * 
61
     */
62
    String ATTR_DEPENDSON   = "dependsOn";
63
    /**
64
     * 
65
     */
66
    String ATTR_ID          = "id";
67
    /**
68
     * 
69
     */
70
    String ATTR_FILE        = "file";
71
    
72
    
73
    /**
74
     * A declarative list of targets that are intended by the project type to be used
75
     * for extensions to plug into.
76
     * @return list of target names
77
     */
78
    List<String> getExtensibleTargets();
79
80
    /**
81
     * Returns Ant Project instance.
82
     * @return The project that this instance of AntBuildExtenderImplementation describes
83
     */
84
    Project getOwningProject();
85
}
(-)src/org/netbeans/spi/project/support/ant/AntBuildExtenderSupport.java (+46 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.spi.project.support.ant;
21
22
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
23
import org.netbeans.api.project.ant.AntBuildExtender;
24
import org.netbeans.modules.project.ant.AntBuildExtenderAccessor;
25
26
/**
27
 * Factory class for creation of AntBuildExtender instances
28
 * @author mkleint
29
 * @since org.netbeans.modules.project.ant 1.16
30
 */
31
public final class AntBuildExtenderSupport {
32
    
33
    /** Creates a new instance of AntBuildExtenderSupport */
34
    private AntBuildExtenderSupport() {
35
    }
36
    
37
    /**
38
     * 
39
     * @param implementation 
40
     * @return 
41
     */
42
    public static AntBuildExtender createAntExtender(AntBuildExtenderImplementation implementation) {
43
        return AntBuildExtenderAccessor.DEFAULT.createExtender(implementation);
44
    }
45
    
46
}
(-)src/org/netbeans/spi/project/support/ant/GeneratedFilesHelper.java (-1 / +111 lines)
Lines 29-34 Link Here
29
import java.io.OutputStream;
29
import java.io.OutputStream;
30
import java.net.URI;
30
import java.net.URI;
31
import java.net.URL;
31
import java.net.URL;
32
import java.util.Collection;
32
import java.util.HashMap;
33
import java.util.HashMap;
33
import java.util.Map;
34
import java.util.Map;
34
import java.util.Properties;
35
import java.util.Properties;
Lines 40-56 Link Here
40
import javax.xml.transform.stream.StreamResult;
41
import javax.xml.transform.stream.StreamResult;
41
import javax.xml.transform.stream.StreamSource;
42
import javax.xml.transform.stream.StreamSource;
42
import org.netbeans.api.project.ProjectManager;
43
import org.netbeans.api.project.ProjectManager;
44
import org.netbeans.api.project.ant.AntBuildExtender;
45
import org.netbeans.api.project.ant.AntBuildExtender.Extension;
46
import org.netbeans.modules.project.ant.AntBuildExtenderAccessor;
43
import org.netbeans.modules.project.ant.UserQuestionHandler;
47
import org.netbeans.modules.project.ant.UserQuestionHandler;
44
import org.openide.ErrorManager;
48
import org.openide.ErrorManager;
45
import org.openide.filesystems.FileLock;
49
import org.openide.filesystems.FileLock;
46
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
47
import org.openide.filesystems.FileSystem;
51
import org.openide.filesystems.FileSystem;
48
import org.openide.filesystems.FileUtil;
52
import org.openide.filesystems.FileUtil;
53
import org.openide.util.Exceptions;
49
import org.openide.util.Mutex;
54
import org.openide.util.Mutex;
50
import org.openide.util.MutexException;
55
import org.openide.util.MutexException;
51
import org.openide.util.NbBundle;
56
import org.openide.util.NbBundle;
52
import org.openide.util.UserQuestionException;
57
import org.openide.util.UserQuestionException;
53
import org.openide.util.Utilities;
58
import org.openide.util.Utilities;
59
import org.openide.xml.XMLUtil;
60
import org.w3c.dom.Attr;
61
import org.w3c.dom.Document;
62
import org.w3c.dom.Element;
63
import org.w3c.dom.Node;
64
import org.w3c.dom.NodeList;
65
import org.w3c.dom.Text;
66
import org.xml.sax.InputSource;
67
import org.xml.sax.SAXException;
54
68
55
/**
69
/**
56
 * Helps a project type (re-)generate, and manage the state and versioning of,
70
 * Helps a project type (re-)generate, and manage the state and versioning of,
Lines 160-165 Link Here
160
    /** Project directory. */
174
    /** Project directory. */
161
    private final FileObject dir;
175
    private final FileObject dir;
162
    
176
    
177
    private AntBuildExtender extender;
178
    
163
    /**
179
    /**
164
     * Create a helper based on the supplied project helper handle.
180
     * Create a helper based on the supplied project helper handle.
165
     * @param h an Ant-based project helper supplied to the project type provider
181
     * @param h an Ant-based project helper supplied to the project type provider
Lines 168-173 Link Here
168
        this.h = h;
184
        this.h = h;
169
        dir = h.getProjectDirectory();
185
        dir = h.getProjectDirectory();
170
    }
186
    }
187
188
    /**
189
     * Create a helper based on the supplied project helper handle. The created
190
     * instance is capable of extending the generated files with 3rd party content.
191
     * @param h an Ant-based project helper supplied to the project type provider
192
     * @param ex build extensibility support
193
     * @since org.netbeans.modules.project.ant 1.16
194
     * 
195
     */
196
    public GeneratedFilesHelper(AntProjectHelper h, AntBuildExtender ex) {
197
        this(h);
198
        extender = ex;
199
    }
171
    
200
    
172
    /**
201
    /**
173
     * Create a helper based only on a project directory.
202
     * Create a helper based only on a project directory.
Lines 255-261 Link Here
255
                                    new ByteArrayInputStream(projectXmlData), projectXmlF.toURI().toString());
284
                                    new ByteArrayInputStream(projectXmlData), projectXmlF.toURI().toString());
256
                                ByteArrayOutputStream result = new ByteArrayOutputStream();
285
                                ByteArrayOutputStream result = new ByteArrayOutputStream();
257
                                t.transform(projectXmlSource, new StreamResult(result));
286
                                t.transform(projectXmlSource, new StreamResult(result));
258
                                resultData = result.toByteArray();
287
                                if (BUILD_IMPL_XML_PATH.equals(path)) {
288
                                    resultData = applyBuildExtensions(result.toByteArray(), extender);
289
                                } else {
290
                                    resultData = result.toByteArray();
291
                                }
259
                            } catch (TransformerException e) {
292
                            } catch (TransformerException e) {
260
                                throw (IOException)new IOException(e.toString()).initCause(e);
293
                                throw (IOException)new IOException(e.toString()).initCause(e);
261
                            }
294
                            }
Lines 369-374 Link Here
369
        }
402
        }
370
    }
403
    }
371
    
404
    
405
    private byte[] applyBuildExtensions(byte[] resultData, AntBuildExtender ext) {
406
        if (ext == null) {
407
            return resultData;
408
        }
409
        try {
410
            ByteArrayInputStream in2 = new ByteArrayInputStream(resultData);
411
            InputSource is = new InputSource(in2);
412
413
            Document doc = XMLUtil.parse(is, false, true, null, null);
414
            Element el = doc.getDocumentElement();
415
            Node firstSubnode = el.getFirstChild();
416
            //TODO check if first one is text and use it as indentation..
417
            for (Extension extension : AntBuildExtenderAccessor.DEFAULT.getExtensions(ext)) {
418
                Text after = doc.createTextNode("\n");
419
                el.insertBefore(after, firstSubnode);
420
                Element imp = createImportElement(AntBuildExtenderAccessor.DEFAULT.getPath(extension), doc);
421
                el.insertBefore(imp, after);
422
                Text before = doc.createTextNode("    ");
423
                el.insertBefore(before, imp);
424
                firstSubnode = before;
425
                NodeList nl = el.getElementsByTagName("target"); //NOI18N
426
                Map<String, Collection<String>> deps  = AntBuildExtenderAccessor.DEFAULT.getDependencies(extension);
427
                for (String targetName : deps.keySet()) {
428
                    Element targetEl = null;
429
                    for (int i = 0; i < nl.getLength(); i++) {
430
                        Element elem = (Element)nl.item(i);
431
                        String at = elem.getAttribute("name"); //NOI18N
432
                        if (at != null && at.equals(targetName)) {
433
                            targetEl = elem;
434
                            break;
435
                        }
436
                    }
437
//                    System.out.println("target name=" + targetName);
438
//                    System.out.println("target elem=" + targetEl);
439
                    if (targetEl != null) {
440
                        Attr depend = targetEl.getAttributeNode("depends"); //NOI18N
441
                        if (depend == null) {
442
                            depend = doc.createAttribute("depends"); //NOI18N
443
                            depend.setValue("");
444
                            targetEl.setAttributeNode(depend);
445
                        }
446
                        String oldVal = depend.getValue();
447
                        for (String targ : deps.get(targetName)) {
448
                            oldVal = oldVal + "," + targ; //NOI18N
449
                        }
450
                        if (oldVal.startsWith(",")) { //NOI18N
451
                            oldVal = oldVal.substring(1);
452
                        }
453
                        depend.setValue(oldVal);
454
                    } else {
455
                        //TODO log??
456
                    }
457
                }
458
            }
459
460
            ByteArrayOutputStream out = new ByteArrayOutputStream();
461
            XMLUtil.write(doc, out, "UTF-8"); //NOI18N
462
            return out.toByteArray();
463
        }
464
        catch (IOException ex) {
465
            ex.printStackTrace();
466
            Exceptions.printStackTrace(ex);
467
            return resultData;
468
        }
469
        catch (SAXException ex) {
470
            ex.printStackTrace();
471
            Exceptions.printStackTrace(ex);
472
            return resultData;
473
        }
474
    }
475
476
    private Element createImportElement(String path, Document doc) {
477
        Element el = doc.createElement("import"); //NOI18N
478
        el.setAttribute("file", path);
479
        return el;
480
    }
481
372
    /**
482
    /**
373
     * Load data from a stream into a buffer.
483
     * Load data from a stream into a buffer.
374
     */
484
     */
(-)src/org/netbeans/spi/project/support/ant/package.html (+4 lines)
Lines 130-135 Link Here
130
{@link org.netbeans.spi.project.support.ant.ProjectXmlSavedHook} to be told when
130
{@link org.netbeans.spi.project.support.ant.ProjectXmlSavedHook} to be told when
131
to recreate them.</p>
131
to recreate them.</p>
132
132
133
<p>To allow 3rd party extensions to build scripts, use {@link org.netbeans.spi.project.ant.AntBuildExtenderImplementation} and
134
{@link org.netbeans.spi.project.support.ant.AntBuildExtenderSupport}.
135
</p>
136
133
<p>{@link org.netbeans.spi.project.support.ant.EditableProperties} is a
137
<p>{@link org.netbeans.spi.project.support.ant.EditableProperties} is a
134
VCS-friendly alternative to {@link java.util.Properties}.
138
VCS-friendly alternative to {@link java.util.Properties}.
135
{@link org.netbeans.spi.project.support.ant.PropertyUtils} also provides various
139
{@link org.netbeans.spi.project.support.ant.PropertyUtils} also provides various
(-)test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java (-3 / +24 lines)
Lines 19-24 Link Here
19
19
20
package org.netbeans.spi.project.support.ant;
20
package org.netbeans.spi.project.support.ant;
21
21
22
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
23
import java.beans.PropertyChangeEvent;
22
import java.beans.PropertyChangeListener;
24
import java.beans.PropertyChangeListener;
23
import java.io.File;
25
import java.io.File;
24
import java.io.FileInputStream;
26
import java.io.FileInputStream;
Lines 51-56 Link Here
51
import org.netbeans.spi.project.AuxiliaryConfiguration;
53
import org.netbeans.spi.project.AuxiliaryConfiguration;
52
import org.netbeans.api.project.ProjectInformation;
54
import org.netbeans.api.project.ProjectInformation;
53
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.ProjectManager;
56
import org.netbeans.api.project.ant.AntBuildExtender;
54
import org.netbeans.spi.project.ant.AntArtifactProvider;
57
import org.netbeans.spi.project.ant.AntArtifactProvider;
55
import org.netbeans.spi.queries.CollocationQueryImplementation;
58
import org.netbeans.spi.queries.CollocationQueryImplementation;
56
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileObject;
Lines 95-100 Link Here
95
        return new TestAntBasedProjectType();
98
        return new TestAntBasedProjectType();
96
    }
99
    }
97
    
100
    
101
    public static AntBasedProjectType testAntBasedProjectType(AntBuildExtenderImplementation extender) {
102
        return new TestAntBasedProjectType(extender);
103
    }
98
    /**
104
    /**
99
     * You can adjust which artifacts are supplied.
105
     * You can adjust which artifacts are supplied.
100
     */
106
     */
Lines 103-117 Link Here
103
    }
109
    }
104
    
110
    
105
    private static final class TestAntBasedProjectType implements AntBasedProjectType {
111
    private static final class TestAntBasedProjectType implements AntBasedProjectType {
112
        private AntBuildExtenderImplementation ext;
106
        
113
        
107
        TestAntBasedProjectType() {}
114
        TestAntBasedProjectType() {}
108
        
115
        
116
        TestAntBasedProjectType(AntBuildExtenderImplementation ext) {
117
            this.ext = ext;
118
        }
119
        
109
        public String getType() {
120
        public String getType() {
110
            return "test";
121
            return "test";
111
        }
122
        }
112
        
123
        
113
        public Project createProject(AntProjectHelper helper) throws IOException {
124
        public Project createProject(AntProjectHelper helper) throws IOException {
114
            return new TestAntBasedProject(helper);
125
            return new TestAntBasedProject(helper, ext);
115
        }
126
        }
116
        
127
        
117
        public String getPrimaryConfigurationDataElementName(boolean shared) {
128
        public String getPrimaryConfigurationDataElementName(boolean shared) {
Lines 131-144 Link Here
131
        private final GeneratedFilesHelper genFilesHelper;
142
        private final GeneratedFilesHelper genFilesHelper;
132
        private final Lookup l;
143
        private final Lookup l;
133
        
144
        
134
        TestAntBasedProject(AntProjectHelper helper) throws IOException {
145
        TestAntBasedProject(AntProjectHelper helper, AntBuildExtenderImplementation ext) throws IOException {
135
            if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) {
146
            if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) {
136
                throw new IOException("broken");
147
                throw new IOException("broken");
137
            }
148
            }
138
            this.helper = helper;
149
            this.helper = helper;
139
            AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration();
150
            AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration();
140
            refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
151
            refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
141
            genFilesHelper = new GeneratedFilesHelper(helper);
152
            Object extContent;
153
            if (ext !=null) {
154
                AntBuildExtender e = AntBuildExtenderSupport.createAntExtender(ext);
155
                genFilesHelper = new GeneratedFilesHelper(helper, e);
156
                extContent = e;
157
            } else {
158
                genFilesHelper = new GeneratedFilesHelper(helper);
159
                extContent = new Object();
160
            }       
142
            l = Lookups.fixed(new Object[] {
161
            l = Lookups.fixed(new Object[] {
143
                new TestInfo(),
162
                new TestInfo(),
144
                helper,
163
                helper,
Lines 161-166 Link Here
161
                    }
180
                    }
162
                },
181
                },
163
                "hello",
182
                "hello",
183
                extContent
164
            });
184
            });
165
        }
185
        }
166
        
186
        
Lines 213-218 Link Here
213
            public void removePropertyChangeListener(PropertyChangeListener listener) {}
233
            public void removePropertyChangeListener(PropertyChangeListener listener) {}
214
            
234
            
215
        }
235
        }
236
216
        
237
        
217
        private final class TestAntArtifactProvider implements AntArtifactProviderMutable {
238
        private final class TestAntArtifactProvider implements AntArtifactProviderMutable {
218
            
239
            
(-)test/unit/src/org/netbeans/spi/project/support/ant/AntBuildExtenderTest.java (+139 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.spi.project.support.ant;
21
22
import org.netbeans.spi.project.AuxiliaryConfiguration;
23
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
24
import java.util.Collections;
25
import java.util.List;
26
import org.netbeans.api.project.Project;
27
import org.netbeans.api.project.ProjectManager;
28
import org.netbeans.api.project.TestUtil;
29
import org.netbeans.api.project.ant.AntBuildExtender;
30
import org.netbeans.junit.NbTestCase;
31
import org.openide.filesystems.FileObject;
32
import org.w3c.dom.Element;
33
import org.w3c.dom.NodeList;
34
35
/**
36
 * Test functionality of AntBuildExtender.
37
 * @author mkleint
38
 */
39
public class AntBuildExtenderTest extends NbTestCase {
40
    
41
    public AntBuildExtenderTest(String name) {
42
        super(name);
43
    }
44
    
45
    private FileObject scratch;
46
    private FileObject projdir;
47
    private FileObject extension1;
48
    private ProjectManager pm;
49
    private Project p;
50
    private AntProjectHelper h;
51
    private GeneratedFilesHelper gfh;
52
    private ExtImpl extenderImpl;
53
    
54
    protected void setUp() throws Exception {
55
        super.setUp();
56
        scratch = TestUtil.makeScratchDir(this);
57
        projdir = scratch.createFolder("proj");
58
        TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml");
59
        extension1 = TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/extension1.xml"), projdir, "nbproject/extension1.xml");
60
        extenderImpl = new ExtImpl();
61
        TestUtil.setLookup(new Object[] {
62
            AntBasedTestUtil.testAntBasedProjectType(extenderImpl),
63
        });
64
        pm = ProjectManager.getDefault();
65
        p = pm.findProject(projdir);
66
        extenderImpl.project = p;
67
        h = p.getLookup().lookup(AntProjectHelper.class);
68
        gfh = p.getLookup().lookup(GeneratedFilesHelper.class);
69
        assertNotNull(gfh);
70
    }
71
    
72
    public void testGetExtendableTargets() {
73
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
74
75
        List<String> result = instance.getExtensibleTargets();
76
77
        assertEquals(1, result.size());
78
        assertEquals("all", result.get(0));
79
    }
80
81
    public void testAddExtension() {
82
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
83
        instance.addExtension("milos", extension1);
84
        Element el = p.getLookup().lookup(AuxiliaryConfiguration.class).getConfigurationFragment(
85
                AntBuildExtenderImplementation.ELEMENT_ROOT, AntBuildExtenderImplementation.AUX_NAMESPACE, true);
86
        assertNotNull(el);
87
        NodeList nl = el.getElementsByTagName(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
88
        assertEquals(1, nl.getLength());
89
        Element extens = (Element) nl.item(0);
90
        assertEquals("milos", extens.getAttribute(AntBuildExtenderImplementation.ATTR_ID));
91
        assertEquals("extension1.xml", extens.getAttribute(AntBuildExtenderImplementation.ATTR_FILE));
92
    }
93
94
    public void testRemoveExtension() {
95
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
96
        testAddExtension();
97
        extenderImpl.oldElement = p.getLookup().lookup(AuxiliaryConfiguration.class).getConfigurationFragment(
98
                AntBuildExtenderImplementation.ELEMENT_ROOT, AntBuildExtenderImplementation.AUX_NAMESPACE, true);
99
        instance.removeExtension("milos");
100
        Element el = p.getLookup().lookup(AuxiliaryConfiguration.class).getConfigurationFragment(
101
                AntBuildExtenderImplementation.ELEMENT_ROOT, AntBuildExtenderImplementation.AUX_NAMESPACE, true);
102
103
        assertNotNull(el);
104
        NodeList nl = el.getElementsByTagName(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
105
        assertEquals(0, nl.getLength());
106
    }
107
108
    public void testGetExtension() {
109
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
110
        testAddExtension();
111
        AntBuildExtender.Extension ext = instance.getExtension("milos");
112
        assertNotNull(ext);
113
    }
114
    
115
    private class ExtImpl implements AntBuildExtenderImplementation {
116
        Project project;
117
        Element newElement;
118
        Element oldElement;
119
        List<String> targets = Collections.singletonList("all");
120
121
        public List<String> getExtensibleTargets() {
122
            return targets;
123
        }
124
125
        public void updateBuildExtensionMetadata(Element element) {
126
            newElement = element;
127
        }
128
129
        public Element getBuildExtensionMetadata() {
130
            return oldElement;
131
        }
132
133
        public Project getOwningProject() {
134
            return project;
135
        }
136
137
    }
138
    
139
}
(-)test/unit/src/org/netbeans/spi/project/support/ant/GeneratedFilesHelperTest.java (-1 / +40 lines)
Lines 19-32 Link Here
19
19
20
package org.netbeans.spi.project.support.ant;
20
package org.netbeans.spi.project.support.ant;
21
21
22
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
22
import java.io.ByteArrayInputStream;
23
import java.io.ByteArrayInputStream;
23
import java.io.File;
24
import java.io.File;
24
import java.net.URL;
25
import java.net.URL;
26
import java.util.Collections;
27
import java.util.List;
25
import org.netbeans.api.project.Project;
28
import org.netbeans.api.project.Project;
26
import org.netbeans.api.project.ProjectManager;
29
import org.netbeans.api.project.ProjectManager;
27
import org.netbeans.api.project.TestUtil;
30
import org.netbeans.api.project.TestUtil;
28
import org.netbeans.junit.NbTestCase;
31
import org.netbeans.junit.NbTestCase;
29
import org.netbeans.modules.project.ant.Util;
32
import org.netbeans.modules.project.ant.Util;
33
import org.netbeans.spi.project.AuxiliaryConfiguration;
30
import org.openide.filesystems.FileObject;
34
import org.openide.filesystems.FileObject;
31
import org.openide.filesystems.FileUtil;
35
import org.openide.filesystems.FileUtil;
32
import org.openide.util.Utilities;
36
import org.openide.util.Utilities;
Lines 46-66 Link Here
46
    
50
    
47
    private FileObject scratch;
51
    private FileObject scratch;
48
    private FileObject projdir;
52
    private FileObject projdir;
53
    private FileObject extension1;
49
    private ProjectManager pm;
54
    private ProjectManager pm;
50
    private Project p;
55
    private Project p;
51
    private AntProjectHelper h;
56
    private AntProjectHelper h;
52
    private GeneratedFilesHelper gfh;
57
    private GeneratedFilesHelper gfh;
58
    private ExtImpl extenderImpl;
53
    
59
    
54
    protected void setUp() throws Exception {
60
    protected void setUp() throws Exception {
55
        super.setUp();
61
        super.setUp();
56
        scratch = TestUtil.makeScratchDir(this);
62
        scratch = TestUtil.makeScratchDir(this);
57
        projdir = scratch.createFolder("proj");
63
        projdir = scratch.createFolder("proj");
58
        TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml");
64
        TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml");
65
        extension1 = TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/extension1.xml"), projdir, "nbproject/extension1.xml");
66
        extenderImpl = new ExtImpl();
59
        TestUtil.setLookup(new Object[] {
67
        TestUtil.setLookup(new Object[] {
60
            AntBasedTestUtil.testAntBasedProjectType(),
68
            AntBasedTestUtil.testAntBasedProjectType(extenderImpl),
61
        });
69
        });
62
        pm = ProjectManager.getDefault();
70
        pm = ProjectManager.getDefault();
63
        p = pm.findProject(projdir);
71
        p = pm.findProject(projdir);
72
        extenderImpl.project = p;
64
        h = p.getLookup().lookup(AntProjectHelper.class);
73
        h = p.getLookup().lookup(AntProjectHelper.class);
65
        gfh = p.getLookup().lookup(GeneratedFilesHelper.class);
74
        gfh = p.getLookup().lookup(GeneratedFilesHelper.class);
66
        assertNotNull(gfh);
75
        assertNotNull(gfh);
Lines 198-203 Link Here
198
            }
207
            }
199
            assertTrue("generated file has platform line endings", ok);
208
            assertTrue("generated file has platform line endings", ok);
200
        }
209
        }
210
    }
211
    
212
    private class ExtImpl implements AntBuildExtenderImplementation {
213
        Project project;
214
        Element newElement;
215
        Element oldElement;
216
217
        public List<String> getExtensibleTargets() {
218
            return Collections.singletonList("all");
219
        }
220
221
        public void updateBuildExtensionMetadata(Element element) {
222
            newElement = element;
223
        }
224
225
        public Element getBuildExtensionMetadata() {
226
            Element el = project.getLookup().lookup(AuxiliaryConfiguration.class).getConfigurationFragment(ELEMENT_ROOT, "urn:test:extension", true);
227
            if (el != null) {
228
                NodeList nl = el.getElementsByTagName(AntBuildExtenderImplementation.ELEMENT_ROOT);
229
                if (nl.getLength() == 1) {
230
                    return (Element) nl.item(0);
231
                }
232
            }
233
            return null;
234
        }
235
236
        public Project getOwningProject() {
237
            return project;
238
        }
239
201
    }
240
    }
202
    
241
    
203
}
242
}
(-)test/unit/src/org/netbeans/spi/project/support/ant/data/extension1.xml (+13 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
3
<!--
4
    Document   : extension1.xml.xml
5
    Created on : March 28, 2007, 3:56 PM
6
    Author     : mkleint
7
    Description:
8
        Purpose of the document follows.
9
-->
10
11
<root>
12
13
</root>

Return to bug 93509