InvocationHandlerFactoryImpl.java revision 608:7e06bf1dcb09
1119418Sobrien/*
2102596Smjacob * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
3101704Smjacob * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4101704Smjacob *
5119418Sobrien * This code is free software; you can redistribute it and/or modify it
6101704Smjacob * under the terms of the GNU General Public License version 2 only, as
7119418Sobrien * published by the Free Software Foundation.  Oracle designates this
8119418Sobrien * particular file as subject to the "Classpath" exception as provided
9119418Sobrien * by Oracle in the LICENSE file that accompanied this code.
10101704Smjacob *
11101704Smjacob * This code is distributed in the hope that it will be useful, but WITHOUT
12101704Smjacob * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13101704Smjacob * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14101704Smjacob * version 2 for more details (a copy is included in the LICENSE file that
15101704Smjacob * accompanied this code).
16101704Smjacob *
17101704Smjacob * You should have received a copy of the GNU General Public License version
18101704Smjacob * 2 along with this work; if not, write to the Free Software Foundation,
19101704Smjacob * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20101704Smjacob *
21101704Smjacob * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22101704Smjacob * or visit www.oracle.com if you need additional information or have any
23101704Smjacob * questions.
24101704Smjacob */
25101704Smjacob
26101704Smjacobpackage com.sun.corba.se.impl.presentation.rmi ;
27101704Smjacob
28101704Smjacobimport java.lang.reflect.InvocationHandler ;
29101704Smjacobimport java.lang.reflect.Proxy ;
30101704Smjacobimport java.lang.reflect.Method ;
31101704Smjacob
32156000Smjacobimport org.omg.CORBA.portable.ObjectImpl ;
33156000Smjacob
34156000Smjacobimport java.io.ObjectStreamException ;
35156000Smjacobimport java.io.Serializable ;
36156000Smjacob
37156000Smjacobimport com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ;
38156000Smjacobimport com.sun.corba.se.spi.presentation.rmi.PresentationManager ;
39156000Smjacobimport com.sun.corba.se.spi.presentation.rmi.DynamicStub ;
40156000Smjacob
41156000Smjacobimport com.sun.corba.se.spi.orbutil.proxy.LinkedInvocationHandler ;
42156000Smjacobimport com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ;
43156000Smjacobimport com.sun.corba.se.spi.orbutil.proxy.DelegateInvocationHandlerImpl ;
44156000Smjacobimport com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandler ;
45156000Smjacobimport com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl ;
46156000Smjacobimport java.security.AccessController;
47156000Smjacobimport java.security.PrivilegedAction;
48156000Smjacob
49156000Smjacobpublic class InvocationHandlerFactoryImpl implements InvocationHandlerFactory
50156000Smjacob{
51156000Smjacob    private final PresentationManager.ClassData classData ;
52156000Smjacob    private final PresentationManager pm ;
53156000Smjacob    private Class[] proxyInterfaces ;
54156000Smjacob
55156000Smjacob    public InvocationHandlerFactoryImpl( PresentationManager pm,
56156000Smjacob        PresentationManager.ClassData classData )
57156000Smjacob    {
58156000Smjacob        this.classData = classData ;
59156000Smjacob        this.pm = pm ;
60156000Smjacob
61156000Smjacob        Class[] remoteInterfaces =
62156000Smjacob            classData.getIDLNameTranslator().getInterfaces() ;
63156000Smjacob        proxyInterfaces = new Class[ remoteInterfaces.length + 1 ] ;
64159052Smjacob        for (int ctr=0; ctr<remoteInterfaces.length; ctr++)
65159052Smjacob            proxyInterfaces[ctr] = remoteInterfaces[ctr] ;
66159052Smjacob
67156000Smjacob        proxyInterfaces[remoteInterfaces.length] = DynamicStub.class ;
68147883Sscottl    }
69147883Sscottl
70147883Sscottl    private class CustomCompositeInvocationHandlerImpl extends
71147883Sscottl        CompositeInvocationHandlerImpl implements LinkedInvocationHandler,
72147883Sscottl        Serializable
73147883Sscottl    {
74147883Sscottl        private transient DynamicStub stub ;
75147883Sscottl
76147883Sscottl        public void setProxy( Proxy proxy )
77147883Sscottl        {
78147883Sscottl            ((DynamicStubImpl)stub).setSelf( (DynamicStub)proxy ) ;
79147883Sscottl        }
80147883Sscottl
81147883Sscottl        public Proxy getProxy()
82147883Sscottl        {
83147883Sscottl            return (Proxy)((DynamicStubImpl)stub).getSelf() ;
84148679Sgibbs        }
85148679Sgibbs
86148679Sgibbs        public CustomCompositeInvocationHandlerImpl( DynamicStub stub )
87147883Sscottl        {
88147883Sscottl            this.stub = stub ;
89147883Sscottl        }
90147883Sscottl
91147883Sscottl        /** Return the stub, which will actually be written to the stream.
92147883Sscottl         * It will be custom marshalled, with the actual writing done in
93147883Sscottl         * StubIORImpl.  There is a corresponding readResolve method on
94147883Sscottl         * DynamicStubImpl which will re-create the full invocation
95147883Sscottl         * handler on read, and return the invocation handler on the
96147883Sscottl         * readResolve method.
97147883Sscottl         */
98147883Sscottl        public Object writeReplace() throws ObjectStreamException
99147883Sscottl        {
100101704Smjacob            return stub ;
101119418Sobrien        }
102119418Sobrien    }
103119418Sobrien
104147883Sscottl    public InvocationHandler getInvocationHandler()
105147883Sscottl    {
106147883Sscottl        final DynamicStub stub = new DynamicStubImpl(
107102199Smjacob            classData.getTypeIds() ) ;
108165814Smjacob
109166721Sjhb        return getInvocationHandler( stub ) ;
110165814Smjacob    }
111165814Smjacob
112166721Sjhb    // This is also used in DynamicStubImpl to implement readResolve.
113165814Smjacob    InvocationHandler getInvocationHandler( DynamicStub stub )
114165814Smjacob    {
115101704Smjacob        // Create an invocation handler for the methods defined on DynamicStub,
116101704Smjacob        // which extends org.omg.CORBA.Object.  This handler delegates all
117101704Smjacob        // calls directly to a DynamicStubImpl, which extends
118101704Smjacob        // org.omg.CORBA.portable.ObjectImpl.
119101704Smjacob        final InvocationHandler dynamicStubHandler =
120101704Smjacob            DelegateInvocationHandlerImpl.create( stub ) ;
121101704Smjacob
122101704Smjacob        // Create an invocation handler that handles any remote interface
123101704Smjacob        // methods.
124102596Smjacob        final InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl(
125102596Smjacob            pm, classData, stub ) ;
126102596Smjacob
127102596Smjacob        // Create a composite handler that handles the DynamicStub interface
128103829Smjacob        // as well as the remote interfaces.
129103829Smjacob        final CompositeInvocationHandler handler =
130103829Smjacob            new CustomCompositeInvocationHandlerImpl( stub ) ;
131103829Smjacob
132101704Smjacob        AccessController.doPrivileged(new PrivilegedAction<Void>() {
133101704Smjacob            @Override
134101704Smjacob            public Void run() {
135101704Smjacob        handler.addInvocationHandler( DynamicStub.class,
136150007Smjacob            dynamicStubHandler ) ;
137150007Smjacob        handler.addInvocationHandler( org.omg.CORBA.Object.class,
138150007Smjacob            dynamicStubHandler ) ;
139150007Smjacob        handler.addInvocationHandler( Object.class,
140159494Smjacob            dynamicStubHandler ) ;
141159494Smjacob                return null;
142159494Smjacob            }
143159494Smjacob        });
144158279Smjacob
145158279Smjacob
146158279Smjacob        // If the method passed to invoke is not from DynamicStub or its superclasses,
147158279Smjacob        // it must be from an implemented interface, so we just handle
148162140Smjacob        // all of these with the stubMethodHandler.  This used to be
149162140Smjacob        // done be adding explicit entries for stubMethodHandler for
150162140Smjacob        // each remote interface, but that does not work correctly
151162140Smjacob        // for abstract interfaces, since the graph analysis ignores
152101704Smjacob        // abstract interfaces in order to compute the type ids
153101704Smjacob        // correctly (see PresentationManagerImpl.NodeImpl.getChildren).
154101704Smjacob        // Rather than produce more graph traversal code to handle this
155101704Smjacob        // problem, we simply use a default.
156155521Smjacob        // This also points to a possible optimization: just use explict
157155521Smjacob        // checks for the three special classes, rather than a general
158155521Smjacob        // table lookup that usually fails.
159155521Smjacob        handler.setDefaultHandler( stubMethodHandler ) ;
160155521Smjacob
161155521Smjacob        return handler ;
162155521Smjacob    }
163155521Smjacob
164155521Smjacob    public Class[] getProxyInterfaces()
165155521Smjacob    {
166155521Smjacob        return proxyInterfaces ;
167155521Smjacob    }
168155521Smjacob}
169155521Smjacob