001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.visualweb.insync.java;
043:
044: import com.sun.rave.designtime.ContextMethod;
045: import com.sun.source.tree.AnnotationTree;
046: import com.sun.source.tree.ClassTree;
047: import com.sun.source.tree.ExpressionTree;
048: import com.sun.source.tree.ImportTree;
049: import com.sun.source.tree.MethodInvocationTree;
050: import com.sun.source.tree.MethodTree;
051: import com.sun.source.tree.ModifiersTree;
052: import com.sun.source.tree.NewClassTree;
053: import com.sun.source.tree.Tree;
054: import com.sun.source.tree.TypeParameterTree;
055: import com.sun.source.tree.VariableTree;
056: import java.util.ArrayList;
057: import java.util.Collections;
058: import java.util.EnumSet;
059: import java.util.List;
060: import javax.lang.model.element.Modifier;
061: import javax.lang.model.element.TypeElement;
062: import javax.lang.model.type.TypeKind;
063: import org.netbeans.api.java.source.Comment;
064: import org.netbeans.api.java.source.TreeMaker;
065: import org.netbeans.api.java.source.WorkingCopy;
066: import org.netbeans.modules.visualweb.insync.beans.Naming;
067:
068: /**
069: *
070: * @author jdeva
071: */
072: public class TreeMakerUtils {
073:
074: /*
075: * Creates a variable tree for a property field
076: */
077: public static VariableTree createPropertyField(WorkingCopy wc,
078: String name, Class type) {
079: TreeMaker make = wc.getTreeMaker();
080: Tree typeTree = createType(wc, type.getCanonicalName());
081: ExpressionTree initializer = make.NewClass(null, Collections
082: .<ExpressionTree> emptyList(),
083: (ExpressionTree) typeTree, Collections
084: .<ExpressionTree> emptyList(), null);
085: return make.Variable(createModifiers(wc, Modifier.PRIVATE),
086: name, typeTree, initializer);
087: }
088:
089: /*
090: * Creates a new method tree for a property getter method
091: */
092: public static MethodTree createPropertyGetterMethod(WorkingCopy wc,
093: String name, Class type) {
094: TreeMaker make = wc.getTreeMaker();
095: return make.Method(createModifiers(wc, Modifier.PUBLIC), Naming
096: .getterName(name), createType(wc, type
097: .getCanonicalName()), Collections
098: .<TypeParameterTree> emptyList(), Collections
099: .<VariableTree> emptyList(), Collections
100: .<ExpressionTree> emptyList(), "{ return " + name
101: + "; }", // NOI18N
102: null);
103: }
104:
105: /*
106: * Creates a new method tree for a property setter method
107: */
108: public static MethodTree createPropertySetterMethod(WorkingCopy wc,
109: String name, Class type) {
110: TreeMaker make = wc.getTreeMaker();
111: String argName = Naming.paramNames(new Class[] { type }, null)[0];
112: return make.Method(createModifiers(wc, Modifier.PUBLIC), Naming
113: .setterName(name), make.PrimitiveType(TypeKind.VOID),
114: Collections.<TypeParameterTree> emptyList(),
115: Collections.singletonList(createVariable(wc, argName,
116: type)), Collections
117: .<ExpressionTree> emptyList(), "{ this." + name
118: + " = " + argName + "; }", // NOI18N
119: null);
120: }
121:
122: /*
123: * Creates a new variable tree for a given name and type
124: */
125: public static VariableTree createVariable(WorkingCopy wc,
126: String name, Class type) {
127: return createVariable(wc, name, createType(wc, type
128: .getCanonicalName()));
129: }
130:
131: /*
132: * Creates a new variable tree for a given name and type
133: */
134: private static VariableTree createVariable(WorkingCopy wc,
135: String name, Tree type) {
136: TreeMaker make = wc.getTreeMaker();
137: return make.Variable(createModifiers(wc), name, type, null);
138: }
139:
140: /*
141: * Creates a method given context method and return type name
142: */
143: public static MethodTree createMethod(WorkingCopy wc,
144: ContextMethod mInfo, String retTypeName) {
145: TreeMaker make = wc.getTreeMaker();
146: Class[] pTypes = mInfo.getParameterTypes();
147: String[] pNames = mInfo.getParameterNames();
148: List<VariableTree> params = new ArrayList<VariableTree>();
149: for (int i = 0; pTypes != null && i < pTypes.length; i++) {
150: VariableTree vtree = createVariable(wc, pNames[i],
151: pTypes[i]);
152: params.add(vtree);
153: }
154:
155: Class[] excepTypes = mInfo.getExceptionTypes();
156: List<ExpressionTree> throwsList = new ArrayList<ExpressionTree>();
157: for (int i = 0; excepTypes != null && i < excepTypes.length; i++) {
158: throwsList.add((ExpressionTree) createType(wc,
159: excepTypes[i].getCanonicalName()));
160: }
161:
162: String body = mInfo.getMethodBodyText();
163: if (body == null) {
164: body = "";
165: }
166:
167: MethodTree mtree = make.Method(createModifiers(wc, mInfo
168: .getModifiers()), mInfo.getName(), createType(wc,
169: retTypeName), Collections
170: .<TypeParameterTree> emptyList(), params, throwsList,
171: "{" + body + "}", null);
172:
173: if (mInfo.getCommentText() != null) {
174: Comment comment = Comment.create(Comment.Style.JAVADOC, -2,
175: -2, -2, mInfo.getCommentText());
176: make.addComment(mtree, comment, true);
177: }
178:
179: return mtree;
180: }
181:
182: /*
183: *
184: */
185: public static MethodTree updateMethod(WorkingCopy wc,
186: ContextMethod cm, MethodTree methTree) {
187: TreeMaker make = wc.getTreeMaker();
188: String[] pNames = cm.getParameterNames();
189:
190: int mods = cm.getModifiers();
191: ModifiersTree modsTree = methTree.getModifiers();
192: if (mods > 0) {
193: modsTree = createModifiers(wc, mods);
194: }
195:
196: //Update param name(s)
197: List<? extends VariableTree> params = methTree.getParameters();
198: if (cm.getParameterTypes().length > 0) {
199: List<VariableTree> newParams = new ArrayList<VariableTree>();
200: String[] paramNames = cm.getParameterNames();
201: for (int i = 0; i < paramNames.length; i++) {
202: VariableTree param = params.get(i);
203: newParams.add(createVariable(wc, param.getName()
204: .toString(), param.getType()));
205: }
206: params = newParams;
207: }
208:
209: //Update comment
210: String commentText = cm.getCommentText();
211: if (commentText != null) {
212: //m.setJavadocText(commentText);
213: }
214:
215: //Update body
216: String code = "{" + cm.getMethodBodyText() + "}";
217:
218: //Update return type
219: Tree retTree = methTree.getReturnType();
220: if (!cm.getName().equals("<init>")) { //NOI18N
221: Class retType = cm.getReturnType();
222: if (retType != null) {
223: retTree = createType(wc, retType.getCanonicalName());
224: }
225: }
226:
227: return make.Method(modsTree, cm.getName(), retTree, methTree
228: .getTypeParameters(), params, methTree.getThrows(),
229: code, null);
230:
231: }
232:
233: /*
234: * Returns a tree for a given type in string format
235: * Note that import for type is handled by make.QualIdent()
236: */
237: public static Tree createType(WorkingCopy wc, String typeName) {
238: if (typeName == null) {
239: return null;
240: }
241:
242: TreeMaker make = wc.getTreeMaker();
243: if (typeName.endsWith("[]")) { // NOI18N
244: String elementTypeName = typeName.substring(0, typeName
245: .length() - 2);
246: return make.ArrayType(createType(wc, elementTypeName));
247: }
248:
249: TypeKind primitiveTypeKind = null;
250: if ("boolean".equals(typeName)) { // NOI18N
251: primitiveTypeKind = TypeKind.BOOLEAN;
252: } else if ("byte".equals(typeName)) { // NOI18N
253: primitiveTypeKind = TypeKind.BYTE;
254: } else if ("short".equals(typeName)) { // NOI18N
255: primitiveTypeKind = TypeKind.SHORT;
256: } else if ("int".equals(typeName)) { // NOI18N
257: primitiveTypeKind = TypeKind.INT;
258: } else if ("long".equals(typeName)) { // NOI18N
259: primitiveTypeKind = TypeKind.LONG;
260: } else if ("char".equals(typeName)) { // NOI18N
261: primitiveTypeKind = TypeKind.CHAR;
262: } else if ("float".equals(typeName)) { // NOI18N
263: primitiveTypeKind = TypeKind.FLOAT;
264: } else if ("double".equals(typeName)) { // NOI18N
265: primitiveTypeKind = TypeKind.DOUBLE;
266: } else if ("void".equals(typeName)) {
267: primitiveTypeKind = TypeKind.VOID;
268: }
269: if (primitiveTypeKind != null) {
270: return make.PrimitiveType(primitiveTypeKind);
271: }
272:
273: TypeElement typeElement = wc.getElements().getTypeElement(
274: typeName);
275: if (typeElement == null) {
276: throw new IllegalArgumentException("Type " + typeName
277: + " cannot be found"); // NOI18N
278: }
279: return make.QualIdent(typeElement);
280: }
281:
282: /*
283: * Returns a import tree for a given type in string format
284: *
285: */
286: public static ImportTree createImport(WorkingCopy wc,
287: String typeName) {
288: Tree tree = createType(wc, typeName);
289: return wc.getTreeMaker().Import(tree, false);
290: }
291:
292: public static ModifiersTree createModifiers(WorkingCopy wc) {
293: return wc.getTreeMaker().Modifiers(
294: Collections.<Modifier> emptySet(),
295: Collections.<AnnotationTree> emptyList());
296: }
297:
298: /*
299: * Creates a modifier tree given a single modifier
300: */
301: public static ModifiersTree createModifiers(WorkingCopy wc,
302: Modifier modifier) {
303: return wc.getTreeMaker().Modifiers(EnumSet.of(modifier),
304: Collections.<AnnotationTree> emptyList());
305: }
306:
307: /*
308: * Creates a modifier tree givena single modifier
309: */
310: public static ModifiersTree createModifiers(WorkingCopy wc,
311: long flags) {
312: return wc.getTreeMaker().Modifiers(flags,
313: Collections.<AnnotationTree> emptyList());
314: }
315:
316: /*
317: * Creates a method invocation expression of the form a.b(arg1, ...)
318: */
319: public static MethodInvocationTree createMethodInvocation(
320: WorkingCopy wc, String beanName, String methodName,
321: List<ExpressionTree> args) {
322: TreeMaker treeMaker = wc.getTreeMaker();
323: return treeMaker.MethodInvocation(Collections
324: .<ExpressionTree> emptyList(), treeMaker.MemberSelect(
325: treeMaker.Identifier(beanName), methodName), args);
326: }
327:
328: /*
329: * Creates a method invocation expression of the form b(arg1, ...)
330: */
331: public static MethodInvocationTree createMethodInvocation(
332: WorkingCopy wc, String methodName, String[] pNames) {
333: TreeMaker treeMaker = wc.getTreeMaker();
334: List<ExpressionTree> args = new ArrayList<ExpressionTree>();
335: for (int i = 0; pNames != null && i < pNames.length; i++) {
336: ExpressionTree tree = treeMaker.Identifier(pNames[i]);
337: args.add(tree);
338: }
339: return treeMaker.MethodInvocation(Collections
340: .<ExpressionTree> emptyList(), treeMaker
341: .Identifier(methodName), args);
342: }
343:
344: /*
345: * Creates a new class expression with empty class body
346: */
347: public static NewClassTree createNewClassExpression(WorkingCopy wc,
348: String className) {
349: TreeMaker treeMaker = wc.getTreeMaker();
350: Tree type = TreeMakerUtils.createType(wc, className);
351: ClassTree classTree = treeMaker.Class(TreeMakerUtils
352: .createModifiers(wc), className, Collections
353: .<TypeParameterTree> emptyList(), null, Collections
354: .<ExpressionTree> emptyList(), Collections
355: .<Tree> emptyList());
356: return treeMaker.NewClass(null, Collections
357: .<ExpressionTree> emptyList(), (ExpressionTree) type,
358: Collections.<ExpressionTree> emptyList(), classTree);
359: }
360: }
|