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