1 8 package org.codehaus.aspectwerkz.aspect.management; 9 10 import org.codehaus.aspectwerkz.aspect.AspectContainer; 11 import org.codehaus.aspectwerkz.aspect.DefaultAspectContainerStrategy; 12 import org.codehaus.aspectwerkz.AspectContext; 13 import org.codehaus.aspectwerkz.cflow.CflowCompiler; 14 import org.codehaus.aspectwerkz.util.ContextClassLoader; 15 import org.codehaus.aspectwerkz.definition.AspectDefinition; 16 import org.codehaus.aspectwerkz.definition.SystemDefinition; 17 import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer; 18 import org.codehaus.aspectwerkz.exception.DefinitionException; 19 20 import java.util.*; 21 import java.lang.reflect.Constructor ; 22 import java.lang.reflect.InvocationTargetException ; 23 24 import gnu.trove.TIntObjectHashMap; 25 26 32 public class Aspects { 33 34 37 public static final String DEFAULT_ASPECT_CONTAINER = DefaultAspectContainerStrategy.class.getName(); 38 39 48 private static Map ASPECT_CONTAINER_LISTS = new WeakHashMap(); 49 50 58 public static String [] getAspectQNameContainerClassName(final ClassLoader visibleFrom, final String qName) { 59 AspectDefinition aspectDefinition = lookupAspectDefinition(visibleFrom, qName); 60 return new String []{aspectDefinition.getQualifiedName(), aspectDefinition.getContainerClassName()}; 61 } 62 63 75 public static AspectContainer getContainerQNamed(final ClassLoader visibleFrom, final Class containerClass, final String qName) { 76 synchronized (ASPECT_CONTAINER_LISTS) { 77 TIntObjectHashMap containers = (TIntObjectHashMap) ASPECT_CONTAINER_LISTS.get(containerClass); 78 if (containers == null) { 79 containers = new TIntObjectHashMap(); 80 ASPECT_CONTAINER_LISTS.put(containerClass, containers); 81 } 82 AspectContainer container = (AspectContainer) containers.get(CompositeVisibleFromQNameKey.hash(visibleFrom, qName)); 83 if (container == null) { 84 container = createAspectContainer(visibleFrom, containerClass, qName); 85 containers.put(CompositeVisibleFromQNameKey.hash(visibleFrom, qName), container); 86 } 87 return container; 88 } 89 } 90 91 98 public static Object aspectOf(final String qName) { 99 return aspectOf(Thread.currentThread().getContextClassLoader(), qName); 100 } 101 102 110 public static Object aspectOf(final Class aspectClass) { 111 String aspectClassName = aspectClass.getName().replace('/', '.'); 112 return aspectOf(aspectClass.getClassLoader(), aspectClassName); 113 } 114 115 122 public static Object aspectOf(final ClassLoader visibleFrom, final String qName) { 123 String [] qNameContainerClassName = getAspectQNameContainerClassName(visibleFrom, qName); 124 return aspect$Of(visibleFrom, qNameContainerClassName[0], qNameContainerClassName[1]); 125 } 126 127 135 public static Object aspectOf(final Class aspectClass, final Class targetClass) { 136 String aspectClassName = aspectClass.getName().replace('/', '.'); 137 return aspectOf(aspectClassName, targetClass); 138 } 139 140 147 public static Object aspectOf(final String qName, final Class targetClass) { 148 String [] qNameContainerClassName = getAspectQNameContainerClassName(targetClass.getClassLoader(), qName); 150 return aspect$Of(qNameContainerClassName[0], qNameContainerClassName[1], targetClass); 151 } 152 153 161 public static Object aspectOf(final Class aspectClass, final Object targetInstance) { 162 String aspectClassName = aspectClass.getName().replace('/', '.'); 163 return aspectOf(aspectClassName, targetInstance); 164 } 165 166 173 public static Object aspectOf(final String qName, final Object targetInstance) { 174 String [] qNameContainerClassName = getAspectQNameContainerClassName(targetInstance.getClass().getClassLoader(), qName); 176 return aspect$Of(qNameContainerClassName[0], qNameContainerClassName[1], targetInstance); 177 } 178 179 181 public static Object aspect$Of(ClassLoader loader, String qName, String containerClassName) { 182 try { 183 Class containerClass = ContextClassLoader.forName(loader, containerClassName); 184 return getContainerQNamed(loader, containerClass, qName).aspectOf(); 185 } catch (Throwable t) { 186 throw new NoAspectBoundException(t, qName); 187 } 188 } 189 190 public static Object aspect$Of(String qName, String containerClassName, final Class perClass) { 191 try { 192 ClassLoader loader = perClass.getClassLoader(); 193 Class containerClass = ContextClassLoader.forName(loader, containerClassName); 194 return getContainerQNamed(loader, containerClass, qName).aspectOf(perClass); 195 } catch (Throwable t) { 196 throw new NoAspectBoundException(t, qName); 197 } 198 } 199 200 public static Object aspect$Of(String qName, String containerClassName, final Object perInstance) { 201 try { 202 ClassLoader loader = perInstance.getClass().getClassLoader(); 203 Class containerClass = ContextClassLoader.forName(loader, containerClassName); 204 return getContainerQNamed(loader, containerClass, qName).aspectOf(perInstance); 205 } catch (Throwable t) { 206 throw new NoAspectBoundException(t, qName); 207 } 208 } 209 210 211 212 213 215 222 private static AspectContainer createAspectContainer(final ClassLoader visibleFrom, final Class containerClass, final String qName) { 223 AspectDefinition aspectDefinition = lookupAspectDefinition(visibleFrom, qName); 224 225 Class aspectClass = null; 226 try { 227 aspectClass = ContextClassLoader.forName(visibleFrom, aspectDefinition.getClassName()); 228 } catch (Throwable t) { 229 throw new NoAspectBoundException(t, qName); 230 } 231 232 try { 233 Constructor constructor = containerClass.getConstructor(new Class []{AspectContext.class}); 234 final AspectContext aspectContext = new AspectContext( 235 aspectDefinition.getSystemDefinition().getUuid(), 236 aspectClass, 237 aspectDefinition.getName(), 238 aspectDefinition.getDeploymentModel(), 239 aspectDefinition, 240 aspectDefinition.getParameters() 241 ); 242 final AspectContainer container = (AspectContainer) constructor.newInstance(new Object []{aspectContext}); 243 aspectContext.setContainer(container); 244 return container; 245 } catch (InvocationTargetException e) { 246 throw new NoAspectBoundException(e, qName); 247 } catch (NoSuchMethodException e) { 248 throw new NoAspectBoundException( 249 "AspectContainer does not have a valid constructor [" 250 + containerClass.getName() 251 + "] need to take an AspectContext instance as its only parameter: " 252 + e.toString(), 253 qName 254 ); 255 } catch (Throwable e) { 256 StringBuffer cause = new StringBuffer (); 257 cause.append("Could not create AspectContainer using the implementation specified ["); 258 cause.append(containerClass.getName()); 259 cause.append("] for ").append(qName); 260 throw new NoAspectBoundException(e, cause.toString()); 261 } 262 } 263 264 272 private static AspectDefinition lookupAspectDefinition(final ClassLoader visibleFrom, final String qName) { 273 AspectDefinition aspectDefinition = null; 274 275 Set definitions = SystemDefinitionContainer.getDefinitionsFor(visibleFrom); 276 if (qName.indexOf('/')>0) { 277 for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { 279 SystemDefinition systemDefinition = (SystemDefinition) iterator.next(); 280 for (Iterator iterator1 = systemDefinition.getAspectDefinitions().iterator(); iterator1.hasNext();) { 281 AspectDefinition aspectDef = (AspectDefinition) iterator1.next(); 282 if (qName.equals(aspectDef.getQualifiedName())) { 283 aspectDefinition = aspectDef; 284 break; 285 } 286 } 287 } 288 } else { 289 int found = 0; 292 for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { 293 SystemDefinition systemDefinition = (SystemDefinition) iterator.next(); 294 for (Iterator iterator1 = systemDefinition.getAspectDefinitions().iterator(); iterator1.hasNext();) { 295 AspectDefinition aspectDef = (AspectDefinition) iterator1.next(); 296 if (qName.equals(aspectDef.getClassName())) { 297 aspectDefinition = aspectDef; 298 found++; 299 } 300 } 301 } 302 if (found > 1) { 303 throw new NoAspectBoundException("More than one AspectDefinition found, consider using other API methods", qName); 304 } 305 306 } 307 308 if (aspectDefinition == null) { 309 throw new NoAspectBoundException("Could not find AspectDefinition", qName); 310 } 311 312 return aspectDefinition; 313 } 314 315 344 347 private Aspects() { 348 } 349 350 360 private static class CompositeVisibleFromQNameKey { 361 381 388 public static int hash(ClassLoader loader, String qName) { 389 int result; 390 result = (loader != null ? loader.hashCode() : 0); 391 result = 29 * result + qName.hashCode(); 392 return result; 393 } 394 } 395 } 396 | Popular Tags |