/************************************************************************************** * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. * * http://aspectwerkz.codehaus.org * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the LGPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package org.codehaus.aspectwerkz.transform; import java.lang.reflect.Modifier; import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType; /** * Utility method used by the transformers. * * @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a> */ public final class TransformationUtil { /** * Return the prefixed clinit method name * * @param className * @return */ public static String getPrefixedOriginalClinitName(final String className) { return getPrefixedOriginalMethodName( TransformationConstants.STATICINITIALIZER_WRAPPER_METHOD_KEY,//need to not clash with a user method named "clinit" className ); } /** * Returns the prefixed method name. * * @param methodName the method name * @param className the class name * @return the name of the join point */ public static String getPrefixedOriginalMethodName(final String methodName, final String className) { final StringBuffer buf = new StringBuffer(); buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX); buf.append(methodName); buf.append(TransformationConstants.DELIMITER); buf.append(className.replace('.', '_').replace('/', '_')); return buf.toString(); } /** * Returns the prefixed method name. * * @param methodName the method name * @param methodDesc the method desc * @param className the class name * @return the name of the join point */ public static String getWrapperMethodName(final String methodName, final String methodDesc, final String className, final String prefix) { final StringBuffer buf = new StringBuffer(); //FIXME: double check me // we use the javaC convention for hidden synthetic method // is the methodSequence enough ? // [ Alex: looks like it will change between each RW since tied to ctx match ] buf.append(TransformationConstants.WRAPPER_METHOD_PREFIX); buf.append(prefix); buf.append(methodName.replace('<', '$').replace('>', '$'));// can be <init> for ctor wrapping buf.append(methodDesc.hashCode());//?? buf.append(className.replace('.', '_').replace('/', '_')); return buf.toString().replace('-', '_'); } /** * Build the join point invoke method descriptor for code (method or constructor) join points. * Depends if the target method is static or not. * * @param codeModifiers * @param codeDesc * @param callerTypeName * @param calleeTypeName * @return */ public static String getInvokeSignatureForCodeJoinPoints(final int codeModifiers, final String codeDesc, final String callerTypeName, final String calleeTypeName) { StringBuffer sig = new StringBuffer("("); if (!Modifier.isStatic(codeModifiers)) { // callee is arg0 for non static target method invoke call // else it is skept sig.append('L'); sig.append(calleeTypeName); sig.append(';'); } int index = codeDesc.lastIndexOf(')'); sig.append(codeDesc.substring(1, index)); sig.append('L'); sig.append(callerTypeName); sig.append(';'); sig.append(codeDesc.substring(index, codeDesc.length())); return sig.toString(); } /** * Build the join point invoke method descriptor for field join points. * Depends if the target field is static or not. * * @param fieldModifiers * @param fieldDesc * @param callerTypeName * @param calleeTypeName * @return the signature */ public static String getInvokeSignatureForFieldJoinPoints(final int fieldModifiers, final String fieldDesc, final String callerTypeName, final String calleeTypeName) { StringBuffer sig = new StringBuffer("("); if (!Modifier.isStatic(fieldModifiers)) { // callee is arg0 for non static target method invoke call // else it is skept sig.append('L'); sig.append(calleeTypeName); sig.append(';'); } sig.append(fieldDesc); sig.append('L'); sig.append(callerTypeName); sig.append(';'); sig.append(')'); sig.append(fieldDesc); return sig.toString(); } /** * Build the join point invoke method descriptor for handler join points. * "Exception invoke(Exception, WithinInstance[can be null])" * * @param withinTypeName * @param exceptionTypeName * @return the signature */ public static String getInvokeSignatureForHandlerJoinPoints(final String withinTypeName, final String exceptionTypeName) { StringBuffer sig = new StringBuffer("("); sig.append('L'); sig.append(exceptionTypeName); sig.append(';'); sig.append('L');//TODO check me [callee + arg0 or just arg0?] sig.append(exceptionTypeName); sig.append(';'); sig.append('L'); sig.append(withinTypeName); sig.append(';'); sig.append(')'); sig.append('L'); sig.append(exceptionTypeName); sig.append(';'); return sig.toString(); } /** * Build the join point invoke method descriptor for ctor call join points. * * @param calleeConstructorDesc * @param callerTypeName * @param calleeTypeName * @return the signature */ public static String getInvokeSignatureForConstructorCallJoinPoints(final String calleeConstructorDesc, final String callerTypeName, final String calleeTypeName) { StringBuffer sig = new StringBuffer("("); int index = calleeConstructorDesc.lastIndexOf(')'); // callee ctor args sig.append(calleeConstructorDesc.substring(1, index)); // caller sig.append('L'); sig.append(callerTypeName); sig.append(';'); sig.append(")L"); sig.append(calleeTypeName); sig.append(';'); return sig.toString(); } /** * Returns the method name used for constructor body * * @param calleeTypeName * @return */ public static String getConstructorBodyMethodName(final String calleeTypeName) { final StringBuffer buf = new StringBuffer(); buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX); buf.append("init"); buf.append(TransformationConstants.DELIMITER); buf.append(calleeTypeName.replace('.', '_').replace('/', '_')); return buf.toString(); } /** * Returns the method used for constructor body signature * The callee type name is prepended to the constructor signature * * @param ctorDesc * @param calleeTypeName * @return */ public static String getConstructorBodyMethodSignature(final String ctorDesc, final String calleeTypeName) { StringBuffer sig = new StringBuffer("(L"); sig.append(calleeTypeName); sig.append(";"); sig.append(ctorDesc.substring(1)); return sig.toString(); } /** * Computes the joinpoint classname : "caller/class_type_hash_suffix" * For constructor call joinpoints, the hash of callee name is used as well. * * @param thisClassName * @param thisMemberName * @param thisMemberDesc * @param targetClassName * @param joinPointType * @param joinPointHash * @return the JIT joinpoint classname */ public static String getJoinPointClassName(final String thisClassName, final String thisMemberName, final String thisMemberDesc, final String targetClassName, final int joinPointType, final int joinPointHash) { StringBuffer classNameBuf = new StringBuffer(thisClassName); // TODO: INNER CLASS OR NOT? // classNameBuf.append("$"); classNameBuf.append('_'); classNameBuf.append(joinPointType); classNameBuf.append('_'); // whithincode support classNameBuf.append((thisMemberName+thisMemberDesc).hashCode()); classNameBuf.append('_'); classNameBuf.append(joinPointHash); //FIXME needed for other jp ? f.e. Handler ?? if (joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT || joinPointType == JoinPointType.METHOD_CALL_INT || joinPointType == JoinPointType.FIELD_GET_INT || joinPointType == JoinPointType.FIELD_SET_INT ) { classNameBuf.append('_').append(targetClassName.hashCode()); } classNameBuf.append(TransformationConstants.JOIN_POINT_CLASS_SUFFIX); //replace minus signs on m_joinPointHash return classNameBuf.toString().replace('-', '_').replace('.', '/'); } }