1 /* 2 * Copyright (c) 1999, 2000, 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.jndi.toolkit.corba; 27 28 // Needed for RMI/IIOP 29 import java.rmi.Remote; 30 31 import java.lang.reflect.Method; 32 import java.lang.reflect.InvocationTargetException; 33 import java.util.Hashtable; 34 import java.util.Properties; 35 import java.util.Enumeration; 36 37 import org.omg.CORBA.ORB; 38 39 import javax.naming.Context; 40 import javax.naming.ConfigurationException; 41 42 /** 43 * Contains utilities for performing CORBA-related tasks: 44 * 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object. 45 * 2. Create an ORB to use for a given host/port, and environment properties. 46 * 47 * @author Simon Nash 48 * @author Bryan Atsatt 49 */ 50 51 public class CorbaUtils { 52 /** 53 * Returns the CORBA object reference associated with a Remote 54 * object by using the javax.rmi.CORBA package. 55 *<p> 56 * Use reflection to avoid hard dependencies on javax.rmi.CORBA package. 57 * This method effective does the following: 58 *<blockquote><pre> 59 * java.lang.Object stub; 60 * try { 61 * stub = PortableRemoteObject.toStub(remoteObj); 62 * } catch (Exception e) { 63 * throw new ConfigurationException("Object not exported or not found"); 64 * } 65 * if (!(stub instanceof javax.rmi.CORBA.Stub)) { 66 * return null; // JRMP impl or JRMP stub 67 * } 68 * try { 69 * ((javax.rmi.CORBA.Stub)stub).connect(orb); // try to connect IIOP stub 70 * } catch (RemoteException e) { 71 * // ignore 'already connected' error 72 * } 73 * return (javax.rmi.CORBA.Stub)stub; 74 * 75 * @param remoteObj The non-null remote object for 76 * @param orb The non-null ORB to connect the remote object to 77 * @return The CORBA Object for remoteObj; null if <tt>remoteObj</tt> 78 * is a JRMP implementation or JRMP stub. 79 * @exception ClassNotFoundException The RMI-IIOP package is not available 80 * @exception ConfigurationException The CORBA Object cannot be obtained 81 * because of configuration problems. 82 */ 83 public static org.omg.CORBA.Object remoteToCorba(Remote remoteObj, ORB orb) 84 throws ClassNotFoundException, ConfigurationException { 85 synchronized (CorbaUtils.class) { 86 if (toStubMethod == null) { 87 initMethodHandles(); 88 } 89 } 90 91 // First, get remoteObj's stub 92 93 // javax.rmi.CORBA.Stub stub = PortableRemoteObject.toStub(remoteObj); 94 95 java.lang.Object stub; 96 97 try { 98 stub = toStubMethod.invoke(null, new java.lang.Object[]{remoteObj}); 99 100 } catch (InvocationTargetException e) { 101 Throwable realException = e.getTargetException(); 102 // realException.printStackTrace(); 103 104 ConfigurationException ce = new ConfigurationException( 105 "Problem with PortableRemoteObject.toStub(); object not exported or stub not found"); 106 ce.setRootCause(realException); 107 throw ce; 108 109 } catch (IllegalAccessException e) { 110 ConfigurationException ce = new ConfigurationException( 111 "Cannot invoke javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)"); 112 113 ce.setRootCause(e); 114 throw ce; 115 } 116 117 // Next, make sure that the stub is javax.rmi.CORBA.Stub 118 119 if (!corbaStubClass.isInstance(stub)) { 120 return null; // JRMP implementation or JRMP stub 121 } 122 123 // Next, make sure that the stub is connected 124 // Invoke stub.connect(orb) 125 try { 126 connectMethod.invoke(stub, new java.lang.Object[]{orb}); 127 128 } catch (InvocationTargetException e) { 129 Throwable realException = e.getTargetException(); 130 // realException.printStackTrace(); 131 132 if (!(realException instanceof java.rmi.RemoteException)) { 133 ConfigurationException ce = new ConfigurationException( 134 "Problem invoking javax.rmi.CORBA.Stub.connect()"); 135 ce.setRootCause(realException); 136 throw ce; 137 } 138 // ignore RemoteException because stub might have already 139 // been connected 140 } catch (IllegalAccessException e) { 141 ConfigurationException ce = new ConfigurationException( 142 "Cannot invoke javax.rmi.CORBA.Stub.connect()"); 143 ce.setRootCause(e); 144 throw ce; 145 } 146 // Finally, return stub 147 return (org.omg.CORBA.Object)stub; 148 } 149 150 /** 151 * Get ORB using given server and port number, and properties from environment. 152 * 153 * @param server Possibly null server; if null means use default; 154 * For applet, it is the applet host; for app, it is localhost. 155 * @param port Port number, -1 means default port 156 * @param env Possibly null environment. Contains environment properties. 157 * Could contain ORB itself; or applet used for initializing ORB. 158 * Use all String properties from env for initializing ORB 159 * @return A non-null ORB. 160 */ 161 public static ORB getOrb(String server, int port, Hashtable env) { 162 // See if we can get info from environment 163 Properties orbProp; 164 165 // Extract any org.omg.CORBA properties from environment 166 if (env != null) { 167 if (env instanceof Properties) { 168 // Already a Properties, just clone 169 orbProp = (Properties) env.clone(); 170 } else { 171 // Get all String properties 172 Enumeration envProp; 173 orbProp = new Properties(); 174 for (envProp = env.keys(); envProp.hasMoreElements();) { 175 String key = (String)envProp.nextElement(); 176 Object val = env.get(key); 177 if (val instanceof String) { 178 orbProp.put(key, val); 179 } 180 } 181 } 182 } else { 183 orbProp = new Properties(); 184 } 185 186 if (server != null) { 187 orbProp.put("org.omg.CORBA.ORBInitialHost", server); 188 } 189 if (port >= 0) { 190 orbProp.put("org.omg.CORBA.ORBInitialPort", ""+port); 191 } 192 193 // Get Applet from environment 194 if (env != null) { 195 Object applet = env.get(Context.APPLET); 196 if (applet != null) { 197 // Create ORBs for an applet 198 return initAppletORB(applet, orbProp); 199 } 200 } 201 202 // Create ORBs using orbProp for a standalone application 203 return ORB.init(new String[0], orbProp); 204 } 205 206 /** 207 * This method returns a new ORB instance for the given applet 208 * without creating a static dependency on java.applet. 209 */ 210 private static ORB initAppletORB(Object applet, Properties orbProp) { 211 try { 212 Class<?> appletClass = Class.forName("java.applet.Applet", true, null); 213 if (!appletClass.isInstance(applet)) { 214 throw new ClassCastException(applet.getClass().getName()); 215 } 216 217 // invoke the static method ORB.init(applet, orbProp); 218 Method method = ORB.class.getMethod("init", appletClass, Properties.class); 219 return (ORB) method.invoke(null, applet, orbProp); 220 } catch (ClassNotFoundException e) { 221 // java.applet.Applet doesn't exist and the applet parameter is 222 // non-null; so throw CCE 223 throw new ClassCastException(applet.getClass().getName()); 224 } catch (NoSuchMethodException e) { 225 throw new AssertionError(e); 226 } catch (InvocationTargetException e) { 227 Throwable cause = e.getCause(); 228 if (cause instanceof RuntimeException) { 229 throw (RuntimeException) cause; 230 } else if (cause instanceof Error) { 231 throw (Error) cause; 232 } 233 throw new AssertionError(e); 234 } catch (IllegalAccessException iae) { 235 throw new AssertionError(iae); 236 } 237 } 238 239 // Fields used for reflection of RMI-IIOP 240 private static Method toStubMethod = null; 241 private static Method connectMethod = null; 242 private static Class corbaStubClass = null; 243 /** 244 * Initializes reflection method handles for RMI-IIOP. 245 * @exception ClassNotFoundException javax.rmi.CORBA.* not available 246 */ 247 private static void initMethodHandles() throws ClassNotFoundException { 248 // Get javax.rmi.CORBA.Stub class 249 corbaStubClass = Class.forName("javax.rmi.CORBA.Stub"); 250 251 // Get javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB) method 252 253 try { 254 connectMethod = corbaStubClass.getMethod("connect", 255 new Class[] {org.omg.CORBA.ORB.class}); 256 } catch (NoSuchMethodException e) { 257 throw new IllegalStateException( 258 "No method definition for javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB)"); 259 } 260 261 // Get javax.rmi.PortableRemoteObject method 262 Class proClass = Class.forName("javax.rmi.PortableRemoteObject"); 263 264 // Get javax.rmi.PortableRemoteObject(java.rmi.Remote) method 265 try { 266 toStubMethod = proClass.getMethod("toStub", 267 new Class[] {java.rmi.Remote.class}); 268 269 } catch (NoSuchMethodException e) { 270 throw new IllegalStateException( 271 "No method definition for javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)"); 272 } 273 } 274 }