001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.glassfish.transform;
006:
007: import com.tc.asm.ClassAdapter;
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.Label;
010: import com.tc.asm.MethodAdapter;
011: import com.tc.asm.MethodVisitor;
012: import com.tc.asm.Opcodes;
013: import com.tc.object.bytecode.ByteCodeUtil;
014: import com.tc.object.bytecode.ClassAdapterFactory;
015:
016: public class RuntimeModelAdapter extends ClassAdapter implements
017: ClassAdapterFactory, Opcodes {
018:
019: private static final String REMOVE_TC_FIELDS_METHOD = ByteCodeUtil.TC_METHOD_PREFIX
020: + "removeTCFields";
021: private static final String REMOVE_TC_FIELDS_METHOD_DESC = "(Ljava/util/List;)Ljava/util/List;";
022:
023: private String this ClassName;
024:
025: public RuntimeModelAdapter(ClassVisitor cv) {
026: super (cv);
027: }
028:
029: public RuntimeModelAdapter() {
030: super (null);
031: }
032:
033: public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) {
034: return new RuntimeModelAdapter(visitor);
035: }
036:
037: public void visit(int version, int access, String name,
038: String signature, String super Name, String[] interfaces) {
039: super .visit(version, access, name, signature, super Name,
040: interfaces);
041: this ClassName = name;
042: }
043:
044: public MethodVisitor visitMethod(int access, String name,
045: String desc, String signature, String[] exceptions) {
046: MethodVisitor mv = super .visitMethod(access, name, desc,
047: signature, exceptions);
048:
049: if ("getFields".equals(name)) {
050: mv = new GetFieldsAdapter(mv);
051: }
052:
053: return mv;
054: }
055:
056: public void visitEnd() {
057: addRemoveTCFieldsMethod();
058: super .visitEnd();
059: }
060:
061: private void addRemoveTCFieldsMethod() {
062: MethodVisitor mv = super .visitMethod(ACC_PRIVATE + ACC_STATIC,
063: REMOVE_TC_FIELDS_METHOD, REMOVE_TC_FIELDS_METHOD_DESC,
064: null, null);
065: mv.visitCode();
066: Label l0 = new Label();
067: mv.visitLabel(l0);
068: mv.visitLineNumber(71, l0);
069: mv.visitVarInsn(ALOAD, 0);
070: mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List",
071: "iterator", "()Ljava/util/Iterator;");
072: mv.visitVarInsn(ASTORE, 1);
073: Label l1 = new Label();
074: mv.visitLabel(l1);
075: Label l2 = new Label();
076: mv.visitJumpInsn(GOTO, l2);
077: Label l3 = new Label();
078: mv.visitLabel(l3);
079: mv.visitLineNumber(72, l3);
080: mv.visitVarInsn(ALOAD, 1);
081: mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator",
082: "next", "()Ljava/lang/Object;");
083: mv.visitTypeInsn(CHECKCAST, "java/lang/String");
084: mv.visitVarInsn(ASTORE, 2);
085: Label l4 = new Label();
086: mv.visitLabel(l4);
087: mv.visitLineNumber(73, l4);
088: mv.visitVarInsn(ALOAD, 2);
089: mv.visitLdcInsn(ByteCodeUtil.TC_FIELD_PREFIX);
090: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
091: "startsWith", "(Ljava/lang/String;)Z");
092: mv.visitJumpInsn(IFEQ, l2);
093: Label l5 = new Label();
094: mv.visitLabel(l5);
095: mv.visitLineNumber(74, l5);
096: mv.visitVarInsn(ALOAD, 1);
097: mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator",
098: "remove", "()V");
099: mv.visitLabel(l2);
100: mv.visitLineNumber(71, l2);
101: mv.visitVarInsn(ALOAD, 1);
102: mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator",
103: "hasNext", "()Z");
104: mv.visitJumpInsn(IFNE, l3);
105: Label l6 = new Label();
106: mv.visitLabel(l6);
107: mv.visitLineNumber(78, l6);
108: mv.visitVarInsn(ALOAD, 0);
109: mv.visitInsn(ARETURN);
110: Label l7 = new Label();
111: mv.visitLabel(l7);
112: mv.visitLocalVariable("fields", "Ljava/util/List;", null, l0,
113: l7, 0);
114: mv.visitLocalVariable("iterator", "Ljava/util/Iterator;", null,
115: l1, l6, 1);
116: mv.visitLocalVariable("field", "Ljava/lang/String;", null, l4,
117: l2, 2);
118: mv.visitMaxs(2, 3);
119: mv.visitEnd();
120: }
121:
122: private class GetFieldsAdapter extends MethodAdapter implements
123: Opcodes {
124:
125: public GetFieldsAdapter(MethodVisitor mv) {
126: super (mv);
127: }
128:
129: public void visitInsn(int opcode) {
130: if (ARETURN == opcode) {
131: mv.visitMethodInsn(INVOKESTATIC, thisClassName,
132: REMOVE_TC_FIELDS_METHOD,
133: REMOVE_TC_FIELDS_METHOD_DESC);
134: }
135:
136: super.visitInsn(opcode);
137: }
138: }
139:
140: }
|