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 }