KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 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.pde.internal.ui.search.dependencies;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.SubProgressMonitor;
27 import org.eclipse.jdt.core.Flags;
28 import org.eclipse.jdt.core.IField;
29 import org.eclipse.jdt.core.IJavaProject;
30 import org.eclipse.jdt.core.IMethod;
31 import org.eclipse.jdt.core.IPackageFragment;
32 import org.eclipse.jdt.core.IType;
33 import org.eclipse.jdt.core.ITypeRoot;
34 import org.eclipse.jdt.core.JavaCore;
35 import org.eclipse.jdt.core.JavaModelException;
36 import org.eclipse.jdt.core.Signature;
37 import org.eclipse.osgi.util.NLS;
38 import org.eclipse.pde.internal.core.ibundle.IBundle;
39 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
40 import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
41 import org.eclipse.pde.internal.core.text.bundle.ExportPackageHeader;
42 import org.eclipse.pde.internal.core.text.bundle.ExportPackageObject;
43 import org.eclipse.pde.internal.core.util.PDEJavaHelper;
44 import org.eclipse.pde.internal.ui.PDEUIMessages;
45 import org.eclipse.ui.actions.WorkspaceModifyOperation;
46 import org.osgi.framework.Constants;
47
48 public class CalculateUsesOperation extends WorkspaceModifyOperation {
49     
50     private IProject fProject;
51     private IBundlePluginModelBase fModel;
52     
53     public CalculateUsesOperation(IProject project, IBundlePluginModelBase model) {
54         fProject = project;
55         fModel = model;
56     }
57
58     protected void execute(IProgressMonitor monitor) throws CoreException,
59             InvocationTargetException JavaDoc, InterruptedException JavaDoc {
60         try {
61             Collection JavaDoc packages = getPublicExportedPackages();
62             if (packages.isEmpty())
63                 return;
64             Map JavaDoc pkgsAndUses = findPackageReferences(packages, monitor);
65             handleSetUsesDirectives(pkgsAndUses);
66         } finally {
67             monitor.done();
68         }
69     }
70     
71     protected Collection JavaDoc getPublicExportedPackages() {
72         IBundle bundle = fModel.getBundleModel().getBundle();
73         IManifestHeader header = bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
74         if (header == null)
75             return Collections.EMPTY_SET;
76         
77         ArrayList JavaDoc list = new ArrayList JavaDoc();
78         ExportPackageObject[] pkgs = ((ExportPackageHeader)header).getPackages();
79         for (int i = 0; i < pkgs.length; i++) {
80             // don't calculate uses directive on private packages
81
if (!pkgs[i].isInternal())
82                 list.add(pkgs[i].getName());
83         }
84         return list;
85     }
86     
87     protected Map JavaDoc findPackageReferences(Collection JavaDoc packages, IProgressMonitor monitor) {
88         IJavaProject jp = JavaCore.create(fProject);
89         HashMap JavaDoc pkgsAndUses = new HashMap JavaDoc();
90         IPackageFragment[] frags = PDEJavaHelper.getPackageFragments(jp, Collections.EMPTY_SET, false);
91         monitor.beginTask("", frags.length * 2); //$NON-NLS-1$
92
for (int i =0; i < frags.length; i++) {
93             monitor.subTask(NLS.bind(PDEUIMessages.CalculateUsesOperation_calculatingDirective, frags[i].getElementName()));
94             if (packages.contains(frags[i].getElementName())) {
95                 HashSet JavaDoc pkgs = new HashSet JavaDoc();
96                 pkgsAndUses.put(frags[i].getElementName(), pkgs);
97                 try {
98                     findReferences(frags[i].getCompilationUnits(), pkgs, new SubProgressMonitor(monitor, 1), false);
99                     findReferences(frags[i].getClassFiles(), pkgs, new SubProgressMonitor(monitor, 1), true);
100                 } catch (JavaModelException e) {
101                 }
102             } else
103                 monitor.worked(2);
104         }
105         return pkgsAndUses;
106     }
107         
108     protected void findReferences(ITypeRoot[] roots, Set JavaDoc pkgs, IProgressMonitor monitor, boolean binary) throws JavaModelException {
109         monitor.beginTask("", roots.length); //$NON-NLS-1$
110
for (int i = 0; i < roots.length; i++) {
111             findReferences(roots[i].findPrimaryType(), pkgs, binary);
112             monitor.worked(1);
113         }
114     }
115     
116     protected void findReferences(IType type, Set JavaDoc pkgs, boolean binary) throws JavaModelException {
117         if (type == null)
118             return;
119         // ignore private classes
120
if (Flags.isPrivate(type.getFlags()))
121             return;
122         
123         IMethod[] methods = type.getMethods();
124         for (int i = 0; i < methods.length; i++) {
125             if (!Flags.isPrivate(methods[i].getFlags())) {
126                 String JavaDoc methodSignature = methods[i].getSignature();
127                 addPackages(Signature.getThrownExceptionTypes(methodSignature), pkgs, type, binary);
128                 addPackages(Signature.getParameterTypes(methodSignature), pkgs, type, binary);
129                 addPackage(Signature.getReturnType(methodSignature), pkgs, type, binary);
130             }
131         }
132         IField[] fields = type.getFields();
133         for (int i =0; i < fields.length; i++)
134             if (!Flags.isPrivate(fields[i].getFlags()))
135                 addPackage(fields[i].getTypeSignature(), pkgs, type, binary);
136         addPackage(type.getSuperclassTypeSignature(), pkgs, type, binary);
137         addPackages(type.getSuperInterfaceTypeSignatures(), pkgs, type, binary);
138         
139         // make sure to check sub classes defined in the class
140
IType[] subTypes = type.getTypes();
141         for (int i = 0; i < subTypes.length; i++) {
142             findReferences(subTypes[i], pkgs, binary);
143         }
144     }
145     
146     protected final void addPackage(String JavaDoc typeSignature, Set JavaDoc pkgs, IType type, boolean binary) throws JavaModelException {
147         if (typeSignature == null)
148             return;
149         if (binary) typeSignature = typeSignature.replace('/', '.');
150         // if typeSignature contains a '.', test to see if it is a subClass first. If not, assume it is a fully qualified name
151
if (typeSignature.indexOf('.') != -1) {
152             try {
153                 String JavaDoc[][] temp = type.resolveType(new String JavaDoc(Signature.toCharArray(typeSignature.toCharArray())));
154                 if (temp != null) {
155                     pkgs.add(temp[0][0]);
156                     return;
157                 }
158             } catch (IllegalArgumentException JavaDoc e) {
159             }
160             String JavaDoc pkg = Signature.getSignatureQualifier(typeSignature);
161             if (pkg.length() > 0) {
162                 pkgs.add(pkg);
163                 return;
164             }
165         // if typeSignature does not contain a '.', then assume the package name is in an import statement and try to resolve through the type object
166
} else {
167             String JavaDoc typeName = Signature.getSignatureSimpleName(typeSignature);
168             String JavaDoc[][] result = type.resolveType(typeName);
169             if (result != null)
170                 pkgs.add(result[0][0]);
171         }
172     }
173     
174     protected final void addPackages(String JavaDoc[] typeSignatures, Set JavaDoc pkgs, IType type, boolean binary) throws JavaModelException {
175         for (int i = 0; i < typeSignatures.length; i++)
176             addPackage(typeSignatures[i], pkgs, type, binary);
177     }
178     
179     protected void handleSetUsesDirectives(Map JavaDoc pkgsAndUses) {
180         if (pkgsAndUses.isEmpty())
181             return;
182         setUsesDirectives(pkgsAndUses);
183     }
184     
185     protected void setUsesDirectives(Map JavaDoc pkgsAndUses) {
186         IBundle bundle = fModel.getBundleModel().getBundle();
187         IManifestHeader header = bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
188         // header will not equal null b/c we would not get this far (ie. no exported packages so we would have returned earlier
189
ExportPackageObject[] pkgs = ((ExportPackageHeader)header).getPackages();
190         for (int i =0; i < pkgs.length; i++) {
191             if (!pkgsAndUses.containsKey(pkgs[i].getName()))
192                 continue;
193             String JavaDoc value = getDirectiveValue(pkgs[i].getName(), pkgsAndUses);
194             pkgs[i].setUsesDirective(value);
195         }
196     }
197     
198     protected String JavaDoc getDirectiveValue(String JavaDoc pkgName, Map JavaDoc pkgsAndUses) {
199         Set JavaDoc usesPkgs = (Set JavaDoc)pkgsAndUses.get(pkgName);
200         usesPkgs.remove(pkgName);
201         StringBuffer JavaDoc buffer = null;
202         Iterator JavaDoc it = usesPkgs.iterator();
203         while (it.hasNext()) {
204             String JavaDoc usedPkgName = (String JavaDoc)it.next();
205             if (usedPkgName.startsWith("java.")) { //$NON-NLS-1$
206
// we should not include java.* packages (bug 167968)
207
it.remove();
208                 continue;
209             }
210             if (buffer == null)
211                 buffer = new StringBuffer JavaDoc();
212             else
213                 buffer.append(',');
214             buffer.append(usedPkgName);
215             it.remove();
216         }
217         if (usesPkgs.isEmpty())
218             pkgsAndUses.remove(pkgName);
219         return (buffer == null) ? null : buffer.toString();
220     }
221
222 }
223
Popular Tags