KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.refactoring.rename;
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.IPath;
21
22 import org.eclipse.core.resources.IProject;
23
24 import org.eclipse.jdt.core.IClasspathEntry;
25 import org.eclipse.jdt.core.IJavaElement;
26 import org.eclipse.jdt.core.IJavaProject;
27 import org.eclipse.jdt.core.IMember;
28 import org.eclipse.jdt.core.IPackageFragmentRoot;
29 import org.eclipse.jdt.core.JavaCore;
30 import org.eclipse.jdt.core.JavaModelException;
31 import org.eclipse.jdt.core.search.IJavaSearchScope;
32 import org.eclipse.jdt.core.search.SearchEngine;
33
34 import org.eclipse.jdt.internal.corext.Assert;
35 import org.eclipse.jdt.internal.corext.util.JdtFlags;
36
37 public class RefactoringScopeFactory {
38
39     private RefactoringScopeFactory() {
40         //no instances
41
}
42
43     public static IJavaSearchScope create(IMember[] members) throws JavaModelException {
44         Assert.isTrue(members != null && members.length > 0);
45         IMember candidate= members[0];
46         int visibility= getVisibility(candidate);
47         for (int i= 1; i < members.length; i++) {
48             int mv= getVisibility(members[i]);
49             if (mv > visibility) {
50                 visibility= mv;
51                 candidate= members[i];
52             }
53         }
54         return create(candidate);
55     }
56     
57     private static int getVisibility(IMember member) throws JavaModelException {
58         if (JdtFlags.isPrivate(member))
59             return 0;
60         if (JdtFlags.isPackageVisible(member))
61             return 1;
62         if (JdtFlags.isProtected(member))
63             return 2;
64         return 4;
65     }
66
67     /**
68      * @return scope with all CUs or projects possibly referencing <code>javaElement</code>.
69      */

70     public static IJavaSearchScope create(IJavaElement javaElement) throws JavaModelException {
71         if (javaElement instanceof IMember) {
72             IMember member= (IMember) javaElement;
73             if (JdtFlags.isPrivate(member)) {
74                 if (member.getCompilationUnit() != null)
75                     return SearchEngine.createJavaSearchScope(new IJavaElement[] { member.getCompilationUnit()});
76                 else
77                     return SearchEngine.createJavaSearchScope(new IJavaElement[] { member });
78             }
79             // Removed code that does some optimizations regarding package visible members. The problem is that
80
// there can be a package fragment with the same name in a different source folder or project. So we
81
// have to treat package visible members like public or protected members.
82
}
83         return create(javaElement.getJavaProject());
84     }
85
86     private static IJavaSearchScope create(IJavaProject javaProject) throws JavaModelException {
87         return SearchEngine.createJavaSearchScope(getAllScopeElements(javaProject), false);
88     }
89
90     private static IJavaElement[] getAllScopeElements(IJavaProject project) throws JavaModelException {
91         Collection JavaDoc sourceRoots= getAllSourceRootsInProjects(getReferencingProjects(project));
92         return (IPackageFragmentRoot[]) sourceRoots.toArray(new IPackageFragmentRoot[sourceRoots.size()]);
93     }
94
95     /**
96      * @param focus
97      * @return Collection containing IJavaProject objects
98      * @throws JavaModelException
99      */

100     private static Collection JavaDoc getReferencingProjects(IJavaProject focus) throws JavaModelException {
101         Set JavaDoc projects= new HashSet JavaDoc();
102
103         addReferencingProjects(focus, projects);
104         projects.add(focus);
105         return projects;
106     }
107
108     /**
109      * Adds to <code>projects</code> IJavaProject objects for all projects
110      * directly or indirectly referencing focus.
111      *
112      * @param focus
113      * @param projects IJavaProjects will be added to this set
114      * @throws JavaModelException
115      */

116     private static void addReferencingProjects(IJavaProject focus, Set JavaDoc projects) throws JavaModelException {
117         IProject[] referencingProjects= focus.getProject().getReferencingProjects();
118         for (int i= 0; i < referencingProjects.length; i++) {
119             IJavaProject candidate= JavaCore.create(referencingProjects[i]);
120             if (candidate == null || projects.contains(candidate) || !candidate.exists())
121                 continue; // break cycle
122
IClasspathEntry entry= getReferencingClassPathEntry(candidate, focus);
123             if (entry != null) {
124                 projects.add(candidate);
125                 if (entry.isExported())
126                     addReferencingProjects(candidate, projects);
127             }
128         }
129     }
130
131     /**
132      * Finds, if possible, a classpathEntry in one given project such that this
133      * classpath entry references another given project. If more than one entry
134      * exists for the referenced project and at least one is exported, then an
135      * exported entry will be returned.
136      *
137      * @param referencingProject
138      * @param referencedProject
139      * @return IClasspathEntry
140      * @throws JavaModelException
141      */

142     private static IClasspathEntry getReferencingClassPathEntry(IJavaProject referencingProject, IJavaProject referencedProject) throws JavaModelException {
143         IClasspathEntry result= null;
144         IPath path= referencedProject.getProject().getFullPath();
145         IClasspathEntry[] classpath= referencingProject.getResolvedClasspath(true);
146         for (int i= 0; i < classpath.length; i++) {
147             IClasspathEntry entry= classpath[i];
148             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && path.equals(entry.getPath())) {
149                 if (entry.isExported())
150                     return entry;
151                 // Consider it as a candidate. May be there is another entry that is
152
// exported.
153
result= entry;
154             }
155         }
156         return result;
157     }
158
159     /**
160      * @param projects a collection of IJavaProject
161      * @return Collection a collection of IPackageFragmentRoot, one element
162      * for each packageFragmentRoot which lies within a project in
163      * <code>projects</code>.
164      */

165     private static Collection JavaDoc getAllSourceRootsInProjects(Collection JavaDoc projects) throws JavaModelException {
166         List JavaDoc result= new ArrayList JavaDoc();
167         for (Iterator JavaDoc it= projects.iterator(); it.hasNext();)
168             result.addAll(getSourceRoots((IJavaProject) it.next()));
169         return result;
170     }
171
172     private static List JavaDoc getSourceRoots(IJavaProject javaProject) throws JavaModelException {
173         List JavaDoc elements= new ArrayList JavaDoc();
174         IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots();
175         // Add all package fragment roots except archives
176
for (int i= 0; i < roots.length; i++) {
177             IPackageFragmentRoot root= roots[i];
178             if (!root.isArchive())
179                 elements.add(root);
180         }
181         return elements;
182     }
183
184     /**
185      * @return scope with all projects possibly referenced from within <code>javaElements</code>.
186      */

187     public static IJavaSearchScope createReferencedScope(IJavaElement[] javaElements) {
188         Set JavaDoc projects= new HashSet JavaDoc();
189         for (int i= 0; i < javaElements.length; i++) {
190             projects.add(javaElements[i].getJavaProject());
191         }
192         IJavaProject[] prj= (IJavaProject[]) projects.toArray(new IJavaProject[projects.size()]);
193         return SearchEngine.createJavaSearchScope(prj, true);
194     }
195 }
196
Popular Tags