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

(-)ant/project/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.support.ant" name="AntBuildExtender"/>
99
            <class package="org.netbeans.spi.project.support.ant" name="GeneratedFileHelper"/>
100
            <class package="org.netbeans.spi.project.support.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">
105
        <change id="includes-excludes">
86
            <api name="general"/>
106
            <api name="general"/>
(-)ant/project/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
(-)ant/project/nbproject/project.xml (+1 lines)
Lines 165-169 Link Here
165
                <built-to>build/tasks.jar</built-to>
165
                <built-to>build/tasks.jar</built-to>
166
            </extra-compilation-unit>
166
            </extra-compilation-unit>
167
        </data>
167
        </data>
168
        <junit-version xmlns="http://www.netbeans.org/ns/junit/1" value="junit3"/>
168
    </configuration>
169
    </configuration>
169
</project>
170
</project>
(-)ant/project/src/org/netbeans/api/project/ant/AntBuildExtender.java (+304 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.ant.AntBuildExtenderImplementation;
37
import org.netbeans.spi.project.support.ant.AntProjectHelper;
38
import org.openide.filesystems.FileObject;
39
import org.openide.filesystems.FileUtil;
40
import org.w3c.dom.Document;
41
import org.w3c.dom.Element;
42
import org.w3c.dom.NodeList;
43
44
/**
45
 * Allows extending the project's build script with 3rd party additions.
46
 * Check the Project's lookup to see if the feature is supported by a given Ant project type.
47
 * Typical usage:
48
 * <ul>
49
 *    <li>Lookup the instance of AntBuildExtender in the project at hand</li>
50
 *    <li>Create the external build script file with your targets and configuration</li>
51
 *    <li>Use the AntBuildExtender to wire your script and targets into the main build lifecycle</li>
52
 *    <li>Call {@link org.netbeans.api.project.ProjectManager#saveProject} to persist the changes and
53
 *        regenerate the main build script</li>
54
 * </ul>
55
 * 
56
 * Please note that it's easy to break the build script functionality and any script extensions
57
 * shall be done with care. A few rules to follow:
58
 * <ul>
59
 *   <li>Pick a reasonably unique extension id</li>
60
 *   <li>Prefix target names and properties you define in your extension with the extension id to prevent clashes.</li>
61
 * </ul>
62
 * @author mkleint
63
 * @since org.netbeans.modules.project.ant 1.16
64
 */
65
public final class AntBuildExtender {
66
    private HashMap<String, Extension> extensions;
67
    private AntBuildExtenderImplementation implementation;
68
    
69
    static {
70
        AntBuildExtenderAccessorImpl.createAccesor();
71
    }
72
73
    AntBuildExtender(AntBuildExtenderImplementation implementation) {
74
        this.implementation = implementation;
75
    }
76
    
77
    /**
78
     * Get a list of target names in the main build script that are allowed to be 
79
     * extended by adding the "depends" attribute definition to them.
80
     * @return list of target names
81
     */
82
    public List<String> getExtendableTargets() {
83
        List<String> targets = new ArrayList<String>();
84
        targets.addAll(implementation.getExtendableTargets());
85
        targets = Collections.unmodifiableList(targets);
86
        return targets;
87
    }
88
    
89
    /**
90
     * Adds a new build script extension.
91
     * @param id identification of the extension
92
     * @param extensionXml fileobject referencing the build script for the extension, 
93
     * needs to be located in nbproject directory or below.
94
     * @return the newly created extension.
95
     */
96
    public synchronized Extension addExtension(String id, FileObject extensionXml) {
97
        assert extensionXml != null;
98
        assert extensionXml.isValid() && extensionXml.isData();
99
        //TODO assert the owner is the same as the owner of this instance of entender.
100
        assert FileOwnerQuery.getOwner(extensionXml) == implementation.getOwningProject();
101
        FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
102
        assert FileUtil.isParentOf(nbproj, extensionXml);
103
        if (extensions == null) {
104
            readProjectMetadata();
105
        }
106
        if (extensions.get(id) != null) {
107
            throw new IllegalStateException("Extension with id '" + id + "' already exists.");
108
        }
109
        Extension ex = new Extension(id, extensionXml, FileUtil.getRelativePath(nbproj, extensionXml));
110
        extensions.put(id, ex);
111
        updateProjectMetadata();
112
        return ex;
113
    }
114
    /**
115
     * Remove an existing build script extension. Make sure to remove the extension's script file
116
     * before/after removing the extension.
117
     * @param id identification of the extension
118
     */
119
    public synchronized void removeExtension(String id) {
120
        if (extensions == null) {
121
            readProjectMetadata();
122
        }
123
        if (extensions.get(id) == null) {
124
            // oh well, just ignore.
125
            return;
126
        }
127
        extensions.remove(id);
128
        updateProjectMetadata();
129
    }
130
    
131
    /**
132
     * Get an extension by the id.
133
     * @param id identification token
134
     * @return Extention with the given id or null if not found.
135
     */
136
    public synchronized Extension getExtension(String id) {
137
        if (extensions == null) {
138
            readProjectMetadata();
139
        }
140
        return extensions.get(id);
141
    }
142
143
144
    synchronized Set<Extension> getExtensions() {
145
        Set<Extension> ext =  new HashSet<Extension>();
146
        if (extensions == null) {
147
            readProjectMetadata();
148
        }
149
        ext.addAll(extensions.values());
150
        return ext;
151
    }
152
    
153
    private static final DocumentBuilder db;
154
    static {
155
        try {
156
            db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
157
        } catch (ParserConfigurationException e) {
158
            throw new AssertionError(e);
159
        }
160
    }
161
    private static Document createNewDocument() {
162
        // #50198: for thread safety, use a separate document.
163
        // Using XMLUtil.createDocument is much too slow.
164
        synchronized (db) {
165
            return db.newDocument();
166
        }
167
    }
168
    
169
    
170
    private void updateProjectMetadata() {
171
        Document doc = createNewDocument();
172
        Element root = doc.createElement(AntBuildExtenderImplementation.ELEMENT_ROOT);
173
        if (extensions  != null) {
174
            FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
175
            for (Extension ext : extensions.values()) {
176
                Element child = doc.createElement(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
177
                child.setAttribute(AntBuildExtenderImplementation.ATTR_ID, ext.id);
178
                String relPath = FileUtil.getRelativePath(nbproj, ext.file);
179
                assert relPath != null;
180
                child.setAttribute(AntBuildExtenderImplementation.ATTR_FILE, relPath);
181
                root.appendChild(child);
182
                for (String target : ext.dependencies.keySet()) {
183
                    for (String depTarget : ext.dependencies.get(target)) {
184
                        Element dep = doc.createElement(AntBuildExtenderImplementation.ELEMENT_DEPENDENCY);
185
                        dep.setAttribute(AntBuildExtenderImplementation.ATTR_TARGET, target);
186
                        dep.setAttribute(AntBuildExtenderImplementation.ATTR_DEPENDSON, depTarget);
187
                        child.appendChild(dep);
188
                    }
189
                }
190
            }
191
        }
192
        implementation.updateBuildExtensionMetadata(root);
193
    }
194
    
195
    private void readProjectMetadata() {
196
        Element cfgEl = implementation.getBuildExtensionMetadata();
197
        List<String> rootIds = new ArrayList<String>();
198
        FileObject nbproj = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH).getParent();
199
        extensions = new HashMap<String, Extension>();
200
        if (cfgEl != null) {
201
            String namespace = cfgEl.getNamespaceURI();
202
            NodeList roots = cfgEl.getElementsByTagNameNS(namespace, AntBuildExtenderImplementation.ELEMENT_EXTENSION);
203
            for (int i=0; i <roots.getLength(); i++) {
204
                Element root = (Element) roots.item(i);
205
                String id = root.getAttribute(AntBuildExtenderImplementation.ATTR_ID);
206
                assert id.length() > 0 : "Illegal project.xml";
207
                String value = root.getAttribute(AntBuildExtenderImplementation.ATTR_FILE);
208
                FileObject script = nbproj.getFileObject(value);
209
                assert script != null : "Missing file " + script;
210
                Extension ext = new Extension(id, script, value);
211
                extensions.put(id, ext);
212
                NodeList deps = root.getElementsByTagNameNS(namespace, AntBuildExtenderImplementation.ELEMENT_DEPENDENCY);
213
                for (int j = 0; j < deps.getLength(); j++) {
214
                    Element dep = (Element)deps.item(j);
215
                    String target = dep.getAttribute(AntBuildExtenderImplementation.ATTR_TARGET);
216
                    String dependsOn = dep.getAttribute(AntBuildExtenderImplementation.ATTR_DEPENDSON);
217
                    assert target != null;
218
                    assert dependsOn != null;
219
                    ext.loadDependency(target, dependsOn);
220
                }
221
            }
222
        }
223
    }
224
    
225
    /**
226
     * Describes and allows to manipulate the build script extension and it's links to the main build script
227
     * of the project.
228
     */
229
    public final class Extension {
230
        String id;
231
        FileObject file;
232
        String path;
233
        TreeMap<String, Collection<String>> dependencies;
234
        
235
        Extension(String id, FileObject script, String relPath) {
236
            this.id = id;
237
            file = script;
238
            path = relPath;
239
            dependencies = new TreeMap<String, Collection<String>>();
240
        }
241
242
        String getPath() {
243
            return path;
244
        }
245
        
246
        /**
247
         * Add a dependency of a main build script target on the target in the extension's script.
248
         * @param mainBuildTarget name of target in the main build script (see {@link org.netbeans.api.project.ant.AntBuildExtender#getExtendableTargets})
249
         * @param extensionTarget name of target in the extention script
250
         */
251
        public void addDependency(String mainBuildTarget, String extensionTarget) {
252
            assert implementation.getExtendableTargets().contains(mainBuildTarget) : 
253
                "The target '" + mainBuildTarget + "' is not designated by the project type as extensible.";
254
            synchronized (AntBuildExtender.class) {
255
                loadDependency(mainBuildTarget, extensionTarget);
256
                updateProjectMetadata();
257
            }
258
        }
259
        
260
        private void loadDependency(String mainBuildTarget, String extensionTarget) {
261
            synchronized (AntBuildExtender.class) {
262
                Collection<String> tars = dependencies.get(mainBuildTarget);
263
                if (tars == null) {
264
                    tars = new ArrayList<String>();
265
                    dependencies.put(mainBuildTarget, tars);
266
                }
267
                if (!tars.contains(extensionTarget)) {
268
                    tars.add(extensionTarget);
269
                } else {
270
                    //log?
271
                }
272
            }
273
        }
274
        
275
        
276
        /**
277
         * Remove a dependency of a main build script target on the target in the extension's script.
278
         * 
279
         * @param mainBuildTarget name of target in the main build script (see {@link org.netbeans.api.project.ant.AntBuildExtender#getExtendableTargets})
280
         * @param extensionTarget name of target in the extention script
281
         */
282
        public void removeDependency(String mainBuildTarget, String extensionTarget) {
283
            Collection<String> str = dependencies.get(mainBuildTarget);
284
            if (str != null) {
285
                str.remove(extensionTarget);
286
                updateProjectMetadata();
287
            } else {
288
                //oh well, just ignore, nothing to update anyway..
289
            }
290
        }
291
292
        Map<String, Collection<String>> getDependencies() {
293
            TreeMap<String, Collection<String>> toRet = new TreeMap<String, Collection<String>>();
294
            synchronized (AntBuildExtender.class) {
295
                for (String str : dependencies.keySet()) {
296
                    ArrayList<String> col = new ArrayList<String>();
297
                    col.addAll(dependencies.get(str));
298
                    toRet.put(str, col);
299
                }
300
            }
301
            return toRet;
302
        }
303
    }
304
}
(-)ant/project/src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java (+60 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
 * To change this template, choose Tools | Template Manager
16
 * and open the template in the editor.
17
 */
18
package org.netbeans.api.project.ant;
19
20
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
21
import java.util.Collection;
22
import java.util.Map;
23
import java.util.Set;
24
import org.netbeans.api.project.ant.AntBuildExtender.Extension;
25
import org.netbeans.modules.project.ant.AntBuildExtenderAccessor;
26
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
27
28
/**
29
 *
30
 * @author mkleint
31
 */
32
class AntBuildExtenderAccessorImpl extends  AntBuildExtenderAccessor {
33
34
    static void createAccesor() {
35
        if (DEFAULT == null) {
36
            DEFAULT= new AntBuildExtenderAccessorImpl();
37
        }
38
    }
39
    
40
    private AntBuildExtenderAccessorImpl() {
41
    }
42
    
43
44
    public AntBuildExtender createExtender(AntBuildExtenderImplementation impl) {
45
        return new AntBuildExtender(impl);
46
    }
47
48
    public Set<Extension> getExtensions(AntBuildExtender ext) {
49
        return ext.getExtensions();
50
    }
51
52
    public String getPath(Extension extension) {
53
        return extension.getPath();
54
    }
55
56
    public Map<String, Collection<String>> getDependencies(Extension extension) {
57
        return extension.getDependencies();
58
    }
59
60
}
(-)ant/project/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
}
(-)ant/project/src/org/netbeans/spi/project/ant/AntBuildExtenderImplementation.java (+104 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
import org.w3c.dom.Element;
25
26
/**
27
 * A project type's spi for {@link org.netbeans.api.project.ant.AntBuildExtender}'s wiring.
28
 * A typical setup in the project type includes:
29
 * <ul>
30
 * <li>Enhance the Project's metadata schema with the build extensibility content.</<li>
31
 * <li>Provide lookup and storage of the metadata content by implementing this interface</<li>
32
 * <li>Provide an instance of {@link org.netbeans.api.project.ant.AntBuildExtender} in project's lookup for use by 3rd
33
 * party modules.</<li>
34
 * <li>Use the new {@link org.netbeans.spi.project.support.ant.GeneratedFilesHelper#GeneratedFilesHelper(AntProjectHelper,AntBuildExtender)} constructor to
35
 *  create the helper for generating build related files.</<li>
36
 * </ul>
37
 * @author mkleint
38
 * @since org.netbeans.modules.project.ant 1.16
39
 */
40
public interface AntBuildExtenderImplementation {
41
    
42
    /**
43
     * 
44
     */
45
    public static final String ELEMENT_ROOT         = "buildExtensions"; //NOI18N
46
    
47
    /**
48
     * 
49
     */
50
    public static final String ELEMENT_EXTENSION    = "extension"; //NOI18N
51
    
52
    /**
53
     * 
54
     */
55
    public static final String ELEMENT_DEPENDENCY   = "dependency"; //NOI18N
56
    
57
    /**
58
     * 
59
     */
60
    public static final String ATTR_TARGET      = "target";
61
    /**
62
     * 
63
     */
64
    public static final String ATTR_DEPENDSON   = "dependsOn";
65
    /**
66
     * 
67
     */
68
    public static final String ATTR_ID          = "id";
69
    /**
70
     * 
71
     */
72
    public static final String ATTR_FILE        = "file";
73
    
74
    
75
    /**
76
     * A declarative list of targets that are intended by the project type to be used
77
     * for extensions to plug into.
78
     * @return list of target names
79
     */
80
    List<String> getExtendableTargets();
81
82
    /**
83
     * Requests an update of build extensibility metadata by the implementation.
84
     * A usual implementation takes the content of <code>root</code> parameter and 
85
     * copies it into the correct place in the primary project configuration space in project.xml
86
     * 
87
     * @param root the root element for extensibility metadata (See {@link org.netbeans.spi.project.ant.AntBuildExtenderImplementation#ELEMENT_ROOT})     */
88
    void updateBuildExtensionMetadata(Element root);
89
    
90
    /**
91
     * Returns the project build script extensibility configuration from a known location in project.xml.
92
     * (As defined by the project type's schema). Usual implementation will use the primary project configuration
93
     * space in project.xml.
94
     * @return project metadata element, the root for project extensions (See {@link org.netbeans.spi.project.ant.AntBuildExtenderImplementation#ELEMENT_ROOT}), or null if not
95
     *  configured.
96
     */
97
    Element getBuildExtensionMetadata();
98
    
99
    /**
100
     * Returns Ant Project instance.
101
     * @return The project that this instance of AntBuildExtenderImplementation describes
102
     */
103
    Project getOwningProject();
104
}
(-)ant/project/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
}
(-)ant/project/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");
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");
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");
441
                        if (depend == null) {
442
                            depend = doc.createAttribute("depends");
443
                            depend.setValue("");
444
                            targetEl.setAttributeNode(depend);
445
                        }
446
                        String oldVal = depend.getValue();
447
                        for (String targ : deps.get(targetName)) {
448
                            oldVal = oldVal + "," + targ;
449
                        }
450
                        if (oldVal.startsWith(",")) {
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");
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");
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
     */
(-)ant/project/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
(-)ant/project/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java (-3 / +23 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;
22
import java.beans.PropertyChangeEvent;
23
import java.beans.PropertyChangeEvent;
23
import java.beans.PropertyChangeListener;
24
import java.beans.PropertyChangeListener;
24
import java.io.File;
25
import java.io.File;
Lines 56-61 Link Here
56
import org.netbeans.spi.project.AuxiliaryConfiguration;
57
import org.netbeans.spi.project.AuxiliaryConfiguration;
57
import org.netbeans.api.project.ProjectInformation;
58
import org.netbeans.api.project.ProjectInformation;
58
import org.netbeans.api.project.ProjectManager;
59
import org.netbeans.api.project.ProjectManager;
60
import org.netbeans.api.project.ant.AntBuildExtender;
59
import org.netbeans.spi.project.ant.AntArtifactProvider;
61
import org.netbeans.spi.project.ant.AntArtifactProvider;
60
import org.netbeans.spi.queries.CollocationQueryImplementation;
62
import org.netbeans.spi.queries.CollocationQueryImplementation;
61
import org.openide.filesystems.FileObject;
63
import org.openide.filesystems.FileObject;
Lines 100-105 Link Here
100
        return new TestAntBasedProjectType();
102
        return new TestAntBasedProjectType();
101
    }
103
    }
102
    
104
    
105
    public static AntBasedProjectType testAntBasedProjectType(AntBuildExtenderImplementation extender) {
106
        return new TestAntBasedProjectType(extender);
107
    }
103
    /**
108
    /**
104
     * You can adjust which artifacts are supplied.
109
     * You can adjust which artifacts are supplied.
105
     */
110
     */
Lines 108-122 Link Here
108
    }
113
    }
109
    
114
    
110
    private static final class TestAntBasedProjectType implements AntBasedProjectType {
115
    private static final class TestAntBasedProjectType implements AntBasedProjectType {
116
        private AntBuildExtenderImplementation ext;
111
        
117
        
112
        TestAntBasedProjectType() {}
118
        TestAntBasedProjectType() {}
113
        
119
        
120
        TestAntBasedProjectType(AntBuildExtenderImplementation ext) {
121
            this.ext = ext;
122
        }
123
        
114
        public String getType() {
124
        public String getType() {
115
            return "test";
125
            return "test";
116
        }
126
        }
117
        
127
        
118
        public Project createProject(AntProjectHelper helper) throws IOException {
128
        public Project createProject(AntProjectHelper helper) throws IOException {
119
            return new TestAntBasedProject(helper);
129
            return new TestAntBasedProject(helper, ext);
120
        }
130
        }
121
        
131
        
122
        public String getPrimaryConfigurationDataElementName(boolean shared) {
132
        public String getPrimaryConfigurationDataElementName(boolean shared) {
Lines 136-149 Link Here
136
        private final GeneratedFilesHelper genFilesHelper;
146
        private final GeneratedFilesHelper genFilesHelper;
137
        private final Lookup l;
147
        private final Lookup l;
138
        
148
        
139
        TestAntBasedProject(AntProjectHelper helper) throws IOException {
149
        TestAntBasedProject(AntProjectHelper helper, AntBuildExtenderImplementation ext) throws IOException {
140
            if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) {
150
            if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) {
141
                throw new IOException("broken");
151
                throw new IOException("broken");
142
            }
152
            }
143
            this.helper = helper;
153
            this.helper = helper;
144
            AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration();
154
            AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration();
145
            refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
155
            refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
146
            genFilesHelper = new GeneratedFilesHelper(helper);
156
            Object extContent;
157
            if (ext !=null) {
158
                AntBuildExtender e = AntBuildExtenderSupport.createAntExtender(ext);
159
                genFilesHelper = new GeneratedFilesHelper(helper, e);
160
                extContent = e;
161
            } else {
162
                genFilesHelper = new GeneratedFilesHelper(helper);
163
                extContent = new Object();
164
            }       
147
            l = Lookups.fixed(new Object[] {
165
            l = Lookups.fixed(new Object[] {
148
                new TestInfo(),
166
                new TestInfo(),
149
                helper,
167
                helper,
Lines 166-171 Link Here
166
                    }
184
                    }
167
                },
185
                },
168
                "hello",
186
                "hello",
187
                extContent
169
            });
188
            });
170
        }
189
        }
171
        
190
        
Lines 218-223 Link Here
218
            public void removePropertyChangeListener(PropertyChangeListener listener) {}
237
            public void removePropertyChangeListener(PropertyChangeListener listener) {}
219
            
238
            
220
        }
239
        }
240
221
        
241
        
222
        private final class TestAntArtifactProvider implements AntArtifactProviderMutable {
242
        private final class TestAntArtifactProvider implements AntArtifactProviderMutable {
223
            
243
            
(-)ant/project/test/unit/src/org/netbeans/spi/project/support/ant/AntBuildExtenderTest.java (+135 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 java.util.Collections;
24
import java.util.List;
25
import org.netbeans.api.project.Project;
26
import org.netbeans.api.project.ProjectManager;
27
import org.netbeans.api.project.TestUtil;
28
import org.netbeans.api.project.ant.AntBuildExtender;
29
import org.netbeans.junit.NbTestCase;
30
import org.openide.filesystems.FileObject;
31
import org.w3c.dom.Element;
32
import org.w3c.dom.NodeList;
33
34
/**
35
 * Test functionality of AntBuildExtender.
36
 * @author mkleint
37
 */
38
public class AntBuildExtenderTest extends NbTestCase {
39
    
40
    public AntBuildExtenderTest(String name) {
41
        super(name);
42
    }
43
    
44
    private FileObject scratch;
45
    private FileObject projdir;
46
    private FileObject extension1;
47
    private ProjectManager pm;
48
    private Project p;
49
    private AntProjectHelper h;
50
    private GeneratedFilesHelper gfh;
51
    private ExtImpl extenderImpl;
52
    
53
    protected void setUp() throws Exception {
54
        super.setUp();
55
        scratch = TestUtil.makeScratchDir(this);
56
        projdir = scratch.createFolder("proj");
57
        TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml");
58
        extension1 = TestUtil.createFileFromContent(GeneratedFilesHelperTest.class.getResource("data/extension1.xml"), projdir, "nbproject/extension1.xml");
59
        extenderImpl = new ExtImpl();
60
        TestUtil.setLookup(new Object[] {
61
            AntBasedTestUtil.testAntBasedProjectType(extenderImpl),
62
        });
63
        pm = ProjectManager.getDefault();
64
        p = pm.findProject(projdir);
65
        extenderImpl.project = p;
66
        h = p.getLookup().lookup(AntProjectHelper.class);
67
        gfh = p.getLookup().lookup(GeneratedFilesHelper.class);
68
        assertNotNull(gfh);
69
    }
70
    
71
    public void testGetExtendableTargets() {
72
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
73
74
        List<String> result = instance.getExtendableTargets();
75
76
        assertEquals(1, result.size());
77
        assertEquals("all", result.get(0));
78
    }
79
80
    public void testAddExtension() {
81
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
82
        instance.addExtension("milos", extension1);
83
        Element el = extenderImpl.newElement;
84
        assertNotNull(el);
85
        NodeList nl = el.getElementsByTagName(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
86
        assertEquals(1, nl.getLength());
87
        Element extens = (Element) nl.item(0);
88
        assertEquals("milos", extens.getAttribute(AntBuildExtenderImplementation.ATTR_ID));
89
        assertEquals("extension1.xml", extens.getAttribute(AntBuildExtenderImplementation.ATTR_FILE));
90
    }
91
92
    public void testRemoveExtension() {
93
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
94
        testAddExtension();
95
        Element el = extenderImpl.newElement;
96
        extenderImpl.oldElement = el;
97
        instance.removeExtension("milos");
98
        el = extenderImpl.newElement;
99
        assertNotNull(el);
100
        NodeList nl = el.getElementsByTagName(AntBuildExtenderImplementation.ELEMENT_EXTENSION);
101
        assertEquals(0, nl.getLength());
102
    }
103
104
    public void testGetExtension() {
105
        AntBuildExtender instance = p.getLookup().lookup(AntBuildExtender.class);
106
        testAddExtension();
107
        AntBuildExtender.Extension ext = instance.getExtension("milos");
108
        assertNotNull(ext);
109
    }
110
    
111
    private class ExtImpl implements AntBuildExtenderImplementation {
112
        Project project;
113
        Element newElement;
114
        Element oldElement;
115
        List<String> targets = Collections.singletonList("all");
116
117
        public List<String> getExtendableTargets() {
118
            return targets;
119
        }
120
121
        public void updateBuildExtensionMetadata(Element element) {
122
            newElement = element;
123
        }
124
125
        public Element getBuildExtensionMetadata() {
126
            return oldElement;
127
        }
128
129
        public Project getOwningProject() {
130
            return project;
131
        }
132
133
    }
134
    
135
}
(-)ant/project/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> getExtendableTargets() {
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
}
(-)ant/project/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