/* * Copyright (c) 2004, 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.io.ObjectStreamException; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import org.jboss.com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandler; import org.jboss.com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl; import org.jboss.com.sun.corba.se.spi.orbutil.proxy.DelegateInvocationHandlerImpl; import org.jboss.com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory; import org.jboss.com.sun.corba.se.spi.orbutil.proxy.LinkedInvocationHandler; import org.jboss.com.sun.corba.se.spi.presentation.rmi.DynamicStub; import org.jboss.com.sun.corba.se.spi.presentation.rmi.PresentationManager; public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory { private final PresentationManager.ClassData classData; private final PresentationManager pm; private Class<?>[] proxyInterfaces; public InvocationHandlerFactoryImpl(PresentationManager pm, PresentationManager.ClassData classData) { this.classData = classData; this.pm = pm; Class<?>[] remoteInterfaces = classData.getIDLNameTranslator().getInterfaces(); proxyInterfaces = new Class[remoteInterfaces.length + 1]; for (int ctr = 0; ctr < remoteInterfaces.length; ctr++) proxyInterfaces[ctr] = remoteInterfaces[ctr]; proxyInterfaces[remoteInterfaces.length] = DynamicStub.class; } private class CustomCompositeInvocationHandlerImpl extends CompositeInvocationHandlerImpl implements LinkedInvocationHandler, Serializable { private transient DynamicStub stub; public void setProxy(Proxy proxy) { ((DynamicStubImpl) stub).setSelf((DynamicStub) proxy); } public Proxy getProxy() { return (Proxy) ((DynamicStubImpl) stub).getSelf(); } public CustomCompositeInvocationHandlerImpl(DynamicStub stub) { this.stub = stub; } /** * Return the stub, which will actually be written to the stream. It will be custom marshalled, with the actual * writing done in StubIORImpl. There is a corresponding readResolve method on DynamicStubImpl which will * re-create the full invocation handler on read, and return the invocation handler on the readResolve method. */ public Object writeReplace() throws ObjectStreamException { return stub; } } public InvocationHandler getInvocationHandler() { final DynamicStub stub = new DynamicStubImpl(classData.getTypeIds()); return getInvocationHandler(stub); } // This is also used in DynamicStubImpl to implement readResolve. InvocationHandler getInvocationHandler(DynamicStub stub) { // Create an invocation handler for the methods defined on DynamicStub, which extends org.omg.CORBA.Object. This // handler delegates all calls directly to a DynamicStubImpl, which extends org.omg.CORBA.portable.ObjectImpl. InvocationHandler dynamicStubHandler = DelegateInvocationHandlerImpl.create(stub); // Create an invocation handler that handles any remote interface methods. InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl(pm, classData, stub); // Create a composite handler that handles the DynamicStub interface as well as the remote interfaces. final CompositeInvocationHandler handler = new CustomCompositeInvocationHandlerImpl(stub); handler.addInvocationHandler(DynamicStub.class, dynamicStubHandler); handler.addInvocationHandler(org.omg.CORBA.Object.class, dynamicStubHandler); handler.addInvocationHandler(Object.class, dynamicStubHandler); // If the method passed to invoke is not from DynamicStub or its superclasses, it must be from an implemented // interface, so we just handle all of these with the stubMethodHandler. This used to be done be adding explicit // entries for stubMethodHandler for each remote interface, but that does not work correctly for abstract // interfaces, since the graph analysis ignores abstract interfaces in order to compute the type ids correctly // (see PresentationManagerImpl.NodeImpl.getChildren). Rather than produce more graph traversal code to handle // this problem, we simply use a default. This also points to a possible optimization: just use explicit checks // for the three special classes, rather than a general table lookup that usually fails. handler.setDefaultHandler(stubMethodHandler); return handler; } public Class<?>[] getProxyInterfaces() { return proxyInterfaces; } }