001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package org.terracotta.modules.iBatis_2_2_0;
005:
006: import com.tc.asm.ClassAdapter;
007: import com.tc.asm.ClassVisitor;
008: import com.tc.asm.Label;
009: import com.tc.asm.MethodAdapter;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.object.bytecode.ClassAdapterFactory;
013:
014: public class IBatisClassAdapter extends ClassAdapter implements
015: Opcodes, ClassAdapterFactory {
016: private final static String SQLMAPCLIENT_CLASS_SLASHES = "com/ibatis/sqlmap/engine/impl/SqlMapClientImpl";
017: private final static String SIMPLEDATASOURCE_CLASS_SLASHES = "com/ibatis/common/jdbc/SimpleDataSource";
018: private String classNameSlashes;
019:
020: public IBatisClassAdapter() {
021: super (null);
022: }
023:
024: public IBatisClassAdapter(ClassVisitor cv) {
025: super (cv);
026: }
027:
028: public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) {
029: return new IBatisClassAdapter(visitor);
030: }
031:
032: public void visit(int version, int access, String name,
033: String signature, String super Name, String[] interfaces) {
034: super .visit(version, access, name, signature, super Name,
035: interfaces);
036: this .classNameSlashes = name;
037: }
038:
039: public MethodVisitor visitMethod(int access, String name,
040: String desc, String signature, String[] exceptions) {
041: MethodVisitor mv = super .visitMethod(access, name, desc,
042: signature, exceptions);
043: if (SIMPLEDATASOURCE_CLASS_SLASHES.equals(classNameSlashes)) {
044: if ("popConnection".equals(name)
045: && "(Ljava/lang/String;Ljava/lang/String;)Lcom/ibatis/common/jdbc/SimpleDataSource$SimplePooledConnection;"
046: .equals(desc)) {
047: mv = new PopConnectionMethodAdapter(mv);
048: }
049: }
050: return mv;
051: }
052:
053: public void visitEnd() {
054: if (SQLMAPCLIENT_CLASS_SLASHES.equals(classNameSlashes)) {
055: addSqlMapClientDefaultConstructor();
056: } else if (SIMPLEDATASOURCE_CLASS_SLASHES
057: .equals(classNameSlashes)) {
058: addSimpleDataSourceConstructor();
059: }
060: super .visitEnd();
061: }
062:
063: private void addSimpleDataSourceConstructor() {
064: MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V",
065: null, null);
066: mv.visitCode();
067: Label l0 = new Label();
068: mv.visitLabel(l0);
069: mv.visitLineNumber(115, l0);
070: mv.visitVarInsn(ALOAD, 0);
071: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>",
072: "()V");
073: Label l1 = new Label();
074: mv.visitLabel(l1);
075: mv.visitLineNumber(78, l1);
076: mv.visitVarInsn(ALOAD, 0);
077: mv.visitTypeInsn(NEW, "java/lang/Object");
078: mv.visitInsn(DUP);
079: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>",
080: "()V");
081: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
082: "POOL_LOCK", "Ljava/lang/Object;");
083: Label l2 = new Label();
084: mv.visitLabel(l2);
085: mv.visitLineNumber(79, l2);
086: mv.visitVarInsn(ALOAD, 0);
087: mv.visitTypeInsn(NEW, "java/util/ArrayList");
088: mv.visitInsn(DUP);
089: mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList",
090: "<init>", "()V");
091: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
092: "idleConnections", "Ljava/util/List;");
093: Label l3 = new Label();
094: mv.visitLabel(l3);
095: mv.visitLineNumber(80, l3);
096: mv.visitVarInsn(ALOAD, 0);
097: mv.visitTypeInsn(NEW, "java/util/ArrayList");
098: mv.visitInsn(DUP);
099: mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList",
100: "<init>", "()V");
101: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
102: "activeConnections", "Ljava/util/List;");
103: Label l4 = new Label();
104: mv.visitLabel(l4);
105: mv.visitLineNumber(81, l4);
106: mv.visitVarInsn(ALOAD, 0);
107: mv.visitInsn(LCONST_0);
108: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
109: "requestCount", "J");
110: Label l5 = new Label();
111: mv.visitLabel(l5);
112: mv.visitLineNumber(82, l5);
113: mv.visitVarInsn(ALOAD, 0);
114: mv.visitInsn(LCONST_0);
115: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
116: "accumulatedRequestTime", "J");
117: Label l6 = new Label();
118: mv.visitLabel(l6);
119: mv.visitLineNumber(83, l6);
120: mv.visitVarInsn(ALOAD, 0);
121: mv.visitInsn(LCONST_0);
122: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
123: "accumulatedCheckoutTime", "J");
124: Label l7 = new Label();
125: mv.visitLabel(l7);
126: mv.visitLineNumber(84, l7);
127: mv.visitVarInsn(ALOAD, 0);
128: mv.visitInsn(LCONST_0);
129: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
130: "claimedOverdueConnectionCount", "J");
131: Label l8 = new Label();
132: mv.visitLabel(l8);
133: mv.visitLineNumber(85, l8);
134: mv.visitVarInsn(ALOAD, 0);
135: mv.visitInsn(LCONST_0);
136: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
137: "accumulatedCheckoutTimeOfOverdueConnections", "J");
138: Label l9 = new Label();
139: mv.visitLabel(l9);
140: mv.visitLineNumber(86, l9);
141: mv.visitVarInsn(ALOAD, 0);
142: mv.visitInsn(LCONST_0);
143: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
144: "accumulatedWaitTime", "J");
145: Label l10 = new Label();
146: mv.visitLabel(l10);
147: mv.visitLineNumber(87, l10);
148: Label l11 = new Label();
149: mv.visitLabel(l11);
150: mv.visitLineNumber(88, l11);
151: mv.visitVarInsn(ALOAD, 0);
152: mv.visitInsn(LCONST_0);
153: mv.visitFieldInsn(PUTFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
154: "badConnectionCount", "J");
155: Label l12 = new Label();
156: mv.visitLabel(l12);
157: mv.visitLineNumber(116, l12);
158: Label l13 = new Label();
159: mv.visitLabel(l13);
160: mv.visitLineNumber(117, l13);
161: mv.visitInsn(RETURN);
162: Label l14 = new Label();
163: mv.visitLabel(l14);
164: mv.visitMaxs(0, 0);
165: mv.visitEnd();
166: }
167:
168: private void addSqlMapClientDefaultConstructor() {
169: MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V",
170: null, null);
171: mv.visitCode();
172: Label l0 = new Label();
173: mv.visitLabel(l0);
174: mv.visitLineNumber(55, l0);
175: mv.visitVarInsn(ALOAD, 0);
176: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>",
177: "()V");
178: Label l1 = new Label();
179: mv.visitLabel(l1);
180: mv.visitLineNumber(48, l1);
181: mv.visitVarInsn(ALOAD, 0);
182: mv.visitTypeInsn(NEW, "java/lang/ThreadLocal");
183: mv.visitInsn(DUP);
184: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/ThreadLocal",
185: "<init>", "()V");
186: mv.visitFieldInsn(PUTFIELD, SQLMAPCLIENT_CLASS_SLASHES,
187: "localSqlMapSession", "Ljava/lang/ThreadLocal;");
188: Label l2 = new Label();
189: mv.visitLabel(l2);
190: mv.visitLineNumber(56, l2);
191: Label l3 = new Label();
192: mv.visitLabel(l3);
193: mv.visitLineNumber(57, l3);
194: mv.visitInsn(RETURN);
195: Label l4 = new Label();
196: mv.visitLabel(l4);
197: mv.visitMaxs(0, 0);
198: mv.visitEnd();
199: }
200:
201: private static class PopConnectionMethodAdapter extends
202: MethodAdapter implements Opcodes {
203: public PopConnectionMethodAdapter(MethodVisitor mv) {
204: super (mv);
205: }
206:
207: public void visitCode() {
208: super .visitCode();
209: mv.visitVarInsn(ALOAD, 0);
210: mv.visitFieldInsn(GETFIELD, SIMPLEDATASOURCE_CLASS_SLASHES,
211: "jdbcDriver", "Ljava/lang/String;");
212: mv.visitMethodInsn(INVOKESTATIC,
213: "com/ibatis/common/resources/Resources",
214: "instantiate",
215: "(Ljava/lang/String;)Ljava/lang/Object;");
216: mv.visitInsn(POP);
217: }
218: }
219: }
|