1 11 package org.eclipse.pde.internal.ui.search.dependencies; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.ListIterator ; 19 import java.util.Stack ; 20 21 import org.eclipse.core.resources.IProject; 22 import org.eclipse.core.runtime.CoreException; 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.core.runtime.SubProgressMonitor; 25 import org.eclipse.jdt.core.IClassFile; 26 import org.eclipse.jdt.core.ICompilationUnit; 27 import org.eclipse.jdt.core.IJavaElement; 28 import org.eclipse.jdt.core.IJavaProject; 29 import org.eclipse.jdt.core.IPackageFragment; 30 import org.eclipse.jdt.core.IType; 31 import org.eclipse.jdt.core.JavaCore; 32 import org.eclipse.jdt.core.JavaModelException; 33 import org.eclipse.jdt.core.search.IJavaSearchConstants; 34 import org.eclipse.jdt.core.search.IJavaSearchScope; 35 import org.eclipse.jdt.core.search.SearchEngine; 36 import org.eclipse.jdt.core.search.SearchMatch; 37 import org.eclipse.jdt.core.search.SearchParticipant; 38 import org.eclipse.jdt.core.search.SearchPattern; 39 import org.eclipse.jdt.core.search.SearchRequestor; 40 import org.eclipse.jface.operation.IRunnableWithProgress; 41 import org.eclipse.pde.core.plugin.IPluginImport; 42 import org.eclipse.pde.core.plugin.IPluginModelBase; 43 import org.eclipse.pde.core.plugin.PluginRegistry; 44 import org.eclipse.pde.internal.core.ClasspathUtilCore; 45 import org.eclipse.pde.internal.core.ibundle.IBundle; 46 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase; 47 import org.eclipse.pde.internal.core.ibundle.IManifestHeader; 48 import org.eclipse.pde.internal.core.search.PluginJavaSearchUtil; 49 import org.eclipse.pde.internal.core.text.bundle.ExportPackageHeader; 50 import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader; 51 import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject; 52 import org.eclipse.pde.internal.ui.PDEUIMessages; 53 import org.osgi.framework.Constants; 54 55 public class GatherUnusedDependenciesOperation implements IRunnableWithProgress { 56 57 class Requestor extends SearchRequestor { 58 boolean fFound = false; 59 public void acceptSearchMatch(SearchMatch match) throws CoreException { 60 fFound = true; 61 } 62 public boolean foundMatches() { 63 return fFound; 64 } 65 } 66 67 private IPluginModelBase fModel; 68 private ArrayList fList; 69 70 public GatherUnusedDependenciesOperation(IPluginModelBase model) { 71 fModel = model; 72 } 73 74 public void run(IProgressMonitor monitor) throws InvocationTargetException , 75 InterruptedException { 76 77 ImportPackageObject[] packages = null; 78 Collection exportedPackages = null; 79 if (ClasspathUtilCore.hasBundleStructure(fModel)) { 80 IBundle bundle = ((IBundlePluginModelBase)fModel).getBundleModel().getBundle(); 81 IManifestHeader header = bundle.getManifestHeader(Constants.IMPORT_PACKAGE); 82 if (header instanceof ImportPackageHeader) { 83 packages = ((ImportPackageHeader)header).getPackages(); 84 } else if (header != null && header.getValue() != null) { 85 header = new ImportPackageHeader(Constants.IMPORT_PACKAGE, header.getValue(), bundle, System.getProperty("line.separator")); packages = ((ImportPackageHeader)header).getPackages(); 87 } 88 89 header = bundle.getManifestHeader(Constants.EXPORT_PACKAGE); 90 if (header instanceof ExportPackageHeader) { 91 exportedPackages = ((ExportPackageHeader)header).getPackageNames(); 92 } else if (header != null && header.getValue() != null) { 93 header = new ExportPackageHeader(Constants.EXPORT_PACKAGE, header.getValue(), bundle, System.getProperty("line.seperator")); exportedPackages = ((ExportPackageHeader)header).getPackageNames(); 95 } 96 } 97 IPluginImport[] imports = fModel.getPluginBase().getImports(); 98 99 int totalWork = imports.length * 3 + (packages != null ? packages.length : 0) + 1; 100 monitor.beginTask("", totalWork); 102 HashMap usedPlugins = new HashMap (); 103 fList = new ArrayList (); 104 for (int i = 0; i < imports.length; i++) { 105 if (monitor.isCanceled()) 106 break; 107 if (isUnused(imports[i], new SubProgressMonitor(monitor, 3))) { 108 fList.add(imports[i]); 109 } else 110 usedPlugins.put(imports[i].getId(), imports[i]); 111 updateMonitor(monitor, fList.size()); 112 } 113 114 ArrayList usedPackages = new ArrayList (); 115 if (packages != null && !monitor.isCanceled()) { 116 for (int i = 0; i < packages.length; i++) { 117 if (monitor.isCanceled()) 118 break; 119 if (isUnused(packages[i], exportedPackages, new SubProgressMonitor(monitor, 1))) { 120 fList.add(packages[i]); 121 updateMonitor(monitor, fList.size()); 122 } else 123 usedPackages.add(packages[i]); 124 } 125 } 126 if (!monitor.isCanceled()) 127 minimizeDependencies(usedPlugins, usedPackages, monitor); 128 monitor.done(); 129 } 130 131 private void updateMonitor(IProgressMonitor monitor, int size) { 132 monitor.setTaskName( 133 PDEUIMessages.UnusedDependencies_analyze 134 + size 135 + " " + PDEUIMessages.UnusedDependencies_unused 137 + " " + (size == 1 139 ? PDEUIMessages.DependencyExtent_singular 140 : PDEUIMessages.DependencyExtent_plural) 141 + " " + PDEUIMessages.DependencyExtent_found); 143 } 144 145 private boolean isUnused(IPluginImport plugin, SubProgressMonitor monitor) { 146 IPluginModelBase[] models = PluginJavaSearchUtil.getPluginImports(plugin); 147 return !provideJavaClasses(models, monitor); 148 } 149 150 private boolean isUnused(ImportPackageObject pkg, Collection exportedPackages, SubProgressMonitor monitor) { 151 if (exportedPackages != null && exportedPackages.contains(pkg.getValue())) { 152 monitor.done(); 153 return false; 154 } 155 return !provideJavaClasses(pkg, monitor); 156 } 157 158 private boolean provideJavaClasses(IPluginModelBase[] models, IProgressMonitor monitor) { 159 try { 160 IProject project = fModel.getUnderlyingResource().getProject(); 161 if (!project.hasNature(JavaCore.NATURE_ID)) 162 return false; 163 164 IJavaProject jProject = JavaCore.create(project); 165 IPackageFragment[] packageFragments = PluginJavaSearchUtil.collectPackageFragments(models, jProject, true); 166 SearchEngine engine = new SearchEngine(); 167 IJavaSearchScope searchScope = PluginJavaSearchUtil.createSeachScope(jProject); 168 169 monitor.beginTask("", packageFragments.length*2); for (int i = 0; i < packageFragments.length; i++) { 171 IPackageFragment pkgFragment = packageFragments[i]; 172 if (pkgFragment.hasChildren()) { 173 Requestor requestor = new Requestor(); 174 engine.search( 175 SearchPattern.createPattern(pkgFragment, IJavaSearchConstants.REFERENCES), 176 new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, 177 searchScope, requestor, new SubProgressMonitor(monitor, 1)); 178 if (requestor.foundMatches()) { 179 if (provideJavaClasses(packageFragments[i], engine, 180 searchScope, new SubProgressMonitor(monitor, 1))) { 181 return true; 182 } 183 } else 184 monitor.worked(1); 185 } else { 186 monitor.worked(2); 187 } 188 } 189 } catch (CoreException e) { 190 } finally { 191 monitor.done(); 192 } 193 return false; 194 } 195 196 private boolean provideJavaClasses(IPackageFragment packageFragment, 197 SearchEngine engine, IJavaSearchScope searchScope, 198 IProgressMonitor monitor) throws JavaModelException, CoreException { 199 Requestor requestor; 200 IJavaElement[] children = packageFragment.getChildren(); 201 monitor.beginTask("", children.length); 203 try { 204 for (int j = 0; j < children.length; j++) { 205 IType[] types = null; 206 if (children[j] instanceof ICompilationUnit) { 207 types = ((ICompilationUnit) children[j]).getAllTypes(); 208 } else if (children[j] instanceof IClassFile) { 209 types = new IType[] { ((IClassFile) children[j]).getType() }; 210 } 211 if (types != null) { 212 for (int t = 0; t < types.length; t++) { 213 requestor = new Requestor(); 214 engine.search(SearchPattern.createPattern(types[t], 215 IJavaSearchConstants.REFERENCES), 216 new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, 217 searchScope, requestor, new SubProgressMonitor(monitor, 1)); 218 if (requestor.foundMatches()) { 219 return true; 220 } 221 } 222 } 223 } 224 } finally { 225 monitor.done(); 226 } 227 return false; 228 } 229 230 private boolean provideJavaClasses(ImportPackageObject pkg, IProgressMonitor monitor) { 231 try { 232 IProject project = fModel.getUnderlyingResource().getProject(); 233 234 if (!project.hasNature(JavaCore.NATURE_ID)) 235 return false; 236 237 monitor.beginTask("", 1); IJavaProject jProject = JavaCore.create(project); 239 SearchEngine engine = new SearchEngine(); 240 IJavaSearchScope searchScope = PluginJavaSearchUtil.createSeachScope(jProject); 241 Requestor requestor = new Requestor(); 242 String packageName = pkg.getName(); 243 244 engine.search( 245 SearchPattern.createPattern(packageName, IJavaSearchConstants.PACKAGE, 246 IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH), 247 new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, 248 searchScope, requestor, new SubProgressMonitor(monitor, 1)); 249 250 if (requestor.foundMatches()) 251 return true; 252 } catch (CoreException e) { 253 } finally { 254 monitor.done(); 255 } 256 return false; 257 } 258 259 public ArrayList getList() { 260 return fList; 261 } 262 263 public static void removeDependencies(IPluginModelBase model, Object [] elements) { 264 ImportPackageHeader pkgHeader = null; 265 for (int i = 0; i < elements.length; i++) { 266 if (elements[i] instanceof IPluginImport) 267 try { 268 model.getPluginBase().remove((IPluginImport) elements[i]); 269 } catch (CoreException e) {} 270 else if (elements[i] instanceof ImportPackageObject) { 271 if (pkgHeader == null) 272 pkgHeader = (ImportPackageHeader)((ImportPackageObject)elements[i]).getHeader(); 273 pkgHeader.removePackage((ImportPackageObject)elements[i]); 274 } 275 } 276 } 277 278 private void minimizeDependencies(HashMap usedPlugins, ArrayList usedPackages, IProgressMonitor monitor) { 279 ListIterator li = usedPackages.listIterator(); 280 while (li.hasNext()) { 281 ImportPackageObject ipo = (ImportPackageObject) li.next(); 282 String bundle = ipo.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE); 283 if (usedPlugins.containsKey(bundle)) 284 fList.add(ipo); 285 } 286 287 Iterator it = usedPlugins.keySet().iterator(); 288 Stack plugins = new Stack (); 289 while (it.hasNext()) 290 plugins.push(it.next().toString()); 291 292 while (!(plugins.isEmpty())) { 293 String pluginId = (String )plugins.pop(); 294 IPluginModelBase base = PluginRegistry.findModel(pluginId); 295 if (base == null) 296 continue; 297 IPluginImport[] imports = base.getPluginBase().getImports(); 298 299 for (int j = 0; j < imports.length; j++) 300 if (imports[j].isReexported()) { 301 String reExportedId = imports[j].getId(); 302 Object pluginImport = usedPlugins.remove(imports[j].getId()); 303 if (pluginImport != null) { 304 fList.add(pluginImport); 305 updateMonitor(monitor, fList.size()); 306 } 307 plugins.push(reExportedId); 308 } 309 } 310 } 311 } 312 | Popular Tags |