diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/java/rmi/activation/Activatable.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/java/rmi/activation/Activatable.java')
-rw-r--r-- | libjava/classpath/java/rmi/activation/Activatable.java | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/libjava/classpath/java/rmi/activation/Activatable.java b/libjava/classpath/java/rmi/activation/Activatable.java new file mode 100644 index 000000000..9ec7cad48 --- /dev/null +++ b/libjava/classpath/java/rmi/activation/Activatable.java @@ -0,0 +1,531 @@ +/* Activatable.java -- A common ancestor for the activatable objects. + Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.rmi.activation; + +import gnu.java.rmi.server.ActivatableServerRef; +import gnu.java.rmi.server.UnicastServer; +import gnu.java.rmi.server.UnicastServerRef; + +import java.lang.reflect.Field; +import java.rmi.MarshalledObject; +import java.rmi.NoSuchObjectException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.server.ObjID; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteServer; +import java.rmi.server.UnicastRemoteObject; + +/** + * A common ancestor for the implementations of the activatable objects. Such + * objects require persistent access over time and can be activated by the + * system. The derived classes also implements the needed interface of some + * remote object and usually have the two parameter constructor, the first + * parameter being the {@link ActivationID} and the second the + * {@link MarshalledObject}. Activatable is the main class that developers need + * to use to implement and manage activatable objects. It also contains methods + * for making activatable remote objects that are not derived from the + * Activatable class. + * + * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) + */ +public abstract class Activatable + extends RemoteServer +{ + + /** + * Use SVUID for interoperability. + */ + static final long serialVersionUID = - 3120617863591563455L; + + /** + * The object activation id. + */ + final ActivationID id; + + /** + * This constructor is used to register export the object on the given port. A + * subclass of the Activatable class calls this constructor to register and + * export the object during initial construction. As a side-effect of + * activatable object construction, the remote object is both "registered" + * with the activation system and "exported" (on an anonymous port, if port is + * zero) to the RMI runtime so that it is available to accept incoming calls + * from clients. + * + * @param codebase the object code base url + * @param data the data, needed to activate the object. + * @param restart specifies reactivation mode after crash. If true, the object + * is activated when activator is restarted or the activation group + * is restarted. If false, the object is only activated on demand. + * This flag does has no effect during the normal operation (the + * object is normally activated on demand). + * @param port the port, on which the object will become available. The value + * 0 means anonymous port. + * @throws ActivationException if the activation failed + * @throws RemoteException if the remote call failed. + */ + protected Activatable(String codebase, MarshalledObject<?> data, + boolean restart, int port) throws ActivationException, + RemoteException + { + ActivationDesc descriptor = new ActivationDesc(getClass().getName(), + codebase, data, restart); + id = obtainId(descriptor); + exportObject(this, id, port); + } + + /** + * This constructor is used to register export the object on the given port, + * additionally specifying the socket factories. A subclass of the Activatable + * class calls this constructor to register and export the object during + * initial construction. + * + * @param codebase the object code base url + * @param data the data, needed to activate the object. + * @param restart specifies reactivation mode after crash. If true, the object + * is activated when activator is restarted or the activation group + * is restarted. If false, the object is only activated on demand. + * This flag does has no effect during the normal operation (the + * object is normally activated on demand). + * @param port the port, on which the object will become available. The value + * 0 means anonymous port. + * @param csf the client socket factory + * @param ssf the server socket factory + * @throws ActivationException if the activation failed + * @throws RemoteException if the remote call failed. + */ + protected Activatable(String codebase, MarshalledObject<?> data, + boolean restart, int port, RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) throws ActivationException, + RemoteException + { + ActivationDesc descriptor = new ActivationDesc(getClass().getName(), + codebase, data, restart); + id = obtainId(descriptor); + exportObject(this, id, port); + } + + /** + * Creates the new instance of activatable with the given activation id and is + * listening at the given port. A subclass of the Activatable class calls this + * constructor when the object itself is activated via its special + * "activation" constructor with the two parameters ({@link ActivationID}, + * {@link MarshalledObject}). As a side effect, the object is exported and is + * available to accept incoming calls. + * + * @param anId the activation id + * @param port the port, on which the activatable will be listening + * @throws RemoteException if the activation failed. + */ + protected Activatable(ActivationID anId, int port) throws RemoteException + { + id = anId; + try + { + exportObject(this, anId, port); + } + catch (Exception e) + { + e.printStackTrace(); + RemoteException acex = + new RemoteException("cannot export Activatable", e); + throw acex; + } + } + + /** + * Creates the new instance of activatable with the given activation id and is + * listening at the given port, using the specified client and server sockets + * factories. A subclass of the Activatable class calls this + * constructor when the object itself is activated via its special + * "activation" constructor with the two parameters ({@link ActivationID}, + * {@link MarshalledObject}). As a side effect, the object is exported and is + * available to accept incoming calls. + * + * @param anId the activation id + * @param port the port, on which the activatable will be listening + * @param csf the client socket factory + * @param ssf the server socket factory + * + * @throws RemoteException if the remote call failed + */ + protected Activatable(ActivationID anId, int port, RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) throws RemoteException + { + id = anId; + try + { + exportObject(this, anId, port, csf, ssf); + } + catch (Exception e) + { + RemoteException acex = new RemoteException(); + acex.initCause(e); + throw acex; + } + } + + /** + * Get the objects activation identifier. + * + * @return the object activation identifier + */ + protected ActivationID getID() + { + return id; + } + + /** + * Obtain the activation Id from the activation descriptor by registering + * within the current group. + */ + static ActivationID obtainId(ActivationDesc descriptor) + throws RemoteException, UnknownGroupException, ActivationException + { + ActivationGroupID id = descriptor.getGroupID(); + ActivationSystem system; + + if (id != null) + system = id.getSystem(); + else + system = ActivationGroup.currentGroupID().getSystem(); + return system.registerObject(descriptor); + } + + /** + * This method registers an activatable object. The object is expected to be + * on the anonymous port (null client and server socket factories). + * + * @param desc the object description. + * @return the remote stub for the activatable object (the first call on this + * stub will activate the object). + * @throws UnknownGroupException if the object group identifier is unknown + * @throws ActivationException if the activation system is not running + * @throws RemoteException if the remote call fails + */ + public static Remote register(ActivationDesc desc) + throws UnknownGroupException, ActivationException, RemoteException + { + ActivationID id = obtainId(desc); + try + { + return toStub( + id, + Thread.currentThread().getContextClassLoader().loadClass( + desc.getClassName())); + } + catch (ClassNotFoundException e) + { + throw new ActivationException("Class not found: "+desc.getClassName()); + } + } + + /** + * Inactivates and unexports the object. The subsequent calls will activate + * the object again. The object is not inactivated if it is currently + * executing calls. + * + * @param id the id of the object being inactivated + * @return true if the object has been inactivated, false if it has not been + * inactivated because of the running or pending calls. + * @throws UnknownObjectException if the object is unknown. + * @throws ActivationException if the object group is not active + * @throws RemoteException if the remote call fails + */ + public static boolean inactive(ActivationID id) + throws UnknownObjectException, ActivationException, RemoteException + { + if (id.group!=null) + id.group.inactiveObject(id); + return UnicastRemoteObject.unexportObject(id.activate(false), false); + } + + /** + * Unregister the object (the object will no longer be activable with that id) + * + * @param id the object id + * @throws UnknownObjectException if the id is unknown + * @throws ActivationException if the activation system is not running + * @throws RemoteException if the remote call fails. + */ + public static void unregister(ActivationID id) throws UnknownObjectException, + ActivationException, RemoteException + { + ActivationGroup.currentGroupId.getSystem().unregisterObject(id); + UnicastServer.unregisterActivatable(id); + } + + /** + * Register and export the object that activatable object that is not derived + * from the Activatable super class. It creates and registers the object + * activation descriptor. There is no need to call this method if the object + * extends Activable, as its work is done in the constructor + * {@link #Activatable(String, MarshalledObject, boolean, int)}. + * + * @param obj the object, that is exported, becoming available at the given + * port. + * @param location the object code location (codebase). + * @param data the data, needed to activate the object + * @param restart the restart mode + * @param port the port, where the object will be available + * + * @return the created object activation ID. + * + * @throws ActivationException if the activation group is not active + * @throws RemoteException if the registration or export fails + */ + public static ActivationID exportObject(Remote obj, String location, + MarshalledObject<?> data, + boolean restart, int port) + throws ActivationException, RemoteException + { + ActivationDesc descriptor = new ActivationDesc(obj.getClass().getName(), + location, data, restart); + ActivationID id = obtainId(descriptor); + Remote stub = exportObject(obj, id, port); + return id; + } + + /** + * Register and export the object that activatable object that is not derived + * from the Activatable super class. It creates and registers the object + * activation descriptor. There is no need to call this method if the object + * extends Activable, as its work is done in the constructor + * {@link #Activatable(String, MarshalledObject, boolean, int, RMIClientSocketFactory, RMIServerSocketFactory)} + * + * @param obj the object, that is exported, becoming available at the given + * port. + * @param location the object code location (codebase). + * @param data the data, needed to activate the object + * @param restart the restart mode + * @param port the port, where the object will be available + * @param csf the client socket factory + * @param ssf the server socket factory + * + * @return the created object activation ID. + * + * @throws ActivationException if the activation group is not active + * @throws RemoteException if the registration or export fails + */ + public static ActivationID exportObject(Remote obj, String location, + MarshalledObject data, + boolean restart, int port, + RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) + throws ActivationException, RemoteException + { + ActivationDesc descriptor = new ActivationDesc(obj.getClass().getName(), + location, data, restart); + ActivationID id = obtainId(descriptor); + Remote stub = exportObject(obj, id, port, csf, ssf); + return id; + + } + + /** + * During activation, this exportObject method should be invoked explicitly by + * the activatable object, that does is not derived from the Activatable + * class. There is no need to call this method if the object extends + * Activable, as its work is done in the constructor + * {@link #Activatable(ActivationID, int)} + * + * @param obj the object + * @param id the known activation id + * @param port the object port + * + * @return the remote stub of the activatable object + * + * @throws RemoteException if the object export fails + */ + public static Remote exportObject(Remote obj, ActivationID id, int port) + throws RemoteException + { + Remote stub = export(id, obj, port, null); + return stub; + } + + /** + * During activation, this exportObject method should be invoked explicitly by + * the activatable object, that does is not derived from the Activatable + * class. There is no need to call this method if the object extends + * Activable, as its work is done in the constructor + * {@link #Activatable(ActivationID, int)} + * + * @param obj the object + * @param id the known activation id + * @param port the object port + * @param csf the client socket factory + * @param ssf the server socket factory + * + * @return the remote stub of the activatable object + * + * @throws RemoteException if the object export fails + */ + public static Remote exportObject(Remote obj, ActivationID id, int port, + RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) + throws RemoteException + { + Remote stub = export(id, obj, port, ssf); + return stub; + + } + + /** + * Make the remote object unavailable for incoming calls. This method also + * unregisters the object, so it cannot be activated again by incoming call + * (unless registered). + * + * @param obj the object to unexport + * @param force if true, cancel all pending or running calls to that object + * (if false, the object with such calls is not unexported and false + * is returned by this method). + * @return if the object was successfully unexported, false otherwise + * @throws NoSuchObjectException if such object is not known + */ + public static boolean unexportObject(Remote obj, boolean force) + throws NoSuchObjectException + { + Object aref = UnicastServer.getExportedRef(obj); + + // Unregister it also (otherwise will be activated during the subsequent + // call. + if (aref instanceof ActivatableServerRef) + { + ActivatableServerRef aar = (ActivatableServerRef) aref; + UnicastServer.unregisterActivatable(aar.actId); + } + return UnicastRemoteObject.unexportObject(obj, force); + } + + static Remote exportObject(Remote obj, int port, + RMIServerSocketFactory serverSocketFactory) + throws RemoteException + { + UnicastServerRef sref = null; + if (obj instanceof RemoteObject) + sref = (UnicastServerRef) ((RemoteObject) obj).getRef(); + + if (sref == null) + sref = new UnicastServerRef(new ObjID(), port, serverSocketFactory); + + Remote stub = sref.exportObject(obj); + // addStub(obj, stub); + // TODO Need to change the place of the stub repository + return stub; + } + + /** + * Create and export the new remote object, making it available at the given + * port, using sockets, produced by the specified factories. + * + * @param port the port, on that the object should become available. Zero + * means anonymous port. + * @param serverSocketFactory the server socket factory + */ + private static Remote export(ActivationID id, Remote obj, int port, + RMIServerSocketFactory serverSocketFactory) + throws RemoteException + { + ActivatableServerRef sref = null; + sref = new ActivatableServerRef(makeId(id), id, port, serverSocketFactory); + return sref.exportObject(obj); + } + + /** + * Make the object ID from the activation ID. The same activation ID always + * produces the identical object id. + * + * @param aid the activation id + * + * @return the object id + */ + private static ObjID makeId(ActivationID aid) + { + ObjID id = new ObjID(0); + + // The fields of both ObjID and ActivationID must be package private, + // so we need to use the reflection to access them anyway. + // Probably other implementations use some very different approach. + + try + { + Field idUid = ObjID.class.getDeclaredField("space"); + Field aidUid = ActivationID.class.getDeclaredField("uid"); + + aidUid.setAccessible(true); + idUid.setAccessible(true); + + idUid.set(id, aidUid.get(aid)); + } + catch (Exception e) + { + InternalError ierr = new InternalError("Unable to set UID field"); + ierr.initCause(e); + throw ierr; + } + + return id; + } + + /** + * Connect the object to the UnicastServer (export), but not activate it. + * The object will be activated on the first call. + */ + static Remote toStub(ActivationID anId, Class stubFor) + { + try + { + ActivatableServerRef asr = + new ActivatableServerRef(makeId(anId), anId, 0, null); + UnicastServer.exportActivatableObject(asr); + return asr.exportClass(stubFor); + } + catch (RemoteException e) + { + InternalError ierr = new InternalError( + "Failed to obtain activatable stub"); + ierr.initCause(e); + throw ierr; + } + } +} |