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.aspectwerkz.aspect.container;
005:
006: import com.tc.asm.Label;
007: import com.tc.asm.MethodVisitor;
008: import com.tc.asm.Type;
009:
010: import com.tc.aspectwerkz.aspect.management.NoAspectBoundException;
011:
012: /**
013: * Factory compiler for perThis perTarget and perInstance (lazy like) models.
014: * All factories rely on HasInstanceLevelAspect interface.
015: *
016: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
017: */
018: public class PerObjectFactoryCompiler extends
019: AbstractAspectFactoryCompiler {
020:
021: public PerObjectFactoryCompiler(String uuid,
022: String aspectClassName, String aspectQualifiedName,
023: String containerClassName, String rawParameters,
024: ClassLoader loader) {
025: super (uuid, aspectClassName, aspectQualifiedName,
026: containerClassName, rawParameters, loader);
027: }
028:
029: protected void createAspectOf() {
030: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC + ACC_STATIC
031: + ACC_FINAL, FACTORY_ASPECTOF_METHOD_NAME,
032: "(Ljava/lang/Object;)" + m_aspectClassSignature, null,
033: null);
034:
035: // instanceOf check
036: cv.visitVarInsn(ALOAD, 0);// object
037: cv.visitTypeInsn(INSTANCEOF,
038: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
039: Label ifInstanceOf = new Label();
040: cv.visitJumpInsn(IFNE, ifInstanceOf);
041: cv.visitTypeInsn(NEW, Type
042: .getInternalName(NoAspectBoundException.class));
043: cv.visitInsn(DUP);
044: cv.visitLdcInsn("Unimplemented interface");
045: cv.visitLdcInsn(m_aspectQualifiedName);
046: cv.visitMethodInsn(INVOKESPECIAL,
047: NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME, INIT_METHOD_NAME,
048: "(Ljava/lang/String;Ljava/lang/String;)V");
049: cv.visitInsn(ATHROW);
050: cv.visitLabel(ifInstanceOf);
051:
052: cv.visitVarInsn(ALOAD, 0);
053: cv.visitTypeInsn(CHECKCAST,
054: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
055: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
056: FACTORY_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
057: cv.visitMethodInsn(INVOKEINTERFACE,
058: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
059: INSTANCE_LEVEL_GETASPECT_METHOD_NAME,
060: INSTANCE_LEVEL_GETASPECT_METHOD_SIGNATURE);
061: cv.visitVarInsn(ASTORE, 1);
062: cv.visitVarInsn(ALOAD, 1);
063: Label ifBound = new Label();
064: cv.visitJumpInsn(IFNONNULL, ifBound);
065: cv.visitTypeInsn(NEW, NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME);
066: cv.visitInsn(DUP);
067: cv.visitLdcInsn("Not bound");
068: cv.visitLdcInsn(m_aspectQualifiedName);
069: cv.visitMethodInsn(INVOKESPECIAL,
070: NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME, INIT_METHOD_NAME,
071: "(Ljava/lang/String;Ljava/lang/String;)V");
072: cv.visitInsn(ATHROW);
073:
074: cv.visitLabel(ifBound);
075: cv.visitVarInsn(ALOAD, 1);
076: cv.visitTypeInsn(CHECKCAST, m_aspectClassName);
077: cv.visitInsn(ARETURN);
078: cv.visitMaxs(0, 0);
079: }
080:
081: protected void createHasAspect() {
082: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
083: FACTORY_HASASPECT_METHOD_NAME, "(Ljava/lang/Object;)Z",
084: null, null);
085:
086: // instanceOf check
087: cv.visitVarInsn(ALOAD, 0);// object
088: cv.visitTypeInsn(INSTANCEOF,
089: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
090: Label ifInstanceOf = new Label();
091: cv.visitJumpInsn(IFNE, ifInstanceOf);
092: cv.visitInsn(ICONST_0);
093: cv.visitInsn(IRETURN);
094: cv.visitLabel(ifInstanceOf);
095:
096: cv.visitVarInsn(ALOAD, 0);
097: cv.visitTypeInsn(CHECKCAST,
098: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
099: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
100: FACTORY_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
101: cv.visitMethodInsn(INVOKEINTERFACE,
102: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
103: INSTANCE_LEVEL_HASASPECT_METHOD_NAME,
104: INSTANCE_LEVEL_HASASPECT_METHOD_SIGNATURE);
105: cv.visitInsn(IRETURN);
106: cv.visitMaxs(0, 0);
107: }
108:
109: protected void createOtherArtifacts() {
110: createBindMethod();
111: }
112:
113: private void createBindMethod() {
114: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC + ACC_STATIC
115: + ACC_FINAL, "bind",
116: "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
117:
118: // instanceOf check
119: cv.visitVarInsn(ALOAD, 0);// object
120: cv.visitTypeInsn(INSTANCEOF,
121: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
122: Label ifInstanceOf = new Label();
123: cv.visitJumpInsn(IFNE, ifInstanceOf);
124: cv.visitTypeInsn(NEW, NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME);
125: cv.visitInsn(DUP);
126: cv.visitLdcInsn("Unimplemented interface");
127: cv.visitLdcInsn(m_aspectQualifiedName);
128: cv.visitMethodInsn(INVOKESPECIAL,
129: NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME, INIT_METHOD_NAME,
130: "(Ljava/lang/String;Ljava/lang/String;)V");
131: cv.visitInsn(ATHROW);
132: cv.visitLabel(ifInstanceOf);
133:
134: cv.visitVarInsn(ALOAD, 0);//object
135: cv.visitTypeInsn(CHECKCAST,
136: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
137: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
138: FACTORY_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
139: cv.visitMethodInsn(INVOKEINTERFACE,
140: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
141: INSTANCE_LEVEL_GETASPECT_METHOD_NAME,
142: INSTANCE_LEVEL_GETASPECT_METHOD_SIGNATURE);
143: cv.visitVarInsn(ASTORE, 1);
144: cv.visitVarInsn(ALOAD, 1);
145: Label ifAlreadyBound = new Label();
146: cv.visitJumpInsn(IFNONNULL, ifAlreadyBound);
147:
148: // target instance and arg0 for bind call
149: cv.visitVarInsn(ALOAD, 0);//object
150: cv.visitTypeInsn(CHECKCAST,
151: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
152: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
153: FACTORY_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
154:
155: if (m_hasAspectContainer) {
156: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
157: FACTORY_CONTAINER_FIELD_NAME,
158: ASPECT_CONTAINER_CLASS_SIGNATURE);
159: cv.visitVarInsn(ALOAD, 0);//associated object
160: cv.visitMethodInsn(INVOKEINTERFACE,
161: ASPECT_CONTAINER_CLASS_NAME,
162: ASPECT_CONTAINER_ASPECTOF_METHOD_NAME,
163: "(Ljava/lang/Object;)Ljava/lang/Object;");
164: cv.visitTypeInsn(CHECKCAST, m_aspectClassName);
165: } else {
166: cv.visitTypeInsn(NEW, m_aspectClassName);
167: cv.visitInsn(DUP);
168: cv.visitMethodInsn(INVOKESPECIAL, m_aspectClassName,
169: INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
170: }
171: cv.visitMethodInsn(INVOKEINTERFACE,
172: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
173: INSTANCE_LEVEL_BINDASPECT_METHOD_NAME,
174: INSTANCE_LEVEL_BINDASPECT_METHOD_SIGNATURE);
175: cv.visitInsn(ARETURN);
176:
177: cv.visitLabel(ifAlreadyBound);
178: cv.visitVarInsn(ALOAD, 1);
179: cv.visitInsn(ARETURN);
180:
181: cv.visitMaxs(0, 0);
182: }
183:
184: public static class PerInstanceFactoryCompiler extends
185: PerObjectFactoryCompiler {
186:
187: public PerInstanceFactoryCompiler(String uuid,
188: String aspectClassName, String aspectQualifiedName,
189: String containerClassName, String rawParameters,
190: ClassLoader loader) {
191: super (uuid, aspectClassName, aspectQualifiedName,
192: containerClassName, rawParameters, loader);
193: }
194:
195: protected void createAspectOf() {
196: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC + ACC_STATIC
197: + ACC_FINAL, FACTORY_ASPECTOF_METHOD_NAME,
198: "(Ljava/lang/Object;)" + m_aspectClassSignature,
199: null, null);
200:
201: // instanceOf check
202: cv.visitVarInsn(ALOAD, 0);// object
203: cv.visitTypeInsn(INSTANCEOF,
204: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
205: Label ifInstanceOf = new Label();
206: cv.visitJumpInsn(IFNE, ifInstanceOf);
207: cv.visitTypeInsn(NEW, Type
208: .getInternalName(NoAspectBoundException.class));
209: cv.visitInsn(DUP);
210: cv.visitLdcInsn("Unimplemented interface");
211: cv.visitLdcInsn(m_aspectQualifiedName);
212: cv.visitMethodInsn(INVOKESPECIAL,
213: NO_ASPECT_BOUND_EXCEPTION_CLASS_NAME,
214: INIT_METHOD_NAME,
215: "(Ljava/lang/String;Ljava/lang/String;)V");
216: cv.visitInsn(ATHROW);
217: cv.visitLabel(ifInstanceOf);
218:
219: cv.visitVarInsn(ALOAD, 0);
220: cv.visitTypeInsn(CHECKCAST,
221: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME);
222: cv.visitFieldInsn(GETSTATIC, m_aspectFactoryClassName,
223: FACTORY_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
224: cv.visitMethodInsn(INVOKEINTERFACE,
225: HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
226: INSTANCE_LEVEL_GETASPECT_METHOD_NAME,
227: INSTANCE_LEVEL_GETASPECT_METHOD_SIGNATURE);
228: cv.visitVarInsn(ASTORE, 1);
229: cv.visitVarInsn(ALOAD, 1);
230: Label ifBound = new Label();
231: cv.visitJumpInsn(IFNONNULL, ifBound);
232: // no aspect bound yet - since perInstance is lazy delegate to bind
233: cv.visitVarInsn(ALOAD, 0);
234: cv.visitMethodInsn(INVOKESTATIC, m_aspectFactoryClassName,
235: "bind", "(Ljava/lang/Object;)Ljava/lang/Object;");
236: cv.visitVarInsn(ASTORE, 1);
237: cv.visitLabel(ifBound);
238: cv.visitVarInsn(ALOAD, 1);
239: cv.visitTypeInsn(CHECKCAST, m_aspectClassName);
240: cv.visitInsn(ARETURN);
241: cv.visitMaxs(0, 0);
242: }
243: }
244: }
|