]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringScopeFactory.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / RefactoringScopeFactory.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 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 *******************************************************************************/
11package org.eclipse.jdt.internal.corext.refactoring;
12
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.HashSet;
16import java.util.Iterator;
17import java.util.List;
18import java.util.Set;
19
20import org.eclipse.core.runtime.Assert;
21import org.eclipse.core.runtime.CoreException;
22import org.eclipse.core.runtime.IPath;
23
24import org.eclipse.core.resources.IProject;
25
26import org.eclipse.jdt.core.IClasspathEntry;
27import org.eclipse.jdt.core.IJavaElement;
28import org.eclipse.jdt.core.IJavaProject;
29import org.eclipse.jdt.core.IMember;
30import org.eclipse.jdt.core.IPackageFragmentRoot;
31import org.eclipse.jdt.core.JavaCore;
32import org.eclipse.jdt.core.JavaModelException;
33import org.eclipse.jdt.core.search.IJavaSearchScope;
34import org.eclipse.jdt.core.search.SearchEngine;
35
36import org.eclipse.jdt.internal.corext.util.JdtFlags;
37
38public class RefactoringScopeFactory {
39
40 /*
41 * Adds to <code> projects </code> IJavaProject objects for all projects directly or indirectly referencing focus. @param projects IJavaProjects will be added to this set
42 */
43 private static void addReferencingProjects(IJavaProject focus, Set<IJavaProject> projects) throws JavaModelException {
44 IProject[] referencingProjects= focus.getProject().getReferencingProjects();
45 for (int i= 0; i < referencingProjects.length; i++) {
46 IJavaProject candidate= JavaCore.create(referencingProjects[i]);
47 if (candidate == null || projects.contains(candidate) || !candidate.exists())
48 continue; // break cycle
49 IClasspathEntry entry= getReferencingClassPathEntry(candidate, focus);
50 if (entry != null) {
51 projects.add(candidate);
52 if (entry.isExported())
53 addReferencingProjects(candidate, projects);
54 }
55 }
56 }
57
58 private static void addRelatedReferencing(IJavaProject focus, Set<IJavaProject> projects) throws CoreException {
59 IProject[] referencingProjects= focus.getProject().getReferencingProjects();
60 for (int i= 0; i < referencingProjects.length; i++) {
61 IJavaProject candidate= JavaCore.create(referencingProjects[i]);
62 if (candidate == null || projects.contains(candidate) || !candidate.exists())
63 continue; // break cycle
64 IClasspathEntry entry= getReferencingClassPathEntry(candidate, focus);
65 if (entry != null) {
66 projects.add(candidate);
67 if (entry.isExported()) {
68 addRelatedReferencing(candidate, projects);
69 addRelatedReferenced(candidate, projects);
70 }
71 }
72 }
73 }
74
75 private static void addRelatedReferenced(IJavaProject focus, Set<IJavaProject> projects) throws CoreException {
76 IProject[] referencedProjects= focus.getProject().getReferencedProjects();
77 for (int i= 0; i < referencedProjects.length; i++) {
78 IJavaProject candidate= JavaCore.create(referencedProjects[i]);
79 if (candidate == null || projects.contains(candidate) || !candidate.exists())
80 continue; // break cycle
81 IClasspathEntry entry= getReferencingClassPathEntry(focus, candidate);
82 if (entry != null) {
83 projects.add(candidate);
84 if (entry.isExported()) {
85 addRelatedReferenced(candidate, projects);
86 addRelatedReferencing(candidate, projects);
87 }
88 }
89 }
90 }
91
92 /**
93 * Creates a new search scope with all compilation units possibly referencing <code>javaElement</code>,
94 * considering the visibility of the element, references only from source
95 *
96 * @param javaElement the java element
97 * @return the search scope
98 * @throws JavaModelException if an error occurs
99 */
100 public static IJavaSearchScope create(IJavaElement javaElement) throws JavaModelException {
101 return RefactoringScopeFactory.create(javaElement, true, true);
102 }
103
104 /**
105 * Creates a new search scope with all compilation units possibly referencing <code>javaElement</code>,
106 * references only from source
107 *
108 * @param javaElement the java element
109 * @param considerVisibility consider visibility of javaElement iff <code>true</code>
110 * @return the search scope
111 * @throws JavaModelException if an error occurs
112 */
113 public static IJavaSearchScope create(IJavaElement javaElement, boolean considerVisibility) throws JavaModelException {
114 return RefactoringScopeFactory.create(javaElement, considerVisibility, true);
115 }
116
117
118 /**
119 * Creates a new search scope with all compilation units possibly referencing <code>javaElement</code>.
120 *
121 * @param javaElement the java element
122 * @param considerVisibility consider visibility of javaElement iff <code>true</code>
123 * @param sourceReferencesOnly consider references in source only (no references in binary)
124 * @return the search scope
125 * @throws JavaModelException if an error occurs
126 */
127 public static IJavaSearchScope create(IJavaElement javaElement, boolean considerVisibility, boolean sourceReferencesOnly) throws JavaModelException {
128 if (considerVisibility & javaElement instanceof IMember) {
129 IMember member= (IMember) javaElement;
130 if (JdtFlags.isPrivate(member)) {
131 if (member.getCompilationUnit() != null)
132 return SearchEngine.createJavaSearchScope(new IJavaElement[] { member.getCompilationUnit()});
133 else
134 return SearchEngine.createJavaSearchScope(new IJavaElement[] { member});
135 }
136 // Removed code that does some optimizations regarding package visible members. The problem is that
137 // there can be a package fragment with the same name in a different source folder or project. So we
138 // have to treat package visible members like public or protected members.
139 }
140
141
142 IJavaProject javaProject= javaElement.getJavaProject();
143 return SearchEngine.createJavaSearchScope(getAllScopeElements(javaProject, sourceReferencesOnly), false);
144 }
145
146 /**
147 * Creates a new search scope comprising <code>members</code>.
148 *
149 * @param members the members
150 * @return the search scope
151 * @throws JavaModelException if an error occurs
152 */
153 public static IJavaSearchScope create(IMember[] members) throws JavaModelException {
154 return create(members, true);
155 }
156
157 /**
158 * Creates a new search scope comprising <code>members</code>.
159 *
160 * @param members the members
161 * @param sourceReferencesOnly consider references in source only (no references in binary)
162 * @return the search scope
163 * @throws JavaModelException if an error occurs
164 */
165 public static IJavaSearchScope create(IMember[] members, boolean sourceReferencesOnly) throws JavaModelException {
166 Assert.isTrue(members != null && members.length > 0);
167 IMember candidate= members[0];
168 int visibility= getVisibility(candidate);
169 for (int i= 1; i < members.length; i++) {
170 int mv= getVisibility(members[i]);
171 if (mv > visibility) {
172 visibility= mv;
173 candidate= members[i];
174 }
175 }
176 return create(candidate, true, sourceReferencesOnly);
177 }
178
179 /**
180 * Creates a new search scope with all projects possibly referenced
181 * from the given <code>javaElements</code>.
182 *
183 * @param javaElements the java elements
184 * @return the search scope
185 */
186 public static IJavaSearchScope createReferencedScope(IJavaElement[] javaElements) {
187 Set<IJavaProject> projects= new HashSet<IJavaProject>();
188 for (int i= 0; i < javaElements.length; i++) {
189 projects.add(javaElements[i].getJavaProject());
190 }
191 IJavaProject[] prj= projects.toArray(new IJavaProject[projects.size()]);
192 return SearchEngine.createJavaSearchScope(prj, true);
193 }
194
195 /**
196 * Creates a new search scope with all projects possibly referenced
197 * from the given <code>javaElements</code>.
198 *
199 * @param javaElements the java elements
200 * @param includeMask the include mask
201 * @return the search scope
202 */
203 public static IJavaSearchScope createReferencedScope(IJavaElement[] javaElements, int includeMask) {
204 Set<IJavaProject> projects= new HashSet<IJavaProject>();
205 for (int i= 0; i < javaElements.length; i++) {
206 projects.add(javaElements[i].getJavaProject());
207 }
208 IJavaProject[] prj= projects.toArray(new IJavaProject[projects.size()]);
209 return SearchEngine.createJavaSearchScope(prj, includeMask);
210 }
211
212 /**
213 * Creates a new search scope containing all projects which reference or are referenced by the specified project.
214 *
215 * @param project the project
216 * @param includeMask the include mask
217 * @return the search scope
218 * @throws CoreException if a referenced project could not be determined
219 */
220 public static IJavaSearchScope createRelatedProjectsScope(IJavaProject project, int includeMask) throws CoreException {
221 IJavaProject[] projects= getRelatedProjects(project);
222 return SearchEngine.createJavaSearchScope(projects, includeMask);
223 }
224
225 /*
226 * @param projects a collection of IJavaProject
227 * @return Array of IPackageFragmentRoot, one element for each packageFragmentRoot which lies within a project in <code> projects </code> .
228 */
229 private static IPackageFragmentRoot[] getAllScopeElements(IJavaProject project, boolean onlySourceRoots) throws JavaModelException {
230 Collection<IJavaProject> referencingProjects= getReferencingProjects(project);
231 List<IPackageFragmentRoot> result= new ArrayList<IPackageFragmentRoot>();
232 for (Iterator<IJavaProject> it= referencingProjects.iterator(); it.hasNext();) {
233 IJavaProject javaProject= it.next();
234 IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots();
235 // Add all package fragment roots except archives
236 for (int i= 0; i < roots.length; i++) {
237 IPackageFragmentRoot root= roots[i];
238 if (!onlySourceRoots || root.getKind() == IPackageFragmentRoot.K_SOURCE)
239 result.add(root);
240 }
241 }
242 return result.toArray(new IPackageFragmentRoot[result.size()]);
243 }
244
245 /*
246 * Finds, if possible, a classpathEntry in one given project such that this classpath entry references another given project. If more than one entry exists for the referenced project and at least one is exported, then an exported entry will be returned.
247 */
248 private static IClasspathEntry getReferencingClassPathEntry(IJavaProject referencingProject, IJavaProject referencedProject) throws JavaModelException {
249 IClasspathEntry result= null;
250 IPath path= referencedProject.getProject().getFullPath();
251 IClasspathEntry[] classpath= referencingProject.getResolvedClasspath(true);
252 for (int i= 0; i < classpath.length; i++) {
253 IClasspathEntry entry= classpath[i];
254 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && path.equals(entry.getPath())) {
255 if (entry.isExported())
256 return entry;
257 // Consider it as a candidate. May be there is another entry that is
258 // exported.
259 result= entry;
260 }
261 }
262 return result;
263 }
264
265 private static IJavaProject[] getRelatedProjects(IJavaProject focus) throws CoreException {
266 final Set<IJavaProject> projects= new HashSet<IJavaProject>();
267
268 addRelatedReferencing(focus, projects);
269 addRelatedReferenced(focus, projects);
270
271 projects.add(focus);
272 return projects.toArray(new IJavaProject[projects.size()]);
273 }
274
275 private static Collection<IJavaProject> getReferencingProjects(IJavaProject focus) throws JavaModelException {
276 Set<IJavaProject> projects= new HashSet<IJavaProject>();
277
278 addReferencingProjects(focus, projects);
279 projects.add(focus);
280 return projects;
281 }
282
283 private static int getVisibility(IMember member) throws JavaModelException {
284 if (JdtFlags.isPrivate(member))
285 return 0;
286 if (JdtFlags.isPackageVisible(member))
287 return 1;
288 if (JdtFlags.isProtected(member))
289 return 2;
290 return 4;
291 }
292
293 private RefactoringScopeFactory() {
294 // no instances
295 }
296}