blob: c6965d27f2f90e2d8785f3efa3093165ca63ae22 [file] [log] [blame]
/*
* Copyright (c) 1999, 2000, 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 com.sun.jndi.toolkit.corba;
// Needed for RMI/IIOP
import java.rmi.Remote;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Enumeration;
import org.omg.CORBA.ORB;
import javax.naming.Context;
import javax.naming.ConfigurationException;
/**
* Contains utilities for performing CORBA-related tasks:
* 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object.
* 2. Create an ORB to use for a given host/port, and environment properties.
*
* @author Simon Nash
* @author Bryan Atsatt
*/
public class CorbaUtils {
/**
* Returns the CORBA object reference associated with a Remote
* object by using the javax.rmi.CORBA package.
*<p>
* Use reflection to avoid hard dependencies on javax.rmi.CORBA package.
* This method effective does the following:
*<blockquote><pre>
* java.lang.Object stub;
* try {
* stub = PortableRemoteObject.toStub(remoteObj);
* } catch (Exception e) {
* throw new ConfigurationException("Object not exported or not found");
* }
* if (!(stub instanceof javax.rmi.CORBA.Stub)) {
* return null; // JRMP impl or JRMP stub
* }
* try {
* ((javax.rmi.CORBA.Stub)stub).connect(orb); // try to connect IIOP stub
* } catch (RemoteException e) {
* // ignore 'already connected' error
* }
* return (javax.rmi.CORBA.Stub)stub;
*
* @param remoteObj The non-null remote object for
* @param orb The non-null ORB to connect the remote object to
* @return The CORBA Object for remoteObj; null if <tt>remoteObj</tt>
* is a JRMP implementation or JRMP stub.
* @exception ClassNotFoundException The RMI-IIOP package is not available
* @exception ConfigurationException The CORBA Object cannot be obtained
* because of configuration problems.
*/
public static org.omg.CORBA.Object remoteToCorba(Remote remoteObj, ORB orb)
throws ClassNotFoundException, ConfigurationException {
synchronized (CorbaUtils.class) {
if (toStubMethod == null) {
initMethodHandles();
}
}
// First, get remoteObj's stub
// javax.rmi.CORBA.Stub stub = PortableRemoteObject.toStub(remoteObj);
java.lang.Object stub;
try {
stub = toStubMethod.invoke(null, new java.lang.Object[]{remoteObj});
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
// realException.printStackTrace();
ConfigurationException ce = new ConfigurationException(
"Problem with PortableRemoteObject.toStub(); object not exported or stub not found");
ce.setRootCause(realException);
throw ce;
} catch (IllegalAccessException e) {
ConfigurationException ce = new ConfigurationException(
"Cannot invoke javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)");
ce.setRootCause(e);
throw ce;
}
// Next, make sure that the stub is javax.rmi.CORBA.Stub
if (!corbaStubClass.isInstance(stub)) {
return null; // JRMP implementation or JRMP stub
}
// Next, make sure that the stub is connected
// Invoke stub.connect(orb)
try {
connectMethod.invoke(stub, new java.lang.Object[]{orb});
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
// realException.printStackTrace();
if (!(realException instanceof java.rmi.RemoteException)) {
ConfigurationException ce = new ConfigurationException(
"Problem invoking javax.rmi.CORBA.Stub.connect()");
ce.setRootCause(realException);
throw ce;
}
// ignore RemoteException because stub might have already
// been connected
} catch (IllegalAccessException e) {
ConfigurationException ce = new ConfigurationException(
"Cannot invoke javax.rmi.CORBA.Stub.connect()");
ce.setRootCause(e);
throw ce;
}
// Finally, return stub
return (org.omg.CORBA.Object)stub;
}
/**
* Get ORB using given server and port number, and properties from environment.
*
* @param server Possibly null server; if null means use default;
* For applet, it is the applet host; for app, it is localhost.
* @param port Port number, -1 means default port
* @param env Possibly null environment. Contains environment properties.
* Could contain ORB itself; or applet used for initializing ORB.
* Use all String properties from env for initializing ORB
* @return A non-null ORB.
*/
public static ORB getOrb(String server, int port, Hashtable env) {
// See if we can get info from environment
Properties orbProp;
// Extract any org.omg.CORBA properties from environment
if (env != null) {
if (env instanceof Properties) {
// Already a Properties, just clone
orbProp = (Properties) env.clone();
} else {
// Get all String properties
Enumeration envProp;
orbProp = new Properties();
for (envProp = env.keys(); envProp.hasMoreElements();) {
String key = (String)envProp.nextElement();
Object val = env.get(key);
if (val instanceof String) {
orbProp.put(key, val);
}
}
}
} else {
orbProp = new Properties();
}
if (server != null) {
orbProp.put("org.omg.CORBA.ORBInitialHost", server);
}
if (port >= 0) {
orbProp.put("org.omg.CORBA.ORBInitialPort", ""+port);
}
// Get Applet from environment
if (env != null) {
Object applet = env.get(Context.APPLET);
if (applet != null) {
// Create ORBs for an applet
return initAppletORB(applet, orbProp);
}
}
// Create ORBs using orbProp for a standalone application
return ORB.init(new String[0], orbProp);
}
/**
* This method returns a new ORB instance for the given applet
* without creating a static dependency on java.applet.
*/
private static ORB initAppletORB(Object applet, Properties orbProp) {
try {
Class<?> appletClass = Class.forName("java.applet.Applet", true, null);
if (!appletClass.isInstance(applet)) {
throw new ClassCastException(applet.getClass().getName());
}
// invoke the static method ORB.init(applet, orbProp);
Method method = ORB.class.getMethod("init", appletClass, Properties.class);
return (ORB) method.invoke(null, applet, orbProp);
} catch (ClassNotFoundException e) {
// java.applet.Applet doesn't exist and the applet parameter is
// non-null; so throw CCE
throw new ClassCastException(applet.getClass().getName());
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
// Fields used for reflection of RMI-IIOP
private static Method toStubMethod = null;
private static Method connectMethod = null;
private static Class corbaStubClass = null;
/**
* Initializes reflection method handles for RMI-IIOP.
* @exception ClassNotFoundException javax.rmi.CORBA.* not available
*/
private static void initMethodHandles() throws ClassNotFoundException {
// Get javax.rmi.CORBA.Stub class
corbaStubClass = Class.forName("javax.rmi.CORBA.Stub");
// Get javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB) method
try {
connectMethod = corbaStubClass.getMethod("connect",
new Class[] {org.omg.CORBA.ORB.class});
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"No method definition for javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB)");
}
// Get javax.rmi.PortableRemoteObject method
Class proClass = Class.forName("javax.rmi.PortableRemoteObject");
// Get javax.rmi.PortableRemoteObject(java.rmi.Remote) method
try {
toStubMethod = proClass.getMethod("toStub",
new Class[] {java.rmi.Remote.class});
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"No method definition for javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)");
}
}
}