/* * @(#)JNDIStateFactoryImpl.java 1.6 04/07/27 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.sun.corba.se.impl.presentation.rmi ; import java.lang.reflect.Field ; import java.util.Hashtable; import javax.naming.*; import javax.naming.spi.StateFactory; import java.security.AccessController ; import java.security.PrivilegedAction ; import javax.rmi.PortableRemoteObject ; import com.sun.corba.se.spi.orb.ORB; import java.rmi.Remote; import java.rmi.server.ExportException; // XXX This creates a dependendcy on the implementation // of the CosNaming service provider. import com.sun.jndi.cosnaming.CNCtx ; import com.sun.corba.se.spi.presentation.rmi.StubAdapter ; /** * StateFactory that turns java.rmi.Remote objects to org.omg.CORBA.Object. * This version works either with standard RMI-IIOP or Dynamic RMI-IIOP. * Based on the original com.sun.jndi.cosnaming.RemoteToCorba and * com.sun.jndi.toolkit.corba.CorbaUtils. * * @author Ken Cavanaugh */ public class JNDIStateFactoryImpl implements StateFactory { private static final Field orbField ; static { orbField = (Field) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { Field fld = null ; try { Class cls = CNCtx.class ; fld = cls.getDeclaredField( "_orb" ) ; fld.setAccessible( true ) ; } catch (Exception exc) { // XXX log exception at FINE } return fld ; } } ) ; } public JNDIStateFactoryImpl() { } /** * Returns the CORBA object for a Remote object. * If input is not a Remote object, or if Remote object uses JRMP, return null. * If the RMI-IIOP library is not available, throw ConfigurationException. * * @param orig The object to turn into a CORBA object. If not Remote, * or if is a JRMP stub or impl, return null. * @param name Ignored * @param ctx The non-null CNCtx whose ORB to use. * @param env Ignored * @return The CORBA object for orig or null. * @exception ConfigurationException If the CORBA object cannot be obtained * due to configuration problems * @exception NamingException If some other problem prevented a CORBA * object from being obtained from the Remote object. */ public Object getStateToBind(Object orig, Name name, Context ctx, Hashtable env) throws NamingException { if (orig instanceof org.omg.CORBA.Object) return orig ; if (!(orig instanceof Remote)) // Not for this StateFactory return null ; ORB orb = getORB( ctx ) ; if (orb == null) // Wrong kind of context, so just give up and let another StateFactory // try to satisfy getStateToBind. return null ; Remote stub = null; try { stub = PortableRemoteObject.toStub( (Remote)orig ) ; } catch (Exception exc) { // XXX log at FINE level? // Wrong sort of object: just return null to allow another StateFactory // to handle this. This can happen easily because this StateFactory // is specified for the application, not the service context provider. return null ; } if (StubAdapter.isStub( stub )) { try { StubAdapter.connect( stub, orb ) ; } catch (Exception exc) { if (!(exc instanceof java.rmi.RemoteException)) { // XXX log at FINE level? // Wrong sort of object: just return null to allow another StateFactory // to handle this call. return null ; } // ignore RemoteException because stub might have already // been connected } } return stub ; } // This is necessary because the _orb field is package private in // com.sun.jndi.cosnaming.CNCtx. This is not an ideal solution. // The best solution for our ORB is to change the CosNaming provider // to use the StubAdapter. But this has problems as well, because // other vendors may use the CosNaming provider with a different ORB // entirely. private ORB getORB( Context ctx ) { ORB orb = null ; try { orb = (ORB)orbField.get( ctx ) ; } catch (Exception exc) { // XXX log this exception at FINE level // ignore the exception and return null. // Note that the exception may be because ctx // is not a CosNaming context. } return orb ; } }