Java tutorial
/******************************************************************************* * Copyright (c) 2005, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.pde.internal.ui.search.dependencies; import org.eclipse.pde.core.plugin.IPluginImport; import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject; import java.lang.reflect.InvocationTargetException; import java.util.*; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.search.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.pde.core.plugin.*; import org.eclipse.pde.internal.core.ClasspathUtilCore; import org.eclipse.pde.internal.core.ibundle.*; import org.eclipse.pde.internal.core.search.PluginJavaSearchUtil; import org.eclipse.pde.internal.core.text.bundle.*; import org.eclipse.pde.internal.ui.PDEUIMessages; import org.osgi.framework.Constants; public class GatherUnusedDependenciesOperation implements IRunnableWithProgress { class Requestor extends SearchRequestor { boolean fFound = false; public void acceptSearchMatch(SearchMatch match) throws CoreException { fFound = true; } public boolean foundMatches() { return fFound; } } private IPluginModelBase fModel; private ArrayList<Object> fList; public GatherUnusedDependenciesOperation(IPluginModelBase model) { fModel = model; } public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { ImportPackageObject[] packages = null; Collection<?> exportedPackages = null; if (ClasspathUtilCore.hasBundleStructure(fModel)) { IBundle bundle = ((IBundlePluginModelBase) fModel).getBundleModel().getBundle(); IManifestHeader header = bundle.getManifestHeader(Constants.IMPORT_PACKAGE); if (header instanceof ImportPackageHeader) { packages = ((ImportPackageHeader) header).getPackages(); } else if (header != null && header.getValue() != null) { header = new ImportPackageHeader(Constants.IMPORT_PACKAGE, header.getValue(), bundle, System.getProperty("line.separator")); //$NON-NLS-1$ packages = ((ImportPackageHeader) header).getPackages(); } header = bundle.getManifestHeader(Constants.EXPORT_PACKAGE); if (header instanceof ExportPackageHeader) { exportedPackages = ((ExportPackageHeader) header).getPackageNames(); } else if (header != null && header.getValue() != null) { header = new ExportPackageHeader(Constants.EXPORT_PACKAGE, header.getValue(), bundle, System.getProperty("line.seperator")); //$NON-NLS-1$ exportedPackages = ((ExportPackageHeader) header).getPackageNames(); } } IPluginImport[] imports = fModel.getPluginBase().getImports(); int totalWork = imports.length * 3 + (packages != null ? packages.length : 0) + 1; monitor.beginTask("", totalWork); //$NON-NLS-1$ HashMap<String, IPluginImport> usedPlugins = new HashMap<String, IPluginImport>(); fList = new ArrayList<Object>(); for (int i = 0; i < imports.length; i++) { if (monitor.isCanceled()) break; if (isUnused(imports[i], new SubProgressMonitor(monitor, 3))) { fList.add(imports[i]); } else usedPlugins.put(imports[i].getId(), imports[i]); updateMonitor(monitor, fList.size()); } ArrayList<ImportPackageObject> usedPackages = new ArrayList<ImportPackageObject>(); if (packages != null && !monitor.isCanceled()) { for (int i = 0; i < packages.length; i++) { if (monitor.isCanceled()) break; if (isUnused(packages[i], exportedPackages, new SubProgressMonitor(monitor, 1))) { fList.add(packages[i]); updateMonitor(monitor, fList.size()); } else usedPackages.add(packages[i]); } } if (!monitor.isCanceled()) minimizeDependencies(usedPlugins, usedPackages, monitor); monitor.done(); } private void updateMonitor(IProgressMonitor monitor, int size) { monitor.setTaskName(PDEUIMessages.UnusedDependencies_analyze + size + " " //$NON-NLS-1$ + PDEUIMessages.UnusedDependencies_unused + " " //$NON-NLS-1$ + (size == 1 ? PDEUIMessages.DependencyExtent_singular : PDEUIMessages.DependencyExtent_plural) + " " //$NON-NLS-1$ + PDEUIMessages.DependencyExtent_found); } private boolean isUnused(IPluginImport plugin, SubProgressMonitor monitor) { IPluginModelBase[] models = PluginJavaSearchUtil.getPluginImports(plugin); return !provideJavaClasses(models, monitor); } private boolean isUnused(ImportPackageObject pkg, Collection<?> exportedPackages, SubProgressMonitor monitor) { if (exportedPackages != null && exportedPackages.contains(pkg.getValue())) { monitor.done(); return false; } return !provideJavaClasses(pkg, monitor); } private boolean provideJavaClasses(IPluginModelBase[] models, IProgressMonitor monitor) { try { IProject project = fModel.getUnderlyingResource().getProject(); if (!project.hasNature(JavaCore.NATURE_ID)) return false; IJavaProject jProject = JavaCore.create(project); IPackageFragment[] packageFragments = PluginJavaSearchUtil.collectPackageFragments(models, jProject, true); SearchEngine engine = new SearchEngine(); IJavaSearchScope searchScope = PluginJavaSearchUtil.createSeachScope(jProject); monitor.beginTask("", packageFragments.length * 2); //$NON-NLS-1$ for (int i = 0; i < packageFragments.length; i++) { IPackageFragment pkgFragment = packageFragments[i]; if (pkgFragment.hasChildren()) { Requestor requestor = new Requestor(); engine.search(SearchPattern.createPattern(pkgFragment, IJavaSearchConstants.REFERENCES), new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, searchScope, requestor, new SubProgressMonitor(monitor, 1)); if (requestor.foundMatches()) { if (provideJavaClasses(packageFragments[i], engine, searchScope, new SubProgressMonitor(monitor, 1))) { return true; } } else monitor.worked(1); } else { monitor.worked(2); } } } catch (CoreException e) { } finally { monitor.done(); } return false; } private boolean provideJavaClasses(IPackageFragment packageFragment, SearchEngine engine, IJavaSearchScope searchScope, IProgressMonitor monitor) throws JavaModelException, CoreException { Requestor requestor; IJavaElement[] children = packageFragment.getChildren(); monitor.beginTask("", children.length); //$NON-NLS-1$ try { for (int j = 0; j < children.length; j++) { IType[] types = null; if (children[j] instanceof ICompilationUnit) { types = ((ICompilationUnit) children[j]).getAllTypes(); } else if (children[j] instanceof IClassFile) { types = new IType[] { ((IClassFile) children[j]).getType() }; } if (types != null) { for (int t = 0; t < types.length; t++) { requestor = new Requestor(); engine.search(SearchPattern.createPattern(types[t], IJavaSearchConstants.REFERENCES), new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, searchScope, requestor, new SubProgressMonitor(monitor, 1)); if (requestor.foundMatches()) { return true; } } } } } finally { monitor.done(); } return false; } private boolean provideJavaClasses(ImportPackageObject pkg, IProgressMonitor monitor) { try { IProject project = fModel.getUnderlyingResource().getProject(); if (!project.hasNature(JavaCore.NATURE_ID)) return false; monitor.beginTask("", 1); //$NON-NLS-1$ IJavaProject jProject = JavaCore.create(project); SearchEngine engine = new SearchEngine(); IJavaSearchScope searchScope = PluginJavaSearchUtil.createSeachScope(jProject); Requestor requestor = new Requestor(); String packageName = pkg.getName(); engine.search( SearchPattern.createPattern(packageName, IJavaSearchConstants.PACKAGE, IJavaSearchConstants.REFERENCES, SearchPattern.R_EXACT_MATCH), new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, searchScope, requestor, new SubProgressMonitor(monitor, 1)); if (requestor.foundMatches()) return true; } catch (CoreException e) { } finally { monitor.done(); } return false; } public ArrayList<Object> getList() { return fList; } public static void removeDependencies(IPluginModelBase model, Object[] elements) { ImportPackageHeader pkgHeader = null; for (int i = 0; i < elements.length; i++) { if (elements[i] instanceof IPluginImport) try { model.getPluginBase().remove((IPluginImport) elements[i]); } catch (CoreException e) { } else if (elements[i] instanceof ImportPackageObject) { if (pkgHeader == null) pkgHeader = (ImportPackageHeader) ((ImportPackageObject) elements[i]).getHeader(); pkgHeader.removePackage((ImportPackageObject) elements[i]); } } } private void minimizeDependencies(HashMap<String, IPluginImport> usedPlugins, ArrayList<ImportPackageObject> usedPackages, IProgressMonitor monitor) { ListIterator<ImportPackageObject> li = usedPackages.listIterator(); while (li.hasNext()) { ImportPackageObject ipo = li.next(); String bundle = ipo.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE); if (usedPlugins.containsKey(bundle)) fList.add(ipo); } Iterator<String> it = usedPlugins.keySet().iterator(); Stack<String> plugins = new Stack<String>(); while (it.hasNext()) plugins.push(it.next().toString()); while (!(plugins.isEmpty())) { String pluginId = plugins.pop(); IPluginModelBase base = PluginRegistry.findModel(pluginId); if (base == null) continue; IPluginImport[] imports = base.getPluginBase().getImports(); for (int j = 0; j < imports.length; j++) if (imports[j].isReexported()) { String reExportedId = imports[j].getId(); Object pluginImport = usedPlugins.remove(imports[j].getId()); if (pluginImport != null) { fList.add(pluginImport); updateMonitor(monitor, fList.size()); } plugins.push(reExportedId); } } } }