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 75471
Collapse All | Expand All

(-)j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java (-1 / +6 lines)
Lines 25-33 Link Here
25
import org.netbeans.api.project.Project;
25
import org.netbeans.api.project.Project;
26
import org.netbeans.api.project.ProjectInformation;
26
import org.netbeans.api.project.ProjectInformation;
27
import org.netbeans.api.project.ProjectManager;
27
import org.netbeans.api.project.ProjectManager;
28
import org.netbeans.api.project.SourceGroup;
29
import org.netbeans.api.project.Sources;
28
import org.netbeans.api.project.ant.AntArtifact;
30
import org.netbeans.api.project.ant.AntArtifact;
29
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
31
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
30
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathExtender;
32
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathExtender;
33
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathModifier;
31
import org.netbeans.modules.java.j2seproject.queries.CompiledSourceForBinaryQuery;
34
import org.netbeans.modules.java.j2seproject.queries.CompiledSourceForBinaryQuery;
32
import org.netbeans.modules.java.j2seproject.queries.JavadocForBinaryQueryImpl;
35
import org.netbeans.modules.java.j2seproject.queries.JavadocForBinaryQueryImpl;
33
import org.netbeans.modules.java.j2seproject.queries.SourceLevelQueryImpl;
36
import org.netbeans.modules.java.j2seproject.queries.SourceLevelQueryImpl;
Lines 144-149 Link Here
144
147
145
    private Lookup createLookup(AuxiliaryConfiguration aux) {
148
    private Lookup createLookup(AuxiliaryConfiguration aux) {
146
        SubprojectProvider spp = refHelper.createSubprojectProvider();
149
        SubprojectProvider spp = refHelper.createSubprojectProvider();
150
        final J2SEProjectClassPathModifier cpMod = new J2SEProjectClassPathModifier(this, this.updateHelper, eval, refHelper);
147
        return Lookups.fixed(new Object[] {
151
        return Lookups.fixed(new Object[] {
148
            new Info(),
152
            new Info(),
149
            aux,
153
            aux,
Lines 165-171 Link Here
165
            new J2SESharabilityQuery (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
169
            new J2SESharabilityQuery (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
166
            new J2SEFileBuiltQuery (this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
170
            new J2SEFileBuiltQuery (this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
167
            new RecommendedTemplatesImpl (this.updateHelper),
171
            new RecommendedTemplatesImpl (this.updateHelper),
168
            new J2SEProjectClassPathExtender(this, this.updateHelper, eval,refHelper),
172
            new J2SEProjectClassPathExtender(cpMod),
173
            cpMod,
169
            this, // never cast an externally obtained Project to J2SEProject - use lookup instead
174
            this, // never cast an externally obtained Project to J2SEProject - use lookup instead
170
            new J2SEProjectOperations(this),
175
            new J2SEProjectOperations(this),
171
            new J2SEProjectWebServicesSupportProvider()
176
            new J2SEProjectWebServicesSupportProvider()
(-)j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java (-4 / +44 lines)
Lines 19-24 Link Here
19
import java.util.HashMap;
19
import java.util.HashMap;
20
20
21
import org.netbeans.api.java.classpath.ClassPath;
21
import org.netbeans.api.java.classpath.ClassPath;
22
import org.netbeans.api.project.SourceGroup;
22
import org.netbeans.spi.java.classpath.ClassPathFactory;
23
import org.netbeans.spi.java.classpath.ClassPathFactory;
23
import org.netbeans.spi.java.classpath.ClassPathProvider;
24
import org.netbeans.spi.java.classpath.ClassPathProvider;
24
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
25
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
Lines 38-43 Link Here
38
    private static final String DIST_JAR = "dist.jar"; // NOI18N
39
    private static final String DIST_JAR = "dist.jar"; // NOI18N
39
    private static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N
40
    private static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N
40
    
41
    
42
    private static final String JAVAC_CLASSPATH = "javac.classpath";    //NOI18N
43
    private static final String JAVAC_TEST_CLASSPATH = "javac.test.classpath";  //NOI18N
44
    private static final String RUN_CLASSPATH = "run.classpath";    //NOI18N
45
    private static final String RUN_TEST_CLASSPATH = "run.test.classpath";  //NOI18N
46
    
47
    
41
    private final AntProjectHelper helper;
48
    private final AntProjectHelper helper;
42
    private final File projectDirectory;
49
    private final File projectDirectory;
43
    private final PropertyEvaluator evaluator;
50
    private final PropertyEvaluator evaluator;
Lines 149-160 Link Here
149
            if (type == 0) {
156
            if (type == 0) {
150
                cp = ClassPathFactory.createClassPath(
157
                cp = ClassPathFactory.createClassPath(
151
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
158
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
152
                    projectDirectory, evaluator, new String[] {"javac.classpath"})); // NOI18N
159
                    projectDirectory, evaluator, new String[] {JAVAC_CLASSPATH})); // NOI18N
153
            }
160
            }
154
            else {
161
            else {
155
                cp = ClassPathFactory.createClassPath(
162
                cp = ClassPathFactory.createClassPath(
156
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
163
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
157
                    projectDirectory, evaluator, new String[] {"javac.test.classpath"})); // NOI18N
164
                    projectDirectory, evaluator, new String[] {JAVAC_TEST_CLASSPATH})); // NOI18N
158
            }
165
            }
159
            cache[2+type] = cp;
166
            cache[2+type] = cp;
160
        }
167
        }
Lines 177-188 Link Here
177
            if (type == 0) {
184
            if (type == 0) {
178
                cp = ClassPathFactory.createClassPath(
185
                cp = ClassPathFactory.createClassPath(
179
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
186
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
180
                    projectDirectory, evaluator, new String[] {"run.classpath"})); // NOI18N
187
                    projectDirectory, evaluator, new String[] {RUN_CLASSPATH})); // NOI18N
181
            }
188
            }
182
            else if (type == 1) {
189
            else if (type == 1) {
183
                cp = ClassPathFactory.createClassPath(
190
                cp = ClassPathFactory.createClassPath(
184
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
191
                    ProjectClassPathSupport.createPropertyBasedClassPathImplementation(
185
                    projectDirectory, evaluator, new String[] {"run.test.classpath"})); // NOI18N
192
                    projectDirectory, evaluator, new String[] {RUN_TEST_CLASSPATH})); // NOI18N
186
            }
193
            }
187
            else if (type == 2) {
194
            else if (type == 2) {
188
                //Only to make the CompiledDataNode hapy
195
                //Only to make the CompiledDataNode hapy
Lines 269-274 Link Here
269
276
270
    public synchronized void propertyChange(PropertyChangeEvent evt) {
277
    public synchronized void propertyChange(PropertyChangeEvent evt) {
271
        dirCache.remove(evt.getPropertyName());
278
        dirCache.remove(evt.getPropertyName());
279
    }
280
    
281
    public String getPropertyName (SourceGroup sg, String classPathId) {
282
        FileObject root = sg.getRootFolder();
283
        FileObject[] path = getPrimarySrcPath();
284
        for (int i=0; i<path.length; i++) {
285
            if (root.equals(path[i])) {
286
                if (ClassPath.COMPILE.equals(classPathId)) {
287
                    return JAVAC_CLASSPATH;
288
                }
289
                else if (ClassPath.EXECUTE.equals(classPathId)) {
290
                    return RUN_CLASSPATH;
291
                }
292
                else {
293
                    return null;
294
                }
295
            }
296
        }
297
        path = getTestSrcDir();
298
        for (int i=0; i<path.length; i++) {
299
            if (root.equals(path[i])) {
300
                if (ClassPath.COMPILE.equals(classPathId)) {
301
                    return JAVAC_TEST_CLASSPATH;
302
                }
303
                else if (ClassPath.EXECUTE.equals(classPathId)) {
304
                    return RUN_TEST_CLASSPATH;
305
                }
306
                else {
307
                    return null;
308
                }
309
            }
310
        }
311
        return null;
272
    }
312
    }
273
    
313
    
274
}
314
}
(-)j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/J2SEProjectClassPathExtender.java (-113 / +11 lines)
Lines 15-20 Link Here
15
import java.io.IOException;
15
import java.io.IOException;
16
import java.io.File;
16
import java.io.File;
17
import java.net.URI;
17
import java.net.URI;
18
import java.net.URL;
18
import java.util.List;
19
import java.util.List;
19
import org.netbeans.modules.java.j2seproject.ui.customizer.AntArtifactChooser;
20
import org.netbeans.modules.java.j2seproject.ui.customizer.AntArtifactChooser;
20
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
21
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
Lines 39-63 Link Here
39
    
40
    
40
    private static final String CP_CLASS_PATH = "javac.classpath"; //NOI18N
41
    private static final String CP_CLASS_PATH = "javac.classpath"; //NOI18N
41
42
42
    private Project project;
43
    private final J2SEProjectClassPathModifier delegate;
43
    private UpdateHelper helper;
44
    private ReferenceHelper refHelper;
45
    private PropertyEvaluator eval;
46
    
47
    
48
    private ClassPathSupport cs;
49
44
50
    public J2SEProjectClassPathExtender (Project project, UpdateHelper helper, PropertyEvaluator eval, ReferenceHelper refHelper) {
45
    public J2SEProjectClassPathExtender (final J2SEProjectClassPathModifier delegate) {
51
        this.project = project;
46
        assert delegate != null;
52
        this.helper = helper;
47
        this.delegate = delegate;
53
        this.eval = eval;
54
        this.refHelper = refHelper;
55
        
56
        this.cs = new ClassPathSupport( eval, refHelper, helper.getAntProjectHelper(), 
57
                                        J2SEProjectProperties.WELL_KNOWN_PATHS, 
58
                                        J2SEProjectProperties.LIBRARY_PREFIX, 
59
                                        J2SEProjectProperties.LIBRARY_SUFFIX, 
60
                                        J2SEProjectProperties.ANT_ARTIFACT_PREFIX );        
61
    }
48
    }
62
49
63
    public boolean addLibrary(final Library library) throws IOException {
50
    public boolean addLibrary(final Library library) throws IOException {
Lines 65-141 Link Here
65
    }
52
    }
66
53
67
    public boolean addLibrary(final String classPathId, final Library library) throws IOException {
54
    public boolean addLibrary(final String classPathId, final Library library) throws IOException {
68
        assert library != null : "Parameter cannot be null";       //NOI18N
55
        return this.delegate.handleLibraries (new Library[] {library},classPathId, J2SEProjectClassPathModifier.ADD);
69
        try {
70
            return ((Boolean)ProjectManager.mutex().writeAccess(
71
                    new Mutex.ExceptionAction () {
72
                        public Object run() throws IOException {
73
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
74
                            String raw = props.getProperty(classPathId);
75
                            List resources = cs.itemsList( raw );
76
                            ClassPathSupport.Item item = ClassPathSupport.Item.create( library, null );
77
                            if (!resources.contains(item)) {
78
                                resources.add (item);                                
79
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );                                
80
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);    //PathParser may change the EditableProperties                                
81
                                props.setProperty(classPathId, itemRefs);                                
82
                                String prop = cs.getLibraryReference( item );
83
                                prop = prop.substring(2, prop.length()-1); // XXX make a PropertyUtils method for this!
84
                                ClassPathSupport.relativizeLibraryClassPath(props, helper.getAntProjectHelper(), prop);                                
85
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
86
                                ProjectManager.getDefault().saveProject(project);
87
                                return Boolean.TRUE;
88
                            }
89
                            return Boolean.FALSE;
90
                        }
91
                    }
92
            )).booleanValue();
93
        } catch (MutexException e) {
94
            throw (IOException) e.getException();
95
        }
96
    }
56
    }
97
57
98
    public boolean addArchiveFile(final FileObject archiveFile) throws IOException {
58
    public boolean addArchiveFile(final FileObject archiveFile) throws IOException {
99
        return addArchiveFile(CP_CLASS_PATH,archiveFile);
59
        return addArchiveFile(CP_CLASS_PATH,archiveFile);
100
    }
60
    }
101
61
102
    public boolean addArchiveFile(final String classPathId, final FileObject archiveFile) throws IOException {
62
    public boolean addArchiveFile(final String classPathId, FileObject archiveFile) throws IOException {
103
        assert archiveFile != null : "Parameter cannot be null";       //NOI18N
63
        if (FileUtil.isArchiveFile(archiveFile)) {
104
        try {
64
            archiveFile = FileUtil.getArchiveRoot (archiveFile);
105
            return ((Boolean)ProjectManager.mutex().writeAccess(
106
                    new Mutex.ExceptionAction () {
107
                        public Object run() throws Exception {
108
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
109
                            String raw = props.getProperty(classPathId);                            
110
                            List resources = cs.itemsList( raw );                                                        
111
                            File f = FileUtil.toFile (archiveFile);
112
                            if (f == null ) {
113
                                throw new IllegalArgumentException ("The file must exist on disk");     //NOI18N
114
                            }
115
                            ClassPathSupport.Item item = ClassPathSupport.Item.create( f, null );
116
117
                            if (!resources.contains(item)) {
118
                                resources.add (item);
119
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );
120
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);  //PathParser may change the EditableProperties
121
                                props.setProperty(classPathId, itemRefs);
122
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
123
                                ProjectManager.getDefault().saveProject(project);
124
                                return Boolean.TRUE;
125
                            }
126
                            return Boolean.FALSE;
127
                        }
128
                    }
129
            )).booleanValue();
130
        } catch (Exception e) {
131
            if (e instanceof IOException) {
132
                throw (IOException) e;
133
            }
134
            else {
135
                Exception t = new IOException ();
136
                throw (IOException) ErrorManager.getDefault().annotate(t,e);
137
            }
138
        }
65
        }
66
        return this.delegate.handleRoots(new URL[] {archiveFile.getURL()},classPathId,J2SEProjectClassPathModifier.ADD);
139
    }
67
    }
140
68
141
    public boolean addAntArtifact(final AntArtifact artifact, final URI artifactElement) throws IOException {
69
    public boolean addAntArtifact(final AntArtifact artifact, final URI artifactElement) throws IOException {
Lines 143-179 Link Here
143
    }
71
    }
144
72
145
    public boolean addAntArtifact(final String classPathId, final AntArtifact artifact, final URI artifactElement) throws IOException {
73
    public boolean addAntArtifact(final String classPathId, final AntArtifact artifact, final URI artifactElement) throws IOException {
146
        assert artifact != null : "Parameter cannot be null";       //NOI18N
74
        return this.delegate.handleAntArtifacts(new AntArtifact[] {artifact}, new URI[] {artifactElement},classPathId,J2SEProjectClassPathModifier.ADD);
147
        try {
148
            return ((Boolean)ProjectManager.mutex().writeAccess(
149
                    new Mutex.ExceptionAction () {
150
                        public Object run() throws Exception {
151
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
152
                            String raw = props.getProperty (classPathId);
153
                            List resources = cs.itemsList( raw );
154
                            ClassPathSupport.Item item = ClassPathSupport.Item.create( artifact, artifactElement, null );                            
155
                            if (!resources.contains(item)) {
156
                                resources.add (item);
157
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );                                
158
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);    //Reread the properties, PathParser changes them
159
                                props.setProperty (classPathId, itemRefs);
160
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
161
                                ProjectManager.getDefault().saveProject(project);
162
                                return Boolean.TRUE;
163
                            }
164
                            return Boolean.FALSE;
165
                        }
166
                    }
167
            )).booleanValue();
168
        } catch (Exception e) {
169
            if (e instanceof IOException) {
170
                throw (IOException) e;
171
            }
172
            else {
173
                Exception t = new IOException ();
174
                throw (IOException) ErrorManager.getDefault().annotate(t,e);
175
            }
176
        }
177
    }
75
    }
178
76
179
}
77
}
(-)j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/J2SEProjectClassPathModifier.java (+276 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.modules.java.j2seproject.classpath;
15
16
import java.beans.PropertyChangeListener;
17
import java.io.File;
18
import java.io.IOException;
19
import java.net.URI;
20
import java.net.URL;
21
import java.util.ArrayList;
22
import java.util.Iterator;
23
import java.util.List;
24
import javax.swing.Icon;
25
import org.netbeans.api.java.classpath.ClassPath;
26
import org.netbeans.api.java.project.JavaProjectConstants;
27
import org.netbeans.api.project.Project;
28
import org.netbeans.api.project.ProjectManager;
29
import org.netbeans.api.project.SourceGroup;
30
import org.netbeans.api.project.Sources;
31
import org.netbeans.api.project.ant.AntArtifact;
32
import org.netbeans.api.project.libraries.Library;
33
import org.netbeans.modules.java.j2seproject.UpdateHelper;
34
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
35
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
36
import org.netbeans.spi.project.support.ant.AntProjectHelper;
37
import org.netbeans.spi.project.support.ant.EditableProperties;
38
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
39
import org.netbeans.spi.project.support.ant.ReferenceHelper;
40
import org.openide.ErrorManager;
41
import org.openide.filesystems.FileObject;
42
import org.openide.filesystems.FileUtil;
43
import org.openide.util.Mutex;
44
import org.openide.util.MutexException;
45
46
/**
47
 *@author Tomas Zezula
48
 *
49
 */
50
public class J2SEProjectClassPathModifier extends ProjectClassPathModifierImplementation {
51
    
52
    static final int ADD = 1;
53
    static final int REMOVE = 2;
54
    
55
    private final Project project;
56
    private final UpdateHelper helper;
57
    private final ReferenceHelper refHelper;
58
    private final PropertyEvaluator eval;    
59
    private final ClassPathSupport cs;    
60
    
61
    /** Creates a new instance of J2SEProjectClassPathModifier */
62
    public J2SEProjectClassPathModifier(final Project project, final UpdateHelper helper, final PropertyEvaluator eval, final ReferenceHelper refHelper) {
63
        assert project != null;
64
        assert helper != null;
65
        assert eval != null;
66
        assert refHelper != null;
67
        this.project = project;
68
        this.helper = helper;
69
        this.eval = eval;
70
        this.refHelper = refHelper;        
71
        this.cs = new ClassPathSupport( eval, refHelper, helper.getAntProjectHelper(), 
72
                                        J2SEProjectProperties.WELL_KNOWN_PATHS, 
73
                                        J2SEProjectProperties.LIBRARY_PREFIX, 
74
                                        J2SEProjectProperties.LIBRARY_SUFFIX, 
75
                                        J2SEProjectProperties.ANT_ARTIFACT_PREFIX );
76
    }
77
    
78
    protected SourceGroup[] getExtensibleSourceGroups() {
79
        Sources s = (Sources) this.project.getLookup().lookup(Sources.class);
80
        assert s != null;
81
        return s.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
82
    }
83
    
84
    protected String[] getExtensibleClassPathTypes (SourceGroup sg) {
85
        return new String[] {
86
            ClassPath.COMPILE,
87
            ClassPath.EXECUTE
88
        };
89
    }
90
91
    protected boolean removeRoots(final URL[] classPathRoots, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {
92
        return handleRoots (classPathRoots, getClassPathProperty(sourceGroup, classPathId), REMOVE);
93
    }
94
95
    protected boolean addRoots (final URL[] classPathRoots, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {        
96
        return handleRoots (classPathRoots, getClassPathProperty(sourceGroup, classPathId), ADD);
97
    }
98
    
99
    boolean handleRoots (final URL[] classPathRoots, final String classPathProperty, final int operation) throws IOException, UnsupportedOperationException {
100
        assert classPathRoots != null : "The classPathRoots cannot be null";      //NOI18N        
101
        assert classPathProperty != null;
102
        try {
103
            return ((Boolean)ProjectManager.mutex().writeAccess(
104
                    new Mutex.ExceptionAction () {
105
                        public Object run() throws Exception {
106
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
107
                            String raw = props.getProperty(classPathProperty);                            
108
                            List resources = cs.itemsList( raw );
109
                            boolean changed = false;
110
                            for (int i=0; i< classPathRoots.length; i++) {
111
                                assert classPathRoots[i] != null;
112
                                assert classPathRoots[i].toExternalForm().endsWith("/");    //NOI18N
113
                                URL toAdd = FileUtil.getArchiveFile(classPathRoots[i]);
114
                                if (toAdd == null) {
115
                                    toAdd = classPathRoots[i];
116
                                }
117
                                File f = FileUtil.normalizeFile( new File (URI.create(toAdd.toExternalForm())));
118
                                if (f == null ) {
119
                                    throw new IllegalArgumentException ("The file must exist on disk");     //NOI18N
120
                                }
121
                                ClassPathSupport.Item item = ClassPathSupport.Item.create( f, null );
122
                                if (operation == ADD && !resources.contains(item)) {
123
                                    resources.add (item);
124
                                    changed = true;
125
                                }                            
126
                                else if (operation == REMOVE && resources.contains(item)) {
127
                                    resources.remove(item);
128
                                    changed = true;
129
                                }
130
                            }                                                                                                                
131
                            if (changed) {
132
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );
133
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);  //PathParser may change the EditableProperties
134
                                props.setProperty(classPathProperty, itemRefs);
135
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
136
                                ProjectManager.getDefault().saveProject(project);
137
                                return Boolean.TRUE;
138
                            }
139
                            return Boolean.FALSE;
140
                        }
141
                    }
142
            )).booleanValue();
143
        } catch (Exception e) {
144
            if (e instanceof IOException) {
145
                throw (IOException) e;
146
            }
147
            else {
148
                Exception t = new IOException ();
149
                throw (IOException) ErrorManager.getDefault().annotate(t,e);
150
            }
151
        }
152
    }
153
154
    protected boolean removeAntArtifacts(final AntArtifact[] artifacts, final URI[] artifactElements, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {
155
        return handleAntArtifacts (artifacts, artifactElements, getClassPathProperty(sourceGroup, classPathId), REMOVE);
156
    }
157
158
    protected boolean addAntArtifacts(final AntArtifact[] artifacts, final URI[] artifactElements, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {
159
        return handleAntArtifacts (artifacts, artifactElements, getClassPathProperty(sourceGroup, classPathId), ADD);
160
    }
161
    
162
    boolean handleAntArtifacts (final AntArtifact[] artifacts, final URI[] artifactElements, final String classPathProperty, final int operation) throws IOException, UnsupportedOperationException {
163
        assert artifacts != null : "Artifacts cannot be null";    //NOI18N
164
        assert artifactElements != null : "ArtifactElements cannot be null";  //NOI18N
165
        assert artifacts.length == artifactElements.length : "Each artifact has to have corresponding artifactElement"; //NOI18N
166
        assert classPathProperty != null;
167
        try {
168
            return ((Boolean)ProjectManager.mutex().writeAccess(
169
                    new Mutex.ExceptionAction () {
170
                        public Object run() throws Exception {
171
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
172
                            String raw = props.getProperty (classPathProperty);
173
                            List resources = cs.itemsList( raw );
174
                            boolean changed = false;
175
                            for (int i=0; i<artifacts.length; i++) {
176
                                assert artifacts[i] != null;
177
                                assert artifactElements[i] != null;
178
                                ClassPathSupport.Item item = ClassPathSupport.Item.create( artifacts[i], artifactElements[i], null );
179
                                if (operation == ADD && !resources.contains(item)) {
180
                                    resources.add (item);
181
                                    changed = true;
182
                                }
183
                                else if (operation == REMOVE && resources.contains(item)) {
184
                                    resources.remove(item);
185
                                    changed = true;
186
                                }
187
                            }                            
188
                            if (changed) {
189
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );                                
190
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);    //Reread the properties, PathParser changes them
191
                                props.setProperty (classPathProperty, itemRefs);
192
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
193
                                ProjectManager.getDefault().saveProject(project);
194
                                return Boolean.TRUE;
195
                            }
196
                            return Boolean.FALSE;
197
                        }
198
                    }
199
            )).booleanValue();
200
        } catch (Exception e) {
201
            if (e instanceof IOException) {
202
                throw (IOException) e;
203
            }
204
            else {
205
                Exception t = new IOException ();
206
                throw (IOException) ErrorManager.getDefault().annotate(t,e);
207
            }
208
        }
209
    }
210
    
211
    
212
    protected boolean removeLibraries(final Library[] libraries, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {
213
        return handleLibraries (libraries, getClassPathProperty(sourceGroup, classPathId), REMOVE);
214
    }
215
216
    protected boolean addLibraries(final Library[] libraries, final SourceGroup sourceGroup, final String classPathId) throws IOException, UnsupportedOperationException {
217
        return handleLibraries (libraries, getClassPathProperty(sourceGroup, classPathId), ADD);
218
    }
219
    
220
    boolean handleLibraries (final Library[] libraries, final String classPathProperty, final int operation) throws IOException, UnsupportedOperationException {
221
        assert libraries != null : "Libraries cannot be null";  //NOI18N
222
        assert classPathProperty != null;
223
        try {
224
            return ((Boolean)ProjectManager.mutex().writeAccess(
225
                    new Mutex.ExceptionAction () {
226
                        public Object run() throws IOException {
227
                            EditableProperties props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);
228
                            String raw = props.getProperty(classPathProperty);
229
                            List resources = cs.itemsList( raw );
230
                            List/*<ClassPathSupport.Item>*/ changed = new ArrayList/*<ClassPathSupport.Item>*/ (libraries.length);
231
                            for (int i=0; i< libraries.length; i++) {
232
                                assert libraries[i] != null;
233
                                ClassPathSupport.Item item = ClassPathSupport.Item.create( libraries[i], null );
234
                                if (operation == ADD && !resources.contains(item)) {
235
                                    resources.add (item);                                
236
                                    changed.add(item);
237
                                }
238
                                else if (operation == REMOVE && resources.contains(item)) {
239
                                    resources.remove(item);
240
                                    changed.add(item);
241
                                }
242
                            }
243
                            if (!changed.isEmpty()) {
244
                                String itemRefs[] = cs.encodeToStrings( resources.iterator() );                                
245
                                props = helper.getProperties (AntProjectHelper.PROJECT_PROPERTIES_PATH);    //PathParser may change the EditableProperties                                
246
                                props.setProperty(classPathProperty, itemRefs);                                
247
                                if (operation == ADD) {
248
                                    for (Iterator/*<ClassPathSupport.Item>*/ it = changed.iterator(); it.hasNext();) {
249
                                        String prop = cs.getLibraryReference( (ClassPathSupport.Item) it.next() );
250
                                        prop = prop.substring(2, prop.length()-1); // XXX make a PropertyUtils method for this!
251
                                        ClassPathSupport.relativizeLibraryClassPath(props, helper.getAntProjectHelper(), prop);
252
                                    }
253
                                }
254
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
255
                                ProjectManager.getDefault().saveProject(project);
256
                                return Boolean.TRUE;
257
                            }
258
                            return Boolean.FALSE;
259
                        }
260
                    }
261
            )).booleanValue();
262
        } catch (MutexException e) {
263
            throw (IOException) e.getException();
264
        }
265
    }
266
    
267
    private String getClassPathProperty (final SourceGroup sg, final String classPathId) throws UnsupportedOperationException {
268
        assert sg != null : "SourceGroup cannot be null";  //NOI18N
269
        assert classPathId != null : "ClassPathId cannot be null";  //NOI18N
270
        final String classPathProperty = ((ClassPathProviderImpl)project.getLookup().lookup(ClassPathProviderImpl.class)).getPropertyName (sg, classPathId);
271
        if (classPathProperty == null) {
272
            throw new UnsupportedOperationException ("Modification of [" + sg.getRootFolder().getPath() +", " + classPathId + "] is not supported"); //NOI8N
273
        }
274
        return classPathProperty;
275
    }
276
}
(-)j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/classpath/J2SEProjectClassPathModifierTest.java (+324 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
package org.netbeans.modules.java.j2seproject.classpath;
14
15
import java.beans.Customizer;
16
import java.beans.PropertyChangeListener;
17
import java.io.OutputStream;
18
import java.net.URL;
19
import java.util.Arrays;
20
import java.util.Collections;
21
import java.util.jar.JarFile;
22
import java.util.jar.JarOutputStream;
23
import java.util.zip.ZipEntry;
24
import java.util.zip.ZipOutputStream;
25
import junit.framework.*;
26
import java.io.File;
27
import java.io.IOException;
28
import java.net.URI;
29
import java.util.List;
30
import org.netbeans.api.java.classpath.ClassPath;
31
import org.netbeans.api.java.project.JavaProjectConstants;
32
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
33
import org.netbeans.api.project.FileOwnerQuery;
34
import org.netbeans.api.project.Project;
35
import org.netbeans.api.project.ProjectManager;
36
import org.netbeans.api.project.SourceGroup;
37
import org.netbeans.api.project.Sources;
38
import org.netbeans.api.project.TestUtil;
39
import org.netbeans.api.project.ant.AntArtifact;
40
import org.netbeans.api.project.libraries.Library;
41
import org.netbeans.api.project.libraries.LibraryManager;
42
import org.netbeans.junit.NbTestCase;
43
import org.netbeans.modules.java.j2seproject.J2SEProjectGenerator;
44
import org.netbeans.modules.java.j2seproject.UpdateHelper;
45
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
46
import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
47
import org.netbeans.spi.project.ant.AntArtifactProvider;
48
import org.netbeans.spi.project.libraries.LibraryImplementation;
49
import org.netbeans.spi.project.libraries.LibraryProvider;
50
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
51
import org.netbeans.spi.project.support.ant.AntProjectHelper;
52
import org.netbeans.spi.project.support.ant.EditableProperties;
53
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
54
import org.netbeans.spi.project.support.ant.PropertyUtils;
55
import org.netbeans.spi.project.support.ant.ReferenceHelper;
56
import org.openide.ErrorManager;
57
import org.openide.filesystems.FileLock;
58
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileUtil;
60
import org.openide.modules.SpecificationVersion;
61
import org.openide.util.Lookup;
62
import org.openide.util.Mutex;
63
import org.openide.util.MutexException;
64
65
/**
66
 *
67
 * @author tom
68
 */
69
public class J2SEProjectClassPathModifierTest extends NbTestCase {
70
    
71
    private FileObject scratch;
72
    private AntProjectHelper helper;
73
    private PropertyEvaluator eval;
74
    private FileObject src;
75
    private FileObject test;
76
    private Project prj;
77
    
78
    public J2SEProjectClassPathModifierTest(String testName) {
79
        super(testName);
80
    }       
81
    
82
    protected void setUp() throws Exception {
83
        super.setUp();
84
        TestUtil.setLookup(new Object[] {
85
            new org.netbeans.modules.java.j2seproject.J2SEProjectType(),
86
            new org.netbeans.modules.projectapi.SimpleFileOwnerQueryImplementation(),
87
            new TestLibraryProvider (),
88
        });
89
        this.scratch = TestUtil.makeScratchDir(this);
90
        FileObject projdir = scratch.createFolder("proj");  //NOI18N
91
        J2SEProjectGenerator.setDefaultSourceLevel(new SpecificationVersion ("1.4"));   //NOI18N    
92
        this.helper = J2SEProjectGenerator.createProject(FileUtil.toFile(projdir),"proj",null,null); //NOI18N
93
        this.eval = this.helper.getStandardPropertyEvaluator();
94
        J2SEProjectGenerator.setDefaultSourceLevel(null);
95
        this.prj = FileOwnerQuery.getOwner(projdir);
96
        assertNotNull (this.prj);
97
        this.src = projdir.getFileObject("src");
98
        assertNotNull (this.src);
99
        this.test = projdir.getFileObject("test");
100
        assertNotNull (this.test);
101
        
102
    }
103
104
    protected void tearDown() throws Exception {
105
    }
106
    
107
    public void testAddRemoveRoot () throws Exception {        
108
        final FileObject rootFolder = this.scratch.createFolder("Root");
109
        final FileObject jarFile = this.scratch.createData("archive","jar");
110
        FileLock lck = jarFile.lock();
111
        try {
112
            ZipOutputStream jf = new ZipOutputStream (jarFile.getOutputStream(lck));            
113
            try {
114
                jf.putNextEntry(new ZipEntry("Test.properties"));
115
            }finally {
116
                jf.close();
117
            }
118
        } finally {
119
            lck.releaseLock();
120
        }
121
        final FileObject jarRoot = FileUtil.getArchiveRoot(jarFile);
122
        ProjectClassPathModifier.addRoots (new URL[] {rootFolder.getURL()}, this.src, ClassPath.COMPILE);
123
        String cp = this.eval.getProperty("javac.classpath");
124
        assertNotNull (cp);
125
        String[] cpRoots = PropertyUtils.tokenizePath (cp);
126
        assertNotNull (cpRoots);
127
        assertEquals(1,cpRoots.length);
128
        assertEquals(rootFolder,this.helper.resolveFileObject(cpRoots[0]));
129
        ProjectClassPathModifier.removeRoots (new URL[] {rootFolder.getURL()},this.src, ClassPath.COMPILE);
130
        cp = this.eval.getProperty("javac.classpath");
131
        assertNotNull (cp);
132
        cpRoots = PropertyUtils.tokenizePath (cp);
133
        assertNotNull (cpRoots);
134
        assertEquals(0,cpRoots.length);
135
        ProjectClassPathModifier.addRoots(new URL[] {jarRoot.getURL()},this.test,ClassPath.EXECUTE);
136
        cp = this.eval.getProperty("run.test.classpath");
137
        assertNotNull (cp);
138
        cpRoots = PropertyUtils.tokenizePath (cp);
139
        assertNotNull (cpRoots);
140
        assertEquals(4,cpRoots.length);
141
        assertEquals(this.helper.resolveFileObject(cpRoots[3]),jarFile);
142
    }
143
    
144
    public void testAddRemoveArtifact () throws Exception {
145
        FileObject projdir = scratch.createFolder("libPrj");  //NOI18N
146
        J2SEProjectGenerator.setDefaultSourceLevel(new SpecificationVersion ("1.4"));   //NOI18N    
147
        AntProjectHelper helper = J2SEProjectGenerator.createProject(FileUtil.toFile(projdir),"libProj",null,null); //NOI18N        
148
        J2SEProjectGenerator.setDefaultSourceLevel(null);
149
        Project libPrj = FileOwnerQuery.getOwner(projdir);
150
        assertNotNull (this.prj);
151
        AntArtifactProvider ap = (AntArtifactProvider) libPrj.getLookup().lookup(AntArtifactProvider.class);
152
        AntArtifact[] aas = ap.getBuildArtifacts();
153
        AntArtifact output = null;
154
        for (int i=0; i<aas.length; i++) {
155
            if (JavaProjectConstants.ARTIFACT_TYPE_JAR.equals(aas[i].getType())) {
156
                output = aas[i];
157
                break;
158
            }
159
        }
160
        assertNotNull (output);
161
        ProjectClassPathModifier.addAntArtifacts(new AntArtifact[] {output}, new URI[] {output.getArtifactLocations()[0]}, this.src, ClassPath.COMPILE);
162
        String cp = this.eval.getProperty("javac.classpath");
163
        assertNotNull (cp);
164
        String[] cpRoots = PropertyUtils.tokenizePath (cp);
165
        assertNotNull (cpRoots);
166
        assertEquals(1,cpRoots.length);
167
        URI projectURI = URI.create(output.getProject().getProjectDirectory().getURL().toExternalForm());
168
        URI expected = projectURI.resolve(output.getArtifactLocations()[0]);
169
        assertEquals(expected,this.helper.resolveFile(cpRoots[0]).toURI());
170
        ProjectClassPathModifier.removeAntArtifacts(new AntArtifact[] {output}, new URI[] {output.getArtifactLocations()[0]},this.src, ClassPath.COMPILE);
171
        cp = this.eval.getProperty("javac.classpath");
172
        assertNotNull (cp);
173
        cpRoots = PropertyUtils.tokenizePath (cp);
174
        assertNotNull (cpRoots);
175
        assertEquals(0,cpRoots.length);
176
    }
177
    
178
    public void testAddRemoveLibrary () throws Exception {
179
        LibraryProvider lp = (LibraryProvider) Lookup.getDefault().lookup(LibraryProvider.class);
180
        assertNotNull (lp);
181
        LibraryImplementation[] impls = lp.getLibraries();
182
        assertNotNull (impls);
183
        assertEquals(1,impls.length);
184
        FileObject libRoot = this.scratch.createFolder("libRoot");
185
        impls[0].setContent("classpath",Collections.singletonList(libRoot.getURL()));
186
        Library[] libs =LibraryManager.getDefault().getLibraries();
187
        assertNotNull (libs);
188
        assertEquals(1,libs.length);                       
189
        ProjectClassPathModifier.addLibraries(libs, this.src, ClassPath.COMPILE);
190
        String cp = this.eval.getProperty("javac.classpath");
191
        assertNotNull (cp);
192
        String[] cpRoots = PropertyUtils.tokenizePath (cp);
193
        assertNotNull (cpRoots);
194
        assertEquals(1,cpRoots.length);
195
        assertEquals("${libs.Test.classpath}",cpRoots[0]);    //There is no build.properties filled, the libraries are not resolved
196
        ProjectClassPathModifier.removeLibraries(libs,this.src, ClassPath.COMPILE);
197
        cp = this.eval.getProperty("javac.classpath");
198
        assertNotNull (cp);
199
        cpRoots = PropertyUtils.tokenizePath (cp);
200
        assertNotNull (cpRoots);
201
        assertEquals(0,cpRoots.length);
202
    }
203
    
204
    public void testClassPathExtenderCompatibility () throws Exception {
205
        final FileObject rootFolder = this.scratch.createFolder("Root");
206
        final FileObject jarFile = this.scratch.createData("archive","jar");
207
        FileLock lck = jarFile.lock();
208
        try {
209
            ZipOutputStream jf = new ZipOutputStream (jarFile.getOutputStream(lck));            
210
            try {
211
                jf.putNextEntry(new ZipEntry("Test.properties"));
212
            }finally {
213
                jf.close();
214
            }
215
        } finally {
216
            lck.releaseLock();
217
        }
218
        final FileObject jarRoot = FileUtil.getArchiveRoot(jarFile);
219
        ProjectClassPathExtender extender = (ProjectClassPathExtender) this.prj.getLookup().lookup(ProjectClassPathExtender.class);
220
        assertNotNull (extender);
221
        extender.addArchiveFile(rootFolder);
222
        extender.addArchiveFile(jarFile);
223
        String cp = this.eval.getProperty("javac.classpath");
224
        assertNotNull (cp);
225
        String[] cpRoots = PropertyUtils.tokenizePath (cp);
226
        assertNotNull (cpRoots);
227
        assertEquals(2,cpRoots.length);
228
        assertEquals(rootFolder,this.helper.resolveFileObject(cpRoots[0]));
229
        assertEquals(jarFile,this.helper.resolveFileObject(cpRoots[1]));
230
    }
231
    
232
    
233
    private static class TestLibraryProvider implements LibraryProvider {
234
        
235
        private LibraryImplementation[] libs;
236
        
237
        public void removePropertyChangeListener(PropertyChangeListener listener) {
238
        }
239
240
        public void addPropertyChangeListener(PropertyChangeListener listener) {
241
        }
242
243
        public LibraryImplementation[] getLibraries() {
244
            if (libs == null) {
245
                this.libs = new LibraryImplementation[] { new TestLibrary ("Test")};
246
            }
247
            return this.libs;
248
        }
249
        
250
    }    
251
    
252
    private static class TestLibrary implements LibraryImplementation {
253
        
254
        private String name;
255
        private List cp = Collections.EMPTY_LIST;
256
        private List src = Collections.EMPTY_LIST;
257
        private List jdoc = Collections.EMPTY_LIST;
258
        
259
        public TestLibrary (String name) {
260
            this.name = name;
261
        }
262
        
263
        public void setName(String name) {
264
        }
265
266
        public void setLocalizingBundle(String resourceName) {
267
        }
268
269
        public void setDescription(String text) {
270
        }
271
272
        public List getContent(String volumeType) throws IllegalArgumentException {
273
            if ("classpath".equals(volumeType)) {
274
                return this.cp; 
275
            }
276
            else if ("src".equals(volumeType)) {
277
                return this.src;
278
            }
279
            else if ("jdoc".equals(volumeType)) {
280
                return this.jdoc;
281
            }
282
            throw new IllegalArgumentException ();
283
        }
284
285
        public void removePropertyChangeListener(PropertyChangeListener l) {
286
        }
287
288
        public void addPropertyChangeListener(PropertyChangeListener l) {
289
        }
290
291
        public void setContent(String volumeType, List path) throws IllegalArgumentException {
292
            if ("classpath".equals(volumeType)) {
293
                this.cp = path;
294
            }
295
            else if ("src".equals(volumeType)) {
296
                this.src = path;
297
            }
298
            else if ("jdoc".equals(volumeType)) {
299
                this.jdoc = path;
300
            }
301
            else {
302
                throw new IllegalArgumentException ();
303
            }
304
        }
305
306
        public String getType() {
307
            return "j2se";
308
        }
309
310
        public String getName() {
311
            return this.name;
312
        }
313
314
        public String getLocalizingBundle() {
315
            return null;
316
        }
317
318
        public String getDescription() {
319
            return null;
320
        }
321
        
322
    }
323
    
324
}
(-)project/apichanges.xml (+23 lines)
Lines 77-82 Link Here
77
    <!-- ACTUAL CHANGES BEGIN HERE: -->
77
    <!-- ACTUAL CHANGES BEGIN HERE: -->
78
78
79
    <changes>
79
    <changes>
80
    <change id="ProjectClassPathModifier">
81
        <api name="classpath"/>
82
        <summary>New ProjectClassPathModifier API/SPI for modification of project's classpath</summary>
83
        <version major="1" minor="10"/>
84
        <date day="15" month="5" year="2006"/>
85
        <author login="tzezula"/>
86
        <compatibility addition="yes"/>
87
        <description>
88
        The new SPI interface ProjectClassPathModifierImplementation was created to allow extension modules to
89
        add or remove classpath elements (archive files, folders, libraries, subprojects) from the
90
        project's classpath. The ProjectClassPathModifierImplementation is provided by the project types in the
91
        project's Lookup. The API client uses the static methods of ProjectClassPathModifier which delegate to
92
        the SPI.
93
        </description>
94
        <class package="org.netbeans.api.java.project.classpath" name="ProjectClassPathModifier"/>
95
        <class package="org.netbeans.spi.java.project.classpath" name="ProjectClassPathModifierImplementation"/>
96
         <issue number="74356"/>
97
         <issue number="75469"/>
98
         <issue number="60852"/>
99
         <issue number="73197"/>
100
         <issue number="73198"/>
101
    </change>
102
                                                                                                                                
80
    <change id="BrokenReferencesModel.updateReference">
103
    <change id="BrokenReferencesModel.updateReference">
81
        <api name="general"/>
104
        <api name="general"/>
82
        <summary>Semantic changes in the BrokenReferencesModel.updateReference behavior</summary>
105
        <summary>Semantic changes in the BrokenReferencesModel.updateReference behavior</summary>
(-)project/manifest.mf (-1 / +1 lines)
Lines 2-7 Link Here
2
OpenIDE-Module: org.netbeans.modules.java.project/1
2
OpenIDE-Module: org.netbeans.modules.java.project/1
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.9
5
OpenIDE-Module-Specification-Version: 1.10
6
OpenIDE-Module-Requires: org.netbeans.modules.project.uiapi.ActionsFactory
6
OpenIDE-Module-Requires: org.netbeans.modules.project.uiapi.ActionsFactory
7
7
(-)project/nbproject/project.properties (+1 lines)
Lines 11-16 Link Here
11
11
12
is.autoload=true
12
is.autoload=true
13
13
14
javac.source=1.5
14
javadoc.title=Java Project API
15
javadoc.title=Java Project API
15
javadoc.overview=${basedir}/overview.html
16
javadoc.overview=${basedir}/overview.html
16
javadoc.arch=${basedir}/arch.xml
17
javadoc.arch=${basedir}/arch.xml
(-)project/src/org/netbeans/api/java/project/classpath/ProjectClassPathModifier.java (+312 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.api.java.project.classpath;
15
16
import java.io.Externalizable;
17
import java.io.IOException;
18
import java.net.URI;
19
import java.net.URL;
20
import java.util.ArrayList;
21
import java.util.List;
22
import org.netbeans.api.java.classpath.ClassPath;
23
import org.netbeans.api.project.FileOwnerQuery;
24
import org.netbeans.api.project.Project;
25
import org.netbeans.api.project.SourceGroup;
26
import org.netbeans.api.project.ant.AntArtifact;
27
import org.netbeans.api.project.libraries.Library;
28
import org.netbeans.modules.java.project.classpath.ProjectClassPathModifierAccessor;
29
import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
30
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
31
import org.openide.filesystems.FileObject;
32
import org.openide.filesystems.FileUtil;
33
import org.openide.filesystems.URLMapper;
34
35
/**
36
 * An API for project's classpaths modification.
37
 * An client can use this interface to add/remove classpath element (folder, archive, library, subproject)
38
 * to/from the project's classpath. Not all operations on all project's classpath are supported, if the project
39
 * type does not support a modification of a given classpath the UnsupportedOperationException is thrown.
40
 * @since org.netbeans.modules.java.project/1 1.10
41
 */
42
public class ProjectClassPathModifier {
43
    
44
    
45
    
46
    private ProjectClassPathModifier () {
47
        
48
    }        
49
    
50
    /**
51
     * Adds libraries into the project's classpath if the
52
     * libraries are not already included.
53
     * @param libraries to be added
54
     * @param projectArtifact a file which classpath should be extended
55
     * @param classPathType the type of classpath to be extended, @see ClassPath
56
     * @return true in case the classpath was changed (at least one library was added to the classpath),
57
     * the value false is returned when all the libraries are already included on the classpath.
58
     * @exception IOException in case the project metadata cannot be changed
59
     * @exception UnsupportedOperationException is thrown when the project does not support
60
     * adding of a library to the classpath of the given id.
61
     */
62
    @SuppressWarnings("deprecation")    //NOI18N
63
    public static  boolean addLibraries (final Library[] libraries, final FileObject projectArtfact, final String classPathType) throws IOException, UnsupportedOperationException {
64
        final Extensible extensible = findExtensible (projectArtfact, classPathType);
65
        if (extensible != null) {            
66
            if (extensible.pcmi != null) {
67
                assert extensible.sg != null;
68
                assert extensible.classPathType != null;
69
                return ProjectClassPathModifierAccessor.INSTANCE.addLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType);
70
            }
71
            else if (extensible.pcpe != null) {
72
                boolean result = false;
73
                for (int i=0; i< libraries.length; i++) {
74
                    result |= extensible.pcpe.addLibrary (libraries[i]);
75
                }
76
                return result;
77
            }
78
        }
79
        throw new UnsupportedOperationException ();
80
    }
81
    
82
    
83
    /**
84
     * Removes libraries from the project's classpath if the
85
     * libraries are included on it.
86
     * @param libraries to be removed
87
     * @param projectArtfact a file from whose classpath the libraries should be removed
88
     * @param classPathType the type of classpath, @see ClassPath
89
     * @return true in case the classpath was changed, (at least one library was removed from the classpath),
90
     * the value false is returned when none of the libraries was included on the classpath.
91
     * @exception IOException in case the project metadata cannot be changed
92
     * @exception UnsupportedOperationException is thrown when the project does not support
93
     * removing of a library from the classpath of the given id.
94
     */
95
    public static boolean removeLibraries (final Library[] libraries, final FileObject projectArtfact, final String classPathType) throws IOException, UnsupportedOperationException {
96
        final Extensible extensible = findExtensible (projectArtfact, classPathType);
97
        if (extensible != null && extensible.pcmi != null) {
98
            assert extensible.sg != null;
99
            assert extensible.classPathType != null;
100
            return ProjectClassPathModifierAccessor.INSTANCE.removeLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType);
101
        }
102
        throw new UnsupportedOperationException ();
103
    }
104
    
105
    /**
106
     * Adds archive files or folders into the project's classpath if the
107
     * entries are not already there.
108
     * @param classPathRoots roots to be added, each root has to be either a root of an archive or a folder
109
     * @param projectArtfact a file which classpath should be extended
110
     * @param classPathType the type of classpath to be extended, @see ClassPath
111
     * @return true in case the classpath was changed, (at least one classpath root was added to the classpath),
112
     * the value false is returned when all the classpath roots are already included on the classpath.
113
     * @exception IOException in case the project metadata cannot be changed
114
     * @exception UnsupportedOperationException is thrown when the project does not support
115
     * adding of a root to the classpath of the given id.
116
     */
117
    @SuppressWarnings("deprecation")        //NOI18N
118
    public static boolean addRoots (final URL[] classPathRoots, final FileObject projectArtfact, final String classPathType) throws IOException, UnsupportedOperationException {
119
        final Extensible extensible = findExtensible(projectArtfact, classPathType);
120
        if (extensible != null) {
121
            if (extensible.pcmi != null) {
122
                assert extensible.sg != null;
123
                assert extensible.classPathType != null;
124
                return ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType);
125
            }
126
            else if (extensible.pcpe != null) {
127
                boolean result = false;
128
                for (int i=0; i< classPathRoots.length; i++) {
129
                    URL urlToAdd = classPathRoots[i];
130
                    if ("jar".equals(urlToAdd.getProtocol())) {
131
                        urlToAdd = FileUtil.getArchiveFile (urlToAdd);
132
                    }
133
                    final FileObject fo = URLMapper.findFileObject(urlToAdd);
134
                    if (fo == null) {
135
                        throw new UnsupportedOperationException ("Adding of a non existent root is not supported by project.");  //NOI18N
136
                    }
137
                    result |= extensible.pcpe.addArchiveFile (fo);
138
                }
139
                return result;
140
            }
141
        }
142
        throw new UnsupportedOperationException ();
143
    }
144
    
145
    /**
146
     * Removes archive files or folders from the project's classpath if the
147
     * entries are included on it.
148
     * @param classPathRoots roots to be removed, each root has to be either a root of an archive or a folder
149
     * @param projectArtfact a file from whose classpath the roots should be removed
150
     * @param classPathType the type of classpath, @see ClassPath
151
     * @return true in case the classpath was changed, (at least one classpath root was removed from the classpath),
152
     * the value false is returned when none of the classpath roots was included on the classpath.
153
     * @exception IOException in case the project metadata cannot be changed
154
     * @exception UnsupportedOperationException is thrown when the project does not support
155
     * removing of a root from the classpath of the given id.
156
     */
157
    public static boolean removeRoots (final URL[] classPathRoots, final FileObject projectArtfact, final String classPathType) throws IOException, UnsupportedOperationException {
158
        final Extensible extensible = findExtensible (projectArtfact, classPathType);
159
        if (extensible != null && extensible.pcmi != null) {
160
            assert extensible.sg != null;
161
            assert extensible.classPathType != null;
162
            return ProjectClassPathModifierAccessor.INSTANCE.removeRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType);
163
        }
164
        throw new UnsupportedOperationException ();
165
    }
166
    
167
    /**
168
     * Adds artifacts (e.g. subprojects) into project's classpath if the
169
     * artifacts are not already on it.
170
     * @param artifacts to be added
171
     * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
172
     * as artifacts. 
173
     * (must be owned by the artifact and be relative to it)
174
     * @param projectArtfact a file which classpath should be extended
175
     * @param classPathType the type of classpath to be extended, @see ClassPath
176
     * @return true in case the classpath was changed, (at least one artifact was added to the classpath),
177
     * the value false is returned when all the artifacts are already included on the classpath.
178
     * @exception IOException in case the project metadata cannot be changed
179
     * @exception UnsupportedOperationException is thrown when the project does not support
180
     * adding of an artifact to the classpath of the given id.
181
     */
182
    @SuppressWarnings("deprecation")        //NOI18N
183
    public static boolean addAntArtifacts (final AntArtifact[] artifacts, final URI[] artifactElements,
184
            final FileObject projectArtfact, final String classPathType) throws IOException, UnsupportedOperationException {
185
        final Extensible extensible = findExtensible (projectArtfact, classPathType);
186
        if (extensible != null) {
187
            assert artifacts.length == artifactElements.length;
188
            if (extensible.pcmi != null) {
189
                assert extensible.sg != null;
190
                assert extensible.classPathType != null;
191
                return ProjectClassPathModifierAccessor.INSTANCE.addAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType);
192
            }
193
            else if (extensible.pcpe != null) {
194
                boolean result = false;
195
                for (int i=0; i< artifacts.length; i++) {
196
                    result |= extensible.pcpe.addAntArtifact (artifacts[i], artifactElements[i]);
197
                }
198
                return result;
199
            }
200
        }
201
        throw new UnsupportedOperationException ();
202
    }
203
    
204
    /**
205
     * Removes artifacts (e.g. subprojects) from project's classpath if the
206
     * artifacts are included on it.
207
     * @param artifacts to be added
208
     * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
209
     * as artifacts.
210
     * (must be owned by the artifact and be relative to it)
211
     * @param projectArtfact a file from whose classpath the dependent projects should be removed
212
     * @param classPathType the type of classpath, @see ClassPath
213
     * @return true in case the classpath was changed, (at least one artifact was removed from the classpath),
214
     * the value false is returned when none of the artifacts was included on the classpath.
215
     * @exception IOException in case the project metadata cannot be changed
216
     * @exception UnsupportedOperationException is thrown when the project does not support
217
     * removing of an artifact from the classpath of the given id.
218
     */
219
    public static boolean removeAntArtifacts (final AntArtifact[] artifacts, final URI[] artifactElements,
220
            final FileObject projectArtifact, final String classPathType) throws IOException, UnsupportedOperationException {
221
        final Extensible extensible = findExtensible (projectArtifact, classPathType);
222
        if (extensible != null && extensible.pcmi != null) {
223
            assert extensible.sg != null;
224
            assert extensible.classPathType != null;
225
            return ProjectClassPathModifierAccessor.INSTANCE.removeAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType);
226
        }
227
        throw new UnsupportedOperationException ();
228
    }
229
    
230
    
231
    /**
232
     * Returns {@link ProjectClassPathModifier#Extensible} for given project artifact and classpath type. 
233
     * An Extensible implies a classpath to be extended. Different project type may provide different types
234
     * of Extensible.
235
     * @param projectArtifact a file owned by SourceGroup which classpath should be changed
236
     * @param classPathType a classpath type, @see ClassPath
237
     * @return an  Extensible or null. In case when the project supports the {@link ProjectClassPathModifierImplementation},
238
     * this interface is used to find an Extensible. If this interface is not provided, but project provides
239
     * the deprecated {@link ProjectClassPathExtender} interface and classpath type is {@link ClassPath@COMPILE} the 
240
     * single Extensible, without assigned SourceGroup, is returned.
241
     * In case when neither {@link ProjectClassPathModifierImplementation} nor {@link ProjectClassPathExtender}
242
     * is supported null is returned.
243
     */
244
    @SuppressWarnings("deprecation")        //NOI18N
245
    private static Extensible findExtensible (final FileObject fo, final String classPathType) {
246
        assert fo != null;
247
        assert classPathType != null;
248
        final Project project = FileOwnerQuery.getOwner(fo);
249
        if (project == null) {
250
            return null;
251
        }
252
        final ProjectClassPathModifierImplementation pm = (ProjectClassPathModifierImplementation) project.getLookup().lookup(ProjectClassPathModifierImplementation.class);
253
        if (pm != null) {            
254
            final SourceGroup[] sgs = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleSourceGroups(pm);
255
            assert sgs != null   : "Class: " + pm.getClass() + " returned null as source groups.";    //NOI18N
256
            for (SourceGroup sg : sgs) {
257
                if ((fo == sg.getRootFolder() || FileUtil.isParentOf(sg.getRootFolder(),fo)) && sg.contains(fo)) {
258
                    final String[] types = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleClassPathTypes(pm,sg);
259
                    assert types != null : "Class: " + pm.getClass() + " returned null as classpath types.";    //NOI18N
260
                    for (String type : types) {
261
                        if (classPathType.equals(type)) {
262
                            return new Extensible (pm, sg, type);
263
                        }
264
                    }
265
                }
266
            }
267
        }
268
        else if (classPathType.equals(ClassPath.COMPILE)) {
269
            final ProjectClassPathExtender pe = (ProjectClassPathExtender) project.getLookup().lookup(ProjectClassPathExtender.class);
270
            if (pe != null) {
271
                return new Extensible (pe);
272
            }
273
        }
274
        return null;
275
    }
276
    
277
    
278
    /**
279
     * Extensible represents a classpath which may be changed by the
280
     * {@link ProjectClassPathModifier}. It encapsulates the compilation
281
     * unit and class path type, @see ClassPath.
282
     */
283
    private static final class Extensible {
284
        
285
        private final String classPathType;       
286
        private final SourceGroup sg;
287
        private final ProjectClassPathModifierImplementation pcmi;
288
        @SuppressWarnings("deprecation")        //NOI18N
289
        private final ProjectClassPathExtender pcpe;
290
        
291
        
292
        private Extensible (final ProjectClassPathModifierImplementation pcmi , final SourceGroup sg, final String classPathType) {
293
            assert pcmi != null;
294
            assert sg != null;
295
            assert classPathType != null;
296
            this.pcmi = pcmi;
297
            this.sg = sg;
298
            this.classPathType = classPathType;
299
            this.pcpe = null;
300
        }
301
        
302
        @SuppressWarnings("deprecation")        //NOI18N
303
        private Extensible (final ProjectClassPathExtender pcpe) {
304
            assert pcpe != null;
305
            this.pcpe = pcpe;
306
            this.pcmi = null;
307
            this.sg = null;
308
            this.classPathType = ClassPath.COMPILE;
309
        }
310
    }    
311
312
}
(-)project/src/org/netbeans/modules/java/project/classpath/ProjectClassPathModifierAccessor.java (+63 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.modules.java.project.classpath;
15
16
import java.io.IOException;
17
import java.net.URI;
18
import java.net.URL;
19
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
20
import org.netbeans.api.project.SourceGroup;
21
import org.netbeans.api.project.ant.AntArtifact;
22
import org.netbeans.api.project.libraries.Library;
23
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
24
import org.openide.ErrorManager;
25
26
/**
27
 *
28
 * @author tom
29
 */
30
public abstract class ProjectClassPathModifierAccessor {
31
    
32
    public static ProjectClassPathModifierAccessor INSTANCE;
33
    
34
    static {
35
        Class c = ProjectClassPathModifierImplementation.class;
36
        try {
37
            Class.forName (c.getName(), true, c.getClassLoader());
38
        } catch (Exception ex) {
39
            ErrorManager.getDefault().notify(ex);
40
        }
41
    }
42
    
43
    /** Creates a new instance of ProjectClassPathModifierAccessor */
44
    public ProjectClassPathModifierAccessor() {
45
    }
46
    
47
    public abstract SourceGroup[] getExtensibleSourceGroups (ProjectClassPathModifierImplementation m);
48
    
49
    public abstract String[] getExtensibleClassPathTypes (ProjectClassPathModifierImplementation m, SourceGroup sg);
50
    
51
    public abstract boolean addLibraries (Library[] libraries, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
52
                
53
    public abstract boolean removeLibraries (Library[] libraries, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
54
        
55
    public abstract boolean addRoots (URL[] classPathRoots, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
56
       
57
    public abstract boolean removeRoots (URL[] classPathRoots, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
58
    
59
    public abstract boolean addAntArtifacts (AntArtifact[] artifacts, URI[] artifactElements, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
60
61
    public abstract boolean removeAntArtifacts (AntArtifact[] artifacts, URI[] artifactElements, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
62
    
63
}
(-)project/src/org/netbeans/spi/java/project/classpath/ProjectClassPathExtender.java (-2 / +6 lines)
Lines 24-32 Link Here
24
 * A project can provide this interface in its {@link org.netbeans.api.project.Project#getLookup lookup} to
24
 * A project can provide this interface in its {@link org.netbeans.api.project.Project#getLookup lookup} to
25
 * allow clients to extend its compilation classpath
25
 * allow clients to extend its compilation classpath
26
 * by a new classpath element (JAR, folder, dependent project, or library).
26
 * by a new classpath element (JAR, folder, dependent project, or library).
27
 * @since org.netbeans.modules.java.project/1 1.3 
27
 * @since org.netbeans.modules.java.project/1 1.3
28
 * @deprecated Please use the {@link ProjectClassPathModifier} instead.
28
 */
29
 */
29
public interface ProjectClassPathExtender {
30
public @Deprecated interface ProjectClassPathExtender {
30
31
31
    /**
32
    /**
32
     * Adds a library into the project's compile classpath if the
33
     * Adds a library into the project's compile classpath if the
Lines 34-39 Link Here
34
     * @param library to be added
35
     * @param library to be added
35
     * @return true in case the classpath was changed
36
     * @return true in case the classpath was changed
36
     * @exception IOException in case the project metadata cannot be changed
37
     * @exception IOException in case the project metadata cannot be changed
38
     * @deprecated Please use {@link ProjectClassPathModifier#addLibrary} instead.
37
     */
39
     */
38
    boolean addLibrary(Library library) throws IOException;
40
    boolean addLibrary(Library library) throws IOException;
39
41
Lines 43-48 Link Here
43
     * @param archiveFile ZIP/JAR file to be added
45
     * @param archiveFile ZIP/JAR file to be added
44
     * @return true in case the classpath was changed
46
     * @return true in case the classpath was changed
45
     * @exception IOException in case the project metadata cannot be changed
47
     * @exception IOException in case the project metadata cannot be changed
48
     * @deprecated Please use {@link ProjectClassPathModifier#addArchive} instead.
46
     */
49
     */
47
    boolean addArchiveFile(FileObject archiveFile) throws IOException;
50
    boolean addArchiveFile(FileObject archiveFile) throws IOException;
48
51
Lines 54-59 Link Here
54
     *                        (must be owned by the artifact and be relative to it)
57
     *                        (must be owned by the artifact and be relative to it)
55
     * @return true in case the classpath was changed
58
     * @return true in case the classpath was changed
56
     * @exception IOException in case the project metadata cannot be changed
59
     * @exception IOException in case the project metadata cannot be changed
60
     * @deprecated Please use {@link ProjectClassPathModifier#addAntArtifact} instead.
57
     */
61
     */
58
    boolean addAntArtifact(AntArtifact artifact, URI artifactElement) throws IOException;
62
    boolean addAntArtifact(AntArtifact artifact, URI artifactElement) throws IOException;
59
63
(-)project/src/org/netbeans/spi/java/project/classpath/ProjectClassPathModifierImplementation.java (+205 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.spi.java.project.classpath;
15
16
import java.io.IOException;
17
import java.net.URI;
18
import java.net.URL;
19
import org.netbeans.api.project.SourceGroup;
20
import org.netbeans.api.project.ant.AntArtifact;
21
import org.netbeans.api.project.libraries.Library;
22
import org.netbeans.modules.java.project.classpath.ProjectClassPathModifierAccessor;
23
import org.openide.filesystems.FileObject;
24
25
/**
26
 * An SPI for project's classpaths modification.
27
 * A project can provide subclass of this class in its {@link org.netbeans.api.project.Project#getLookup lookup} to
28
 * allow clients to add or remove new classpath elements (JAR, folder, dependent project, or library) to its 
29
 * classpaths.
30
 * @since org.netbeans.modules.java.project/1 1.10
31
 */
32
public abstract class ProjectClassPathModifierImplementation {
33
    
34
    static {
35
        ProjectClassPathModifierAccessor.INSTANCE = new Accessor ();
36
    }    
37
    
38
    protected ProjectClassPathModifierImplementation () {
39
    }
40
    
41
    
42
    /**
43
     * Returns the {@link SourceGroup}s providing classpath(s)
44
     * which may be modified.
45
     * @return (possibly empty) array of {@link SourceGroup}, never returns null
46
     */
47
    protected abstract SourceGroup [] getExtensibleSourceGroups ();
48
    
49
    
50
    /**
51
     * Returns the types of classpaths for given {@link SourceGroup} which may be modified.
52
     * @param sourceGroup for which the classpath types should be returned
53
     * @return (possibly empty) array of classpath types, never returns null
54
     */
55
    protected abstract String[] getExtensibleClassPathTypes (SourceGroup sourceGroup);
56
            
57
    /**
58
     * Adds libraries into the project's classpath if the
59
     * libraries are not already included.
60
     * @param libraries to be added
61
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
62
     * identifying the compilation unit to change
63
     * @param type the type of the classpath the library should be added to,
64
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
65
     * @return true in case the classpath was changed (at least one library was added to the classpath),
66
     * the value false is returned when all the libraries are already included on the classpath.
67
     * @exception IOException in case the project metadata cannot be changed
68
     * @exception UnsupportedOperationException is thrown when the project does not support
69
     * adding of a library to the classpath of the given id.
70
     */
71
    protected abstract boolean addLibraries (Library[] libraries, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
72
    
73
    
74
    /**
75
     * Removes libraries from the project's classpath if the
76
     * libraries are included on it.
77
     * @param libraries to be removed
78
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
79
     * identifying the compilation unit to change
80
     * @param type the type of the classpath the library should be removed from,
81
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
82
     * @return true in case the classpath was changed, (at least one library was removed from the classpath),
83
     * the value false is returned when none of the libraries was included on the classpath.
84
     * @exception IOException in case the project metadata cannot be changed
85
     * @exception UnsupportedOperationException is thrown when the project does not support
86
     * removing of a library from the classpath of the given id.
87
     */
88
    protected abstract boolean removeLibraries (Library[] libraries, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
89
    
90
    /**
91
     * Adds archive files or folders into the project's classpath if the
92
     * entries are not already there.
93
     * @param classPathRoots roots to be added, each root has to be either a root of an archive or a folder
94
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
95
     * identifying the compilation unit to change
96
     * @param type the type of the classpath the root should be added to,
97
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
98
     * @return true in case the classpath was changed, (at least one classpath root was added to the classpath),
99
     * the value false is returned when all the classpath roots are already included on the classpath.
100
     * @exception IOException in case the project metadata cannot be changed
101
     * @exception UnsupportedOperationException is thrown when the project does not support
102
     * adding of a root to the classpath of the given id.
103
     */
104
    protected abstract boolean addRoots (URL[] classPathRoots, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
105
    
106
    /**
107
     * Removes archive files or folders from the project's classpath if the
108
     * entries are included on it.
109
     * @param classPathRoots roots to be removed, each root has to be either a root of an archive or a folder
110
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
111
     * identifying the compilation unit to change
112
     * @param type the type of the classpath the root should be removed from,
113
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
114
     * @return true in case the classpath was changed, (at least one classpath root was removed from the classpath),
115
     * the value false is returned when none of the classpath roots was included on the classpath.
116
     * @exception IOException in case the project metadata cannot be changed
117
     * @exception UnsupportedOperationException is thrown when the project does not support
118
     * removing of a root from the classpath of the given id.
119
     */
120
    protected abstract boolean removeRoots (URL[] classPathRoots, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
121
    
122
    /**
123
     * Adds artifacts (e.g. subprojects) into project's classpath if the
124
     * artifacts are not already on it.
125
     * @param artifacts to be added
126
     * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
127
     * as artifacts. 
128
     * (must be owned by the artifact and be relative to it)
129
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
130
     * identifying the compilation unit to change
131
     * @param type the type of the classpath the artifact should be added to,
132
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
133
     * @return true in case the classpath was changed, (at least one artifact was added to the classpath),
134
     * the value false is returned when all the artifacts are already included on the classpath.
135
     * @exception IOException in case the project metadata cannot be changed
136
     * @exception UnsupportedOperationException is thrown when the project does not support
137
     * adding of an artifact to the classpath of the given id.
138
     */
139
    protected abstract boolean addAntArtifacts (AntArtifact[] artifacts, URI[] artifactElements, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
140
    
141
    /**
142
     * Removes artifacts (e.g. subprojects) from project's classpath if the
143
     * artifacts are included on it.
144
     * @param artifacts to be added
145
     * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
146
     * as artifacts.
147
     * (must be owned by the artifact and be relative to it)
148
     * @param sourceGroup of type {@link org.netbeans.api.java.project.JavaProjectConstants#SOURCES_TYPE_JAVA}
149
     * identifying the compilation unit to change
150
     * @param type the type of the classpath the artifact should be removed from,
151
     * eg {@link org.netbeans.api.java.classpath.ClassPath.COMPILE}
152
     * @return true in case the classpath was changed, (at least one artifact was removed from the classpath),
153
     * the value false is returned when none of the artifacts was included on the classpath.
154
     * @exception IOException in case the project metadata cannot be changed
155
     * @exception UnsupportedOperationException is thrown when the project does not support
156
     * removing of an artifact from the classpath of the given id.
157
     */
158
    protected abstract boolean removeAntArtifacts (AntArtifact[] artifacts, URI[] artifactElements, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException;
159
160
    
161
    private static class Accessor extends ProjectClassPathModifierAccessor {        
162
        
163
        public SourceGroup[] getExtensibleSourceGroups(final ProjectClassPathModifierImplementation m) {
164
            assert m != null;
165
            return m.getExtensibleSourceGroups();
166
        }
167
        
168
        public String[] getExtensibleClassPathTypes (final ProjectClassPathModifierImplementation m, SourceGroup sg) {
169
            assert m != null;
170
            assert sg != null;
171
            return m.getExtensibleClassPathTypes(sg);
172
        }
173
        
174
        public boolean removeLibraries(Library[] libraries, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
175
            assert m!= null;
176
            return m.removeLibraries(libraries, sourceGroup, type);
177
        }
178
179
        public boolean removeAntArtifacts(AntArtifact[] artifacts, URI[] artifactElements, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
180
            assert m!= null;
181
            return m.removeAntArtifacts(artifacts, artifactElements, sourceGroup, type);
182
        }
183
184
        public boolean addLibraries (Library[] libraries, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
185
            assert m!= null;
186
            return m.addLibraries(libraries, sourceGroup, type);
187
        }
188
189
        public boolean addAntArtifacts (AntArtifact[] artifacts, URI[] artifactElements, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
190
            assert m!= null;
191
            return m.addAntArtifacts (artifacts, artifactElements, sourceGroup, type);
192
        }
193
194
        public boolean removeRoots (URL[] classPathRoots, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
195
            assert m!= null;
196
            return m.removeRoots(classPathRoots, sourceGroup, type);
197
        }
198
199
        public boolean addRoots (URL[] classPathRoots, ProjectClassPathModifierImplementation m, SourceGroup sourceGroup, String type) throws IOException, UnsupportedOperationException {
200
            assert m!= null;
201
            return m.addRoots (classPathRoots, sourceGroup, type);
202
        }       
203
                        
204
    }
205
}

Return to bug 75471