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.aspect.management;
9   
10  import gnu.trove.TIntObjectHashMap;
11  import gnu.trove.TObjectIntHashMap;
12  import org.codehaus.aspectwerkz.ConstructorTuple;
13  import org.codehaus.aspectwerkz.CrossCuttingInfo;
14  import org.codehaus.aspectwerkz.AdviceInfo;
15  import org.codehaus.aspectwerkz.MethodTuple;
16  import org.codehaus.aspectwerkz.Mixin;
17  import org.codehaus.aspectwerkz.joinpoint.management.JoinPointManager;
18  import org.codehaus.aspectwerkz.aspect.AspectContainer;
19  import org.codehaus.aspectwerkz.aspect.Introduction;
20  import org.codehaus.aspectwerkz.aspect.IntroductionContainer;
21  import org.codehaus.aspectwerkz.definition.AdviceDefinition;
22  import org.codehaus.aspectwerkz.definition.IntroductionDefinition;
23  import org.codehaus.aspectwerkz.definition.StartupManager;
24  import org.codehaus.aspectwerkz.definition.SystemDefinition;
25  import org.codehaus.aspectwerkz.exception.DefinitionException;
26  import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
27  import org.codehaus.aspectwerkz.expression.ExpressionContext;
28  import org.codehaus.aspectwerkz.transform.ReflectHelper;
29  import org.codehaus.aspectwerkz.transform.TransformationUtil;
30  import org.codehaus.aspectwerkz.transform.TransformationConstants;
31  import org.codehaus.aspectwerkz.util.SequencedHashMap;
32  import org.codehaus.aspectwerkz.util.Strings;
33  
34  import java.lang.reflect.Constructor;
35  import java.lang.reflect.Field;
36  import java.lang.reflect.Method;
37  import java.util.ArrayList;
38  import java.util.Collection;
39  import java.util.HashMap;
40  import java.util.Iterator;
41  import java.util.List;
42  import java.util.Map;
43  
44  /***
45   * Stores the aspects, advices, pointcuts etc. Manages the method, advice and aspect indexing.
46   * 
47   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
48   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
49   * @TODO Use hashes, aspect=>hashcode for class advice=>hashcode for method signature
50   * @TODO Store references to all join points that uses advices from a certain aspect [aspectKey=>joinPoints]
51   * @TODO Map all aspects to a key, meaning have a key that maps to a data structure that contains full info about the
52   *       aspect and all its advice methods. [aspectKey=>aspectDataStructure].
53   */
54  public class AspectRegistry {
55      /***
56       * Holds references to the methods to the advised classes in the system.
57       */
58      private final static Map s_methods = new HashMap(); //WEAK
59  
60      /***
61       * Holds references to the fields to the advised classes in the system.
62       */
63      private final static Map s_fields = new HashMap();
64  
65      /***
66       * Holds references to all the the advised constructors in the system, maps the target Class to a sorted list of all
67       * the advised constructors in the class.
68       */
69      private final static Map s_constructors = new HashMap();
70  
71      /***
72       * The AspectManager for the system.
73       */
74      private final AspectManager m_aspectManager;
75  
76      /***
77       * The definition.
78       */
79      private final SystemDefinition m_definition;
80  
81      /***
82       * Marks the system as initialized.
83       */
84      private boolean m_initialized = false;
85  
86      /***
87       * Sorted map with PointcutManager instance containing the pointcut instance the aspect, mapped to its name (the
88       * name of the class implementing the aspect).
89       */
90      private final Map m_pointcutManagerMap = new SequencedHashMap();
91  
92      /***
93       * Holds the indexes for the aspects, maps the aspect name to the index for the aspect.
94       */
95      private final TObjectIntHashMap m_aspectIndexes = new TObjectIntHashMap();
96  
97      /***
98       * Holds the index (a tuple of the aspect index and the advice index) for the advices, mapped to its name
99       * ([fullyQualifiedClassName].[methodName]).
100      */
101     private final Map m_adviceIndexes = new HashMap();
102 
103     /***
104      * An array with all the the aspect containers in the system.
105      */
106     private AspectContainer[] m_aspectContainers = new AspectContainer[0];
107 
108     /***
109      * An array of all the mixins in the system, each nested class in aspect has its own index.
110      */
111     private Mixin[] m_mixins = new Mixin[0];
112 
113     /***
114      * Creates a new aspect registry.
115      * 
116      * @param aspectManager the system aspectManager
117      * @param definition the system definition
118      */
119     public AspectRegistry(final AspectManager aspectManager, final SystemDefinition definition) {
120         m_aspectManager = aspectManager;
121         m_definition = definition;
122     }
123 
124     /***
125      * Initializes the aspect registry. The initialization needs to be separated fromt he construction of the registry,
126      * and is triggered by the runtime system.
127      */
128     public void initialize() {
129         synchronized (this) {
130             if (m_initialized) {
131                 return;
132             }
133             m_initialized = true;
134             StartupManager.initializeSystem(m_aspectManager, m_definition);
135         }
136     }
137 
138     /***
139      * Registers a new aspect.
140      * 
141      * @param aspectContainer the aspectContainer for the aspect to register
142      * @param pointcutManager the pointcut manager
143      */
144     public void register(final AspectContainer aspectContainer, final PointcutManager pointcutManager) {
145         if (aspectContainer == null) {
146             throw new IllegalArgumentException("aspect aspectContainer can not be null");
147         }
148         if (pointcutManager == null) {
149             throw new IllegalArgumentException("pointcut manager can not be null");
150         }
151         synchronized (m_aspectContainers) {
152             synchronized (m_aspectIndexes) {
153                 synchronized (m_adviceIndexes) {
154                     synchronized (m_mixins) {
155                         synchronized (m_pointcutManagerMap) {
156                             try {
157                                 CrossCuttingInfo crossCuttingInfo = aspectContainer.getCrossCuttingInfo();
158                                 m_pointcutManagerMap.put(crossCuttingInfo.getName(), pointcutManager);
159                                 final int indexAspect = m_aspectContainers.length + 1;
160                                 m_aspectIndexes.put(crossCuttingInfo.getName(), indexAspect);
161                                 final Object[] tmpAspects = new Object[m_aspectContainers.length + 1];
162                                 java.lang.System.arraycopy(
163                                     m_aspectContainers,
164                                     0,
165                                     tmpAspects,
166                                     0,
167                                     m_aspectContainers.length);
168                                 tmpAspects[m_aspectContainers.length] = aspectContainer;
169                                 m_aspectContainers = new AspectContainer[m_aspectContainers.length + 1];
170                                 java.lang.System.arraycopy(tmpAspects, 0, m_aspectContainers, 0, tmpAspects.length);
171 
172                                 // retrieve a sorted advices list => matches the sorted method list
173                                 // in the
174                                 // aspectContainer
175                                 List advices = crossCuttingInfo.getAspectDefinition().getAllAdvices();
176                                 for (Iterator it = advices.iterator(); it.hasNext();) {
177                                     final AdviceDefinition adviceDef = (AdviceDefinition) it.next();
178                                     AdviceInfo tuple = new AdviceInfo(
179                                         indexAspect,
180                                         adviceDef.getMethodIndex(),
181                                         m_aspectManager,
182                                         adviceDef.getType(),
183                                         adviceDef.getSpecialArgumentType());
184 
185                                     //prefix AdviceName with AspectName to allow AspectReuse
186                                     m_adviceIndexes.put(crossCuttingInfo.getName() + "/" + adviceDef.getName(), tuple);
187                                 }
188 
189                                 // mixins
190                                 List introductions = crossCuttingInfo.getAspectDefinition().getIntroductions();
191 
192                                 for (Iterator it = introductions.iterator(); it.hasNext();) {
193                                     IntroductionDefinition introDef = (IntroductionDefinition) it.next();
194 
195                                     // load default mixinPrototype impl from the aspect which
196                                     // defines it
197                                     Class defaultImplClass = crossCuttingInfo.getAspectClass().getClassLoader()
198                                             .loadClass(introDef.getName());
199 
200                                     Introduction mixinPrototype = new Introduction(
201                                         introDef.getName(),
202                                         defaultImplClass,
203                                         crossCuttingInfo,
204                                         introDef);
205                                     IntroductionContainer introductionContainer = new IntroductionContainer(
206                                         mixinPrototype,
207                                         aspectContainer);
208                                     aspectContainer.addIntroductionContainer(introDef.getName(), introductionContainer);
209 
210                                     // prepare the aspectContainer
211                                     mixinPrototype.setContainer(introductionContainer);
212                                     final Mixin[] tmpMixins = new Mixin[m_mixins.length + 1];
213                                     java.lang.System.arraycopy(m_mixins, 0, tmpMixins, 0, m_mixins.length);
214                                     tmpMixins[m_mixins.length] = mixinPrototype;
215                                     m_mixins = new Mixin[m_mixins.length + 1];
216                                     java.lang.System.arraycopy(tmpMixins, 0, m_mixins, 0, tmpMixins.length);
217                                 }
218                             } catch (Exception e) {
219                                 e.printStackTrace();
220                                 throw new DefinitionException("could not register aspect ["
221                                     + aspectContainer.getCrossCuttingInfo().getName()
222                                     + "] due to: "
223                                     + e.toString());
224                             }
225                             if (m_aspectContainers.length != m_aspectIndexes.size()) {
226                                 throw new IllegalStateException("aspect indexing out of synch");
227                             }
228                         }
229                     }
230                 }
231             }
232         }
233     }
234 
235     /***
236      * Retrieves a specific aspect container based on index.
237      * 
238      * @param index the index of the aspect
239      * @return the aspect container
240      */
241     public AspectContainer getAspectContainer(final int index) {
242         AspectContainer aspect;
243         try {
244             aspect = m_aspectContainers[index - 1];
245         } catch (Throwable e) {
246             initialize();
247             try {
248                 aspect = m_aspectContainers[index - 1];
249             } catch (ArrayIndexOutOfBoundsException e1) {
250                 throw new DefinitionException("no aspect with index " + index);
251             }
252         }
253         return aspect;
254     }
255 
256     /***
257      * Returns the aspect container for a specific name.
258      * 
259      * @param name the name of the aspect
260      * @return the the aspect container
261      */
262     public AspectContainer getAspectContainer(final String name) {
263         AspectContainer container;
264         try {
265             container = m_aspectContainers[m_aspectIndexes.get(name) - 1];
266         } catch (Throwable e1) {
267             initialize();
268             try {
269                 container = m_aspectContainers[m_aspectIndexes.get(name) - 1];
270             } catch (ArrayIndexOutOfBoundsException e2) {
271                 throw new DefinitionException("container for cross-cutting class ["
272                     + name
273                     + "] is not properly defined");
274             }
275         }
276         return container;
277     }
278 
279     /***
280      * Returns the aspect for a specific name, deployed as perJVM.
281      * 
282      * @param name the name of the aspect
283      * @return the the aspect
284      */
285     public CrossCuttingInfo getCrossCuttingInfo(final String name) {
286         return getAspectContainer(name).getCrossCuttingInfo();
287     }
288 
289     /***
290      * Retrieves a specific mixin based on its index.
291      * 
292      * @param index the index of the introduction (aspect in this case)
293      * @return the the mixin (aspect in this case)
294      */
295     public Mixin getMixin(final int index) {
296         Mixin mixin;
297         try {
298             mixin = m_mixins[index - 1];
299         } catch (Throwable e1) {
300             initialize();
301             try {
302                 mixin = m_mixins[index - 1];
303             } catch (ArrayIndexOutOfBoundsException e2) {
304                 throw new DefinitionException("no mixin with index " + index);
305             }
306         }
307         return mixin;
308     }
309 
310     /***
311      * Returns the mixin implementation for a specific name.
312      * 
313      * @param name the name of the introduction (aspect in this case)
314      * @return the the mixin (aspect in this case)
315      */
316     public Mixin getMixin(final String name) {
317         if (name == null) {
318             throw new IllegalArgumentException("introduction name can not be null");
319         }
320         Mixin introduction;
321         try {
322             introduction = m_mixins[m_definition.getMixinIndexByName(name) - 1];
323         } catch (Throwable e1) {
324             initialize();
325             try {
326                 introduction = m_mixins[m_definition.getMixinIndexByName(name) - 1];
327             } catch (ArrayIndexOutOfBoundsException e2) {
328                 throw new DefinitionException("no introduction with name " + name);
329             }
330         }
331         return introduction;
332     }
333 
334     /***
335      * Returns the index for a specific name to aspect mapping.
336      * 
337      * @param name the name of the aspect
338      * @return the index of the aspect
339      */
340     public int getAspectIndexFor(final String name) {
341         if (name == null) {
342             throw new IllegalArgumentException("aspect name can not be null");
343         }
344         final int index = m_aspectIndexes.get(name);
345         if (index == 0) {
346             throw new DefinitionException("aspect " + name + " is not properly defined");
347         }
348         return index;
349     }
350 
351     /***
352      * Returns the index for a specific name to advice mapping.
353      * 
354      * @param name the name of the advice
355      * @return the index of the advice
356      */
357     public AdviceInfo getAdviceIndexFor(final String name) {
358         if (name == null) {
359             throw new IllegalArgumentException("advice name can not be null");
360         }
361         final AdviceInfo index = (AdviceInfo) m_adviceIndexes.get(name);
362         if (index == null) {
363             throw new DefinitionException("advice " + name + " is not properly defined");
364         }
365         return index;
366     }
367 
368     /***
369      * Returns the pointcut managers for the name specified.
370      * 
371      * @param name the name of the aspect
372      * @return the pointcut manager
373      */
374     public PointcutManager getPointcutManager(final String name) {
375         if (name == null) {
376             throw new IllegalArgumentException("aspect name can not be null");
377         }
378         if (m_pointcutManagerMap.containsKey(name)) {
379             return (PointcutManager) m_pointcutManagerMap.get(name);
380         } else {
381             initialize();
382             if (m_pointcutManagerMap.containsKey(name)) {
383                 return (PointcutManager) m_pointcutManagerMap.get(name);
384             } else {
385                 throw new DefinitionException("aspect " + name + " is not properly defined");
386             }
387         }
388     }
389 
390     /***
391      * Returns a list with all the pointcut managers.
392      * 
393      * @return the pointcut managers
394      */
395     public Collection getPointcutManagers() {
396         initialize();
397         return m_pointcutManagerMap.values();
398     }
399 
400     /***
401      * Returns an array with all the aspect containers.
402      * 
403      * @return the aspect containers
404      */
405     public AspectContainer[] getAspectContainers() {
406         initialize();
407         return m_aspectContainers;
408     }
409 
410     /***
411      * Returns the pointcut list for the context specified.
412      * 
413      * @param ctx the expression context
414      * @return the pointcuts for this join point
415      */
416     public List getPointcuts(final ExpressionContext ctx) {
417         List pointcuts = new ArrayList();
418         for (Iterator it = m_pointcutManagerMap.values().iterator(); it.hasNext();) {
419             PointcutManager pointcutManager = (PointcutManager) it.next();
420             pointcuts.addAll(pointcutManager.getPointcuts(ctx));
421         }
422         return pointcuts;
423     }
424 
425     /***
426      * Returns the cflow pointcut list for the context specified.
427      * 
428      * @param ctx the expression context
429      * @return the pointcuts for this join point
430      */
431     public List getCflowPointcuts(final ExpressionContext ctx) {
432         List pointcuts = new ArrayList();
433         for (Iterator it = m_pointcutManagerMap.values().iterator(); it.hasNext();) {
434             PointcutManager pointcutManager = (PointcutManager) it.next();
435             pointcuts.addAll(pointcutManager.getCflowPointcuts(ctx));
436         }
437         return pointcuts;
438     }
439 
440     /***
441      * Checks if a specific class has an aspect defined.
442      * 
443      * @param name the name of the aspect
444      * @return boolean true if the class has an aspect defined
445      */
446     public boolean hasAspect(final String name) {
447         if (name == null) {
448             throw new IllegalArgumentException("aspect name can not be null");
449         }
450         initialize();
451         if (m_pointcutManagerMap.containsKey(name)) {
452             return true;
453         } else {
454             return false;
455         }
456     }
457 
458     /***
459      * Returns a specific method by the class and the method hash.
460      * 
461      * @param klass the class housing the method
462      * @param methodHash the method hash
463      * @return the method tuple
464      */
465     public static MethodTuple getMethodTuple(final Class klass, final int methodHash) {
466         if (klass == null) {
467             throw new IllegalArgumentException("class can not be null");
468         }
469         try {
470             // create the method repository lazily
471             if (!s_methods.containsKey(klass)) {
472                 createMethodRepository(klass);
473             }
474         } catch (Exception e) {
475             throw new WrappedRuntimeException(e);
476         }
477         MethodTuple methodTuple;
478         try {
479             methodTuple = (MethodTuple) ((TIntObjectHashMap) s_methods.get(klass)).get(methodHash);
480         } catch (Throwable e1) {
481             throw new WrappedRuntimeException(e1);
482         }
483         return methodTuple;
484     }
485 
486     /***
487      * Returns a specific constructor by the class and the method hash.
488      * 
489      * @param klass the class housing the method
490      * @param constructorHash the constructor hash
491      * @return the constructor
492      */
493     public static ConstructorTuple getConstructorTuple(final Class klass, final int constructorHash) {
494         if (klass == null) {
495             throw new IllegalArgumentException("class can not be null");
496         }
497         try {
498             // create the constructor repository lazily
499             if (!s_constructors.containsKey(klass)) {
500                 createConstructorRepository(klass);
501             }
502         } catch (Exception e) {
503             throw new WrappedRuntimeException(e);
504         }
505         ConstructorTuple constructorTuple;
506         try {
507             constructorTuple = (ConstructorTuple) ((TIntObjectHashMap) s_constructors.get(klass)).get(constructorHash);
508         } catch (Throwable e1) {
509             throw new WrappedRuntimeException(e1);
510         }
511         // if no tuple found - we have a ctor call jp only - no wrapper.
512         if (constructorTuple == null) {
513             Constructor constructor = getConstructor(klass, constructorHash);
514             return new ConstructorTuple(constructor, constructor);
515         }
516         return constructorTuple;
517     }
518 
519     /***
520      * Returns a specific field by the class and the field hash.
521      * 
522      * @param klass the class housing the method
523      * @param fieldHash the field hash
524      * @return the field
525      */
526     public static Field getField(final Class klass, final int fieldHash) {
527         if (klass == null) {
528             throw new IllegalArgumentException("class can not be null");
529         }
530         try {
531             // create the fields repository lazily
532             if (!s_fields.containsKey(klass)) {
533                 createFieldRepository(klass);
534             }
535         } catch (Exception e) {
536             throw new WrappedRuntimeException(e);
537         }
538         Field field;
539         try {
540             field = (Field) ((TIntObjectHashMap) s_fields.get(klass)).get(fieldHash);
541         } catch (Throwable e1) {
542             throw new WrappedRuntimeException(e1);
543         }
544         return field;
545     }
546 
547     /***
548      * Returns a specific constructor by the class and the constructor hash.
549      *
550      * @param klass the class housing the method
551      * @param constructorHash the constructor hash
552      * @return the constructor
553      */
554     public static Constructor getConstructor(final Class klass, final int constructorHash) {
555         if (klass == null) {
556             throw new IllegalArgumentException("class can not be null");
557         }
558         //FIXME used only in inlining - remove 1.0 tuple based impl and cache this one instead
559         for (int i = 0; i < klass.getDeclaredConstructors().length; i++) {
560             Constructor constructor = klass.getDeclaredConstructors()[i];
561             if (ReflectHelper.calculateHash(constructor) == constructorHash) {
562                 return constructor;
563             }
564         }
565         return null;
566 //
567 //        try {
568 //            // create the constructor repository lazily
569 //            if (!s_constructors.containsKey(klass)) {
570 //                createConstructorRepository(klass);
571 //            }
572 //        } catch (Exception e) {
573 //            throw new WrappedRuntimeException(e);
574 //        }
575 //        Constructor constructor;
576 //        try {
577 //            constructor = (Constructor) ((TIntObjectHashMap) s_constructors.get(klass)).get(constructorHash);
578 //        } catch (Throwable e1) {
579 //            throw new WrappedRuntimeException(e1);
580 //        }
581 //        return constructor;
582     }
583 
584     /***
585      * Creates a new method repository for the class specified.
586      * 
587      * @param klass the class
588      */
589     protected static void createMethodRepository(final Class klass) {
590         if (klass == null) {
591             throw new IllegalArgumentException("class can not be null");
592         }
593         Method[] methods = klass.getDeclaredMethods();
594         TIntObjectHashMap methodMap = new TIntObjectHashMap(methods.length);
595         for (int i = 0; i < methods.length; i++) {
596             Method wrapperMethod = methods[i];
597             if (!wrapperMethod.getName().startsWith(TransformationConstants.ASPECTWERKZ_PREFIX)) {
598                 Method prefixedMethod = null;
599                 for (int j = 0; j < methods.length; j++) {
600                     Method method2 = methods[j];
601                     if (method2.getName().startsWith(TransformationConstants.ASPECTWERKZ_PREFIX)) {
602                         String[] tokens = Strings.splitString(method2.getName(), TransformationConstants.DELIMITER);
603                         String methodName = tokens[1];
604                         if (!methodName.equals(wrapperMethod.getName())) {
605                             continue;
606                         }
607                         Class[] parameterTypes1 = wrapperMethod.getParameterTypes();
608                         Class[] parameterTypes2 = method2.getParameterTypes();
609                         if (parameterTypes2.length != parameterTypes1.length) {
610                             continue;
611                         }
612                         boolean match = true;
613                         for (int k = 0; k < parameterTypes1.length; k++) {
614                             if (parameterTypes1[k] != parameterTypes2[k]) {
615                                 match = false;
616                                 break;
617                             }
618                         }
619                         if (!match) {
620                             continue;
621                         }
622                         prefixedMethod = method2;
623                         break;
624                     }
625                 }
626 
627                 // create a method tuple with 'wrapped method' and 'prefixed method'
628                 MethodTuple methodTuple = new MethodTuple(wrapperMethod, prefixedMethod);
629 
630                 // map the tuple to the hash for the 'wrapper method'
631                 int methodHash = ReflectHelper.calculateHash(wrapperMethod);
632                 methodMap.put(methodHash, methodTuple);
633             }
634         }
635         synchronized (s_methods) {
636             s_methods.put(klass, methodMap);
637         }
638     }
639 
640     /***
641      * Creates a new constructor repository for the class specified.
642      * 
643      * @param klass the class
644      */
645     protected static void createConstructorRepository(final Class klass) {
646         if (klass == null) {
647             throw new IllegalArgumentException("class can not be null");
648         }
649         Constructor[] constructors = klass.getDeclaredConstructors();
650         TIntObjectHashMap constructorMap = new TIntObjectHashMap(constructors.length);
651         for (int i = 0; i < constructors.length; i++) {
652             Constructor constructor1 = constructors[i];
653             Constructor prefixedConstructor = null;
654             // try to find a prefixed ctor for this one, that is with JPManager as last argument
655             Class[] parameterTypes2 = new Class[constructor1.getParameterTypes().length + 1];
656             System.arraycopy(constructor1.getParameterTypes(), 0, parameterTypes2, 0, constructor1.getParameterTypes().length);
657             parameterTypes2[parameterTypes2.length-1] = JoinPointManager.class;
658             try {
659                 prefixedConstructor = klass.getDeclaredConstructor(parameterTypes2);
660             } catch (NoSuchMethodException e) {
661                 // this one as no tuple available ie call pc or already a wrapper constructor
662                 continue;
663             }
664 
665             // create a constructor tuple with 'wrapper constructor' and 'prefixed constructor'
666             ConstructorTuple constructorTuple = new ConstructorTuple(constructor1, prefixedConstructor);
667 
668             // map the tuple to the hash for the 'wrapper constructor'
669             int constructorHash = ReflectHelper.calculateHash(constructor1);
670             constructorMap.put(constructorHash, constructorTuple);
671         }
672 
673 //
674 //
675 //
676 //
677 //
678 //            Constructor prefixedConstructor = constructor1;
679 //            Constructor wrapperConstructor = constructor1;
680 //            for (int j = 0; j < constructors.length; j++) {
681 //                Constructor constructor2 = constructors[j];
682 //                Class[] parameterTypes1 = constructor1.getParameterTypes();
683 //                Class[] parameterTypes2 = constructor2.getParameterTypes();
684 //                if (!constructor2.getName().equals(constructor1.getName())) {
685 //                    continue;
686 //                }
687 //                if (parameterTypes1.length == parameterTypes2.length) {
688 //                    continue;
689 //                } else if ((parameterTypes1.length < parameterTypes2.length)
690 //                    && (parameterTypes1.length == (parameterTypes2.length - 1))) {
691 //                    boolean match = true;
692 //                    for (int k = 0; k < parameterTypes1.length; k++) {
693 //                        if (parameterTypes1[k] != parameterTypes2[k]) {
694 //                            match = false;
695 //                            break;
696 //                        }
697 //                    }
698 //                    if (parameterTypes2[parameterTypes1.length].getName().equals(
699 //                        TransformationConstants.JOIN_POINT_MANAGER_CLASS)) {
700 //                        match = true;
701 //                    }
702 //                    if (!match) {
703 //                        continue;
704 //                    }
705 //                    wrapperConstructor = constructor1;
706 //                    prefixedConstructor = constructor2;
707 //                    break;
708 //                } else if ((parameterTypes2.length < parameterTypes1.length)
709 //                    && (parameterTypes2.length == (parameterTypes1.length - 1))) {
710 //                    boolean match = true;
711 //                    for (int k = 0; k < parameterTypes2.length; k++) {
712 //                        if (parameterTypes2[k] != parameterTypes1[k]) {
713 //                            match = false;
714 //                            break;
715 //                        }
716 //                    }
717 //                    if (parameterTypes1[parameterTypes2.length].getName().equals(
718 //                        TransformationConstants.JOIN_POINT_MANAGER_CLASS)) {
719 //                        match = true;
720 //                    }
721 //                    if (!match) {
722 //                        continue;
723 //                    }
724 //                    wrapperConstructor = constructor2;
725 //                    prefixedConstructor = constructor1;
726 //                    break;
727 //                }
728 //            }
729 //
730 //            // create a constructor tuple with 'wrapper constructor' and 'prefixed constructor'
731 //            ConstructorTuple constructorTuple = new ConstructorTuple(wrapperConstructor, prefixedConstructor);
732 //
733 //            // map the tuple to the hash for the 'wrapper constructor'
734 //            int constructorHash = ReflectHelper.calculateHash(wrapperConstructor);
735 //            constructorMap.put(constructorHash, constructorTuple);
736 //        }
737         synchronized (s_constructors) {
738             s_constructors.put(klass, constructorMap);
739         }
740     }
741 
742     /***
743      * Creates a new field repository for the class specified.
744      * 
745      * @param klass the class
746      */
747     protected static void createFieldRepository(final Class klass) {
748         if (klass == null) {
749             throw new IllegalArgumentException("class can not be null");
750         }
751         Field[] fields = klass.getDeclaredFields();
752         TIntObjectHashMap fieldMap = new TIntObjectHashMap(fields.length);
753         for (int i = 0; i < fields.length; i++) {
754             Field field = fields[i];
755             field.setAccessible(true);
756             int fieldHash = ReflectHelper.calculateHash(field);
757             fieldMap.put(fieldHash, field);
758         }
759         synchronized (s_fields) {
760             s_fields.put(klass, fieldMap);
761         }
762     }
763 }