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;
005:
006: import java.lang.reflect.Modifier;
007:
008: import com.tc.aspectwerkz.joinpoint.management.JoinPointType;
009:
010: /**
011: * Utility method used by the transformers.
012: *
013: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
014: */
015: public final class TransformationUtil {
016:
017: /**
018: * Return the prefixed clinit method name
019: *
020: * @param className
021: * @return
022: */
023: public static String getPrefixedOriginalClinitName(
024: final String className) {
025: return getPrefixedOriginalMethodName(
026: TransformationConstants.STATICINITIALIZER_WRAPPER_METHOD_KEY,//need to not clash with a user method named "clinit"
027: className);
028: }
029:
030: /**
031: * Returns the prefixed method name.
032: *
033: * @param methodName the method name
034: * @param className the class name
035: * @return the name of the join point
036: */
037: public static String getPrefixedOriginalMethodName(
038: final String methodName, final String className) {
039: final StringBuffer buf = new StringBuffer();
040: buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX);
041: buf.append(methodName);
042: buf.append(TransformationConstants.DELIMITER);
043: buf.append(className.replace('.', '_').replace('/', '_'));
044: return buf.toString();
045: }
046:
047: /**
048: * Returns the prefixed method name.
049: *
050: * @param methodName the method name
051: * @param methodDesc the method desc
052: * @param className the class name
053: * @return the name of the join point
054: */
055: public static String getWrapperMethodName(final String methodName,
056: final String methodDesc, final String className,
057: final String prefix) {
058: final StringBuffer buf = new StringBuffer();
059: //FIXME: double check me
060: // we use the javaC convention for hidden synthetic method
061: // is the methodSequence enough ?
062: // [ Alex: looks like it will change between each RW since tied to ctx match ]
063: buf.append(TransformationConstants.WRAPPER_METHOD_PREFIX);
064: buf.append(prefix);
065: buf.append(methodName.replace('<', '$').replace('>', '$'));// can be <init> for ctor wrapping
066: buf.append(methodDesc.hashCode());//??
067: buf.append(className.replace('.', '_').replace('/', '_'));
068: return buf.toString().replace('-', '_');
069: }
070:
071: /**
072: * Build the join point invoke method descriptor for code (method or constructor) join points.
073: * Depends if the target method is static or not.
074: *
075: * @param codeModifiers
076: * @param codeDesc
077: * @param callerTypeName
078: * @param calleeTypeName
079: * @return
080: */
081: public static String getInvokeSignatureForCodeJoinPoints(
082: final int codeModifiers, final String codeDesc,
083: final String callerTypeName, final String calleeTypeName) {
084: StringBuffer sig = new StringBuffer("(");
085: if (!Modifier.isStatic(codeModifiers)) {
086: // callee is arg0 for non static target method invoke call
087: // else it is skept
088: sig.append('L');
089: sig.append(calleeTypeName);
090: sig.append(';');
091: }
092: int index = codeDesc.lastIndexOf(')');
093: sig.append(codeDesc.substring(1, index));
094: sig.append('L');
095: sig.append(callerTypeName);
096: sig.append(';');
097: sig.append(codeDesc.substring(index, codeDesc.length()));
098: return sig.toString();
099: }
100:
101: /**
102: * Build the join point invoke method descriptor for field join points.
103: * Depends if the target field is static or not.
104: *
105: * @param fieldModifiers
106: * @param fieldDesc
107: * @param callerTypeName
108: * @param calleeTypeName
109: * @return the signature
110: */
111: public static String getInvokeSignatureForFieldJoinPoints(
112: final int fieldModifiers, final String fieldDesc,
113: final String callerTypeName, final String calleeTypeName) {
114: StringBuffer sig = new StringBuffer("(");
115: if (!Modifier.isStatic(fieldModifiers)) {
116: // callee is arg0 for non static target method invoke call
117: // else it is skept
118: sig.append('L');
119: sig.append(calleeTypeName);
120: sig.append(';');
121: }
122: sig.append(fieldDesc);
123: sig.append('L');
124: sig.append(callerTypeName);
125: sig.append(';');
126: sig.append(')');
127: sig.append(fieldDesc);
128: return sig.toString();
129: }
130:
131: /**
132: * Build the join point invoke method descriptor for handler join points.
133: * "Exception invoke(Exception, WithinInstance[can be null])"
134: *
135: * @param withinTypeName
136: * @param exceptionTypeName
137: * @return the signature
138: */
139: public static String getInvokeSignatureForHandlerJoinPoints(
140: final String withinTypeName, final String exceptionTypeName) {
141: StringBuffer sig = new StringBuffer("(");
142: sig.append('L');
143: sig.append(exceptionTypeName);
144: sig.append(';');
145: sig.append('L');//TODO check me [callee + arg0 or just arg0?]
146: sig.append(exceptionTypeName);
147: sig.append(';');
148: sig.append('L');
149: sig.append(withinTypeName);
150: sig.append(';');
151: sig.append(')');
152: sig.append('L');
153: sig.append(exceptionTypeName);
154: sig.append(';');
155: return sig.toString();
156: }
157:
158: /**
159: * Build the join point invoke method descriptor for ctor call join points.
160: *
161: * @param calleeConstructorDesc
162: * @param callerTypeName
163: * @param calleeTypeName
164: * @return the signature
165: */
166: public static String getInvokeSignatureForConstructorCallJoinPoints(
167: final String calleeConstructorDesc,
168: final String callerTypeName, final String calleeTypeName) {
169: StringBuffer sig = new StringBuffer("(");
170: int index = calleeConstructorDesc.lastIndexOf(')');
171: // callee ctor args
172: sig.append(calleeConstructorDesc.substring(1, index));
173: // caller
174: sig.append('L');
175: sig.append(callerTypeName);
176: sig.append(';');
177: sig.append(")L");
178: sig.append(calleeTypeName);
179: sig.append(';');
180: return sig.toString();
181: }
182:
183: /**
184: * Returns the method name used for constructor body
185: *
186: * @param calleeTypeName
187: * @return
188: */
189: public static String getConstructorBodyMethodName(
190: final String calleeTypeName) {
191: final StringBuffer buf = new StringBuffer();
192: buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX);
193: buf.append("init");
194: buf.append(TransformationConstants.DELIMITER);
195: buf.append(calleeTypeName.replace('.', '_').replace('/', '_'));
196: return buf.toString();
197: }
198:
199: /**
200: * Returns the method used for constructor body signature
201: * The callee type name is prepended to the constructor signature
202: *
203: * @param ctorDesc
204: * @param calleeTypeName
205: * @return
206: */
207: public static String getConstructorBodyMethodSignature(
208: final String ctorDesc, final String calleeTypeName) {
209: StringBuffer sig = new StringBuffer("(L");
210: sig.append(calleeTypeName);
211: sig.append(";");
212: sig.append(ctorDesc.substring(1));
213: return sig.toString();
214: }
215:
216: /**
217: * Computes the joinpoint classname : "caller/class_type_hash_suffix"
218: * For constructor call joinpoints, the hash of callee name is used as well.
219: *
220: * @param thisClassName
221: * @param thisMemberName
222: * @param thisMemberDesc
223: * @param targetClassName
224: * @param joinPointType
225: * @param joinPointHash
226: * @return the JIT joinpoint classname
227: */
228: public static String getJoinPointClassName(
229: final String this ClassName, final String this MemberName,
230: final String this MemberDesc, final String targetClassName,
231: final int joinPointType, final int joinPointHash) {
232: StringBuffer classNameBuf = new StringBuffer(this ClassName);
233: // TODO: INNER CLASS OR NOT?
234: // classNameBuf.append("$");
235: classNameBuf.append('_');
236: classNameBuf.append(joinPointType);
237: classNameBuf.append('_');
238: // whithincode support
239: classNameBuf.append((this MemberName + this MemberDesc)
240: .hashCode());
241: classNameBuf.append('_');
242: classNameBuf.append(joinPointHash);
243: //FIXME needed for other jp ? f.e. Handler ??
244: if (joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT
245: || joinPointType == JoinPointType.METHOD_CALL_INT
246: || joinPointType == JoinPointType.FIELD_GET_INT
247: || joinPointType == JoinPointType.FIELD_SET_INT) {
248: classNameBuf.append('_').append(targetClassName.hashCode());
249: }
250: classNameBuf
251: .append(TransformationConstants.JOIN_POINT_CLASS_SUFFIX);
252:
253: //replace minus signs on m_joinPointHash
254: return classNameBuf.toString().replace('-', '_').replace('.',
255: '/');
256: }
257:
258: }
|