KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > kernel > basic > BasicProxyManager


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.kernel.basic;
18
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
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 /**
42  * Creates proxies that communicate directly with a Kernel located in the same
43  * JVM as the client.
44  *
45  * @version $Rev:386515 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
46  */

47 public class BasicProxyManager implements ProxyManager {
48     private final static String JavaDoc 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 JavaDoc interceptors = Collections.synchronizedMap(new BasicProxyMap());
53
54     public BasicProxyManager(Kernel kernel) {
55         this.kernel = kernel;
56     }
57
58     public ProxyFactory createProxyFactory(Class JavaDoc[] types, ClassLoader JavaDoc classLoader) {
59         if (types == null) throw new NullPointerException JavaDoc("type is null");
60         if (types.length == 0) throw new IllegalArgumentException JavaDoc("interface list is empty");
61         if (classLoader == null) throw new NullPointerException JavaDoc("classLoader is null");
62
63         Class JavaDoc managedBean = null;
64         try {
65             managedBean = classLoader.loadClass(MANAGED_BEAN_NAME);
66         } catch (ClassNotFoundException JavaDoc e) {
67             // Can't load GeronimoManagedBean if the incoming type doesn't have a ClassLoader set
68
log.debug("Unable to add GeronimoManagedBean to proxy (specified class loader does not have class)");
69         }
70
71         if(managedBean != null) {
72             Class JavaDoc[] adjusted = new Class JavaDoc[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 JavaDoc createProxy(AbstractName target, Class JavaDoc type) {
82         if (target == null) throw new NullPointerException JavaDoc("target is null");
83         if (type == null) throw new NullPointerException JavaDoc("type is null");
84
85         try {
86             // if the type is visible from the target's classloader use it
87
// otherwise use the type's classloader
88
ClassLoader JavaDoc 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 JavaDoc ignored) {
95                 classLoader = type.getClassLoader();
96             }
97
98             // add any interface exposed by the gbean that is visible from the selected class loader
99
List JavaDoc types = getVisibleInterfaces(target, classLoader, true);
100             if (types == null) types = new ArrayList JavaDoc();
101             types.add(type);
102
103             return createProxyFactory((Class JavaDoc[]) types.toArray(new Class JavaDoc[types.size()]), classLoader).createProxy(target);
104         } catch (GBeanNotFoundException e) {
105             throw new IllegalArgumentException JavaDoc("Could not get GBeanInfo for target object: " + target);
106         }
107     }
108
109     public Object JavaDoc createProxy(AbstractName target, ClassLoader JavaDoc classLoader) {
110         if (target == null) throw new NullPointerException JavaDoc("target is null");
111         if (classLoader == null) throw new NullPointerException JavaDoc("classLoader is null");
112
113         try {
114             List JavaDoc types = getVisibleInterfaces(target, classLoader, true);
115             if (types == null) return null;
116             return createProxyFactory((Class JavaDoc[]) types.toArray(new Class JavaDoc[types.size()]), classLoader).createProxy(target);
117         } catch (GBeanNotFoundException e) {
118             throw new IllegalArgumentException JavaDoc("Could not get GBeanInfo for target object: " + target);
119         }
120     }
121
122     private List JavaDoc getVisibleInterfaces(AbstractName target, ClassLoader JavaDoc classLoader, boolean shouldLog) throws GBeanNotFoundException {
123         GBeanInfo info = kernel.getGBeanInfo(target);
124         Set JavaDoc 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 JavaDoc[] names = (String JavaDoc[]) interfaces.toArray(new String JavaDoc[0]);
132         List JavaDoc types = new ArrayList JavaDoc();
133         for (int i = 0; i < names.length; i++) {
134             try {
135                 Class JavaDoc type = classLoader.loadClass(names[i]);
136                 if (type.isInterface()) {
137                     types.add(type);
138                 }
139             } catch (ClassNotFoundException JavaDoc 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 JavaDoc 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 JavaDoc proxy) {
160         return interceptors.containsKey(proxy);
161     }
162
163     public AbstractName getProxyTarget(Object JavaDoc 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 JavaDoc proxyType;
173         private final FastClass fastClass;
174
175         public ManagedProxyFactory(Class JavaDoc type, ClassLoader JavaDoc classLoader) {
176             this(new Class JavaDoc[]{type}, classLoader);
177         }
178
179         public ManagedProxyFactory(Class JavaDoc[] type, ClassLoader JavaDoc classLoader) {
180             Enhancer enhancer = new Enhancer();
181             if(type.length > 1) { // shrink first -- may reduce from many to one
182
type = ClassLoading.reduceInterfaces(type);
183             }
184             if(type.length == 0) {
185                 throw new IllegalArgumentException JavaDoc("Cannot generate proxy for 0 interfaces!");
186             } else if(type.length == 1) { // Unlikely (as a result of GeronimoManagedBean)
187
enhancer.setSuperclass(type[0]);
188             } else {
189                 if(type[0].isInterface()) {
190                     enhancer.setSuperclass(Object JavaDoc.class);
191                     enhancer.setInterfaces(type);
192                 } else { // there's a class and reduceInterfaces put the class in the first spot
193
Class JavaDoc[] intfs = new Class JavaDoc[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 JavaDoc 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 JavaDoc proxy = fastClass.newInstance();
214                 interceptors.put(proxy, callback);
215                 return proxy;
216             } catch (InvocationTargetException JavaDoc e) {
217                 Throwable JavaDoc cause = e.getCause();
218                 if (cause instanceof RuntimeException JavaDoc) {
219                   throw (RuntimeException JavaDoc) cause;
220                 } else if (cause instanceof Error JavaDoc) {
221                   throw (Error JavaDoc) 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 JavaDoc 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