KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > js > util > JavaParser


1 package org.apache.ws.jaxme.js.util;
2
3 import java.io.File JavaDoc;
4 import java.io.FileNotFoundException JavaDoc;
5 import java.io.FileReader JavaDoc;
6 import java.io.Reader JavaDoc;
7 import java.io.Serializable JavaDoc;
8 import java.util.ArrayList JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.StringTokenizer JavaDoc;
11
12 import org.apache.ws.jaxme.js.AbstractJavaMethod;
13 import org.apache.ws.jaxme.js.JavaConstructor;
14 import org.apache.ws.jaxme.js.JavaField;
15 import org.apache.ws.jaxme.js.JavaMethod;
16 import org.apache.ws.jaxme.js.JavaQName;
17 import org.apache.ws.jaxme.js.JavaQNameImpl;
18 import org.apache.ws.jaxme.js.JavaSource;
19 import org.apache.ws.jaxme.js.JavaSourceFactory;
20 import org.apache.ws.jaxme.js.JavaSourceObject;
21 import org.apache.ws.jaxme.js.Parameter;
22 import org.apache.ws.jaxme.js.jparser.JavaLexer;
23 import org.apache.ws.jaxme.js.jparser.JavaRecognizer;
24 import org.apache.ws.jaxme.js.jparser.JavaTokenTypes;
25
26 import antlr.RecognitionException;
27 import antlr.TokenStream;
28 import antlr.TokenStreamException;
29 import antlr.collections.AST;
30
31
32 /** <p>The <code>JavaParser</code> is a utility class, that
33  * reads Java sources and converts them into instances of
34  * {@link org.apache.ws.jaxme.js.JavaSource}.</p>
35  */

36 public class JavaParser implements Serializable JavaDoc, Cloneable JavaDoc {
37     private final JavaSourceFactory factory;
38     private final List JavaDoc importStatements = new ArrayList JavaDoc();
39     private final List JavaDoc generatedClasses = new ArrayList JavaDoc();
40     private String JavaDoc packageName;
41
42     /** <p>Creates a new instance of <code>JavaParser</code>,
43      * that will use the given {@link JavaSourceFactory} for
44      * creating instances of {@link JavaSource}.</p>
45      */

46     public JavaParser(JavaSourceFactory pFactory) {
47         factory = pFactory;
48     }
49
50     /** Returns the factory.
51      */

52     public JavaSourceFactory getFactory() {
53         return factory;
54     }
55
56     /** Returns the package name.
57      */

58     public String JavaDoc getPackageName() {
59         return packageName;
60     }
61
62     /** Sets the package name.
63      */

64     public void setPackageName(String JavaDoc pPackageName) {
65         packageName = pPackageName;
66     }
67
68     /** <p>Parses the given file.</p>
69      * @return List of classes, that have been read.
70      */

71     public List JavaDoc parse(File JavaDoc pFile) throws RecognitionException, TokenStreamException, FileNotFoundException JavaDoc {
72         return parse(new FileReader JavaDoc(pFile));
73     }
74
75     /** <p>Parses the input read from the given
76      * {@link Reader} <code>pReader</code>.</p>
77      * @return List of classes, that have been read.
78      */

79     public List JavaDoc parse(Reader JavaDoc pReader) throws RecognitionException, TokenStreamException {
80         return parse(new JavaLexer(pReader));
81     }
82
83     private void showAST(int pLevel, AST pAST) {
84         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
85         for (int i = 0; i < pLevel; i++) {
86             sb.append(" ");
87         }
88         System.out.println(sb.toString() + pAST.getType() + " " + pAST.getText());
89         for (AST child = pAST.getFirstChild(); child != null; child = child.getNextSibling()) {
90             showAST(pLevel+1, child);
91         }
92     }
93
94     private void reset() {
95         packageName = null;
96         importStatements.clear();
97     }
98
99     /** Parses the given {@link TokenStream} <code>pStream</code>.
100      * @return List of classes, that have been read.
101      */

102     public List JavaDoc parse(TokenStream pStream) throws RecognitionException, TokenStreamException {
103         reset();
104         JavaRecognizer parser = new JavaRecognizer(pStream);
105         parser.compilationUnit();
106         for (AST ast = parser.getAST(); ast != null; ast = ast.getNextSibling()) {
107             //showAST(0, ast);
108
parseAST(ast);
109         }
110         return generatedClasses;
111     }
112
113     private void parsePackageName(AST pAST) {
114         setPackageName(parseIdentifier(pAST));
115     }
116
117     private void addImportStatement(JavaQName pQName) {
118         importStatements.add(pQName);
119     }
120
121     private void parseImportStatement(AST pAST) {
122         addImportStatement(JavaQNameImpl.getInstance(parseIdentifier(pAST), true));
123     }
124
125     private String JavaDoc parseIdentifier(AST pAST) {
126         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
127         for (AST child = pAST.getFirstChild(); child != null; child = child.getNextSibling()) {
128             parseIdentifier(child, sb);
129         }
130         return sb.toString();
131     }
132
133     private String JavaDoc parseSimpleIdentifier(AST pAST) {
134         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
135         parseIdentifier(pAST, sb);
136         return sb.toString();
137     }
138
139     private void parseIdentifier(AST pAST, StringBuffer JavaDoc sb) {
140         switch (pAST.getType()) {
141             case JavaTokenTypes.ANNOTATIONS:
142                 // Ignore this
143
break;
144             case JavaTokenTypes.LITERAL_void:
145             case JavaTokenTypes.LITERAL_boolean:
146             case JavaTokenTypes.LITERAL_byte:
147             case JavaTokenTypes.LITERAL_char:
148             case JavaTokenTypes.LITERAL_short:
149             case JavaTokenTypes.LITERAL_int:
150             case JavaTokenTypes.LITERAL_long:
151             case JavaTokenTypes.LITERAL_float:
152             case JavaTokenTypes.LITERAL_double:
153                 sb.append(pAST.getText());
154                 break;
155             case JavaTokenTypes.IDENT:
156                 sb.append(pAST.getText());
157                 break;
158             case JavaTokenTypes.DOT:
159                 boolean first = true;
160                 for (AST child = pAST.getFirstChild(); child != null; child = child.getNextSibling()) {
161                     if (first) {
162                         first = false;
163                     } else {
164                         sb.append('.');
165                     }
166                     parseIdentifier(child, sb);
167                 }
168                 break;
169             case JavaTokenTypes.ARRAY_DECLARATOR:
170                 sb.append("[]");
171                 for (AST child = pAST.getFirstChild(); child != null;
172                      child = child.getNextSibling()) {
173                     parseIdentifier(child, sb);
174                 }
175                 break;
176             default:
177                 throw new IllegalStateException JavaDoc("Unknown token: " + pAST.getType());
178         }
179     }
180
181     private AST findChild(AST pAST, int pType) {
182         for (AST child = pAST.getFirstChild(); child != null; child = child.getNextSibling()) {
183             if (child.getType() == pType) {
184                 return child;
185             }
186         }
187         return null;
188     }
189
190     private JavaSource getJavaSource(JavaSource pOuterClass, AST pAST) {
191         AST classNameAST = findChild(pAST, JavaRecognizer.IDENT);
192         if (classNameAST == null) {
193             throw new IllegalStateException JavaDoc("Missing class name");
194         }
195         String JavaDoc className = classNameAST.getText();
196         if (pOuterClass == null) {
197             String JavaDoc packageName = getPackageName();
198             JavaQName qName;
199             if (packageName == null) {
200                 qName = JavaQNameImpl.getInstance(className);
201             } else {
202                 qName = JavaQNameImpl.getInstance(packageName, className);
203             }
204             JavaSource js = factory.newJavaSource(qName, JavaSource.DEFAULT_PROTECTION);
205             generatedClasses.add(js);
206             return js;
207         } else {
208             return pOuterClass.newJavaInnerClass(className, JavaSource.DEFAULT_PROTECTION);
209         }
210     }
211
212     private void parseModifiers(JavaSourceObject pObject, AST pAST) {
213         AST modifiers = findChild(pAST, JavaRecognizer.MODIFIERS);
214         if (modifiers == null) {
215             throw new IllegalStateException JavaDoc("Missing MODIFIERS");
216         }
217         for (AST child = modifiers.getFirstChild(); child != null; child = child.getNextSibling()) {
218             switch (child.getType()) {
219                 case JavaTokenTypes.LITERAL_public:
220                     pObject.setProtection(JavaSource.PUBLIC);
221                     break;
222                 case JavaTokenTypes.LITERAL_protected:
223                     pObject.setProtection(JavaSource.PROTECTED);
224                     break;
225                 case JavaTokenTypes.LITERAL_private:
226                     pObject.setProtection(JavaSource.PRIVATE);
227                     break;
228                 case JavaTokenTypes.LITERAL_static:
229                     pObject.setStatic(true);
230                     break;
231                 case JavaTokenTypes.ABSTRACT:
232                     pObject.setAbstract(true);
233                     break;
234                 case JavaTokenTypes.FINAL:
235                     pObject.setFinal(true);
236                     break;
237             }
238         }
239     }
240
241     private void parseModifiers(Parameter pParam, AST pAST) {
242         AST modifiers = findChild(pAST, JavaRecognizer.MODIFIERS);
243         if (modifiers == null) {
244             throw new IllegalStateException JavaDoc("Missing MODIFIERS");
245         }
246     }
247
248     private void parseModifiers(JavaSource pSource, AST pAST) {
249         AST modifiers = findChild(pAST, JavaRecognizer.MODIFIERS);
250         if (modifiers == null) {
251             throw new IllegalStateException JavaDoc("Missing MODIFIERS");
252         }
253         for (AST child = modifiers.getFirstChild(); child != null; child = child.getNextSibling()) {
254             switch (child.getType()) {
255                 case JavaTokenTypes.LITERAL_public:
256                     pSource.setProtection(JavaSource.PUBLIC);
257                     break;
258                 case JavaTokenTypes.LITERAL_protected:
259                     pSource.setProtection(JavaSource.PROTECTED);
260                     break;
261                 case JavaTokenTypes.LITERAL_private:
262                     pSource.setProtection(JavaSource.PRIVATE);
263                     break;
264                 case JavaTokenTypes.LITERAL_static:
265                     pSource.setStatic(true);
266                     break;
267                 case JavaTokenTypes.ABSTRACT:
268                     pSource.setAbstract(true);
269                     break;
270                 case JavaTokenTypes.FINAL:
271                     //pSource.setFinal(true);
272
break;
273             }
274         }
275     }
276
277     private JavaQName getQName(String JavaDoc pName) {
278         if (pName.endsWith("[]")) {
279             return JavaQNameImpl.getArray(getQName(pName.substring(0, pName.length()-2)));
280         }
281         int offset = pName.indexOf('.');
282         String JavaDoc firstIdent;
283         String JavaDoc suffix;
284         if (offset > 0) {
285             firstIdent = pName.substring(0, offset);
286             suffix = pName.substring(offset+1);
287         } else {
288             firstIdent = pName;
289             suffix = "";
290         }
291         for (int i = 0; i < importStatements.size(); i++) {
292             JavaQName qName = (JavaQName) importStatements.get(i);
293             if (qName.getClassName().equals(firstIdent)) {
294                 for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(suffix, "."); st.hasMoreTokens(); ) {
295                     String JavaDoc s = st.nextToken();
296                     qName = JavaQNameImpl.getInnerInstance(qName, s);
297                 }
298                 return qName;
299             }
300         }
301         return JavaQNameImpl.getInstance(pName, true);
302     }
303
304     private void parseImplementsOrExtends(JavaSource pSource, AST pAST, int pType) {
305         AST implementsAST = findChild(pAST, pType);
306         if (implementsAST == null) {
307             throw new IllegalStateException JavaDoc("AST implements not found");
308         }
309         if (implementsAST.getFirstChild() != null) {
310             String JavaDoc ident = parseIdentifier(implementsAST);
311             JavaQName qName = getQName(ident);
312             if (pType == JavaRecognizer.IMPLEMENTS_CLAUSE) {
313                 pSource.addImplements(qName);
314             } else {
315                 pSource.addExtends(qName);
316             }
317         }
318     }
319
320     private JavaField getJavaField(JavaSource pSource, AST pAST) {
321         AST fieldNameAST = findChild(pAST, JavaRecognizer.IDENT);
322         if (fieldNameAST == null) {
323             throw new IllegalStateException JavaDoc("Missing IDENT AST");
324         }
325         String JavaDoc fieldName = fieldNameAST.getText();
326         AST type = findChild(pAST, JavaRecognizer.TYPE);
327         if (type == null) {
328             throw new IllegalStateException JavaDoc("Missing TYPE AST");
329         }
330         String JavaDoc typeName = parseIdentifier(type);
331         JavaQName typeQName = getQName(typeName);
332         return pSource.newJavaField(fieldName, typeName, JavaSource.DEFAULT_PROTECTION);
333     }
334
335     private void parseFieldDefinition(JavaSource pSource, AST pAST) {
336         JavaField jf = getJavaField(pSource, pAST);
337         parseModifiers(jf, pAST);
338     }
339
340
341     private JavaMethod getJavaMethod(JavaSource pSource, AST pAST) {
342         AST fieldNameAST = findChild(pAST, JavaRecognizer.IDENT);
343         if (fieldNameAST == null) {
344             throw new IllegalStateException JavaDoc("Missing IDENT AST");
345         }
346         String JavaDoc fieldName = fieldNameAST.getText();
347         AST type = findChild(pAST, JavaRecognizer.TYPE);
348         if (type == null) {
349             throw new IllegalStateException JavaDoc("Missing TYPE AST");
350         }
351         String JavaDoc typeName = parseIdentifier(type);
352         if (typeName == null) {
353             throw new IllegalStateException JavaDoc("Missing identifier for " + fieldName);
354         }
355         JavaQName typeQName = getQName(typeName);
356         return pSource.newJavaMethod(fieldName, typeQName, JavaSource.DEFAULT_PROTECTION);
357     }
358
359     private Parameter getParameter(AbstractJavaMethod pMethod, AST pAST) {
360         AST paramNameAST = findChild(pAST, JavaRecognizer.IDENT);
361         if (paramNameAST == null) {
362             throw new IllegalStateException JavaDoc("Missing IDENT AST");
363         }
364         String JavaDoc paramName = paramNameAST.getText();
365         AST type = findChild(pAST, JavaRecognizer.TYPE);
366         if (type == null) {
367             throw new IllegalStateException JavaDoc("Missing TYPE AST");
368         }
369         String JavaDoc typeName = parseIdentifier(type);
370         JavaQName typeQName = getQName(typeName);
371         return pMethod.addParam(typeQName, paramName);
372     }
373
374     private void parseParameter(AbstractJavaMethod pMethod, AST pAST) {
375         Parameter param = getParameter(pMethod, pAST);
376         parseModifiers(param, pAST);
377     }
378
379     private void parseParameters(AbstractJavaMethod pMethod, AST pAST) {
380         AST params = findChild(pAST, JavaRecognizer.PARAMETERS);
381         if (params == null) {
382             throw new IllegalStateException JavaDoc("Missing PARAMETERS AST");
383         }
384         for (AST child = params.getFirstChild(); child != null; child = child.getNextSibling()) {
385             switch (child.getType()) {
386                 case JavaRecognizer.PARAMETER_DEF:
387                     parseParameter(pMethod, child);
388                     break;
389             }
390         }
391     }
392
393     private void parseExceptions(AbstractJavaMethod pMethod, AST pAST) {
394         AST throwsClause = findChild(pAST, JavaTokenTypes.LITERAL_throws);
395         if (throwsClause != null) {
396             for (AST child = throwsClause.getFirstChild(); child != null; child = child.getNextSibling()) {
397                 String JavaDoc ident = parseSimpleIdentifier(child);
398                 JavaQName qName = getQName(ident);
399                 pMethod.addThrows(qName);
400             }
401         }
402     }
403
404     private void parseMethodDefinition(JavaSource pSource, AST pAST) {
405         JavaMethod jm = getJavaMethod(pSource, pAST);
406         parseModifiers(jm, pAST);
407         parseParameters(jm, pAST);
408         parseExceptions(jm, pAST);
409     }
410
411     private void parseConstructorDefinition(JavaSource pSource, AST pAST) {
412         JavaConstructor jc = pSource.newJavaConstructor(JavaSource.DEFAULT_PROTECTION);
413         parseModifiers(jc, pAST);
414         parseParameters(jc, pAST);
415         parseExceptions(jc, pAST);
416     }
417
418     private void parseObjects(JavaSource pSource, AST pAST) {
419         AST objBlock = findChild(pAST, JavaRecognizer.OBJBLOCK);
420         if (objBlock == null) {
421             throw new IllegalStateException JavaDoc("Missing OBKBLOCK");
422         }
423         for (AST child = objBlock.getFirstChild(); child != null; child = child.getNextSibling()) {
424             switch (child.getType()) {
425                 case JavaTokenTypes.VARIABLE_DEF:
426                     parseFieldDefinition(pSource, child);
427                     break;
428                 case JavaTokenTypes.METHOD_DEF:
429                     parseMethodDefinition(pSource, child);
430                     break;
431                 case JavaTokenTypes.CTOR_DEF:
432                     parseConstructorDefinition(pSource, child);
433                     break;
434                 case JavaTokenTypes.CLASS_DEF:
435                     parseClassDefinition(pSource, JavaSource.CLASS, child);
436                     break;
437                 case JavaTokenTypes.INTERFACE_DEF:
438                     parseClassDefinition(pSource, JavaSource.CLASS, child);
439                     break;
440             }
441         }
442     }
443
444     private void parseClassDefinition(JavaSource pOuterClass,
445                                       JavaSource.Type pType, AST pAST) {
446         JavaSource currentClass = getJavaSource(pOuterClass, pAST);
447         currentClass.setType(pType);
448         parseModifiers(currentClass, pAST);
449         parseImplementsOrExtends(currentClass, pAST, JavaRecognizer.EXTENDS_CLAUSE);
450         if (!JavaSource.INTERFACE.equals(pType)) {
451             parseImplementsOrExtends(currentClass, pAST, JavaRecognizer.IMPLEMENTS_CLAUSE);
452         }
453         parseObjects(currentClass, pAST);
454     }
455
456     private void parseAST(AST pAST) {
457         switch (pAST.getType()) {
458             case JavaRecognizer.PACKAGE_DEF:
459                 parsePackageName(pAST);
460                 break;
461             case JavaRecognizer.IMPORT:
462                 parseImportStatement(pAST);
463                 break;
464             case JavaRecognizer.CLASS_DEF:
465                 parseClassDefinition(null, JavaSource.CLASS, pAST);
466                 break;
467             case JavaRecognizer.INTERFACE_DEF:
468                 parseClassDefinition(null, JavaSource.INTERFACE, pAST);
469                 break;
470         }
471     }
472
473     /** For tests
474      */

475     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
476         for (int i = 0; i < args.length; i++) {
477             new JavaParser(new JavaSourceFactory()).parse(new File JavaDoc(args[i]));
478         }
479     }
480 }
481
Popular Tags