Util.java revision 608:7e06bf1dcb09
1336823Sdim/*
2336823Sdim * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3353358Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4353358Sdim *
5353358Sdim * This code is free software; you can redistribute it and/or modify it
6336823Sdim * under the terms of the GNU General Public License version 2 only, as
7336823Sdim * published by the Free Software Foundation.  Oracle designates this
8336823Sdim * particular file as subject to the "Classpath" exception as provided
9336823Sdim * by Oracle in the LICENSE file that accompanied this code.
10336823Sdim *
11336823Sdim * This code is distributed in the hope that it will be useful, but WITHOUT
12336823Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13336823Sdim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14336823Sdim * version 2 for more details (a copy is included in the LICENSE file that
15336823Sdim * accompanied this code).
16336823Sdim *
17336823Sdim * You should have received a copy of the GNU General Public License version
18336823Sdim * 2 along with this work; if not, write to the Free Software Foundation,
19336823Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20336823Sdim *
21336823Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22336823Sdim * or visit www.oracle.com if you need additional information or have any
23353358Sdim * questions.
24336823Sdim */
25336823Sdim/*
26336823Sdim * Licensed Materials - Property of IBM
27336823Sdim * RMI-IIOP v1.0
28336823Sdim * Copyright IBM Corp. 1998 1999  All Rights Reserved
29336823Sdim *
30336823Sdim */
31336823Sdim
32336823Sdimpackage javax.rmi.CORBA;
33336823Sdim
34336823Sdimimport java.rmi.RemoteException;
35336823Sdim
36336823Sdimimport org.omg.CORBA.ORB;
37336823Sdimimport org.omg.CORBA.INITIALIZE;
38336823Sdimimport org.omg.CORBA.SystemException;
39336823Sdimimport org.omg.CORBA.Any;
40336823Sdimimport org.omg.CORBA.portable.InputStream;
41336823Sdimimport org.omg.CORBA.portable.OutputStream;
42336823Sdimimport org.omg.CORBA.portable.ObjectImpl;
43336823Sdim
44336823Sdimimport javax.rmi.CORBA.Tie;
45336823Sdimimport java.rmi.Remote;
46336823Sdimimport java.io.File;
47336823Sdimimport java.io.FileInputStream;
48336823Sdimimport java.net.MalformedURLException ;
49336823Sdimimport java.security.AccessController;
50336823Sdimimport java.security.PrivilegedAction;
51336823Sdimimport java.util.Properties;
52336823Sdimimport java.rmi.server.RMIClassLoader;
53336823Sdim
54336823Sdimimport com.sun.corba.se.impl.orbutil.GetPropertyAction;
55353358Sdim
56336823Sdim/**
57336823Sdim * Provides utility methods that can be used by stubs and ties to
58336823Sdim * perform common operations.
59353358Sdim */
60336823Sdimpublic class Util {
61336823Sdim
62336823Sdim    // This can only be set at static initialization time (no sync necessary).
63336823Sdim    private static final javax.rmi.CORBA.UtilDelegate utilDelegate;
64336823Sdim    private static final String UtilClassKey = "javax.rmi.CORBA.UtilClass";
65336823Sdim
66336823Sdim    static {
67336823Sdim        utilDelegate = (javax.rmi.CORBA.UtilDelegate)createDelegate(UtilClassKey);
68336823Sdim    }
69336823Sdim
70336823Sdim    private Util(){}
71336823Sdim
72336823Sdim    /**
73336823Sdim     * Maps a SystemException to a RemoteException.
74336823Sdim     * @param ex the SystemException to map.
75336823Sdim     * @return the mapped exception.
76336823Sdim     */
77336823Sdim    public static RemoteException mapSystemException(SystemException ex) {
78336823Sdim
79336823Sdim        if (utilDelegate != null) {
80353358Sdim            return utilDelegate.mapSystemException(ex);
81336823Sdim        }
82336823Sdim        return null;
83353358Sdim    }
84336823Sdim
85336823Sdim    /**
86336823Sdim     * Writes any java.lang.Object as a CORBA any.
87336823Sdim     * @param out the stream in which to write the any.
88336823Sdim     * @param obj the object to write as an any.
89336823Sdim     */
90336823Sdim    public static void writeAny(OutputStream out, Object obj) {
91336823Sdim
92336823Sdim        if (utilDelegate != null) {
93336823Sdim            utilDelegate.writeAny(out, obj);
94353358Sdim        }
95336823Sdim    }
96336823Sdim
97336823Sdim    /**
98353358Sdim     * Reads a java.lang.Object as a CORBA any.
99353358Sdim     * @param in the stream from which to read the any.
100353358Sdim     * @return the object read from the stream.
101336823Sdim     */
102336823Sdim    public static Object readAny(InputStream in) {
103336823Sdim
104336823Sdim        if (utilDelegate != null) {
105336823Sdim            return utilDelegate.readAny(in);
106336823Sdim        }
107336823Sdim        return null;
108336823Sdim    }
109336823Sdim
110353358Sdim    /**
111336823Sdim     * Writes a java.lang.Object as a CORBA Object. If <code>obj</code> is
112336823Sdim     * an exported RMI-IIOP server object, the tie is found
113336823Sdim     * and wired to <code>obj</code>, then written to
114336823Sdim<code>out.write_Object(org.omg.CORBA.Object)</code>.
115336823Sdim     * If <code>obj</code> is a CORBA Object, it is written to
116336823Sdim     * <code>out.write_Object(org.omg.CORBA.Object)</code>.
117336823Sdim     * @param out the stream in which to write the object.
118353358Sdim     * @param obj the object to write.
119336823Sdim     */
120336823Sdim    public static void writeRemoteObject(OutputStream out,
121336823Sdim                                         java.lang.Object obj) {
122336823Sdim
123336823Sdim        if (utilDelegate != null) {
124336823Sdim            utilDelegate.writeRemoteObject(out, obj);
125336823Sdim        }
126336823Sdim
127336823Sdim    }
128336823Sdim
129336823Sdim    /**
130336823Sdim     * Writes a java.lang.Object as either a value or a CORBA Object.
131336823Sdim     * If <code>obj</code> is a value object or a stub object, it is written to
132336823Sdim     * <code>out.write_abstract_interface(java.lang.Object)</code>. If <code>obj</code>
133336823Sdimis
134336823Sdiman exported
135336823Sdim     * RMI-IIOP server object, the tie is found and wired to <code>obj</code>,
136336823Sdim     * then written to <code>out.write_abstract_interface(java.lang.Object)</code>.
137336823Sdim     * @param out the stream in which to write the object.
138336823Sdim     * @param obj the object to write.
139336823Sdim     */
140336823Sdim    public static void writeAbstractObject(OutputStream out,
141336823Sdim                                           java.lang.Object obj) {
142336823Sdim
143353358Sdim        if (utilDelegate != null) {
144336823Sdim            utilDelegate.writeAbstractObject(out, obj);
145336823Sdim        }
146336823Sdim    }
147336823Sdim
148336823Sdim    /**
149336823Sdim     * Registers a target for a tie. Adds the tie to an internal table and calls
150336823Sdim     * {@link Tie#setTarget} on the tie object.
151336823Sdim     * @param tie the tie to register.
152336823Sdim     * @param target the target for the tie.
153336823Sdim     */
154336823Sdim    public static void registerTarget(javax.rmi.CORBA.Tie tie,
155336823Sdim                                      java.rmi.Remote target) {
156336823Sdim
157353358Sdim        if (utilDelegate != null) {
158336823Sdim            utilDelegate.registerTarget(tie, target);
159336823Sdim        }
160336823Sdim
161336823Sdim    }
162336823Sdim
163336823Sdim    /**
164336823Sdim     * Removes the associated tie from an internal table and calls {@link
165336823SdimTie#deactivate}
166336823Sdim     * to deactivate the object.
167336823Sdim     * @param target the object to unexport.
168336823Sdim     */
169336823Sdim    public static void unexportObject(java.rmi.Remote target)
170336823Sdim        throws java.rmi.NoSuchObjectException
171353358Sdim    {
172336823Sdim
173336823Sdim        if (utilDelegate != null) {
174353358Sdim            utilDelegate.unexportObject(target);
175336823Sdim        }
176336823Sdim
177336823Sdim    }
178336823Sdim
179336823Sdim    /**
180336823Sdim     * Returns the tie (if any) for a given target object.
181336823Sdim     * @return the tie or null if no tie is registered for the given target.
182336823Sdim     */
183336823Sdim    public static Tie getTie (Remote target) {
184353358Sdim
185336823Sdim        if (utilDelegate != null) {
186336823Sdim            return utilDelegate.getTie(target);
187353358Sdim        }
188336823Sdim        return null;
189336823Sdim    }
190353358Sdim
191336823Sdim
192336823Sdim    /**
193353358Sdim     * Returns a singleton instance of a class that implements the
194336823Sdim     * {@link ValueHandler} interface.
195336823Sdim     * @return a class which implements the ValueHandler interface.
196336823Sdim     */
197336823Sdim    public static ValueHandler createValueHandler() {
198336823Sdim
199336823Sdim        if (utilDelegate != null) {
200336823Sdim            return utilDelegate.createValueHandler();
201353358Sdim        }
202336823Sdim        return null;
203336823Sdim    }
204353358Sdim
205336823Sdim    /**
206336823Sdim     * Returns the codebase, if any, for the given class.
207353358Sdim     * @param clz the class to get a codebase for.
208336823Sdim     * @return a space-separated list of URLs, or null.
209336823Sdim     */
210336823Sdim    public static String getCodebase(java.lang.Class clz) {
211336823Sdim        if (utilDelegate != null) {
212336823Sdim            return utilDelegate.getCodebase(clz);
213336823Sdim        }
214336823Sdim        return null;
215353358Sdim    }
216336823Sdim
217336823Sdim    /**
218336823Sdim     * Returns a class instance for the specified class.
219336823Sdim     * <P>The spec for this method is the "Java to IDL language
220336823Sdim     * mapping", ptc/00-01-06.
221336823Sdim     * <P>In Java SE Platform, this method works as follows:
222336823Sdim     * <UL><LI>Find the first non-null <tt>ClassLoader</tt> on the
223336823Sdim     * call stack and attempt to load the class using this
224336823Sdim     * <tt>ClassLoader</tt>.
225336823Sdim     * <LI>If the first step fails, and if <tt>remoteCodebase</tt>
226336823Sdim     * is non-null and
227336823Sdim     * <tt>useCodebaseOnly</tt> is false, then call
228336823Sdim     * <tt>java.rmi.server.RMIClassLoader.loadClass(remoteCodebase, className)</tt>.
229336823Sdim     * <LI>If <tt>remoteCodebase</tt> is null or <tt>useCodebaseOnly</tt>
230336823Sdim     * is true, then call <tt>java.rmi.server.RMIClassLoader.loadClass(className)</tt>.
231336823Sdim     * <LI>If a class was not successfully loaded by step 1, 2, or 3,
232336823Sdim     * and <tt>loader</tt> is non-null, then call <tt>loader.loadClass(className)</tt>.
233336823Sdim     * <LI>If a class was successfully loaded by step 1, 2, 3, or 4, then
234336823Sdim     *  return the loaded class, else throw <tt>ClassNotFoundException</tt>.
235336823Sdim     * @param className the name of the class.
236336823Sdim     * @param remoteCodebase a space-separated list of URLs at which
237336823Sdim     * the class might be found. May be null.
238353358Sdim     * @param loader a <tt>ClassLoader</tt> that may be used to
239336823Sdim     * load the class if all other methods fail.
240336823Sdim     * @return the <code>Class</code> object representing the loaded class.
241336823Sdim     * @exception ClassNotFoundException if class cannot be loaded.
242336823Sdim     */
243336823Sdim    public static Class loadClass(String className,
244336823Sdim                                  String remoteCodebase,
245336823Sdim                                  ClassLoader loader)
246353358Sdim        throws ClassNotFoundException {
247336823Sdim        if (utilDelegate != null) {
248336823Sdim            return utilDelegate.loadClass(className,remoteCodebase,loader);
249353358Sdim        }
250336823Sdim        return null ;
251336823Sdim    }
252336823Sdim
253336823Sdim
254336823Sdim    /**
255336823Sdim     * The <tt>isLocal</tt> method has the same semantics as the
256336823Sdim     * <tt>ObjectImpl._is_local</tt>
257336823Sdim     * method, except that it can throw a <tt>RemoteException</tt>.
258336823Sdim     *
259336823Sdim     * The <tt>_is_local()</tt> method is provided so that stubs may determine if a
260336823Sdim     * particular object is implemented by a local servant and hence local
261336823Sdim     * invocation APIs may be used.
262336823Sdim     *
263336823Sdim     * @param stub the stub to test.
264336823Sdim     *
265336823Sdim     * @return The <tt>_is_local()</tt> method returns true if
266336823Sdim     * the servant incarnating the object is located in the same process as
267336823Sdim     * the stub and they both share the same ORB instance.  The <tt>_is_local()</tt>
268336823Sdim     * method returns false otherwise. The default behavior of <tt>_is_local()</tt> is
269336823Sdim     * to return false.
270353358Sdim     *
271353358Sdim     * @throws RemoteException The Java to IDL specification does not
272353358Sdim     * specify the conditions that cause a <tt>RemoteException</tt> to be thrown.
273336823Sdim     */
274336823Sdim    public static boolean isLocal(Stub stub) throws RemoteException {
275336823Sdim
276336823Sdim        if (utilDelegate != null) {
277336823Sdim            return utilDelegate.isLocal(stub);
278336823Sdim        }
279336823Sdim
280336823Sdim        return false;
281336823Sdim    }
282336823Sdim
283336823Sdim    /**
284353358Sdim     * Wraps an exception thrown by an implementation
285353358Sdim     * method.  It returns the corresponding client-side exception.
286353358Sdim     * @param orig the exception to wrap.
287336823Sdim     * @return the wrapped exception.
288336823Sdim     */
289336823Sdim    public static RemoteException wrapException(Throwable orig) {
290336823Sdim
291336823Sdim        if (utilDelegate != null) {
292336823Sdim            return utilDelegate.wrapException(orig);
293336823Sdim        }
294336823Sdim
295336823Sdim        return null;
296336823Sdim    }
297336823Sdim
298336823Sdim    /**
299336823Sdim     * Copies or connects an array of objects. Used by local stubs
300336823Sdim     * to copy any number of actual parameters, preserving sharing
301336823Sdim     * across parameters as necessary to support RMI semantics.
302336823Sdim     * @param obj the objects to copy or connect.
303336823Sdim     * @param orb the ORB.
304336823Sdim     * @return the copied or connected objects.
305336823Sdim     * @exception RemoteException if any object could not be copied or connected.
306336823Sdim     */
307336823Sdim    public static Object[] copyObjects (Object[] obj, ORB orb)
308336823Sdim        throws RemoteException {
309336823Sdim
310336823Sdim        if (utilDelegate != null) {
311336823Sdim            return utilDelegate.copyObjects(obj, orb);
312336823Sdim        }
313336823Sdim
314336823Sdim        return null;
315336823Sdim    }
316336823Sdim
317336823Sdim    /**
318336823Sdim     * Copies or connects an object. Used by local stubs to copy
319336823Sdim     * an actual parameter, result object, or exception.
320336823Sdim     * @param obj the object to copy.
321336823Sdim     * @param orb the ORB.
322336823Sdim     * @return the copy or connected object.
323336823Sdim     * @exception RemoteException if the object could not be copied or connected.
324336823Sdim     */
325336823Sdim    public static Object copyObject (Object obj, ORB orb)
326353358Sdim        throws RemoteException {
327336823Sdim
328336823Sdim        if (utilDelegate != null) {
329336823Sdim            return utilDelegate.copyObject(obj, orb);
330336823Sdim        }
331336823Sdim        return null;
332336823Sdim    }
333336823Sdim
334336823Sdim    // Same code as in PortableRemoteObject. Can not be shared because they
335336823Sdim    // are in different packages and the visibility needs to be package for
336336823Sdim    // security reasons. If you know a better solution how to share this code
337336823Sdim    // then remove it from PortableRemoteObject. Also in Stub.java
338336823Sdim    private static Object createDelegate(String classKey) {
339336823Sdim        String className = (String)
340336823Sdim            AccessController.doPrivileged(new GetPropertyAction(classKey));
341336823Sdim        if (className == null) {
342336823Sdim            Properties props = getORBPropertiesFile();
343336823Sdim            if (props != null) {
344353358Sdim                className = props.getProperty(classKey);
345336823Sdim            }
346336823Sdim        }
347336823Sdim
348336823Sdim        if (className == null) {
349336823Sdim            return new com.sun.corba.se.impl.javax.rmi.CORBA.Util();
350336823Sdim        }
351353358Sdim
352336823Sdim        try {
353336823Sdim            return loadDelegateClass(className).newInstance();
354336823Sdim        } catch (ClassNotFoundException ex) {
355336823Sdim            INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className);
356336823Sdim            exc.initCause( ex ) ;
357336823Sdim            throw exc ;
358336823Sdim        } catch (Exception ex) {
359336823Sdim            INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className);
360336823Sdim            exc.initCause( ex ) ;
361336823Sdim            throw exc ;
362336823Sdim        }
363336823Sdim    }
364336823Sdim
365336823Sdim    private static Class loadDelegateClass( String className )  throws ClassNotFoundException
366336823Sdim    {
367336823Sdim        try {
368336823Sdim            ClassLoader loader = Thread.currentThread().getContextClassLoader();
369336823Sdim            return Class.forName(className, false, loader);
370336823Sdim        } catch (ClassNotFoundException e) {
371336823Sdim            // ignore, then try RMIClassLoader
372336823Sdim        }
373336823Sdim
374336823Sdim        try {
375336823Sdim            return RMIClassLoader.loadClass(className);
376336823Sdim        } catch (MalformedURLException e) {
377336823Sdim            String msg = "Could not load " + className + ": " + e.toString();
378336823Sdim            ClassNotFoundException exc = new ClassNotFoundException( msg ) ;
379336823Sdim            throw exc ;
380336823Sdim        }
381336823Sdim    }
382336823Sdim    /**
383336823Sdim     * Load the orb.properties file.
384336823Sdim     */
385336823Sdim    private static Properties getORBPropertiesFile ()
386336823Sdim    {
387336823Sdim        return (Properties) AccessController.doPrivileged(
388336823Sdim            new GetORBPropertiesFileAction());
389336823Sdim    }
390336823Sdim
391336823Sdim}
392336823Sdim