| /* |
| * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.corba.se.impl.presentation.rmi ; |
| |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| |
| import java.lang.reflect.Method ; |
| import java.lang.reflect.InvocationHandler ; |
| import java.lang.reflect.Proxy ; |
| import java.lang.reflect.InvocationTargetException ; |
| |
| import java.io.ObjectInputStream ; |
| import java.io.ObjectOutputStream ; |
| import java.io.IOException ; |
| |
| import java.rmi.Remote ; |
| |
| import javax.rmi.CORBA.Util ; |
| |
| import org.omg.CORBA.portable.ObjectImpl ; |
| import org.omg.CORBA.portable.Delegate ; |
| import org.omg.CORBA.portable.ServantObject ; |
| import org.omg.CORBA.portable.ApplicationException ; |
| import org.omg.CORBA.portable.RemarshalException ; |
| |
| import org.omg.CORBA.SystemException ; |
| |
| import com.sun.corba.se.spi.orb.ORB ; |
| |
| import com.sun.corba.se.pept.transport.ContactInfoList ; |
| |
| import com.sun.corba.se.spi.transport.CorbaContactInfoList ; |
| |
| import com.sun.corba.se.spi.protocol.CorbaClientDelegate ; |
| import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher ; |
| |
| import com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ; |
| import com.sun.corba.se.spi.presentation.rmi.DynamicMethodMarshaller ; |
| import com.sun.corba.se.spi.presentation.rmi.PresentationManager ; |
| import com.sun.corba.se.spi.presentation.rmi.StubAdapter ; |
| |
| import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ; |
| import com.sun.corba.se.spi.orbutil.proxy.LinkedInvocationHandler ; |
| |
| import com.sun.corba.se.impl.corba.CORBAObjectImpl ; |
| |
| public final class StubInvocationHandlerImpl implements LinkedInvocationHandler |
| { |
| private transient PresentationManager.ClassData classData ; |
| private transient PresentationManager pm ; |
| private transient org.omg.CORBA.Object stub ; |
| private transient Proxy self ; |
| |
| public void setProxy( Proxy self ) |
| { |
| this.self = self ; |
| } |
| |
| public Proxy getProxy() |
| { |
| return self ; |
| } |
| |
| public StubInvocationHandlerImpl( PresentationManager pm, |
| PresentationManager.ClassData classData, org.omg.CORBA.Object stub ) |
| { |
| SecurityManager s = System.getSecurityManager(); |
| if (s != null) { |
| s.checkPermission(new DynamicAccessPermission("access")); |
| } |
| this.classData = classData ; |
| this.pm = pm ; |
| this.stub = stub ; |
| } |
| |
| private boolean isLocal() |
| { |
| boolean result = false ; |
| Delegate delegate = StubAdapter.getDelegate( stub ) ; |
| |
| if (delegate instanceof CorbaClientDelegate) { |
| CorbaClientDelegate cdel = (CorbaClientDelegate)delegate ; |
| ContactInfoList cil = cdel.getContactInfoList() ; |
| if (cil instanceof CorbaContactInfoList) { |
| CorbaContactInfoList ccil = (CorbaContactInfoList)cil ; |
| LocalClientRequestDispatcher lcrd = |
| ccil.getLocalClientRequestDispatcher() ; |
| result = lcrd.useLocalInvocation( null ) ; |
| } |
| } |
| |
| return result ; |
| } |
| |
| /** Invoke the given method with the args and return the result. |
| * This may result in a remote invocation. |
| * @param proxy The proxy used for this class (null if not using java.lang.reflect.Proxy) |
| */ |
| public Object invoke( Object proxy, final Method method, |
| Object[] args ) throws Throwable |
| { |
| String giopMethodName = classData.getIDLNameTranslator(). |
| getIDLName( method ) ; |
| DynamicMethodMarshaller dmm = |
| pm.getDynamicMethodMarshaller( method ) ; |
| |
| Delegate delegate = null ; |
| try { |
| delegate = StubAdapter.getDelegate( stub ) ; |
| } catch (SystemException ex) { |
| throw Util.mapSystemException(ex) ; |
| } |
| |
| if (!isLocal()) { |
| try { |
| org.omg.CORBA_2_3.portable.InputStream in = null ; |
| try { |
| // create request |
| org.omg.CORBA_2_3.portable.OutputStream out = |
| (org.omg.CORBA_2_3.portable.OutputStream) |
| delegate.request( stub, giopMethodName, true); |
| |
| // marshal arguments |
| dmm.writeArguments( out, args ) ; |
| |
| // finish invocation |
| in = (org.omg.CORBA_2_3.portable.InputStream) |
| delegate.invoke( stub, out); |
| |
| // unmarshal result |
| return dmm.readResult( in ) ; |
| } catch (ApplicationException ex) { |
| throw dmm.readException( ex ) ; |
| } catch (RemarshalException ex) { |
| return invoke( proxy, method, args ) ; |
| } finally { |
| delegate.releaseReply( stub, in ); |
| } |
| } catch (SystemException ex) { |
| throw Util.mapSystemException(ex) ; |
| } |
| } else { |
| // local branch |
| ORB orb = (ORB)delegate.orb( stub ) ; |
| ServantObject so = delegate.servant_preinvoke( stub, giopMethodName, |
| method.getDeclaringClass() ); |
| if (so == null) { |
| return invoke( stub, method, args ) ; |
| } |
| try { |
| Object[] copies = dmm.copyArguments( args, orb ) ; |
| |
| if (!method.isAccessible()) { |
| // Make sure that we can invoke a method from a normally |
| // inaccessible package, as this reflective class must always |
| // be able to invoke a non-public method. |
| AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| method.setAccessible( true ) ; |
| return null ; |
| } |
| } ) ; |
| } |
| |
| Object result = method.invoke( so.servant, copies ) ; |
| |
| return dmm.copyResult( result, orb ) ; |
| } catch (InvocationTargetException ex) { |
| Throwable mex = ex.getCause() ; |
| // mex should never be null, as null cannot be thrown |
| Throwable exCopy = (Throwable)Util.copyObject(mex,orb); |
| if (dmm.isDeclaredException( exCopy )) |
| throw exCopy ; |
| else |
| throw Util.wrapException(exCopy); |
| } catch (Throwable thr) { |
| if (thr instanceof ThreadDeath) |
| throw (ThreadDeath)thr ; |
| |
| // This is not a user thrown exception from the |
| // method call, so don't copy it. This is either |
| // an error or a reflective invoke exception. |
| throw Util.wrapException( thr ) ; |
| } finally { |
| delegate.servant_postinvoke( stub, so); |
| } |
| } |
| } |
| } |