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 }