001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.loaders;
006:
007: import com.tc.asm.ClassAdapter;
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.Label;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.object.bytecode.ByteCodeUtil;
013: import com.tc.object.bytecode.ClassAdapterFactory;
014:
015: /**
016: * Adds the NamedClassLoader interface (and required impl) to a loader implementation
017: */
018: public class NamedLoaderAdapter extends ClassAdapter implements
019: Opcodes, ClassAdapterFactory {
020:
021: private static final String LOADER_NAME_FIELD = ByteCodeUtil.TC_FIELD_PREFIX
022: + "loaderName";
023: private String owner;
024:
025: public NamedLoaderAdapter() {
026: super (null);
027: }
028:
029: private NamedLoaderAdapter(ClassVisitor cv, ClassLoader caller) {
030: super (cv);
031: }
032:
033: public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) {
034: return new NamedLoaderAdapter(visitor, loader);
035: }
036:
037: public void visit(int version, int access, String name,
038: String signature, String super Name, String[] interfaces) {
039: interfaces = ByteCodeUtil.addInterfaces(interfaces,
040: new String[] { ByteCodeUtil.NAMEDCLASSLOADER_CLASS });
041: super .visit(version, access, name, signature, super Name,
042: interfaces);
043: this .owner = name;
044: }
045:
046: public void visitEnd() {
047: super .visitField(ACC_SYNTHETIC | ACC_VOLATILE | ACC_TRANSIENT
048: | ACC_PRIVATE, LOADER_NAME_FIELD, "Ljava/lang/String;",
049: null, null);
050:
051: MethodVisitor mv = super .visitMethod(
052: ACC_PUBLIC | ACC_SYNTHETIC, "__tc_setClassLoaderName",
053: "(Ljava/lang/String;)V", null, null);
054: mv.visitVarInsn(ALOAD, 0);
055: mv.visitVarInsn(ALOAD, 1);
056: mv.visitFieldInsn(PUTFIELD, owner, LOADER_NAME_FIELD,
057: "Ljava/lang/String;");
058: mv.visitInsn(RETURN);
059: mv.visitMaxs(0, 0);
060: mv.visitEnd();
061:
062: mv = super .visitMethod(ACC_PUBLIC | ACC_SYNTHETIC,
063: "__tc_getClassLoaderName", "()Ljava/lang/String;",
064: null, null);
065: mv.visitCode();
066: mv.visitVarInsn(ALOAD, 0);
067: mv.visitFieldInsn(GETFIELD, owner, LOADER_NAME_FIELD,
068: "Ljava/lang/String;");
069: Label l1 = new Label();
070: mv.visitJumpInsn(IFNONNULL, l1);
071: mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
072: mv.visitInsn(DUP);
073: mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
074: mv.visitInsn(DUP);
075: mv
076: .visitLdcInsn("Classloader name not set, instances defined from this loader not supported in Terracotta (loader: ");
077: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer",
078: "<init>", "(Ljava/lang/String;)V");
079: mv.visitVarInsn(ALOAD, 0);
080: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
081: "getClass", "()Ljava/lang/Class;");
082: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName",
083: "()Ljava/lang/String;");
084: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
085: "append",
086: "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
087: mv.visitLdcInsn(")");
088: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
089: "append",
090: "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
091: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
092: "toString", "()Ljava/lang/String;");
093: mv.visitMethodInsn(INVOKESPECIAL,
094: "java/lang/IllegalStateException", "<init>",
095: "(Ljava/lang/String;)V");
096: mv.visitInsn(ATHROW);
097: mv.visitLabel(l1);
098: mv.visitVarInsn(ALOAD, 0);
099: mv.visitFieldInsn(GETFIELD, owner, LOADER_NAME_FIELD,
100: "Ljava/lang/String;");
101: mv.visitInsn(ARETURN);
102: mv.visitMaxs(0, 0);
103: mv.visitEnd();
104:
105: super.visitEnd();
106: }
107:
108: }
|