1 30 31 package oracle.toplink.libraries.asm.attrs; 32 33 import java.util.ArrayList ; 34 import java.util.List ; 35 36 import oracle.toplink.libraries.asm.ByteVector; 37 import oracle.toplink.libraries.asm.ClassReader; 38 import oracle.toplink.libraries.asm.ClassWriter; 39 import oracle.toplink.libraries.asm.Type; 40 41 181 182 public class Annotation { 183 184 187 public String type; 188 189 198 public List elementValues = new ArrayList (); 199 200 public Annotation() { 201 } 202 203 public Annotation( String type) { 204 this.type = type; 205 } 206 207 public void add (String name, Object value) { 208 elementValues.add(new Object []{name, value}); 209 } 210 211 222 223 public int read (ClassReader cr, int off, char[] buf) { 224 type = cr.readUTF8(off, buf); 225 int numElementValuePairs = cr.readUnsignedShort(off + 2); 226 off += 4; 227 int[] aoff = new int[] { off}; 228 for (int i = 0; i < numElementValuePairs; i++) { 229 String elementName = cr.readUTF8(aoff[ 0], buf); 230 aoff[ 0] += 2; 231 elementValues.add(new Object []{elementName, readValue(cr, aoff, buf)}); 232 } 233 return aoff[ 0]; 234 } 235 236 244 245 public void write (ByteVector bv, ClassWriter cw) { 246 bv.putShort(cw.newUTF8(type)); 247 bv.putShort(elementValues.size()); 248 for (int i = 0; i < elementValues.size(); i++) { 249 Object [] value = (Object [])elementValues.get(i); 250 bv.putShort(cw.newUTF8((String )value[0])); 251 writeValue(bv, value[1], cw); 252 } 253 } 254 255 268 269 public static int readAnnotations ( 270 List annotations, ClassReader cr, int off, char[] buf) { 271 int size = cr.readUnsignedShort(off); 272 off += 2; 273 for (int i = 0; i < size; i++) { 274 Annotation ann = new Annotation(); 275 off = ann.read(cr, off, buf); 276 annotations.add(ann); 277 } 278 return off; 279 } 280 281 293 294 public static void readParameterAnnotations ( 295 List parameters, ClassReader cr, int off, char[] buf) { 296 int numParameters = cr.b[off++] & 0xff; 297 for (int i = 0; i < numParameters; i++) { 298 List annotations = new ArrayList (); 299 off = Annotation.readAnnotations(annotations, cr, off, buf); 300 parameters.add(annotations); 301 } 302 } 303 304 316 317 public static ByteVector writeAnnotations (ByteVector bv, 318 List annotations, ClassWriter cw) { 319 bv.putShort(annotations.size()); 320 for (int i = 0; i < annotations.size(); i++) { 321 ((Annotation)annotations.get(i)).write(bv, cw); 322 } 323 return bv; 324 } 325 326 338 339 public static ByteVector writeParametersAnnotations (ByteVector bv, 340 List parameters, 341 ClassWriter cw) { 342 bv.putByte(parameters.size()); 343 for (int i = 0; i < parameters.size(); i++) { 344 writeAnnotations(bv, (List )parameters.get(i), cw); 345 } 346 return bv; 347 } 348 349 357 358 public static String stringAnnotations (List annotations) { 359 StringBuffer sb = new StringBuffer (); 360 if (annotations.size() > 0) { 361 for (int i = 0; i < annotations.size(); i++) { 362 sb.append('\n').append(annotations.get(i)); 363 } 364 } else { 365 sb.append( "<none>"); 366 } 367 return sb.toString(); 368 } 369 370 378 379 public static String stringParameterAnnotations (List parameters) { 380 StringBuffer sb = new StringBuffer (); 381 String sep = ""; 382 for (int i = 0; i < parameters.size(); i++) { 383 sb.append(sep).append(stringAnnotations((List )parameters.get(i))); 384 sep = ", "; 385 } 386 return sb.toString(); 387 } 388 389 400 401 protected static Object readValue (ClassReader cr, int[] off, char[] buf) { 402 Object value = null; 403 int tag = cr.readByte(off[ 0]++); 404 switch (tag) { 405 case 'I': case 'J': case 'D': case 'F': value = cr.readConst(cr.readUnsignedShort(off[0]), buf); 410 off[0] += 2; 411 break; 412 413 case 'B': value = new Byte (( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))); 415 off[0] += 2; 416 break; 417 418 case 'C': value = new Character (( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))); 420 off[0] += 2; 421 break; 422 423 case 'S': value = new Short (( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))); 425 off[0] += 2; 426 break; 427 428 case 'Z': value = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))==0 ? Boolean.FALSE : Boolean.TRUE; 430 off[0] += 2; 431 break; 432 433 case 's': value = cr.readUTF8(off[0], buf); 435 off[0] += 2; 436 break; 437 438 case 'e': value = new EnumConstValue(cr.readUTF8(off[0], buf), cr.readUTF8(off[0] + 2, buf)); 441 off[0] += 4; 442 break; 443 444 case 'c': value = Type.getType(cr.readUTF8(off[0], buf)); 446 off[0] += 2; 447 break; 448 449 case '@': value = new Annotation(); 451 off[0] = ((Annotation) value).read(cr, off[0], buf); 452 break; 453 454 case '[': int size = cr.readUnsignedShort(off[0]); 456 off[0] += 2; 457 int childTag = cr.readByte( off[ 0]); 458 switch( childTag) { 459 case 'I': { 461 int[] v = new int[ size]; 462 for( int i = 0; i < size; i++) { 463 off[ 0]++; v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))); 465 off[ 0] += 2; 466 } 467 value = v; 468 } 469 break; 470 471 case 'J': { 473 long[] v = new long[ size]; 474 for( int i = 0; i < size; i++) { 475 off[ 0]++; v[ i] = cr.readLong( cr.getItem( cr.readUnsignedShort(off[0]))); 477 off[ 0] += 2; 478 } 479 value = v; 480 } 481 break; 482 483 case 'D': { 485 double[] v = new double[ size]; 486 for( int i = 0; i < size; i++) { 487 off[ 0]++; v[ i] = Double.longBitsToDouble( cr.readLong( cr.getItem( cr.readUnsignedShort(off[0])))); 489 off[ 0] += 2; 490 } 491 value = v; 492 } 493 break; 494 495 case 'F': { 497 float[] v = new float[ size]; 498 for( int i = 0; i < size; i++) { 499 off[ 0]++; v[ i] = Float.intBitsToFloat( cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))); 501 off[ 0] += 2; 502 } 503 value = v; 504 } 505 break; 506 507 case 'B': { 509 byte[] v = new byte[ size]; 510 for( int i = 0; i < size; i++) { 511 off[ 0]++; v[ i] = ( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))); 513 off[ 0] += 2; 514 } 515 value = v; 516 } 517 break; 518 519 case 'C': { 521 char[] v = new char[ size]; 522 for( int i = 0; i < size; i++) { 523 off[ 0]++; v[ i] = ( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))); 525 off[ 0] += 2; 526 } 527 value = v; 528 } 529 break; 530 531 case 'S': { 533 short[] v = new short[ size]; 534 for( int i = 0; i < size; i++) { 535 off[ 0]++; v[ i] = ( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))); 537 off[ 0] += 2; 538 } 539 value = v; 540 } 541 break; 542 543 case 'Z': { 545 boolean[] v = new boolean[ size]; 546 for( int i = 0; i < size; i++) { 547 off[ 0]++; v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))!=0; 549 off[ 0] += 2; 550 } 551 value = v; 552 } 553 break; 554 555 default: 556 Object [] v = new Object [ size]; 557 value = v; 558 for (int i = 0; i < size; i++) { 559 v[i] = readValue(cr, off, buf); 560 } 561 break; 562 } 563 564 } 565 return value; 566 } 567 568 578 579 protected static ByteVector writeValue (ByteVector bv, Object value, ClassWriter cw) { 580 if (value instanceof String ) { 581 bv.putByte('s'); 582 bv.putShort(cw.newUTF8((String )value)); 583 584 } else if (value instanceof EnumConstValue) { 585 bv.putByte('e'); 586 bv.putShort(cw.newUTF8(((EnumConstValue)value).typeName)); 587 bv.putShort(cw.newUTF8(((EnumConstValue)value).constName)); 588 589 } else if (value instanceof Type) { 590 bv.putByte('c'); 591 bv.putShort(cw.newUTF8(((Type)value).getDescriptor())); 592 593 } else if (value instanceof Annotation) { 594 bv.putByte('@'); 595 ((Annotation)value).write(bv, cw); 596 597 } else if (value instanceof Object []) { 598 bv.putByte('['); 599 Object [] v = (Object [])value; 600 bv.putShort(v.length); 601 for (int i = 0; i < v.length; i++) { 602 writeValue(bv, v[i], cw); 603 } 604 605 } else if( value instanceof byte[]) { 606 bv.putByte('['); 607 byte[] v = (byte[])value; 608 bv.putShort(v.length); 609 for (int i = 0; i < v.length; i++) { 610 bv.putByte('B'); 611 bv.putShort(cw.newConstInt(v[i])); 612 } 613 614 } else if( value instanceof short[]) { 615 bv.putByte('['); 616 short[] v = (short[])value; 617 bv.putShort(v.length); 618 for (int i = 0; i < v.length; i++) { 619 bv.putByte('S'); 620 bv.putShort(cw.newConstInt(v[i])); 621 } 622 623 } else if( value instanceof int[]) { 624 bv.putByte('['); 625 int[] v = (int[])value; 626 bv.putShort(v.length); 627 for (int i = 0; i < v.length; i++) { 628 bv.putByte('I'); 629 bv.putShort(cw.newConstInt(v[i])); 630 } 631 632 } else if( value instanceof char[]) { 633 bv.putByte('['); 634 char[] v = (char[])value; 635 bv.putShort(v.length); 636 for (int i = 0; i < v.length; i++) { 637 bv.putByte('C'); 638 bv.putShort(cw.newConstInt(v[i])); 639 } 640 641 } else if( value instanceof boolean[]) { 642 bv.putByte('['); 643 boolean[] v = (boolean[])value; 644 bv.putShort(v.length); 645 for (int i = 0; i < v.length; i++) { 646 bv.putByte('Z'); 647 bv.putShort(cw.newConstInt(v[i] ? 1 : 0)); 648 } 649 650 } else if( value instanceof long[]) { 651 bv.putByte('['); 652 long[] v = (long[])value; 653 bv.putShort(v.length); 654 for (int i = 0; i < v.length; i++) { 655 bv.putByte('J'); 656 bv.putShort(cw.newConstLong(v[i])); 657 } 658 659 } else if( value instanceof float[]) { 660 bv.putByte('['); 661 float[] v = (float[])value; 662 bv.putShort(v.length); 663 for (int i = 0; i < v.length; i++) { 664 bv.putByte('F'); 665 bv.putShort(cw.newConstFloat(v[i])); 666 } 667 668 } else if( value instanceof double[]) { 669 bv.putByte('['); 670 double[] v = (double[])value; 671 bv.putShort(v.length); 672 for (int i = 0; i < v.length; i++) { 673 bv.putByte('D'); 674 bv.putShort(cw.newConstDouble(v[i])); 675 } 676 677 } else { 678 int tag = -1; 679 if (value instanceof Integer ) { 680 tag = 'I'; 681 } else if (value instanceof Byte ) { 682 tag = 'B'; 683 } else if (value instanceof Character ) { 684 tag = 'C'; 685 } else if (value instanceof Double ) { 686 tag = 'D'; 687 } else if (value instanceof Float ) { 688 tag = 'F'; 689 } else if (value instanceof Long ) { 690 tag = 'J'; 691 } else if (value instanceof Short ) { 692 tag = 'S'; 693 } else if (value instanceof Boolean ) { 694 tag = 'Z'; 695 } 696 bv.putByte(tag); 697 bv.putShort(cw.newConst(value)); 698 699 } 700 701 return bv; 702 } 703 704 705 710 711 public String toString () { 712 StringBuffer sb = new StringBuffer ("@").append(type); 713 if (elementValues.size() > 0) { 715 sb.append(" ( "); 716 String sep = ""; 717 for (int i = 0; i < elementValues.size(); i++) { 718 Object [] value = (Object [])elementValues.get(i); 719 if ( !( elementValues.size()==1 || "value".equals( elementValues.get( 0)))) { 721 sb.append(sep).append(value[0]).append(" = "); 722 } 723 if(value[1] instanceof Object []) { 724 Object [] v = ( Object []) value[1]; 725 sb.append("{"); 726 String sep2 = ""; 727 for( int j = 0; j < v.length; j++) { 728 sb.append(sep2).append(v[ j]); 729 sep2 = ", "; 730 } 731 sb.append("}"); 732 } else { 733 sb.append(value[1]); 734 } 735 sep = ", "; 736 } 737 sb.append(" )"); 738 } 739 return sb.toString(); 740 } 741 742 743 746 public static class EnumConstValue { 747 748 public String typeName; 749 750 public String constName; 751 752 public EnumConstValue (String typeName, String constName) { 753 this.typeName = typeName; 754 this.constName = constName; 755 } 756 757 public String toString () { 758 return typeName + ":" + constName; 759 } 760 } 761 762 } 763 764 | Popular Tags |