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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 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 }