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.transform.inlining.spi;
005:
006: import com.tc.asm.ClassWriter;
007: import com.tc.asm.MethodVisitor;
008: import com.tc.asm.Type;
009: import com.tc.asm.ClassVisitor;
010:
011: import com.tc.aspectwerkz.definition.AspectDefinition;
012: import com.tc.aspectwerkz.transform.JoinPointCompiler;
013: import com.tc.aspectwerkz.transform.inlining.AdviceMethodInfo;
014: import com.tc.aspectwerkz.transform.inlining.AspectInfo;
015: import com.tc.aspectwerkz.transform.inlining.compiler.CompilationInfo;
016: import com.tc.aspectwerkz.transform.inlining.compiler.CompilerInput;
017: import com.tc.aspectwerkz.reflect.ClassInfo;
018:
019: /**
020: * An aspect model defines a custom hook for the JoinPointCompiler.
021: * <p/>
022: * The AspectModel is registered using AspectModelManager, and the AspectDefinition is linked to the model
023: * "getAspectModelType()" unique identifier.
024: * <p/>
025: * An no arg constructor instance of the model will be callback during aspect registration for defineAspect(..)
026: * </p>
027: * During compilation, different aspect model instance can be instantiated per compilation using the getInstance(..)
028: * method (not returning "this").
029: *
030: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
031: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
032: */
033: public interface AspectModel {
034:
035: /**
036: * A prototype patttern. Ones may return "this" if singleton / non thread safe instance is enough.
037: *
038: * @param compilationModel
039: * @return
040: */
041: AspectModel getInstance(CompilationInfo.Model compilationModel);
042:
043: /**
044: * Returns the aspect model type, which is an id for the the special aspect model, can be anything as long
045: * as it is unique.
046: *
047: * @return the aspect model type id
048: */
049: String getAspectModelType();
050:
051: /**
052: * Defines the aspect and adds definition to the aspect definition.
053: *
054: * @param aspectClassInfo
055: * @param aspectDef
056: * @param loader
057: */
058: void defineAspect(ClassInfo aspectClassInfo,
059: AspectDefinition aspectDef, ClassLoader loader);
060:
061: /**
062: * Returns info about the closure class, name and type (interface or class).
063: *
064: * @return the closure class info
065: */
066: AroundClosureClassInfo getAroundClosureClassInfo();
067:
068: /**
069: * Creates the methods required to implement or extend to implement the closure for the specific aspect model type.
070: *
071: * @param cw
072: * @param compiler
073: */
074: void createMandatoryMethods(ClassWriter cw,
075: JoinPointCompiler compiler);
076:
077: /**
078: * Creates invocation of the super class for the around closure.
079: * <p/>
080: * E.g. the invocation of super(..) in the constructor.
081: * <p/>
082: * Only needed to be implemented if the around closure base class is really a base class and not an interface.
083: *
084: * @param cv
085: */
086: void createInvocationOfAroundClosureSuperClass(MethodVisitor cv);
087:
088: /**
089: * Creates aspect reference field (field in the jit jointpoint class f.e.) for an aspect instance.
090: * Creates instantiation of an aspect instance and stores them if appropriate (see createAspectReferenceField).
091: *
092: * @param cw for the jp class beeing compiled
093: * @param cv for the <clinit> method
094: * @param aspectInfo
095: * @param joinPointClassName
096: */
097: void createAndStoreStaticAspectInstantiation(ClassVisitor cw,
098: MethodVisitor cv, AspectInfo aspectInfo,
099: String joinPointClassName);
100:
101: /**
102: * Initializes instance level aspects, retrieves them from the target instance through the
103: * <code>HasInstanceLevelAspect</code> interfaces.
104: * <p/>
105: * Use by 'perInstance', 'perThis' and 'perTarget' deployment models.
106: *
107: * @param cv
108: * @param input
109: * @param aspectInfo
110: */
111: void createAndStoreRuntimeAspectInstantiation(
112: final MethodVisitor cv, final CompilerInput input,
113: final AspectInfo aspectInfo);
114:
115: /**
116: * Loads the aspect instance on stack.
117: * See loadJoinPointInstance(..) and
118: *
119: * @param cv
120: * @param aspectInfo
121: */
122: void loadAspect(final MethodVisitor cv, final CompilerInput input,
123: final AspectInfo aspectInfo);
124:
125: /**
126: * Handles the arguments to the around advice.
127: *
128: * @param cv
129: * @param adviceMethodInfo
130: */
131: void createAroundAdviceArgumentHandling(MethodVisitor cv,
132: CompilerInput input, Type[] joinPointArgumentTypes,
133: AdviceMethodInfo adviceMethodInfo);
134:
135: /**
136: * Handles the arguments to the before or after (after XXX) advice.
137: *
138: * @param cv
139: * @param input
140: * @param joinPointArgumentTypes
141: * @param adviceMethodInfo
142: * @param specialArgIndex index on the stack of the throwned exception / returned value (makes sense for after advice,
143: * else set to INDEX_NOTAVAILABLE)
144: */
145: public void createBeforeOrAfterAdviceArgumentHandling(
146: MethodVisitor cv, CompilerInput input,
147: Type[] joinPointArgumentTypes,
148: AdviceMethodInfo adviceMethodInfo, int specialArgIndex);
149:
150: /**
151: * Should return true if the aspect model requires that Runtime Type Information (RTTI) is build up
152: * for the join point. Needed for reflective systems and systems that does not support f.e. args() binding.
153: *
154: * @return
155: */
156: boolean requiresReflectiveInfo();
157:
158: /**
159: * Info about the around closure class or interface for this specific aspect model.
160: *
161: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
162: */
163: public static class AroundClosureClassInfo {
164:
165: private final String m_super ClassName;
166:
167: private final String[] m_interfaceNames;
168:
169: public AroundClosureClassInfo(final String super ClassName,
170: final String[] interfaceNames) {
171: if (super ClassName != null) {
172: m_super ClassName = super ClassName.replace('.', '/');
173: } else {
174: m_super ClassName = null;
175: }
176: m_interfaceNames = new String[interfaceNames.length];
177: for (int i = 0; i < interfaceNames.length; i++) {
178: m_interfaceNames[i] = interfaceNames[i].replace('.',
179: '/');
180: }
181: }
182:
183: public String getSuperClassName() {
184: return m_super ClassName;
185: }
186:
187: public String[] getInterfaceNames() {
188: return m_interfaceNames;
189: }
190:
191: /**
192: * Type safe enum for the around closure class type.
193: */
194: public static class Type {
195: public static final Type INTERFACE = new Type("INTERFACE");
196: public static final Type CLASS = new Type("CLASS");
197: private final String m_name;
198:
199: private Type(String name) {
200: m_name = name;
201: }
202:
203: public String toString() {
204: return m_name;
205: }
206: }
207:
208: }
209: }
|