1 4 package com.tc.object.bytecode; 5 6 import com.tc.asm.ClassAdapter; 7 import com.tc.asm.ClassVisitor; 8 import com.tc.asm.Label; 9 import com.tc.asm.MethodAdapter; 10 import com.tc.asm.MethodVisitor; 11 import com.tc.asm.Opcodes; 12 13 public class LogicalClassSerializationAdapter implements Opcodes { 14 public static final String SERIALIZATION_OVERRIDE_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX 15 + "isSerializationOverride"; 16 public static final String SERIALIZATION_OVERRIDE_METHOD_DESC = "()Z"; 17 public static final String WRITE_OBJECT_SIGNATURE = "writeObject(Ljava/io/ObjectOutputStream;)V"; 18 public static final String READ_OBJECT_SIGNATURE = "readObject(Ljava/io/ObjectInputStream;)V"; 19 20 public static void addCheckSerializationOverrideMethod(ClassVisitor cv, boolean returnValue) { 21 MethodVisitor mv = cv.visitMethod(ACC_PROTECTED, SERIALIZATION_OVERRIDE_METHOD_NAME, 22 SERIALIZATION_OVERRIDE_METHOD_DESC, null, null); 23 mv.visitCode(); 24 if (returnValue) { 25 mv.visitInsn(ICONST_1); 26 } else { 27 mv.visitInsn(ICONST_0); 28 } 29 mv.visitInsn(IRETURN); 30 mv.visitMaxs(1, 1); 31 mv.visitEnd(); 32 } 33 34 public static void addDelegateFieldWriteObjectCode(MethodVisitor mv, String classNameSlashes, 35 String logicalExtendingClassName, String delegateFieldName) { 36 mv.visitVarInsn(ALOAD, 1); 37 mv.visitVarInsn(ALOAD, 0); 38 mv.visitMethodInsn(INVOKESPECIAL, classNameSlashes, ByteCodeUtil.fieldGetterMethod(delegateFieldName), 39 "()L" + logicalExtendingClassName + ";"); 40 mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/ObjectOutputStream", "writeObject", "(Ljava/lang/Object;)V"); 41 } 42 43 public static void addDelegateFieldReadObjectCode(MethodVisitor mv, String classNameSlashes, 44 String logicalExtendingClassName, String delegateFieldName) { 45 mv.visitVarInsn(ALOAD, 0); 46 mv.visitVarInsn(ALOAD, 1); 47 mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/ObjectInputStream", "readObject", "()Ljava/lang/Object;"); 48 mv.visitTypeInsn(CHECKCAST, logicalExtendingClassName); 49 mv.visitMethodInsn(INVOKESPECIAL, classNameSlashes, ByteCodeUtil.fieldSetterMethod(delegateFieldName), 50 "(L" + logicalExtendingClassName + ";)V"); 51 } 52 53 public static class LogicalClassSerializationMethodAdapter extends MethodAdapter implements Opcodes { 54 private final String classNameSlashes; 55 56 public LogicalClassSerializationMethodAdapter(MethodVisitor mv, String classNameSlashes) { 57 super(mv); 58 this.classNameSlashes = classNameSlashes; 59 } 60 61 public void visitCode() { 62 super.visitCode(); 63 64 mv.visitVarInsn(ALOAD, 0); 65 mv.visitMethodInsn(INVOKEVIRTUAL, classNameSlashes, SERIALIZATION_OVERRIDE_METHOD_NAME, 66 SERIALIZATION_OVERRIDE_METHOD_DESC); 67 Label l1 = new Label(); 68 mv.visitJumpInsn(IFEQ, l1); 69 mv.visitInsn(RETURN); 70 visitLabel(l1); 71 } 72 } 73 74 public static class LogicalSubclassSerializationMethodAdapter extends MethodAdapter implements Opcodes { 75 private final String methodSignature; 76 private final String classNameSlashes; 77 private final String logicalExtendingClassName; 78 private final String delegateFieldName; 79 80 public LogicalSubclassSerializationMethodAdapter(MethodVisitor mv, String methodSignature, String classNameSlashes, 81 String logicalExtendingClassName, String delegateFieldName) { 82 super(mv); 83 this.methodSignature = methodSignature; 84 this.classNameSlashes = classNameSlashes; 85 this.logicalExtendingClassName = logicalExtendingClassName; 86 this.delegateFieldName = delegateFieldName; 87 } 88 89 public void visitCode() { 90 super.visitCode(); 91 if (WRITE_OBJECT_SIGNATURE.equals(methodSignature)) { 92 addDelegateFieldWriteObjectCode(mv, classNameSlashes, logicalExtendingClassName, delegateFieldName); 93 } else if (READ_OBJECT_SIGNATURE.equals(methodSignature)) { 94 addDelegateFieldReadObjectCode(mv, classNameSlashes, logicalExtendingClassName, delegateFieldName); 95 } 96 } 97 } 98 99 public static class LogicalClassSerializationClassAdapter extends ClassAdapter implements Opcodes { 100 private final String classNameSlashes; 101 102 public LogicalClassSerializationClassAdapter(ClassVisitor cv, String className) { 103 super(cv); 104 this.classNameSlashes = className.replace(ChangeClassNameHierarchyAdapter.DOT_DELIMITER, ChangeClassNameHierarchyAdapter.SLASH_DELIMITER); 105 } 106 107 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 108 String methodDesc = name + desc; 109 if (WRITE_OBJECT_SIGNATURE.equals(methodDesc) || READ_OBJECT_SIGNATURE.equals(methodDesc)) { return new LogicalClassSerializationAdapter.LogicalClassSerializationMethodAdapter( 110 super 111 .visitMethod( 112 access, 113 name, 114 desc, 115 signature, 116 exceptions), 117 classNameSlashes); } 118 119 return super.visitMethod(access, name, desc, signature, exceptions); 120 } 121 122 public void visitEnd() { 123 addCheckSerializationOverrideMethod(cv, false); 124 super.visitEnd(); 125 } 126 } 127 128 } 129 | Popular Tags |