/* * 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); } } } }