1 /*
   2  * Copyright (c) 1998, 2015, 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.net.MalformedURLException ;
  49 import java.security.AccessController;
  50 import java.security.PrivilegedAction;
  51 import java.util.Properties;
  52 import java.rmi.server.RMIClassLoader;
  53 
  54 import com.sun.corba.se.impl.orbutil.GetPropertyAction;
  55 
  56 /**
  57  * Provides utility methods that can be used by stubs and ties to
  58  * perform common operations.
  59  */
  60 public class Util {
  61 
  62     // This can only be set at static initialization time (no sync necessary).
  63     private static final javax.rmi.CORBA.UtilDelegate utilDelegate;
  64     private static final String UtilClassKey = "javax.rmi.CORBA.UtilClass";
  65 
  66     static {
  67         utilDelegate = (javax.rmi.CORBA.UtilDelegate)createDelegate(UtilClassKey);
  68     }
  69 
  70     private Util(){}
  71 
  72     /**
  73      * Maps a SystemException to a RemoteException.
  74      * @param ex the SystemException to map.
  75      * @return the mapped exception.
  76      */
  77     public static RemoteException mapSystemException(SystemException ex) {
  78 
  79         if (utilDelegate != null) {
  80             return utilDelegate.mapSystemException(ex);
  81         }
  82         return null;
  83     }
  84 
  85     /**
  86      * Writes any java.lang.Object as a CORBA any.
  87      * @param out the stream in which to write the any.
  88      * @param obj the object to write as an any.
  89      */
  90     public static void writeAny(OutputStream out, Object obj) {
  91 
  92         if (utilDelegate != null) {
  93             utilDelegate.writeAny(out, obj);
  94         }
  95     }
  96 
  97     /**
  98      * Reads a java.lang.Object as a CORBA any.
  99      * @param in the stream from which to read the any.
 100      * @return the object read from the stream.
 101      */
 102     public static Object readAny(InputStream in) {
 103 
 104         if (utilDelegate != null) {
 105             return utilDelegate.readAny(in);
 106         }
 107         return null;
 108     }
 109 
 110     /**
 111      * Writes a java.lang.Object as a CORBA Object. If <code>obj</code> is
 112      * an exported RMI-IIOP server object, the tie is found
 113      * and wired to <code>obj</code>, then written to
 114 <code>out.write_Object(org.omg.CORBA.Object)</code>.
 115      * If <code>obj</code> is a CORBA Object, it is written to
 116      * <code>out.write_Object(org.omg.CORBA.Object)</code>.
 117      * @param out the stream in which to write the object.
 118      * @param obj the object to write.
 119      */
 120     public static void writeRemoteObject(OutputStream out,
 121                                          java.lang.Object obj) {
 122 
 123         if (utilDelegate != null) {
 124             utilDelegate.writeRemoteObject(out, obj);
 125         }
 126 
 127     }
 128 
 129     /**
 130      * Writes a java.lang.Object as either a value or a CORBA Object.
 131      * If <code>obj</code> is a value object or a stub object, it is written to
 132      * <code>out.write_abstract_interface(java.lang.Object)</code>. If <code>obj</code>
 133 is
 134 an exported
 135      * RMI-IIOP server object, the tie is found and wired to <code>obj</code>,
 136      * then written to <code>out.write_abstract_interface(java.lang.Object)</code>.
 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 and calls {@link
 165 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         if (utilDelegate != null) {
 200             return utilDelegate.createValueHandler();
 201         }
 202         return null;
 203     }
 204 
 205     /**
 206      * Returns the codebase, if any, for the given class.
 207      * @param clz the class to get a codebase for.
 208      * @return a space-separated list of URLs, or null.
 209      */
 210     public static String getCodebase(java.lang.Class clz) {
 211         if (utilDelegate != null) {
 212             return utilDelegate.getCodebase(clz);
 213         }
 214         return null;
 215     }
 216 
 217     /**
 218      * Returns a class instance for the specified class.
 219      * <P>The spec for this method is the "Java to IDL language
 220      * mapping", ptc/00-01-06.
 221      * <P>In Java SE Platform, this method works as follows:
 222      * <UL><LI>Find the first non-null <tt>ClassLoader</tt> on the
 223      * call stack and attempt to load the class using this
 224      * <tt>ClassLoader</tt>.
 225      * <LI>If the first step fails, and if <tt>remoteCodebase</tt>
 226      * is non-null and
 227      * <tt>useCodebaseOnly</tt> is false, then call
 228      * <tt>java.rmi.server.RMIClassLoader.loadClass(remoteCodebase, className)</tt>.
 229      * <LI>If <tt>remoteCodebase</tt> is null or <tt>useCodebaseOnly</tt>
 230      * is true, then call <tt>java.rmi.server.RMIClassLoader.loadClass(className)</tt>.
 231      * <LI>If a class was not successfully loaded by step 1, 2, or 3,
 232      * and <tt>loader</tt> is non-null, then call <tt>loader.loadClass(className)</tt>.
 233      * <LI>If a class was successfully loaded by step 1, 2, 3, or 4, then
 234      *  return the loaded class, else throw <tt>ClassNotFoundException</tt>.
 235      * </UL>
 236      *
 237      * @param className the name of the class.
 238      * @param remoteCodebase a space-separated list of URLs at which
 239      * the class might be found. May be null.
 240      * @param loader a <tt>ClassLoader</tt> that may be used to
 241      * load the class if all other methods fail.
 242      * @return the <code>Class</code> object representing the loaded class.
 243      * @exception ClassNotFoundException if class cannot be loaded.
 244      */
 245     public static Class loadClass(String className,
 246                                   String remoteCodebase,
 247                                   ClassLoader loader)
 248         throws ClassNotFoundException {
 249         if (utilDelegate != null) {
 250             return utilDelegate.loadClass(className,remoteCodebase,loader);
 251         }
 252         return null ;
 253     }
 254 
 255 
 256     /**
 257      * The <tt>isLocal</tt> method has the same semantics as the
 258      * <tt>ObjectImpl._is_local</tt>
 259      * method, except that it can throw a <tt>RemoteException</tt>.
 260      *
 261      * The <tt>_is_local()</tt> method is provided so that stubs may determine if a
 262      * particular object is implemented by a local servant and hence local
 263      * invocation APIs may be used.
 264      *
 265      * @param stub the stub to test.
 266      *
 267      * @return The <tt>_is_local()</tt> method returns true if
 268      * the servant incarnating the object is located in the same process as
 269      * the stub and they both share the same ORB instance.  The <tt>_is_local()</tt>
 270      * method returns false otherwise. The default behavior of <tt>_is_local()</tt> is
 271      * to return false.
 272      *
 273      * @throws RemoteException The Java to IDL specification does not
 274      * specify the conditions that cause a <tt>RemoteException</tt> to be thrown.
 275      */
 276     public static boolean isLocal(Stub stub) throws RemoteException {
 277 
 278         if (utilDelegate != null) {
 279             return utilDelegate.isLocal(stub);
 280         }
 281 
 282         return false;
 283     }
 284 
 285     /**
 286      * Wraps an exception thrown by an implementation
 287      * method.  It returns the corresponding client-side exception.
 288      * @param orig the exception to wrap.
 289      * @return the wrapped exception.
 290      */
 291     public static RemoteException wrapException(Throwable orig) {
 292 
 293         if (utilDelegate != null) {
 294             return utilDelegate.wrapException(orig);
 295         }
 296 
 297         return null;
 298     }
 299 
 300     /**
 301      * Copies or connects an array of objects. Used by local stubs
 302      * to copy any number of actual parameters, preserving sharing
 303      * across parameters as necessary to support RMI semantics.
 304      * @param obj the objects to copy or connect.
 305      * @param orb the ORB.
 306      * @return the copied or connected objects.
 307      * @exception RemoteException if any object could not be copied or connected.
 308      */
 309     public static Object[] copyObjects (Object[] obj, ORB orb)
 310         throws RemoteException {
 311 
 312         if (utilDelegate != null) {
 313             return utilDelegate.copyObjects(obj, orb);
 314         }
 315 
 316         return null;
 317     }
 318 
 319     /**
 320      * Copies or connects an object. Used by local stubs to copy
 321      * an actual parameter, result object, or exception.
 322      * @param obj the object to copy.
 323      * @param orb the ORB.
 324      * @return the copy or connected object.
 325      * @exception RemoteException if the object could not be copied or connected.
 326      */
 327     public static Object copyObject (Object obj, ORB orb)
 328         throws RemoteException {
 329 
 330         if (utilDelegate != null) {
 331             return utilDelegate.copyObject(obj, orb);
 332         }
 333         return null;
 334     }
 335 
 336     // Same code as in PortableRemoteObject. Can not be shared because they
 337     // are in different packages and the visibility needs to be package for
 338     // security reasons. If you know a better solution how to share this code
 339     // then remove it from PortableRemoteObject. Also in Stub.java
 340     private static Object createDelegate(String classKey) {
 341         String className = (String)
 342             AccessController.doPrivileged(new GetPropertyAction(classKey));
 343         if (className == null) {
 344             Properties props = getORBPropertiesFile();
 345             if (props != null) {
 346                 className = props.getProperty(classKey);
 347             }
 348         }
 349 
 350         if (className == null) {
 351             return new com.sun.corba.se.impl.javax.rmi.CORBA.Util();
 352         }
 353 
 354         try {
 355             return loadDelegateClass(className).newInstance();
 356         } catch (ClassNotFoundException ex) {
 357             INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className);
 358             exc.initCause( ex ) ;
 359             throw exc ;
 360         } catch (Exception ex) {
 361             INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className);
 362             exc.initCause( ex ) ;
 363             throw exc ;
 364         }
 365     }
 366 
 367     private static Class loadDelegateClass( String className )  throws ClassNotFoundException
 368     {
 369         try {
 370             ClassLoader loader = Thread.currentThread().getContextClassLoader();
 371             return Class.forName(className, false, loader);
 372         } catch (ClassNotFoundException e) {
 373             // ignore, then try RMIClassLoader
 374         }
 375 
 376         try {
 377             return RMIClassLoader.loadClass(className);
 378         } catch (MalformedURLException e) {
 379             String msg = "Could not load " + className + ": " + e.toString();
 380             ClassNotFoundException exc = new ClassNotFoundException( msg ) ;
 381             throw exc ;
 382         }
 383     }
 384     /**
 385      * Load the orb.properties file.
 386      */
 387     private static Properties getORBPropertiesFile ()
 388     {
 389         return (Properties) AccessController.doPrivileged(
 390             new GetORBPropertiesFileAction());
 391     }
 392 
 393 }