1 /* 2 * Copyright (c) 1998, 2016, 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 * Licensed Materials - Property of IBM 27 * RMI-IIOP v1.0 28 * Copyright IBM Corp. 1998 1999 All Rights Reserved 29 * 30 */ 31 32 package javax.rmi.CORBA; 33 34 import java.rmi.RemoteException; 35 36 import org.omg.CORBA.ORB; 37 import org.omg.CORBA.INITIALIZE; 38 import org.omg.CORBA.SystemException; 39 import org.omg.CORBA.Any; 40 import org.omg.CORBA.portable.InputStream; 41 import org.omg.CORBA.portable.OutputStream; 42 import org.omg.CORBA.portable.ObjectImpl; 43 44 import javax.rmi.CORBA.Tie; 45 import java.rmi.Remote; 46 import java.io.File; 47 import java.io.FileInputStream; 48 import java.io.SerializablePermission; 49 import java.net.MalformedURLException ; 50 import java.security.AccessController; 51 import java.security.PrivilegedAction; 52 import java.util.Properties; 53 import java.rmi.server.RMIClassLoader; 54 55 import com.sun.corba.se.impl.orbutil.GetPropertyAction; 56 57 /** 58 * Provides utility methods that can be used by stubs and ties to 59 * perform common operations. 60 */ 61 public class Util { 62 63 // This can only be set at static initialization time (no sync necessary). 64 private static final javax.rmi.CORBA.UtilDelegate utilDelegate; 65 private static final String UtilClassKey = "javax.rmi.CORBA.UtilClass"; 66 67 static { 68 utilDelegate = (javax.rmi.CORBA.UtilDelegate)createDelegate(UtilClassKey); 69 } 70 71 private Util(){} 72 73 /** 74 * Maps a SystemException to a RemoteException. 75 * @param ex the SystemException to map. 76 * @return the mapped exception. 77 */ 78 public static RemoteException mapSystemException(SystemException ex) { 79 80 if (utilDelegate != null) { 81 return utilDelegate.mapSystemException(ex); 82 } 83 return null; 84 } 85 86 /** 87 * Writes any java.lang.Object as a CORBA any. 88 * @param out the stream in which to write the any. 89 * @param obj the object to write as an any. 90 */ 91 public static void writeAny(OutputStream out, Object obj) { 92 93 if (utilDelegate != null) { 94 utilDelegate.writeAny(out, obj); 95 } 96 } 97 98 /** 99 * Reads a java.lang.Object as a CORBA any. 100 * @param in the stream from which to read the any. 101 * @return the object read from the stream. 102 */ 103 public static Object readAny(InputStream in) { 104 105 if (utilDelegate != null) { 106 return utilDelegate.readAny(in); 107 } 108 return null; 109 } 110 111 /** 112 * Writes a java.lang.Object as a CORBA Object. If {@code obj} is 113 * an exported RMI-IIOP server object, the tie is found 114 * and wired to {@code obj}, then written to 115 * {@code out.write_Object(org.omg.CORBA.Object)}. 116 * If {@code obj} is a CORBA Object, it is written to 117 * {@code out.write_Object(org.omg.CORBA.Object)}. 118 * @param out the stream in which to write the object. 119 * @param obj the object to write. 120 */ 121 public static void writeRemoteObject(OutputStream out, 122 java.lang.Object obj) { 123 124 if (utilDelegate != null) { 125 utilDelegate.writeRemoteObject(out, obj); 126 } 127 128 } 129 130 /** 131 * Writes a java.lang.Object as either a value or a CORBA Object. 132 * If {@code obj} is a value object or a stub object, it is written to 133 * {@code out.write_abstract_interface(java.lang.Object)}. 134 * If {@code obj} is an exported 135 * RMI-IIOP server object, the tie is found and wired to {@code obj}, 136 * then written to {@code out.write_abstract_interface(java.lang.Object)}. 137 * @param out the stream in which to write the object. 138 * @param obj the object to write. 139 */ 140 public static void writeAbstractObject(OutputStream out, 141 java.lang.Object obj) { 142 143 if (utilDelegate != null) { 144 utilDelegate.writeAbstractObject(out, obj); 145 } 146 } 147 148 /** 149 * Registers a target for a tie. Adds the tie to an internal table and calls 150 * {@link Tie#setTarget} on the tie object. 151 * @param tie the tie to register. 152 * @param target the target for the tie. 153 */ 154 public static void registerTarget(javax.rmi.CORBA.Tie tie, 155 java.rmi.Remote target) { 156 157 if (utilDelegate != null) { 158 utilDelegate.registerTarget(tie, target); 159 } 160 161 } 162 163 /** 164 * Removes the associated tie from an internal table 165 * and calls {@link Tie#deactivate} 166 * to deactivate the object. 167 * @param target the object to unexport. 168 */ 169 public static void unexportObject(java.rmi.Remote target) 170 throws java.rmi.NoSuchObjectException 171 { 172 173 if (utilDelegate != null) { 174 utilDelegate.unexportObject(target); 175 } 176 177 } 178 179 /** 180 * Returns the tie (if any) for a given target object. 181 * @return the tie or null if no tie is registered for the given target. 182 */ 183 public static Tie getTie (Remote target) { 184 185 if (utilDelegate != null) { 186 return utilDelegate.getTie(target); 187 } 188 return null; 189 } 190 191 192 /** 193 * Returns a singleton instance of a class that implements the 194 * {@link ValueHandler} interface. 195 * @return a class which implements the ValueHandler interface. 196 */ 197 public static ValueHandler createValueHandler() { 198 199 isCustomSerializationPermitted(); 200 201 if (utilDelegate != null) { 202 return utilDelegate.createValueHandler(); 203 } 204 return null; 205 } 206 207 /** 208 * Returns the codebase, if any, for the given class. 209 * @param clz the class to get a codebase for. 210 * @return a space-separated list of URLs, or null. 211 */ 212 public static String getCodebase(java.lang.Class clz) { 213 if (utilDelegate != null) { 214 return utilDelegate.getCodebase(clz); 215 } 216 return null; 217 } 218 219 /** 220 * Returns a class instance for the specified class. 221 * <P>The spec for this method is the "Java to IDL language 222 * mapping", ptc/00-01-06. 223 * <P>In Java SE Platform, this method works as follows: 224 * <UL><LI>Find the first non-null {@code ClassLoader} on the 225 * call stack and attempt to load the class using this 226 * {@code ClassLoader}. 227 * <LI>If the first step fails, and if {@code remoteCodebase} 228 * is non-null and 229 * {@code useCodebaseOnly} is false, then call 230 * {@code java.rmi.server.RMIClassLoader.loadClass(remoteCodebase, className)}. 231 * <LI>If {@code remoteCodebase} is null or {@code useCodebaseOnly} 232 * is true, then call {@code java.rmi.server.RMIClassLoader.loadClass(className)}. 233 * <LI>If a class was not successfully loaded by step 1, 2, or 3, 234 * and {@code loader} is non-null, then call {@code loader.loadClass(className)}. 235 * <LI>If a class was successfully loaded by step 1, 2, 3, or 4, then 236 * return the loaded class, else throw {@code ClassNotFoundException}. 237 * </UL> 238 * 239 * @param className the name of the class. 240 * @param remoteCodebase a space-separated list of URLs at which 241 * the class might be found. May be null. 242 * @param loader a {@code ClassLoader} that may be used to 243 * load the class if all other methods fail. 244 * @return the {@code Class} object representing the loaded class. 245 * @exception ClassNotFoundException if class cannot be loaded. 246 */ 247 public static Class loadClass(String className, 248 String remoteCodebase, 249 ClassLoader loader) 250 throws ClassNotFoundException { 251 if (utilDelegate != null) { 252 return utilDelegate.loadClass(className,remoteCodebase,loader); 253 } 254 return null ; 255 } 256 257 258 /** 259 * The {@code isLocal} method has the same semantics as the 260 * {@code ObjectImpl._is_local} 261 * method, except that it can throw a {@code RemoteException}. 262 * 263 * The {@code _is_local()} method is provided so that stubs may determine if a 264 * particular object is implemented by a local servant and hence local 265 * invocation APIs may be used. 266 * 267 * @param stub the stub to test. 268 * 269 * @return The {@code _is_local()} method returns true if 270 * the servant incarnating the object is located in the same process as 271 * the stub and they both share the same ORB instance. The {@code _is_local()} 272 * method returns false otherwise. The default behavior of {@code _is_local()} is 273 * to return false. 274 * 275 * @throws RemoteException The Java to IDL specification does not 276 * specify the conditions that cause a {@code RemoteException} to be thrown. 277 */ 278 public static boolean isLocal(Stub stub) throws RemoteException { 279 280 if (utilDelegate != null) { 281 return utilDelegate.isLocal(stub); 282 } 283 284 return false; 285 } 286 287 /** 288 * Wraps an exception thrown by an implementation 289 * method. It returns the corresponding client-side exception. 290 * @param orig the exception to wrap. 291 * @return the wrapped exception. 292 */ 293 public static RemoteException wrapException(Throwable orig) { 294 295 if (utilDelegate != null) { 296 return utilDelegate.wrapException(orig); 297 } 298 299 return null; 300 } 301 302 /** 303 * Copies or connects an array of objects. Used by local stubs 304 * to copy any number of actual parameters, preserving sharing 305 * across parameters as necessary to support RMI semantics. 306 * @param obj the objects to copy or connect. 307 * @param orb the ORB. 308 * @return the copied or connected objects. 309 * @exception RemoteException if any object could not be copied or connected. 310 */ 311 public static Object[] copyObjects (Object[] obj, ORB orb) 312 throws RemoteException { 313 314 if (utilDelegate != null) { 315 return utilDelegate.copyObjects(obj, orb); 316 } 317 318 return null; 319 } 320 321 /** 322 * Copies or connects an object. Used by local stubs to copy 323 * an actual parameter, result object, or exception. 324 * @param obj the object to copy. 325 * @param orb the ORB. 326 * @return the copy or connected object. 327 * @exception RemoteException if the object could not be copied or connected. 328 */ 329 public static Object copyObject (Object obj, ORB orb) 330 throws RemoteException { 331 332 if (utilDelegate != null) { 333 return utilDelegate.copyObject(obj, orb); 334 } 335 return null; 336 } 337 338 // Same code as in PortableRemoteObject. Can not be shared because they 339 // are in different packages and the visibility needs to be package for 340 // security reasons. If you know a better solution how to share this code 341 // then remove it from PortableRemoteObject. Also in Stub.java 342 private static Object createDelegate(String classKey) { 343 344 String className = (String) 345 AccessController.doPrivileged(new GetPropertyAction(classKey)); 346 if (className == null) { 347 Properties props = getORBPropertiesFile(); 348 if (props != null) { 349 className = props.getProperty(classKey); 350 } 351 } 352 if (className == null) { 353 return new com.sun.corba.se.impl.javax.rmi.CORBA.Util(); 354 } 355 356 try { 357 return loadDelegateClass(className).newInstance(); 358 } catch (ClassNotFoundException ex) { 359 INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className); 360 exc.initCause( ex ) ; 361 throw exc ; 362 } catch (Exception ex) { 363 INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className); 364 exc.initCause( ex ) ; 365 throw exc ; 366 } 367 } 368 369 private static Class loadDelegateClass( String className ) throws ClassNotFoundException 370 { 371 try { 372 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 373 return Class.forName(className, false, loader); 374 } catch (ClassNotFoundException e) { 375 // ignore, then try RMIClassLoader 376 } 377 378 try { 379 return RMIClassLoader.loadClass(className); 380 } catch (MalformedURLException e) { 381 String msg = "Could not load " + className + ": " + e.toString(); 382 ClassNotFoundException exc = new ClassNotFoundException( msg ) ; 383 throw exc ; 384 } 385 } 386 /** 387 * Load the orb.properties file. 388 */ 389 private static Properties getORBPropertiesFile () 390 { 391 return (Properties) AccessController.doPrivileged( 392 new GetORBPropertiesFileAction()); 393 } 394 395 private static void isCustomSerializationPermitted() { 396 SecurityManager sm = System.getSecurityManager(); 397 if ( sm != null) { 398 // check that a serialization permission has been 399 // set to allow the loading of the Util delegate 400 // which provides access to custom ValueHandler 401 sm.checkPermission(new SerializablePermission( 402 "enableCustomValueHandler")); 403 } 404 } 405 }