1 22 package org.jboss.aop.proxy.container; 23 24 import java.util.WeakHashMap ; 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 33 38 public class ContainerCache 39 { 40 private static volatile int counter; 41 public static final Object mapLock = new Object (); 42 private static WeakHashMap containerCache = new WeakHashMap (); 43 44 private AspectManager manager; 45 private ContainerProxyCacheKey key; 46 47 private Advisor classAdvisor; 48 private InstanceProxyContainer instanceContainer; 49 boolean isClassProxyContainer; 50 Class [] interfaces; 51 AOPProxyFactoryMixin[] mixins; 52 53 Object metaDataContext; 56 SimpleMetaData simpleMetaData; 57 58 private ContainerCache(AspectManager manager, Class proxiedClass, Class [] interfaces, AOPProxyFactoryMixin[] mixins, Object 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 proxiedClass, Object metaDataContext) 69 { 70 return initialise(manager, proxiedClass, null, null, metaDataContext, null); 71 } 72 73 public static ContainerCache initialise(AspectManager manager, Class proxiedClass, Class [] interfaces, AOPProxyFactoryMixin[] mixins, Object 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 classname = (key.getClazz() != null) ? key.getClazz().getName() : "AOP$Hollow"; 167 ClassProxyContainer container = new ClassProxyContainer(classname , domain); 168 domain.setAdvisor(container); 169 container.initialise(key.getClazz()); 170 171 return container; 172 } 173 174 private void cacheContainer(ContainerProxyCacheKey key, Class 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 proxiedClass = classAdvisor.getClazz(); 190 Class clazz = (proxiedClass != null) ? proxiedClass : Object .class; 191 String [] 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 [] mixinInterfaces = mixins[i].getInterfaces(); 207 Class mixinClass = mixins[i].getMixin(); 208 209 if (mixinInterfaces == null) 210 { 211 throw new RuntimeException ("When defining a mixin, interfaces must be defined"); 212 } 213 if (mixinClass == null) 214 { 215 throw new RuntimeException ("When defining a mixin, the mixin must be defined"); 216 } 217 218 String [] 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 [] getClassNames(Class [] classes) 225 { 226 if (classes == null) 227 { 228 return null; 229 } 230 231 String [] names = new String [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 |