1 17 package org.apache.geronimo.kernel.basic; 18 19 import java.lang.reflect.InvocationTargetException ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 import net.sf.cglib.proxy.Callback; 27 import net.sf.cglib.proxy.Enhancer; 28 import net.sf.cglib.proxy.MethodInterceptor; 29 import net.sf.cglib.reflect.FastClass; 30 import org.apache.commons.logging.Log; 31 import org.apache.commons.logging.LogFactory; 32 import org.apache.geronimo.gbean.AbstractName; 33 import org.apache.geronimo.gbean.GBeanInfo; 34 import org.apache.geronimo.kernel.ClassLoading; 35 import org.apache.geronimo.kernel.GBeanNotFoundException; 36 import org.apache.geronimo.kernel.Kernel; 37 import org.apache.geronimo.kernel.proxy.ProxyCreationException; 38 import org.apache.geronimo.kernel.proxy.ProxyFactory; 39 import org.apache.geronimo.kernel.proxy.ProxyManager; 40 41 47 public class BasicProxyManager implements ProxyManager { 48 private final static String MANAGED_BEAN_NAME = "org.apache.geronimo.kernel.proxy.GeronimoManagedBean"; 49 private final static Log log = LogFactory.getLog(BasicProxyManager.class); 50 private final Kernel kernel; 51 52 private final Map interceptors = Collections.synchronizedMap(new BasicProxyMap()); 53 54 public BasicProxyManager(Kernel kernel) { 55 this.kernel = kernel; 56 } 57 58 public ProxyFactory createProxyFactory(Class [] types, ClassLoader classLoader) { 59 if (types == null) throw new NullPointerException ("type is null"); 60 if (types.length == 0) throw new IllegalArgumentException ("interface list is empty"); 61 if (classLoader == null) throw new NullPointerException ("classLoader is null"); 62 63 Class managedBean = null; 64 try { 65 managedBean = classLoader.loadClass(MANAGED_BEAN_NAME); 66 } catch (ClassNotFoundException e) { 67 log.debug("Unable to add GeronimoManagedBean to proxy (specified class loader does not have class)"); 69 } 70 71 if(managedBean != null) { 72 Class [] adjusted = new Class [types.length+1]; 73 System.arraycopy(types, 0, adjusted, 0, types.length); 74 adjusted[types.length] = managedBean; 75 types = adjusted; 76 } 77 78 return new ManagedProxyFactory(types, classLoader); 79 } 80 81 public Object createProxy(AbstractName target, Class type) { 82 if (target == null) throw new NullPointerException ("target is null"); 83 if (type == null) throw new NullPointerException ("type is null"); 84 85 try { 86 ClassLoader classLoader; 89 try { 90 classLoader = kernel.getClassLoaderFor(target); 91 if (!type.equals(ClassLoading.loadClass(type.getName(), classLoader))) { 92 classLoader = type.getClassLoader(); 93 } 94 } catch (Exception ignored) { 95 classLoader = type.getClassLoader(); 96 } 97 98 List types = getVisibleInterfaces(target, classLoader, true); 100 if (types == null) types = new ArrayList (); 101 types.add(type); 102 103 return createProxyFactory((Class []) types.toArray(new Class [types.size()]), classLoader).createProxy(target); 104 } catch (GBeanNotFoundException e) { 105 throw new IllegalArgumentException ("Could not get GBeanInfo for target object: " + target); 106 } 107 } 108 109 public Object createProxy(AbstractName target, ClassLoader classLoader) { 110 if (target == null) throw new NullPointerException ("target is null"); 111 if (classLoader == null) throw new NullPointerException ("classLoader is null"); 112 113 try { 114 List types = getVisibleInterfaces(target, classLoader, true); 115 if (types == null) return null; 116 return createProxyFactory((Class []) types.toArray(new Class [types.size()]), classLoader).createProxy(target); 117 } catch (GBeanNotFoundException e) { 118 throw new IllegalArgumentException ("Could not get GBeanInfo for target object: " + target); 119 } 120 } 121 122 private List getVisibleInterfaces(AbstractName target, ClassLoader classLoader, boolean shouldLog) throws GBeanNotFoundException { 123 GBeanInfo info = kernel.getGBeanInfo(target); 124 Set interfaces = info.getInterfaces(); 125 if(interfaces.size() == 0) { 126 if (shouldLog) { 127 log.warn("No interfaces found for " + target + " ("+target+")"); 128 } 129 return null; 130 } 131 String [] names = (String []) interfaces.toArray(new String [0]); 132 List types = new ArrayList (); 133 for (int i = 0; i < names.length; i++) { 134 try { 135 Class type = classLoader.loadClass(names[i]); 136 if (type.isInterface()) { 137 types.add(type); 138 } 139 } catch (ClassNotFoundException e) { 140 if (shouldLog) { 141 log.warn("Could not load interface "+names[i]+" in provided ClassLoader for "+target); 142 } 143 } 144 } 145 return types; 146 } 147 148 public void destroyProxy(Object proxy) { 149 if (proxy == null) { 150 return; 151 } 152 153 MethodInterceptor methodInterceptor = (MethodInterceptor) interceptors.remove(proxy); 154 if (methodInterceptor != null) { 155 doDestroy(methodInterceptor); 156 } 157 } 158 159 public boolean isProxy(Object proxy) { 160 return interceptors.containsKey(proxy); 161 } 162 163 public AbstractName getProxyTarget(Object proxy) { 164 MethodInterceptor methodInterceptor = (MethodInterceptor) interceptors.get(proxy); 165 if (methodInterceptor == null) { 166 return null; 167 } 168 return getAbstractName(methodInterceptor); 169 } 170 171 private class ManagedProxyFactory implements ProxyFactory { 172 private final Class proxyType; 173 private final FastClass fastClass; 174 175 public ManagedProxyFactory(Class type, ClassLoader classLoader) { 176 this(new Class []{type}, classLoader); 177 } 178 179 public ManagedProxyFactory(Class [] type, ClassLoader classLoader) { 180 Enhancer enhancer = new Enhancer(); 181 if(type.length > 1) { type = ClassLoading.reduceInterfaces(type); 183 } 184 if(type.length == 0) { 185 throw new IllegalArgumentException ("Cannot generate proxy for 0 interfaces!"); 186 } else if(type.length == 1) { enhancer.setSuperclass(type[0]); 188 } else { 189 if(type[0].isInterface()) { 190 enhancer.setSuperclass(Object .class); 191 enhancer.setInterfaces(type); 192 } else { Class [] intfs = new Class [type.length-1]; 194 System.arraycopy(type, 1, intfs, 0, intfs.length); 195 enhancer.setSuperclass(type[0]); 196 enhancer.setInterfaces(intfs); 197 } 198 } 199 enhancer.setClassLoader(classLoader); 200 enhancer.setCallbackType(MethodInterceptor.class); 201 enhancer.setUseFactory(false); 202 proxyType = enhancer.createClass(); 203 fastClass = FastClass.create(proxyType); 204 } 205 206 public Object createProxy(AbstractName target) { 207 assert target != null: "target is null"; 208 209 Callback callback = getMethodInterceptor(proxyType, kernel, target); 210 211 Enhancer.registerCallbacks(proxyType, new Callback[]{callback}); 212 try { 213 Object proxy = fastClass.newInstance(); 214 interceptors.put(proxy, callback); 215 return proxy; 216 } catch (InvocationTargetException e) { 217 Throwable cause = e.getCause(); 218 if (cause instanceof RuntimeException ) { 219 throw (RuntimeException ) cause; 220 } else if (cause instanceof Error ) { 221 throw (Error ) cause; 222 } else if (cause != null) { 223 throw new ProxyCreationException(cause); 224 } else { 225 throw new ProxyCreationException(e); 226 } 227 } 228 } 229 } 230 231 protected Callback getMethodInterceptor(Class proxyType, Kernel kernel, AbstractName target) { 232 return new ProxyMethodInterceptor(proxyType, kernel, target); 233 } 234 235 protected void doDestroy(MethodInterceptor methodInterceptor) { 236 ((ProxyMethodInterceptor)methodInterceptor).destroy(); 237 } 238 239 protected AbstractName getAbstractName(MethodInterceptor methodInterceptor) { 240 return ((ProxyMethodInterceptor)methodInterceptor).getAbstractName(); 241 } 242 } 243 | Popular Tags |