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