KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.WeakHashMap JavaDoc;
25
26 import org.jboss.aop.Advised;
27 import org.jboss.aop.Advisor;
28 import org.jboss.aop.AspectManager;
29 import org.jboss.aop.introduction.InterfaceIntroduction;
30 import org.jboss.aop.metadata.SimpleMetaData;
31 //import org.jboss.repository.spi.MetaDataContext;
32

33 /**
34  *
35  * @author <a HREF="kabir.khan@jboss.com">Kabir Khan</a>
36  * @version $Revision: 57019 $
37  */

38 public class ContainerCache
39 {
40    private static volatile int counter;
41    public static final Object JavaDoc mapLock = new Object JavaDoc();
42    private static WeakHashMap JavaDoc containerCache = new WeakHashMap JavaDoc();
43
44    private AspectManager manager;
45    private ContainerProxyCacheKey key;
46    /** This will be ClassAdvisor if class has been woven i.e implements Advised, or ClassProxyContainer*/
47    private Advisor classAdvisor;
48    private InstanceProxyContainer instanceContainer;
49    boolean isClassProxyContainer;
50    Class JavaDoc[] interfaces;
51    AOPProxyFactoryMixin[] mixins;
52
53    //FIXME - make metaDataContext a MetaDataContext once MC 2.0 is released
54
//MetaDataContext metaDataContext;
55
Object JavaDoc metaDataContext;
56    SimpleMetaData simpleMetaData;
57
58    private ContainerCache(AspectManager manager, Class JavaDoc proxiedClass, Class JavaDoc[] interfaces, AOPProxyFactoryMixin[] mixins, /*MetaDataContext*/ Object JavaDoc metaDataContext, SimpleMetaData simpleMetaData)
59    {
60       this.manager = manager;
61       this.interfaces = interfaces;
62       this.mixins = mixins;
63       this.metaDataContext = metaDataContext;
64       this.simpleMetaData = simpleMetaData;
65       key = new ContainerProxyCacheKey(proxiedClass, interfaces, mixins, metaDataContext);
66    }
67    
68    public static ContainerCache initialise(AspectManager manager, Class JavaDoc proxiedClass, /*MetaDataContext*/ Object JavaDoc metaDataContext)
69    {
70       return initialise(manager, proxiedClass, null, null, metaDataContext, null);
71    }
72    
73    //FIXME - make metaDataContext a MetaDataContext once MC 2.0 is released
74
public static ContainerCache initialise(AspectManager manager, Class JavaDoc proxiedClass, Class JavaDoc[] interfaces, AOPProxyFactoryMixin[] mixins, /*MetaDataContext*/ Object JavaDoc metaDataContext, SimpleMetaData simpleMetaData)
75    {
76       ContainerCache factory = new ContainerCache(manager, proxiedClass, interfaces, mixins, metaDataContext, simpleMetaData);
77       synchronized (mapLock)
78       {
79          factory.initClassContainer();
80          factory.initInstanceContainer();
81       }
82       
83       return factory;
84    }
85
86    public ContainerProxyCacheKey getKey()
87    {
88       return key;
89    }
90    
91    public Advisor getAdvisor()
92    {
93       return (instanceContainer != null) ? instanceContainer : classAdvisor;
94    }
95
96    public Advisor getClassAdvisor()
97    {
98       return classAdvisor;
99    }
100
101    public InstanceProxyContainer getInstanceContainer()
102    {
103       return instanceContainer;
104    }
105
106    public boolean hasAspects()
107    {
108       if (instanceContainer != null)
109       {
110          return instanceContainer.hasAspects();
111       }
112       return classAdvisor.hasAspects();
113    }
114    
115    public boolean requiresInstanceAdvisor()
116    {
117       return hasInterfaceIntroductions() || hasMixins() || metaDataContext != null || simpleMetaData != null;
118    }
119    
120    public boolean isAdvised()
121    {
122       return Advised.class.isAssignableFrom(key.getClazz());
123    }
124
125    private boolean hasInterfaceIntroductions()
126    {
127       return interfaces != null && interfaces.length > 0;
128    }
129    
130    private boolean hasMixins()
131    {
132       return mixins != null && mixins.length > 0;
133    }
134    
135    private void initClassContainer()
136    {
137       if (Advised.class.isAssignableFrom(key.getClazz()))
138       {
139          classAdvisor = AspectManager.instance().getAdvisor(key.getClazz());
140       }
141       else
142       {
143          classAdvisor = getCachedContainer(manager);
144          if (classAdvisor == null)
145          {
146             classAdvisor = createAndCacheContainer();
147          }
148       }
149    }
150
151    private ClassProxyContainer getCachedContainer(AspectManager manager)
152    {
153       return (ClassProxyContainer)containerCache.get(key.getClazz());
154    }
155    
156    private ClassProxyContainer createAndCacheContainer()
157    {
158       ClassProxyContainer container = createContainer();
159       cacheContainer(key, key.getClazz(), container);
160       return container;
161    }
162    
163    private ClassProxyContainer createContainer()
164    {
165       ProxyAdvisorDomain domain = new ProxyAdvisorDomain(manager, key.getClazz(), false);
166       String JavaDoc classname = (key.getClazz() != null) ? key.getClazz().getName() : "AOP$Hollow";
167       ClassProxyContainer container = new ClassProxyContainer(classname /*+ " ClassProxy" + (counter++)*/, domain);
168       domain.setAdvisor(container);
169       container.initialise(key.getClazz());
170       
171       return container;
172    }
173    
174    private void cacheContainer(ContainerProxyCacheKey key, Class JavaDoc proxiedClass, ClassProxyContainer container)
175    {
176       containerCache.put(proxiedClass, container);
177    }
178    
179    private InterfaceIntroduction getInterfaceIntroduction()
180    {
181       int introductionLength = (hasInterfaceIntroductions()) ? interfaces.length : 0;
182       int mixinLength = (hasMixins()) ? mixins.length : 0;
183
184       if (introductionLength == 0 && mixinLength == 0)
185       {
186          return null;
187       }
188       
189       Class JavaDoc proxiedClass = classAdvisor.getClazz();
190       Class JavaDoc clazz = (proxiedClass != null) ? proxiedClass : Object JavaDoc.class;
191       String JavaDoc[] introducedNames = getClassNames(interfaces);
192       InterfaceIntroduction intro = new InterfaceIntroduction("Introduction" + counter++, clazz.getName(), introducedNames);
193
194       if (mixinLength > 0)
195       {
196          addMixins(intro);
197       }
198       
199       return intro;
200    }
201    
202    private void addMixins(InterfaceIntroduction intro)
203    {
204       for (int i = 0 ; i < mixins.length && mixins != null; i++)
205       {
206          Class JavaDoc[] mixinInterfaces = mixins[i].getInterfaces();
207          Class JavaDoc mixinClass = mixins[i].getMixin();
208          
209          if (mixinInterfaces == null)
210          {
211             throw new RuntimeException JavaDoc("When defining a mixin, interfaces must be defined");
212          }
213          if (mixinClass == null)
214          {
215             throw new RuntimeException JavaDoc("When defining a mixin, the mixin must be defined");
216          }
217          
218          String JavaDoc[] mixinInterfaceNames = getClassNames(mixinInterfaces);
219          InterfaceIntroduction.Mixin mixin = new InterfaceIntroduction.Mixin(mixinClass.getName(), mixinInterfaceNames, mixins[i].getConstruction(), false);
220          intro.addMixin(mixin);
221       }
222    }
223    
224    private String JavaDoc[] getClassNames(Class JavaDoc[] classes)
225    {
226       if (classes == null)
227       {
228          return null;
229       }
230       
231       String JavaDoc[] names = new String JavaDoc[classes.length];
232       for (int i = 0 ; i < classes.length ; i++)
233       {
234          names[i] = classes[i].getName();
235       }
236       return names;
237    }
238
239    private void initInstanceContainer()
240    {
241       if (requiresInstanceAdvisor())
242       {
243          InterfaceIntroduction introduction = null;
244          if (hasInterfaceIntroductions() || hasMixins())
245          {
246             introduction = getInterfaceIntroduction();
247          }
248
249          instanceContainer = InstanceProxyContainer.createInstanceProxyContainer(classAdvisor, introduction, metaDataContext);
250       }
251    }
252 }
253
254
255
256
257
Popular Tags