1 /*******************************************************************************
2  *  Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  *  This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License 2.0
6  *  which accompanies this distribution, and is available at
7  *  https://www.eclipse.org/legal/epl-2.0/
8  *
9  *  SPDX-License-Identifier: EPL-2.0
10  *
11  *  Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.pde.internal.core.search;
15 
16 import java.io.File;
17 import java.util.ArrayList;
18 import java.util.HashSet;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.jdt.core.IJavaElement;
24 import org.eclipse.jdt.core.IJavaProject;
25 import org.eclipse.jdt.core.IPackageFragment;
26 import org.eclipse.jdt.core.IPackageFragmentRoot;
27 import org.eclipse.jdt.core.JavaModelException;
28 import org.eclipse.jdt.core.search.IJavaSearchScope;
29 import org.eclipse.jdt.core.search.SearchEngine;
30 import org.eclipse.osgi.service.resolver.VersionRange;
31 import org.eclipse.pde.core.plugin.IFragmentModel;
32 import org.eclipse.pde.core.plugin.IPlugin;
33 import org.eclipse.pde.core.plugin.IPluginBase;
34 import org.eclipse.pde.core.plugin.IPluginImport;
35 import org.eclipse.pde.core.plugin.IPluginLibrary;
36 import org.eclipse.pde.core.plugin.IPluginModelBase;
37 import org.eclipse.pde.core.plugin.PluginRegistry;
38 import org.eclipse.pde.internal.core.ClasspathUtilCore;
39 import org.eclipse.pde.internal.core.PDEManager;
40 
41 public class PluginJavaSearchUtil {
42 
getPluginImports(IPluginImport dep)43 	public static IPluginModelBase[] getPluginImports(IPluginImport dep) {
44 		HashSet<IPluginModelBase> set = new HashSet<>();
45 		VersionRange range = new VersionRange(dep.getVersion());
46 		collectAllPrerequisites(PluginRegistry.findModel(dep.getId(), range, null), set);
47 		return set.toArray(new IPluginModelBase[set.size()]);
48 	}
49 
getPluginImports(String pluginImportID)50 	public static IPluginModelBase[] getPluginImports(String pluginImportID) {
51 		HashSet<IPluginModelBase> set = new HashSet<>();
52 		collectAllPrerequisites(PluginRegistry.findModel(pluginImportID), set);
53 		return set.toArray(new IPluginModelBase[set.size()]);
54 	}
55 
collectAllPrerequisites(IPluginModelBase model, HashSet<IPluginModelBase> set)56 	public static void collectAllPrerequisites(IPluginModelBase model, HashSet<IPluginModelBase> set) {
57 		if (model == null || !set.add(model)) {
58 			return;
59 		}
60 		IPluginImport[] imports = model.getPluginBase().getImports();
61 		for (IPluginImport pluginImport : imports) {
62 			if (pluginImport.isReexported()) {
63 				IPluginModelBase child = PluginRegistry.findModel(pluginImport.getId());
64 				if (child != null) {
65 					collectAllPrerequisites(child, set);
66 				}
67 			}
68 		}
69 	}
70 
collectPackageFragments(IPluginModelBase[] models, IJavaProject parentProject, boolean filterEmptyPackages)71 	public static IPackageFragment[] collectPackageFragments(IPluginModelBase[] models, IJavaProject parentProject, boolean filterEmptyPackages) throws JavaModelException {
72 		ArrayList<IPackageFragment> result = new ArrayList<>();
73 		IPackageFragmentRoot[] roots = parentProject.getAllPackageFragmentRoots();
74 
75 		for (IPluginModelBase model : models) {
76 			IResource resource = model.getUnderlyingResource();
77 			if (resource == null) {
78 				ArrayList<Path> libraryPaths = new ArrayList<>();
79 				addLibraryPaths(model, libraryPaths);
80 				for (IPackageFragmentRoot root : roots) {
81 					if (libraryPaths.contains(root.getPath())) {
82 						extractPackageFragments(root, result, filterEmptyPackages);
83 					}
84 				}
85 			} else {
86 				IProject project = resource.getProject();
87 				for (IPackageFragmentRoot root : roots) {
88 					IJavaProject jProject = (IJavaProject) root.getParent();
89 					if (jProject.getProject().equals(project)) {
90 						extractPackageFragments(root, result, filterEmptyPackages);
91 					}
92 				}
93 			}
94 		}
95 		return result.toArray(new IPackageFragment[result.size()]);
96 	}
97 
extractPackageFragments(IPackageFragmentRoot root, ArrayList<IPackageFragment> result, boolean filterEmpty)98 	private static void extractPackageFragments(IPackageFragmentRoot root, ArrayList<IPackageFragment> result, boolean filterEmpty) {
99 		try {
100 			IJavaElement[] children = root.getChildren();
101 			for (IJavaElement element : children) {
102 				IPackageFragment fragment = (IPackageFragment) element;
103 				if (!filterEmpty || fragment.hasChildren()) {
104 					result.add(fragment);
105 				}
106 			}
107 		} catch (JavaModelException e) {
108 		}
109 	}
110 
addLibraryPaths(IPluginModelBase model, ArrayList<Path> libraryPaths)111 	private static void addLibraryPaths(IPluginModelBase model, ArrayList<Path> libraryPaths) {
112 		IPluginBase plugin = model.getPluginBase();
113 
114 		IFragmentModel[] fragments = new IFragmentModel[0];
115 		if (plugin instanceof IPlugin) {
116 			fragments = PDEManager.findFragmentsFor(model);
117 		}
118 
119 		File file = new File(model.getInstallLocation());
120 		if (file.isFile()) {
121 			libraryPaths.add(new Path(file.getAbsolutePath()));
122 		} else {
123 			IPluginLibrary[] libraries = plugin.getLibraries();
124 			for (IPluginLibrary library : libraries) {
125 				String libraryName = ClasspathUtilCore.expandLibraryName(library.getName());
126 				String path = plugin.getModel().getInstallLocation() + IPath.SEPARATOR + libraryName;
127 				if (new File(path).exists()) {
128 					libraryPaths.add(new Path(path));
129 				} else {
130 					findLibraryInFragments(fragments, libraryName, libraryPaths);
131 				}
132 			}
133 		}
134 		if (ClasspathUtilCore.hasExtensibleAPI(model)) {
135 			for (IFragmentModel fragment : fragments) {
136 				addLibraryPaths(fragment, libraryPaths);
137 			}
138 		}
139 	}
140 
findLibraryInFragments(IFragmentModel[] fragments, String libraryName, ArrayList<Path> libraryPaths)141 	private static void findLibraryInFragments(IFragmentModel[] fragments, String libraryName, ArrayList<Path> libraryPaths) {
142 		for (IFragmentModel fragment : fragments) {
143 			String path = fragment.getInstallLocation() + IPath.SEPARATOR + libraryName;
144 			if (new File(path).exists()) {
145 				libraryPaths.add(new Path(path));
146 				break;
147 			}
148 		}
149 	}
150 
createSeachScope(IJavaProject jProject)151 	public static IJavaSearchScope createSeachScope(IJavaProject jProject) throws JavaModelException {
152 		IPackageFragmentRoot[] roots = jProject.getPackageFragmentRoots();
153 		ArrayList<IPackageFragmentRoot> filteredRoots = new ArrayList<>();
154 		for (IPackageFragmentRoot root : roots) {
155 			if (root.getResource() != null && root.getResource().getProject().equals(jProject.getProject())) {
156 				filteredRoots.add(root);
157 			}
158 		}
159 		return SearchEngine.createJavaSearchScope(filteredRoots.toArray(new IJavaElement[filteredRoots.size()]));
160 	}
161 
162 }
163