com.kedwards.swt
Class ServiceWrapper

com.kedwards.swt.ServiceWrapper
All Implemented Interfaces:
Checkpointed

public class ServiceWrapper
implements Checkpointed

ServiceWrapper.java

A ServiceWrapper handles a number of chores related to being a service. In particular, it

Note that ServiceWrappers are used differently depending on whether the service backend is activatable or not. Most service backends are created and then passed to a wrapper for management. Activatable backends, though, create their own service wrappers internally.

See http://www.kedwards.com/jini

No warranty expressed or implied; use at your own risk; for educational purposes only.

Author:
Keith Edwards

Field Summary
static java.lang.String DEBUG
          Property to control wrapper debugging.
static java.lang.String SWT_NO_ADMIN_UI_ATTR
          Set to any value to prevent the wrapper from adding a default admin UI to the service's registration.
static java.lang.String SWT_NO_DEBUG_ATTRS
          Set to any value to prevent the wrapper from adding its own debugging attributes to the service's registration.
 
Constructor Summary
ServiceWrapper(ServiceBackend backend, Persistifier persistifier, ClassExporter exporter)
          This is the most general form of the constructor.
ServiceWrapper(ServiceBackend backend, java.lang.String file)
          Create a new wrapper to manage the provided backend.
ServiceWrapper(ServiceBackend backend, java.lang.String file, ClassExporter exporter)
          Create a new wrapper to manage the provided backend.
 
Method Summary
static void __run(ServiceBackend backend, java.lang.String checkpointLoc)
          Subclasses can launch services in one of two ways.
 void checkpoint()
          This is the top-level method that is called to initiate the checkpoint process.
static java.lang.String declassify(java.lang.String classname)
           
 void getCheckpointData(TaggedPersistentData data)
          Called when the wrapper must checkpoint its state.
 net.jini.discovery.DiscoveryManagement getDiscoveryManager()
          Returns the discovery management object in use by the wrapper.
 ClassExporter getExporter()
          Returns the class exporter in use by the wrapper.
protected  net.jini.core.entry.Entry[] getInitialAttributes()
          This method calls the backend to get any initial attributes.
 net.jini.lookup.JoinManager getJoinManager()
          Returns the join manager in use by the wrapper.
 Persistifier getPersistifier()
          Returns the persistifier in use by the wrapper.
protected  java.lang.Object getProxy()
          This method calls out to the backend to get the proxy.
protected  net.jini.core.entry.Entry[] getWrapperProvidedAttributes()
          The wrapper can optionally add its own attributes to the service's registration that are not directly provided by the backend.
 void initialize()
          Initialize the wrapper.
 void restore()
          This is the top-level method that is called to restore the state of the service from checkpointed data.
static void run(ServiceBackend backend, java.lang.String checkpointLoc)
           
static void run(ServiceBackend backend, java.lang.String[] commandLineArgs)
           
 void serviceIDNotify(net.jini.core.lookup.ServiceID id)
          Called by the JoinManager when we've got a service ID.
 void setCheckpointData(TaggedPersistentData data)
          Called when the wrapper must recover its state from checkpointed data.
 void shutdown()
          administration will call this to shutdown.
 

Field Detail

DEBUG

public static final java.lang.String DEBUG
Property to control wrapper debugging. Set to a comma-separated list containing "rmi", "discovery", "lookup", "wrapper", or "all".

SWT_NO_DEBUG_ATTRS

public static final java.lang.String SWT_NO_DEBUG_ATTRS
Set to any value to prevent the wrapper from adding its own debugging attributes to the service's registration.

SWT_NO_ADMIN_UI_ATTR

public static final java.lang.String SWT_NO_ADMIN_UI_ATTR
Set to any value to prevent the wrapper from adding a default admin UI to the service's registration.
Constructor Detail

ServiceWrapper

public ServiceWrapper(ServiceBackend backend,
                      java.lang.String file)
               throws java.io.IOException,
                      ArgException
Create a new wrapper to manage the provided backend. This version of the constructor uses the FSPersistifier to save state, and creates a ContextClassExporter to export class files.
Parameters:
backend - A service backend to be managed.
file - A file to use for checkpoint data.

ServiceWrapper

public ServiceWrapper(ServiceBackend backend,
                      java.lang.String file,
                      ClassExporter exporter)
               throws java.io.IOException,
                      ArgException
Create a new wrapper to manage the provided backend. This version of the constructor uses the FSPersistifier to save state.
Parameters:
backend - A service backend to be managed.
file - A file to use for checkpoint data.
exporter - The class exporter to use to serve classfiles.

ServiceWrapper

public ServiceWrapper(ServiceBackend backend,
                      Persistifier persistifier,
                      ClassExporter exporter)
               throws java.io.IOException
This is the most general form of the constructor. It lets you choose any persistifier and any exporter to use.
Parameters:
backend - A service backend to be managed.
persistifier - An object that will handle the service's checkpoint/restore duties.
exprter - The exporter to use to serve classfiles.
Method Detail

shutdown

public void shutdown()
administration will call this to shutdown. clients can override.

getJoinManager

public net.jini.lookup.JoinManager getJoinManager()
Returns the join manager in use by the wrapper.
Returns:
The wrapper's JoinManager.

getDiscoveryManager

public net.jini.discovery.DiscoveryManagement getDiscoveryManager()
Returns the discovery management object in use by the wrapper.
Returns:
The wrapper's DiscoveryManagement.

getPersistifier

public Persistifier getPersistifier()
Returns the persistifier in use by the wrapper.
Returns:
The wrapper's persistifier.

getExporter

public ClassExporter getExporter()
Returns the class exporter in use by the wrapper.
Returns:
The wrapper's ClassExporter.

serviceIDNotify

public void serviceIDNotify(net.jini.core.lookup.ServiceID id)
Called by the JoinManager when we've got a service ID. This code sets the ID in the backend, calls postInitialize() on it, and then checkpoints itself.

getCheckpointData

public void getCheckpointData(TaggedPersistentData data)
                       throws java.io.IOException
Called when the wrapper must checkpoint its state. The wrapper adds its own state to the data object, and then calls the backend so that it can adds whatever data it needs checkpointed.
Specified by:
getCheckpointData in interface Checkpointed
Parameters:
data - The persistent data object to which the wrapper adds the data it wants to be checkpointed.

setCheckpointData

public void setCheckpointData(TaggedPersistentData data)
                       throws java.io.IOException,
                              java.lang.ClassNotFoundException
Called when the wrapper must recover its state from checkpointed data. The wrapper reads the information it added, so that it can recover the JoinManager's state. It then calls out to the backend so that it can recover its state.
Specified by:
setCheckpointData in interface Checkpointed
Parameters:
data - The persistent data object from which the wrapper will recover its state.

checkpoint

public void checkpoint()
                throws java.io.IOException
This is the top-level method that is called to initiate the checkpoint process. It can be invoked any time a service changes its state and wishes to update the checkpointed data.

restore

public void restore()
             throws java.io.IOException,
                    java.lang.ClassNotFoundException
This is the top-level method that is called to restore the state of the service from checkpointed data. It should only be called once, when the service is initially restored upon startup.

getProxy

protected java.lang.Object getProxy()
                             throws java.io.IOException,
                                    java.lang.ClassNotFoundException
This method calls out to the backend to get the proxy. It also does some early error checking. If the wrapper debug flag is set, it tests the proxy for proper serializability.

getInitialAttributes

protected net.jini.core.entry.Entry[] getInitialAttributes()
                                                    throws java.io.IOException,
                                                           java.lang.ClassNotFoundException
This method calls the backend to get any initial attributes. To this list, it also adds any attributes returned by getWrapperProvidedAttributes. If the wraper debug flag is set, it then tests these for proper serializability.

getWrapperProvidedAttributes

protected net.jini.core.entry.Entry[] getWrapperProvidedAttributes()
The wrapper can optionally add its own attributes to the service's registration that are not directly provided by the backend. If the swt.noDebugAttr property is set to any value, then no extra entries will be added. If the swt.noAdminUI property is set, then no default administrative UI will be added.

initialize

public void initialize()
                throws java.lang.Exception
Initialize the wrapper. This method invokes preInitialize on the backend, and then creates a new LookupDiscoveryManager. After this, it either invoked restore on the backend (if it is restorable), or initialize (if this is the first time the service has been run). A JoinManager is then created. Only after a ServiceID is available will postInitialize be called on the service backend.

declassify

public static java.lang.String declassify(java.lang.String classname)

__run

public static void __run(ServiceBackend backend,
                         java.lang.String checkpointLoc)
Subclasses can launch services in one of two ways. The hand-crafted approach is to create a main that instantiates the service backend, pass it to the ServiceWrapper constructor, and then call initialize() on the constructor. This way gives you access to the ServiceWrapper constructor, and the time at which you set a security manager. The second way is to use the run() method below, passing it an instance of your service's backend. This method implements the common case for a main. For example: public static void main(String[] args) { ServiceWrapper.run(new MyBackend(), args[0]); }

run

public static void run(ServiceBackend backend,
                       java.lang.String checkpointLoc)

run

public static void run(ServiceBackend backend,
                       java.lang.String[] commandLineArgs)
                throws ArgException