duke@1: /* ohair@240: * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@158: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@158: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@158: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@158: * or visit www.oracle.com if you need additional information or have any ohair@158: * questions. duke@1: */ duke@1: /* duke@1: * Licensed Materials - Property of IBM duke@1: * RMI-IIOP v1.0 duke@1: * Copyright IBM Corp. 1998 1999 All Rights Reserved duke@1: * duke@1: */ duke@1: duke@1: package javax.rmi; duke@1: duke@1: import java.lang.reflect.Method ; duke@1: duke@1: import org.omg.CORBA.INITIALIZE; duke@1: import javax.rmi.CORBA.Util; duke@1: duke@1: import java.rmi.RemoteException; duke@1: import java.rmi.NoSuchObjectException; duke@1: import java.rmi.Remote; duke@1: import java.io.File; duke@1: import java.io.FileInputStream; duke@1: import java.util.Properties; duke@1: import java.net.MalformedURLException ; duke@1: import java.security.AccessController; duke@1: import java.security.PrivilegedAction; duke@1: import java.rmi.server.RMIClassLoader; duke@1: duke@1: import com.sun.corba.se.impl.orbutil.GetPropertyAction; duke@1: duke@1: /** duke@1: * Server implementation objects may either inherit from duke@1: * javax.rmi.PortableRemoteObject or they may implement a remote interface duke@1: * and then use the exportObject method to register themselves as a server object. duke@1: * The toStub method takes a server implementation and returns a stub that duke@1: * can be used to access that server object. duke@1: * The connect method makes a Remote object ready for remote communication. duke@1: * The unexportObject method is used to deregister a server object, allowing it to become duke@1: * available for garbage collection. duke@1: * The narrow method takes an object reference or abstract interface type and duke@1: * attempts to narrow it to conform to duke@1: * the given interface. If the operation is successful the result will be an duke@1: * object of the specified type, otherwise an exception will be thrown. duke@1: */ duke@1: public class PortableRemoteObject { duke@1: alanb@533: private static final javax.rmi.CORBA.PortableRemoteObjectDelegate proDelegate; duke@1: duke@1: private static final String PortableRemoteObjectClassKey = duke@1: "javax.rmi.CORBA.PortableRemoteObjectClass"; duke@1: duke@1: static { duke@1: proDelegate = (javax.rmi.CORBA.PortableRemoteObjectDelegate) alanb@533: createDelegate(PortableRemoteObjectClassKey); duke@1: } duke@1: duke@1: /** duke@1: * Initializes the object by calling exportObject(this). duke@1: * @exception RemoteException if export fails. duke@1: */ duke@1: protected PortableRemoteObject() throws RemoteException { duke@1: if (proDelegate != null) { duke@1: PortableRemoteObject.exportObject((Remote)this); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Makes a server object ready to receive remote calls. Note duke@1: * that subclasses of PortableRemoteObject do not need to call this duke@1: * method, as it is called by the constructor. duke@1: * @param obj the server object to export. duke@1: * @exception RemoteException if export fails. duke@1: */ duke@1: public static void exportObject(Remote obj) duke@1: throws RemoteException { duke@1: duke@1: // Let the delegate do everything, including error handling. duke@1: if (proDelegate != null) { duke@1: proDelegate.exportObject(obj); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Returns a stub for the given server object. duke@1: * @param obj the server object for which a stub is required. Must either be a subclass duke@1: * of PortableRemoteObject or have been previously the target of a call to duke@1: * {@link #exportObject}. duke@1: * @return the most derived stub for the object. duke@1: * @exception NoSuchObjectException if a stub cannot be located for the given server object. duke@1: */ duke@1: public static Remote toStub (Remote obj) duke@1: throws NoSuchObjectException { duke@1: duke@1: if (proDelegate != null) { duke@1: return proDelegate.toStub(obj); duke@1: } duke@1: return null; duke@1: } duke@1: duke@1: /** duke@1: * Deregisters a server object from the runtime, allowing the object to become duke@1: * available for garbage collection. duke@1: * @param obj the object to unexport. duke@1: * @exception NoSuchObjectException if the remote object is not duke@1: * currently exported. duke@1: */ duke@1: public static void unexportObject(Remote obj) duke@1: throws NoSuchObjectException { duke@1: duke@1: if (proDelegate != null) { duke@1: proDelegate.unexportObject(obj); duke@1: } duke@1: duke@1: } duke@1: duke@1: /** duke@1: * Checks to ensure that an object of a remote or abstract interface type duke@1: * can be cast to a desired type. duke@1: * @param narrowFrom the object to check. duke@1: * @param narrowTo the desired type. duke@1: * @return an object which can be cast to the desired type. duke@1: * @throws ClassCastException if narrowFrom cannot be cast to narrowTo. duke@1: */ duke@1: public static java.lang.Object narrow ( java.lang.Object narrowFrom, duke@1: java.lang.Class narrowTo) duke@1: throws ClassCastException { duke@1: duke@1: if (proDelegate != null) { duke@1: return proDelegate.narrow(narrowFrom, narrowTo); duke@1: } duke@1: return null; duke@1: duke@1: } duke@1: duke@1: /** duke@1: * Makes a Remote object ready for remote communication. This normally duke@1: * happens implicitly when the object is sent or received as an argument duke@1: * on a remote method call, but in some circumstances it is useful to duke@1: * perform this action by making an explicit call. See the andrew@135: * {@link javax.rmi.CORBA.Stub#connect} method for more information. duke@1: * @param target the object to connect. duke@1: * @param source a previously connected object. duke@1: * @throws RemoteException if source is not connected duke@1: * or if target is already connected to a different ORB than duke@1: * source. duke@1: */ duke@1: public static void connect (Remote target, Remote source) duke@1: throws RemoteException { duke@1: duke@1: if (proDelegate != null) { duke@1: proDelegate.connect(target, source); duke@1: } duke@1: duke@1: } duke@1: duke@1: // Same code as in javax.rmi.CORBA.Util. Can not be shared because they duke@1: // are in different packages and the visibility needs to be package for duke@1: // security reasons. If you know a better solution how to share this code duke@1: // then remove it from here. alanb@533: private static Object createDelegate(String classKey) { duke@1: String className = (String) duke@1: AccessController.doPrivileged(new GetPropertyAction(classKey)); duke@1: if (className == null) { duke@1: Properties props = getORBPropertiesFile(); duke@1: if (props != null) { duke@1: className = props.getProperty(classKey); duke@1: } duke@1: } duke@1: if (className == null) { alanb@533: return new com.sun.corba.se.impl.javax.rmi.PortableRemoteObject(); duke@1: } duke@1: duke@1: try { duke@1: return (Object) loadDelegateClass(className).newInstance(); duke@1: } catch (ClassNotFoundException ex) { duke@1: INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className); duke@1: exc.initCause( ex ) ; duke@1: throw exc ; duke@1: } catch (Exception ex) { duke@1: INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className); duke@1: exc.initCause( ex ) ; duke@1: throw exc ; duke@1: } duke@1: duke@1: } duke@1: duke@1: private static Class loadDelegateClass( String className ) throws ClassNotFoundException duke@1: { duke@1: try { duke@1: ClassLoader loader = Thread.currentThread().getContextClassLoader(); duke@1: return Class.forName(className, false, loader); duke@1: } catch (ClassNotFoundException e) { duke@1: // ignore, then try RMIClassLoader duke@1: } duke@1: duke@1: try { duke@1: return RMIClassLoader.loadClass(className); duke@1: } catch (MalformedURLException e) { duke@1: String msg = "Could not load " + className + ": " + e.toString(); duke@1: ClassNotFoundException exc = new ClassNotFoundException( msg ) ; duke@1: throw exc ; duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Load the orb.properties file. duke@1: */ duke@1: private static Properties getORBPropertiesFile () { duke@1: return (Properties) AccessController.doPrivileged(new GetORBPropertiesFileAction()); duke@1: } duke@1: } duke@1: duke@1: class GetORBPropertiesFileAction implements PrivilegedAction { duke@1: private boolean debug = false ; duke@1: duke@1: public GetORBPropertiesFileAction () { duke@1: } duke@1: duke@1: private String getSystemProperty(final String name) { duke@1: // This will not throw a SecurityException because this duke@1: // class was loaded from rt.jar using the bootstrap classloader. duke@1: String propValue = (String) AccessController.doPrivileged( duke@1: new PrivilegedAction() { duke@1: public java.lang.Object run() { duke@1: return System.getProperty(name); duke@1: } duke@1: } duke@1: ); duke@1: duke@1: return propValue; duke@1: } duke@1: duke@1: private void getPropertiesFromFile( Properties props, String fileName ) duke@1: { duke@1: try { duke@1: File file = new File( fileName ) ; duke@1: if (!file.exists()) duke@1: return ; duke@1: duke@1: FileInputStream in = new FileInputStream( file ) ; duke@1: duke@1: try { duke@1: props.load( in ) ; duke@1: } finally { duke@1: in.close() ; duke@1: } duke@1: } catch (Exception exc) { duke@1: if (debug) duke@1: System.out.println( "ORB properties file " + fileName + duke@1: " not found: " + exc) ; duke@1: } duke@1: } duke@1: duke@1: public Object run() duke@1: { duke@1: Properties defaults = new Properties() ; duke@1: duke@1: String javaHome = getSystemProperty( "java.home" ) ; duke@1: String fileName = javaHome + File.separator + "lib" + File.separator + duke@1: "orb.properties" ; duke@1: duke@1: getPropertiesFromFile( defaults, fileName ) ; duke@1: duke@1: Properties results = new Properties( defaults ) ; duke@1: duke@1: String userHome = getSystemProperty( "user.home" ) ; duke@1: fileName = userHome + File.separator + "orb.properties" ; duke@1: duke@1: getPropertiesFromFile( results, fileName ) ; duke@1: return results ; duke@1: } duke@1: }