KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > project > classpath > ProjectClassPathModifier


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.java.project.classpath;
21
22 import java.io.Externalizable JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.net.URI JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.List JavaDoc;
28 import org.netbeans.api.java.classpath.ClassPath;
29 import org.netbeans.api.project.FileOwnerQuery;
30 import org.netbeans.api.project.Project;
31 import org.netbeans.api.project.SourceGroup;
32 import org.netbeans.api.project.ant.AntArtifact;
33 import org.netbeans.api.project.libraries.Library;
34 import org.netbeans.modules.java.project.classpath.ProjectClassPathModifierAccessor;
35 import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
36 import org.openide.filesystems.FileObject;
37 import org.openide.filesystems.FileUtil;
38 import org.openide.filesystems.URLMapper;
39
40 /**
41  * An API for project's classpaths modification.
42  * An client can use this interface to add/remove classpath element (folder, archive, library, subproject)
43  * to/from the project's classpath. Not all operations on all project's classpath are supported, if the project
44  * type does not support a modification of a given classpath the UnsupportedOperationException is thrown.
45  * @since org.netbeans.modules.java.project/1 1.10
46  */

47 public class ProjectClassPathModifier {
48     
49     
50     
51     private ProjectClassPathModifier () {
52         
53     }
54     
55     /**
56      * Adds libraries into the project's classpath if the
57      * libraries are not already included.
58      * @param libraries to be added
59      * @param projectArtifact a file whose classpath should be extended
60      * @param classPathType the type of classpath to be extended, @see ClassPath
61      * @return true in case the classpath was changed (at least one library was added to the classpath),
62      * the value false is returned when all the libraries are already included on the classpath.
63      * @exception IOException in case the project metadata cannot be changed
64      * @exception UnsupportedOperationException is thrown when the project does not support
65      * adding of a library to the classpath of the given type.
66      */

67     @SuppressWarnings JavaDoc("deprecation") //NOI18N
68
public static boolean addLibraries (final Library[] libraries, final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
69         final Extensible extensible = findExtensible (projectArtifact, classPathType);
70         if (extensible != null) {
71             if (extensible.pcmi != null) {
72                 assert extensible.sg != null;
73                 assert extensible.classPathType != null;
74                 return ProjectClassPathModifierAccessor.INSTANCE.addLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType);
75             }
76             else if (extensible.pcpe != null) {
77                 boolean result = false;
78                 for (int i=0; i< libraries.length; i++) {
79                     result |= extensible.pcpe.addLibrary (libraries[i]);
80                 }
81                 return result;
82             }
83         }
84         throw new UnsupportedOperationException JavaDoc ();
85     }
86     
87     
88     /**
89      * Removes libraries from the project's classpath if the
90      * libraries are included on it.
91      * @param libraries to be removed
92      * @param projectArtifact a file from whose classpath the libraries should be removed
93      * @param classPathType the type of classpath, @see ClassPath
94      * @return true in case the classpath was changed, (at least one library was removed from the classpath),
95      * the value false is returned when none of the libraries was included on the classpath.
96      * @exception IOException in case the project metadata cannot be changed
97      * @exception UnsupportedOperationException is thrown when the project does not support
98      * removing of a library from the classpath of the given type.
99      */

100     public static boolean removeLibraries (final Library[] libraries, final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
101         final Extensible extensible = findExtensible (projectArtifact, classPathType);
102         if (extensible != null && extensible.pcmi != null) {
103             assert extensible.sg != null;
104             assert extensible.classPathType != null;
105             return ProjectClassPathModifierAccessor.INSTANCE.removeLibraries (libraries, extensible.pcmi, extensible.sg, extensible.classPathType);
106         }
107         throw new UnsupportedOperationException JavaDoc ();
108     }
109     
110     /**
111      * Adds archive files or folders into the project's classpath if the
112      * entries are not already there.
113      * @param classPathRoots roots to be added, each root has to be either a root of an archive or a folder
114      * @param projectArtifact a file whose classpath should be extended
115      * @param classPathType the type of classpath to be extended, @see ClassPath
116      * @return true in case the classpath was changed, (at least one classpath root was added to the classpath),
117      * the value false is returned when all the classpath roots are already included on the classpath.
118      * @exception IOException in case the project metadata cannot be changed
119      * @exception UnsupportedOperationException is thrown when the project does not support
120      * adding of a root to the classpath of the given type.
121      */

122     @SuppressWarnings JavaDoc("deprecation") //NOI18N
123
public static boolean addRoots (final URL JavaDoc[] classPathRoots, final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
124         final Extensible extensible = findExtensible(projectArtifact, classPathType);
125         if (extensible != null) {
126             if (extensible.pcmi != null) {
127                 assert extensible.sg != null;
128                 assert extensible.classPathType != null;
129                 return ProjectClassPathModifierAccessor.INSTANCE.addRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType);
130             }
131             else if (extensible.pcpe != null) {
132                 boolean result = false;
133                 for (int i=0; i< classPathRoots.length; i++) {
134                     URL JavaDoc urlToAdd = classPathRoots[i];
135                     if ("jar".equals(urlToAdd.getProtocol())) {
136                         urlToAdd = FileUtil.getArchiveFile (urlToAdd);
137                     }
138                     final FileObject fo = URLMapper.findFileObject(urlToAdd);
139                     if (fo == null) {
140                         throw new UnsupportedOperationException JavaDoc ("Adding of a non existent root is not supported by project."); //NOI18N
141
}
142                     result |= extensible.pcpe.addArchiveFile (fo);
143                 }
144                 return result;
145             }
146         }
147         throw new UnsupportedOperationException JavaDoc ();
148     }
149     
150     /**
151      * Removes archive files or folders from the project's classpath if the
152      * entries are included on it.
153      * @param classPathRoots roots to be removed, each root has to be either a root of an archive or a folder
154      * @param projectArtifact a file from whose classpath the roots should be removed
155      * @param classPathType the type of classpath, @see ClassPath
156      * @return true in case the classpath was changed, (at least one classpath root was removed from the classpath),
157      * the value false is returned when none of the classpath roots was included on the classpath.
158      * @exception IOException in case the project metadata cannot be changed
159      * @exception UnsupportedOperationException is thrown when the project does not support
160      * removing of a root from the classpath of the given type.
161      */

162     public static boolean removeRoots (final URL JavaDoc[] classPathRoots, final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
163         final Extensible extensible = findExtensible (projectArtifact, classPathType);
164         if (extensible != null && extensible.pcmi != null) {
165             assert extensible.sg != null;
166             assert extensible.classPathType != null;
167             return ProjectClassPathModifierAccessor.INSTANCE.removeRoots (classPathRoots, extensible.pcmi, extensible.sg, extensible.classPathType);
168         }
169         throw new UnsupportedOperationException JavaDoc ();
170     }
171     
172     /**
173      * Adds artifacts (e.g. subprojects) into project's classpath if the
174      * artifacts are not already on it.
175      * @param artifacts to be added
176      * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
177      * as artifacts.
178      * (must be owned by the artifact and be relative to it)
179      * @param projectArtifact a file whose classpath should be extended
180      * @param classPathType the type of classpath to be extended, @see ClassPath
181      * @return true in case the classpath was changed, (at least one artifact was added to the classpath),
182      * the value false is returned when all the artifacts are already included on the classpath.
183      * @exception IOException in case the project metadata cannot be changed
184      * @exception UnsupportedOperationException is thrown when the project does not support
185      * adding of an artifact to the classpath of the given type.
186      */

187     @SuppressWarnings JavaDoc("deprecation") //NOI18N
188
public static boolean addAntArtifacts (final AntArtifact[] artifacts, final URI JavaDoc[] artifactElements,
189             final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
190         final Extensible extensible = findExtensible (projectArtifact, classPathType);
191         if (extensible != null) {
192             assert artifacts.length == artifactElements.length;
193             if (extensible.pcmi != null) {
194                 assert extensible.sg != null;
195                 assert extensible.classPathType != null;
196                 return ProjectClassPathModifierAccessor.INSTANCE.addAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType);
197             }
198             else if (extensible.pcpe != null) {
199                 boolean result = false;
200                 for (int i=0; i< artifacts.length; i++) {
201                     result |= extensible.pcpe.addAntArtifact (artifacts[i], artifactElements[i]);
202                 }
203                 return result;
204             }
205         }
206         throw new UnsupportedOperationException JavaDoc ();
207     }
208     
209     /**
210      * Removes artifacts (e.g. subprojects) from project's classpath if the
211      * artifacts are included on it.
212      * @param artifacts to be added
213      * @param artifactElements the URIs of the build output, the artifactElements has to have the same length
214      * as artifacts.
215      * (must be owned by the artifact and be relative to it)
216      * @param projectArtifact a file from whose classpath the dependent projects should be removed
217      * @param classPathType the type of classpath, @see ClassPath
218      * @return true in case the classpath was changed, (at least one artifact was removed from the classpath),
219      * the value false is returned when none of the artifacts was included on the classpath.
220      * @exception IOException in case the project metadata cannot be changed
221      * @exception UnsupportedOperationException is thrown when the project does not support
222      * removing of an artifact from the classpath of the given type.
223      */

224     public static boolean removeAntArtifacts (final AntArtifact[] artifacts, final URI JavaDoc[] artifactElements,
225             final FileObject projectArtifact, final String JavaDoc classPathType) throws IOException JavaDoc, UnsupportedOperationException JavaDoc {
226         final Extensible extensible = findExtensible (projectArtifact, classPathType);
227         if (extensible != null && extensible.pcmi != null) {
228             assert extensible.sg != null;
229             assert extensible.classPathType != null;
230             return ProjectClassPathModifierAccessor.INSTANCE.removeAntArtifacts (artifacts, artifactElements, extensible.pcmi, extensible.sg, extensible.classPathType);
231         }
232         throw new UnsupportedOperationException JavaDoc ();
233     }
234     
235     
236     /**
237      * Returns {@link ProjectClassPathModifier#Extensible} for given project artifact and classpath type.
238      * An Extensible implies a classpath to be extended. Different project type may provide different types
239      * of Extensible.
240      * @param projectArtifact a file owned by SourceGroup whose classpath should be changed
241      * @param classPathType a classpath type, @see ClassPath
242      * @return an Extensible or null. In case when the project supports the {@link ProjectClassPathModifierImplementation},
243      * this interface is used to find an Extensible. If this interface is not provided, but project provides
244      * the deprecated {@link ProjectClassPathExtender} interface and classpath type is {@link ClassPath@COMPILE} the
245      * single Extensible, without assigned SourceGroup, is returned.
246      * In case when neither {@link ProjectClassPathModifierImplementation} nor {@link ProjectClassPathExtender}
247      * is supported null is returned.
248      */

249     @SuppressWarnings JavaDoc("deprecation") //NOI18N
250
private static Extensible findExtensible (final FileObject fo, final String JavaDoc classPathType) {
251         assert fo != null;
252         assert classPathType != null;
253         final Project project = FileOwnerQuery.getOwner(fo);
254         if (project == null) {
255             return null;
256         }
257         final ProjectClassPathModifierImplementation pm = project.getLookup().lookup(ProjectClassPathModifierImplementation.class);
258         if (pm != null) {
259             final SourceGroup[] sgs = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleSourceGroups(pm);
260             assert sgs != null : "Class: " + pm.getClass() + " returned null as source groups."; //NOI18N
261
for (SourceGroup sg : sgs) {
262                 if ((fo == sg.getRootFolder() || FileUtil.isParentOf(sg.getRootFolder(),fo)) && sg.contains(fo)) {
263                     final String JavaDoc[] types = ProjectClassPathModifierAccessor.INSTANCE.getExtensibleClassPathTypes(pm,sg);
264                     assert types != null : "Class: " + pm.getClass() + " returned null as classpath types."; //NOI18N
265
for (String JavaDoc type : types) {
266                         if (classPathType.equals(type)) {
267                             return new Extensible (pm, sg, type);
268                         }
269                     }
270                 }
271             }
272         }
273         else if (classPathType.equals(ClassPath.COMPILE)) {
274             final org.netbeans.spi.java.project.classpath.ProjectClassPathExtender pe =
275                     project.getLookup().lookup(org.netbeans.spi.java.project.classpath.ProjectClassPathExtender.class);
276             if (pe != null) {
277                 return new Extensible (pe);
278             }
279         }
280         return null;
281     }
282     
283     
284     /**
285      * Extensible represents a classpath which may be changed by the
286      * {@link ProjectClassPathModifier}. It encapsulates the compilation
287      * unit and class path type, @see ClassPath.
288      */

289     private static final class Extensible {
290         
291         private final String JavaDoc classPathType;
292         private final SourceGroup sg;
293         private final ProjectClassPathModifierImplementation pcmi;
294         @SuppressWarnings JavaDoc("deprecation") //NOI18N
295
private final org.netbeans.spi.java.project.classpath.ProjectClassPathExtender pcpe;
296         
297         
298         private Extensible (final ProjectClassPathModifierImplementation pcmi , final SourceGroup sg, final String JavaDoc classPathType) {
299             assert pcmi != null;
300             assert sg != null;
301             assert classPathType != null;
302             this.pcmi = pcmi;
303             this.sg = sg;
304             this.classPathType = classPathType;
305             this.pcpe = null;
306         }
307         
308         @SuppressWarnings JavaDoc("deprecation") //NOI18N
309
private Extensible (final org.netbeans.spi.java.project.classpath.ProjectClassPathExtender pcpe) {
310             assert pcpe != null;
311             this.pcpe = pcpe;
312             this.pcmi = null;
313             this.sg = null;
314             this.classPathType = ClassPath.COMPILE;
315         }
316     }
317
318 }
319
Popular Tags