1 15 16 package javassist.bytecode; 17 18 import java.util.Map ; 19 import java.io.IOException ; 20 import java.io.DataInputStream ; 21 import java.io.ByteArrayOutputStream ; 22 import javassist.bytecode.annotation.*; 23 24 52 public class AnnotationsAttribute extends AttributeInfo { 53 56 public static final String visibleTag = "RuntimeVisibleAnnotations"; 57 58 61 public static final String invisibleTag = "RuntimeInvisibleAnnotations"; 62 63 73 public AnnotationsAttribute(ConstPool cp, String attrname, byte[] info) { 74 super(cp, attrname, info); 75 } 76 77 88 public AnnotationsAttribute(ConstPool cp, String attrname) { 89 this(cp, attrname, new byte[] { 0, 0 }); 90 } 91 92 95 AnnotationsAttribute(ConstPool cp, int n, DataInputStream in) 96 throws IOException 97 { 98 super(cp, n, in); 99 } 100 101 104 public int numAnnotations() { 105 return ByteArray.readU16bit(info, 0); 106 } 107 108 111 public AttributeInfo copy(ConstPool newCp, Map classnames) { 112 Copier copier = new Copier(info, constPool, newCp, classnames); 113 try { 114 copier.annotationArray(); 115 return new AnnotationsAttribute(newCp, getName(), copier.close()); 116 } 117 catch (Exception e) { 118 throw new RuntimeException (e.toString()); 119 } 120 } 121 122 130 public Annotation getAnnotation(String type) { 131 Annotation[] annotations = getAnnotations(); 132 for (int i = 0; i < annotations.length; i++) { 133 if (annotations[i].getTypeName().equals(type)) 134 return annotations[i]; 135 } 136 137 return null; 138 } 139 140 146 public void addAnnotation(Annotation annotation) { 147 String type = annotation.getTypeName(); 148 Annotation[] annotations = getAnnotations(); 149 for (int i = 0; i < annotations.length; i++) { 150 if (annotations[i].getTypeName().equals(type)) { 151 annotations[i] = annotation; 152 setAnnotations(annotations); 153 return; 154 } 155 } 156 157 Annotation[] newlist = new Annotation[annotations.length + 1]; 158 System.arraycopy(annotations, 0, newlist, 0, annotations.length); 159 newlist[annotations.length] = annotation; 160 setAnnotations(newlist); 161 } 162 163 172 public Annotation[] getAnnotations() { 173 try { 174 return new Parser(info, constPool).parseAnnotations(); 175 } 176 catch (Exception e) { 177 throw new RuntimeException (e.toString()); 178 } 179 } 180 181 188 public void setAnnotations(Annotation[] annotations) { 189 ByteArrayOutputStream output = new ByteArrayOutputStream (); 190 AnnotationsWriter writer = new AnnotationsWriter(output, constPool); 191 try { 192 int n = annotations.length; 193 writer.numAnnotations(n); 194 for (int i = 0; i < n; ++i) 195 annotations[i].write(writer); 196 197 writer.close(); 198 } 199 catch (IOException e) { 200 throw new RuntimeException (e); } 202 203 set(output.toByteArray()); 204 } 205 206 213 public void setAnnotation(Annotation annotation) { 214 setAnnotations(new Annotation[] { annotation }); 215 } 216 217 220 public String toString() { 221 Annotation[] a = getAnnotations(); 222 StringBuffer sbuf = new StringBuffer (); 223 int i = 0; 224 while (i < a.length) { 225 sbuf.append(a[i++].toString()); 226 if (i != a.length) 227 sbuf.append(", "); 228 } 229 230 return sbuf.toString(); 231 } 232 233 static class Walker { 234 byte[] info; 235 236 Walker(byte[] attrInfo) { 237 info = attrInfo; 238 } 239 240 final void parameters() throws Exception { 241 int numParam = info[0] & 0xff; 242 parameters(numParam, 1); 243 } 244 245 void parameters(int numParam, int pos) throws Exception { 246 for (int i = 0; i < numParam; ++i) 247 pos = annotationArray(pos); 248 } 249 250 final void annotationArray() throws Exception { 251 annotationArray(0); 252 } 253 254 final int annotationArray(int pos) throws Exception { 255 int num = ByteArray.readU16bit(info, pos); 256 return annotationArray(pos + 2, num); 257 } 258 259 int annotationArray(int pos, int num) throws Exception { 260 for (int i = 0; i < num; ++i) 261 pos = annotation(pos); 262 263 return pos; 264 } 265 266 final int annotation(int pos) throws Exception { 267 int type = ByteArray.readU16bit(info, pos); 268 int numPairs = ByteArray.readU16bit(info, pos + 2); 269 return annotation(pos + 4, type, numPairs); 270 } 271 272 int annotation(int pos, int type, int numPairs) throws Exception { 273 for (int j = 0; j < numPairs; ++j) 274 pos = memberValuePair(pos); 275 276 return pos; 277 } 278 279 final int memberValuePair(int pos) throws Exception { 280 int nameIndex = ByteArray.readU16bit(info, pos); 281 return memberValuePair(pos + 2, nameIndex); 282 } 283 284 int memberValuePair(int pos, int nameIndex) throws Exception { 285 return memberValue(pos); 286 } 287 288 final int memberValue(int pos) throws Exception { 289 int tag = info[pos] & 0xff; 290 if (tag == 'e') { 291 int typeNameIndex = ByteArray.readU16bit(info, pos + 1); 292 int constNameIndex = ByteArray.readU16bit(info, pos + 3); 293 enumMemberValue(typeNameIndex, constNameIndex); 294 return pos + 5; 295 } 296 else if (tag == 'c') { 297 int index = ByteArray.readU16bit(info, pos + 1); 298 classMemberValue(index); 299 return pos + 3; 300 } 301 else if (tag == '@') 302 return annotationMemberValue(pos + 1); 303 else if (tag == '[') { 304 int num = ByteArray.readU16bit(info, pos + 1); 305 return arrayMemberValue(pos + 3, num); 306 } 307 else { int index = ByteArray.readU16bit(info, pos + 1); 309 constValueMember(tag, index); 310 return pos + 3; 311 } 312 } 313 314 void constValueMember(int tag, int index) throws Exception {} 315 316 void enumMemberValue(int typeNameIndex, int constNameIndex) 317 throws Exception { 318 } 319 320 void classMemberValue(int index) throws Exception {} 321 322 int annotationMemberValue(int pos) throws Exception { 323 return annotation(pos); 324 } 325 326 int arrayMemberValue(int pos, int num) throws Exception { 327 for (int i = 0; i < num; ++i) { 328 pos = memberValue(pos); 329 } 330 331 return pos; 332 } 333 } 334 335 static class Copier extends Walker { 336 ByteArrayOutputStream output; 337 AnnotationsWriter writer; 338 ConstPool srcPool, destPool; 339 Map classnames; 340 341 352 Copier(byte[] info, ConstPool src, ConstPool dest, Map map) { 353 super(info); 354 output = new ByteArrayOutputStream (); 355 writer = new AnnotationsWriter(output, dest); 356 srcPool = src; 357 destPool = dest; 358 classnames = map; 359 } 360 361 byte[] close() throws IOException { 362 writer.close(); 363 return output.toByteArray(); 364 } 365 366 void parameters(int numParam, int pos) throws Exception { 367 writer.numParameters(numParam); 368 super.parameters(numParam, pos); 369 } 370 371 int annotationArray(int pos, int num) throws Exception { 372 writer.numAnnotations(num); 373 return super.annotationArray(pos, num); 374 } 375 376 int annotation(int pos, int type, int numPairs) throws Exception { 377 writer.annotation(copy(type), numPairs); 378 return super.annotation(pos, type, numPairs); 379 } 380 381 int memberValuePair(int pos, int nameIndex) throws Exception { 382 writer.memberValuePair(copy(nameIndex)); 383 return super.memberValuePair(pos, nameIndex); 384 } 385 386 void constValueMember(int tag, int index) throws Exception { 387 writer.constValueIndex(tag, copy(index)); 388 super.constValueMember(tag, index); 389 } 390 391 void enumMemberValue(int typeNameIndex, int constNameIndex) 392 throws Exception 393 { 394 writer.enumConstValue(copy(typeNameIndex), copy(constNameIndex)); 395 super.enumMemberValue(typeNameIndex, constNameIndex); 396 } 397 398 void classMemberValue(int index) throws Exception { 399 writer.classInfoIndex(copy(index)); 400 super.classMemberValue(index); 401 } 402 403 int annotationMemberValue(int pos) throws Exception { 404 writer.annotationValue(); 405 return super.annotationMemberValue(pos); 406 } 407 408 int arrayMemberValue(int pos, int num) throws Exception { 409 writer.arrayValue(num); 410 return super.arrayMemberValue(pos, num); 411 } 412 413 422 int copy(int srcIndex) { 423 return srcPool.copy(srcIndex, destPool, classnames); 424 } 425 } 426 427 static class Parser extends Walker { 428 ConstPool pool; 429 Annotation[][] allParams; Annotation[] allAnno; Annotation currentAnno; MemberValue memberValue; 433 434 441 Parser(byte[] info, ConstPool cp) { 442 super(info); 443 pool = cp; 444 } 445 446 Annotation[][] parseParameters() throws Exception { 447 parameters(); 448 return allParams; 449 } 450 451 Annotation[] parseAnnotations() throws Exception { 452 annotationArray(); 453 return allAnno; 454 } 455 456 void parameters(int numParam, int pos) throws Exception { 457 Annotation[][] params = new Annotation[numParam][]; 458 for (int i = 0; i < numParam; ++i) { 459 pos = annotationArray(pos); 460 params[i] = allAnno; 461 } 462 463 allParams = params; 464 } 465 466 int annotationArray(int pos, int num) throws Exception { 467 Annotation[] array = new Annotation[num]; 468 for (int i = 0; i < num; ++i) { 469 pos = annotation(pos); 470 array[i] = currentAnno; 471 } 472 473 allAnno = array; 474 return pos; 475 } 476 477 int annotation(int pos, int type, int numPairs) throws Exception { 478 currentAnno = new Annotation(type, pool); 479 return super.annotation(pos, type, numPairs); 480 } 481 482 int memberValuePair(int pos, int nameIndex) throws Exception { 483 pos = super.memberValuePair(pos, nameIndex); 484 currentAnno.addMemberValue(nameIndex, memberValue); 485 return pos; 486 } 487 488 void constValueMember(int tag, int index) throws Exception { 489 MemberValue m; 490 ConstPool cp = pool; 491 switch (tag) { 492 case 'B' : 493 m = new ByteMemberValue(index, cp); 494 break; 495 case 'C' : 496 m = new CharMemberValue(index, cp); 497 break; 498 case 'D' : 499 m = new DoubleMemberValue(index, cp); 500 break; 501 case 'F' : 502 m = new FloatMemberValue(index, cp); 503 break; 504 case 'I' : 505 m = new IntegerMemberValue(index, cp); 506 break; 507 case 'J' : 508 m = new LongMemberValue(index, cp); 509 break; 510 case 'S' : 511 m = new ShortMemberValue(index, cp); 512 break; 513 case 'Z' : 514 m = new BooleanMemberValue(index, cp); 515 break; 516 case 's' : 517 m = new StringMemberValue(index, cp); 518 break; 519 default : 520 throw new RuntimeException ("unknown tag:" + tag); 521 } 522 523 memberValue = m; 524 super.constValueMember(tag, index); 525 } 526 527 void enumMemberValue(int typeNameIndex, int constNameIndex) 528 throws Exception 529 { 530 memberValue = new EnumMemberValue(typeNameIndex, 531 constNameIndex, pool); 532 super.enumMemberValue(typeNameIndex, constNameIndex); 533 } 534 535 void classMemberValue(int index) throws Exception { 536 memberValue = new ClassMemberValue(index, pool); 537 super.classMemberValue(index); 538 } 539 540 int annotationMemberValue(int pos) throws Exception { 541 Annotation anno = currentAnno; 542 pos = super.annotationMemberValue(pos); 543 memberValue = new AnnotationMemberValue(currentAnno, pool); 544 currentAnno = anno; 545 return pos; 546 } 547 548 int arrayMemberValue(int pos, int num) throws Exception { 549 ArrayMemberValue amv = new ArrayMemberValue(pool); 550 MemberValue[] elements = new MemberValue[num]; 551 for (int i = 0; i < num; ++i) { 552 pos = memberValue(pos); 553 elements[i] = memberValue; 554 } 555 556 amv.setValue(elements); 557 memberValue = amv; 558 return pos; 559 } 560 } 561 } 562 | Popular Tags |