1 4 package com.tc.aspectwerkz.aspect.management; 5 6 7 import com.tc.aspectwerkz.DeploymentModel; 8 import com.tc.aspectwerkz.aspect.DefaultMixinFactory; 9 import com.tc.aspectwerkz.aspect.MixinFactory; 10 import com.tc.aspectwerkz.definition.MixinDefinition; 11 import com.tc.aspectwerkz.definition.SystemDefinition; 12 import com.tc.aspectwerkz.definition.SystemDefinitionContainer; 13 import com.tc.aspectwerkz.exception.DefinitionException; 14 import com.tc.aspectwerkz.util.ContextClassLoader; 15 16 import java.util.*; 17 import java.lang.reflect.Constructor ; 18 import java.lang.reflect.InvocationTargetException ; 19 20 26 public class Mixins { 27 28 31 public static final String DEFAULT_MIXIN_FACTORY = DefaultMixinFactory.class.getName(); 32 33 36 private static final Map MIXIN_FACTORIES = new WeakHashMap(); 37 38 45 public static MixinFactory getFactory(final Class mixinClass, final ClassLoader mixinCalledFromLoader) { 46 synchronized (MIXIN_FACTORIES) { 47 MixinFactory factory = (MixinFactory) MIXIN_FACTORIES.get(mixinClass); 48 if (factory == null) { 49 factory = createMixinFactory(mixinClass, mixinCalledFromLoader); 50 MIXIN_FACTORIES.put(mixinClass, factory); 54 } 55 return factory; 56 } 57 } 58 59 66 public static Object mixinOf(final String name, ClassLoader loader) { 67 try { 68 Class mixinClass = Class.forName(name, false, loader); 69 return mixinOf(mixinClass); 70 } catch (ClassNotFoundException e) { 71 throw new RuntimeException ("could not load mixin " + name + " from " + loader); 72 } 73 } 74 75 82 public static Object mixinOf(final Class mixinClass) { 83 return getFactory(mixinClass, mixinClass.getClassLoader()).mixinOf(); 84 } 85 86 93 public static Object mixinOf(final String name, final Class targetClass) { 94 try { 95 Class mixinClass = Class.forName(name, false, targetClass.getClassLoader()); 96 return mixinOf(mixinClass, targetClass); 97 } catch (ClassNotFoundException e) { 98 throw new RuntimeException ("could not load mixin " + name + " from " + targetClass.getClassLoader()); 99 } 100 } 101 102 110 public static Object mixinOf(final Class mixinClass, final Class targetClass) { 111 return getFactory(mixinClass, targetClass.getClassLoader()).mixinOf(targetClass); 112 } 113 114 121 public static Object mixinOf(final String name, final Object targetInstance) { 122 try { 123 Class mixinClass = Class.forName(name, false, targetInstance.getClass().getClassLoader()); 124 return mixinOf(mixinClass, targetInstance); 125 } catch (ClassNotFoundException e) { 126 throw new RuntimeException ( 127 "could not load mixin " + name + " from " + targetInstance.getClass().getClassLoader() 128 ); 129 } 130 } 131 132 140 public static Object mixinOf(final Class mixinClass, final Object targetInstance) { 141 return getFactory(mixinClass, targetInstance.getClass().getClassLoader()).mixinOf(targetInstance); 143 } 144 145 151 private static MixinFactory createMixinFactory(final Class mixinClass, final ClassLoader mixinCalledFromLoader) { 152 final MixinDefinition mixinDefinition = getMixinDefinition(mixinClass, mixinCalledFromLoader); 153 154 String factoryClassName = mixinDefinition.getFactoryClassName(); 155 try { 156 Class containerClass; 157 if (factoryClassName == null) { 158 containerClass = ContextClassLoader.forName(mixinClass.getClassLoader(), DEFAULT_MIXIN_FACTORY); 159 } else { 160 containerClass = ContextClassLoader.forName(mixinClass.getClassLoader(), factoryClassName); 161 } 162 Constructor constructor = containerClass.getConstructor(new Class []{Class .class, DeploymentModel.class}); 163 final MixinFactory factory = (MixinFactory) constructor.newInstance( 164 new Object []{mixinClass, mixinDefinition.getDeploymentModel()} 165 ); 166 return factory; 167 } catch (InvocationTargetException e) { 168 throw new DefinitionException(e.getTargetException().toString()); 169 } catch (NoSuchMethodException e) { 170 throw new DefinitionException( 171 "mixin factory does not have a valid constructor [" 172 + factoryClassName 173 + "] need to have a signature like this [MyMixinFactory(Class mixin, DeploymentModel scope)]: " 174 + e.toString() 175 ); 176 } catch (Throwable e) { 177 StringBuffer cause = new StringBuffer (); 178 cause.append("could not create mixin container using the implementation specified ["); 179 cause.append(factoryClassName); 180 cause.append("] due to: "); 181 cause.append(e.toString()); 182 throw new DefinitionException(cause.toString()); 183 } 184 } 185 186 199 public static Map getParameters(Class mixinClass, ClassLoader loader) { 200 MixinDefinition mixinDefinition = getMixinDefinition(mixinClass, loader); 201 return mixinDefinition.getParameters(); 202 } 203 204 212 public static MixinDefinition getMixinDefinition(Class mixinClass, ClassLoader visibleFrom) { 213 MixinDefinition mixinDefinition = null; 214 215 Set definitions = SystemDefinitionContainer.getDefinitionsFor(visibleFrom); 216 for (Iterator iterator = definitions.iterator(); iterator.hasNext() && mixinDefinition == null;) { 217 SystemDefinition systemDefinition = (SystemDefinition) iterator.next(); 218 for (Iterator iterator1 = systemDefinition.getMixinDefinitions().iterator(); iterator1.hasNext();) { 219 MixinDefinition mixinDef = (MixinDefinition) iterator1.next(); 220 if (mixinClass.getName().replace('/', '.').equals(mixinDef.getMixinImpl().getName())) { 221 mixinDefinition = mixinDef; 222 break; 223 } 224 } 225 } 226 if (mixinDefinition == null) { 227 throw new DefinitionException("could not find definition for mixin: " + mixinClass.getName() 228 + " (loader " + mixinClass.getClassLoader() + ")" 229 + " from loader " + visibleFrom); 230 } 231 return mixinDefinition; 232 } 233 234 237 private Mixins() { 238 } 239 } 240 | Popular Tags |