1 8 package org.codehaus.aspectwerkz.aspect.management; 9 10 import org.codehaus.aspectwerkz.aspect.DefaultMixinFactory; 11 import org.codehaus.aspectwerkz.aspect.MixinFactory; 12 import org.codehaus.aspectwerkz.util.ContextClassLoader; 13 import org.codehaus.aspectwerkz.DeploymentModel; 14 import org.codehaus.aspectwerkz.util.ContextClassLoader; 15 import org.codehaus.aspectwerkz.definition.SystemDefinition; 16 import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer; 17 import org.codehaus.aspectwerkz.definition.MixinDefinition; 18 import org.codehaus.aspectwerkz.exception.DefinitionException; 19 import org.codehaus.aspectwerkz.DeploymentModel; 20 21 import java.util.*; 22 import java.lang.reflect.Constructor ; 23 import java.lang.reflect.InvocationTargetException ; 24 25 31 public class Mixins { 32 33 36 public static final String DEFAULT_MIXIN_FACTORY = DefaultMixinFactory.class.getName(); 37 38 41 private static final Map MIXIN_FACTORIES = new WeakHashMap(); 42 43 50 public static MixinFactory getFactory(final Class mixinClass, final ClassLoader mixinCalledFromLoader) { 51 synchronized (MIXIN_FACTORIES) { 52 MixinFactory factory = (MixinFactory) MIXIN_FACTORIES.get(mixinClass); 53 if (factory == null) { 54 factory = createMixinFactory(mixinClass, mixinCalledFromLoader); 55 MIXIN_FACTORIES.put(mixinClass, factory); 59 } 60 return factory; 61 } 62 } 63 64 71 public static Object mixinOf(final String name, ClassLoader loader) { 72 try { 73 Class mixinClass = Class.forName(name, false, loader); 74 return mixinOf(mixinClass); 75 } catch (ClassNotFoundException e) { 76 throw new RuntimeException ("could not load mixin " + name + " from " + loader); 77 } 78 } 79 80 87 public static Object mixinOf(final Class mixinClass) { 88 return getFactory(mixinClass, mixinClass.getClassLoader()).mixinOf(); 89 } 90 91 98 public static Object mixinOf(final String name, final Class targetClass) { 99 try { 100 Class mixinClass = Class.forName(name, false, targetClass.getClassLoader()); 101 return mixinOf(mixinClass, targetClass); 102 } catch (ClassNotFoundException e) { 103 throw new RuntimeException ("could not load mixin " + name + " from " + targetClass.getClassLoader()); 104 } 105 } 106 107 115 public static Object mixinOf(final Class mixinClass, final Class targetClass) { 116 return getFactory(mixinClass, targetClass.getClassLoader()).mixinOf(targetClass); 117 } 118 119 126 public static Object mixinOf(final String name, final Object targetInstance) { 127 try { 128 Class mixinClass = Class.forName(name, false, targetInstance.getClass().getClassLoader()); 129 return mixinOf(mixinClass, targetInstance); 130 } catch (ClassNotFoundException e) { 131 throw new RuntimeException ( 132 "could not load mixin " + name + " from " + targetInstance.getClass().getClassLoader() 133 ); 134 } 135 } 136 137 145 public static Object mixinOf(final Class mixinClass, final Object targetInstance) { 146 return getFactory(mixinClass, targetInstance.getClass().getClassLoader()).mixinOf(targetInstance); 148 } 149 150 156 private static MixinFactory createMixinFactory(final Class mixinClass, final ClassLoader mixinCalledFromLoader) { 157 final MixinDefinition mixinDefinition = getMixinDefinition(mixinClass, mixinCalledFromLoader); 158 159 String factoryClassName = mixinDefinition.getFactoryClassName(); 160 try { 161 Class containerClass; 162 if (factoryClassName == null) { 163 containerClass = ContextClassLoader.forName(mixinClass.getClassLoader(), DEFAULT_MIXIN_FACTORY); 164 } else { 165 containerClass = ContextClassLoader.forName(mixinClass.getClassLoader(), factoryClassName); 166 } 167 Constructor constructor = containerClass.getConstructor(new Class []{Class .class, DeploymentModel.class}); 168 final MixinFactory factory = (MixinFactory) constructor.newInstance( 169 new Object []{mixinClass, mixinDefinition.getDeploymentModel()} 170 ); 171 return factory; 172 } catch (InvocationTargetException e) { 173 throw new DefinitionException(e.getTargetException().toString()); 174 } catch (NoSuchMethodException e) { 175 throw new DefinitionException( 176 "mixin factory does not have a valid constructor [" 177 + factoryClassName 178 + "] need to have a signature like this [MyMixinFactory(Class mixin, DeploymentModel scope)]: " 179 + e.toString() 180 ); 181 } catch (Throwable e) { 182 StringBuffer cause = new StringBuffer (); 183 cause.append("could not create mixin container using the implementation specified ["); 184 cause.append(factoryClassName); 185 cause.append("] due to: "); 186 cause.append(e.toString()); 187 throw new DefinitionException(cause.toString()); 188 } 189 } 190 191 204 public static Map getParameters(Class mixinClass, ClassLoader loader) { 205 MixinDefinition mixinDefinition = getMixinDefinition(mixinClass, loader); 206 return mixinDefinition.getParameters(); 207 } 208 209 217 public static MixinDefinition getMixinDefinition(Class mixinClass, ClassLoader visibleFrom) { 218 MixinDefinition mixinDefinition = null; 219 220 Set definitions = SystemDefinitionContainer.getDefinitionsFor(visibleFrom); 221 for (Iterator iterator = definitions.iterator(); iterator.hasNext() && mixinDefinition == null;) { 222 SystemDefinition systemDefinition = (SystemDefinition) iterator.next(); 223 for (Iterator iterator1 = systemDefinition.getMixinDefinitions().iterator(); iterator1.hasNext();) { 224 MixinDefinition mixinDef = (MixinDefinition) iterator1.next(); 225 if (mixinClass.getName().replace('/', '.').equals(mixinDef.getMixinImpl().getName())) { 226 mixinDefinition = mixinDef; 227 break; 228 } 229 } 230 } 231 if (mixinDefinition == null) { 232 throw new DefinitionException("could not find definition for mixin: " + mixinClass.getName() 233 + " (loader " + mixinClass.getClassLoader() + ")" 234 + " from loader " + visibleFrom); 235 } 236 return mixinDefinition; 237 } 238 239 242 private Mixins() { 243 } 244 } 245 | Popular Tags |