1 8 package org.codehaus.aspectwerkz.proxy; 9 10 import java.util.WeakHashMap ; 11 import java.util.Map ; 12 import java.util.Set ; 13 import java.util.Iterator ; 14 15 import org.codehaus.aspectwerkz.hook.impl.ClassPreProcessorHelper; 16 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; 17 import org.codehaus.aspectwerkz.definition.DefinitionParserHelper; 18 import org.codehaus.aspectwerkz.definition.SystemDefinition; 19 import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer; 20 import org.codehaus.aspectwerkz.intercept.AdvisableImpl; 21 import org.codehaus.aspectwerkz.DeploymentModel; 22 23 29 public class Proxy { 30 31 34 public static final String PROXY_SUFFIX_START = "$$ProxiedByAW$$"; 35 36 39 private static final Map PROXY_CLASS_CACHE = new WeakHashMap (); 40 41 50 public static Object newInstance(final Class clazz) { 51 try { 52 Class proxyClass = getProxyClassFor(clazz, true, false); 53 return proxyClass.newInstance(); 54 } catch (Throwable e) { 55 e.printStackTrace(); 56 throw new Error (e.toString()); 57 } 58 } 59 60 71 public static Object newInstance(final Class clazz, final Class [] argumentTypes, final Object [] argumentValues) { 72 try { 73 Class proxyClass = getProxyClassFor(clazz, true, false); 74 return proxyClass.getDeclaredConstructor(argumentTypes).newInstance(argumentValues); 75 } catch (Throwable e) { 76 e.printStackTrace(); 77 throw new Error (e.toString()); 78 } 79 } 80 81 91 public static Object newInstance(final Class clazz, final boolean useCache, final boolean makeAdvisable) { 92 try { 93 Class proxyClass = getProxyClassFor(clazz, useCache, makeAdvisable); 94 return proxyClass.newInstance(); 95 } catch (Throwable e) { 96 e.printStackTrace(); 97 throw new Error (e.toString()); 98 } 99 } 100 101 113 public static Object newInstance(final Class clazz, 114 final Class [] argumentTypes, 115 final Object [] argumentValues, 116 final boolean useCache, 117 final boolean makeAdvisable) { 118 try { 119 Class proxyClass = getProxyClassFor(clazz, useCache, makeAdvisable); 120 return proxyClass.getDeclaredConstructor(argumentTypes).newInstance(argumentValues); 121 } catch (Throwable e) { 122 e.printStackTrace(); 123 throw new Error (e.toString()); 124 } 125 } 126 127 136 public static Class getProxyClassFor(final Class clazz, final boolean useCache, final boolean makeAdvisable) { 137 138 if (clazz.getName().startsWith("java.")) { 140 throw new RuntimeException ("can not create proxies from system classes (java.*)"); 141 } 142 if (!useCache) { 143 return getNewProxyClassFor(clazz, makeAdvisable); 144 } else { 145 synchronized (PROXY_CLASS_CACHE) { 146 Object cachedProxyClass = PROXY_CLASS_CACHE.get(clazz); 147 if (cachedProxyClass != null) { 148 return (Class ) cachedProxyClass; 149 } 150 Class proxyClass = getNewProxyClassFor(clazz, makeAdvisable); 151 PROXY_CLASS_CACHE.put(clazz, proxyClass); 152 return proxyClass; 153 } 154 } 155 } 156 157 166 private static Class getNewProxyClassFor(final Class clazz, final boolean makeAdvisable) { 167 ClassLoader loader = clazz.getClassLoader(); 168 String proxyClassName = getUniqueClassNameForProxy(clazz); 169 170 if (makeAdvisable) { 171 makeProxyAdvisable(clazz); 172 } 173 174 byte[] bytes = ProxyCompiler.compileProxyFor(clazz, proxyClassName); 175 byte[] transformedBytes = ClassPreProcessorHelper.defineClass0Pre( 176 loader, proxyClassName, bytes, 0, bytes.length, null 177 ); 178 179 return AsmHelper.defineClass(loader, transformedBytes, proxyClassName); 180 } 181 182 188 private static String getUniqueClassNameForProxy(final Class clazz) { 189 return clazz.getName().replace('.', '/') + PROXY_SUFFIX_START + new Long (Uuid.newUuid()).toString(); 190 } 191 192 198 public static String getUniqueClassNameFromProxy(final String proxyClassName) { 199 int index = proxyClassName.lastIndexOf(PROXY_SUFFIX_START); 200 if (index > 0) { 201 return proxyClassName.substring(0, index); 202 } else { 203 return null; 204 } 205 } 206 207 213 private static void makeProxyAdvisable(final Class clazz) { 214 SystemDefinition definition = SystemDefinitionContainer.getVirtualDefinitionAt(clazz.getClassLoader()); 216 addAdvisableDefToSystemDef(clazz, definition); 217 } 218 219 private static void addAdvisableDefToSystemDef(final Class clazz, final SystemDefinition definition) { 220 String withinPointcut = "within(" + clazz.getName().replace('/', '.') + ')'; 221 definition.addMixinDefinition( 222 DefinitionParserHelper.createAndAddMixinDefToSystemDef( 223 AdvisableImpl.CLASS_INFO, 224 withinPointcut, 225 DeploymentModel.PER_INSTANCE, 226 false, 227 definition 228 ) 229 ); 230 DefinitionParserHelper.createAndAddAdvisableDef( 231 "(execution(!static * *.*(..)) && " + withinPointcut + ')', 232 definition 233 ); 234 } 235 } 236 | Popular Tags |