KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > jboss > transform > UCLAdapter


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.jboss.transform;
6
7 import com.tc.asm.ClassAdapter;
8 import com.tc.asm.ClassVisitor;
9 import com.tc.asm.Label;
10 import com.tc.asm.MethodAdapter;
11 import com.tc.asm.MethodVisitor;
12 import com.tc.asm.Opcodes;
13 import com.tc.object.bytecode.ByteCodeUtil;
14 import com.tc.object.bytecode.ClassAdapterFactory;
15 import com.tc.object.loaders.NamedClassLoader;
16
17 public class UCLAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory {
18
19   private static final String JavaDoc LOADER_DESC_FIELD = ByteCodeUtil.TC_FIELD_PREFIX + "loaderDesc";
20   private String JavaDoc owner;
21
22   public UCLAdapter() {
23     super(null);
24   }
25
26   private UCLAdapter(ClassVisitor cv, ClassLoader JavaDoc caller) {
27     super(cv);
28   }
29
30   public ClassAdapter create(ClassVisitor visitor, ClassLoader JavaDoc loader) {
31     return new UCLAdapter(visitor, loader);
32   }
33
34   public void visit(int version, int access, String JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] interfaces) {
35     interfaces = ByteCodeUtil.addInterfaces(interfaces, new String JavaDoc[] { NamedClassLoader.CLASS });
36     super.visit(version, access, name, signature, superName, interfaces);
37     owner = name;
38   }
39
40   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
41     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
42
43     if ("<init>".equals(name)) {
44       mv = new CstrAdapter(mv);
45     }
46
47     return mv;
48   }
49
50   public void visitEnd() {
51     addLoaderDescField();
52     addNamedClassLoaderMethods();
53     super.visitEnd();
54   }
55
56   private void addNamedClassLoaderMethods() {
57     MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_setClassLoaderName",
58                                          "(Ljava/lang/String;)V", null, null);
59     mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
60     mv.visitInsn(DUP);
61     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "()V");
62     mv.visitInsn(ATHROW);
63     mv.visitMaxs(0, 0);
64     mv.visitEnd();
65
66     mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_getClassLoaderName", "()Ljava/lang/String;",
67                            null, null);
68     mv.visitVarInsn(ALOAD, 0);
69     mv.visitFieldInsn(GETFIELD, owner, LOADER_DESC_FIELD, "Ljava/lang/String;");
70     Label l1 = new Label();
71     mv.visitJumpInsn(IFNONNULL, l1);
72     mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
73     mv.visitInsn(DUP);
74     mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
75     mv.visitInsn(DUP);
76     mv.visitLdcInsn("Classes from this loader cannot be shared ");
77     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
78     mv.visitVarInsn(ALOAD, 0);
79     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
80     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
81                        "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
82     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
83     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "(Ljava/lang/String;)V");
84     mv.visitInsn(ATHROW);
85     mv.visitLabel(l1);
86     mv.visitVarInsn(ALOAD, 0);
87     mv.visitFieldInsn(GETFIELD, owner, LOADER_DESC_FIELD, "Ljava/lang/String;");
88     mv.visitInsn(ARETURN);
89     mv.visitMaxs(0, 0);
90     mv.visitEnd();
91   }
92
93   private void addLoaderDescField() {
94     super.visitField(ACC_SYNTHETIC | ACC_TRANSIENT | ACC_PRIVATE | ACC_FINAL, LOADER_DESC_FIELD, "Ljava/lang/String;",
95                      null, null);
96   }
97
98   private class CstrAdapter extends MethodAdapter implements Opcodes {
99
100     public CstrAdapter(MethodVisitor mv) {
101       super(mv);
102     }
103
104     public void visitInsn(int opcode) {
105       if (RETURN == opcode) {
106         assignLoaderDesc();
107
108         super.visitVarInsn(ALOAD, 0);
109         super.visitFieldInsn(GETFIELD, owner, LOADER_DESC_FIELD, "Ljava/lang/String;");
110         Label isNull = new Label();
111         super.visitJumpInsn(IFNULL, isNull);
112         super.visitVarInsn(ALOAD, 0);
113         super.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/hook/impl/ClassProcessorHelper",
114                               "registerGlobalLoader", "(Lcom/tc/object/loaders/NamedClassLoader;)V");
115         super.visitLabel(isNull);
116       }
117
118       super.visitInsn(opcode);
119     }
120
121     private void assignLoaderDesc() {
122       super.visitVarInsn(ALOAD, 0);
123       super.visitVarInsn(ALOAD, 0);
124       super.visitMethodInsn(INVOKESTATIC, "com/tc/jboss/JBossLoaderNaming", "getLoaderName",
125                             "(Ljava/lang/ClassLoader;)Ljava/lang/String;");
126       super.visitFieldInsn(PUTFIELD, owner, LOADER_DESC_FIELD, "Ljava/lang/String;");
127     }
128
129   }
130
131 }
132
Popular Tags