1 /* 2 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.corba.se.impl.presentation.rmi ; 27 28 import java.lang.reflect.InvocationHandler ; 29 import java.lang.reflect.Proxy ; 30 import java.lang.reflect.Method ; 31 32 import org.omg.CORBA.portable.ObjectImpl ; 33 34 import java.io.ObjectStreamException ; 35 import java.io.Serializable ; 36 37 import com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ; 38 import com.sun.corba.se.spi.presentation.rmi.PresentationManager ; 39 import com.sun.corba.se.spi.presentation.rmi.DynamicStub ; 40 41 import com.sun.corba.se.spi.orbutil.proxy.LinkedInvocationHandler ; 42 import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ; 43 import com.sun.corba.se.spi.orbutil.proxy.DelegateInvocationHandlerImpl ; 44 import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandler ; 45 import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl ; 46 import java.security.AccessController; 47 import java.security.PrivilegedAction; 48 49 public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory 50 { 51 private final PresentationManager.ClassData classData ; 52 private final PresentationManager pm ; 53 private Class[] proxyInterfaces ; 54 55 public InvocationHandlerFactoryImpl( PresentationManager pm, 56 PresentationManager.ClassData classData ) 57 { 58 this.classData = classData ; 59 this.pm = pm ; 60 61 Class[] remoteInterfaces = 62 classData.getIDLNameTranslator().getInterfaces() ; 63 proxyInterfaces = new Class[ remoteInterfaces.length + 1 ] ; 64 for (int ctr=0; ctr<remoteInterfaces.length; ctr++) 65 proxyInterfaces[ctr] = remoteInterfaces[ctr] ; 66 67 proxyInterfaces[remoteInterfaces.length] = DynamicStub.class ; 68 } 69 70 private class CustomCompositeInvocationHandlerImpl extends 71 CompositeInvocationHandlerImpl implements LinkedInvocationHandler, 72 Serializable 73 { 74 private transient DynamicStub stub ; 75 76 public void setProxy( Proxy proxy ) 77 { 78 ((DynamicStubImpl)stub).setSelf( (DynamicStub)proxy ) ; 79 } 80 81 public Proxy getProxy() 82 { 83 return (Proxy)((DynamicStubImpl)stub).getSelf() ; 84 } 85 86 public CustomCompositeInvocationHandlerImpl( DynamicStub stub ) 87 { 88 this.stub = stub ; 89 } 90 91 /** Return the stub, which will actually be written to the stream. 92 * It will be custom marshalled, with the actual writing done in 93 * StubIORImpl. There is a corresponding readResolve method on 94 * DynamicStubImpl which will re-create the full invocation 95 * handler on read, and return the invocation handler on the 96 * readResolve method. 97 */ 98 public Object writeReplace() throws ObjectStreamException 99 { 100 return stub ; 101 } 102 } 103 104 public InvocationHandler getInvocationHandler() 105 { 106 final DynamicStub stub = new DynamicStubImpl( 107 classData.getTypeIds() ) ; 108 109 return getInvocationHandler( stub ) ; 110 } 111 112 // This is also used in DynamicStubImpl to implement readResolve. 113 InvocationHandler getInvocationHandler( DynamicStub stub ) 114 { 115 // Create an invocation handler for the methods defined on DynamicStub, 116 // which extends org.omg.CORBA.Object. This handler delegates all 117 // calls directly to a DynamicStubImpl, which extends 118 // org.omg.CORBA.portable.ObjectImpl. 119 final InvocationHandler dynamicStubHandler = 120 DelegateInvocationHandlerImpl.create( stub ) ; 121 122 // Create an invocation handler that handles any remote interface 123 // methods. 124 final InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl( 125 pm, classData, stub ) ; 126 127 // Create a composite handler that handles the DynamicStub interface 128 // as well as the remote interfaces. 129 final CompositeInvocationHandler handler = 130 new CustomCompositeInvocationHandlerImpl( stub ) ; 131 132 AccessController.doPrivileged(new PrivilegedAction<Void>() { 133 @Override 134 public Void run() { 135 handler.addInvocationHandler( DynamicStub.class, 136 dynamicStubHandler ) ; 137 handler.addInvocationHandler( org.omg.CORBA.Object.class, 138 dynamicStubHandler ) ; 139 handler.addInvocationHandler( Object.class, 140 dynamicStubHandler ) ; 141 return null; 142 } 143 }); 144 145 146 // If the method passed to invoke is not from DynamicStub or its superclasses, 147 // it must be from an implemented interface, so we just handle 148 // all of these with the stubMethodHandler. This used to be 149 // done be adding explicit entries for stubMethodHandler for 150 // each remote interface, but that does not work correctly 151 // for abstract interfaces, since the graph analysis ignores 152 // abstract interfaces in order to compute the type ids 153 // correctly (see PresentationManagerImpl.NodeImpl.getChildren). 154 // Rather than produce more graph traversal code to handle this 155 // problem, we simply use a default. 156 // This also points to a possible optimization: just use explict 157 // checks for the three special classes, rather than a general 158 // table lookup that usually fails. 159 handler.setDefaultHandler( stubMethodHandler ) ; 160 161 return handler ; 162 } 163 164 public Class[] getProxyInterfaces() 165 { 166 return proxyInterfaces ; 167 } 168 }