001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.corba;
018
019 import java.lang.reflect.Method;
020 import java.rmi.AccessException;
021 import java.rmi.MarshalException;
022 import java.rmi.NoSuchObjectException;
023 import java.rmi.Remote;
024 import java.rmi.RemoteException;
025 import javax.transaction.InvalidTransactionException;
026 import javax.transaction.TransactionRequiredException;
027 import javax.transaction.TransactionRolledbackException;
028
029 import net.sf.cglib.proxy.Callback;
030 import net.sf.cglib.proxy.CallbackFilter;
031 import net.sf.cglib.proxy.Enhancer;
032 import net.sf.cglib.proxy.MethodInterceptor;
033 import net.sf.cglib.proxy.MethodProxy;
034 import net.sf.cglib.proxy.NoOp;
035 import org.apache.commons.logging.Log;
036 import org.apache.commons.logging.LogFactory;
037 import org.omg.CORBA.INVALID_TRANSACTION;
038 import org.omg.CORBA.MARSHAL;
039 import org.omg.CORBA.NO_PERMISSION;
040 import org.omg.CORBA.OBJECT_NOT_EXIST;
041 import org.omg.CORBA.TRANSACTION_REQUIRED;
042 import org.omg.CORBA.TRANSACTION_ROLLEDBACK;
043 import org.omg.CORBA.UNKNOWN;
044
045
046 /**
047 * @version $Revision: 465108 $ $Date: 2006-10-17 17:23:40 -0700 (Tue, 17 Oct 2006) $
048 */
049 public class AdapterProxyFactory {
050
051 private final static Log log = LogFactory.getLog(AdapterProxyFactory.class);
052 private final static AdapterMethodInterceptor interceptor = new AdapterMethodInterceptor();
053 private final Enhancer enhancer;
054
055 public AdapterProxyFactory(Class clientInterface) {
056 this(clientInterface, clientInterface.getClassLoader());
057 }
058
059 public AdapterProxyFactory(Class clientInterface, ClassLoader classLoader) {
060 this(new Class[]{clientInterface}, classLoader);
061 }
062
063
064 public AdapterProxyFactory(Class[] clientInterfaces, ClassLoader classLoader) {
065 assert clientInterfaces != null;
066 assert areAllInterfaces(clientInterfaces);
067
068 enhancer = new Enhancer();
069 enhancer.setClassLoader(classLoader);
070 enhancer.setSuperclass(AdapterDelegate.class);
071 enhancer.setInterfaces(clientInterfaces);
072 enhancer.setCallbackTypes(new Class[]{NoOp.class, MethodInterceptor.class});
073 enhancer.setCallbackFilter(FILTER);
074 enhancer.setUseFactory(false);
075 }
076
077 private static boolean areAllInterfaces(Class[] clientInterfaces) {
078 for (int i = 0; i < clientInterfaces.length; i++) {
079 if (clientInterfaces[i] == null || !clientInterfaces[i].isInterface()) {
080 return false;
081 }
082 }
083 return true;
084 }
085
086 public Object create(Remote delegate, ClassLoader classLoader) {
087 return create(new Class[]{Remote.class, ClassLoader.class}, new Object[]{delegate, classLoader});
088 }
089
090 public synchronized Object create(Class[] types, Object[] arguments) {
091 enhancer.setCallbacks(new Callback[]{NoOp.INSTANCE, interceptor});
092 return enhancer.create(types, arguments);
093 }
094
095 private final static class AdapterMethodInterceptor implements MethodInterceptor {
096
097 public final Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
098 ClassLoader savedCL = Thread.currentThread().getContextClassLoader();
099 try {
100 AdapterDelegate delegate = (AdapterDelegate) o;
101 Thread.currentThread().setContextClassLoader(delegate.getClassLoader());
102
103 if (log.isDebugEnabled()) log.debug("Calling " + method.getName());
104
105 return methodProxy.invoke(delegate.getDelegate(), args);
106 } catch (TransactionRolledbackException e) {
107 log.debug("TransactionRolledbackException", e);
108 throw new TRANSACTION_ROLLEDBACK(e.toString()).initCause(e);
109 } catch (TransactionRequiredException e) {
110 log.debug("TransactionRequiredException", e);
111 throw new TRANSACTION_REQUIRED(e.toString()).initCause(e);
112 } catch (InvalidTransactionException e) {
113 log.debug("InvalidTransactionException", e);
114 throw new INVALID_TRANSACTION(e.toString()).initCause(e);
115 } catch (NoSuchObjectException e) {
116 log.debug("NoSuchObjectException", e);
117 throw new OBJECT_NOT_EXIST(e.toString()).initCause(e);
118 } catch (AccessException e) {
119 log.debug("AccessException", e);
120 throw new NO_PERMISSION(e.toString()).initCause(e);
121 } catch (MarshalException e) {
122 log.debug("MarshalException", e);
123 throw new MARSHAL(e.toString()).initCause(e);
124 } catch (RemoteException e) {
125 log.debug("RemoteException", e);
126 throw new UNKNOWN(e.toString()).initCause(e);
127 } finally {
128 Thread.currentThread().setContextClassLoader(savedCL);
129 }
130 }
131 }
132
133 private static final CallbackFilter FILTER = new CallbackFilter() {
134 public int accept(Method method) {
135 if (method.getName().equals("finalize") &&
136 method.getParameterTypes().length == 0 &&
137 method.getReturnType() == Void.TYPE) {
138 return 0;
139 }
140 return 1;
141 }
142 };
143 }
144