1 18 package org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.declaration; 19 20 import org.apache.beehive.netui.compiler.JpfLanguageConstants; 21 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance; 22 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeDeclaration; 23 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeElementDeclaration; 24 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue; 25 import org.apache.beehive.netui.compiler.typesystem.declaration.Declaration; 26 import org.apache.beehive.netui.compiler.typesystem.declaration.Modifier; 27 import org.apache.beehive.netui.compiler.typesystem.type.AnnotationType; 28 import org.apache.beehive.netui.compiler.typesystem.type.ClassType; 29 import org.apache.beehive.netui.compiler.typesystem.type.PrimitiveType; 30 import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance; 31 import org.apache.beehive.netui.compiler.typesystem.type.ArrayType; 32 import org.apache.beehive.netui.compiler.typesystem.type.DeclaredType; 33 import org.apache.beehive.netui.compiler.typesystem.util.SourcePosition; 34 import org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.DelegatingImpl; 35 import org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.env.SourcePositionImpl; 36 import org.apache.beehive.netui.compiler.xdoclet.typesystem.impl.type.AnnotationTypeImpl; 37 import org.apache.beehive.netui.xdoclet.XDocletCompilerUtils; 38 import xjavadoc.XDoc; 39 import xjavadoc.XProgramElement; 40 import xjavadoc.XTag; 41 42 import java.io.BufferedReader ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.io.InputStreamReader ; 46 import java.io.Reader ; 47 import java.io.StreamTokenizer ; 48 import java.util.ArrayList ; 49 import java.util.Collection ; 50 import java.util.HashMap ; 51 import java.util.HashSet ; 52 import java.util.Iterator ; 53 import java.util.List ; 54 import java.util.Set ; 55 import java.util.StringTokenizer ; 56 57 public class DeclarationImpl 58 extends DelegatingImpl 59 implements Declaration, JpfLanguageConstants 60 { 61 private static final String VALIDATION_ERROR_FORWARD_TAG_NAME = "ValidationErrorForward"; 62 private static final HashMap MODIFIERS = new HashMap (); 63 private static final HashMap MEMBER_ARRAY_ANNOTATIONS = new HashMap (); 64 private static final HashMap MEMBER_ANNOTATIONS = new HashMap (); 65 private static final HashSet MEMBER_OR_TOPLEVEL_ANNOTATIONS = new HashSet (); 66 67 static 68 { 69 MODIFIERS.put( "abstract", Modifier.ABSTRACT ); 70 MODIFIERS.put( "private", Modifier.PRIVATE ); 71 MODIFIERS.put( "protected", Modifier.PROTECTED ); 72 MODIFIERS.put( "public", Modifier.PUBLIC ); 73 MODIFIERS.put( "static", Modifier.STATIC ); 74 MODIFIERS.put( "transient", Modifier.TRANSIENT ); 75 MODIFIERS.put( "final", Modifier.FINAL ); 76 MODIFIERS.put( "synchronized", Modifier.SYNCHRONIZED ); 77 MODIFIERS.put( "native", Modifier.NATIVE ); 78 79 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + FORWARD_TAG_NAME, FORWARDS_ATTR ); 80 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + CATCH_TAG_NAME, CATCHES_ATTR ); 81 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + SIMPLE_ACTION_TAG_NAME, SIMPLE_ACTIONS_ATTR ); 82 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + ACTION_OUTPUT_TAG_NAME, ACTION_OUTPUTS_ATTR ); 83 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + CONDITIONAL_FORWARD_TAG_NAME, CONDITIONAL_FORWARDS_ATTR ); 84 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + MESSAGE_BUNDLE_TAG_NAME, MESSAGE_BUNDLES_ATTR ); 85 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + MESSAGE_ARG_TAG_NAME, MESSAGE_ARGS_ATTR ); 86 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_CUSTOM_RULE_TAG_NAME, VALIDATE_CUSTOM_ATTR ); 87 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_CUSTOM_VARIABLE_TAG_NAME, VARIABLES_ATTR ); 88 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATION_LOCALE_RULES_TAG_NAME, LOCALE_RULES_ATTR ); 89 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATABLE_PROPERTY_TAG_NAME, VALIDATABLE_PROPERTIES_ATTR ); 90 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATABLE_BEAN_TAG_NAME, VALIDATABLE_BEANS_ATTR ); 91 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + RAISE_ACTION_TAG_NAME, RAISE_ACTIONS_ATTR ); 92 MEMBER_ARRAY_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + SHARED_FLOW_REF_TAG_NAME, SHARED_FLOW_REFS_ATTR ); 93 94 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATION_ERROR_FORWARD_TAG_NAME, VALIDATION_ERROR_FORWARD_ATTR ); 95 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_REQUIRED_TAG_NAME, VALIDATE_REQUIRED_ATTR ); 96 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_MIN_LENGTH_TAG_NAME, VALIDATE_MIN_LENGTH_ATTR ); 97 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_MAX_LENGTH_TAG_NAME, VALIDATE_MAX_LENGTH_ATTR ); 98 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_MASK_TAG_NAME, VALIDATE_MASK_ATTR ); 99 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_TYPE_TAG_NAME, VALIDATE_TYPE_ATTR ); 100 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_DATE_TAG_NAME, VALIDATE_DATE_ATTR ); 101 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_RANGE_TAG_NAME, VALIDATE_RANGE_ATTR ); 102 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_CREDIT_CARD_TAG_NAME, VALIDATE_CREDIT_CARD_ATTR ); 103 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_EMAIL_TAG_NAME, VALIDATE_EMAIL_ATTR ); 104 MEMBER_ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATE_VALID_WHEN_TAG_NAME, VALIDATE_VALID_WHEN_ATTR ); 105 106 MEMBER_OR_TOPLEVEL_ANNOTATIONS.add( ANNOTATION_INTERFACE_PREFIX + VALIDATABLE_PROPERTY_TAG_NAME ); 107 } 108 109 private HashSet _modifiers; 110 private AnnotationInstance[] _annotations; 111 112 public DeclarationImpl( XProgramElement delegate ) 113 { 114 super( delegate ); 115 ArrayList annotations = getAnnotations( delegate ); 116 _annotations = ( AnnotationInstance[] ) annotations.toArray( new AnnotationInstance[ annotations.size() ] ); 117 } 118 119 public String getDocComment() 120 { 121 return getDelegateXProgramElement().getDoc().getCommentText(); 122 } 123 124 public AnnotationInstance[] getAnnotationInstances() 125 { 126 return _annotations; 127 } 128 129 public Set getModifiers() 130 { 131 if ( _modifiers == null ) 132 { 133 HashSet modifiers = new HashSet (); 134 StringTokenizer tok = new StringTokenizer ( getDelegateXProgramElement().getModifiers() ); 135 136 while ( tok.hasMoreTokens() ) 137 { 138 String modifierString = tok.nextToken(); 139 Modifier modifier = ( Modifier ) MODIFIERS.get( modifierString ); 140 assert modifier != null : "unrecognized modifier: " + modifierString; 141 modifiers.add( modifier ); 142 } 143 144 _modifiers = modifiers; 145 } 146 147 return _modifiers; 148 } 149 150 public String getSimpleName() 151 { 152 String name = getDelegateXProgramElement().getName(); 153 int lastDot = name.lastIndexOf( '.' ); 154 return lastDot != -1 ? name.substring( lastDot + 1 ) : name; 155 } 156 157 public SourcePosition getPosition() 158 { 159 return SourcePositionImpl.get( getDelegateXProgramElement() ); 160 } 161 162 public boolean hasModifier( Modifier modifier ) 163 { 164 return getModifiers().contains( modifier ); 165 } 166 167 protected XProgramElement getDelegateXProgramElement() 168 { 169 return ( XProgramElement ) super.getDelegate(); 170 } 171 172 173 private static HashMap ANNOTATIONS = new HashMap (); 174 private static AnnotationTypeDeclaration[] ALL_ANNOTATIONS; 175 176 static 177 { 178 parseAnnotations(); 179 ALL_ANNOTATIONS = ( AnnotationTypeDeclaration[] ) 180 ANNOTATIONS.values().toArray( new AnnotationTypeDeclaration[ ANNOTATIONS.size() ] ); 181 } 182 183 public static AnnotationTypeDeclaration[] getAllAnnotations() 184 { 185 return ALL_ANNOTATIONS; 186 } 187 188 private static StreamTokenizer getJavaTokenizer( Reader reader ) 189 { 190 StreamTokenizer tok = new StreamTokenizer ( reader ); 191 tok.eolIsSignificant( false ); 192 tok.lowerCaseMode( false ); 193 tok.parseNumbers(); 194 tok.slashSlashComments( true ); 195 tok.slashStarComments( true ); 196 tok.wordChars( '_', '_' ); 197 tok.wordChars( '@', '@' ); 198 tok.wordChars( '[', '[' ); 199 tok.wordChars( ']', ']' ); 200 tok.wordChars( '.', '.' ); 201 tok.wordChars( '"', '"' ); 202 tok.wordChars( '-', '-' ); 203 return tok; 204 } 205 206 private static void parseAnnotations() 207 { 208 try 209 { 210 String annotationsSource = ANNOTATIONS_CLASSNAME.replace( '.', '/' ) + ".java"; 211 InputStream in = DeclarationImpl.class.getClassLoader().getResourceAsStream( annotationsSource ); 212 assert in != null : "annotations source not found: " + annotationsSource; 213 BufferedReader reader = new BufferedReader ( new InputStreamReader ( in ) ); 214 HashMap enums = new HashMap (); StreamTokenizer tok = getJavaTokenizer( reader ); 216 217 218 String interfaceQualifier = null; 219 String packageName = null; 220 221 while ( tok.nextToken() != StreamTokenizer.TT_EOF ) 222 { 223 switch ( tok.ttype ) 224 { 225 case StreamTokenizer.TT_WORD: 226 String str = tok.sval; 227 228 if ( packageName == null && str.equals( "package" ) ) 229 { 230 packageName = assertWord( tok ); 231 } 232 else if ( str.equals( "public" ) ) 233 { 234 str = assertWord( tok ); 235 236 if ( str.equals( "interface" ) ) 237 { 238 interfaceQualifier = assertWord( tok ) + '.'; 239 assertChar( tok, '{' ); 240 } 241 else if ( str.equals( "@interface" ) ) 242 { 243 AnnotationTypeDeclarationImpl ann = 244 readAnnotation( tok, interfaceQualifier, packageName, enums ); 245 ANNOTATIONS.put( ann.getIntermediateName(), ann ); 246 247 if ( ann.getSimpleName().equals( FORWARD_TAG_NAME ) ) 255 { 256 AnnotationTypeDeclarationImpl validationErrorForwardAnn = 257 new AnnotationTypeDeclarationImpl( ann, VALIDATION_ERROR_FORWARD_TAG_NAME, 258 interfaceQualifier ); 259 ANNOTATIONS.put( ANNOTATION_INTERFACE_PREFIX + VALIDATION_ERROR_FORWARD_TAG_NAME, 260 validationErrorForwardAnn ); 261 } 262 } 263 else if ( str.equals( "enum" ) ) 264 { 265 readEnum( tok, enums ); 266 } 267 } 268 else if ( str.charAt( 0 ) == '@' ) 269 { 270 ignoreAnnotation( tok ); 271 } 272 break; 273 274 case StreamTokenizer.TT_NUMBER: 275 break; 276 277 default: 278 char c = ( char ) tok.ttype; 279 280 if ( c == '}' ) 281 { 282 assert interfaceQualifier != null; 283 interfaceQualifier = null; 284 } 285 } 286 } 287 288 reader.close(); 289 } 290 catch ( IOException e ) 291 { 292 assert false : e; 293 } 294 } 295 296 private static String assertWord( StreamTokenizer tok ) 297 throws IOException  298 { 299 tok.nextToken(); 300 assert tok.ttype == StreamTokenizer.TT_WORD : tok.ttype; 301 return tok.sval; 302 } 303 304 private static void assertChar( StreamTokenizer tok, char c ) 305 throws IOException  306 { 307 tok.nextToken(); 308 assert tok.ttype == c : tok.ttype; 309 } 310 311 private static AnnotationTypeDeclarationImpl readAnnotation( StreamTokenizer tok, String interfaceQualifier, 312 String packageName, HashMap enums ) 313 throws IOException  314 { 315 String annotationName = assertWord( tok ); 316 ArrayList memberDecls = new ArrayList (); 317 assertChar( tok, '{' ); 318 319 while ( tok.nextToken() == StreamTokenizer.TT_WORD ) 320 { 321 String memberType = tok.sval; 322 HashSet enumVals = ( HashSet ) enums.get( memberType ); 323 324 tok.nextToken(); 325 if ( tok.ttype == '<' ) { 327 while ( tok.nextToken() != '>' ) 328 { 329 assert tok.ttype != StreamTokenizer.TT_EOF; 330 assert tok.ttype != ';'; 331 } 332 tok.nextToken(); 333 } 334 assert tok.ttype == StreamTokenizer.TT_WORD; 335 String memberName = tok.sval; 336 assertChar( tok, '(' ); 337 assertChar( tok, ')' ); 338 339 Object defaultVal = null; 340 341 if ( tok.nextToken() == StreamTokenizer.TT_WORD ) 342 { 343 assert tok.sval.equals( "default" ); 344 345 tok.nextToken(); 346 if ( tok.ttype == '{' ) 347 { 348 assertChar( tok, '}' ); 349 defaultVal = new ArrayList (); 350 } 351 else 352 { 353 assert tok.ttype == StreamTokenizer.TT_WORD || tok.ttype == StreamTokenizer.TT_NUMBER : tok.ttype; 354 355 if ( tok.ttype == StreamTokenizer.TT_NUMBER ) 356 { 357 defaultVal = getNumericDefaultVal( memberType, tok.nval ); 358 } 359 else 360 { 361 String defaultString = tok.sval; 362 363 if ( defaultString.charAt( 0 ) == '@' ) 364 { 365 ignoreAnnotation( tok ); 367 } 368 else 369 { 370 if ( memberType.equals( "String" ) ) 371 { 372 assert defaultString.charAt( 0 ) == '"' : defaultString; 373 int len = defaultString.length(); 374 assert len > 1 && defaultString.charAt( len - 1 ) == '"' : defaultString; 375 defaultVal = defaultString.substring( 0, len - 1 ); 376 } 377 else if ( memberType.equals( "boolean" ) ) 378 { 379 defaultVal = Boolean.valueOf( defaultString ); 380 } 381 else if ( memberType.equals( "Class") ) 382 { 383 assert defaultString.endsWith( ".class" ); 384 defaultVal = defaultString.substring( 0, defaultString.indexOf( ".class" ) ); 385 } 386 else 387 { 388 defaultVal = readDefaultEnumVal( defaultString, memberType, enumVals ); 389 } 390 } 391 } 392 } 393 394 tok.nextToken(); 395 } 396 397 assert tok.ttype == ';'; 398 399 if ( enumVals != null ) memberType = "String"; 400 memberDecls.add( new AnnotationTypeElementDeclarationImpl( memberName, memberType, defaultVal, enumVals ) ); 401 } 402 403 assert tok.ttype == '}'; 404 405 AnnotationTypeElementDeclaration[] memberArray = ( AnnotationTypeElementDeclaration[] ) 406 memberDecls.toArray( new AnnotationTypeElementDeclaration[ memberDecls.size() ] ); 407 return new AnnotationTypeDeclarationImpl( annotationName, interfaceQualifier, packageName, memberArray ); 408 } 409 410 private static String readDefaultEnumVal( String defaultString, String memberType, HashSet enumVals ) 411 { 412 int dot = defaultString.indexOf( '.' ); 413 assert dot != -1 : "expected an enum value: " + defaultString; 414 String type = defaultString.substring( 0, dot ); 415 assert type.equals( memberType ) : "expected enum " + memberType + ", got " + type; 416 assert enumVals != null : "no enum " + memberType 417 + " defined; currently, enum must be defined before its use"; 418 String defaultVal = defaultString.substring( dot + 1 ); 419 assert enumVals.contains( defaultVal ) : 420 "invalid enum field " + defaultVal + " on enum " + type; 421 return defaultVal; 422 } 423 424 private static Object getNumericDefaultVal( String expectedType, double defaultNumber ) 425 { 426 if ( expectedType.equals( "int" ) ) 427 { 428 return new Integer ( ( int ) defaultNumber ); 429 } 430 else if ( expectedType.equals( "long" ) ) 431 { 432 return new Long ( ( long ) defaultNumber ); 433 } 434 else if ( expectedType.equals( "float" ) ) 435 { 436 return new Float ( ( float ) defaultNumber ); 437 } 438 else if ( expectedType.equals( "double" ) ) 439 { 440 return new Double ( defaultNumber ); 441 } 442 443 assert false : "type " + expectedType + " cannot accept value " + defaultNumber; 444 return null; 445 } 446 447 private static void ignoreAnnotation( StreamTokenizer tok ) 448 throws IOException  449 { 450 while ( tok.nextToken() != ')' ) 451 { 452 assert tok.ttype != StreamTokenizer.TT_EOF; 453 assert tok.ttype != ';'; 454 } 455 } 456 457 private static void readEnum( StreamTokenizer tok, HashMap enums ) 458 throws IOException  459 { 460 String enumName = assertWord( tok ); 461 462 assertChar( tok, '{' ); 463 HashSet fieldNames = new HashSet (); 464 465 while ( true ) 466 { 467 fieldNames.add( assertWord( tok ) ); 468 tok.nextToken(); 469 if ( tok.ttype == '}' ) break; 470 assert tok.ttype == ',' : tok.ttype; } 472 473 enums.put( enumName, fieldNames ); 474 } 475 476 481 private static ArrayList getAnnotations( XProgramElement element ) 482 { 483 XDoc doc = element.getDoc(); 484 ArrayList annotations = new ArrayList (); 485 List tags = doc != null ? doc.getTags() : null; 486 ArrayList parentAnnotations = new ArrayList (); 488 if ( tags == null ) return annotations; 489 490 for ( Iterator i = tags.iterator(); i.hasNext(); ) 491 { 492 XTag tag = ( XTag ) i.next(); 493 AnnotationTypeDeclaration decl = ( AnnotationTypeDeclaration ) ANNOTATIONS.get( tag.getName() ); 494 495 if ( decl != null ) 496 { 497 AnnotationType type = new AnnotationTypeImpl( decl ); 498 Collection attrNames = tag.getAttributeNames(); 499 HashMap elementValues = new HashMap (); 500 501 for ( Iterator j = attrNames.iterator(); j.hasNext(); ) 502 { 503 String attrName = ( String ) j.next(); 504 AnnotationTypeElementDeclaration memberDecl = decl.getMember( attrName ); 505 SourcePositionImpl pos = SourcePositionImpl.get( tag, attrName, element ); 506 Object val = parseValue( memberDecl, tag.getAttributeValue( attrName ), pos ); 507 AnnotationValue value = new AnnotationValueImpl( val, pos, memberDecl ); 508 elementValues.put( memberDecl, value ); 509 } 510 511 AnnotationInstanceImpl ann = new AnnotationInstanceImpl( tag, element, type, elementValues ); 512 513 String memberName = ( String ) MEMBER_ARRAY_ANNOTATIONS.get( tag.getName() ); 514 515 if ( memberName != null ) 516 { 517 if ( ! addAnnotationToParent( annotations, ann, memberName, true, parentAnnotations ) ) 518 { 519 annotations.add( ann ); 520 } 521 } 522 else if ( ( memberName = ( String ) MEMBER_ANNOTATIONS.get( tag.getName() ) ) != null ) 523 { 524 if ( ! addAnnotationToParent( annotations, ann, memberName, false, parentAnnotations ) ) 525 { 526 annotations.add( ann ); 527 } 528 } 529 else 530 { 531 annotations.add( ann ); 532 } 533 534 for ( int j = 0, len = parentAnnotations.size(); j < len; ++j ) 535 { 536 AnnotationInstanceImpl parentAnn = ( AnnotationInstanceImpl ) parentAnnotations.get( j ); 537 538 if ( parentAnn.getAnnotationType().equals( ann.getAnnotationType() ) ) 539 { 540 for ( int k = j; k < len; ++k ) 543 { 544 parentAnnotations.remove( j ); 545 } 546 break; 547 } 548 } 549 550 parentAnnotations.add( ann ); 551 } 552 } 553 554 return annotations; 555 } 556 557 private static boolean addAnnotationToParent( ArrayList annotations, AnnotationInstanceImpl ann, String memberArrayName, 558 boolean memberIsArray, ArrayList parentAnnotations ) 559 { 560 if ( annotations.size() == 0 ) 561 { 562 String annName = ann.getDelegateXTag().getName(); 563 if ( MEMBER_OR_TOPLEVEL_ANNOTATIONS.contains( annName ) ) return false; 564 565 XDocletCompilerUtils.addError( ann.getPosition(), "error.no-parent-annotation", 566 new String []{ ann.getAnnotationType().getAnnotationTypeDeclaration().getQualifiedName() } ); 567 } 568 else 569 { 570 AnnotationInstanceImpl foundTheRightParent = null; 571 572 for ( int i = parentAnnotations.size() - 1; i >= 0; --i ) 577 { 578 AnnotationInstanceImpl parentAnnotation = ( AnnotationInstanceImpl ) parentAnnotations.get( i ); 579 AnnotationTypeElementDeclaration elementDecl = 580 parentAnnotation.getAnnotationType().getAnnotationTypeDeclaration().getMember( memberArrayName ); 581 582 if ( elementDecl != null ) 583 { 584 foundTheRightParent = parentAnnotation; 585 586 for ( int j = i + 1, len = parentAnnotations.size(); j < len; ++j ) 590 { 591 parentAnnotations.remove( i + 1 ); 592 } 593 594 break; 595 } 596 } 597 598 if ( foundTheRightParent != null ) 599 { 600 foundTheRightParent.addElementValue( memberArrayName, memberIsArray, ann, ann.getPosition() ); 601 } 602 else 603 { 604 String annName = ann.getDelegateXTag().getName(); 605 if ( MEMBER_OR_TOPLEVEL_ANNOTATIONS.contains( annName ) ) return false; 606 607 XDocletCompilerUtils.addError( ann.getPosition(), "error.no-parent-annotation", 608 new String []{ ann.getAnnotationType().getAnnotationTypeDeclaration().getQualifiedName() } ); 609 } 610 } 611 612 return true; 613 } 614 615 private static Object parseValue( AnnotationTypeElementDeclaration memberDecl, String strValue, SourcePositionImpl pos ) 616 { 617 TypeInstance type = memberDecl.getReturnType(); 618 619 if ( type instanceof ClassType ) 620 { 621 ClassType classType = ( ClassType ) type; 622 String typeName = classType.getClassTypeDeclaration().getQualifiedName(); 623 624 if ( typeName.equals( "java.lang.String" ) ) 625 { 626 return strValue; 627 } 628 else if ( typeName.equals( "java.lang.Class" ) ) 629 { 630 TypeInstance retVal = XDocletCompilerUtils.resolveType( strValue, false, pos.getOuterClass() ); 631 632 if ( retVal == null ) 633 { 634 XDocletCompilerUtils.addError( pos, "error.unknown-class", 635 new String []{ strValue, memberDecl.getSimpleName() } ); 636 } 637 638 return XDocletCompilerUtils.resolveType( strValue, true, pos.getOuterClass() ); 639 } 640 else 641 { 642 assert false : "unexpected type in annotation declaration: " + typeName; 643 } 644 } 645 else if ( type instanceof ArrayType ) 646 { 647 ArrayType arrayType = ( ArrayType ) type; 648 TypeInstance componentType = arrayType.getComponentType(); 649 650 assert componentType instanceof DeclaredType : componentType.getClass().getName(); 652 assert ( ( DeclaredType ) componentType ).getDeclaration().getQualifiedName().equals( String .class.getName() ) 653 : ( ( DeclaredType ) componentType ).getDeclaration().getQualifiedName(); 654 StringTokenizer tok = new StringTokenizer ( strValue, "," ); 655 ArrayList arrayValues = new ArrayList (); 656 while ( tok.hasMoreTokens() ) 657 { 658 arrayValues.add( new AnnotationValueImpl( tok.nextToken().trim(), pos, memberDecl ) ); 659 } 660 return arrayValues; 661 } 662 663 assert type instanceof PrimitiveType : type.getClass().getName(); 664 switch ( ( ( PrimitiveType ) type ).getKind().asInt() ) 665 { 666 case PrimitiveType.Kind.INT_BOOLEAN: 667 return Boolean.valueOf( strValue ); 668 669 case PrimitiveType.Kind.INT_BYTE: 670 return new Byte ( strValue ); 671 672 case PrimitiveType.Kind.INT_SHORT: 673 return new Short ( strValue ); 674 675 case PrimitiveType.Kind.INT_INT: 676 return new Integer ( strValue ); 677 678 case PrimitiveType.Kind.INT_LONG: 679 return new Long ( strValue ); 680 681 case PrimitiveType.Kind.INT_FLOAT: 682 return new Float ( strValue ); 683 684 case PrimitiveType.Kind.INT_DOUBLE: 685 return new Double ( strValue ); 686 } 687 688 assert false : "unrecognized type: " + type.toString(); 689 return null; 690 } 691 } 692 | Popular Tags |