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.util; 018 019 import java.rmi.AccessException; 020 import java.rmi.MarshalException; 021 import java.rmi.NoSuchObjectException; 022 import java.rmi.Remote; 023 import java.rmi.RemoteException; 024 import java.lang.reflect.Proxy; 025 import java.lang.reflect.InvocationHandler; 026 import javax.rmi.CORBA.Stub; 027 import javax.rmi.CORBA.Tie; 028 import javax.rmi.CORBA.UtilDelegate; 029 import javax.rmi.CORBA.ValueHandler; 030 import javax.transaction.InvalidTransactionException; 031 import javax.transaction.TransactionRequiredException; 032 import javax.transaction.TransactionRolledbackException; 033 import javax.ejb.EJBHome; 034 import javax.ejb.EJBObject; 035 036 import org.apache.commons.logging.Log; 037 import org.apache.commons.logging.LogFactory; 038 import org.omg.CORBA.CompletionStatus; 039 import org.omg.CORBA.INVALID_TRANSACTION; 040 import org.omg.CORBA.MARSHAL; 041 import org.omg.CORBA.NO_PERMISSION; 042 import org.omg.CORBA.OBJECT_NOT_EXIST; 043 import org.omg.CORBA.ORB; 044 import org.omg.CORBA.SystemException; 045 import org.omg.CORBA.TRANSACTION_REQUIRED; 046 import org.omg.CORBA.TRANSACTION_ROLLEDBACK; 047 import org.omg.CORBA.UNKNOWN; 048 import org.omg.CORBA.portable.InputStream; 049 import org.omg.CORBA.portable.OutputStream; 050 051 import org.apache.geronimo.corba.AdapterWrapper; 052 import org.apache.geronimo.corba.CORBAException; 053 import org.apache.geronimo.corba.RefGenerator; 054 import org.apache.geronimo.corba.StandardServant; 055 import org.apache.openejb.InterfaceType; 056 import org.apache.openejb.BeanType; 057 import org.apache.openejb.core.ivm.BaseEjbProxyHandler; 058 import org.apache.openejb.core.CoreDeploymentInfo; 059 060 /** 061 * @version $Revision: 451417 $ $Date: 2006-09-29 13:13:22 -0700 (Fri, 29 Sep 2006) $ 062 */ 063 public final class UtilDelegateImpl implements UtilDelegate { 064 065 private final Log log = LogFactory.getLog(UtilDelegateImpl.class); 066 private final UtilDelegate delegate; 067 private static ClassLoader classLoader; 068 069 private final static String DELEGATE_NAME = "org.apache.geronimo.corba.UtilDelegateClass"; 070 071 public UtilDelegateImpl() throws ClassNotFoundException, IllegalAccessException, InstantiationException { 072 String value = System.getProperty(DELEGATE_NAME); 073 if (value == null) { 074 log.error("No delegate specfied via " + DELEGATE_NAME); 075 throw new IllegalStateException("The property " + DELEGATE_NAME + " must be defined!"); 076 } 077 078 if (log.isDebugEnabled()) log.debug("Set delegate " + value); 079 delegate = (UtilDelegate) Class.forName(value).newInstance(); 080 } 081 082 static void setClassLoader(ClassLoader classLoader) { 083 UtilDelegateImpl.classLoader = classLoader; 084 } 085 086 public void unexportObject(Remote target) throws NoSuchObjectException { 087 delegate.unexportObject(target); 088 } 089 090 public boolean isLocal(Stub stub) throws RemoteException { 091 return delegate.isLocal(stub); 092 } 093 094 public ValueHandler createValueHandler() { 095 return delegate.createValueHandler(); 096 } 097 098 public Object readAny(InputStream in) { 099 return delegate.readAny(in); 100 } 101 102 public void writeAbstractObject(OutputStream out, Object obj) { 103 delegate.writeAbstractObject(out, obj); 104 } 105 106 public void writeAny(OutputStream out, Object obj) { 107 delegate.writeAny(out, obj); 108 } 109 110 public void writeRemoteObject(OutputStream out, Object obj) { 111 try { 112 if (obj instanceof Tie && ((Tie) obj).getTarget() instanceof Proxy) { 113 obj = ((Tie) obj).getTarget(); 114 } 115 if (obj instanceof Proxy) { 116 obj = convertEJBToCORBAObject((Proxy) obj); 117 } 118 if (obj instanceof StandardServant) { 119 StandardServant servant = (StandardServant) obj; 120 InterfaceType servantType = servant.getInterfaceType(); 121 String deploymentId = servant.getEjbDeployment().getDeploymentId(); 122 try { 123 RefGenerator refGenerator = AdapterWrapper.getRefGenerator(deploymentId); 124 if (refGenerator == null) { 125 throw new MARSHAL("Could not find RefGenerator for deployment id: " + deploymentId); 126 } 127 if (InterfaceType.EJB_HOME == servantType) { 128 obj = refGenerator.genHomeReference(); 129 } else if (InterfaceType.EJB_OBJECT == servantType) { 130 obj = refGenerator.genObjectReference(servant.getPrimaryKey()); 131 } else { 132 log.error("Encountered unknown local invocation handler of type " + servantType + ":" + deploymentId); 133 throw new MARSHAL("Internal server error while marshaling the reply", 0, CompletionStatus.COMPLETED_YES); 134 } 135 } catch (CORBAException e) { 136 log.error("Encountered unknown local invocation handler of type " + servantType + ":" + deploymentId); 137 throw (MARSHAL)new MARSHAL("Internal server error while marshaling the reply", 0, CompletionStatus.COMPLETED_YES).initCause(e); 138 } 139 } 140 delegate.writeRemoteObject(out, obj); 141 } catch (Throwable e) { 142 log.error("Received unexpected exception while marshaling an object reference:", e); 143 throw (MARSHAL)new MARSHAL("Internal server error while marshaling the reply", 0, CompletionStatus.COMPLETED_YES).initCause(e); 144 } 145 } 146 147 public String getCodebase(Class clz) { 148 return delegate.getCodebase(clz); 149 } 150 151 public void registerTarget(Tie tie, Remote target) { 152 delegate.registerTarget(tie, target); 153 } 154 155 public RemoteException wrapException(Throwable obj) { 156 return delegate.wrapException(obj); 157 } 158 159 public RemoteException mapSystemException(SystemException ex) { 160 if (ex instanceof TRANSACTION_ROLLEDBACK) { 161 TransactionRolledbackException transactionRolledbackException = new TransactionRolledbackException(ex.getMessage()); 162 transactionRolledbackException.detail = ex; 163 return transactionRolledbackException; 164 } 165 if (ex instanceof TRANSACTION_REQUIRED) { 166 TransactionRequiredException transactionRequiredException = new TransactionRequiredException(ex.getMessage()); 167 transactionRequiredException.detail = ex; 168 return transactionRequiredException; 169 } 170 if (ex instanceof INVALID_TRANSACTION) { 171 InvalidTransactionException invalidTransactionException = new InvalidTransactionException(ex.getMessage()); 172 invalidTransactionException.detail = ex; 173 return invalidTransactionException; 174 } 175 if (ex instanceof OBJECT_NOT_EXIST) { 176 NoSuchObjectException noSuchObjectException = new NoSuchObjectException(ex.getMessage()); 177 noSuchObjectException.detail = ex; 178 return noSuchObjectException; 179 } 180 if (ex instanceof NO_PERMISSION) { 181 return new AccessException(ex.getMessage(), ex); 182 } 183 if (ex instanceof MARSHAL) { 184 return new MarshalException(ex.getMessage(), ex); 185 } 186 if (ex instanceof UNKNOWN) { 187 return new RemoteException(ex.getMessage(), ex); 188 } 189 return delegate.mapSystemException(ex); 190 } 191 192 public Tie getTie(Remote target) { 193 return delegate.getTie(target); 194 } 195 196 public Object copyObject(Object obj, ORB orb) throws RemoteException { 197 return delegate.copyObject(obj, orb); 198 } 199 200 public Object[] copyObjects(Object[] obj, ORB orb) throws RemoteException { 201 return delegate.copyObjects(obj, orb); 202 } 203 204 public Class loadClass(String className, String remoteCodebase, ClassLoader loader) throws ClassNotFoundException { 205 if (log.isDebugEnabled()) log.debug("Load class: " + className + ", " + remoteCodebase + ", " + loader); 206 207 Class result = null; 208 try { 209 result = delegate.loadClass(className, remoteCodebase, loader); 210 } catch (ClassNotFoundException e) { 211 if (log.isDebugEnabled()) log.debug("Unable to load class from delegate"); 212 } 213 if (result == null && classLoader != null) { 214 if (log.isDebugEnabled()) log.debug("Attempting to load " + className + " from the static class loader"); 215 216 try { 217 result = classLoader.loadClass(className); 218 } catch (ClassNotFoundException e) { 219 if (log.isDebugEnabled()) log.debug("Unable to load " + className + " from the static class loader"); 220 throw e; 221 } 222 223 if (log.isDebugEnabled()) log.debug("result: " + (result == null ? "NULL" : result.getName())); 224 } 225 226 return result; 227 } 228 229 /** 230 * handle activation 231 */ 232 private Object convertEJBToCORBAObject(Proxy proxy) { 233 InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy); 234 if (!(invocationHandler instanceof BaseEjbProxyHandler)) { 235 return proxy; 236 } 237 238 BaseEjbProxyHandler ejbProxyHandler = (BaseEjbProxyHandler) invocationHandler; 239 CoreDeploymentInfo deploymentInfo = ejbProxyHandler.getDeploymentInfo(); 240 String deploymentId = (String) deploymentInfo.getDeploymentID(); 241 try { 242 RefGenerator refGenerator = AdapterWrapper.getRefGenerator(deploymentId); 243 if (refGenerator == null) { 244 throw new MARSHAL("Could not find RefGenerator for deployment id: " +deploymentId); 245 } 246 if (proxy instanceof EJBHome) { 247 return refGenerator.genHomeReference(); 248 } else if (proxy instanceof EJBObject) { 249 Object primaryKey = null; 250 if (deploymentInfo.getComponentType() != BeanType.STATELESS) { 251 EJBObject ejbObject = (EJBObject) proxy; 252 primaryKey = ejbObject.getPrimaryKey(); 253 } 254 return refGenerator.genObjectReference(primaryKey); 255 } else { 256 log.error("Encountered unknown local invocation handler of type " + proxy.getClass().getSuperclass() + ":" + deploymentId); 257 throw new MARSHAL("Internal server error while marshaling the reply", 0, CompletionStatus.COMPLETED_YES); 258 } 259 } catch (CORBAException e) { 260 log.error("Encountered unknown local invocation handler of type " + proxy.getClass().getSuperclass() + ":" + deploymentId); 261 throw (MARSHAL)new MARSHAL("Encountered unknown local invocation handler of type " + proxy.getClass().getSuperclass() + ":" + deploymentId, 0, CompletionStatus.COMPLETED_YES).initCause(e); 262 } catch (RemoteException e) { 263 log.error("Unable to get primary key from bean from bean of type " + proxy.getClass().getSuperclass() + ":" + deploymentId); 264 throw (MARSHAL)new MARSHAL("Unable to get primary key from bean from bean of type " + proxy.getClass().getSuperclass() + ":" + deploymentId, 0, CompletionStatus.COMPLETED_YES).initCause(e); 265 } 266 } 267 }