1 23 24 package org.objectweb.fractal.julia.asm; 25 26 import org.objectweb.fractal.julia.loader.Loader; 27 import org.objectweb.fractal.julia.loader.Tree; 28 29 import org.objectweb.asm.ClassVisitor; 30 import org.objectweb.asm.ClassWriter; 31 import org.objectweb.asm.CodeVisitor; 32 import org.objectweb.asm.Constants; 33 import org.objectweb.asm.Label; 34 import org.objectweb.asm.Type; 35 36 import java.util.ArrayList ; 37 import java.util.Arrays ; 38 import java.util.HashMap ; 39 import java.util.List ; 40 import java.util.Map ; 41 42 92 93 public class ContextClassGenerator implements Constants, ClassGenerator { 94 95 99 100 private final static String SUPER = 101 "org/objectweb/fractal/julia/InitializationContext"; 102 103 106 107 private final static String [] OPTIMIZATIONS = { 108 "none", 109 "mergeControllers", 110 "mergeControllersAndInterceptors", 111 "mergeControllersAndContent", 112 "mergeControllersInterceptorsAndContent" 113 }; 114 115 118 119 private String name; 120 121 124 125 private ClassVisitor cv; 126 127 130 131 private Tree args; 132 133 136 137 private Loader loader; 138 139 private ClassLoader classLoader; 140 141 145 146 private Tree interfaceTypes; 147 148 152 153 private Tree[] controllerTrees; 154 155 159 160 private List controllerClasses; 161 162 166 167 private Class contentClass; 168 169 189 190 public byte[] generateClass ( 191 final String name, 192 final Tree args, 193 final Loader loader, 194 final ClassLoader classLoader) throws ClassGenerationException 195 { 196 this.name = name.replace('.', '/'); 197 this.cv = new ClassWriter(true); 198 this.args = args; 199 this.loader = loader; 200 this.classLoader = classLoader; 201 202 cv.visit( 204 V1_1, 205 ACC_PUBLIC, 206 this.name, 207 SUPER, 208 new String [] { "org/objectweb/fractal/julia/loader/Generated" }, 209 null); 210 211 cv.visitField( 213 ACC_PRIVATE + ACC_STATIC, 214 "componentType", 215 "Lorg/objectweb/fractal/api/type/ComponentType;", 216 null, 217 null); 218 219 cv.visitField( 221 ACC_PRIVATE + ACC_STATIC, 222 "internalComponentType", 223 "Lorg/objectweb/fractal/api/type/ComponentType;", 224 null, 225 null); 226 227 CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 229 mv.visitVarInsn(ALOAD, 0); 230 mv.visitMethodInsn(INVOKESPECIAL, SUPER, "<init>", "()V"); 231 mv.visitInsn(RETURN); 232 mv.visitMaxs(0, 0); 233 234 mv = cv.visitMethod(ACC_PUBLIC, "create", "()V", null, null); 236 mv.visitVarInsn(ALOAD, 0); 237 mv.visitMethodInsn(INVOKESPECIAL, SUPER, "create", "()V"); 238 computeInterfaceTypes(); 239 generateCreateType(mv); 240 generateCreateControllers(mv); 241 generateCreateContent(mv); 242 generateCreateInterfaces(mv); 243 mv.visitInsn(RETURN); 244 mv.visitMaxs(0, 0); 245 246 String mName = "getFcGeneratorParameters"; 248 String mDesc = "()Ljava/lang/String;"; 249 mv = cv.visitMethod(ACC_PUBLIC, mName, mDesc, null, null); 250 mv.visitLdcInsn(args.toString()); 251 mv.visitInsn(ARETURN); 252 mv.visitMaxs(0, 0); 253 254 return ((ClassWriter)cv).toByteArray(); 256 } 257 258 263 264 public void computeInterfaceTypes () { 265 Tree[] functionalItfs = args.getSubTree(1).getSubTrees(); 266 Tree[] controlItfs = args.getSubTree(2).getSubTree(1).getSubTrees(); 267 Tree[] allItfs = new Tree[functionalItfs.length + controlItfs.length]; 268 for (int i = 0; i < controlItfs.length; ++i) { 269 allItfs[i] = new Tree(new Tree[] { 270 controlItfs[i].getSubTree(0), 271 controlItfs[i].getSubTree(1), 272 new Tree("false"), 273 new Tree("false"), 274 new Tree("false") 275 }); 276 } 277 for (int i = 0; i < functionalItfs.length; ++i) { 278 allItfs[i + controlItfs.length] = functionalItfs[i]; 279 } 280 interfaceTypes = new Tree(allItfs); 281 } 282 283 289 290 public void generateCreateType (final CodeVisitor mv) { 291 Label l = new Label(); 293 mv.visitFieldInsn( 294 GETSTATIC, 295 name, 296 "componentType", 297 "Lorg/objectweb/fractal/api/type/ComponentType;"); 298 mv.visitJumpInsn(IFNONNULL, l); 299 300 mv.visitVarInsn(ALOAD, 0); 302 mv.visitFieldInsn(GETFIELD, name, "hints", "Ljava/lang/Object;"); 303 mv.visitTypeInsn(CHECKCAST, "org/objectweb/fractal/api/type/TypeFactory"); 304 mv.visitVarInsn(ASTORE, 1); 305 306 308 int externalItfs = interfaceTypes.getSize(); 310 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 311 Tree itf = interfaceTypes.getSubTree(i); 312 if (itf.getSubTree(0).toString().startsWith("/")) { 313 --externalItfs; 314 } 315 } 316 317 mv.visitVarInsn(ALOAD, 1); 319 mv.visitIntInsn(SIPUSH, externalItfs); 320 mv.visitTypeInsn(ANEWARRAY, "org/objectweb/fractal/api/type/InterfaceType"); 321 322 int j = 0; 323 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 324 Tree itf = interfaceTypes.getSubTree(i); 325 if (itf.getSubTree(0).toString().startsWith("/")) { 326 continue; 327 } 328 mv.visitInsn(DUP); 330 mv.visitIntInsn(SIPUSH, j++); 331 mv.visitVarInsn(ALOAD, 1); 332 mv.visitLdcInsn(itf.getSubTree(0).toString()); 333 mv.visitLdcInsn(itf.getSubTree(1).toString()); 334 mv.visitInsn(itf.getSubTree(2).equals("true") ? ICONST_1 : ICONST_0); 335 mv.visitInsn(itf.getSubTree(3).equals("true") ? ICONST_1 : ICONST_0); 336 mv.visitInsn(itf.getSubTree(4).equals("true") ? ICONST_1 : ICONST_0); 337 mv.visitMethodInsn( 338 INVOKEINTERFACE, 339 "org/objectweb/fractal/api/type/TypeFactory", 340 "createFcItfType", 341 "(Ljava/lang/String;Ljava/lang/String;ZZZ)" + 342 "Lorg/objectweb/fractal/api/type/InterfaceType;"); 343 mv.visitInsn(AASTORE); 344 } 345 346 mv.visitMethodInsn( 348 INVOKEINTERFACE, 349 "org/objectweb/fractal/api/type/TypeFactory", 350 "createFcType", 351 "([Lorg/objectweb/fractal/api/type/InterfaceType;)" + 352 "Lorg/objectweb/fractal/api/type/ComponentType;"); 353 mv.visitFieldInsn( 354 PUTSTATIC, 355 name, 356 "componentType", 357 "Lorg/objectweb/fractal/api/type/ComponentType;"); 358 359 361 int internalIfts = interfaceTypes.getSize(); 363 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 364 Tree itf = interfaceTypes.getSubTree(i); 365 String name = itf.getSubTree(0).toString(); 366 if (name.startsWith("/") || 367 name.equals("component") || 368 name.endsWith("-controller")) 369 { 370 --internalIfts; 371 } 372 } 373 374 mv.visitVarInsn(ALOAD, 1); 376 mv.visitIntInsn(SIPUSH, internalIfts); 377 mv.visitTypeInsn(ANEWARRAY, "org/objectweb/fractal/api/type/InterfaceType"); 378 379 j = 0; 380 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 381 Tree itf = interfaceTypes.getSubTree(i); 382 String name = itf.getSubTree(0).toString(); 383 if (name.startsWith("/") || 384 name.equals("component") || 385 name.endsWith("-controller")) 386 { 387 continue; 388 } 389 mv.visitInsn(DUP); 391 mv.visitIntInsn(SIPUSH, j++); 392 mv.visitVarInsn(ALOAD, 1); 393 mv.visitLdcInsn(itf.getSubTree(0).toString()); 394 mv.visitLdcInsn(itf.getSubTree(1).toString()); 395 mv.visitInsn(itf.getSubTree(2).equals("true") ? ICONST_0 : ICONST_1); 396 mv.visitInsn(itf.getSubTree(3).equals("true") ? ICONST_1 : ICONST_0); 397 mv.visitInsn(itf.getSubTree(4).equals("true") ? ICONST_1 : ICONST_0); 398 mv.visitMethodInsn( 399 INVOKEINTERFACE, 400 "org/objectweb/fractal/api/type/TypeFactory", 401 "createFcItfType", 402 "(Ljava/lang/String;Ljava/lang/String;ZZZ)" + 403 "Lorg/objectweb/fractal/api/type/InterfaceType;"); 404 mv.visitInsn(AASTORE); 405 } 406 407 mv.visitMethodInsn( 409 INVOKEINTERFACE, 410 "org/objectweb/fractal/api/type/TypeFactory", 411 "createFcType", 412 "([Lorg/objectweb/fractal/api/type/InterfaceType;)" + 413 "Lorg/objectweb/fractal/api/type/ComponentType;"); 414 mv.visitFieldInsn( 415 PUTSTATIC, 416 name, 417 "internalComponentType", 418 "Lorg/objectweb/fractal/api/type/ComponentType;"); 419 420 mv.visitLabel(l); 422 423 mv.visitVarInsn(ALOAD, 0); 425 mv.visitFieldInsn( 426 GETSTATIC, 427 name, 428 "componentType", 429 "Lorg/objectweb/fractal/api/type/ComponentType;"); 430 mv.visitFieldInsn( 431 PUTFIELD, 432 name, 433 "type", 434 "Lorg/objectweb/fractal/api/Type;"); 435 436 mv.visitFieldInsn( 438 GETSTATIC, 439 name, 440 "componentType", 441 "Lorg/objectweb/fractal/api/type/ComponentType;"); 442 mv.visitVarInsn(ASTORE, 2); 443 } 444 445 451 452 public void generateCreateControllers (final CodeVisitor mv) 453 throws ClassGenerationException 454 { 455 Map context = new HashMap (); 457 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 458 String itfName = interfaceTypes.getSubTree(i).getSubTree(0).toString(); 459 if (itfName.equals("attribute-controller")) { 460 Tree itfSignature = interfaceTypes.getSubTree(i).getSubTree(1); 461 context.put("attributeControllerInterface", itfSignature); 462 break; 463 } 464 } 465 466 Tree[] controllerDescs; 468 Tree[] controllerArgs; 469 try { 470 Tree t = args.getSubTree(2).getSubTree(2); 471 controllerDescs = loader.evalTree(t, context).getSubTrees(); 472 controllerArgs = new Tree[controllerDescs.length]; 473 for (int i = 0; i < controllerDescs.length; i++) { 474 Tree controllerDesc = controllerDescs[i]; 475 if (controllerDesc.getSize() > 0) { 476 controllerDescs[i] = controllerDesc.getSubTree(0); 477 if (controllerDesc.getSize() > 1) { 478 Tree[] trees = controllerDesc.getSubTrees(); 479 Tree[] args = new Tree[trees.length - 1]; 480 System.arraycopy(trees, 1, args, 0, args.length); 481 controllerArgs[i] = new Tree(args); 482 } 483 } 484 } 485 } catch (Exception e) { 486 throw new ClassGenerationException( 487 e, 488 args.toString(), 489 "Cannot find or evaluate the controller class descriptors"); 490 } 491 492 String optimize = args.getSubTree(2).getSubTree(5).toString(); 494 if (!Arrays.asList(OPTIMIZATIONS).contains(optimize)) { 495 throw new ClassGenerationException( 496 null, args.toString(), "Invalid optimization level: " + optimize); 497 } 498 499 controllerClasses = new ArrayList (); 500 if (optimize.indexOf("Controllers") != -1) { 501 Tree[] mergeClassDesc = new Tree[controllerDescs.length + 2]; 503 mergeClassDesc[0] = args.getSubTree(2).getSubTree(4); 505 mergeClassDesc[1] = new Tree("java.lang.Object"); 507 508 String content = args.getSubTree(3).toString(); 509 if (optimize.indexOf("Content") != -1 && !content.equals("EMPTY")) { 510 try { 511 contentClass = loader.loadClass(content, classLoader); 512 } catch (ClassNotFoundException e) { 513 throw new ClassGenerationException( 514 e, args.toString(), "Cannot find the '" + content + "' class"); 515 } 516 mergeClassDesc[1] = new Tree(content); 517 } 518 for (int i = 0; i < controllerDescs.length; ++i) { 520 Tree controllerDesc = controllerDescs[i]; 521 try { 522 Class c = loader.loadClass(controllerDesc, classLoader); 523 mergeClassDesc[i + 2] = new Tree(c.getName()); 524 } catch (ClassNotFoundException e) { 525 throw new ClassGenerationException( 526 e, 527 args.toString(), 528 "Cannot find or generate the '" + controllerDesc + 529 "' controller class"); 530 } 531 } 532 533 Class mergedClass; 535 String mergedClassName; 536 try { 537 mergedClass = loader.loadClass(new Tree(mergeClassDesc), classLoader); 538 mergedClassName = Type.getInternalName(mergedClass); 539 } catch (ClassNotFoundException e) { 540 throw new ClassGenerationException( 541 e, 542 args.toString(), 543 "Cannot find or generate the merged controller class"); 544 } 545 546 Tree interceptors = args.getSubTree(2).getSubTree(3); 547 if (optimize.indexOf("Interceptors") > 0 && interceptors.getSize() > 0) { 548 551 List itfList = new ArrayList (); 553 List itfNameList = new ArrayList (); 554 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 555 Tree itfType = interfaceTypes.getSubTree(i); 556 String itfName = itfType.getSubTree(0).toString(); 557 String itfSignature = itfType.getSubTree(1).toString(); 558 boolean isClient = itfType.getSubTree(2).equals("true"); 559 boolean isControl = 560 itfName.startsWith("/") || 561 itfName.equals("component") || 562 itfName.endsWith("-controller"); 563 if (!isClient && !isControl && !itfList.contains(itfSignature)) { 564 itfList.add(itfSignature); 565 itfNameList.add(new Tree(itfName)); 566 } 567 } 568 for (int i = 0; i < itfList.size(); ++i) { 569 itfList.set(i, new Tree((String )itfList.get(i))); 570 } 571 Tree[] itfTrees = 572 (Tree[])itfList.toArray(new Tree[itfList.size()]); 573 Tree[] itfNameTrees = 574 (Tree[])itfNameList.toArray(new Tree[itfNameList.size()]); 575 576 Map itfCtxt = new HashMap (); 578 itfCtxt.put("interfaceName", new Tree(itfNameTrees)); 579 Tree classGen; 580 try { 581 classGen = loader.evalTree(interceptors.getSubTree(0), itfCtxt); 582 } catch (Exception e) { 583 throw new ClassGenerationException( 584 e, 585 args.toString(), 586 "Cannot get the merged interceptor class generator descriptor"); 587 } 588 589 try { 591 mergedClass = loader.loadClass(new Tree(new Tree[] { 592 classGen, 593 new Tree(mergedClass.getName()), 594 new Tree(itfTrees), 595 new Tree(new Tree[0]), 596 new Tree("in") 597 }), classLoader); 598 mergedClassName = Type.getInternalName(mergedClass); 599 } catch (ClassNotFoundException e) { 600 throw new ClassGenerationException( 601 e, 602 args.toString(), 603 "Cannot find or generate the merged interceptor class"); 604 } 605 } 606 607 controllerClasses.add(mergedClass); 608 609 mv.visitVarInsn(ALOAD, 0); 611 mv.visitFieldInsn(GETFIELD, name, "controllers", "Ljava/util/List;"); 612 mv.visitTypeInsn(NEW, mergedClassName); 613 mv.visitInsn(DUP); 614 mv.visitMethodInsn(INVOKESPECIAL, mergedClassName, "<init>", "()V"); 615 mv.visitInsn(DUP); 617 mv.visitTypeInsn( 618 CHECKCAST, 619 "org/objectweb/fractal/julia/loader/Initializable"); 620 generateCreateTreeCode(mv, new Tree(controllerArgs)); 621 mv.visitMethodInsn( 622 INVOKEINTERFACE, 623 "org/objectweb/fractal/julia/loader/Initializable", 624 "initialize", 625 "(Lorg/objectweb/fractal/julia/loader/Tree;)V"); 626 mv.visitMethodInsn( 628 INVOKEINTERFACE, 629 "java/util/List", 630 "add", 631 "(Ljava/lang/Object;)Z"); 632 mv.visitInsn(POP); 633 634 if (optimize.indexOf("Content") != -1 && !content.equals("EMPTY")) { 635 mv.visitVarInsn(ALOAD, 0); 637 mv.visitVarInsn(ALOAD, 0); 638 mv.visitFieldInsn(GETFIELD, name, "controllers", "Ljava/util/List;"); 639 mv.visitInsn(ICONST_0); 640 mv.visitMethodInsn( 641 INVOKEINTERFACE, 642 "java/util/List", 643 "get", 644 "(I)Ljava/lang/Object;"); 645 mv.visitFieldInsn(PUTFIELD, name, "content", "Ljava/lang/Object;"); 646 } 647 } else { 648 for (int i = 0; i < controllerDescs.length; ++i) { 650 Tree controllerDesc = controllerDescs[i]; 651 Class c; 652 String n; 653 try { 654 c = loader.loadClass(controllerDesc, classLoader); 655 n = c.getName().replace('.', '/'); 656 controllerClasses.add(c); 657 } catch (ClassNotFoundException e) { 658 throw new ClassGenerationException( 659 e, 660 args.toString(), 661 "Cannot find or generate the '" + controllerDesc + 662 "' controller class"); 663 } 664 mv.visitVarInsn(ALOAD, 0); 666 mv.visitFieldInsn(GETFIELD, name, "controllers", "Ljava/util/List;"); 667 mv.visitTypeInsn(NEW, n); 668 mv.visitInsn(DUP); 669 mv.visitMethodInsn(INVOKESPECIAL, n, "<init>", "()V"); 670 if (controllerArgs[i] != null) { 671 mv.visitInsn(DUP); 673 mv.visitTypeInsn( 674 CHECKCAST, 675 "org/objectweb/fractal/julia/loader/Initializable"); 676 generateCreateTreeCode(mv, controllerArgs[i]); 677 mv.visitMethodInsn( 678 INVOKEINTERFACE, 679 "org/objectweb/fractal/julia/loader/Initializable", 680 "initialize", 681 "(Lorg/objectweb/fractal/julia/loader/Tree;)V"); 682 } 683 mv.visitMethodInsn( 685 INVOKEINTERFACE, 686 "java/util/List", 687 "add", 688 "(Ljava/lang/Object;)Z"); 689 mv.visitInsn(POP); 690 } 691 } 692 693 controllerTrees = new Tree[controllerClasses.size()]; 695 for (int l = 0; l < controllerTrees.length; ++l) { 696 controllerTrees[l] = new Tree(((Class )controllerClasses.get(l)).getName()); 697 } 698 } 699 700 706 707 private void generateCreateTreeCode (final CodeVisitor mv, final Tree t) { 708 String tree = "org/objectweb/fractal/julia/loader/Tree"; 709 if (t == null) { 710 mv.visitInsn(ACONST_NULL); 711 } else if (t.getSize() == 0) { 712 mv.visitTypeInsn(NEW, tree); 713 mv.visitInsn(DUP); 714 mv.visitLdcInsn(t.toString()); 715 mv.visitMethodInsn(INVOKESPECIAL, tree, "<init>", "(Ljava/lang/String;)V"); 716 } else { 717 mv.visitTypeInsn(NEW, tree); 718 mv.visitInsn(DUP); 719 mv.visitIntInsn(SIPUSH, t.getSize()); 720 mv.visitTypeInsn(ANEWARRAY, tree); 721 for (int i = 0; i < t.getSize(); ++i) { 722 mv.visitInsn(DUP); 723 mv.visitIntInsn(SIPUSH, i); 724 generateCreateTreeCode(mv, t.getSubTree(i)); 725 mv.visitInsn(AASTORE); 726 } 727 mv.visitMethodInsn(INVOKESPECIAL, tree, "<init>", "([L" + tree + ";)V"); 728 } 729 } 730 731 738 739 public void generateCreateContent (final CodeVisitor mv) 740 throws ClassGenerationException 741 { 742 String content = args.getSubTree(3).toString(); 743 if (content.equals("EMPTY")) { 744 return; 745 } 746 747 if (contentClass == null) { 749 try { 750 contentClass = loader.loadClass(content, classLoader); 751 } catch (ClassNotFoundException e) { 752 throw new ClassGenerationException( 753 e, args.toString(), "Cannot find the '" + content + "' class"); 754 } 755 content = content.replace('.', '/'); 756 Label end = new Label(); 758 mv.visitVarInsn(ALOAD, 0); 759 mv.visitFieldInsn(GETFIELD, name, "content", "Ljava/lang/Object;"); 760 mv.visitJumpInsn(IFNONNULL, end); 761 mv.visitVarInsn(ALOAD, 0); 762 mv.visitTypeInsn(NEW, content); 763 mv.visitInsn(DUP); 764 mv.visitMethodInsn(INVOKESPECIAL, content, "<init>", "()V"); 765 mv.visitFieldInsn(PUTFIELD, name, "content", "Ljava/lang/Object;"); 766 mv.visitLabel(end); 767 } 768 769 mv.visitVarInsn(ALOAD, 0); 771 mv.visitFieldInsn(GETFIELD, this.name, "interfaces", "Ljava/util/Map;"); 772 mv.visitLdcInsn("/content"); 773 mv.visitVarInsn(ALOAD, 0); 774 mv.visitFieldInsn(GETFIELD, name, "content", "Ljava/lang/Object;"); 775 mv.visitMethodInsn( 776 INVOKEINTERFACE, 777 "java/util/Map", 778 "put", 779 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 780 mv.visitInsn(POP); 781 } 782 783 789 790 public void generateCreateInterfaces (final CodeVisitor mv) 791 throws ClassGenerationException 792 { 793 String optimize = args.getSubTree(2).getSubTree(5).toString(); 794 Tree interceptors = args.getSubTree(2).getSubTree(3); 795 boolean interceptorsMerged = optimize.indexOf("Interceptors") != -1; 796 797 Tree itfClassGen = args.getSubTree(2).getSubTree(0); 798 boolean hasItfClassGen = !itfClassGen.equals("NONE"); 799 800 mv.visitInsn(ACONST_NULL); 802 mv.visitVarInsn(ASTORE, 3); 803 804 for (int i = 0; i < interfaceTypes.getSize(); ++i) { 805 Tree itf = interfaceTypes.getSubTree(i); 806 String itfName = itf.getSubTree(0).toString(); 807 String itfSignature = itf.getSubTree(1).toString(); 808 boolean isClient = itf.getSubTree(2).toString().equals("true"); 809 boolean isCollection = itf.getSubTree(4).toString().equals("true"); 810 boolean isControl = 811 !isClient && 812 (itfName.startsWith("/") || 813 itfName.equals("component") || 814 itfName.endsWith("-controller")); 815 816 Class itfClass; 818 try { 819 itfClass = loader.loadClass(itfSignature, classLoader); 820 } catch (ClassNotFoundException e) { 821 throw new ClassGenerationException( 822 e, args.toString(), "Cannot find the '" + itfSignature + "' class"); 823 } 824 825 Class compItfClass; 827 String compItfClassName; 828 if (hasItfClassGen) { 829 try { 830 compItfClass = loader.loadClass(new Tree(new Tree[] { 831 itfClassGen, 832 new Tree(new Tree[] { new Tree(itfSignature) }) 833 }), classLoader); 834 compItfClassName = compItfClass.getName().replace('.', '/'); 835 } catch (ClassNotFoundException e) { 836 throw new ClassGenerationException( 837 e, 838 args.toString(), 839 "Cannot find or generate the ComponentInterface class for the '" + 840 itfSignature + "' class"); 841 } 842 } else { 843 compItfClass = null; 844 compItfClassName = null; 845 } 846 847 850 if (isClient) { 851 mv.visitInsn(ACONST_NULL); 853 mv.visitVarInsn(ASTORE, 4); 854 } else { 855 int u = -1; 857 int v = -1; 858 int w; 859 for (int j = 0; j < controllerClasses.size(); ++j) { 860 if (itfClass.isAssignableFrom((Class )controllerClasses.get(j))) { 861 u = j + 1; 862 break; 863 } 864 } 865 if (contentClass != null && itfClass.isAssignableFrom(contentClass)) { 866 v = 0; 867 } 868 if (isControl || interceptorsMerged) { 869 w = u != -1 ? u : v; 870 } else { 871 w = v != -1 ? v : u; 872 } 873 if (w == -1 && isControl) { 874 throw new ClassGenerationException( 875 null, 876 args.toString(), 877 "Implementation missing for control interface " + 878 itfName + " of type " + itfSignature); 879 } 880 881 if (w != -1) { 883 if (w == 0) { 884 mv.visitVarInsn(ALOAD, 0); 886 mv.visitFieldInsn(GETFIELD, name, "content", "Ljava/lang/Object;"); 887 } else { 888 mv.visitVarInsn(ALOAD, 0); 890 mv.visitFieldInsn(GETFIELD, name, "controllers", "Ljava/util/List;"); 891 mv.visitIntInsn(SIPUSH, w - 1); 892 mv.visitMethodInsn( 893 INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); 894 } 895 } else { 896 mv.visitInsn(ACONST_NULL); 898 } 899 mv.visitVarInsn(ASTORE, 4); 900 } 901 902 906 if (!isControl && 907 interceptors.getSize() > 0 && 908 (isClient || !interceptorsMerged)) 909 { 910 914 Class ic; 916 try { 917 String superClass; 920 if (isClient) { 921 superClass = "org.objectweb.fractal.julia.InterceptorInterface"; 922 } else { 923 superClass = "java.lang.Object"; 924 } 925 926 Map itfCtxt = new HashMap (); 928 itfCtxt.put( 929 "interfaceName", 930 new Tree(new Tree[] { new Tree(itfName) })); 931 932 Tree icDesc = new Tree(new Tree[] { 934 loader.evalTree(interceptors.getSubTree(0), itfCtxt), 935 new Tree(superClass), 936 new Tree(new Tree[] { new Tree(itfSignature) }), 937 new Tree(controllerTrees), 938 new Tree(isClient ? "out" : "in") 939 }); 940 941 ic = loader.loadClass(icDesc, classLoader); 943 } catch (IllegalClassDescriptorException e) { 944 ic = null; 945 } catch (Exception e) { 946 throw new ClassGenerationException( 947 e, 948 args.toString(), 949 "Cannot find or generate the interceptor class for the '" + 950 itfSignature + "' interface"); 951 } 952 953 if (ic != null) { 954 String icName = ic.getName().replace('.', '/'); 956 957 mv.visitTypeInsn(NEW, icName); 959 mv.visitInsn(DUP); 960 mv.visitVarInsn(ALOAD, 4); 961 mv.visitMethodInsn( 962 INVOKESPECIAL, icName, "<init>", "(Ljava/lang/Object;)V"); 963 mv.visitVarInsn(ASTORE, 4); 964 965 mv.visitVarInsn(ALOAD, 0); 967 mv.visitFieldInsn(GETFIELD, name, "controllers", "Ljava/util/List;"); 968 mv.visitVarInsn(ALOAD, 4); 969 mv.visitMethodInsn( 970 INVOKEINTERFACE, 971 "java/util/List", 972 "add", 973 "(Ljava/lang/Object;)Z"); 974 mv.visitInsn(POP); 975 } 976 } 977 978 980 mv.visitVarInsn(ALOAD, 0); 982 mv.visitFieldInsn(GETFIELD, name, "interfaces", "Ljava/util/Map;"); 983 mv.visitLdcInsn(isCollection ? "/collection/" + itfName : itfName); 984 985 if (hasItfClassGen) { 986 mv.visitTypeInsn(NEW, compItfClassName); 993 mv.visitInsn(DUP); 994 mv.visitVarInsn(ALOAD, 3); 995 mv.visitLdcInsn(itfName); 996 if (itfName.startsWith("/")) { 997 mv.visitInsn(ACONST_NULL); 998 } else { 999 mv.visitVarInsn(ALOAD, 2); 1000 mv.visitLdcInsn(itfName); 1001 mv.visitMethodInsn( 1002 INVOKEINTERFACE, 1003 "org/objectweb/fractal/api/type/ComponentType", 1004 "getFcInterfaceType", 1005 "(Ljava/lang/String;)Lorg/objectweb/fractal/api/type/InterfaceType;"); 1006 } 1007 mv.visitInsn(ICONST_0); 1008 mv.visitVarInsn(ALOAD, 4); 1009 mv.visitMethodInsn( 1010 INVOKESPECIAL, 1011 compItfClassName, 1012 "<init>", 1013 "(Lorg/objectweb/fractal/api/Component;Ljava/lang/String;" + 1014 "Lorg/objectweb/fractal/api/Type;ZLjava/lang/Object;)V"); 1015 } else { 1016 mv.visitVarInsn(ALOAD, 4); 1018 } 1019 1020 if (itfName.equals("component")) { 1021 mv.visitInsn(DUP); 1023 mv.visitVarInsn(ASTORE, 3); 1024 } 1025 1026 mv.visitMethodInsn( 1028 INVOKEINTERFACE, 1029 "java/util/Map", 1030 "put", 1031 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 1032 mv.visitInsn(POP); 1033 1034 1036 if (isControl) { 1037 continue; 1038 } 1039 1040 mv.visitVarInsn(ALOAD, 0); 1042 mv.visitFieldInsn(GETFIELD, name, "internalInterfaces", "Ljava/util/Map;"); 1043 mv.visitLdcInsn(isCollection ? "/collection/" + itfName : itfName); 1044 1045 if (hasItfClassGen) { 1046 mv.visitTypeInsn(NEW, compItfClassName); 1053 mv.visitInsn(DUP); 1054 mv.visitVarInsn(ALOAD, 3); 1055 mv.visitLdcInsn(itfName); 1056 mv.visitFieldInsn( 1057 GETSTATIC, 1058 name, 1059 "internalComponentType", 1060 "Lorg/objectweb/fractal/api/type/ComponentType;"); 1061 mv.visitLdcInsn(itfName); 1062 mv.visitMethodInsn( 1063 INVOKEINTERFACE, 1064 "org/objectweb/fractal/api/type/ComponentType", 1065 "getFcInterfaceType", 1066 "(Ljava/lang/String;)Lorg/objectweb/fractal/api/type/InterfaceType;"); 1067 mv.visitInsn(ICONST_1); 1068 mv.visitVarInsn(ALOAD, 4); 1069 mv.visitMethodInsn( 1070 INVOKESPECIAL, 1071 compItfClassName, 1072 "<init>", 1073 "(Lorg/objectweb/fractal/api/Component;Ljava/lang/String;" + 1074 "Lorg/objectweb/fractal/api/Type;ZLjava/lang/Object;)V"); 1075 } else { 1076 mv.visitVarInsn(ALOAD, 4); 1078 } 1079 1080 mv.visitMethodInsn( 1082 INVOKEINTERFACE, 1083 "java/util/Map", 1084 "put", 1085 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 1086 mv.visitInsn(POP); 1087 } 1088 } 1089} 1090 | Popular Tags |