001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.bytecode;
005:
006: import com.tc.asm.ClassVisitor;
007: import com.tc.asm.MethodAdapter;
008: import com.tc.asm.MethodVisitor;
009: import com.tc.asm.Opcodes;
010: import com.tc.asm.Type;
011: import com.tc.object.SerializationUtil;
012: import com.tcclient.util.MapEntrySetWrapper;
013:
014: public class TreeMapAdapter {
015:
016: public static class EntrySetAdapter extends AbstractMethodAdapter {
017:
018: public MethodVisitor adapt(ClassVisitor classVisitor) {
019: return new Adapter(visitOriginal(classVisitor));
020: }
021:
022: public boolean doesOriginalNeedAdapting() {
023: return false;
024: }
025:
026: private class Adapter extends MethodAdapter implements Opcodes {
027: public Adapter(MethodVisitor mv) {
028: super (mv);
029: }
030:
031: public void visitMethodInsn(int opcode, String owner,
032: String name, String desc) {
033: super .visitMethodInsn(opcode, owner, name, desc);
034:
035: if ((opcode == INVOKESPECIAL) && "<init>".equals(name)
036: && "java/util/TreeMap$3".equals(owner)) {
037: mv.visitVarInsn(ASTORE, 1);
038: mv.visitTypeInsn(NEW,
039: MapEntrySetWrapper.CLASS_SLASH);
040: mv.visitInsn(DUP);
041: mv.visitVarInsn(ALOAD, 0);
042: mv.visitVarInsn(ALOAD, 1);
043: mv.visitMethodInsn(INVOKESPECIAL,
044: MapEntrySetWrapper.CLASS_SLASH, "<init>",
045: "(Ljava/util/Map;Ljava/util/Set;)V");
046: }
047: }
048: }
049:
050: }
051:
052: public static class DeleteEntryAdapter extends
053: AbstractMethodAdapter {
054:
055: public MethodVisitor adapt(ClassVisitor classVisitor) {
056: return new Adapter(visitOriginal(classVisitor));
057: }
058:
059: public boolean doesOriginalNeedAdapting() {
060: return false;
061: }
062:
063: private class Adapter extends MethodAdapter implements Opcodes {
064: public Adapter(MethodVisitor mv) {
065: super (mv);
066:
067: mv.visitVarInsn(ALOAD, 0);
068: mv.visitLdcInsn(SerializationUtil.REMOVE_KEY_SIGNATURE);
069: mv.visitLdcInsn(new Integer(1));
070: mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
071: mv.visitInsn(DUP);
072: mv.visitLdcInsn(new Integer(0));
073: mv.visitVarInsn(ALOAD, 1);
074: mv.visitMethodInsn(INVOKEVIRTUAL,
075: "java/util/TreeMap$Entry", "getKey",
076: "()Ljava/lang/Object;");
077: mv.visitInsn(AASTORE);
078: managerHelper.callManagerMethod("logicalInvoke", mv);
079: }
080: }
081: }
082:
083: public static class PutAdapter extends AbstractMethodAdapter {
084:
085: public MethodVisitor adapt(ClassVisitor classVisitor) {
086: return new Adapter(visitOriginal(classVisitor));
087: }
088:
089: protected MethodVisitor visitOriginal(ClassVisitor classVisitor) {
090: MethodVisitor mv = super .visitOriginal(classVisitor);
091: mv.visitVarInsn(ALOAD, 0);
092: managerHelper.callManagerMethod("checkWriteAccess", mv);
093:
094: return mv;
095: }
096:
097: public boolean doesOriginalNeedAdapting() {
098: return false;
099: }
100:
101: private class Adapter extends MethodAdapter implements Opcodes {
102:
103: public Adapter(MethodVisitor mv) {
104: super (mv);
105: }
106:
107: public void visitMethodInsn(int opcode, String className,
108: String method, String desc) {
109: super .visitMethodInsn(opcode, className, method, desc);
110:
111: if ((INVOKESPECIAL == opcode)
112: && "<init>".equals(method)
113: && "java/util/TreeMap$Entry".equals(className)) {
114: mv.visitVarInsn(ALOAD, 0);
115: mv.visitLdcInsn(methodName + description);
116: ByteCodeUtil.createParametersToArrayByteCode(mv,
117: Type.getArgumentTypes(description));
118: managerHelper
119: .callManagerMethod("logicalInvoke", mv);
120: }
121:
122: if ((INVOKEVIRTUAL == opcode)
123: && "setValue".equals(method)
124: && "java/util/TreeMap$Entry".equals(className)) {
125: mv.visitInsn(DUP);
126: mv.visitVarInsn(ALOAD, 0);
127: mv.visitLdcInsn(methodName + description);
128: mv.visitLdcInsn(new Integer(2));
129: mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
130: mv.visitInsn(DUP);
131: mv.visitInsn(DUP);
132: mv.visitLdcInsn(new Integer(0));
133: mv.visitVarInsn(ALOAD, 3);
134: mv.visitMethodInsn(INVOKEVIRTUAL,
135: "java/util/TreeMap$Entry", "getKey",
136: "()Ljava/lang/Object;");
137: mv.visitInsn(AASTORE);
138: mv.visitLdcInsn(new Integer(1));
139: mv.visitVarInsn(ALOAD, 2);
140: mv.visitInsn(AASTORE);
141: managerHelper
142: .callManagerMethod("logicalInvoke", mv);
143: }
144:
145: }
146: }
147: }
148: }
|