KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > search > JavaSearchScope


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.search;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.ResourcesPlugin;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.jdt.core.IClasspathContainer;
23 import org.eclipse.jdt.core.IClasspathEntry;
24 import org.eclipse.jdt.core.IJavaElement;
25 import org.eclipse.jdt.core.IJavaElementDelta;
26 import org.eclipse.jdt.core.IJavaModel;
27 import org.eclipse.jdt.core.IJavaProject;
28 import org.eclipse.jdt.core.IMember;
29 import org.eclipse.jdt.core.IPackageFragmentRoot;
30 import org.eclipse.jdt.core.JavaCore;
31 import org.eclipse.jdt.core.JavaModelException;
32 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
33 import org.eclipse.jdt.internal.core.ClasspathEntry;
34 import org.eclipse.jdt.internal.core.JavaElement;
35 import org.eclipse.jdt.internal.core.JavaModel;
36 import org.eclipse.jdt.internal.core.JavaModelManager;
37 import org.eclipse.jdt.internal.core.JavaProject;
38 import org.eclipse.jdt.internal.core.PackageFragment;
39 import org.eclipse.jdt.internal.core.util.Util;
40
41 /**
42  * A Java-specific scope for searching relative to one or more java elements.
43  */

44 public class JavaSearchScope extends AbstractSearchScope {
45     
46     private ArrayList JavaDoc elements;
47
48     /* The paths of the resources in this search scope
49         (or the classpath entries' paths if the resources are projects)
50     */

51     private ArrayList JavaDoc projectPaths = new ArrayList JavaDoc(); // container paths projects
52
private int[] projectIndexes; // Indexes of projects in list
53
private String JavaDoc[] containerPaths; // path to the container (e.g. /P/src, /P/lib.jar, c:\temp\mylib.jar)
54
private String JavaDoc[] relativePaths; // path relative to the container (e.g. x/y/Z.class, x/y, (empty))
55
private boolean[] isPkgPath; // in the case of packages, matches must be direct children of the folder
56
protected AccessRuleSet[] pathRestrictions;
57     private int pathsCount;
58     private int threshold;
59     
60     private IPath[] enclosingProjectsAndJars;
61     public final static AccessRuleSet NOT_ENCLOSED = new AccessRuleSet(null, null);
62
63 public JavaSearchScope() {
64     this(5);
65 }
66
67 private JavaSearchScope(int size) {
68     initialize(size);
69     
70     //disabled for now as this could be expensive
71
//JavaModelManager.getJavaModelManager().rememberScope(this);
72
}
73     
74 private void addEnclosingProjectOrJar(IPath path) {
75     int length = this.enclosingProjectsAndJars.length;
76     for (int i = 0; i < length; i++) {
77         if (this.enclosingProjectsAndJars[i].equals(path)) return;
78     }
79     System.arraycopy(
80         this.enclosingProjectsAndJars,
81         0,
82         this.enclosingProjectsAndJars = new IPath[length+1],
83         0,
84         length);
85     this.enclosingProjectsAndJars[length] = path;
86 }
87
88 /**
89  * Add java project all fragment roots to current java search scope.
90  * @see #add(JavaProject, IPath, int, HashSet, IClasspathEntry)
91  */

92 public void add(JavaProject project, int includeMask, HashSet JavaDoc visitedProject) throws JavaModelException {
93     add(project, null, includeMask, visitedProject, null);
94 }
95 /**
96  * Add a path to current java search scope or all project fragment roots if null.
97  * Use project resolved classpath to retrieve and store access restriction on each classpath entry.
98  * Recurse if dependent projects are found.
99  * @param javaProject Project used to get resolved classpath entries
100  * @param pathToAdd Path to add in case of single element or null if user want to add all project package fragment roots
101  * @param includeMask Mask to apply on classpath entries
102  * @param visitedProjects Set to avoid infinite recursion
103  * @param referringEntry Project raw entry in referring project classpath
104  * @throws JavaModelException May happen while getting java model info
105  */

106 void add(JavaProject javaProject, IPath pathToAdd, int includeMask, HashSet JavaDoc visitedProjects, IClasspathEntry referringEntry) throws JavaModelException {
107     IProject project = javaProject.getProject();
108     if (!project.isAccessible() || !visitedProjects.add(project)) return;
109
110     IPath projectPath = project.getFullPath();
111     String JavaDoc projectPathString = projectPath.toString();
112     this.addEnclosingProjectOrJar(projectPath);
113
114     IClasspathEntry[] entries = javaProject.getResolvedClasspath();
115     IJavaModel model = javaProject.getJavaModel();
116     JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
117     for (int i = 0, length = entries.length; i < length; i++) {
118         IClasspathEntry entry = entries[i];
119         AccessRuleSet access = null;
120         ClasspathEntry cpEntry = (ClasspathEntry) entry;
121         if (referringEntry != null) {
122             // Add only exported entries.
123
// Source folder are implicitly exported.
124
if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) continue;
125             cpEntry = cpEntry.combineWith((ClasspathEntry)referringEntry);
126 // cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry);
127
}
128         access = cpEntry.getAccessRuleSet();
129         switch (entry.getEntryKind()) {
130             case IClasspathEntry.CPE_LIBRARY:
131                 IClasspathEntry rawEntry = null;
132                 Map JavaDoc rootPathToRawEntries = perProjectInfo.rootPathToRawEntries;
133                 if (rootPathToRawEntries != null) {
134                     rawEntry = (IClasspathEntry) rootPathToRawEntries.get(entry.getPath());
135                 }
136                 if (rawEntry == null) break;
137                 switch (rawEntry.getEntryKind()) {
138                     case IClasspathEntry.CPE_LIBRARY:
139                     case IClasspathEntry.CPE_VARIABLE:
140                         if ((includeMask & APPLICATION_LIBRARIES) != 0) {
141                             IPath path = entry.getPath();
142                             if (pathToAdd == null || pathToAdd.equals(path)) {
143                                 String JavaDoc pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
144                                 add(projectPath.toString(), "", pathToString, false/*not a package*/, access); //$NON-NLS-1$
145
addEnclosingProjectOrJar(path);
146                             }
147                         }
148                         break;
149                     case IClasspathEntry.CPE_CONTAINER:
150                         IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), javaProject);
151                         if (container == null) break;
152                         if ((container.getKind() == IClasspathContainer.K_APPLICATION && (includeMask & APPLICATION_LIBRARIES) != 0)
153                                 || (includeMask & SYSTEM_LIBRARIES) != 0) {
154                             IPath path = entry.getPath();
155                             if (pathToAdd == null || pathToAdd.equals(path)) {
156                                 String JavaDoc pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
157                                 add(projectPath.toString(), "", pathToString, false/*not a package*/, access); //$NON-NLS-1$
158
addEnclosingProjectOrJar(path);
159                             }
160                         }
161                         break;
162                 }
163                 break;
164             case IClasspathEntry.CPE_PROJECT:
165                 if ((includeMask & REFERENCED_PROJECTS) != 0) {
166                     IPath path = entry.getPath();
167                     if (pathToAdd == null || pathToAdd.equals(path)) {
168                         add((JavaProject) model.getJavaProject(entry.getPath().lastSegment()), null, includeMask, visitedProjects, cpEntry);
169                     }
170                 }
171                 break;
172             case IClasspathEntry.CPE_SOURCE:
173                 if ((includeMask & SOURCES) != 0) {
174                     IPath path = entry.getPath();
175                     if (pathToAdd == null || pathToAdd.equals(path)) {
176                         add(projectPath.toString(), Util.relativePath(path,1/*remove project segment*/), projectPathString, false/*not a package*/, access);
177                     }
178                 }
179                 break;
180         }
181     }
182 }
183 /**
184  * Add an element to the java search scope.
185  * @param element The element we want to add to current java search scope
186  * @throws JavaModelException May happen if some Java Model info are not available
187  */

188 public void add(IJavaElement element) throws JavaModelException {
189     IPath containerPath = null;
190     String JavaDoc containerPathToString = null;
191     int includeMask = SOURCES | APPLICATION_LIBRARIES | SYSTEM_LIBRARIES;
192     switch (element.getElementType()) {
193         case IJavaElement.JAVA_MODEL:
194             // a workspace sope should be used
195
break;
196         case IJavaElement.JAVA_PROJECT:
197             add((JavaProject)element, null, includeMask, new HashSet JavaDoc(2), null);
198             break;
199         case IJavaElement.PACKAGE_FRAGMENT_ROOT:
200             IPackageFragmentRoot root = (IPackageFragmentRoot)element;
201             IPath rootPath = root.getPath();
202             containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : rootPath;
203             containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
204             IResource rootResource = root.getResource();
205             String JavaDoc projectPath = root.getJavaProject().getPath().toString();
206             if (rootResource != null && rootResource.isAccessible()) {
207                 String JavaDoc relativePath = Util.relativePath(rootResource.getFullPath(), containerPath.segmentCount());
208                 add(projectPath, relativePath, containerPathToString, false/*not a package*/, null);
209             } else {
210                 add(projectPath, "", containerPathToString, false/*not a package*/, null); //$NON-NLS-1$
211
}
212             break;
213         case IJavaElement.PACKAGE_FRAGMENT:
214             root = (IPackageFragmentRoot)element.getParent();
215             projectPath = root.getJavaProject().getPath().toString();
216             if (root.isArchive()) {
217                 String JavaDoc relativePath = Util.concatWith(((PackageFragment) element).names, '/');
218                 containerPath = root.getPath();
219                 containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
220                 add(projectPath, relativePath, containerPathToString, true/*package*/, null);
221             } else {
222                 IResource resource = element.getResource();
223                 if (resource != null) {
224                     if (resource.isAccessible()) {
225                         containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.getPath();
226                     } else {
227                         // for working copies, get resource container full path
228
containerPath = resource.getParent().getFullPath();
229                     }
230                     containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
231                     String JavaDoc relativePath = Util.relativePath(resource.getFullPath(), containerPath.segmentCount());
232                     add(projectPath, relativePath, containerPathToString, true/*package*/, null);
233                 }
234             }
235             break;
236         default:
237             // remember sub-cu (or sub-class file) java elements
238
if (element instanceof IMember) {
239                 if (this.elements == null) {
240                     this.elements = new ArrayList JavaDoc();
241                 }
242                 this.elements.add(element);
243             }
244             root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
245             projectPath = root.getJavaProject().getPath().toString();
246             String JavaDoc relativePath;
247             if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
248                 containerPath = root.getParent().getPath();
249                 relativePath = Util.relativePath(getPath(element, false/*full path*/), 1/*remove project segmet*/);
250             } else {
251                 containerPath = root.getPath();
252                 relativePath = getPath(element, true/*relative path*/).toString();
253             }
254             containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
255             add(projectPath, relativePath, containerPathToString, false/*not a package*/, null);
256     }
257     
258     if (containerPath != null)
259         addEnclosingProjectOrJar(containerPath);
260 }
261
262 /**
263  * Adds the given path to this search scope. Remember if subfolders need to be included
264  * and associated access restriction as well.
265  */

266 private void add(String JavaDoc projectPath, String JavaDoc relativePath, String JavaDoc containerPath, boolean isPackage, AccessRuleSet access) {
267     // normalize containerPath and relativePath
268
containerPath = normalize(containerPath);
269     relativePath = normalize(relativePath);
270     int length = this.containerPaths.length,
271         index = (containerPath.hashCode()& 0x7FFFFFFF) % length;
272     String JavaDoc currentRelativePath, currentContainerPath;
273     while ((currentRelativePath = this.relativePaths[index]) != null && (currentContainerPath = this.containerPaths[index]) != null) {
274         if (currentRelativePath.equals(relativePath) && currentContainerPath.equals(containerPath))
275             return;
276         if (++index == length) {
277             index = 0;
278         }
279     }
280     int idx = this.projectPaths.indexOf(projectPath);
281     if (idx == -1) {
282         // store project in separated list to minimize memory footprint
283
this.projectPaths.add(projectPath);
284         idx = this.projectPaths.indexOf(projectPath);
285     }
286     this.projectIndexes[index] = idx;
287     this.relativePaths[index] = relativePath;
288     this.containerPaths[index] = containerPath;
289     this.isPkgPath[index] = isPackage;
290     if (this.pathRestrictions != null)
291         this.pathRestrictions[index] = access;
292     else if (access != null) {
293         this.pathRestrictions = new AccessRuleSet[this.relativePaths.length];
294         this.pathRestrictions[index] = access;
295     }
296
297     // assumes the threshold is never equal to the size of the table
298
if (++this.pathsCount > this.threshold)
299         rehash();
300 }
301
302 /*
303  * E.g.
304  *
305  * 1. /P/src/pkg/X.java
306  * 2. /P/src/pkg
307  * 3. /P/lib.jar|org/eclipse/jdt/core/IJavaElement.class
308  * 4. /home/mylib.jar|x/y/z/X.class
309  * 5. c:\temp\mylib.jar|x/y/Y.class
310  *
311  * @see IJavaSearchScope#encloses(String)
312  */

313 public boolean encloses(String JavaDoc resourcePathString) {
314     int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR);
315     if (separatorIndex != -1) {
316         // internal or external jar (case 3, 4, or 5)
317
String JavaDoc jarPath = resourcePathString.substring(0, separatorIndex);
318         String JavaDoc relativePath = resourcePathString.substring(separatorIndex+1);
319         return indexOf(jarPath, relativePath) >= 0;
320     }
321     // resource in workspace (case 1 or 2)
322
return indexOf(resourcePathString) >= 0;
323 }
324
325 /**
326  * Returns paths list index of given path or -1 if not found.
327  * NOTE: Use indexOf(String, String) for path inside jars
328  *
329  * @param fullPath the full path of the resource, e.g.
330  * 1. /P/src/pkg/X.java
331  * 2. /P/src/pkg
332  */

333 private int indexOf(String JavaDoc fullPath) {
334     // cannot guess the index of the container path
335
// fallback to sequentially looking at all known paths
336
for (int i = 0, length = this.relativePaths.length; i < length; i++) {
337         String JavaDoc currentRelativePath = this.relativePaths[i];
338         if (currentRelativePath == null) continue;
339         String JavaDoc currentContainerPath = this.containerPaths[i];
340         String JavaDoc currentFullPath = currentRelativePath.length() == 0 ? currentContainerPath : (currentContainerPath + '/' + currentRelativePath);
341         if (encloses(currentFullPath, fullPath, i))
342             return i;
343     }
344     return -1;
345 }
346
347 /**
348  * Returns paths list index of given path or -1 if not found.
349  * @param containerPath the path of the container, e.g.
350  * 1. /P/src
351  * 2. /P
352  * 3. /P/lib.jar
353  * 4. /home/mylib.jar
354  * 5. c:\temp\mylib.jar
355  * @param relativePath the forward slash path relatively to the container, e.g.
356  * 1. x/y/Z.class
357  * 2. x/y
358  * 3. X.java
359  * 4. (empty)
360  */

361 private int indexOf(String JavaDoc containerPath, String JavaDoc relativePath) {
362     // use the hash to get faster comparison
363
int length = this.containerPaths.length,
364         index = (containerPath.hashCode()& 0x7FFFFFFF) % length;
365     String JavaDoc currentContainerPath;
366     while ((currentContainerPath = this.containerPaths[index]) != null) {
367         if (currentContainerPath.equals(containerPath)) {
368             String JavaDoc currentRelativePath = this.relativePaths[index];
369             if (encloses(currentRelativePath, relativePath, index))
370                 return index;
371         }
372         if (++index == length) {
373             index = 0;
374         }
375     }
376     return -1;
377 }
378
379 /*
380  * Returns whether the enclosing path encloses the given path (or is equal to it)
381  */

382 private boolean encloses(String JavaDoc enclosingPath, String JavaDoc path, int index) {
383     // normalize given path as it can come from outside
384
path = normalize(path);
385     
386     int pathLength = path.length();
387     int enclosingLength = enclosingPath.length();
388     if (pathLength < enclosingLength) {
389         return false;
390     }
391     if (enclosingLength == 0) {
392         return true;
393     }
394     if (pathLength == enclosingLength) {
395         return path.equals(enclosingPath);
396     }
397     if (!this.isPkgPath[index]) {
398         return path.startsWith(enclosingPath)
399             && path.charAt(enclosingLength) == '/';
400     } else {
401         // if looking at a package, this scope encloses the given path
402
// if the given path is a direct child of the folder
403
// or if the given path path is the folder path (see bug 13919 Declaration for package not found if scope is not project)
404
if (path.startsWith(enclosingPath)
405             && ((enclosingPath.length() == path.lastIndexOf('/'))
406                 || (enclosingPath.length() == path.length()))) {
407             return true;
408         }
409     }
410     return false;
411 }
412
413 /* (non-Javadoc)
414  * @see IJavaSearchScope#encloses(IJavaElement)
415  */

416 public boolean encloses(IJavaElement element) {
417     if (this.elements != null) {
418         for (int i = 0, length = this.elements.size(); i < length; i++) {
419             IJavaElement scopeElement = (IJavaElement)this.elements.get(i);
420             IJavaElement searchedElement = element;
421             while (searchedElement != null) {
422                 if (searchedElement.equals(scopeElement))
423                     return true;
424                 searchedElement = searchedElement.getParent();
425             }
426         }
427         return false;
428     }
429     IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
430     if (root != null && root.isArchive()) {
431         // external or internal jar
432
IPath rootPath = root.getPath();
433         String JavaDoc rootPathToString = rootPath.getDevice() == null ? rootPath.toString() : rootPath.toOSString();
434         IPath relativePath = getPath(element, true/*relative path*/);
435         return indexOf(rootPathToString, relativePath.toString()) >= 0;
436     }
437     // resource in workspace
438
String JavaDoc fullResourcePathString = getPath(element, false/*full path*/).toString();
439     return indexOf(fullResourcePathString) >= 0;
440 }
441
442 /* (non-Javadoc)
443  * @see IJavaSearchScope#enclosingProjectsAndJars()
444  */

445 public IPath[] enclosingProjectsAndJars() {
446     return this.enclosingProjectsAndJars;
447 }
448 private IPath getPath(IJavaElement element, boolean relativeToRoot) {
449     switch (element.getElementType()) {
450         case IJavaElement.JAVA_MODEL:
451             return Path.EMPTY;
452         case IJavaElement.JAVA_PROJECT:
453             return element.getPath();
454         case IJavaElement.PACKAGE_FRAGMENT_ROOT:
455             if (relativeToRoot)
456                 return Path.EMPTY;
457             return element.getPath();
458         case IJavaElement.PACKAGE_FRAGMENT:
459             String JavaDoc relativePath = Util.concatWith(((PackageFragment) element).names, '/');
460             return getPath(element.getParent(), relativeToRoot).append(new Path(relativePath));
461         case IJavaElement.COMPILATION_UNIT:
462         case IJavaElement.CLASS_FILE:
463             return getPath(element.getParent(), relativeToRoot).append(new Path(element.getElementName()));
464         default:
465             return getPath(element.getParent(), relativeToRoot);
466     }
467 }
468
469 /**
470  * Get access rule set corresponding to a given path.
471  * @param relativePath The path user want to have restriction access
472  * @return The access rule set for given path or null if none is set for it.
473  * Returns specific uninit access rule set when scope does not enclose the given path.
474  */

475 public AccessRuleSet getAccessRuleSet(String JavaDoc relativePath, String JavaDoc containerPath) {
476     int index = indexOf(containerPath, relativePath);
477     if (index == -1) {
478         // this search scope does not enclose given path
479
return NOT_ENCLOSED;
480     }
481     if (this.pathRestrictions == null)
482         return null;
483     return this.pathRestrictions[index];
484 }
485
486 protected void initialize(int size) {
487     this.pathsCount = 0;
488     this.threshold = size; // size represents the expected number of elements
489
int extraRoom = (int) (size * 1.75f);
490     if (this.threshold == extraRoom)
491         extraRoom++;
492     this.relativePaths = new String JavaDoc[extraRoom];
493     this.containerPaths = new String JavaDoc[extraRoom];
494     this.projectPaths = new ArrayList JavaDoc();
495     this.projectIndexes = new int[extraRoom];
496     this.isPkgPath = new boolean[extraRoom];
497     this.pathRestrictions = null; // null to optimize case where no access rules are used
498

499     this.enclosingProjectsAndJars = new IPath[0];
500 }
501
502 /*
503  * Removes trailing slashes from the given path
504  */

505 private String JavaDoc normalize(String JavaDoc path) {
506     int pathLength = path.length();
507     int index = pathLength-1;
508     while (index >= 0 && path.charAt(index) == '/')
509         index--;
510     if (index != pathLength-1)
511         return path.substring(0, index + 1);
512     return path;
513 }
514
515 /*
516  * @see AbstractSearchScope#processDelta(IJavaElementDelta)
517  */

518 public void processDelta(IJavaElementDelta delta) {
519     switch (delta.getKind()) {
520         case IJavaElementDelta.CHANGED:
521             IJavaElementDelta[] children = delta.getAffectedChildren();
522             for (int i = 0, length = children.length; i < length; i++) {
523                 IJavaElementDelta child = children[i];
524                 this.processDelta(child);
525             }
526             break;
527         case IJavaElementDelta.REMOVED:
528             IJavaElement element = delta.getElement();
529             if (this.encloses(element)) {
530                 if (this.elements != null) {
531                     this.elements.remove(element);
532                 }
533                 IPath path = null;
534                 switch (element.getElementType()) {
535                     case IJavaElement.JAVA_PROJECT:
536                         path = ((IJavaProject)element).getProject().getFullPath();
537                     case IJavaElement.PACKAGE_FRAGMENT_ROOT:
538                         if (path == null) {
539                             path = ((IPackageFragmentRoot)element).getPath();
540                         }
541                         int toRemove = -1;
542                         for (int i = 0; i < this.pathsCount; i++) {
543                             if (this.relativePaths[i].equals(path)) { // TODO (jerome) this compares String and IPath !
544
toRemove = i;
545                                 break;
546                             }
547                         }
548                         if (toRemove != -1) {
549                             this.relativePaths[toRemove] = null;
550                             rehash();
551                         }
552                 }
553             }
554             break;
555     }
556 }
557
558 /**
559  * Returns the package fragment root corresponding to a given resource path.
560  *
561  * @param resourcePathString path of expected package fragment root.
562  * @return the {@link IPackageFragmentRoot package fragment root} which path
563  * match the given one or <code>null</code> if none was found.
564  */

565 public IPackageFragmentRoot packageFragmentRoot(String JavaDoc resourcePathString) {
566     int index = -1;
567     int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR);
568     boolean isJarFile = separatorIndex != -1;
569     if (isJarFile) {
570         // internal or external jar (case 3, 4, or 5)
571
String JavaDoc jarPath = resourcePathString.substring(0, separatorIndex);
572         String JavaDoc relativePath = resourcePathString.substring(separatorIndex+1);
573         index = indexOf(jarPath, relativePath);
574     } else {
575         // resource in workspace (case 1 or 2)
576
index = indexOf(resourcePathString);
577     }
578     if (index >= 0) {
579         int idx = projectIndexes[index];
580         String JavaDoc projectPath = idx == -1 ? null : (String JavaDoc) this.projectPaths.get(idx);
581         if (projectPath != null) {
582             IJavaProject project =JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(projectPath));
583             if (isJarFile) {
584                 return project.getPackageFragmentRoot(this.containerPaths[index]);
585             }
586             Object JavaDoc target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), new Path(this.containerPaths[index]+'/'+this.relativePaths[index]), false);
587             if (target instanceof IProject) {
588                 return project.getPackageFragmentRoot((IProject) target);
589             }
590             if (target instanceof IResource) {
591                 IJavaElement element = JavaCore.create((IResource)target);
592                 return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
593             }
594         }
595     }
596     return null;
597 }
598
599 private void rehash() {
600     JavaSearchScope newScope = new JavaSearchScope(this.pathsCount * 2); // double the number of expected elements
601
newScope.projectPaths.ensureCapacity(this.projectPaths.size());
602     String JavaDoc currentPath;
603     for (int i = this.relativePaths.length; --i >= 0;)
604         if ((currentPath = this.relativePaths[i]) != null) {
605             int idx = this.projectIndexes[i];
606             String JavaDoc projectPath = idx == -1 ? null : (String JavaDoc)this.projectPaths.get(idx);
607             newScope.add(projectPath, currentPath, this.containerPaths[i], this.isPkgPath[i], this.pathRestrictions == null ? null : this.pathRestrictions[i]);
608         }
609
610     this.relativePaths = newScope.relativePaths;
611     this.containerPaths = newScope.containerPaths;
612     this.projectPaths = newScope.projectPaths;
613     this.projectIndexes = newScope.projectIndexes;
614     this.isPkgPath = newScope.isPkgPath;
615     this.pathRestrictions = newScope.pathRestrictions;
616     this.threshold = newScope.threshold;
617 }
618
619 public String JavaDoc toString() {
620     StringBuffer JavaDoc result = new StringBuffer JavaDoc("JavaSearchScope on "); //$NON-NLS-1$
621
if (this.elements != null) {
622         result.append("["); //$NON-NLS-1$
623
for (int i = 0, length = this.elements.size(); i < length; i++) {
624             JavaElement element = (JavaElement)this.elements.get(i);
625             result.append("\n\t"); //$NON-NLS-1$
626
result.append(element.toStringWithAncestors());
627         }
628         result.append("\n]"); //$NON-NLS-1$
629
} else {
630         if (this.pathsCount == 0) {
631             result.append("[empty scope]"); //$NON-NLS-1$
632
} else {
633             result.append("["); //$NON-NLS-1$
634
for (int i = 0; i < this.relativePaths.length; i++) {
635                 String JavaDoc path = this.relativePaths[i];
636                 if (path == null) continue;
637                 result.append("\n\t"); //$NON-NLS-1$
638
result.append(this.containerPaths[i]);
639                 if (path.length() > 0) {
640                     result.append('/');
641                     result.append(path);
642                 }
643             }
644             result.append("\n]"); //$NON-NLS-1$
645
}
646     }
647     return result.toString();
648 }
649 }
650
Popular Tags