From 4f9533c7722fa07511a94d005227961f4a4dec23 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 18 May 2006 17:29:21 +0000 Subject: Imported GNU Classpath 0.90 Imported GNU Classpath 0.90 * scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale. * sources.am: Regenerated. * gcj/javaprims.h: Regenerated. * Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * testsuite/Makefile.in: Regenerated. * gnu/java/lang/VMInstrumentationImpl.java: New override. * gnu/java/net/local/LocalSocketImpl.java: Likewise. * gnu/classpath/jdwp/VMMethod.java: Likewise. * gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest interface. * java/lang/Thread.java: Add UncaughtExceptionHandler. * java/lang/reflect/Method.java: Implements GenericDeclaration and isSynthetic(), * java/lang/reflect/Field.java: Likewise. * java/lang/reflect/Constructor.java * java/lang/Class.java: Implements Type, GenericDeclaration, getSimpleName() and getEnclosing*() methods. * java/lang/Class.h: Add new public methods. * java/lang/Math.java: Add signum(), ulp() and log10(). * java/lang/natMath.cc (log10): New function. * java/security/VMSecureRandom.java: New override. * java/util/logging/Logger.java: Updated to latest classpath version. * java/util/logging/LogManager.java: New override. From-SVN: r113887 --- .../classpath/java/rmi/activation/Activatable.java | 514 +++++++++++++++++++-- .../java/rmi/activation/ActivationDesc.java | 279 ++++++++--- .../java/rmi/activation/ActivationGroup.java | 314 +++++++++++-- .../java/rmi/activation/ActivationGroupDesc.java | 449 +++++++++++++++--- .../java/rmi/activation/ActivationGroupID.java | 96 +++- .../java/rmi/activation/ActivationGroup_Stub.java | 2 +- .../java/rmi/activation/ActivationID.java | 179 +++++-- .../rmi/activation/ActivationInstantiator.java | 23 + .../java/rmi/activation/ActivationMonitor.java | 42 +- .../java/rmi/activation/ActivationSystem.java | 196 ++++++-- .../classpath/java/rmi/activation/Activator.java | 22 + libjava/classpath/java/rmi/activation/package.html | 33 +- libjava/classpath/java/rmi/dgc/VMID.java | 139 ++++-- libjava/classpath/java/rmi/dgc/package.html | 12 +- libjava/classpath/java/rmi/server/ObjID.java | 202 +++++--- libjava/classpath/java/rmi/server/Operation.java | 8 + .../classpath/java/rmi/server/RemoteObject.java | 124 +++-- .../rmi/server/RemoteObjectInvocationHandler.java | 10 +- .../classpath/java/rmi/server/RemoteServer.java | 99 ++-- libjava/classpath/java/rmi/server/UID.java | 262 +++++++---- 20 files changed, 2441 insertions(+), 564 deletions(-) (limited to 'libjava/classpath/java/rmi') diff --git a/libjava/classpath/java/rmi/activation/Activatable.java b/libjava/classpath/java/rmi/activation/Activatable.java index b4c38bf..472c65c 100644 --- a/libjava/classpath/java/rmi/activation/Activatable.java +++ b/libjava/classpath/java/rmi/activation/Activatable.java @@ -1,5 +1,6 @@ -/* Activatable.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. +/* 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. @@ -38,68 +39,493 @@ 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; -public abstract class Activatable extends RemoteServer +/** + * 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 { -static final long serialVersionUID = -3120617863591563455L; -protected Activatable(String location, MarshalledObject data, boolean restart, int port) throws ActivationException, RemoteException { - throw new Error("Not implemented"); -} + /** + * 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); + } -protected Activatable(String location, MarshalledObject data, boolean restart, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws ActivationException, RemoteException { - throw new Error("Not implemented"); -} + /** + * 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); + } -protected Activatable(ActivationID id, int port) throws RemoteException { - throw new Error("Not implemented"); -} + /** + * 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 incomming 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; + } + } -protected Activatable(ActivationID id, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - throw new Error("Not implemented"); -} + /** + * 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 incomming 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; -protected ActivationID getID() { - throw new Error("Not implemented"); -} + 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; + } -public static Remote register(ActivationDesc desc) throws UnknownGroupException, ActivationException, RemoteException { - throw new Error("Not implemented"); -} + /** + * 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; -public static boolean inactive(ActivationID id) throws UnknownObjectException, ActivationException, RemoteException { - throw new Error("Not implemented"); -} + } -public static void unregister(ActivationID id) throws UnknownObjectException, ActivationException, RemoteException { - throw new Error("Not implemented"); -} + /** + * 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; + } -public static ActivationID exportObject(Remote obj, String location, MarshalledObject data, boolean restart, int port) throws ActivationException, RemoteException { - throw new Error("Not implemented"); -} + /** + * 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; -public static ActivationID exportObject(Remote obj, String location, MarshalledObject data, boolean restart, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws ActivationException, RemoteException { - throw new Error("Not implemented"); -} + } -public static Remote exportObject(Remote obj, ActivationID id, int port) throws RemoteException { - throw new Error("Not implemented"); -} + /** + * Make the remote object unavailable for incoming calls. This method also + * unregisters the object, so it cannot be activated again by incomming 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(); -public static Remote exportObject(Remote obj, ActivationID id, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - throw new Error("Not implemented"); -} - -public static boolean unexportObject(Remote obj, boolean force) throws NoSuchObjectException { - throw new Error("Not implemented"); -} + 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 + */ + public 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 + */ + public 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; + } + } } diff --git a/libjava/classpath/java/rmi/activation/ActivationDesc.java b/libjava/classpath/java/rmi/activation/ActivationDesc.java index 65894f8..b861656 100644 --- a/libjava/classpath/java/rmi/activation/ActivationDesc.java +++ b/libjava/classpath/java/rmi/activation/ActivationDesc.java @@ -1,6 +1,6 @@ -/* ActivationDecc.java -- +/* ActivationDesc.java -- record with info to activate an object Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. - + This file is part of GNU Classpath. GNU Classpath is free software; you can redistribute it and/or modify @@ -40,74 +40,215 @@ package java.rmi.activation; import java.io.Serializable; import java.rmi.MarshalledObject; -public final class ActivationDesc implements Serializable +/** + * Contains the information, necessary to activate the object. This information + * includes: + * + * + * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) + */ +public final class ActivationDesc + implements Serializable { + /** + * Use SVUID for interoperability. + */ static final long serialVersionUID = 7455834104417690957L; -private ActivationGroupID groupid; -private String classname; -private String location; -private MarshalledObject data; -private boolean restart; - -public ActivationDesc(String className, String location, MarshalledObject data) throws ActivationException { - this(ActivationGroup.currentGroupID(), className, location, data, false); -} - -public ActivationDesc(String className, String location, MarshalledObject data, boolean restart) throws ActivationException { - this(ActivationGroup.currentGroupID(), className, location, data, restart); -} - -public ActivationDesc(ActivationGroupID groupID, String className, String location, MarshalledObject data) { - this(groupID, className, location, data, false); -} - -public ActivationDesc(ActivationGroupID groupID, String className, String location, MarshalledObject data, boolean restart) { - this.groupid = groupID; - this.classname = className; - this.location = location; - this.data = data; - this.restart = restart; -} - -public ActivationGroupID getGroupID() { - return (groupid); -} - -public String getClassName() { - return (classname); -} - -public String getLocation() { - return (location); -} - -public MarshalledObject getData() { - return (data); -} - -public boolean getRestartMode() { - return (restart); -} - -public boolean equals(Object obj) { - if (!(obj instanceof ActivationDesc)) { - return (false); - } - ActivationDesc that = (ActivationDesc)obj; - - if (this.groupid.equals(that.groupid) && - this.classname.equals(that.classname) && - this.location.equals(that.location) && - this.data.equals(that.data) && - this.restart == that.restart) { - return (true); - } - return (false); -} - -public int hashCode() { - return (groupid.hashCode() ^ classname.hashCode() ^ location.hashCode() ^ data.hashCode()); -} - + /** + * The group id. + */ + private ActivationGroupID groupid; + + /** + * The class name. + */ + private String classname; + + /** + * The code location URL. + */ + private String location; + + /** + * The object specific intitalization data. + */ + private MarshalledObject data; + + /** + * The start mode. + */ + private boolean restart; + + /** + * Create the new activation description, assuming the object group is the + * {@link ActivationGroup#currentGroupID()}. + * + * @param className the object fully qualified class name + * @param location the code base URL + * @param data the object initialization data, contained in a marshalled form + */ + public ActivationDesc(String className, String location, MarshalledObject data) + throws ActivationException + { + this(ActivationGroup.currentGroupID(), className, location, data, false); + } + + /** + * Create the new activation description, assuming the object group is the + * {@link ActivationGroup#currentGroupID()}. + * + * @param className the object fully qualified class name + * @param location the code base URL + * @param data the object initialization data, contained in a marshalled form + * @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). + */ + public ActivationDesc(String className, String location, + MarshalledObject data, boolean restart) + throws ActivationException + { + this(ActivationGroup.currentGroupID(), className, location, data, restart); + } + + /** + * Create the new activation description. Under crash, the object will only + * be reactivated on demand. + * + * @param groupID the object group id. + * @param className the object fully qualified class name + * @param location the code base URL + * @param data the object initialization data, contained in a marshalled form + */ + public ActivationDesc(ActivationGroupID groupID, String className, + String location, MarshalledObject data) + { + this(groupID, className, location, data, false); + } + + /** + * Create the new activation description, providing full information. + * + * @param groupID the object group id. + * @param className the object fully qualified class name + * @param location the code base URL + * @param data the object initialization data, contained in a marshalled form + * @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). + */ + public ActivationDesc(ActivationGroupID groupID, String className, + String location, MarshalledObject data, boolean restart) + { + this.groupid = groupID; + this.classname = className; + this.location = location; + this.data = data; + this.restart = restart; + } + + public ActivationGroupID getGroupID() + { + return groupid; + } + + /** + * Get the class name of the object being activated + * + * @return the fully qualified class name of the object being activated + */ + public String getClassName() + { + return classname; + } + + /** + * Get the code location URL ("codebase") of the object being activated. + * + * @return the codebase of the object being activated. + */ + public String getLocation() + { + return location; + } + + public MarshalledObject getData() + { + return data; + } + + /** + * Get the object reactivation strategy after crash. + * + * @return true ir the object is activated when activator is restarted or the + * activation group is restarted. False if the object is only + * activated on demand. This flag does has no effect during the normal + * operation (the object is normally activated on demand). + */ + public boolean getRestartMode() + { + return restart; + } + + /** + * Compare this object with another activation description for equality. + * + * @return true if all fields have the equal values, false otherwise. + */ + public boolean equals(Object obj) + { + if (obj instanceof ActivationDesc) + { + ActivationDesc that = (ActivationDesc) obj; + return eq(groupid, that.groupid) && + eq(classname, that.classname) && + eq(location, that.location) && + eq(data, that.data) + && restart == that.restart; + } + else + return false; + } + + /** + * Get the hash code of this object (overridden to make the returned value + * consistent with .equals(..). + */ + public int hashCode() + { + return hash(groupid) ^ hash(classname) ^ + hash(location) ^ hash(data); + } + + /** + * Get the hashcode of x or 0 if x == null. + */ + static final int hash(Object x) + { + return x == null ? 0 : x.hashCode(); + } + + /** + * Compare by .equals if both a and b are not null, compare directly if at + * least one of them is null. + */ + static final boolean eq(Object a, Object b) + { + if (a == null || b == null) + return a == b; + else + return a.equals(b); + } } diff --git a/libjava/classpath/java/rmi/activation/ActivationGroup.java b/libjava/classpath/java/rmi/activation/ActivationGroup.java index e5774a1..5e7bbd2 100644 --- a/libjava/classpath/java/rmi/activation/ActivationGroup.java +++ b/libjava/classpath/java/rmi/activation/ActivationGroup.java @@ -1,5 +1,5 @@ -/* ActivationGroup.java -- - Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +/* ActivationGroup.java -- the RMI activation group. + Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,48 +38,302 @@ exception statement from your version. */ package java.rmi.activation; +import gnu.java.rmi.activation.DefaultActivationGroup; +import gnu.java.rmi.activation.DefaultActivationSystem; + +import java.lang.reflect.Constructor; import java.rmi.MarshalledObject; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; -public abstract class ActivationGroup extends UnicastRemoteObject - implements ActivationInstantiator +/** + * The entity that receives the request to activate object and activates it. + * Frequently there is one activation group per virtual machine. + * + * @author Audrius Meskauskas (audriusa@Bioinformatics.org) (from stub) + */ +public abstract class ActivationGroup + extends UnicastRemoteObject + implements ActivationInstantiator { -static final long serialVersionUID = -7696947875314805420L; -protected ActivationGroup(ActivationGroupID groupID) throws RemoteException { - throw new Error("Not implemented"); -} + /** + * Use the SVUID for interoperability. + */ + static final long serialVersionUID = - 7696947875314805420L; + + /** + * The Id of the current group on this VM (null if none). + */ + static ActivationGroupID currentGroupId = null; + + /** + * The groups identifier. + */ + final ActivationGroupID groupId; -public boolean inactiveObject(ActivationID id) throws ActivationException, UnknownObjectException, RemoteException { - throw new Error("Not implemented"); -} + /** + * The groups activation monitor. + */ + ActivationMonitor monitor; + + /** + * The groups incarnation number. + */ + long incarnation; + + /** + * The groups activation system. + */ + static ActivationSystem system; + + /** + * Used during the group creation (required constructor). + */ + static final Class[] cConstructorTypes = new Class[] + { + ActivationGroupID.class, + MarshalledObject.class + }; -public abstract void activeObject(ActivationID id, Remote obj) throws ActivationException, UnknownObjectException, RemoteException; + /** + * Create the new activation group with the given group id. + * + * @param aGroupId the group Id. + * + * @throws RemoteException if the group export fails. + */ + protected ActivationGroup(ActivationGroupID aGroupId) throws RemoteException + { + groupId = aGroupId; + } + + /** + * The method is called when the object is exported. The group must notify + * the activation monitor, if this was not already done before. + * + * @param id the object activation id + * @param obj the remote object implementation + * + * @throws ActivationException if the group is inactive + * @throws UnknownObjectException if such object is not known + * @throws RemoteException if the call to monitor fails + */ + public abstract void activeObject(ActivationID id, Remote obj) + throws ActivationException, UnknownObjectException, RemoteException; + + /** + * Notifies the monitor about the object being inactivated. + * + * @param id the object being inactivated. + * @return true always (must be overridden to return other values). + * @throws ActivationException never + * @throws UnknownObjectException if the object is not known + * @throws RemoteException if the remote call to monitor fails + */ + public boolean inactiveObject(ActivationID id) throws ActivationException, + UnknownObjectException, RemoteException + { + if (monitor != null) + monitor.inactiveObject(id); + return true; + } -public static ActivationGroup createGroup(ActivationGroupID id, ActivationGroupDesc desc, long incarnation) throws ActivationException { - throw new Error("Not implemented"); -} + /** + * Create the new instance of the activation group, using the class name and + * location information, stored in the passed descriptor. The method expects + * the group class to have the two parameter constructor, the first parameter + * being the {@link ActivationGroupID} and the second the + * {@link MarshalledObject}. The group must be first be registered with the + * ActivationSystem. Once a group is created, the currentGroupID method + * returns the identifier for this group until the group becomes inactive. + * + * @param id the activation group id + * @param desc the group descriptor, providing the information, necessary to + * create the group + * @param incarnation the incarnation number + * @return the created group instance + * @throws ActivationException if the activation fails due any reason + */ + public static ActivationGroup createGroup(ActivationGroupID id, + ActivationGroupDesc desc, + long incarnation) + throws ActivationException + { + // If the activation system is not yet set, set it to the system. + // passed in the group id. + if (system == null) + system = id.system; + + ActivationGroup group = null; -public static ActivationGroupID currentGroupID() { - throw new Error("Not implemented"); -} + // TODO at the moment all groups are created on the current jre and the + // group class must be reachable via thread context class loader. + Class groupClass; -public static void setSystem(ActivationSystem system) throws ActivationException { - throw new Error("Not implemented"); -} + if (desc.className != null) + { + try + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + groupClass = loader.loadClass(desc.className); + } + catch (ClassNotFoundException e) + { + ActivationException acex = new ActivationException( + "Cannot load " + desc.className); + acex.detail = e; + throw acex; + } + } + else + groupClass = DefaultActivationGroup.class; -public static ActivationSystem getSystem() throws ActivationException { - throw new Error("Not implemented"); -} + try + { + Constructor constructor = groupClass.getConstructor(cConstructorTypes); + group = (ActivationGroup) constructor.newInstance( + new Object[] { id, desc.data }); + } + catch (Exception e) + { + ActivationException acex = new ActivationException( + "Cannot instantiate " + desc.className); + acex.detail = e; + throw acex; + } -protected void activeObject(ActivationID id, MarshalledObject mobj) throws ActivationException, UnknownObjectException, RemoteException { - throw new Error("Not implemented"); -} + currentGroupId = id; + try + { + group.monitor = getSystem().activeGroup(id, group, incarnation); + return group; + } + catch (RemoteException e) + { + ActivationException acex = new ActivationException("createGroup"); + acex.detail = e; + throw acex; + } + } -protected void inactiveGroup() throws UnknownGroupException, RemoteException { - throw new Error("Not implemented"); -} + /** + * Get the id of current activation group. + * + * @return the id of the current activation group or null if none exists. + */ + public static ActivationGroupID currentGroupID() + { + try + { + if (currentGroupId==null) + { + // This will also assing the currentGroupId to the current + // (default) group of the default system. + setSystem(DefaultActivationSystem.get()); + } + } + catch (ActivationException e) + { + InternalError ierr = new InternalError("Unable to activate AS"); + ierr.initCause(e); + throw ierr; + } + + return currentGroupId; + } + + /** + * Set the activation system for this virtual machine. The system can only + * be set if no group is active. + * + * @param aSystem the system to set + * + * @throws ActivationException if some group is active now. + */ + public static void setSystem(ActivationSystem aSystem) + throws ActivationException + { + if (currentGroupId!=null) + throw new ActivationException("Group active"); + else + { + try + { + // Register the default transient activation system and group. + system = aSystem; + ActivationGroupDesc def = new ActivationGroupDesc( + DefaultActivationGroup.class.getName(), + "", + null, + null, + null); + currentGroupId = system.registerGroup(def); + } + catch (Exception ex) + { + InternalError ierr = new InternalError("Unable to start default AG"); + ierr.initCause(ex); + throw ierr; + } + } + } + + /** + * Get the current activation system. If the system is not set via + * {@link #setSystem} method, the default system for this virtual machine is + * returned. The default system is first searched by name + * "java.rmi.activation.ActivationSystem" on the activation registry port. The + * default value of the activation registry port is + * {@link ActivationSystem#SYSTEM_PORT}, but it can be changed by putting the + * system property java.rmi.activation.port. Both activation system and + * activation registry are provided by the RMI daemon tool, RMID, if it is + * running on the local host. If the RMID is not running, the internal + * transient activation system will be created and returned. This internal + * system is highly limited in in capabilities and is not intended to be used + * anywhere apart automated testing. + * + * @return the activation system for this virtual machine + * @throws ActivationException + */ + public static ActivationSystem getSystem() throws ActivationException + { + if (system == null) + system = DefaultActivationSystem.get(); + return system; + } + + /** + * Makes the call back to the groups {@link ActivationMonitor}. + * + * @param id the id obj the object being activated + * @param mObject the marshalled object, contains the activated remote object + * stub. + * @throws ActivationException on activation error + * @throws UnknownObjectException if such object is not registered + * @throws RemoteException on remote call (to monitor) error + */ + protected void activeObject(ActivationID id, MarshalledObject mObject) + throws ActivationException, UnknownObjectException, RemoteException + { + if (monitor!=null) + monitor.activeObject(id, mObject); + + id.group = this; + } + + /** + * Makes the call back to the groups {@link ActivationMonitor} and sets + * the current group to null. + */ + protected void inactiveGroup() throws UnknownGroupException, RemoteException + { + if (monitor!=null) + monitor.inactiveGroup(groupId, incarnation); + + if (currentGroupId!=null && currentGroupId.equals(groupId)) + currentGroupId = null; + } } diff --git a/libjava/classpath/java/rmi/activation/ActivationGroupDesc.java b/libjava/classpath/java/rmi/activation/ActivationGroupDesc.java index 35b546e..76ac63b 100644 --- a/libjava/classpath/java/rmi/activation/ActivationGroupDesc.java +++ b/libjava/classpath/java/rmi/activation/ActivationGroupDesc.java @@ -1,5 +1,6 @@ -/* ActivationGroupDesc.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. +/* ActivationGroupDesc.java -- the RMI activation group descriptor + Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,97 +39,395 @@ exception statement from your version. */ package java.rmi.activation; +import gnu.java.rmi.activation.DefaultActivationGroup; + import java.io.Serializable; import java.rmi.MarshalledObject; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Iterator; import java.util.Properties; +import java.util.TreeSet; +import java.util.zip.Adler32; -public final class ActivationGroupDesc implements Serializable +/** + * Contains information, necessary to create of recreate the activation objects. + * The group descriptor contains: + * + * The groups are created by the {@link ActivationGroup#createGroup} method that + * expectes the group class to have the two parameter constructor, the first + * parameter being the {@link ActivationGroupID} and the second the + * {@link MarshalledObject}. + * + * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) + */ +public final class ActivationGroupDesc + implements Serializable { - static final long serialVersionUID = -4936225423168276595L; + /** + * Contains the startup options for the {@link ActivationGroup} + * implementations. Allows to override system properties and specify other + * options for the implementation groups. + * + * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) + */ + public static class CommandEnvironment + implements Serializable + { -public static class CommandEnvironment - implements Serializable { + /** + * Use the SVUID for interoperability. + */ + static final long serialVersionUID = 6165754737887770191L; + + /** + * The zero size string array used as argv value when null is passed. + */ + private static final String[] NO_ARGS = new String[0]; -static final long serialVersionUID = 6165754737887770191L; - -private String cmdpath; -private String[] argv; + /** + * The path to the java executable (or null for using default jre). + */ + final String command; + + /** + * The extra parameters (may be empty array but never null). + */ + final String[] options; + + /** + * Create the new command environment. + * + * @param commandPatch the full path (and name) to the java executable of + * null for using the default executable. + * @param args extra options that will be used when creating the activation + * group. Null has the same effect as the empty list. + */ + public CommandEnvironment(String commandPatch, String[] args) + { + command = commandPatch; + if (args != null) + options = args; + else + options = NO_ARGS; + } + + /** + * Get the path to the java executable. + * + * @return the path to the java executable or null for using the default + * jre. + */ + public String getCommandPath() + { + return command; + } + + /** + * Get the additional command options. + * + * @return the command options array, may be empty string + */ + public String[] getCommandOptions() + { + return options; + } + + /** + * Compare for content equality. + */ + public boolean equals(Object obj) + { + if (obj instanceof CommandEnvironment) + { + CommandEnvironment that = (CommandEnvironment) obj; -public CommandEnvironment(String cmdpath, String[] argv) { - this.cmdpath = cmdpath; - this.argv = argv; -} - -public String getCommandPath() { - return (cmdpath); -} - -public String[] getCommandOptions() { - return (argv); -} - -public boolean equals(Object obj) { - if (!(obj instanceof CommandEnvironment)) { - return (false); - } - CommandEnvironment that = (CommandEnvironment)obj; - - if (!this.cmdpath.equals(that.cmdpath)) { - return (false); - } - - int len = this.argv.length; - if (len != that.argv.length) { - return (false); - } - for (int i = 0; i < len; i++) { - if (!this.argv[i].equals(that.argv[i])) { - return (false); - } - } - return (true); -} + if (command == null || that.command == null) + { + // Use direct comparison if null is involved. + if (command != that.command) + return false; + } + else + { + // Use .equals if null is not involved. + if (! this.command.equals(that.command)) + return false; + } -public int hashCode() { - return (cmdpath.hashCode()); // Not a very good hash code. -} + return Arrays.equals(options, that.options); + } + else + return false; + } -} + /** + * Get the hash code. + */ + public int hashCode() + { + int h = command == null ? 0 : command.hashCode(); + for (int i = 0; i < options.length; i++) + h ^= options[i].hashCode(); -public ActivationGroupDesc(Properties overrides, ActivationGroupDesc.CommandEnvironment cmd) { - throw new Error("Not implemented"); -} + return h; + } + } + + /** + * Use the SVUID for interoperability. + */ + static final long serialVersionUID = - 4936225423168276595L; + + /** + * The group class name or null for the default group class implementation. + */ + final String className; + + /** + * The group class download location URL (codebase), ignored by the + * default implementation. + */ + final String location; + + /** + * The group initialization data. + */ + final MarshalledObject data; + + /** + * The path to the group jre and the parameters of this jre, may be + * null for the default jre. + */ + final ActivationGroupDesc.CommandEnvironment env; + + /** + * The properties that override the system properties. + */ + final Properties props; + + /** + * The cached hash code. + */ + transient long hash; + + /** + * Create the new activation group descriptor that will use the default + * activation group implementation with the given properties and + * environment. + * + * @param aProperties the properties that override the system properties + * @param environment the command line (and parameters), indicating, where to + * find the jre executable and with that parameters to call it. May + * be null if the default executable should be used. In this case, + * the activation group with the null name (the system default group) + * will be created. + */ + public ActivationGroupDesc(Properties aProperties, + ActivationGroupDesc.CommandEnvironment environment) + { + this(DefaultActivationGroup.class.getName(), null, null, aProperties, + environment); + } + + /** + * Create the new activation group descriptor. + * + * @param aClassName the name of the group implementation class. The null + * value indicates the default implementation. + * @param aLocation the location, from where the group implementation class + * should be loaded (ignored for the system default implementation). + * @param aData the group intialization data + * @param aProperties the properties that will override the system properties + * of the new group. These properties will be translated into -D + * options. + * @param environment the record, containing path to the jre executable and + * start options for the jre or null for using the default jre and + * options. + */ + public ActivationGroupDesc(String aClassName, String aLocation, + MarshalledObject aData, Properties aProperties, + ActivationGroupDesc.CommandEnvironment environment) + { + className = aClassName; + location = aLocation; + data = aData; + props = aProperties; + env = environment; + } + + /** + * Get the activation group class name. + * + * @return the activation group class name (null for default implementation) + */ + public String getClassName() + { + return className; + } + + /** + * Get the location, from where the group class will be loaded + * + * @return the location, from where the implementation should be loaded (null + * for the default implementation) + */ + public String getLocation() + { + return location; + } + + /** + * Get the group intialization data. + * + * @return the group intialization data in the marshalled form. + */ + public MarshalledObject getData() + { + return data; + } -public ActivationGroupDesc(String className, String location, MarshalledObject data, Properties overrides, ActivationGroupDesc.CommandEnvironment cmd) { - throw new Error("Not implemented"); -} + /** + * Get the overridded system properties. + * + * @return the overridden group system properties. + */ + public Properties getPropertyOverrides() + { + return props; + } + + /** + * Get the group command environment, containing path to the jre executable + * and startup options. + * + * @return the command environment or null if the default environment should + * be used. + */ + public ActivationGroupDesc.CommandEnvironment getCommandEnvironment() + { + return env; + } + + /** + * Compare for the content equality. + */ + public boolean equals(Object obj) + { + if (obj instanceof ActivationGroupDesc) + { + ActivationGroupDesc that = (ActivationGroupDesc) obj; -public String getClassName() { - throw new Error("Not implemented"); -} + // Ensure the hashcodes are computed. + if (hash == 0) + hashCode(); + if (that.hash == 0) + that.hashCode(); -public String getLocation() { - throw new Error("Not implemented"); -} + // We compare the hash fields as they are type long rather than int. + if (hash != that.hash) + return false; -public MarshalledObject getData() { - throw new Error("Not implemented"); -} + if (! eq(className, that.className)) + return false; + if (! eq(data, that.data)) + return false; + if (! eq(env, that.env)) + return false; + if (! eq(location, that.location)) + return false; -public Properties getPropertyOverrides() { - throw new Error("Not implemented"); -} + // Compare the properties. + if (eq(props, that.props)) + return true; -public ActivationGroupDesc.CommandEnvironment getCommandEnvironment() { - throw new Error("Not implemented"); -} + if (props.size() != that.props.size()) + return false; -public boolean equals(Object obj) { - throw new Error("Not implemented"); -} + Enumeration en = props.propertyNames(); + Object key, value; -public int hashCode() { - throw new Error("Not implemented"); -} + while (en.hasMoreElements()) + { + key = en.nextElement(); + if (! that.props.containsKey(key)) + return false; + if (! eq(props.get(key), that.props.get(key))) + return false; + } + return true; + } + else + return false; + } + + /** + * Compare for direct equality if one or both parameters are null, otherwise + * call .equals. + */ + static boolean eq(Object a, Object b) + { + if (a == null || b == null) + return a == b; + else + return a.equals(b); + } + + /** + * Return the hashcode. + */ + public int hashCode() + { + if (hash==0) + { + // Using Adler32 - the hashcode is cached, will be computed only + // once and due need to scan properties is the expensive operation + // anyway. Reliability is more important. + Adler32 adler = new Adler32(); + if (className!=null) + adler.update(className.getBytes()); + if (data!=null) + adler.update(data.hashCode()); + if (env!=null) + adler.update(env.hashCode()); + if (location!=null) + adler.update(location.getBytes()); + if (props!=null) + { + Enumeration en = props.propertyNames(); + + // Using the intermediate sorted set to ensure that the + // properties are sorted. + TreeSet pr = new TreeSet(); + + Object key; + Object value; + while (en.hasMoreElements()) + { + key = en.nextElement(); + if (key!=null) + pr.add(key); + } + + Iterator it = pr.iterator(); + while (it.hasNext()) + { + key = it.next(); + value = props.get(key); + adler.update(key.hashCode()); + if (value!=null) + adler.update(value.hashCode()); + } + } + hash = adler.getValue(); + } + return (int) hash; + } } diff --git a/libjava/classpath/java/rmi/activation/ActivationGroupID.java b/libjava/classpath/java/rmi/activation/ActivationGroupID.java index 5e0b964..e54b2a0 100644 --- a/libjava/classpath/java/rmi/activation/ActivationGroupID.java +++ b/libjava/classpath/java/rmi/activation/ActivationGroupID.java @@ -1,5 +1,5 @@ /* ActivationGroupID.java -- - Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -35,36 +35,88 @@ 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 java.io.Serializable; +import java.rmi.server.UID; -public class ActivationGroupID implements Serializable +/** + * This identifier identifies the activation group inside the scope of its + * activation system. It also contains (and can provide) the reference to the + * groups activation system. + * + * @see ActivationSystem#registerGroup(ActivationGroupDesc) + */ +public class ActivationGroupID + implements Serializable { - static final long serialVersionUID = -1648432278909740833L; + /** + * Use SVUID for interoperability. + */ + static final long serialVersionUID = - 1648432278909740833L; -private ActivationSystem system; + /** + * The associated activation system. + */ + final ActivationSystem system; + + /** + * The object identifier, making the ID unique. + */ + final UID uid; -public ActivationGroupID(ActivationSystem system) { - this.system = system; -} + /** + * Create the new activation group id in the scope of the given activation + * system + * + * @param aSystem the activation system + */ + public ActivationGroupID(ActivationSystem aSystem) + { + system = aSystem; + uid = new UID(); + } -public ActivationSystem getSystem() { - return (system); -} + /** + * Get the associated activation system + * + * @return the associated activation system + */ + public ActivationSystem getSystem() + { + return system; + } -public int hashCode() { - return (system.hashCode()); -} + /** + * Get the hash code of the associated activation system. + */ + public int hashCode() + { + return uid.hashCode(); + } -public boolean equals(Object obj) { - if (obj instanceof ActivationGroupID) { - ActivationGroupID that = (ActivationGroupID)obj; - if (this.system.equals(that.system)) { - return (true); - } - } - return (false); -} + /** + * Copmare for equality, returns true if the passed object is also the + * activation group id and its activation system is the same. + */ + public boolean equals(Object obj) + { + if (obj instanceof ActivationGroupID) + { + ActivationGroupID that = (ActivationGroupID) obj; + return uid.equals(that.uid); + } + else + return false; + } + + /** + * Get the string representation + */ + public String toString() + { + return uid.toString(); + } } diff --git a/libjava/classpath/java/rmi/activation/ActivationGroup_Stub.java b/libjava/classpath/java/rmi/activation/ActivationGroup_Stub.java index 249137b..fb55e5f 100644 --- a/libjava/classpath/java/rmi/activation/ActivationGroup_Stub.java +++ b/libjava/classpath/java/rmi/activation/ActivationGroup_Stub.java @@ -51,7 +51,7 @@ import java.rmi.server.RemoteStub; * * @author Roman Kennke (kennke@aicas.com) */ -public class ActivationGroup_Stub extends RemoteStub +public final class ActivationGroup_Stub extends RemoteStub implements ActivationInstantiator, Remote { private static final long serialVersionUID = 2L; diff --git a/libjava/classpath/java/rmi/activation/ActivationID.java b/libjava/classpath/java/rmi/activation/ActivationID.java index 23ed853..c4bbcd2 100644 --- a/libjava/classpath/java/rmi/activation/ActivationID.java +++ b/libjava/classpath/java/rmi/activation/ActivationID.java @@ -1,5 +1,5 @@ -/* ActivationID.java -- - Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +/* ActivationID.java -- the object activation identifier + Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -35,38 +35,165 @@ 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 java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.rmi.Remote; import java.rmi.RemoteException; +import java.rmi.server.UID; -public class ActivationID implements Serializable +/** + * Denotes the object that can be activated over time. The instance of the + * ActivationID for the given object can be obtained in the following ways: + * + * An instance of the ActivationID has the {@link UID} as its component and + * hence is globally unique. + * + * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) + */ +public class ActivationID + implements Serializable { - static final long serialVersionUID = -4608673054848209235L; - -private Activator activator; - -public ActivationID(Activator activator) { - this.activator = activator; -} + /** + * Use SVUID for interoperability. + */ + static final long serialVersionUID = - 4608673054848209235L; -public Remote activate(boolean force) throws ActivationException, UnknownObjectException, RemoteException { - throw new Error("Not implemented"); -} - -public int hashCode() { - return (activator.hashCode()); -} + /** + * The activator. + */ + transient Activator activator; + + /** + * The UID, making this instance unique. + */ + transient UID uid; + + /** + * The activation group that has activated the object with this + * activation id. The field is filled in inside the group and is used + * to notify the group about the request to inactivated the object. + */ + transient ActivationGroup group; -public boolean equals(Object obj) { - if (obj instanceof ActivationID) { - ActivationID that = (ActivationID)obj; - if (this.activator.equals(that.activator)) { - return (true); - } - } - return (false); -} + /** + * Create a new instance with the given activator. + * + * @param an_activator tha activator that should activate the object. + */ + public ActivationID(Activator an_activator) + { + activator = an_activator; + uid = new UID(); + } + + /** + * Activate the object. + * + * @param force if true, always contact the group. Otherwise, the cached value + * may be returned. + * @return the activated object + * @throws UnknownObjectException if the object is unknown + * @throws ActivationException if the activation has failed + * @throws RemoteException if the remote call has failed + */ + public Remote activate(boolean force) throws ActivationException, + UnknownObjectException, RemoteException + { + try + { + return (Remote) activator.activate(this, force).get(); + } + catch (IOException e) + { + ActivationException acex = new ActivationException("id "+uid, e); + throw acex; + } + catch (ClassNotFoundException e) + { + ActivationException acex = new ActivationException("id "+uid, e); + throw acex; + } + } + + /** + * Returns the hash code of the activator. + */ + public int hashCode() + { + return uid == null ? 0 : uid.hashCode(); + } + + /** + * Compares the activators for equality. + */ + public boolean equals(Object obj) + { + if (obj instanceof ActivationID) + { + ActivationID that = (ActivationID) obj; + return eq(uid, that.uid); + } + else + return false; + } + + /** + * Read the object from the input stream. + * + * @param in the stream to read from + * + * @throws IOException if thrown by the stream + * @throws ClassNotFoundException + */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException + { + uid = (UID) in.readObject(); + activator = (Activator) in.readObject(); + } + + /** + * Write the object to the output stream. + * + * @param out the stream to write int + * @throws IOException if thrown by the stream + * @throws ClassNotFoundException + */ + private void writeObject(ObjectOutputStream out) throws IOException, + ClassNotFoundException + { + out.writeObject(uid); + out.writeObject(activator); + }; + + /** + * Compare by .equals if both a and b are not null, compare directly if at + * least one of them is null. + */ + static final boolean eq(Object a, Object b) + { + if (a == null || b == null) + return a == b; + else + return a.equals(b); + } + /** + * Return the content based string representation. + */ + public String toString() + { + return uid.toString(); + } + } diff --git a/libjava/classpath/java/rmi/activation/ActivationInstantiator.java b/libjava/classpath/java/rmi/activation/ActivationInstantiator.java index 0aceb7a..a0f04ed 100644 --- a/libjava/classpath/java/rmi/activation/ActivationInstantiator.java +++ b/libjava/classpath/java/rmi/activation/ActivationInstantiator.java @@ -42,9 +42,32 @@ import java.rmi.MarshalledObject; import java.rmi.Remote; import java.rmi.RemoteException; +/** + * The implementation of this interface creates (instantiates) the new remote + * objects in response to the activation request. The instantiator is returned + * by the {@link ActivationGroup} that calls + * {@link ActivationSystem#activeGroup(ActivationGroupID, ActivationInstantiator, long)}. + */ public interface ActivationInstantiator extends Remote { + /** + * Creates and instantiate a new remote object. This method performs the + * following tasks: + *