KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > microcontainer > integration > AOPDependencyBuilderDelegate


1 /*
2 * JBoss, Home of Professional Open Source.
3 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
4 * as indicated by the @author tags. See the copyright.txt file in the
5 * distribution for a full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.aop.microcontainer.integration;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Set JavaDoc;
31
32 import org.jboss.aop.Advisor;
33 import org.jboss.aop.AspectManager;
34 import org.jboss.aop.ReflectiveAspectBinder;
35 import org.jboss.aop.advice.AspectDefinition;
36 import org.jboss.aop.microcontainer.beans.ManagedAspectDefinition;
37 import org.jboss.aop.proxy.container.ContainerCache;
38 import org.jboss.aop.util.Advisable;
39 import org.jboss.aop.util.ClassInfoMethodHashing;
40 import org.jboss.classadapter.plugins.dependency.AbstractDependencyBuilder;
41 import org.jboss.classadapter.spi.ClassAdapter;
42 import org.jboss.classadapter.spi.Dependency;
43 import org.jboss.reflect.plugins.AnnotationValueFactory;
44 import org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactoryImpl;
45 import org.jboss.reflect.spi.AnnotationInfo;
46 import org.jboss.reflect.spi.AnnotationValue;
47 import org.jboss.reflect.spi.ArrayInfo;
48 import org.jboss.reflect.spi.ArrayValue;
49 import org.jboss.reflect.spi.ClassInfo;
50 import org.jboss.reflect.spi.MethodInfo;
51 import org.jboss.reflect.spi.StringValue;
52 import org.jboss.reflect.spi.TypeInfo;
53 import org.jboss.reflect.spi.Value;
54 import org.jboss.repository.spi.MetaDataContext;
55
56 /**
57  * Used by the AOPDependencyBuilder once the AspectManager has been installed. Finds all managed aspects that apply
58  * to the bean and includes their dependencies as dependencies of the bean
59  *
60  * @author <a HREF="kabir.khan@jboss.com">Kabir Khan</a>
61  * @version $Revision: 1.1 $
62  */

63 public class AOPDependencyBuilderDelegate extends AbstractDependencyBuilder
64 {
65    private static final String JavaDoc DEPENDENCY_CLASS_NAME = Dependency.class.getName();
66    private static final String JavaDoc DEPENDENCY_NAME_ATTRIBUTE = "name";
67    private static final IntrospectionTypeInfoFactoryImpl typeInfoFactory = new IntrospectionTypeInfoFactoryImpl();
68
69    public List JavaDoc getDependencies(ClassAdapter classAdapter)
70    {
71       AspectManager manager = AspectManager.instance();
72       try
73       {
74          ClassInfo classInfo = classAdapter.getClassInfo();
75          String JavaDoc className = classInfo.getName();
76          if (className != null)
77          {
78             if (manager.isNonAdvisableClassName(className))
79             {
80                return super.getDependencies(classAdapter);
81             }
82             
83             MetaDataContext metaDataContext = classAdapter.getMetaDataContext();
84
85             ClassLoader JavaDoc loader = classAdapter.getClassLoader();
86             if (loader == null)
87             {
88                loader = Thread.currentThread().getContextClassLoader();
89             }
90             Class JavaDoc clazz = loader.loadClass(className);
91
92             Advisor advisor;
93             synchronized (ContainerCache.mapLock)
94             {
95                ContainerCache cache = ContainerCache.initialise(manager, clazz, metaDataContext);
96                advisor = cache.getAdvisor();
97             }
98             
99             ReflectiveAspectBinder binder = new ReflectiveAspectBinder(clazz, advisor);
100             Set JavaDoc aspects = binder.getAspects();
101             
102             ArrayList JavaDoc<Object JavaDoc> depends = new ArrayList JavaDoc<Object JavaDoc>();
103             if (aspects != null && aspects.size() > 0)
104             {
105                Iterator JavaDoc it = aspects.iterator();
106                while (it.hasNext())
107                {
108                   AspectDefinition def = (AspectDefinition) it.next();
109                   if (def instanceof ManagedAspectDefinition)
110                   {
111                      depends.add(def.getName());
112                   }
113                }
114             }
115             
116             HashSet JavaDoc<Object JavaDoc> annotationDependencies = getAnnotationDependencies(classInfo, metaDataContext);
117             depends.addAll(annotationDependencies);
118             
119             return depends;
120          }
121          return null;
122          
123       }
124       catch (ClassNotFoundException JavaDoc e)
125       {
126          throw new RuntimeException JavaDoc(e);
127       }
128    }
129    
130    private HashSet JavaDoc<Object JavaDoc> getAnnotationDependencies(ClassInfo classInfo, MetaDataContext metaDataContext)
131    {
132       try
133       {
134          HashSet JavaDoc<Object JavaDoc> dependencies = new HashSet JavaDoc<Object JavaDoc>();
135          getClassAnnotationDependencies(classInfo, metaDataContext, dependencies);
136          getMethodAnnotationDependencies(classInfo, metaDataContext, dependencies);
137          return dependencies;
138       }
139       catch (RuntimeException JavaDoc e)
140       {
141          throw e;
142       }
143       catch (Exception JavaDoc e)
144       {
145          throw new RuntimeException JavaDoc(e);
146       }
147    }
148
149    private void getClassAnnotationDependencies(ClassInfo classInfo, MetaDataContext metaDataContext, HashSet JavaDoc<Object JavaDoc> dependencies) throws Exception JavaDoc
150    {
151       HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> realMap = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>>();
152       getRealClassAnnotationDependencies(classInfo, realMap);
153       HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> metaMap = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>>();
154       getMetaDataContextClassAnnotationDependencies(metaDataContext, metaMap);
155       addAllDependenciesToSet(dependencies, realMap, metaMap);
156    }
157    
158    private void getRealClassAnnotationDependencies(ClassInfo classInfo, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies) throws Exception JavaDoc
159    {
160       AnnotationValue[] annotations = classInfo.getAnnotations();
161       
162       for (int i = 0 ; i < annotations.length ; i++)
163       {
164          getDependenciesForAnnotation(annotations[i].getType().getName(), annotations[i], dependencies);
165       }
166    }
167    
168    private void getMetaDataContextClassAnnotationDependencies(MetaDataContext metaDataContext, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies) throws Exception JavaDoc
169    {
170       if (metaDataContext != null)
171       {
172          for (Iterator JavaDoc it = metaDataContext.getAnnotations().iterator() ; it.hasNext() ; )
173          {
174             Object JavaDoc annotation = it.next();
175             getDependenciesForMetaDataAnnotation(annotation, dependencies);
176          }
177       }
178    }
179    
180    private void getMethodAnnotationDependencies(ClassInfo classInfo, MetaDataContext metaDataContext, HashSet JavaDoc<Object JavaDoc> dependencies) throws Exception JavaDoc
181    {
182       Map JavaDoc methodMap = ClassInfoMethodHashing.getMethodMap(classInfo);
183       if (methodMap != null)
184       {
185          for (Iterator JavaDoc it = methodMap.values().iterator() ; it.hasNext() ; )
186          {
187             MethodInfo method = (MethodInfo)it.next();
188             if (Advisable.isAdvisableMethod(method.getModifiers(), method.getName()))
189             {
190                HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> classMap = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>>();
191                getRealMethodAnnotationDependencies(method, classMap);
192                HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> overrideMap = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>>();
193                getMetaDataContextMethodAnnotationDependencies(method, metaDataContext, overrideMap);
194                addAllDependenciesToSet(dependencies, classMap, overrideMap);
195             }
196          }
197       }
198    }
199    
200    private void getRealMethodAnnotationDependencies(MethodInfo methodInfo, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies) throws Exception JavaDoc
201    {
202       AnnotationValue[] annotations = methodInfo.getAnnotations();
203       if (annotations != null)
204       {
205          for (int i = 0 ; i < annotations.length ; i++)
206          {
207             getDependenciesForAnnotation(annotations[i].getType().getName(), annotations[i], dependencies);
208          }
209       }
210    }
211    
212    private void getMetaDataContextMethodAnnotationDependencies(MethodInfo method, MetaDataContext metaDataContext, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies) throws Exception JavaDoc
213    {
214       if (metaDataContext != null)
215       {
216          long hash = ClassInfoMethodHashing.methodHash(method);
217          List JavaDoc methodAnnotations = metaDataContext.getAnnotationsForMethod(hash);
218          for (Iterator JavaDoc it = methodAnnotations.iterator() ; it.hasNext() ; )
219          {
220             Object JavaDoc annotation = it.next();
221             getDependenciesForMetaDataAnnotation(annotation, dependencies);
222          }
223       }
224    }
225    
226    private void getDependenciesForMetaDataAnnotation(Object JavaDoc annotation, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies) throws Exception JavaDoc
227    {
228       AnnotationInfo info;
229       Class JavaDoc clazz = annotation.getClass().getInterfaces()[0];
230       try
231       {
232          info = (AnnotationInfo)typeInfoFactory.getTypeInfo(clazz);
233       }
234       catch (RuntimeException JavaDoc e)
235       {
236          // AutoGenerated
237
throw new RuntimeException JavaDoc("Error creating annotation for " + clazz.getName(), e);
238       }
239       AnnotationValue value = AnnotationValueFactory.createAnnotationValue(typeInfoFactory, typeInfoFactory, info, annotation);
240       getDependenciesForAnnotation(info.getName(), value, dependencies);
241    }
242    
243    private void getDependenciesForAnnotation(String JavaDoc topLevelAnnotationName, AnnotationValue annotation, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies)
244    {
245       if (annotation != null)
246       {
247          addAnnotationAttributeDependencies(topLevelAnnotationName, annotation, dependencies);
248          
249          AnnotationValue[] annotationAnnotations = annotation.getAnnotationType().getAnnotations();
250          for (int i = 0 ; i < annotationAnnotations.length ; i++)
251          {
252             if (annotationAnnotations[i].getAnnotationType().getName().equals(DEPENDENCY_CLASS_NAME))
253             {
254                StringValue value = (StringValue)annotationAnnotations[i].getValue(DEPENDENCY_NAME_ATTRIBUTE);
255                StringValue dependency = (StringValue)annotation.getValue(value.getValue());
256                addDependency(topLevelAnnotationName, dependency, dependencies);
257             }
258          }
259       }
260    }
261    
262    private void addAnnotationAttributeDependencies(String JavaDoc topLevelAnnotationName, AnnotationValue annotation, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies)
263    {
264       MethodInfo[] attributes = annotation.getAnnotationType().getDeclaredMethods();
265       if (attributes != null)
266       {
267          for (int i = 0 ; i < attributes.length ; i++)
268          {
269             Value value = annotation.getValue(attributes[i].getName());
270             
271             if (value instanceof AnnotationValue)
272             {
273                getDependenciesForAnnotation(topLevelAnnotationName, (AnnotationValue)value, dependencies);
274             }
275             else if (value instanceof ArrayValue)
276             {
277                ArrayValue arrVal = (ArrayValue)value;
278                TypeInfo type = ((ArrayInfo)arrVal.getType()).getComponentType();
279                if (type instanceof AnnotationInfo)
280                {
281                   Value[] values = arrVal.getValues();
282                   for (int j = 0 ; j < values.length ; j++)
283                   {
284                      getDependenciesForAnnotation(topLevelAnnotationName, (AnnotationValue)values[j], dependencies);
285                   }
286                }
287             }
288          }
289       }
290    }
291    
292    private void addDependency(String JavaDoc topLevelAnnotationName, StringValue dependency, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencies)
293    {
294       ArrayList JavaDoc<String JavaDoc> list = dependencies.get(topLevelAnnotationName);
295       if (list == null)
296       {
297          list = new ArrayList JavaDoc<String JavaDoc>();
298          dependencies.put(topLevelAnnotationName, list);
299       }
300       
301       list.add(dependency.getValue());
302    }
303
304    private void addAllDependenciesToSet(HashSet JavaDoc<Object JavaDoc> dependencies, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> classMap, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> overrideMap)
305    {
306       HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> dependencyMap = mergeClassAndOverrideMaps(classMap, overrideMap);
307       if (dependencyMap.size() > 0)
308       {
309          for (ArrayList JavaDoc<String JavaDoc> deps : dependencyMap.values())
310          {
311             dependencies.addAll(deps);
312          }
313       }
314    }
315    
316    private HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> mergeClassAndOverrideMaps(HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> classMap, HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<String JavaDoc>> overrideMap)
317    {
318       if (classMap.size() == 0 && overrideMap.size() == 0)
319       {
320          return classMap;
321       }
322       if (classMap.size() > 0 && overrideMap.size() == 0)
323       {
324          return classMap;
325       }
326       if (classMap.size() == 0 && overrideMap.size() > 0)
327       {
328          return overrideMap;
329       }
330       
331       for (String JavaDoc key : overrideMap.keySet())
332       {
333          classMap.put(key, overrideMap.get(key));
334       }
335       return classMap;
336    }
337 }
338
Popular Tags