1 package org.apache.ws.jaxme.js.util; 2 3 import java.io.File ; 4 import java.io.FileNotFoundException ; 5 import java.io.FileReader ; 6 import java.io.Reader ; 7 import java.io.Serializable ; 8 import java.util.ArrayList ; 9 import java.util.List ; 10 import java.util.StringTokenizer ; 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 36 public class JavaParser implements Serializable , Cloneable { 37 private final JavaSourceFactory factory; 38 private final List importStatements = new ArrayList (); 39 private final List generatedClasses = new ArrayList (); 40 private String packageName; 41 42 46 public JavaParser(JavaSourceFactory pFactory) { 47 factory = pFactory; 48 } 49 50 52 public JavaSourceFactory getFactory() { 53 return factory; 54 } 55 56 58 public String getPackageName() { 59 return packageName; 60 } 61 62 64 public void setPackageName(String pPackageName) { 65 packageName = pPackageName; 66 } 67 68 71 public List parse(File pFile) throws RecognitionException, TokenStreamException, FileNotFoundException { 72 return parse(new FileReader (pFile)); 73 } 74 75 79 public List parse(Reader pReader) throws RecognitionException, TokenStreamException { 80 return parse(new JavaLexer(pReader)); 81 } 82 83 private void showAST(int pLevel, AST pAST) { 84 StringBuffer sb = new StringBuffer (); 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 102 public List 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 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 parseIdentifier(AST pAST) { 126 StringBuffer sb = new StringBuffer (); 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 parseSimpleIdentifier(AST pAST) { 134 StringBuffer sb = new StringBuffer (); 135 parseIdentifier(pAST, sb); 136 return sb.toString(); 137 } 138 139 private void parseIdentifier(AST pAST, StringBuffer sb) { 140 switch (pAST.getType()) { 141 case JavaTokenTypes.ANNOTATIONS: 142 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 ("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 ("Missing class name"); 194 } 195 String className = classNameAST.getText(); 196 if (pOuterClass == null) { 197 String 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 ("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 ("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 ("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 break; 273 } 274 } 275 } 276 277 private JavaQName getQName(String pName) { 278 if (pName.endsWith("[]")) { 279 return JavaQNameImpl.getArray(getQName(pName.substring(0, pName.length()-2))); 280 } 281 int offset = pName.indexOf('.'); 282 String firstIdent; 283 String 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 st = new StringTokenizer (suffix, "."); st.hasMoreTokens(); ) { 295 String 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 ("AST implements not found"); 308 } 309 if (implementsAST.getFirstChild() != null) { 310 String 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 ("Missing IDENT AST"); 324 } 325 String fieldName = fieldNameAST.getText(); 326 AST type = findChild(pAST, JavaRecognizer.TYPE); 327 if (type == null) { 328 throw new IllegalStateException ("Missing TYPE AST"); 329 } 330 String 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 ("Missing IDENT AST"); 345 } 346 String fieldName = fieldNameAST.getText(); 347 AST type = findChild(pAST, JavaRecognizer.TYPE); 348 if (type == null) { 349 throw new IllegalStateException ("Missing TYPE AST"); 350 } 351 String typeName = parseIdentifier(type); 352 if (typeName == null) { 353 throw new IllegalStateException ("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 ("Missing IDENT AST"); 363 } 364 String paramName = paramNameAST.getText(); 365 AST type = findChild(pAST, JavaRecognizer.TYPE); 366 if (type == null) { 367 throw new IllegalStateException ("Missing TYPE AST"); 368 } 369 String 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 ("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 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 ("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 475 public static void main(String [] args) throws Exception { 476 for (int i = 0; i < args.length; i++) { 477 new JavaParser(new JavaSourceFactory()).parse(new File (args[i])); 478 } 479 } 480 } 481 | Popular Tags |