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