KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > hierarchy > HierarchyBuilder


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.jdt.internal.core.hierarchy;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.OperationCanceledException;
21 import org.eclipse.jdt.core.IType;
22 import org.eclipse.jdt.core.JavaModelException;
23 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
25 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
26 import org.eclipse.jdt.internal.compiler.env.IGenericType;
27 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
28 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
29 import org.eclipse.jdt.internal.core.*;
30 import org.eclipse.jdt.internal.core.util.ResourceCompilationUnit;
31 import org.eclipse.jdt.internal.core.util.Util;
32
33 public abstract class HierarchyBuilder {
34     /**
35      * The hierarchy being built.
36      */

37     protected TypeHierarchy hierarchy;
38     /**
39      * @see NameLookup
40      */

41     protected NameLookup nameLookup;
42     /**
43      * The resolver used to resolve type hierarchies
44      * @see HierarchyResolver
45      */

46     protected HierarchyResolver hierarchyResolver;
47     /**
48      * A temporary cache of infos to handles to speed info
49      * to handle translation - it only contains the entries
50      * for the types in the region (in other words, it contains
51      * no supertypes outside the region).
52      */

53     protected Map JavaDoc infoToHandle;
54     /*
55      * The dot-separated fully qualified name of the focus type, or null of none.
56      */

57     protected String JavaDoc focusQualifiedName;
58     
59     public HierarchyBuilder(TypeHierarchy hierarchy) throws JavaModelException {
60         
61         this.hierarchy = hierarchy;
62         JavaProject project = (JavaProject) hierarchy.javaProject();
63         
64         IType focusType = hierarchy.getType();
65         org.eclipse.jdt.core.ICompilationUnit unitToLookInside = focusType == null ? null : focusType.getCompilationUnit();
66         org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.hierarchy.workingCopies;
67         org.eclipse.jdt.core.ICompilationUnit[] unitsToLookInside;
68         if (unitToLookInside != null) {
69             int wcLength = workingCopies == null ? 0 : workingCopies.length;
70             if (wcLength == 0) {
71                 unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[] {unitToLookInside};
72             } else {
73                 unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[wcLength+1];
74                 unitsToLookInside[0] = unitToLookInside;
75                 System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
76             }
77         } else {
78             unitsToLookInside = workingCopies;
79         }
80         if (project != null) {
81             SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
82             this.nameLookup = searchableEnvironment.nameLookup;
83             this.hierarchyResolver =
84                 new HierarchyResolver(
85                     searchableEnvironment,
86                     project.getOptions(true),
87                     this,
88                     new DefaultProblemFactory());
89         }
90         this.infoToHandle = new HashMap JavaDoc(5);
91         this.focusQualifiedName = focusType == null ? null : focusType.getFullyQualifiedName();
92     }
93     
94     public abstract void build(boolean computeSubtypes)
95         throws JavaModelException, CoreException;
96     /**
97      * Configure this type hierarchy by computing the supertypes only.
98      */

99     protected void buildSupertypes() {
100         IType focusType = this.getType();
101         if (focusType == null)
102             return;
103         // get generic type from focus type
104
IGenericType type;
105         try {
106             type = (IGenericType) ((JavaElement) focusType).getElementInfo();
107         } catch (JavaModelException e) {
108             // if the focus type is not present, or if cannot get workbench path
109
// we cannot create the hierarchy
110
return;
111         }
112         //NB: no need to set focus type on hierarchy resolver since no other type is injected
113
// in the hierarchy resolver, thus there is no need to check that a type is
114
// a sub or super type of the focus type.
115
this.hierarchyResolver.resolve(type);
116
117         // Add focus if not already in (case of a type with no explicit super type)
118
if (!this.hierarchy.contains(focusType)) {
119             this.hierarchy.addRootClass(focusType);
120         }
121     }
122     /**
123      * Connect the supplied type to its superclass & superinterfaces.
124      * The superclass & superinterfaces are the identical binary or source types as
125      * supplied by the name environment.
126      */

127     public void connect(
128         IGenericType type,
129         IType typeHandle,
130         IType superclassHandle,
131         IType[] superinterfaceHandles) {
132
133         /*
134          * Temporary workaround for 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class
135          */

136         if (typeHandle == null)
137             return;
138         if (TypeHierarchy.DEBUG) {
139             System.out.println(
140                 "Connecting: " + ((JavaElement) typeHandle).toStringWithAncestors()); //$NON-NLS-1$
141
System.out.println(
142                 " to superclass: " //$NON-NLS-1$
143
+ (superclassHandle == null
144                         ? "<None>" //$NON-NLS-1$
145
: ((JavaElement) superclassHandle).toStringWithAncestors()));
146             System.out.print(" and superinterfaces:"); //$NON-NLS-1$
147
if (superinterfaceHandles == null || superinterfaceHandles.length == 0) {
148                 System.out.println(" <None>"); //$NON-NLS-1$
149
} else {
150                 System.out.println();
151                 for (int i = 0, length = superinterfaceHandles.length; i < length; i++) {
152                     if (superinterfaceHandles[i] == null) continue;
153                     System.out.println(
154                         " " + ((JavaElement) superinterfaceHandles[i]).toStringWithAncestors()); //$NON-NLS-1$
155
}
156             }
157         }
158         // now do the caching
159
switch (TypeDeclaration.kind(type.getModifiers())) {
160             case TypeDeclaration.CLASS_DECL :
161             case TypeDeclaration.ENUM_DECL :
162                 if (superclassHandle == null) {
163                     this.hierarchy.addRootClass(typeHandle);
164                 } else {
165                     this.hierarchy.cacheSuperclass(typeHandle, superclassHandle);
166                 }
167                 break;
168             case TypeDeclaration.INTERFACE_DECL :
169             case TypeDeclaration.ANNOTATION_TYPE_DECL :
170                 this.hierarchy.addInterface(typeHandle);
171                 break;
172         }
173         if (superinterfaceHandles == null) {
174             superinterfaceHandles = TypeHierarchy.NO_TYPE;
175         }
176         this.hierarchy.cacheSuperInterfaces(typeHandle, superinterfaceHandles);
177          
178         // record flags
179
this.hierarchy.cacheFlags(typeHandle, type.getModifiers());
180     }
181     /**
182      * Returns a handle for the given generic type or null if not found.
183      */

184     protected IType getHandle(IGenericType genericType, ReferenceBinding binding) {
185         if (genericType == null)
186             return null;
187         if (genericType instanceof HierarchyType) {
188             IType handle = (IType)this.infoToHandle.get(genericType);
189             if (handle == null) {
190                 handle = ((HierarchyType)genericType).typeHandle;
191                 handle = (IType) ((JavaElement) handle).resolved(binding);
192                 this.infoToHandle.put(genericType, handle);
193             }
194             return handle;
195         } else if (genericType.isBinaryType()) {
196             ClassFile classFile = (ClassFile) this.infoToHandle.get(genericType);
197             // if it's null, it's from outside the region, so do lookup
198
if (classFile == null) {
199                 IType handle = lookupBinaryHandle((IBinaryType) genericType);
200                 if (handle == null)
201                     return null;
202                 // case of an anonymous type (see 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class)
203
// optimization: remember the handle for next call (case of java.io.Serializable that a lot of classes implement)
204
classFile = (ClassFile) handle.getParent();
205                 this.infoToHandle.put(genericType, classFile);
206             }
207             return new ResolvedBinaryType(classFile, classFile.getTypeName(), new String JavaDoc(binding.computeUniqueKey()));
208         } else if (genericType instanceof SourceTypeElementInfo) {
209             IType handle = ((SourceTypeElementInfo) genericType).getHandle();
210             return (IType) ((JavaElement) handle).resolved(binding);
211         } else
212             return null;
213     }
214     protected IType getType() {
215         return this.hierarchy.getType();
216     }
217     /**
218      * Looks up and returns a handle for the given binary info.
219      */

220     protected IType lookupBinaryHandle(IBinaryType typeInfo) {
221         int flag;
222         String JavaDoc qualifiedName;
223         switch (TypeDeclaration.kind(typeInfo.getModifiers())) {
224             case TypeDeclaration.CLASS_DECL :
225                 flag = NameLookup.ACCEPT_CLASSES;
226                 break;
227             case TypeDeclaration.INTERFACE_DECL :
228                 flag = NameLookup.ACCEPT_INTERFACES;
229                 break;
230             case TypeDeclaration.ENUM_DECL :
231                 flag = NameLookup.ACCEPT_ENUMS;
232                 break;
233             default:
234                 //case IGenericType.ANNOTATION :
235
flag = NameLookup.ACCEPT_ANNOTATIONS;
236                 break;
237         }
238         char[] bName = typeInfo.getName();
239         qualifiedName = new String JavaDoc(ClassFile.translatedName(bName));
240         if (qualifiedName.equals(this.focusQualifiedName)) return getType();
241         NameLookup.Answer answer = this.nameLookup.findType(qualifiedName,
242             false,
243             flag,
244             true/* consider secondary types */,
245             false/* do NOT wait for indexes */,
246             false/*don't check restrictions*/,
247             null);
248         return answer == null || answer.type == null || !answer.type.isBinary() ? null : answer.type;
249         
250     }
251     protected void worked(IProgressMonitor monitor, int work) {
252         if (monitor != null) {
253             if (monitor.isCanceled()) {
254                 throw new OperationCanceledException();
255             } else {
256                 monitor.worked(work);
257             }
258         }
259     }
260 /**
261  * Create an ICompilationUnit info from the given compilation unit on disk.
262  */

263 protected ICompilationUnit createCompilationUnitFromPath(Openable handle, IFile file) {
264     final char[] elementName = handle.getElementName().toCharArray();
265     return new ResourceCompilationUnit(file, file.getLocationURI()) {
266         public char[] getFileName() {
267             return elementName;
268         }
269     };
270 }
271     /**
272  * Creates the type info from the given class file on disk and
273  * adds it to the given list of infos.
274  */

275 protected IBinaryType createInfoFromClassFile(Openable handle, IResource file) {
276     IBinaryType info = null;
277     try {
278         info = Util.newClassFileReader(file);
279     } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
280         if (TypeHierarchy.DEBUG) {
281             e.printStackTrace();
282         }
283         return null;
284     } catch (java.io.IOException JavaDoc e) {
285         if (TypeHierarchy.DEBUG) {
286             e.printStackTrace();
287         }
288         return null;
289     } catch (CoreException e) {
290         if (TypeHierarchy.DEBUG) {
291             e.printStackTrace();
292         }
293         return null;
294     }
295     this.infoToHandle.put(info, handle);
296     return info;
297 }
298     /**
299  * Create a type info from the given class file in a jar and adds it to the given list of infos.
300  */

301 protected IBinaryType createInfoFromClassFileInJar(Openable classFile) {
302     PackageFragment pkg = (PackageFragment) classFile.getParent();
303     String JavaDoc classFilePath = Util.concatWith(pkg.names, classFile.getElementName(), '/');
304     IBinaryType info = null;
305     java.util.zip.ZipFile JavaDoc zipFile = null;
306     try {
307         zipFile = ((JarPackageFragmentRoot)pkg.getParent()).getJar();
308         info = org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader.read(
309             zipFile,
310             classFilePath);
311     } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
312         if (TypeHierarchy.DEBUG) {
313             e.printStackTrace();
314         }
315         return null;
316     } catch (java.io.IOException JavaDoc e) {
317         if (TypeHierarchy.DEBUG) {
318             e.printStackTrace();
319         }
320         return null;
321     } catch (CoreException e) {
322         if (TypeHierarchy.DEBUG) {
323             e.printStackTrace();
324         }
325         return null;
326     } finally {
327         JavaModelManager.getJavaModelManager().closeZipFile(zipFile);
328     }
329     this.infoToHandle.put(info, classFile);
330     return info;
331 }
332
333 }
334
Popular Tags