KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > common > source > SourceUtils


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
20 package org.netbeans.modules.j2ee.common.source;
21
22 import com.sun.source.tree.*;
23 import com.sun.source.util.*;
24 import java.io.IOException JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Set JavaDoc;
27 import javax.lang.model.element.*;
28 import javax.lang.model.type.*;
29 import org.netbeans.api.java.source.CompilationController;
30 import org.netbeans.api.java.source.ElementUtilities;
31 import org.netbeans.api.java.source.JavaSource.Phase;
32 import org.openide.util.Parameters;
33
34 /**
35  *
36  * @author Andrei Badea, Martin Adamek
37  */

38 public class SourceUtils {
39
40     // TODO we could probably also have a SourceUtils(CompilationController, TypeElement) factory method
41

42     /**
43      * The compilation controller this instance works with.
44      */

45     private final CompilationController controller;
46
47     /**
48      * The type element this instance works with. Do not use directly, use
49      * {@link #getTypeElement} instead.
50      */

51     private TypeElement typeElement;
52
53     /**
54      * The class tree corresponding to {@link #typeElement}. Do not use directly,
55      * use {@link #getClassTree} instead.
56      */

57     private ClassTree classTree;
58
59     // <editor-fold defaultstate="collapsed" desc="Constructors and factory methods">
60

61     SourceUtils(CompilationController controller, TypeElement typeElement) {
62         this.controller = controller;
63         this.typeElement = typeElement;
64     }
65
66     SourceUtils(CompilationController controller, ClassTree classTree) {
67         this.controller = controller;
68         this.classTree = classTree;
69     }
70
71     public static SourceUtils newInstance(CompilationController controller, TypeElement typeElement) {
72         Parameters.notNull("controller", controller); // NOI18N
73
Parameters.notNull("typeElement", typeElement); // NOI18N
74

75         return new SourceUtils(controller, typeElement);
76     }
77
78     public static SourceUtils newInstance(CompilationController controller, ClassTree classTree) {
79         Parameters.notNull("controller", controller); // NOI18N
80
Parameters.notNull("classTree", classTree); // NOI18N
81

82         return new SourceUtils(controller, classTree);
83     }
84
85     public static SourceUtils newInstance(CompilationController controller) throws IOException JavaDoc {
86         Parameters.notNull("controller", controller); // NOI18N
87

88         ClassTree classTree = findPublicTopLevelClass(controller);
89         if (classTree != null) {
90             return newInstance(controller, classTree);
91         }
92         return null;
93     }
94
95     // </editor-fold>
96

97     // <editor-fold defaultstate="collapsed" desc="Non-public static methods">
98

99     /**
100      * Finds the first public top-level type in the compilation unit given by the
101      * given <code>CompilationController</code>.
102      *
103      * This method assumes the restriction that there is at most a public
104      * top-level type declaration in a compilation unit, as described in the
105      * section 7.6 of the JLS.
106      */

107     static ClassTree findPublicTopLevelClass(CompilationController controller) throws IOException JavaDoc {
108         controller.toPhase(Phase.ELEMENTS_RESOLVED);
109
110         final String JavaDoc mainElementName = controller.getFileObject().getName();
111         for (Tree tree : controller.getCompilationUnit().getTypeDecls()) {
112             if (tree.getKind() != Tree.Kind.CLASS) {
113                 continue;
114             }
115             ClassTree classTree = (ClassTree)tree;
116             if (!classTree.getSimpleName().contentEquals(mainElementName)) {
117                 continue;
118             }
119             if (!classTree.getModifiers().getFlags().contains(Modifier.PUBLIC)) {
120                 continue;
121             }
122             return classTree;
123         }
124         return null;
125     }
126
127     // </editor-fold>
128

129     // <editor-fold desc="Public methods">
130

131     /**
132      * Returns the type element that this instance works with
133      * (corresponding to {@link #getClassTree}.
134      *
135      * @return the type element that this instance works with; never null.
136      */

137     public TypeElement getTypeElement() {
138         if (typeElement == null) {
139             assert classTree != null;
140             TreePath classTreePath = controller.getTrees().getPath(getCompilationController().getCompilationUnit(), classTree);
141             typeElement = (TypeElement)controller.getTrees().getElement(classTreePath);
142         }
143         return typeElement;
144     }
145
146     /**
147      * Returns the class tree that this instance works with
148      * (corresponding to {@link #getTypeElement}.
149      *
150      * @return the class tree that this instance works with; never null.
151      */

152     public ClassTree getClassTree() {
153         if (classTree == null) {
154             assert typeElement != null;
155             classTree = controller.getTrees().getTree(typeElement);
156         }
157         return classTree;
158     }
159
160     /**
161      * Returns true if {@link #getTypeElement} is a subtype of the given type.
162      *
163      * @param type the string representation of a type. The type will be parsed
164      * in the context of {@link #getTypeElement}.
165      * @return true {@link #getTypeElement} is a subtype of the given type,
166      * false otherwise.
167      */

168     public boolean isSubtype(String JavaDoc type) {
169         Parameters.notNull("type", type); // NOI18N
170

171         TypeMirror typeMirror = getCompilationController().getTreeUtilities().parseType(type, getTypeElement());
172         if (typeMirror != null) {
173             return getCompilationController().getTypes().isSubtype(getTypeElement().asType(), typeMirror);
174         }
175         return false;
176     }
177
178     // </editor-fold>
179

180     // <editor-fold defaultstate="collapsed" desc="Non-public methods">
181

182     /**
183      * Returns the <code>CompilationController</code> that this instance
184      * works with.
185      */

186     CompilationController getCompilationController() {
187         return controller;
188     }
189
190     /**
191      * Returns the non-synthetic no-arg constructor of the main type element.
192      */

193     ExecutableElement getNoArgConstructor() throws IOException JavaDoc {
194         controller.toPhase(Phase.ELEMENTS_RESOLVED);
195
196         ElementUtilities elementUtils = controller.getElementUtilities();
197         for (Element element : getTypeElement().getEnclosedElements()) {
198             if (element.getKind() == ElementKind.CONSTRUCTOR) {
199                 ExecutableElement constructor = (ExecutableElement)element;
200                 if (constructor.getParameters().size() == 0 && !elementUtils.isSynthetic(constructor)) {
201                     return constructor;
202                 }
203             }
204         }
205         return null;
206     }
207
208     /**
209      * Returns true if the given method is a main method.
210      */

211     private boolean isMainMethod(ExecutableElement method) {
212         // check method name
213
if (!method.getSimpleName().contentEquals("main")) { // NOI18N
214
return false;
215         }
216         // check modifiers
217
Set JavaDoc<Modifier> modifiers = method.getModifiers();
218         if (!modifiers.contains(Modifier.PUBLIC) || !modifiers.contains(Modifier.STATIC)) {
219             return false;
220         }
221         // check return type
222
if (TypeKind.VOID != method.getReturnType().getKind()) {
223             return false;
224         }
225         // check parameters
226
// there must be just one parameter
227
List JavaDoc<? extends VariableElement> params = method.getParameters();
228         if (params.size() != 1) {
229             return false;
230         }
231         VariableElement param = params.get(0); // it is ok to take first item, it was tested before
232
TypeMirror paramType = param.asType();
233         // parameter must be an array
234
if (TypeKind.ARRAY != paramType.getKind()) {
235             return false;
236         }
237         ArrayType arrayType = (ArrayType) paramType;
238         TypeElement stringTypeElement = controller.getElements().getTypeElement(String JavaDoc.class.getName());
239         // array must be array of Strings
240
if (!controller.getTypes().isSameType(stringTypeElement.asType(), arrayType.getComponentType())) {
241             return false;
242         }
243         return true;
244     }
245
246     // </editor-fold>
247
}
248
Popular Tags