KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > gen > TreeMakerDemo


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.api.java.source.gen;
20
21 import com.sun.source.tree.*;
22 import com.sun.source.util.SourcePositions;
23 import java.io.BufferedReader JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.FileReader JavaDoc;
26 import java.io.PrintStream JavaDoc;
27 import java.util.List JavaDoc;
28 import org.netbeans.api.java.source.CancellableTask;
29 import org.netbeans.api.java.source.JavaSource;
30 import org.netbeans.api.java.source.JavaSource.Phase;
31 import org.netbeans.api.java.source.TestUtilities;
32 import org.netbeans.api.java.source.TreeMaker;
33 import org.netbeans.api.java.source.TreeUtilities;
34 import org.netbeans.api.java.source.WorkingCopy;
35 import org.netbeans.junit.NbTestCase;
36 import org.openide.filesystems.FileUtil;
37 import static com.sun.source.tree.Tree.*;
38
39 /**
40  * This class demonstrates how to make trees. It gets the statement as a string,
41  * string is get parsed and then parsed tree is reversed to code which can be
42  * used in source code for tree/code creation.
43  *
44  * @author Pavel Flaska
45  */

46 public class TreeMakerDemo extends NbTestCase {
47     
48     /* Prevent instantiation */
49     public TreeMakerDemo(String JavaDoc name) {
50         super(name);
51     }
52     
53     public static String JavaDoc reverse(Tree tree) {
54         StringBuilder JavaDoc builder = new StringBuilder JavaDoc();
55         reverse(tree, 0, builder);
56         int length = builder.length();
57         builder.replace(length-1, length, ";");
58         return builder.toString();
59     }
60     
61     private static void reverse(List JavaDoc<? extends Tree> list, int indent, StringBuilder JavaDoc builder, boolean comma) {
62         int size = list.size();
63         indent(indent, builder);
64         switch (size) {
65             case 0:
66                 builder.append("Collections.emptyList(),");
67                 return; // finished, exit immediately, no ) is needed
68
case 1:
69                 builder.append("Collections.<typePar>singletonList(");
70                 ++indent;
71                 reverse(list.iterator().next(), indent, builder);
72                 removeLastCharacter(builder);
73                 break;
74             default:
75                 builder.append("new ArrayList<typePar>(");
76                 for (Tree t : list) {
77                     indent(indent, builder);
78                     reverse(t, ++indent, builder);
79                     builder.append(',');
80                 }
81                 removeLastCharacter(builder);
82                 break;
83         }
84         indent(--indent, builder);
85         builder.append(')');
86         if (comma) builder.append(',');
87     }
88
89     private static void removeLastCharacter(StringBuilder JavaDoc builder) {
90         builder.delete(builder.length()-1, builder.length());
91     }
92     
93     private static void reverse(CharSequence JavaDoc identifier, int indent, StringBuilder JavaDoc builder) {
94         indent(indent, builder);
95         builder.append('"').append(identifier).append('"');
96     }
97     
98     private static void reverse(Tree tree, int indent, StringBuilder JavaDoc builder) {
99         reverse(tree, indent, builder, true);
100     }
101     
102     private static void reverse(Tree tree, int indent, StringBuilder JavaDoc builder, boolean comma) {
103         // null values are allowed
104
if (tree == null) {
105             indent(indent, builder);
106             builder.append("null,");
107             return;
108         }
109         indent(indent, builder);
110         switch (tree.getKind()) {
111             case ASSIGNMENT:
112                 builder.append("make.Assignment(");
113                 AssignmentTree assignmentTree = (AssignmentTree) tree;
114                 reverse(assignmentTree.getVariable(), ++indent, builder, true);
115                 reverse(assignmentTree.getExpression(), indent, builder, false);
116                 break;
117             case EXPRESSION_STATEMENT:
118                 builder.append("make.ExpressionStatement(");
119                 ExpressionStatementTree exprStatement = (ExpressionStatementTree) tree;
120                 reverse(exprStatement.getExpression(), ++indent, builder, false);
121                 break;
122             case IDENTIFIER:
123                 builder.append("make.Identifier(\"");
124                 IdentifierTree identifier = (IdentifierTree) tree;
125                 builder.append(identifier.getName());
126                 builder.append("\")");
127                 if (comma) builder.append(',');
128                 return; // branch finished, return immediately
129
case MEMBER_SELECT:
130                 builder.append("make.MemberSelect(");
131                 MemberSelectTree memberSelect = (MemberSelectTree) tree;
132                 ++indent;
133                 reverse(memberSelect.getExpression(), indent, builder);
134                 reverse(memberSelect.getIdentifier(), indent, builder);
135                 break;
136             case METHOD_INVOCATION:
137                 builder.append("make.MethodInvocation(");
138                 MethodInvocationTree methodInvocation = (MethodInvocationTree) tree;
139                 ++indent;
140                 reverse(methodInvocation.getTypeArguments(), indent, builder, true);
141                 reverse(methodInvocation.getMethodSelect(), indent, builder);
142                 reverse(methodInvocation.getArguments(), indent, builder, false);
143                 break;
144             case NEW_CLASS:
145                 builder.append("make.NewClass(");
146                 NewClassTree newClassTree = (NewClassTree) tree;
147                 ++indent;
148                 reverse(newClassTree.getEnclosingExpression(), indent, builder);
149                 reverse(newClassTree.getTypeArguments(), indent, builder, true);
150                 reverse(newClassTree.getIdentifier(), indent, builder);
151                 reverse(newClassTree.getArguments(), indent, builder, true);
152                 reverse(newClassTree.getClassBody(), indent, builder);
153                 break;
154             case NULL_LITERAL:
155             case INT_LITERAL:
156             case LONG_LITERAL:
157             case FLOAT_LITERAL:
158             case DOUBLE_LITERAL:
159             case BOOLEAN_LITERAL:
160             case STRING_LITERAL:
161             case CHAR_LITERAL:
162                 builder.append("make.Literal(");
163                 if (Kind.STRING_LITERAL == tree.getKind()) builder.append('"');
164                 if (Kind.CHAR_LITERAL == tree.getKind()) builder.append('\'');
165                 LiteralTree literalTree = (LiteralTree) tree;
166                 builder.append(literalTree.getValue());
167                 if (Kind.STRING_LITERAL == tree.getKind()) builder.append('"');
168                 if (Kind.CHAR_LITERAL == tree.getKind()) builder.append('\'');
169                 builder.append("),");
170                 return;
171             case CLASS:
172                 builder.append("make.Class(");
173                 ClassTree classTree = (ClassTree) tree;
174                 ++indent;
175                 reverse(classTree.getModifiers(), indent, builder, true);
176                 reverse(classTree.getSimpleName(), indent, builder);
177                 reverse(classTree.getTypeParameters(), indent, builder, true);
178                 reverse(classTree.getExtendsClause(), indent, builder, true);
179                 reverse(classTree.getImplementsClause(), indent, builder, true);
180                 reverse(classTree.getMembers(), indent, builder, false);
181                 break;
182             case METHOD:
183                 builder.append("make.Method(");
184                 MethodTree methodTree = (MethodTree) tree;
185                 ++indent;
186                 reverse(methodTree.getModifiers(), indent, builder, true);
187                 reverse(methodTree.getTypeParameters(), indent, builder, true);
188                 reverse(methodTree.getReturnType(), indent, builder, true);
189                 reverse(methodTree.getName(), indent, builder);
190                 reverse(methodTree.getParameters(), indent, builder, true);
191                 reverse(methodTree.getThrows(), indent, builder, true);
192                 reverse(methodTree.getBody(), indent, builder, true);
193                 reverse(methodTree.getDefaultValue(), indent, builder, false);
194                 break;
195             case PRIMITIVE_TYPE:
196                 builder.append("make.PrimitiveType(TypeKind.");
197                 PrimitiveTypeTree primitiveTypeTree = (PrimitiveTypeTree) tree;
198                 builder.append(primitiveTypeTree.getPrimitiveTypeKind().toString());
199                 builder.append("),");
200                 return;
201             case MODIFIERS:
202                 builder.append("make.Modifiers(");
203                 ModifiersTree modifiersTree = (ModifiersTree) tree;
204                 ++indent;
205                 // todo: not finished!
206
builder.append("),");
207                 return;
208             case BLOCK:
209                 builder.append("make.Block(");
210                 BlockTree blockTree = (BlockTree) tree;
211                 ++indent;
212                 reverse(blockTree.getStatements(), indent, builder, true);
213                 builder.append(' ').append(blockTree.isStatic());
214                 break;
215             default:
216                 builder.append("\"<");
217                 builder.append(tree.getKind());
218                 builder.append(" tree was not reversed!>\"");
219                 return;
220         }
221         indent(--indent, builder);
222         builder.append(')');
223         if (comma) builder.append(',');
224     }
225     
226     static void indent(int i, StringBuilder JavaDoc builder) {
227         builder.append('\n');
228         for (int j = 0; j < i; j++)
229             builder.append(" ");
230     }
231     
232     public void test() throws Exception JavaDoc {
233         main(null);
234     }
235     
236     /**
237      * @param args the command line arguments
238      */

239     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
240         File JavaDoc testFile = new File JavaDoc("/tmp/Test.java");
241         TestUtilities.copyStringToFile(testFile,
242             "package hierbas.del.litoral;\n\n" +
243             "import java.io.*;\n\n" +
244             "public class Test {\n" +
245             " public void taragui() {\n" +
246             " }\n" +
247             "}\n"
248             );
249         JavaSource tutorialSource = JavaSource.forFileObject(FileUtil.toFileObject(testFile));
250         final String JavaDoc statementText =
251                 " new Runnable() {" +
252                 " public void run() {" +
253                 " }" +
254                 " };";
255         
256         CancellableTask task = new CancellableTask<WorkingCopy>() {
257
258             public void run(WorkingCopy workingCopy) throws java.io.IOException JavaDoc {
259                 workingCopy.toPhase(Phase.RESOLVED);
260                 TreeMaker make = workingCopy.getTreeMaker();
261                 
262                 SourcePositions[] positions = new SourcePositions[1];
263                 final TreeUtilities treeUtils = workingCopy.getTreeUtilities();
264                 StatementTree body = treeUtils.parseStatement(statementText, positions);
265                 System.err.println(TreeMakerDemo.reverse(body));
266             }
267             
268             public void cancel() {
269             }
270         };
271
272         tutorialSource.runModificationTask(task).commit();
273         
274         // print the result to the System.err to see the changes in console.
275
BufferedReader JavaDoc in = new BufferedReader JavaDoc(new FileReader JavaDoc(testFile));
276         PrintStream JavaDoc out = System.out;
277         String JavaDoc str;
278         while ((str = in.readLine()) != null) {
279             out.println(str);
280         }
281         in.close();
282     }
283 }
284
Popular Tags