/*
* 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 org.jboss.com.sun.corba.se.impl.presentation.rmi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.rmi.CORBA.Util;
import org.jboss.com.sun.corba.se.pept.transport.ContactInfoList;
import org.jboss.com.sun.corba.se.spi.orb.ORB;
import org.jboss.com.sun.corba.se.spi.orbutil.proxy.LinkedInvocationHandler;
import org.jboss.com.sun.corba.se.spi.presentation.rmi.DynamicMethodMarshaller;
import org.jboss.com.sun.corba.se.spi.presentation.rmi.PresentationManager;
import org.jboss.com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import org.jboss.com.sun.corba.se.spi.protocol.CorbaClientDelegate;
import org.jboss.com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher;
import org.jboss.com.sun.corba.se.spi.transport.CorbaContactInfoList;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.Delegate;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.CORBA.portable.ServantObject;
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<Void>()
{
public Void 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);
}
}
}
}