/* * @(#)StubFactoryImpl.java 1.9 03/12/03 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ 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); } } } }