View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.transform;
    9
    10  import java.lang.reflect.Modifier;
    11
    12  import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType;
    13
    14  /***
    15   * Utility method used by the transformers.
    16   *
    17   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    18   */
    19  public final class TransformationUtil {
    20
    21      /***
    22       * Return the prefixed clinit method name
    23       *
    24       * @param className
    25       * @return
    26       */
    27      public static String getPrefixedOriginalClinitName(final String className) {
    28          return getPrefixedOriginalMethodName(
    29                  TransformationConstants.STATICINITIALIZER_WRAPPER_METHOD_KEY,//need to not clash with a user method named "clinit"
    30                  className
    31          );
    32      }
    33
    34      /***
    35       * Returns the prefixed method name.
    36       *
    37       * @param methodName the method name
    38       * @param className  the class name
    39       * @return the name of the join point
    40       */
    41      public static String getPrefixedOriginalMethodName(final String methodName,
    42                                                         final String className) {
    43          final StringBuffer buf = new StringBuffer();
    44          buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX);
    45          buf.append(methodName);
    46          buf.append(TransformationConstants.DELIMITER);
    47          buf.append(className.replace('.', '_').replace('/', '_'));
    48          return buf.toString();
    49      }
    50
    51      /***
    52       * Returns the prefixed method name.
    53       *
    54       * @param methodName the method name
    55       * @param methodDesc the method desc
    56       * @param className  the class name
    57       * @return the name of the join point
    58       */
    59      public static String getWrapperMethodName(final String methodName,
    60                                                final String methodDesc,
    61                                                final String className,
    62                                                final String prefix) {
    63          final StringBuffer buf = new StringBuffer();
    64          //FIXME: double check me
    65          // we use the javaC convention for hidden synthetic method
    66          // is the methodSequence enough ?
    67          // [ Alex: looks like it will change between each RW since tied to ctx match ]
    68          buf.append(TransformationConstants.WRAPPER_METHOD_PREFIX);
    69          buf.append(prefix);
    70          buf.append(methodName);
    71          buf.append(methodDesc.hashCode());//??
    72          buf.append(className.replace('.', '_').replace('/', '_'));
    73          return buf.toString().replace('-', '_');
    74      }
    75
    76      /***
    77       * Build the join point invoke method descriptor for code (method or constructor) join points.
    78       * Depends if the target method is static or not.
    79       *
    80       * @param codeModifiers
    81       * @param codeDesc
    82       * @param callerTypeName
    83       * @param calleeTypeName
    84       * @return
    85       */
    86      public static String getInvokeSignatureForCodeJoinPoints(final int codeModifiers,
    87                                                               final String codeDesc,
    88                                                               final String callerTypeName,
    89                                                               final String calleeTypeName) {
    90          StringBuffer sig = new StringBuffer("(");
    91          if (!Modifier.isStatic(codeModifiers)) {
    92              // callee is arg0 for non static target method invoke call
    93              // else it is skept
    94              sig.append('L');
    95              sig.append(calleeTypeName);
    96              sig.append(';');
    97          }
    98          int index = codeDesc.lastIndexOf(')');
    99          sig.append(codeDesc.substring(1, index));
    100         sig.append('L');
    101         sig.append(callerTypeName);
    102         sig.append(';');
    103         sig.append(codeDesc.substring(index, codeDesc.length()));
    104         return sig.toString();
    105     }
    106
    107     /***
    108      * Build the join point invoke method descriptor for field join points.
    109      * Depends if the target field is static or not.
    110      *
    111      * @param fieldModifiers
    112      * @param fieldDesc
    113      * @param callerTypeName
    114      * @param calleeTypeName
    115      * @return the signature
    116      */
    117     public static String getInvokeSignatureForFieldJoinPoints(final int fieldModifiers,
    118                                                               final String fieldDesc,
    119                                                               final String callerTypeName,
    120                                                               final String calleeTypeName) {
    121         StringBuffer sig = new StringBuffer("(");
    122         if (!Modifier.isStatic(fieldModifiers)) {
    123             // callee is arg0 for non static target method invoke call
    124             // else it is skept
    125             sig.append('L');
    126             sig.append(calleeTypeName);
    127             sig.append(';');
    128         }
    129         sig.append(fieldDesc);
    130         sig.append('L');
    131         sig.append(callerTypeName);
    132         sig.append(';');
    133         sig.append(')');
    134         sig.append(fieldDesc);
    135         return sig.toString();
    136     }
    137
    138     /***
    139      * Build the join point invoke method descriptor for handler join points.
    140      * "Exception invoke(Exception, WithinInstance[can be null])"
    141      *
    142      * @param withinTypeName
    143      * @param exceptionTypeName
    144      * @return the signature
    145      */
    146     public static String getInvokeSignatureForHandlerJoinPoints(final String withinTypeName,
    147                                                                 final String exceptionTypeName) {
    148         StringBuffer sig = new StringBuffer("(");
    149         sig.append('L');
    150         sig.append(exceptionTypeName);
    151         sig.append(';');
    152         sig.append('L');//TODO check me [callee + arg0 or just arg0?]
    153         sig.append(exceptionTypeName);
    154         sig.append(';');
    155         sig.append('L');
    156         sig.append(withinTypeName);
    157         sig.append(';');
    158         sig.append(')');
    159         sig.append('L');
    160         sig.append(exceptionTypeName);
    161         sig.append(';');
    162         return sig.toString();
    163     }
    164
    165     /***
    166      * Build the join point invoke method descriptor for ctor call join points.
    167      *
    168      * @param calleeConstructorDesc
    169      * @param callerTypeName
    170      * @param calleeTypeName
    171      * @return the signature
    172      */
    173     public static String getInvokeSignatureForConstructorCallJoinPoints(final String calleeConstructorDesc,
    174                                                                         final String callerTypeName,
    175                                                                         final String calleeTypeName) {
    176         StringBuffer sig = new StringBuffer("(");
    177         int index = calleeConstructorDesc.lastIndexOf(')');
    178         // callee ctor args
    179         sig.append(calleeConstructorDesc.substring(1, index));
    180         // caller
    181         sig.append('L');
    182         sig.append(callerTypeName);
    183         sig.append(';');
    184         sig.append(")L");
    185         sig.append(calleeTypeName);
    186         sig.append(';');
    187         return sig.toString();
    188     }
    189
    190     /***
    191      * Returns the method name used for constructor body
    192      *
    193      * @param calleeTypeName
    194      * @return
    195      */
    196     public static String getConstructorBodyMethodName(final String calleeTypeName) {
    197         final StringBuffer buf = new StringBuffer();
    198         buf.append(TransformationConstants.ORIGINAL_METHOD_PREFIX);
    199         buf.append("init");
    200         buf.append(TransformationConstants.DELIMITER);
    201         buf.append(calleeTypeName.replace('.', '_').replace('/', '_'));
    202         return buf.toString();
    203     }
    204
    205     /***
    206      * Returns the method used for constructor body signature
    207      * The callee type name is prepended to the constructor signature
    208      *
    209      * @param ctorDesc
    210      * @param calleeTypeName
    211      * @return
    212      */
    213     public static String getConstructorBodyMethodSignature(final String ctorDesc, final String calleeTypeName) {
    214         StringBuffer sig = new StringBuffer("(L");
    215         sig.append(calleeTypeName);
    216         sig.append(";");
    217         sig.append(ctorDesc.substring(1));
    218         return sig.toString();
    219     }
    220
    221     /***
    222      * Computes the joinpoint classname : "caller/class_type_hash_suffix"
    223      * For constructor call joinpoints, the hash of callee name is used as well.
    224      *
    225      * @param thisClassName
    226      * @param thisMemberName
    227      * @param thisMemberDesc
    228      * @param targetClassName
    229      * @param joinPointType
    230      * @param joinPointHash
    231      * @return the JIT joinpoint classname
    232      */
    233     public static String getJoinPointClassName(final String thisClassName,
    234                                                final String thisMemberName,
    235                                                final String thisMemberDesc,
    236                                                final String targetClassName,
    237                                                final int joinPointType,
    238                                                final int joinPointHash) {
    239         StringBuffer classNameBuf = new StringBuffer(thisClassName);
    240         // TODO: INNER CLASS OR NOT?
    241 //        classNameBuf.append("$");
    242         classNameBuf.append('_');
    243         classNameBuf.append(joinPointType);
    244         classNameBuf.append('_');
    245         // whithincode support
    246         classNameBuf.append((thisMemberName+thisMemberDesc).hashCode());
    247         classNameBuf.append('_');
    248         classNameBuf.append(joinPointHash);
    249         //FIXME needed for other jp ? f.e. Handler ??
    250         if (joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT || joinPointType == JoinPointType.METHOD_CALL_INT
    251             || joinPointType == JoinPointType.FIELD_GET_INT
    252             || joinPointType == JoinPointType.FIELD_SET_INT
    253         ) {
    254             classNameBuf.append('_').append(targetClassName.hashCode());
    255         }
    256         classNameBuf.append(TransformationConstants.JOIN_POINT_CLASS_SUFFIX);
    257
    258         //replace minus signs on m_joinPointHash
    259         return classNameBuf.toString().replace('-', '_').replace('.', '/');
    260     }
    261
    262 }