KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > junit > TopClassFinder


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.junit;
21
22 import com.sun.source.tree.ClassTree;
23 import com.sun.source.tree.CompilationUnitTree;
24 import com.sun.source.tree.Tree;
25 import com.sun.source.util.TreePath;
26 import com.sun.source.util.Trees;
27 import java.io.IOException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Collection JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.List JavaDoc;
32 import javax.lang.model.element.Element;
33 import javax.lang.model.element.ElementKind;
34 import javax.lang.model.element.TypeElement;
35 import org.netbeans.api.java.source.CancellableTask;
36 import org.netbeans.api.java.source.CompilationController;
37 import org.netbeans.api.java.source.CompilationInfo;
38 import org.netbeans.api.java.source.ElementHandle;
39 import org.netbeans.api.java.source.JavaSource;
40 import org.netbeans.api.java.source.JavaSource.Phase;
41 import org.netbeans.api.java.source.TreeUtilities;
42 import org.netbeans.modules.junit.TestabilityResult.SkippedClass;
43
44 /**
45  * Finds all non-annotation top-level classes in a compilation unit.
46  *
47  * @author Marian Petras
48  */

49 final class TopClassFinder {
50     
51     private TopClassFinder() { }
52
53     /**
54      */

55     private static class TopClassFinderTask
56                             implements CancellableTask<CompilationController> {
57         private List JavaDoc<ElementHandle<TypeElement>> topClassElems;
58         private TestabilityJudge judgeOfTestability;
59         private Collection JavaDoc<SkippedClass> nonTestable;
60         private volatile boolean cancelled;
61         private TopClassFinderTask() {
62             this.judgeOfTestability = null;
63             this.nonTestable = null;
64         }
65         private TopClassFinderTask(TestabilityJudge testabilityJudge,
66                                    Collection JavaDoc<SkippedClass> nonTestable) {
67             if (testabilityJudge == null) {
68                 throw new IllegalArgumentException JavaDoc("judgeOfTestability: null"); //NOI18N
69
}
70             if (nonTestable == null) {
71                 throw new IllegalArgumentException JavaDoc("nonTestable: null"); //NOI18N
72
}
73             this.judgeOfTestability = testabilityJudge;
74             this.nonTestable = nonTestable;
75         }
76         public void run(CompilationController controller) throws IOException JavaDoc {
77             controller.toPhase(Phase.ELEMENTS_RESOLVED);
78             if (cancelled) {
79                 return;
80             }
81             
82             if (judgeOfTestability == null) {
83                 topClassElems = findTopClassElemHandles(
84                                                     controller,
85                                                     controller.getCompilationUnit());
86             } else {
87                 topClassElems = findTopClassElemHandles(
88                                                     controller,
89                                                     controller.getCompilationUnit(),
90                                                     judgeOfTestability,
91                                                     nonTestable);
92             }
93         }
94         public void cancel() {
95             cancelled = true;
96         }
97     }
98     
99     /**
100      */

101     static List JavaDoc<ElementHandle<TypeElement>> findTopClasses(
102                                                     JavaSource javaSource)
103                                                         throws IOException JavaDoc {
104         TopClassFinderTask analyzer = new TopClassFinderTask();
105         javaSource.runUserActionTask(analyzer, true);
106         return analyzer.topClassElems;
107     }
108     
109     /**
110      * Finds testable top-level classes, interfaces and enums in a given
111      * Java source.
112      *
113      * @param javaSource source in which testable classes should be found
114      * @param judge {@code TestCreator} that will select testable
115      * top-level classes
116      * (see {@link TestCreator#isClassTestable})
117      * @param nonTestable container where names of found non-testable classes
118      * should be stored
119      * @return handles to testable top-level classes, interfaces and enums
120      * @exception java.lang.IllegalArgumentException
121      * if any of the parameters is {@code null}
122      */

123     static List JavaDoc<ElementHandle<TypeElement>> findTestableTopClasses(
124                                                 JavaSource javaSource,
125                                                 TestabilityJudge testabilityJudge,
126                                                 Collection JavaDoc<SkippedClass> nonTestable)
127                                                         throws IOException JavaDoc {
128         TopClassFinderTask analyzer = new TopClassFinderTask(testabilityJudge, nonTestable);
129         javaSource.runUserActionTask(analyzer, true);
130         return analyzer.topClassElems;
131     }
132
133     /**
134      *
135      * @return list of top classes, or an empty list of none were found
136      */

137     static List JavaDoc<ClassTree> findTopClasses(
138                                         CompilationUnitTree compilationUnit,
139                                         TreeUtilities treeUtils) {
140         List JavaDoc<? extends Tree> typeDecls = compilationUnit.getTypeDecls();
141         if ((typeDecls == null) || typeDecls.isEmpty()) {
142             return Collections.<ClassTree>emptyList();
143         }
144
145         List JavaDoc<ClassTree> result = new ArrayList JavaDoc<ClassTree>(typeDecls.size());
146         
147         for (Tree typeDecl : typeDecls) {
148             if (typeDecl.getKind() == Tree.Kind.CLASS) {
149                 ClassTree clsTree = (ClassTree) typeDecl;
150                 if (isTestable(clsTree, treeUtils)) {
151                     result.add(clsTree);
152                 }
153             }
154         }
155
156         return result;
157     }
158
159     /**
160      *
161      * @return list of {@code Element}s representing top classes,
162      * or an empty list of none were found
163      */

164     private static List JavaDoc<TypeElement> findTopClassElems(
165                                         CompilationInfo compInfo,
166                                         CompilationUnitTree compilationUnit,
167                                         TestabilityJudge testabilityJudge,
168                                         Collection JavaDoc<SkippedClass> nonTestable) {
169         List JavaDoc<? extends Tree> typeDecls = compilationUnit.getTypeDecls();
170         if ((typeDecls == null) || typeDecls.isEmpty()) {
171             return Collections.<TypeElement>emptyList();
172         }
173         
174         List JavaDoc<TypeElement> result = new ArrayList JavaDoc<TypeElement>(typeDecls.size());
175
176         Trees trees = compInfo.getTrees();
177         for (Tree typeDecl : typeDecls) {
178             if (typeDecl.getKind() == Tree.Kind.CLASS) {
179                 Element element = trees.getElement(
180                         new TreePath(new TreePath(compilationUnit), typeDecl));
181                 TypeElement typeElement = (TypeElement) element;
182                 if (testabilityJudge != null) {
183                     TestabilityResult testabilityStatus
184                             = testabilityJudge.isClassTestable(compInfo,
185                                                                typeElement);
186                     if (testabilityStatus.isTestable()) {
187                         result.add(typeElement);
188                     } else {
189                         nonTestable.add(new SkippedClass(
190                                 typeElement.getQualifiedName().toString(),
191                                 testabilityStatus));
192                     }
193                 } else if (isTestable(element)) {
194                     result.add(typeElement);
195                 }
196             }
197         }
198
199         return result;
200     }
201
202     /**
203      *
204      * @return list of handles to {@code Element}s representing top classes,
205      * or an empty list of none were found
206      */

207     private static List JavaDoc<ElementHandle<TypeElement>> findTopClassElemHandles(
208                                         CompilationInfo compInfo,
209                                         CompilationUnitTree compilationUnit) {
210         return getElemHandles(findTopClassElems(compInfo, compilationUnit,
211                                                 null, null));
212     }
213
214     /**
215      *
216      * @return list of handles to {@code Element}s representing top classes,
217      * or an empty list of none were found
218      */

219     private static List JavaDoc<ElementHandle<TypeElement>> findTopClassElemHandles(
220                                         CompilationInfo compInfo,
221                                         CompilationUnitTree compilationUnit,
222                                         TestabilityJudge testabilityJudge,
223                                         Collection JavaDoc<SkippedClass> nonTestable) {
224         return getElemHandles(findTopClassElems(compInfo, compilationUnit,
225                                                 testabilityJudge, nonTestable));
226     }
227
228     private static <T extends Element> List JavaDoc<ElementHandle<T>> getElemHandles(List JavaDoc<T> elements) {
229         if (elements == null) {
230             return null;
231         }
232         if (elements.isEmpty()) {
233             return Collections.<ElementHandle<T>>emptyList();
234         }
235
236         List JavaDoc<ElementHandle<T>> handles = new ArrayList JavaDoc<ElementHandle<T>>(elements.size());
237         for (T element : elements) {
238             handles.add(ElementHandle.<T>create(element));
239         }
240         return handles;
241     }
242
243     private static boolean isTestable(ClassTree typeDecl,
244                                       TreeUtilities treeUtils) {
245         return !treeUtils.isAnnotation(typeDecl);
246     }
247
248     static boolean isTestable(Element typeDeclElement) {
249         ElementKind elemKind = typeDeclElement.getKind();
250         return (elemKind != ElementKind.ANNOTATION_TYPE)
251                && (elemKind.isClass()|| elemKind.isInterface());
252     }
253     
254 }
255
Popular Tags