KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > RefactoringScopeFactory


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.jdt.internal.corext.refactoring;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23
24 import org.eclipse.core.resources.IProject;
25
26 import org.eclipse.jdt.core.IClasspathEntry;
27 import org.eclipse.jdt.core.IJavaElement;
28 import org.eclipse.jdt.core.IJavaProject;
29 import org.eclipse.jdt.core.IMember;
30 import org.eclipse.jdt.core.IPackageFragmentRoot;
31 import org.eclipse.jdt.core.JavaCore;
32 import org.eclipse.jdt.core.JavaModelException;
33 import org.eclipse.jdt.core.search.IJavaSearchScope;
34 import org.eclipse.jdt.core.search.SearchEngine;
35
36 import org.eclipse.jdt.internal.corext.util.JdtFlags;
37
38 public 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 JavaDoc 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 JavaDoc 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 JavaDoc 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.
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);
102     }
103     
104     /**
105      * Creates a new search scope with all compilation units possibly referencing <code>javaElement</code>.
106      *
107      * @param javaElement the java element
108      * @param considerVisibility consider visibility of javaElement iff <code>true</code>
109      * @return the search scope
110      * @throws JavaModelException if an error occurs
111      */

112     public static IJavaSearchScope create(IJavaElement javaElement, boolean considerVisibility) throws JavaModelException {
113         if (considerVisibility & javaElement instanceof IMember) {
114             IMember member= (IMember) javaElement;
115             if (JdtFlags.isPrivate(member)) {
116                 if (member.getCompilationUnit() != null)
117                     return SearchEngine.createJavaSearchScope(new IJavaElement[] { member.getCompilationUnit()});
118                 else
119                     return SearchEngine.createJavaSearchScope(new IJavaElement[] { member});
120             }
121             // Removed code that does some optimizations regarding package visible members. The problem is that
122
// there can be a package fragment with the same name in a different source folder or project. So we
123
// have to treat package visible members like public or protected members.
124
}
125         return create(javaElement.getJavaProject());
126     }
127
128     private static IJavaSearchScope create(IJavaProject javaProject) throws JavaModelException {
129         return SearchEngine.createJavaSearchScope(getAllScopeElements(javaProject), false);
130     }
131
132     /**
133      * Creates a new search scope comprising <code>members</code>.
134      *
135      * @param members the members
136      * @return the search scope
137      * @throws JavaModelException if an error occurs
138      */

139     public static IJavaSearchScope create(IMember[] members) throws JavaModelException {
140         Assert.isTrue(members != null && members.length > 0);
141         IMember candidate= members[0];
142         int visibility= getVisibility(candidate);
143         for (int i= 1; i < members.length; i++) {
144             int mv= getVisibility(members[i]);
145             if (mv > visibility) {
146                 visibility= mv;
147                 candidate= members[i];
148             }
149         }
150         return create(candidate);
151     }
152
153     /**
154      * Creates a new search scope with all projects possibly referenced
155      * from the given <code>javaElements</code>.
156      *
157      * @param javaElements the java elements
158      * @return the search scope
159      */

160     public static IJavaSearchScope createReferencedScope(IJavaElement[] javaElements) {
161         Set JavaDoc projects= new HashSet JavaDoc();
162         for (int i= 0; i < javaElements.length; i++) {
163             projects.add(javaElements[i].getJavaProject());
164         }
165         IJavaProject[] prj= (IJavaProject[]) projects.toArray(new IJavaProject[projects.size()]);
166         return SearchEngine.createJavaSearchScope(prj, true);
167     }
168
169     /**
170      * Creates a new search scope with all projects possibly referenced
171      * from the given <code>javaElements</code>.
172      *
173      * @param javaElements the java elements
174      * @param includeMask the include mask
175      * @return the search scope
176      */

177     public static IJavaSearchScope createReferencedScope(IJavaElement[] javaElements, int includeMask) {
178         Set JavaDoc projects= new HashSet JavaDoc();
179         for (int i= 0; i < javaElements.length; i++) {
180             projects.add(javaElements[i].getJavaProject());
181         }
182         IJavaProject[] prj= (IJavaProject[]) projects.toArray(new IJavaProject[projects.size()]);
183         return SearchEngine.createJavaSearchScope(prj, includeMask);
184     }
185
186     /**
187      * Creates a new search scope containing all projects which reference or are referenced by the specified project.
188      *
189      * @param project the project
190      * @param includeMask the include mask
191      * @return the search scope
192      * @throws CoreException if a referenced project could not be determined
193      */

194     public static IJavaSearchScope createRelatedProjectsScope(IJavaProject project, int includeMask) throws CoreException {
195         IJavaProject[] projects= getRelatedProjects(project);
196         return SearchEngine.createJavaSearchScope(projects, includeMask);
197     }
198
199     private static IJavaElement[] getAllScopeElements(IJavaProject project) throws JavaModelException {
200         Collection JavaDoc sourceRoots= getAllSourceRootsInProjects(getReferencingProjects(project));
201         return (IPackageFragmentRoot[]) sourceRoots.toArray(new IPackageFragmentRoot[sourceRoots.size()]);
202     }
203
204     /*
205      * @param projects a collection of IJavaProject @return Collection a collection of IPackageFragmentRoot, one element for each packageFragmentRoot which lies within a project in <code> projects </code> .
206      */

207     private static Collection JavaDoc getAllSourceRootsInProjects(Collection JavaDoc projects) throws JavaModelException {
208         List JavaDoc result= new ArrayList JavaDoc();
209         for (Iterator JavaDoc it= projects.iterator(); it.hasNext();)
210             result.addAll(getSourceRoots((IJavaProject) it.next()));
211         return result;
212     }
213
214     /*
215      * 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.
216      */

217     private static IClasspathEntry getReferencingClassPathEntry(IJavaProject referencingProject, IJavaProject referencedProject) throws JavaModelException {
218         IClasspathEntry result= null;
219         IPath path= referencedProject.getProject().getFullPath();
220         IClasspathEntry[] classpath= referencingProject.getResolvedClasspath(true);
221         for (int i= 0; i < classpath.length; i++) {
222             IClasspathEntry entry= classpath[i];
223             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && path.equals(entry.getPath())) {
224                 if (entry.isExported())
225                     return entry;
226                 // Consider it as a candidate. May be there is another entry that is
227
// exported.
228
result= entry;
229             }
230         }
231         return result;
232     }
233
234     private static IJavaProject[] getRelatedProjects(IJavaProject focus) throws CoreException {
235         final Set JavaDoc projects= new HashSet JavaDoc();
236
237         addRelatedReferencing(focus, projects);
238         addRelatedReferenced(focus, projects);
239
240         projects.add(focus);
241         return (IJavaProject[]) projects.toArray(new IJavaProject[projects.size()]);
242     }
243
244     private static Collection JavaDoc getReferencingProjects(IJavaProject focus) throws JavaModelException {
245         Set JavaDoc projects= new HashSet JavaDoc();
246
247         addReferencingProjects(focus, projects);
248         projects.add(focus);
249         return projects;
250     }
251
252     private static List JavaDoc getSourceRoots(IJavaProject javaProject) throws JavaModelException {
253         List JavaDoc elements= new ArrayList JavaDoc();
254         IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots();
255         // Add all package fragment roots except archives
256
for (int i= 0; i < roots.length; i++) {
257             IPackageFragmentRoot root= roots[i];
258             if (!root.isArchive())
259                 elements.add(root);
260         }
261         return elements;
262     }
263
264     private static int getVisibility(IMember member) throws JavaModelException {
265         if (JdtFlags.isPrivate(member))
266             return 0;
267         if (JdtFlags.isPackageVisible(member))
268             return 1;
269         if (JdtFlags.isProtected(member))
270             return 2;
271         return 4;
272     }
273
274     private RefactoringScopeFactory() {
275         // no instances
276
}
277 }
278
Popular Tags