KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > resources > ProjectDescription


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.resources;
12
13 import java.net.URI JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import org.eclipse.core.filesystem.URIUtil;
17 import org.eclipse.core.internal.events.BuildCommand;
18 import org.eclipse.core.internal.utils.FileUtil;
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.IPath;
22
23 public class ProjectDescription extends ModelObject implements IProjectDescription {
24     private static final ICommand[] EMPTY_COMMAND_ARRAY = new ICommand[0];
25     // constants
26
private static final IProject[] EMPTY_PROJECT_ARRAY = new IProject[0];
27     private static final String JavaDoc[] EMPTY_STRING_ARRAY = new String JavaDoc[0];
28     protected static boolean isReading = false;
29
30     //flags to indicate when we are in the middle of reading or writing a
31
// workspace description
32
//these can be static because only one description can be read at once.
33
protected static boolean isWriting = false;
34     protected ICommand[] buildSpec = EMPTY_COMMAND_ARRAY;
35     /*
36      * Cached union of static and dynamic references (duplicates omitted).
37      * This cache is not persisted.
38      */

39     protected IProject[] cachedRefs = null;
40     protected String JavaDoc comment = ""; //$NON-NLS-1$
41
protected IProject[] dynamicRefs = EMPTY_PROJECT_ARRAY;
42     
43     /**
44      * Map of (IPath -> LinkDescription) pairs for each linked resource
45      * in this project, where IPath is the project relative path of the resource.
46      */

47     protected HashMap JavaDoc linkDescriptions = null;
48
49     // fields
50
protected URI JavaDoc location = null;
51     protected String JavaDoc[] natures = EMPTY_STRING_ARRAY;
52     protected IProject[] staticRefs = EMPTY_PROJECT_ARRAY;
53
54     public ProjectDescription() {
55         super();
56     }
57
58     public Object JavaDoc clone() {
59         ProjectDescription clone = (ProjectDescription) super.clone();
60         //don't want the clone to have access to our internal link locations table or builders
61
clone.linkDescriptions = null;
62         clone.buildSpec = getBuildSpec(true);
63         return clone;
64     }
65
66     /**
67      * Returns a copy of the given array with all duplicates removed
68      */

69     private IProject[] copyAndRemoveDuplicates(IProject[] projects) {
70         IProject[] result = new IProject[projects.length];
71         int count = 0;
72         next: for (int i = 0; i < projects.length; i++) {
73                 IProject project = projects[i];
74                 // scan to see if there are any other projects by the same name
75
for (int j = 0; j < count; j++)
76                         if (project.equals(result[j]))
77                                 continue next;
78                 // not found
79
result[count++] = project;
80         }
81         if (count < projects.length) {
82                 //shrink array
83
IProject[] reduced = new IProject[count];
84                 System.arraycopy(result, 0, reduced, 0, count);
85                 return reduced;
86         }
87         return result;
88 }
89     /**
90      * Returns the union of the description's static and dynamic project references,
91      * with duplicates omitted. The calculation is optimized by caching the result
92      */

93     public IProject[] getAllReferences(boolean makeCopy) {
94         if (cachedRefs == null) {
95             IProject[] statik = getReferencedProjects(false);
96             IProject[] dynamic = getDynamicReferences(false);
97             if (dynamic.length == 0) {
98                 cachedRefs = statik;
99             } else if (statik.length == 0) {
100                 cachedRefs = dynamic;
101             } else {
102                 //combine all references
103
IProject[] result = new IProject[dynamic.length + statik.length];
104                 System.arraycopy(statik, 0, result, 0, statik.length);
105                 System.arraycopy(dynamic, 0, result, statik.length, dynamic.length);
106                 cachedRefs = copyAndRemoveDuplicates(result);
107             }
108         }
109         //still need to copy the result to prevent tampering with the cache
110
return makeCopy ? (IProject[]) cachedRefs.clone() : cachedRefs;
111     }
112
113     /* (non-Javadoc)
114      * @see IProjectDescription#getBuildSpec()
115      */

116     public ICommand[] getBuildSpec() {
117         return getBuildSpec(true);
118     }
119
120     public ICommand[] getBuildSpec(boolean makeCopy) {
121         //thread safety: copy reference in case of concurrent write
122
ICommand[] oldCommands = this.buildSpec;
123         if (oldCommands == null)
124             return EMPTY_COMMAND_ARRAY;
125         if (!makeCopy)
126             return oldCommands;
127         ICommand[] result = new ICommand[oldCommands.length];
128         for (int i = 0; i < result.length; i++)
129             result[i] = (ICommand) ((BuildCommand) oldCommands[i]).clone();
130         return result;
131     }
132
133     /* (non-Javadoc)
134      * @see IProjectDescription#getComment()
135      */

136     public String JavaDoc getComment() {
137         return comment;
138     }
139
140     /* (non-Javadoc)
141      * @see IProjectDescription#getDynamicReferences()
142      */

143     public IProject[] getDynamicReferences() {
144         return getDynamicReferences(true);
145     }
146
147     public IProject[] getDynamicReferences(boolean makeCopy) {
148         if (dynamicRefs == null)
149             return EMPTY_PROJECT_ARRAY;
150         return makeCopy ? (IProject[]) dynamicRefs.clone() : dynamicRefs;
151     }
152
153     /**
154      * Returns the link location for the given resource name. Returns null if
155      * no such link exists.
156      */

157     public URI JavaDoc getLinkLocationURI(IPath aPath) {
158         if (linkDescriptions == null)
159             return null;
160         LinkDescription desc = (LinkDescription) linkDescriptions.get(aPath);
161         return desc == null ? null : desc.getLocationURI();
162     }
163
164     /**
165      * Returns the map of link descriptions (IPath (project relative path) -> LinkDescription).
166      * Since this method is only used internally, it never creates a copy.
167      * Returns null if the project does not have any linked resources.
168      */

169     public HashMap JavaDoc getLinks() {
170         return linkDescriptions;
171     }
172
173     /**
174      * @see IProjectDescription#getLocation()
175      * @deprecated
176      */

177     public IPath getLocation() {
178         if (location == null)
179             return null;
180         return FileUtil.toPath(location);
181     }
182
183     /* (non-Javadoc)
184      * @see IProjectDescription#getLocationURI()
185      */

186     public URI JavaDoc getLocationURI() {
187         return location;
188     }
189
190     /* (non-Javadoc)
191      * @see IProjectDescription#getNatureIds()
192      */

193     public String JavaDoc[] getNatureIds() {
194         return getNatureIds(true);
195     }
196
197     public String JavaDoc[] getNatureIds(boolean makeCopy) {
198         if (natures == null)
199             return EMPTY_STRING_ARRAY;
200         return makeCopy ? (String JavaDoc[]) natures.clone() : natures;
201     }
202
203     /* (non-Javadoc)
204      * @see IProjectDescription#getReferencedProjects()
205      */

206     public IProject[] getReferencedProjects() {
207         return getReferencedProjects(true);
208     }
209
210     public IProject[] getReferencedProjects(boolean makeCopy) {
211         if (staticRefs == null)
212             return EMPTY_PROJECT_ARRAY;
213         return makeCopy ? (IProject[]) staticRefs.clone() : staticRefs;
214     }
215
216     /* (non-Javadoc)
217      * @see IProjectDescription#hasNature(String)
218      */

219     public boolean hasNature(String JavaDoc natureID) {
220         String JavaDoc[] natureIDs = getNatureIds(false);
221         for (int i = 0; i < natureIDs.length; ++i)
222             if (natureIDs[i].equals(natureID))
223                 return true;
224         return false;
225     }
226
227     /**
228      * Returns true if any private attributes of the description have changed.
229      * Private attributes are those that are not stored in the project description
230      * file (.project).
231      */

232     public boolean hasPrivateChanges(ProjectDescription description) {
233         if (!Arrays.equals(dynamicRefs, description.getDynamicReferences(false)))
234             return true;
235         IPath otherLocation = description.getLocation();
236         if (location == null)
237             return otherLocation != null;
238         return !location.equals(otherLocation);
239     }
240
241     /**
242      * Returns true if any public attributes of the description have changed.
243      * Public attributes are those that are stored in the project description
244      * file (.project).
245      */

246     public boolean hasPublicChanges(ProjectDescription description) {
247         if (!getName().equals(description.getName()))
248             return true;
249         if (!comment.equals(description.getComment()))
250             return true;
251         //don't bother optimizing if the order has changed
252
if (!Arrays.equals(buildSpec, description.getBuildSpec(false)))
253             return true;
254         if (!Arrays.equals(staticRefs, description.getReferencedProjects(false)))
255             return true;
256         if (!Arrays.equals(natures, description.getNatureIds(false)))
257             return true;
258         HashMap JavaDoc otherLinks = description.getLinks();
259         if (linkDescriptions == null)
260             return otherLinks != null;
261         return !linkDescriptions.equals(otherLinks);
262     }
263
264     /* (non-Javadoc)
265      * @see IProjectDescription#newCommand()
266      */

267     public ICommand newCommand() {
268         return new BuildCommand();
269     }
270
271     /* (non-Javadoc)
272      * @see IProjectDescription#setBuildSpec(ICommand[])
273      */

274     public void setBuildSpec(ICommand[] value) {
275         Assert.isLegal(value != null);
276         //perform a deep copy in case clients perform further changes to the command
277
ICommand[] result = new ICommand[value.length];
278         for (int i = 0; i < result.length; i++) {
279             result[i] = (ICommand) ((BuildCommand) value[i]).clone();
280             //copy the reference to any builder instance from the old build spec
281
//to preserve builder states if possible.
282
for (int j = 0; j < buildSpec.length; j++) {
283                 if (result[i].equals(buildSpec[j])) {
284                     ((BuildCommand) result[i]).setBuilder(((BuildCommand) buildSpec[j]).getBuilder());
285                     break;
286                 }
287             }
288         }
289         buildSpec = result;
290     }
291
292     /* (non-Javadoc)
293      * @see IProjectDescription#setComment(String)
294      */

295     public void setComment(String JavaDoc value) {
296         comment = value;
297     }
298
299     /* (non-Javadoc)
300      * @see IProjectDescription#setDynamicReferences(IProject[])
301      */

302     public void setDynamicReferences(IProject[] value) {
303         Assert.isLegal(value != null);
304         dynamicRefs = copyAndRemoveDuplicates(value);
305         cachedRefs = null;
306     }
307
308     /**
309      * Sets the map of link descriptions (String name -> LinkDescription).
310      * Since this method is only used internally, it never creates a copy. May
311      * pass null if this project does not have any linked resources
312      */

313     public void setLinkDescriptions(HashMap JavaDoc linkDescriptions) {
314         this.linkDescriptions = linkDescriptions;
315     }
316
317     /**
318      * Sets the description of a link. Setting to a description of null will
319      * remove the link from the project description.
320      */

321     public void setLinkLocation(IPath path, LinkDescription description) {
322         HashMap JavaDoc tempMap = linkDescriptions;
323         if (description != null) {
324             //addition or modification
325
if (tempMap == null)
326                 tempMap = new HashMap JavaDoc(10);
327             else
328                 //copy on write to protect against concurrent read
329
tempMap = (HashMap JavaDoc) tempMap.clone();
330             tempMap.put(path, description);
331             linkDescriptions = tempMap;
332         } else {
333             //removal
334
if (tempMap != null) {
335                 //copy on write to protect against concurrent access
336
HashMap JavaDoc newMap = (HashMap JavaDoc) tempMap.clone();
337                 newMap.remove(path);
338                 linkDescriptions = newMap.size() == 0 ? null : newMap;
339             }
340         }
341     }
342
343     /* (non-Javadoc)
344      * @see IProjectDescription#setLocation(IPath)
345      */

346     public void setLocation(IPath path) {
347         this.location = path == null ? null : URIUtil.toURI(path);
348     }
349
350     public void setLocationURI(URI JavaDoc location) {
351         this.location = location;
352     }
353
354     /* (non-Javadoc)
355      * @see IProjectDescription#setName(String)
356      */

357     public void setName(String JavaDoc value) {
358         super.setName(value);
359     }
360
361     /* (non-Javadoc)
362      * @see IProjectDescription#setNatureIds(String[])
363      */

364     public void setNatureIds(String JavaDoc[] value) {
365         natures = (String JavaDoc[]) value.clone();
366     }
367
368     /* (non-Javadoc)
369      * @see IProjectDescription#setReferencedProjects(IProject[])
370      */

371     public void setReferencedProjects(IProject[] value) {
372         Assert.isLegal(value != null);
373         staticRefs = copyAndRemoveDuplicates(value);
374         cachedRefs = null;
375     }
376 }
377
Popular Tags