KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > refactoring > java > plugins > JavaWhereUsedQueryPlugin


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.refactoring.java.plugins;
20
21 import com.sun.source.tree.CompilationUnitTree;
22 import com.sun.source.tree.Tree;
23 import com.sun.source.util.TreePath;
24 import java.io.IOException JavaDoc;
25 import java.util.*;
26 import java.util.HashSet JavaDoc;
27 import javax.lang.model.element.*;
28 import org.netbeans.api.java.classpath.ClassPath;
29 import org.netbeans.api.java.source.*;
30 import org.netbeans.api.java.source.JavaSource.Phase;
31 import org.netbeans.modules.refactoring.api.WhereUsedQuery;
32 import org.netbeans.modules.refactoring.java.RetoucheUtils;
33 import org.netbeans.modules.refactoring.java.WhereUsedElement;
34 import org.netbeans.modules.refactoring.api.Problem;
35 import org.netbeans.modules.refactoring.api.ProgressEvent;
36 import org.netbeans.modules.refactoring.api.WhereUsedQuery;
37 import org.netbeans.modules.refactoring.java.api.WhereUsedQueryConstants;
38 import org.netbeans.modules.refactoring.java.classpath.RefactoringClassPathImplementation;
39 import org.netbeans.modules.refactoring.java.plugins.FindOverridingVisitor;
40 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
41 import org.openide.ErrorManager;
42 import org.openide.filesystems.FileObject;
43 import org.openide.loaders.DataObject;
44 import org.openide.text.CloneableEditorSupport;
45 import org.openide.util.NbBundle;
46
47 /**
48  *
49  * @author Jan Becicka
50  */

51 public class JavaWhereUsedQueryPlugin extends JavaRefactoringPlugin {
52     private WhereUsedQuery refactoring;
53     private ClasspathInfo classPathInfo=null;
54     
55     
56     /** Creates a new instance of WhereUsedQuery */
57     public JavaWhereUsedQueryPlugin(WhereUsedQuery refactoring) {
58         this.refactoring = refactoring;
59     }
60     
61     private ClasspathInfo getClasspathInfo(ClasspathInfo info) {
62         if (classPathInfo == null) {
63             ClassPath boot = info.getClassPath(ClasspathInfo.PathKind.BOOT);
64             FileObject fo = getSearchHandle().getFileObject();
65             ClassPath rcp = RefactoringClassPathImplementation.getCustom(Collections.singleton(fo));
66             classPathInfo = ClasspathInfo.create(boot, rcp, rcp);
67         }
68         return classPathInfo;
69     }
70     private TreePathHandle getSearchHandle() {
71         return refactoring.getRefactoringSource().lookup(TreePathHandle.class);
72     }
73     
74     public Problem preCheck() {
75 // Problem p = isElementAvail(getSearchHandle(), refactoring.getContext().lookup(CompilationInfo.class));
76
// if (p != null)
77
// return p;
78

79 // if (!((jmiObject instanceof Feature) || (jmiObject instanceof Variable) || (jmiObject instanceof JavaPackage) || (jmiObject instanceof TypeParameter)) ) {
80
// return new Problem(true, NbBundle.getMessage(WhereUsedQuery.class, "ERR_WhereUsedWrongType"));
81
// }
82

83         return null;
84     }
85     
86     private Set JavaDoc<FileObject> getRelevantFiles(final TreePathHandle tph) {
87         final ClasspathInfo cpInfo = refactoring.getContext().lookup(ClasspathInfo.class);
88         final ClassIndex idx = cpInfo.getClassIndex();
89         final Set JavaDoc<FileObject> set = new HashSet JavaDoc<FileObject>();
90                 
91         JavaSource source = JavaSource.create(cpInfo, new FileObject[]{tph.getFileObject()});
92         //XXX: This is slow!
93
CancellableTask<CompilationController> task = new CancellableTask<CompilationController>() {
94             public void cancel() {
95             }
96             
97             public void run(CompilationController info) throws Exception JavaDoc {
98                 info.toPhase(Phase.RESOLVED);
99                 set.add(tph.getFileObject());
100                 final Element el = tph.resolveElement(info);
101                 if (el.getKind().isField()) {
102                     //get field references from index
103
set.addAll(idx.getResources(ElementHandle.create((TypeElement)el.getEnclosingElement()), EnumSet.of(ClassIndex.SearchKind.FIELD_REFERENCES), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
104                 } else if (el.getKind().isClass() || el.getKind().isInterface()) {
105                     if (isFindSubclasses()||isFindDirectSubclassesOnly()) {
106                         if (isFindDirectSubclassesOnly()) {
107                             //get direct implementors from index
108
EnumSet searchKind = EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS);
109                             set.addAll(idx.getResources(ElementHandle.create((TypeElement)el), searchKind,EnumSet.of(ClassIndex.SearchScope.SOURCE)));
110                         } else {
111                             //itererate implementors recursively
112
set.addAll(getImplementorsRecursive(idx, cpInfo, (TypeElement)el));
113                         }
114                     } else {
115                         //get type references from index
116
set.addAll(idx.getResources(ElementHandle.create((TypeElement) el), EnumSet.of(ClassIndex.SearchKind.TYPE_REFERENCES, ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.of(ClassIndex.SearchScope.SOURCE)));
117                     }
118                 } else if (el.getKind() == ElementKind.METHOD && isFindOverridingMethods()) {
119                     //Find overriding methods
120
TypeElement type = (TypeElement) el.getEnclosingElement();
121                     set.addAll(getImplementorsRecursive(idx, cpInfo, type));
122                 }
123                 if (el.getKind() == ElementKind.METHOD && isFindUsages()) {
124                     //get method references for method and for all it's overriders
125
Set JavaDoc<ElementHandle<TypeElement>> s = idx.getElements(ElementHandle.create((TypeElement) el.getEnclosingElement()), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.of(ClassIndex.SearchScope.SOURCE));
126                     for (ElementHandle<TypeElement> eh:s) {
127                         TypeElement te = eh.resolve(info);
128                         if (te==null) {
129                             continue;
130                         }
131                         for (Element e:te.getEnclosedElements()) {
132                             if (e instanceof ExecutableElement) {
133                                 if (info.getElements().overrides((ExecutableElement)e, (ExecutableElement)el, te)) {
134                                     set.addAll(idx.getResources(ElementHandle.create(te), EnumSet.of(ClassIndex.SearchKind.METHOD_REFERENCES),EnumSet.of(ClassIndex.SearchScope.SOURCE)));
135                                 }
136                             }
137                         }
138                     }
139                     set.addAll(idx.getResources(ElementHandle.create((TypeElement) el.getEnclosingElement()), EnumSet.of(ClassIndex.SearchKind.METHOD_REFERENCES),EnumSet.of(ClassIndex.SearchScope.SOURCE))); //?????
140
} else if (el.getKind() == ElementKind.CONSTRUCTOR) {
141                         set.addAll(idx.getResources(ElementHandle.create((TypeElement) el.getEnclosingElement()), EnumSet.of(ClassIndex.SearchKind.TYPE_REFERENCES),EnumSet.of(ClassIndex.SearchScope.SOURCE)));
142                 }
143                     
144             }
145         };
146         try {
147             source.runUserActionTask(task, true);
148         } catch (IOException JavaDoc ioe) {
149             throw (RuntimeException JavaDoc) new RuntimeException JavaDoc().initCause(ioe);
150         }
151         return set;
152     }
153     
154     private Set JavaDoc<FileObject> getImplementorsRecursive(ClassIndex idx, ClasspathInfo cpInfo, TypeElement el) {
155         Set JavaDoc<FileObject> set = new HashSet JavaDoc<FileObject>();
156         LinkedList<ElementHandle<TypeElement>> elements = new LinkedList(idx.getElements(ElementHandle.create(el),
157                 EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
158                 EnumSet.of(ClassIndex.SearchScope.SOURCE)));
159         HashSet JavaDoc<ElementHandle> result = new HashSet JavaDoc();
160         while(!elements.isEmpty()) {
161             ElementHandle<TypeElement> next = elements.removeFirst();
162             result.add(next);
163             elements.addAll(idx.getElements(next,
164                     EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),
165                     EnumSet.of(ClassIndex.SearchScope.SOURCE)));
166         }
167         for (ElementHandle<TypeElement> e : result) {
168             FileObject fo = SourceUtils.getFile(e, cpInfo);
169             assert fo != null: "issue 90196, Cannot find file for " + e + ". cpInfo=" + cpInfo ;
170             set.add(fo);
171         }
172         return set;
173     }
174     
175     //@Override
176
public Problem prepare(final RefactoringElementsBag elements) {
177         ClasspathInfo cpInfo = refactoring.getContext().lookup(ClasspathInfo.class);
178         
179         refactoring.getContext().add(getClasspathInfo(cpInfo));
180         
181         Set JavaDoc<FileObject> a = getRelevantFiles(getSearchHandle());
182         fireProgressListenerStart(ProgressEvent.START, a.size());
183         processFiles(a, new FindTask(elements));
184         fireProgressListenerStop();
185         return null;
186     }
187     
188     //@Override
189
public Problem fastCheckParameters() {
190         if (getSearchHandle().getKind() == Tree.Kind.METHOD) {
191             return checkParametersForMethod(isFindOverridingMethods(), isFindUsages());
192         }
193         return null;
194     }
195     
196     //@Override
197
public Problem checkParameters() {
198         return null;
199     }
200     
201     private Problem checkParametersForMethod(boolean overriders, boolean usages) {
202         if (!(usages || overriders)) {
203             return new Problem(true, NbBundle.getMessage(JavaWhereUsedQueryPlugin.class, "MSG_NothingToFind"));
204         } else
205             return null;
206     }
207     
208     public static CloneableEditorSupport findCloneableEditorSupport(DataObject dob) {
209         Object JavaDoc obj = dob.getCookie(org.openide.cookies.OpenCookie.class);
210         if (obj instanceof CloneableEditorSupport) {
211             return (CloneableEditorSupport)obj;
212         }
213         obj = dob.getCookie(org.openide.cookies.EditorCookie.class);
214         if (obj instanceof CloneableEditorSupport) {
215             return (CloneableEditorSupport)obj;
216         }
217         return null;
218     }
219     
220     private boolean isFindSubclasses() {
221         return refactoring.getBooleanValue(WhereUsedQueryConstants.FIND_SUBCLASSES);
222     }
223     private boolean isFindUsages() {
224         return refactoring.getBooleanValue(refactoring.FIND_REFERENCES);
225     }
226     private boolean isFindDirectSubclassesOnly() {
227         return refactoring.getBooleanValue(WhereUsedQueryConstants.FIND_DIRECT_SUBCLASSES);
228     }
229     
230     private boolean isFindOverridingMethods() {
231         return refactoring.getBooleanValue(WhereUsedQueryConstants.FIND_OVERRIDING_METHODS);
232     }
233     private boolean isSearchFromBaseClass() {
234         return false;
235     }
236     
237     
238     // public void start(ProgressEvent event) {
239
// fireProgressListenerStart(event.getOperationType(), event.getCount());
240
// }
241
//
242
// public void step(ProgressEvent event) {
243
// fireProgressListenerStep();
244
// }
245
//
246
// public void stop(ProgressEvent event) {
247
// fireProgressListenerStop();
248
// }
249

250     private class FindTask implements CancellableTask<WorkingCopy> {
251
252         private RefactoringElementsBag elements;
253         private volatile boolean cancelled;
254
255         public FindTask(RefactoringElementsBag elements) {
256             super();
257             this.elements = elements;
258         }
259
260         public void cancel() {
261             cancelled=true;
262         }
263
264         public void run(WorkingCopy compiler) throws IOException JavaDoc {
265             if (cancelled)
266                 return ;
267             compiler.toPhase(Phase.RESOLVED);
268             CompilationUnitTree cu = compiler.getCompilationUnit();
269             if (cu == null) {
270                 ErrorManager.getDefault().log(ErrorManager.ERROR, "compiler.getCompilationUnit() is null " + compiler);
271                 return;
272             }
273             Element element = getSearchHandle().resolveElement(compiler);
274             assert element != null;
275             Collection<TreePath> result = new ArrayList();
276             if (isFindUsages()) {
277                 FindUsagesVisitor findVisitor = new FindUsagesVisitor(compiler);
278                 findVisitor.scan(compiler.getCompilationUnit(), element);
279                 result.addAll(findVisitor.getUsages());
280             }
281             if (element.getKind() == ElementKind.METHOD && isFindOverridingMethods()) {
282                 FindOverridingVisitor override = new FindOverridingVisitor(compiler);
283                 override.scan(compiler.getCompilationUnit(), element);
284                 result.addAll(override.getUsages());
285             } else if ((element.getKind().isClass() || element.getKind().isInterface()) &&
286                     (isFindSubclasses()||isFindDirectSubclassesOnly())) {
287                 FindSubtypesVisitor subtypes = new FindSubtypesVisitor(!isFindDirectSubclassesOnly(), compiler);
288                 subtypes.scan(compiler.getCompilationUnit(), element);
289                 result.addAll(subtypes.getUsages());
290             }
291             for (TreePath tree : result) {
292                 elements.add(refactoring, WhereUsedElement.create(compiler, tree));
293             }
294             fireProgressListenerStep();
295         }
296     }
297
298 }
299
Popular Tags