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.lang.reflect.InvocationTargetException;
020 import java.lang.reflect.Method;
021 import java.util.Collections;
022 import java.util.Map;
023
024 import javax.ejb.EJBObject;
025 import javax.rmi.CORBA.Util;
026
027 import net.sf.cglib.proxy.MethodInterceptor;
028 import net.sf.cglib.proxy.MethodProxy;
029 import org.omg.CORBA.SystemException;
030 import org.omg.CORBA.portable.ApplicationException;
031 import org.omg.CORBA.portable.RemarshalException;
032 import org.omg.CORBA.portable.ServantObject;
033 import org.omg.CORBA_2_3.portable.InputStream;
034 import org.omg.CORBA_2_3.portable.OutputStream;
035
036 /**
037 * @version $Revision: 502310 $ $Date: 2007-02-01 10:34:57 -0800 (Thu, 01 Feb 2007) $
038 */
039 public class StubMethodInterceptor implements MethodInterceptor {
040 private static final Method ISIDENTICAL;
041
042 static {
043 try {
044 ISIDENTICAL = EJBObject.class.getMethod("isIdentical", new Class[]{EJBObject.class});
045 } catch (NoSuchMethodException e) {
046 throw new ExceptionInInitializerError(e);
047 }
048 }
049
050 private final Class type;
051 private final Map operations;
052
053 public StubMethodInterceptor(Class type) {
054 this.type = type;
055 this.operations = Collections.unmodifiableMap(org.apache.geronimo.corba.util.Util.mapMethodToOperation(type));
056 }
057
058 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
059 ClientContextHolderStub stub = (ClientContextHolderStub) proxy;
060
061 // handle is identical in stub to avoid unnecessary round trip
062 if (method.equals(ISIDENTICAL)) {
063 org.omg.CORBA.Object otherObject = (org.omg.CORBA.Object) args[0];
064 return new Boolean(stub._is_equivalent(otherObject));
065 }
066
067 // get the operation name object
068 String operationName = (String) operations.get(method);
069 if (operationName == null) {
070 throw new IllegalStateException("Unknown method: " + method);
071 }
072
073 while (true) {
074 // if this is a stub to a remote object we invoke over the wire
075 if (!Util.isLocal(stub)) {
076
077 InputStream in = null;
078 try {
079 // create the request output stream
080 OutputStream out = (OutputStream) stub._request(operationName, true);
081
082 // write the arguments
083 Class[] parameterTypes = method.getParameterTypes();
084 for (int i = 0; i < parameterTypes.length; i++) {
085 Class parameterType = parameterTypes[i];
086 org.apache.geronimo.corba.util.Util.writeObject(parameterType, args[i], out);
087 }
088
089 // send the invocation
090 in = (InputStream) stub._invoke(out);
091
092 // read the result
093 Object result = org.apache.geronimo.corba.util.Util.readObject(method.getReturnType(), in);
094 return result;
095 } catch (RemarshalException exception) {
096 continue;
097 } catch (ApplicationException exception) {
098 org.apache.geronimo.corba.util.Util.throwException(method, (InputStream) exception.getInputStream());
099 } catch (SystemException e) {
100 throw Util.mapSystemException(e);
101 } finally {
102 stub._releaseReply(in);
103 }
104 } else {
105 // get the servant
106 ServantObject servantObject = stub._servant_preinvoke(operationName, type);
107 if (servantObject == null) {
108 continue;
109 }
110
111 try {
112 // copy the arguments
113 Object[] argsCopy = Util.copyObjects(args, stub._orb());
114
115 // invoke the servant
116 Object result = null;
117 try {
118 result = method.invoke(servantObject.servant, argsCopy);
119 } catch (InvocationTargetException e) {
120 if (e.getCause() != null) {
121 throw e.getCause();
122 }
123 throw e;
124 }
125
126 // copy the result
127 result = Util.copyObject(result, stub._orb());
128
129 return result;
130 } catch (Throwable throwable) {
131 // copy the exception
132 Throwable throwableCopy = (Throwable) Util.copyObject(throwable, stub._orb());
133
134 // if it is one of my exception rethrow it
135 Class[] exceptionTypes = method.getExceptionTypes();
136 for (int i = 0; i < exceptionTypes.length; i++) {
137 Class exceptionType = exceptionTypes[i];
138 if (exceptionType.isInstance(throwableCopy)) {
139 throw throwableCopy;
140 }
141 }
142
143 throw Util.wrapException(throwableCopy);
144 } finally {
145 stub._servant_postinvoke(servantObject);
146 }
147 }
148 }
149 }
150 }