1 4 package com.tc.aspectwerkz.proxy; 5 6 7 import com.tc.aspectwerkz.definition.SystemDefinition; 8 import com.tc.aspectwerkz.definition.SystemDefinitionContainer; 9 import com.tc.aspectwerkz.exception.WrappedRuntimeException; 10 11 import java.lang.reflect.InvocationTargetException ; 12 import java.util.Arrays ; 13 import java.util.Map ; 14 import java.util.WeakHashMap ; 15 16 23 public class ProxyDelegationStrategy { 24 25 28 public static final String PROXY_SUFFIX = "$$ProxiedByAWDelegation$$"; 29 30 33 private final static Map PROXY_CLASS_CACHE = new WeakHashMap (); 34 35 44 static Class getProxyClassFor(String proxyName, 45 Class [] interfaces, 46 boolean useCache, 47 boolean makeAdvisable, 48 final SystemDefinition definition) { 49 final Class proxyClass; 50 if (!useCache) { 51 proxyClass = getNewProxyClassFor( 52 proxyName, 53 interfaces, 54 makeAdvisable, 55 definition); 56 } else { 57 CompositeClassKey key = new CompositeClassKey(interfaces); 58 synchronized (PROXY_CLASS_CACHE) { 59 Object cachedProxyClass = PROXY_CLASS_CACHE.get(key); 60 if (cachedProxyClass != null) { 61 return (Class ) cachedProxyClass; 62 } 63 proxyClass = getNewProxyClassFor( 64 proxyName, 65 interfaces, 66 makeAdvisable, 67 definition); 68 PROXY_CLASS_CACHE.put(key, proxyClass); 69 } 70 } 71 ProxyCompilerHelper.compileJoinPoint(proxyClass, definition); 72 return proxyClass; 73 } 74 75 85 static Object newInstance(final Class [] interfaces, 86 final Object [] implementations, 87 final boolean useCache, 88 final boolean makeAdvisable, 89 final SystemDefinition definition) { 90 if (!implementsRespectively(interfaces, implementations)) { 91 throw new RuntimeException ( 92 "Given implementations not consistents with given interfaces"); 93 } 94 Class proxy = getProxyClassFor( 95 definition.getUuid(), 96 interfaces, 97 useCache, 98 makeAdvisable, 99 definition 100 ); 101 try { 102 return proxy.getConstructor(interfaces).newInstance(implementations); 103 } catch (InvocationTargetException t) { 104 throw new WrappedRuntimeException(t.getCause()); 105 } catch (Throwable t) { 106 throw new WrappedRuntimeException(t); 107 } 108 } 109 110 117 private static boolean implementsRespectively(final Class [] interfaces, 118 final Object [] implementations) { 119 if (interfaces.length != implementations.length) { 120 return false; 121 } 122 for (int i = 0; i < interfaces.length; i++) { 123 if (!interfaces[i].isAssignableFrom(implementations[i].getClass())) { 124 return false; 125 } 126 } 127 return true; 128 } 129 130 139 private static Class getNewProxyClassFor(String proxyName, 140 Class [] interfaces, 141 boolean makeAdvisable, 142 final SystemDefinition definition) { 143 ClassLoader loader = getLowestClassLoader(interfaces); 144 if (makeAdvisable) { 145 Proxy.makeProxyAdvisable(proxyName, loader, definition); 146 } 147 final byte[] bytes = ProxyDelegationCompiler.compileProxyFor(loader, interfaces, proxyName); 148 return ProxyCompilerHelper.weaveAndDefineProxyClass( 149 bytes, 150 loader, 151 proxyName, 152 definition 153 ); 154 } 155 156 162 private static ClassLoader getLowestClassLoader(Class [] classes) { 163 ClassLoader loader = classes[0].getClassLoader(); 164 for (int i = 1; i < classes.length; i++) { 165 Class other = classes[i]; 166 if (SystemDefinitionContainer.isChildOf(other.getClassLoader(), loader)) { 167 loader = other.getClassLoader(); 168 } else if (SystemDefinitionContainer.isChildOf(loader, other.getClassLoader())) { 169 ; } else { 171 throw new RuntimeException ("parallel classloader hierarchy not supported"); 172 } 173 } 174 return loader; 175 } 176 177 180 private static class CompositeClassKey { 181 private final Class [] m_interfaces; 182 183 CompositeClassKey(Class [] interfaces) { 184 m_interfaces = interfaces; 185 } 186 187 public boolean equals(Object o) { 188 if (this == o) return true; 189 if (!(o instanceof CompositeClassKey)) return false; 190 191 final CompositeClassKey compositeClassKey = (CompositeClassKey) o; 192 193 if (!Arrays.equals(m_interfaces, compositeClassKey.m_interfaces)) return false; 194 195 return true; 196 } 197 198 public int hashCode() { 199 int result = 1; 200 for (int i = 0; i < m_interfaces.length; i++) { 201 result = 31 * result + m_interfaces[i].hashCode(); 202 } 203 return result; 204 } 205 } 206 207 } 208 | Popular Tags |