KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.eclipse.core.runtime.IPath;
14 import org.eclipse.jdt.core.IClasspathEntry;
15 import org.eclipse.jdt.core.IJavaElement;
16 import org.eclipse.jdt.core.IJavaModel;
17 import org.eclipse.jdt.core.IJavaProject;
18 import org.eclipse.jdt.core.JavaModelException;
19 import org.eclipse.jdt.core.search.IJavaSearchScope;
20 import org.eclipse.jdt.core.search.SearchPattern;
21 import org.eclipse.jdt.internal.compiler.util.SimpleSet;
22 import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
23 import org.eclipse.jdt.internal.core.JavaModelManager;
24 import org.eclipse.jdt.internal.core.JavaProject;
25 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
26 import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
27 import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
28
29 /**
30  * Selects the indexes that correspond to projects in a given search scope
31  * and that are dependent on a given focus element.
32  */

33 public class IndexSelector {
34     IJavaSearchScope searchScope;
35     SearchPattern pattern;
36     IPath[] indexLocations; // cache of the keys for looking index up
37

38 public IndexSelector(
39         IJavaSearchScope searchScope,
40         SearchPattern pattern) {
41     
42     this.searchScope = searchScope;
43     this.pattern = pattern;
44 }
45 /**
46  * Returns whether elements of the given project or jar can see the given focus (an IJavaProject or
47  * a JarPackageFragmentRot) either because the focus is part of the project or the jar, or because it is
48  * accessible throught the project's classpath
49  */

50 public static boolean canSeeFocus(IJavaElement focus, boolean isPolymorphicSearch, IPath projectOrJarPath) {
51     try {
52         IClasspathEntry[] focusEntries = null;
53         if (isPolymorphicSearch) {
54             JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
55             focusEntries = focusProject.getExpandedClasspath();
56         }
57         IJavaModel model = focus.getJavaModel();
58         IJavaProject project = getJavaProject(projectOrJarPath, model);
59         if (project != null)
60             return canSeeFocus(focus, (JavaProject) project, focusEntries);
61
62         // projectOrJarPath is a jar
63
// it can see the focus only if it is on the classpath of a project that can see the focus
64
IJavaProject[] allProjects = model.getJavaProjects();
65         for (int i = 0, length = allProjects.length; i < length; i++) {
66             JavaProject otherProject = (JavaProject) allProjects[i];
67             IClasspathEntry entry = otherProject.getClasspathEntryFor(projectOrJarPath);
68             if (entry != null
69                     && entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
70                     && canSeeFocus(focus, otherProject, focusEntries))
71                 return true;
72         }
73         return false;
74     } catch (JavaModelException e) {
75         return false;
76     }
77 }
78 public static boolean canSeeFocus(IJavaElement focus, JavaProject javaProject, IClasspathEntry[] focusEntriesForPolymorphicSearch) {
79     try {
80         if (focus.equals(javaProject))
81             return true;
82
83         if (focusEntriesForPolymorphicSearch != null) {
84             // look for refering project
85
IPath projectPath = javaProject.getProject().getFullPath();
86             for (int i = 0, length = focusEntriesForPolymorphicSearch.length; i < length; i++) {
87                 IClasspathEntry entry = focusEntriesForPolymorphicSearch[i];
88                 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(projectPath))
89                     return true;
90             }
91         }
92         if (focus instanceof JarPackageFragmentRoot) {
93             // focus is part of a jar
94
IPath focusPath = focus.getPath();
95             IClasspathEntry[] entries = javaProject.getExpandedClasspath();
96             for (int i = 0, length = entries.length; i < length; i++) {
97                 IClasspathEntry entry = entries[i];
98                 if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(focusPath))
99                     return true;
100             }
101             return false;
102         }
103         // look for dependent projects
104
IPath focusPath = ((JavaProject) focus).getProject().getFullPath();
105         IClasspathEntry[] entries = javaProject.getExpandedClasspath();
106         for (int i = 0, length = entries.length; i < length; i++) {
107             IClasspathEntry entry = entries[i];
108             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(focusPath))
109                 return true;
110         }
111         return false;
112     } catch (JavaModelException e) {
113         return false;
114     }
115 }
116 /*
117  * Compute the list of paths which are keying index files.
118  */

119 private void initializeIndexLocations() {
120     IPath[] projectsAndJars = this.searchScope.enclosingProjectsAndJars();
121     IndexManager manager = JavaModelManager.getJavaModelManager().getIndexManager();
122     SimpleSet locations = new SimpleSet();
123     IJavaElement focus = MatchLocator.projectOrJarFocus(this.pattern);
124     if (focus == null) {
125         for (int i = 0; i < projectsAndJars.length; i++)
126             locations.add(manager.computeIndexLocation(projectsAndJars[i]));
127     } else {
128         try {
129             // find the projects from projectsAndJars that see the focus then walk those projects looking for the jars from projectsAndJars
130
int length = projectsAndJars.length;
131             JavaProject[] projectsCanSeeFocus = new JavaProject[length];
132             SimpleSet visitedProjects = new SimpleSet(length);
133             int projectIndex = 0;
134             SimpleSet jarsToCheck = new SimpleSet(length);
135             IClasspathEntry[] focusEntries = null;
136             if (this.pattern instanceof MethodPattern) { // should consider polymorphic search for method patterns
137
JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
138                 focusEntries = focusProject.getExpandedClasspath();
139             }
140             IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
141             for (int i = 0; i < length; i++) {
142                 IPath path = projectsAndJars[i];
143                 JavaProject project = (JavaProject) getJavaProject(path, model);
144                 if (project != null) {
145                     visitedProjects.add(project);
146                     if (canSeeFocus(focus, project, focusEntries)) {
147                         locations.add(manager.computeIndexLocation(path));
148                         projectsCanSeeFocus[projectIndex++] = project;
149                     }
150                 } else {
151                     jarsToCheck.add(path);
152                 }
153             }
154             for (int i = 0; i < projectIndex && jarsToCheck.elementSize > 0; i++) {
155                 IClasspathEntry[] entries = projectsCanSeeFocus[i].getResolvedClasspath();
156                 for (int j = entries.length; --j >= 0;) {
157                     IClasspathEntry entry = entries[j];
158                     if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
159                         IPath path = entry.getPath();
160                         if (jarsToCheck.includes(path)) {
161                             locations.add(manager.computeIndexLocation(entry.getPath()));
162                             jarsToCheck.remove(path);
163                         }
164                     }
165                 }
166             }
167             // jar files can be included in the search scope without including one of the projects that references them, so scan all projects that have not been visited
168
if (jarsToCheck.elementSize > 0) {
169                 IJavaProject[] allProjects = model.getJavaProjects();
170                 for (int i = 0, l = allProjects.length; i < l && jarsToCheck.elementSize > 0; i++) {
171                     JavaProject project = (JavaProject) allProjects[i];
172                     if (!visitedProjects.includes(project)) {
173                         IClasspathEntry[] entries = project.getResolvedClasspath();
174                         for (int j = entries.length; --j >= 0;) {
175                             IClasspathEntry entry = entries[j];
176                             if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
177                                 IPath path = entry.getPath();
178                                 if (jarsToCheck.includes(path)) {
179                                     locations.add(manager.computeIndexLocation(entry.getPath()));
180                                     jarsToCheck.remove(path);
181                                 }
182                             }
183                         }
184                     }
185                 }
186             }
187         } catch (JavaModelException e) {
188             // ignored
189
}
190     }
191
192     this.indexLocations = new IPath[locations.elementSize];
193     Object JavaDoc[] values = locations.values;
194     int count = 0;
195     for (int i = values.length; --i >= 0;)
196         if (values[i] != null)
197             this.indexLocations[count++] = (IPath) values[i];
198 }
199 public IPath[] getIndexLocations() {
200     if (this.indexLocations == null) {
201         this.initializeIndexLocations();
202     }
203     return this.indexLocations;
204 }
205
206 /**
207  * Returns the java project that corresponds to the given path.
208  * Returns null if the path doesn't correspond to a project.
209  */

210 private static IJavaProject getJavaProject(IPath path, IJavaModel model) {
211     IJavaProject project = model.getJavaProject(path.lastSegment());
212     if (project.exists()) {
213         return project;
214     }
215     return null;
216 }
217 }
218
Popular Tags