JNDIStateFactoryImpl.java revision 704:3ef63dbde965
1/*
2 * Copyright (c) 2004, 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
26package com.sun.corba.se.impl.presentation.rmi ;
27
28import java.lang.reflect.Field ;
29
30import java.util.Hashtable;
31
32import javax.naming.*;
33import javax.naming.spi.StateFactory;
34
35import java.security.AccessController ;
36import java.security.PrivilegedAction ;
37
38import javax.rmi.PortableRemoteObject ;
39
40import com.sun.corba.se.spi.orb.ORB;
41
42import java.rmi.Remote;
43import java.rmi.server.ExportException;
44
45// XXX This creates a dependendcy on the implementation
46// of the CosNaming service provider.
47import com.sun.jndi.cosnaming.CNCtx ;
48
49import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
50
51/**
52  * StateFactory that turns java.rmi.Remote objects to org.omg.CORBA.Object.
53  * This version works either with standard RMI-IIOP or Dynamic RMI-IIOP.
54  * Based on the original com.sun.jndi.cosnaming.RemoteToCorba and
55  * com.sun.jndi.toolkit.corba.CorbaUtils.
56  *
57  * @author Ken Cavanaugh
58  */
59
60public class JNDIStateFactoryImpl implements StateFactory
61{
62    private static final Field orbField ;
63
64    static {
65        orbField = (Field) AccessController.doPrivileged(
66            new PrivilegedAction() {
67                public Object run() {
68                    Field fld = null ;
69                    try {
70                        Class cls = CNCtx.class ;
71                        fld = cls.getDeclaredField( "_orb" ) ;
72                        fld.setAccessible( true ) ;
73                    } catch (Exception exc) {
74                        // XXX log exception at FINE
75                    }
76                    return fld ;
77                }
78            }
79        ) ;
80    }
81
82    public JNDIStateFactoryImpl()
83    {
84    }
85
86    /**
87     * Returns the CORBA object for a Remote object.
88     * If input is not a Remote object, or if Remote object uses JRMP, return null.
89     * If the RMI-IIOP library is not available, throw ConfigurationException.
90     *
91     * @param orig The object to turn into a CORBA object. If not Remote,
92     *             or if is a JRMP stub or impl, return null.
93     * @param name Ignored
94     * @param ctx The non-null CNCtx whose ORB to use.
95     * @param env Ignored
96     * @return The CORBA object for {@code orig} or null.
97     * @exception ConfigurationException If the CORBA object cannot be obtained
98     *    due to configuration problems
99     * @exception NamingException If some other problem prevented a CORBA
100     *    object from being obtained from the Remote object.
101     */
102    public Object getStateToBind(Object orig, Name name, Context ctx,
103        Hashtable<?,?> env) throws NamingException
104    {
105        if (orig instanceof org.omg.CORBA.Object)
106            return orig ;
107
108        if (!(orig instanceof Remote))
109            // Not for this StateFactory
110            return null ;
111
112        ORB orb = getORB( ctx ) ;
113        if (orb == null)
114            // Wrong kind of context, so just give up and let another StateFactory
115            // try to satisfy getStateToBind.
116            return null ;
117
118        Remote stub = null;
119
120        try {
121            stub = PortableRemoteObject.toStub( (Remote)orig ) ;
122        } catch (Exception exc) {
123            // XXX log at FINE level?
124            // Wrong sort of object: just return null to allow another StateFactory
125            // to handle this.  This can happen easily because this StateFactory
126            // is specified for the application, not the service context provider.
127            return null ;
128        }
129
130        if (StubAdapter.isStub( stub )) {
131            try {
132                StubAdapter.connect( stub, orb ) ;
133            } catch (Exception exc) {
134                if (!(exc instanceof java.rmi.RemoteException)) {
135                    // XXX log at FINE level?
136                    // Wrong sort of object: just return null to allow another StateFactory
137                    // to handle this call.
138                    return null ;
139                }
140
141                // ignore RemoteException because stub might have already
142                // been connected
143            }
144        }
145
146        return stub ;
147    }
148
149    // This is necessary because the _orb field is package private in
150    // com.sun.jndi.cosnaming.CNCtx.  This is not an ideal solution.
151    // The best solution for our ORB is to change the CosNaming provider
152    // to use the StubAdapter.  But this has problems as well, because
153    // other vendors may use the CosNaming provider with a different ORB
154    // entirely.
155    private ORB getORB( Context ctx )
156    {
157        ORB orb = null ;
158
159        try {
160            orb = (ORB)orbField.get( ctx ) ;
161        } catch (Exception exc) {
162            // XXX log this exception at FINE level
163            // ignore the exception and return null.
164            // Note that the exception may be because ctx
165            // is not a CosNaming context.
166        }
167
168        return orb ;
169    }
170}
171