KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > search > dependencies > PackageFinder


1 /*******************************************************************************
2  * Copyright (c) 2007 IBM Corporation.
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.pde.internal.ui.search.dependencies;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.Stack JavaDoc;
18
19 import org.eclipse.core.resources.IContainer;
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.jdt.core.IClassFile;
26 import org.eclipse.jdt.core.IJavaElement;
27 import org.eclipse.jdt.core.IPackageFragment;
28 import org.eclipse.jdt.core.IPackageFragmentRoot;
29 import org.eclipse.jdt.core.JavaCore;
30 import org.eclipse.jdt.core.JavaModelException;
31 import org.eclipse.jdt.core.Signature;
32 import org.eclipse.jdt.core.ToolFactory;
33 import org.eclipse.jdt.core.util.IClassFileReader;
34 import org.eclipse.jdt.core.util.IConstantPool;
35 import org.eclipse.jdt.core.util.IConstantPoolConstant;
36 import org.eclipse.jdt.core.util.IConstantPoolEntry;
37 import org.eclipse.jdt.core.util.IExceptionAttribute;
38 import org.eclipse.jdt.core.util.IFieldInfo;
39 import org.eclipse.jdt.core.util.IMethodInfo;
40 import org.eclipse.osgi.util.ManifestElement;
41 import org.eclipse.pde.internal.core.ibundle.IBundle;
42 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
43 import org.eclipse.pde.internal.ui.PDEUIMessages;
44 import org.osgi.framework.BundleException;
45 import org.osgi.framework.Constants;
46
47 public class PackageFinder {
48     
49     public static Set JavaDoc findPackagesInClassFiles(IClassFile[] files, IProgressMonitor monitor) {
50         Set JavaDoc packages = new HashSet JavaDoc();
51         monitor.beginTask(PDEUIMessages.PackageFinder_taskName, files.length);
52         for (int i = 0; i < files.length; i++) {
53             IClassFileReader reader = ToolFactory.createDefaultClassFileReader(files[i],IClassFileReader.ALL);
54             if (reader!=null)
55                 computeReferencedTypes(reader, packages);
56             monitor.worked(1);
57         }
58         monitor.done();
59         return packages;
60     }
61         
62     static void computeReferencedTypes(IClassFileReader cfr, Set JavaDoc packages) {
63
64         char[][] interfaces= cfr.getInterfaceNames();
65         if (interfaces != null) {
66             for (int i=0; i<interfaces.length; i++) {
67                 //note: have to convert names like Ljava/lang/Object; to java.lang.Object
68
packages.add(getPackage(new String JavaDoc(interfaces[i]).replace('/','.')));
69             }
70         }
71         
72         char[] scn = cfr.getSuperclassName();
73         if (scn != null){
74             packages.add(getPackage(new String JavaDoc(scn).replace('/','.')));
75         }
76         
77         IFieldInfo[] fieldInfo= cfr.getFieldInfos();
78         for (int i=0; i<fieldInfo.length; i++) {
79
80             String JavaDoc fieldName = new String JavaDoc(fieldInfo[i].getDescriptor());
81             if (!isPrimitiveTypeSignature(fieldName)) {
82                 String JavaDoc fieldDescriptor= extractFullyQualifiedType(fieldName);
83                 packages.add(getPackage(new String JavaDoc(fieldDescriptor)));
84             }
85         }
86         
87         IMethodInfo[] methodInfo= cfr.getMethodInfos();
88         for (int i=0; i<methodInfo.length; i++) {
89             IExceptionAttribute exceptionAttribute= methodInfo[i].getExceptionAttribute();
90             if (exceptionAttribute != null) {
91                 char[][] exceptionNames= exceptionAttribute.getExceptionNames();
92                 for (int j=0; j<exceptionNames.length; j++) {
93                     packages.add(getPackage(new String JavaDoc(exceptionNames[j]).replace('/','.')));
94                 }
95             }
96             
97             String JavaDoc descriptor= new String JavaDoc(methodInfo[i].getDescriptor());
98             //add parameter types
99
String JavaDoc [] parameterTypes = Signature.getParameterTypes(descriptor);
100             for (int j = 0;j<parameterTypes.length;j++) {
101                 //have to parse to convert [Ljava/lang/String; to java.lang.String
102
if (!isPrimitiveTypeSignature(parameterTypes[j])) {
103                     packages.add(getPackage(new String JavaDoc(extractFullyQualifiedType(parameterTypes[j]))));
104                 }
105             }
106             //add return type
107
String JavaDoc returnType = Signature.getReturnType(descriptor);
108             if (!isPrimitiveTypeSignature(returnType)) {
109                 returnType = extractFullyQualifiedType(returnType);
110                 packages.add(getPackage(returnType));
111             }
112         }
113         
114         // Is there more to extract from the constant pool??
115
IConstantPoolEntry entry;
116         IConstantPool pool= cfr.getConstantPool();
117         int length= pool.getConstantPoolCount();
118         for (int i=1; i<length; i++) {
119             switch (pool.getEntryKind(i)) {
120                 case IConstantPoolConstant.CONSTANT_Class:
121                     // add reference to the class
122
entry= pool.decodeEntry(i);
123                     //note: may have to convert names like Ljava/lang/Object; to java.lang.Object
124
String JavaDoc className = new String JavaDoc(entry.getClassInfoName()).replace('/','.');
125                     className = className.indexOf(';') >=0 ? extractFullyQualifiedType(className) : className;
126                     packages.add(getPackage(className));
127                     break;
128                 
129                 case IConstantPoolConstant.CONSTANT_NameAndType:
130                     // add reference to the name and type
131
entry= pool.decodeEntry(i);
132                     int descIndex= entry.getNameAndTypeInfoDescriptorIndex();
133                     if (pool.getEntryKind(descIndex) == IConstantPoolConstant.CONSTANT_Utf8) {
134                         entry= pool.decodeEntry(descIndex);
135                         char[] type= entry.getUtf8Value();
136                         if (type[0] == '(') {
137                             // Method signature.
138

139                             //add parameter types
140
String JavaDoc descriptor = new String JavaDoc(type);
141                             String JavaDoc [] parameterTypes = Signature.getParameterTypes(descriptor);
142                             for (int j = 0;j<parameterTypes.length;j++) {
143                                 if (!isPrimitiveTypeSignature(parameterTypes[j])) {
144                                     packages.add(getPackage(extractFullyQualifiedType(parameterTypes[j])));
145                                 }
146                             }
147                             //add return type
148
String JavaDoc returnType = Signature.getReturnType(descriptor);
149                             if (!isPrimitiveTypeSignature(returnType)) {
150                                 returnType = extractFullyQualifiedType(returnType);
151                                 packages.add(getPackage(returnType));
152                             }
153                             
154                         } else {
155                             // Field type.
156
String JavaDoc typeString = new String JavaDoc(type);
157                             if (!isPrimitiveTypeSignature(typeString)) {
158                                 packages.add(getPackage(extractFullyQualifiedType(typeString)));
159                             }
160                         }
161                     }
162                     break;
163             }
164         }
165         packages.remove(""); // removes default package if it exists //$NON-NLS-1$
166
}
167     
168     static boolean isPrimitiveTypeSignature(String JavaDoc typeSig) {
169         //check for array of primitives
170
/* bug 101514 - changed >= 2 and typeSig.subString(1, typeSig.length) to incorporate multi dimensional arrays of primitives */
171         if (typeSig.length() >= 2 && typeSig.startsWith("[") && isPrimitiveTypeSignature(typeSig.substring(1,typeSig.length()))) return true; //$NON-NLS-1$
172

173         //check for primitives
174
if (typeSig.length() != 1) return false;
175         if (typeSig.equals(Signature.SIG_VOID) ||
176             typeSig.equals(Signature.SIG_BOOLEAN) ||
177             typeSig.equals(Signature.SIG_BYTE) ||
178             typeSig.equals(Signature.SIG_CHAR) ||
179             typeSig.equals(Signature.SIG_DOUBLE) ||
180             typeSig.equals(Signature.SIG_FLOAT) ||
181             typeSig.equals(Signature.SIG_INT) ||
182             typeSig.equals(Signature.SIG_LONG) ||
183             typeSig.equals(Signature.SIG_SHORT)) {
184             
185             return true;
186         }
187         return false;
188     }
189
190     static String JavaDoc extractFullyQualifiedType(String JavaDoc typeName) {
191         
192         //first convert from / to .
193
typeName = typeName.replace('/','.');
194         
195         //hack to handle inner classes
196
if (typeName.indexOf('$') >=0) {
197             //inner class
198
typeName = Signature.toString(typeName);
199             typeName = typeName.substring(0,typeName.lastIndexOf('.')) + "$" + typeName.substring(typeName.lastIndexOf('.')+1); //$NON-NLS-1$
200
} else {
201             //not an inner class
202
typeName = Signature.toString(typeName);
203         }
204         
205         //remove array indicator if it is there
206
typeName = typeName.endsWith("[]") ? typeName.substring(0,typeName.length()-2) : typeName; //$NON-NLS-1$
207

208         return typeName;
209     }
210     
211     static String JavaDoc getPackage(String JavaDoc classType){
212         int period = classType.lastIndexOf('.');
213         return (period == -1) ? "" : classType.substring(0, period); // if no period, then we have a class in the default package, return "" for packagename //$NON-NLS-1$
214
}
215     
216     public static IClassFile[] getClassFiles(IProject project, IBundlePluginModelBase base) {
217         ArrayList JavaDoc classFiles = new ArrayList JavaDoc();
218         IBundle bundle = base.getBundleModel().getBundle();
219         String JavaDoc value = bundle.getHeader(Constants.BUNDLE_CLASSPATH);
220         if (value == null)
221             value = "."; //$NON-NLS-1$
222
ManifestElement elems[] = null;
223         try {
224             elems = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, value);
225         } catch (BundleException e) {
226             return new IClassFile[0];
227         }
228         for (int i = 0; i < elems.length; i++) {
229             String JavaDoc lib = elems[i].getValue();
230             IResource res = project.findMember(lib);
231             if (res != null) {
232                 addClassFilesFromResource(res, classFiles);
233             }
234         }
235         return (IClassFile[]) classFiles.toArray(new IClassFile[classFiles.size()]);
236     }
237         
238     private static void addClassFilesFromResource(IResource res, List JavaDoc classFiles) {
239         if (res == null)
240             return;
241         Stack JavaDoc stack = new Stack JavaDoc();
242         if (res instanceof IContainer) {
243             stack.push(res);
244             while(!stack.isEmpty()) {
245                 try {
246                     IResource[] children = ((IContainer)stack.pop()).members();
247                     for (int i = 0; i < children.length; i++)
248                         if (children[i] instanceof IFile &&
249                                 "class".equals(children[i].getFileExtension())) { //$NON-NLS-1$
250
classFiles.add(JavaCore.createClassFileFrom((IFile)children[i]));
251                         } else if (children[i] instanceof IContainer)
252                             stack.push(children[i]);
253                 } catch (CoreException e) {
254                 }
255             }
256         } else if (res instanceof IFile) {
257             if (res.getFileExtension().equals("jar") || res.getFileExtension().equals("zip")) { //$NON-NLS-1$ //$NON-NLS-2$
258
IPackageFragmentRoot root = JavaCore.create(res.getProject()).getPackageFragmentRoot(res);
259                 if (root == null)
260                     return;
261                 try {
262                     IJavaElement[] children = root.getChildren();
263                     for (int i = 0; i < children.length; i++) {
264                         if (children[i] instanceof IPackageFragment) {
265                             IPackageFragment frag = (IPackageFragment) children[i];
266                             IClassFile[] files = frag.getClassFiles();
267                             for (int j = 0; j < files.length; j++)
268                                 classFiles.add(files[j]);
269                         }
270                     }
271                 } catch (JavaModelException e) {
272                 }
273             } else if (res.getFileExtension().equals("class")) //$NON-NLS-1$
274
JavaCore.createClassFileFrom((IFile)res);
275         }
276     }
277
278 }
279
Popular Tags