KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > JavaProjectElementInfo


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.jdt.internal.core;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.core.resources.IContainer;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.jdt.core.*;
21 import org.eclipse.jdt.internal.core.util.HashSetOfArray;
22 import org.eclipse.jdt.internal.core.util.Util;
23 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
24
25 /**
26  * Info for IJavaProject.
27  * <p>
28  * Note: <code>getChildren()</code> returns all of the <code>IPackageFragmentRoots</code>
29  * specified on the classpath for the project. This can include roots external to the
30  * project. See <code>JavaProject#getAllPackageFragmentRoots()</code> and
31  * <code>JavaProject#getPackageFragmentRoots()</code>. To get only the <code>IPackageFragmentRoots</code>
32  * that are internal to the project, use <code>JavaProject#getChildren()</code>.
33  */

34
35 /* package */
36 class JavaProjectElementInfo extends OpenableElementInfo {
37     
38     static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0];
39
40     static class ProjectCache {
41         ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, Map JavaDoc rootToResolvedEntries, Map JavaDoc pkgFragmentsCaches) {
42             this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
43             this.rootToResolvedEntries = rootToResolvedEntries;
44             this.pkgFragmentsCaches = pkgFragmentsCaches;
45         }
46         
47         /*
48          * A cache of all package fragment roots of this project.
49          */

50         public IPackageFragmentRoot[] allPkgFragmentRootsCache;
51         
52         /*
53          * A cache of all package fragments in this project.
54          * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name))
55          */

56         public HashtableOfArrayToObject allPkgFragmentsCache;
57         
58         /*
59          * A cache of package fragments for each package fragment root of this project
60          * (a map from IPackageFragmentRoot to a set of String[] (the package name))
61          */

62         public Map JavaDoc pkgFragmentsCaches;
63         
64         public Map JavaDoc rootToResolvedEntries;
65     }
66     
67     /**
68      * A array with all the non-java resources contained by this PackageFragment
69      */

70     private Object JavaDoc[] nonJavaResources;
71     
72     ProjectCache projectCache;
73     
74     /*
75      * Adds the given name and its super names to the given set
76      * (e.g. for {"a", "b", "c"}, adds {"a", "b", "c"}, {"a", "b"}, and {"a"})
77      */

78     static void addSuperPackageNames(String JavaDoc[] pkgName, HashtableOfArrayToObject packageFragments) {
79         for (int i = pkgName.length-1; i > 0; i--) {
80             if (packageFragments.getKey(pkgName, i) == null) {
81                 System.arraycopy(pkgName, 0, pkgName = new String JavaDoc[i], 0, i);
82                 packageFragments.put(pkgName, NO_ROOTS);
83             }
84         }
85     }
86     
87     /**
88      * Create and initialize a new instance of the receiver
89      */

90     public JavaProjectElementInfo() {
91         this.nonJavaResources = null;
92     }
93     
94     /**
95      * Compute the non-java resources contained in this java project.
96      */

97     private Object JavaDoc[] computeNonJavaResources(JavaProject project) {
98         
99         // determine if src == project and/or if bin == project
100
IPath projectPath = project.getProject().getFullPath();
101         boolean srcIsProject = false;
102         boolean binIsProject = false;
103         char[][] inclusionPatterns = null;
104         char[][] exclusionPatterns = null;
105         IPath projectOutput = null;
106         boolean isClasspathResolved = true;
107         try {
108             IClasspathEntry entry = project.getClasspathEntryFor(projectPath);
109             if (entry != null) {
110                 srcIsProject = true;
111                 inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
112                 exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
113             }
114             projectOutput = project.getOutputLocation();
115             binIsProject = projectPath.equals(projectOutput);
116         } catch (JavaModelException e) {
117             isClasspathResolved = false;
118         }
119
120         Object JavaDoc[] resources = new IResource[5];
121         int resourcesCounter = 0;
122         try {
123             IResource[] members = ((IContainer) project.getResource()).members();
124             int length = members.length;
125             if (length > 0) {
126                 String JavaDoc sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
127                 String JavaDoc complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
128                 IClasspathEntry[] classpath = project.getResolvedClasspath();
129                 for (int i = 0; i < length; i++) {
130                     IResource res = members[i];
131                     switch (res.getType()) {
132                         case IResource.FILE :
133                             IPath resFullPath = res.getFullPath();
134                             String JavaDoc resName = res.getName();
135                         
136                             // ignore a jar file on the classpath
137
if (isClasspathResolved && org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(resName) && this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput)) {
138                                 break;
139                             }
140                             // ignore .java file if src == project
141
if (srcIsProject
142                                     && Util.isValidCompilationUnitName(resName, sourceLevel, complianceLevel)
143                                     && !Util.isExcluded(res, inclusionPatterns, exclusionPatterns)) {
144                                 break;
145                             }
146                             // ignore .class file if bin == project
147
if (binIsProject && Util.isValidClassFileName(resName, sourceLevel, complianceLevel)) {
148                                 break;
149                             }
150                             // else add non java resource
151
if (resources.length == resourcesCounter) {
152                                 // resize
153
System.arraycopy(
154                                         resources,
155                                         0,
156                                         (resources = new IResource[resourcesCounter * 2]),
157                                         0,
158                                         resourcesCounter);
159                             }
160                             resources[resourcesCounter++] = res;
161                             break;
162                         case IResource.FOLDER :
163                             resFullPath = res.getFullPath();
164                         
165                             // ignore non-excluded folders on the classpath or that correspond to an output location
166
if ((srcIsProject && !Util.isExcluded(res, inclusionPatterns, exclusionPatterns) && Util.isValidFolderNameForPackage(res.getName(), sourceLevel, complianceLevel))
167                                     || (isClasspathResolved && this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput))) {
168                                 break;
169                             }
170                             // else add non java resource
171
if (resources.length == resourcesCounter) {
172                                 // resize
173
System.arraycopy(
174                                         resources,
175                                         0,
176                                         (resources = new IResource[resourcesCounter * 2]),
177                                         0,
178                                         resourcesCounter);
179                             }
180                             resources[resourcesCounter++] = res;
181                     }
182                 }
183             }
184             if (resources.length != resourcesCounter) {
185                 System.arraycopy(
186                     resources,
187                     0,
188                     (resources = new IResource[resourcesCounter]),
189                     0,
190                     resourcesCounter);
191             }
192         } catch (CoreException e) {
193             resources = NO_NON_JAVA_RESOURCES;
194             resourcesCounter = 0;
195         }
196         return resources;
197     }
198     
199     ProjectCache getProjectCache(JavaProject project) {
200         ProjectCache cache = this.projectCache;
201         if (cache == null) {
202             IPackageFragmentRoot[] roots;
203             Map JavaDoc reverseMap = new HashMap JavaDoc(3);
204             try {
205                 roots = project.getAllPackageFragmentRoots(reverseMap);
206             } catch (JavaModelException e) {
207                 // project does not exist: cannot happen since this is the info of the project
208
roots = new IPackageFragmentRoot[0];
209                 reverseMap.clear();
210             }
211             
212             HashMap JavaDoc rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
213             HashMap JavaDoc pkgFragmentsCaches = new HashMap JavaDoc();
214             int length = roots.length;
215             for (int i = 0; i < length; i++) {
216                 IPackageFragmentRoot root = roots[i];
217                 DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
218                 if (rootInfo == null || rootInfo.project.equals(project)) {
219                     // compute fragment cache
220
HashSetOfArray fragmentsCache = new HashSetOfArray();
221                     initializePackageNames(root, fragmentsCache);
222                     pkgFragmentsCaches.put(root, fragmentsCache);
223                 }
224             }
225             
226             cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches);
227             this.projectCache = cache;
228         }
229         return cache;
230     }
231     
232     /**
233      * Returns an array of non-java resources contained in the receiver.
234      */

235     Object JavaDoc[] getNonJavaResources(JavaProject project) {
236
237         if (this.nonJavaResources == null) {
238             this.nonJavaResources = computeNonJavaResources(project);
239         }
240         return this.nonJavaResources;
241     }
242     
243     private void initializePackageNames(IPackageFragmentRoot root, HashSetOfArray fragmentsCache) {
244         IJavaElement[] frags = null;
245         try {
246             if (!root.isOpen()) {
247                 PackageFragmentRootInfo info = root.isArchive() ? new JarPackageFragmentRootInfo() : new PackageFragmentRootInfo();
248                 ((PackageFragmentRoot) root).computeChildren(info, new HashMap JavaDoc());
249                 frags = info.children;
250             } else
251                 frags = root.getChildren();
252         } catch (JavaModelException e) {
253             // root doesn't exist: ignore
254
return;
255         }
256         for (int j = 0, length2 = frags.length; j < length2; j++) {
257             fragmentsCache.add(((PackageFragment) frags[j]).names);
258         }
259     }
260
261     /*
262      * Returns whether the given path is a classpath entry or an output location.
263      */

264     private boolean isClasspathEntryOrOutputLocation(IPath path, IClasspathEntry[] resolvedClasspath, IPath projectOutput) {
265         if (projectOutput.equals(path)) return true;
266         for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
267             IClasspathEntry entry = resolvedClasspath[i];
268             if (entry.getPath().equals(path)) {
269                 return true;
270             }
271             IPath output;
272             if ((output = entry.getOutputLocation()) != null && output.equals(path)) {
273                 return true;
274             }
275         }
276         return false;
277     }
278     
279     /*
280      * Creates a new name lookup for this project info.
281      * The given project is assumed to be the handle of this info.
282      * This name lookup first looks in the given working copies.
283      */

284     NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
285         ProjectCache cache = getProjectCache(project);
286         HashtableOfArrayToObject allPkgFragmentsCache = cache.allPkgFragmentsCache;
287         if (allPkgFragmentsCache == null) {
288             HashMap JavaDoc rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
289             IPackageFragmentRoot[] allRoots = cache.allPkgFragmentRootsCache;
290             int length = allRoots.length;
291             allPkgFragmentsCache = new HashtableOfArrayToObject();
292             for (int i = 0; i < length; i++) {
293                 IPackageFragmentRoot root = allRoots[i];
294                 DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
295                 JavaProject rootProject = rootInfo == null ? project : rootInfo.project;
296                 HashSetOfArray fragmentsCache;
297                 if (rootProject.equals(project)) {
298                     // retrieve package fragments cache from this project
299
fragmentsCache = (HashSetOfArray) cache.pkgFragmentsCaches.get(root);
300                 } else {
301                     // retrieve package fragments cache from the root's project
302
ProjectCache rootProjectCache;
303                     try {
304                         rootProjectCache = rootProject.getProjectCache();
305                     } catch (JavaModelException e) {
306                         // project doesn't exit
307
continue;
308                     }
309                     fragmentsCache = (HashSetOfArray) rootProjectCache.pkgFragmentsCaches.get(root);
310                 }
311                 if (fragmentsCache == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183833
312
fragmentsCache = new HashSetOfArray();
313                     initializePackageNames(root, fragmentsCache);
314                 }
315                 Object JavaDoc[][] set = fragmentsCache.set;
316                 for (int j = 0, length2 = set.length; j < length2; j++) {
317                     String JavaDoc[] pkgName = (String JavaDoc[]) set[j];
318                     if (pkgName == null)
319                         continue;
320                     Object JavaDoc existing = allPkgFragmentsCache.get(pkgName);
321                     if (existing == null || existing == NO_ROOTS) {
322                         allPkgFragmentsCache.put(pkgName, root);
323                         // ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
324
// are also in the map
325
addSuperPackageNames(pkgName, allPkgFragmentsCache);
326                     } else {
327                         if (existing instanceof PackageFragmentRoot) {
328                             allPkgFragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
329                         } else {
330                             IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
331                             int rootLength = roots.length;
332                             System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
333                             roots[rootLength] = root;
334                             allPkgFragmentsCache.put(pkgName, roots);
335                         }
336                     }
337                 }
338             }
339             cache.allPkgFragmentsCache = allPkgFragmentsCache;
340         }
341         return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries);
342     }
343     
344     /*
345      * Reset the package fragment roots and package fragment caches
346      */

347     void resetCaches() {
348         this.projectCache = null;
349     }
350     
351     /**
352      * Set the fNonJavaResources to res value
353      */

354     void setNonJavaResources(Object JavaDoc[] resources) {
355
356         this.nonJavaResources = resources;
357     }
358     
359 }
360
Popular Tags