KickJava   Java API By Example, From Geeks To Geeks.

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


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.Path;
14 import org.eclipse.jdt.core.IClassFile;
15 import org.eclipse.jdt.core.ICompilationUnit;
16 import org.eclipse.jdt.core.IJavaElement;
17 import org.eclipse.jdt.core.IPackageFragment;
18 import org.eclipse.jdt.core.IPackageFragmentRoot;
19 import org.eclipse.jdt.core.IType;
20 import org.eclipse.jdt.core.JavaModelException;
21 import org.eclipse.jdt.core.compiler.CharOperation;
22 import org.eclipse.jdt.core.search.IJavaSearchScope;
23 import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
24 import org.eclipse.jdt.core.search.TypeNameRequestor;
25 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
26 import org.eclipse.jdt.internal.core.Openable;
27 import org.eclipse.jdt.internal.core.PackageFragmentRoot;
28 import org.eclipse.jdt.internal.core.util.HandleFactory;
29 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
30
31 /**
32  * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
33  * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
34  * char[] packageName,
35  * int packageMatchRule,
36  * char[] typeName,
37  * int typeMatchRule,
38  * int searchFor,
39  * org.eclipse.jdt.core.search.IJavaSearchScope scope,
40  * IRestrictedAccessTypeRequestor nameRequestor,
41  * int waitingPolicy,
42  * org.eclipse.core.runtime.IProgressMonitor monitor) }.
43  * from API method {@link org.eclipse.jdt.core.search.SearchEngine#searchAllTypeNames(
44  * char[] packageName,
45  * int packageMatchRule,
46  * char[] typeName,
47  * int matchRule,
48  * int searchFor,
49  * org.eclipse.jdt.core.search.IJavaSearchScope scope,
50  * TypeNameRequestor nameRequestor,
51  * int waitingPolicy,
52  * org.eclipse.core.runtime.IProgressMonitor monitor) }.
53  */

54 public class TypeNameMatchRequestorWrapper implements IRestrictedAccessTypeRequestor {
55     TypeNameMatchRequestor requestor;
56     private IJavaSearchScope scope; // scope is needed to retrieve project path for external resource
57
private HandleFactory handleFactory; // in case of IJavaSearchScope defined by clients, use an HandleFactory instead
58

59     /**
60      * Cache package fragment root information to optimize speed performance.
61      */

62     private String JavaDoc lastPkgFragmentRootPath;
63     private IPackageFragmentRoot lastPkgFragmentRoot;
64
65     /**
66      * Cache package handles to optimize memory.
67      */

68     private HashtableOfArrayToObject packageHandles;
69
70 public TypeNameMatchRequestorWrapper(TypeNameMatchRequestor requestor, IJavaSearchScope scope) {
71     this.requestor = requestor;
72     this.scope = scope;
73     if (!(scope instanceof JavaSearchScope)) {
74         this.handleFactory = new HandleFactory();
75     }
76 }
77
78 /* (non-Javadoc)
79  * @see org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor#acceptType(int, char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
80  */

81 public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String JavaDoc path, AccessRestriction access) {
82     try {
83         IType type = null;
84         if (this.handleFactory != null) {
85             Openable openable = this.handleFactory.createOpenable(path, this.scope);
86             if (openable == null) return;
87             switch (openable.getElementType()) {
88                 case IJavaElement.COMPILATION_UNIT:
89                     ICompilationUnit cu = (ICompilationUnit) openable;
90                     if (enclosingTypeNames != null && enclosingTypeNames.length > 0) {
91                         type = cu.getType(new String JavaDoc(enclosingTypeNames[0]));
92                         for (int j=1, l=enclosingTypeNames.length; j<l; j++) {
93                             type = type.getType(new String JavaDoc(enclosingTypeNames[j]));
94                         }
95                         type = type.getType(new String JavaDoc(simpleTypeName));
96                     } else {
97                         type = cu.getType(new String JavaDoc(simpleTypeName));
98                     }
99                     break;
100                 case IJavaElement.CLASS_FILE:
101                     type = ((IClassFile)openable).getType();
102                     break;
103             }
104         } else {
105             int separatorIndex= path.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
106             type = separatorIndex == -1
107                 ? createTypeFromPath(path, new String JavaDoc(simpleTypeName), enclosingTypeNames)
108                 : createTypeFromJar(path, separatorIndex);
109         }
110         if (type != null) {
111             this.requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, modifiers));
112         }
113     } catch (JavaModelException e) {
114         // skip
115
}
116 }
117 private IType createTypeFromJar(String JavaDoc resourcePath, int separatorIndex) throws JavaModelException {
118     // path to a class file inside a jar
119
// Optimization: cache package fragment root handle and package handles
120
if (this.lastPkgFragmentRootPath == null
121             || this.lastPkgFragmentRootPath.length() > resourcePath.length()
122             || !resourcePath.startsWith(this.lastPkgFragmentRootPath)) {
123         String JavaDoc jarPath= resourcePath.substring(0, separatorIndex);
124         IPackageFragmentRoot root= ((JavaSearchScope)this.scope).packageFragmentRoot(resourcePath);
125         if (root == null) return null;
126         this.lastPkgFragmentRootPath= jarPath;
127         this.lastPkgFragmentRoot= root;
128         this.packageHandles= new HashtableOfArrayToObject(5);
129     }
130     // create handle
131
String JavaDoc classFilePath= resourcePath.substring(separatorIndex + 1);
132     String JavaDoc[] simpleNames = new Path(classFilePath).segments();
133     String JavaDoc[] pkgName;
134     int length = simpleNames.length-1;
135     if (length > 0) {
136         pkgName = new String JavaDoc[length];
137         System.arraycopy(simpleNames, 0, pkgName, 0, length);
138     } else {
139         pkgName = CharOperation.NO_STRINGS;
140     }
141     IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
142     if (pkgFragment == null) {
143         pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName);
144         this.packageHandles.put(pkgName, pkgFragment);
145     }
146     return pkgFragment.getClassFile(simpleNames[length]).getType();
147 }
148 private IType createTypeFromPath(String JavaDoc resourcePath, String JavaDoc simpleTypeName, char[][] enclosingTypeNames) throws JavaModelException {
149     // path to a file in a directory
150
// Optimization: cache package fragment root handle and package handles
151
int rootPathLength = -1;
152     if (this.lastPkgFragmentRootPath == null
153         || !(resourcePath.startsWith(this.lastPkgFragmentRootPath)
154             && (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0
155             && resourcePath.charAt(rootPathLength) == '/')) {
156         IPackageFragmentRoot root = ((JavaSearchScope)this.scope).packageFragmentRoot(resourcePath);
157         if (root == null) return null;
158         this.lastPkgFragmentRoot = root;
159         this.lastPkgFragmentRootPath = this.lastPkgFragmentRoot.getPath().toString();
160         this.packageHandles = new HashtableOfArrayToObject(5);
161     }
162     // create handle
163
resourcePath = resourcePath.substring(this.lastPkgFragmentRootPath.length() + 1);
164     String JavaDoc[] simpleNames = new Path(resourcePath).segments();
165     String JavaDoc[] pkgName;
166     int length = simpleNames.length-1;
167     if (length > 0) {
168         pkgName = new String JavaDoc[length];
169         System.arraycopy(simpleNames, 0, pkgName, 0, length);
170     } else {
171         pkgName = CharOperation.NO_STRINGS;
172     }
173     IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
174     if (pkgFragment == null) {
175         pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName);
176         this.packageHandles.put(pkgName, pkgFragment);
177     }
178     String JavaDoc simpleName= simpleNames[length];
179     if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(simpleName)) {
180         ICompilationUnit unit= pkgFragment.getCompilationUnit(simpleName);
181         int etnLength = enclosingTypeNames == null ? 0 : enclosingTypeNames.length;
182         IType type = (etnLength == 0) ? unit.getType(simpleTypeName) : unit.getType(new String JavaDoc(enclosingTypeNames[0]));
183         if (etnLength > 0) {
184             for (int i=1; i<etnLength; i++) {
185                 type = type.getType(new String JavaDoc(enclosingTypeNames[i]));
186             }
187             type = type.getType(simpleTypeName);
188         }
189         return type;
190     } else {
191         IClassFile classFile= pkgFragment.getClassFile(simpleName);
192         return classFile.getType();
193     }
194 }
195 }
196
Popular Tags