KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > proxy > container > ClassProxyContainer


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * 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.proxy.container;
23
24 import java.security.AccessController JavaDoc;
25 import java.security.PrivilegedAction JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30
31 import org.jboss.aop.Advisor;
32 import org.jboss.aop.ClassContainer;
33 import org.jboss.aop.AspectManager;
34 import org.jboss.aop.ClassAdvisor;
35 import org.jboss.aop.advice.AspectDefinition;
36 import org.jboss.aop.introduction.InterfaceIntroduction;
37 import org.jboss.aop.util.ConstructorComparator;
38 import org.jboss.aop.util.MethodHashing;
39 //import org.jboss.repository.spi.MetaDataContext;
40

41 /**
42  * Extension of ClassContainer needed because of Mixins
43  * we want to be able to match pointcut expressions on the base class of the delegate
44  * we also want to be able to match pointcuts of instanceof{} of the Mixin interfaces.
45  *
46  * We also want to create constructor tables based on the constructor of the delegate so we can intercept
47  * construction
48  *
49  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
50  */

51 public class ClassProxyContainer extends ClassContainer
52 {
53    public ClassProxyContainer(String JavaDoc name, AspectManager manager)
54    {
55       super(name, manager);
56    }
57    
58    protected void createConstructorTables()
59    {
60       Class JavaDoc useClass = clazz;
61       if (clazz.getName().startsWith(ContainerProxyFactory.PROXY_NAME_PREFIX) && clazz != null && clazz.getSuperclass() != null)
62       {
63          useClass = clazz.getSuperclass();
64       }
65       if (useClass != null)
66       {
67          final Class JavaDoc theUseClass = useClass;
68          AccessController.doPrivileged(new PrivilegedAction JavaDoc()
69          {
70             public Object JavaDoc run()
71             {
72                constructors = theUseClass.getDeclaredConstructors();
73                for (int i = 0; i < constructors.length; i++)
74                {
75                   constructors[i].setAccessible(true);
76                }
77                return null;
78             }
79          });
80          Arrays.sort(constructors, ConstructorComparator.INSTANCE);
81       }
82    }
83
84
85    protected void createMethodMap()
86    {
87       //System.out.println("============================================ Create method map - " + this + " " + clazz.getName());
88
try
89       {
90          Method JavaDoc[] declaredMethods = clazz.getMethods();
91          
92          Class JavaDoc superclass = clazz.getSuperclass();
93          for (int i = 0; i < declaredMethods.length; i++)
94          {
95             Method JavaDoc method = declaredMethods[i];
96             if (ClassAdvisor.isAdvisable(method))
97             {
98                long hash = MethodHashing.methodHash(method);
99                try
100                {
101                   if (method.getDeclaringClass().getName().indexOf(ContainerProxyFactory.PROXY_NAME_PREFIX) >= 0 && superclass != null)
102                      method = superclass.getMethod(method.getName(), method.getParameterTypes());
103                }
104                catch (NoSuchMethodException JavaDoc ignored)
105                {
106                   // this is a mixin method or a proxy method
107
}
108                //System.out.println("--------> Adding method " + method);
109
advisedMethods.put(hash, method);
110             }
111          }
112          
113          for (int i = 0; i < interfaceIntroductions.size(); ++i)
114          {
115             InterfaceIntroduction ii = (InterfaceIntroduction) interfaceIntroductions.get(i);
116             String JavaDoc[] intf = ii.getInterfaces();
117             addMethodsFromInterfaces(intf);
118             
119             ArrayList JavaDoc mixins = ii.getMixins();
120             if (mixins.size() > 0)
121             {
122                for (Iterator JavaDoc it = mixins.iterator() ; it.hasNext() ;)
123                {
124                   InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin)it.next();
125                   String JavaDoc[] mintf = mixin.getInterfaces();
126                   addMethodsFromInterfaces(mintf);
127                }
128             }
129          }
130       }
131       catch (Exception JavaDoc e)
132       {
133          throw new RuntimeException JavaDoc(e);
134       }
135    }
136
137    private void addMethodsFromInterfaces(String JavaDoc[] intf) throws Exception JavaDoc
138    {
139       ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
140       for (int j = 0; intf != null && j < intf.length; ++j)
141       {
142          Class JavaDoc iface = cl.loadClass(intf[j]);
143          Method JavaDoc[] ifaceMethods = iface.getMethods();
144          for (int k = 0; k < ifaceMethods.length; k++)
145          {
146             long hash = MethodHashing.methodHash(ifaceMethods[k]);
147             
148             if (advisedMethods.get(hash) == null)
149             {
150                advisedMethods.put(hash, ifaceMethods[k]);
151                //System.out.println("--------> Adding method " + ifaceMethods[k]);
152
}
153          }
154       }
155    }
156    
157    public InstanceProxyContainer createInstanceProxyContainer(InterfaceIntroduction introduction, /*MetaDataContext*/ Object JavaDoc metaDataContext)
158    {
159       ProxyAdvisorDomain domain = new ProxyAdvisorDomain(manager, clazz, false);
160       domain.setInheritsBindings(true);
161       domain.setInheritsDeclarations(true);
162       if (introduction != null)
163       {
164          domain.addInterfaceIntroduction(introduction);
165       }
166
167       InstanceProxyContainer ia = new InstanceProxyContainer(super.getName(), domain, this, metaDataContext);
168       
169       return ia;
170    }
171    
172    public InstanceProxyContainer createInstanceProxyContainer()
173    {
174       return createInstanceProxyContainer(null, null);
175    }
176
177    public void initialise(Class JavaDoc proxiedClass)
178    {
179       setClass(proxiedClass);
180       ((ProxyAdvisorDomain)manager).attachAdvisor();
181       initializeInterfaceIntroductions(proxiedClass);
182       super.initializeClassContainer();
183    }
184
185    protected Advisor getParentAdvisor()
186    {
187       return null;
188    }
189    
190    public void addPerClassAspect(AspectDefinition def)
191    {
192       Advisor parentAdvisor = getParentAdvisor();
193       if (parentAdvisor != null)
194       {
195          parentAdvisor.addPerClassAspect(def);
196          return;
197       }
198       super.addPerClassAspect(def);
199    }
200
201    /**
202     * If this is an instance advisor, will check with parent advisor if the aspect
203     * is already registered. If so, we should use the one from the parent advisor
204     */

205    public Object JavaDoc getPerClassAspect(AspectDefinition def)
206    {
207       Advisor parentAdvisor = getParentAdvisor();
208       
209       if (parentAdvisor != null)
210       {
211          Object JavaDoc aspect = parentAdvisor.getPerClassAspect(def);
212          if (aspect != null) return aspect;
213       }
214       
215       return super.getPerClassAspect(def);
216    }
217
218    public boolean chainOverridingForInheritedMethods()
219    {
220       return true;
221    }
222 }
223
Popular Tags