blob: 028580ba24a9b2e56c4ca91aafbcf1cf148b628e [file] [log] [blame]
/*
* 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);
}
}
}
}