livespace.services
Class EntityContainer

java.lang.Object
  extended by livespace.services.EntityContainer
All Implemented Interfaces:
PropertyListener, Disposable, Closeable, EventListener, CloseListener, NotificationListener
Direct Known Subclasses:
EntityClient, EntityServer

public abstract class EntityContainer
extends Object
implements PropertyListener, NotificationListener, CloseListener, Disposable, Closeable

Base class for containers that manage distributed Entity instances.

Author:
Matthew Phillips
See Also:
EntityClient, EntityServer

Nested Class Summary
protected  class EntityContainer.EmitNotificationTask
          Used to emit a notification as a background task.
 
Field Summary
protected  String containerId
          UUID for this container.
 Elvin elvin
          The elvin connection being used by the container.
 EntityRegistry entities
          The entities being managed by the container.
 RoomEntity room
          The room the conatiner is operating within.
protected  Scheduler scheduler
          Scheduler used for periodic and one-off background tasks.
 
Constructor Summary
EntityContainer(Elvin elvin, RoomEntity room)
           
EntityContainer(Elvin elvin, RoomEntity room, EntityRegistry entities)
           
 
Method Summary
 void close()
          Synonym for dispose().
 void connectionClosed(CloseEvent e)
           
protected  Entity createEntity(String id, String entityType)
          Create a new entity or re-use an existing weakly-cached version previously created in this container.
protected  XmlInput createXmlInput()
           
protected  XmlOutput createXmlOutput()
           
 void dispose()
          Dispose of the object (unregister listeners, close open resources etc).
protected  void emit(Notification ntfn)
          Shortcut to emit a notification.
protected  void emitAsync(Notification ntfn)
          Emit a notification asynchronously using a scheduler task.
protected  Entity getOrCreateEntity(String id, String entityType)
          Find an existing entity in the registry or create a new one if none exists.
protected abstract  void handleNotification(NotificationEvent e)
           
 boolean isClosed()
           
protected  boolean isInResponseToMe(Notification ntfn)
          Test if a notification was generated in response to something I sent.
 Object mutex()
          The lock that must be held to ensure thread-safe access to entities in this container.
 void notificationReceived(NotificationEvent e)
           
protected  void read(Entity entity, Notification ntfn, boolean init)
          Read and update state from an incoming info notification.
protected  void registerEntityTree(Object object)
          Register any entities found in a tree of data objects.
protected static void setContainerRecursively(IDataObject object, EntityContainer container)
          Set the container property for a tree of data objects.
protected static void setContainerRecursively(IDataObject object, EntityContainer container, boolean shouldEmitNotification)
          Set the container property for a tree of data objects.
static void setDefaultUpdaterForThread(Executor executor)
          Set the default update executor for the current thread, or null to revert to the default.
 void setUpdateExecutor(Executor newExecutor)
          Set the update executor for this container, or null to use the default executor.
protected static boolean shouldPublish(Entity entity, Object property)
          Test if a given property should be automatically exported/imported by the read ()/write () functions.
protected static String[] splitPropertyPath(String str)
          Split a property path of the form "prop1/prop2/prop3" into a string array.
protected  void write(Entity entity, Notification ntfn)
          Write the entity's significant state into a notification for publication.
protected  void write(Notification ntfn, PropertyPath path, Object value)
          Write an abbreviated version of the entity's significant state into a notification, given that a specified property has just changed.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface dsto.dfc.databeans.PropertyListener
propertyValueChanged
 

Field Detail

elvin

public final Elvin elvin
The elvin connection being used by the container.


entities

public final EntityRegistry entities
The entities being managed by the container.


room

public final RoomEntity room
The room the conatiner is operating within. May be null for "roomless" operation.


containerId

protected String containerId
UUID for this container.


scheduler

protected Scheduler scheduler
Scheduler used for periodic and one-off background tasks. This scheduler is shared among all containers in a VM via Livespace.acquireScheduler().

Constructor Detail

EntityContainer

public EntityContainer(Elvin elvin,
                       RoomEntity room)
                throws IOException
Throws:
IOException

EntityContainer

public EntityContainer(Elvin elvin,
                       RoomEntity room,
                       EntityRegistry entities)
                throws IOException
Throws:
IOException
Method Detail

close

public void close()
Synonym for dispose().

Specified by:
close in interface Closeable

dispose

public void dispose()
Description copied from interface: Disposable
Dispose of the object (unregister listeners, close open resources etc). It should be safe to call this method more than once. Note for beans that support client event listeners: if there are listeners registered when this is called, this method should do nothing.

Specified by:
dispose in interface Disposable

isClosed

public boolean isClosed()

mutex

public Object mutex()
The lock that must be held to ensure thread-safe access to entities in this container.

See Also:
Entity.mutex(), EntityRegistry.mutex()

setDefaultUpdaterForThread

public static void setDefaultUpdaterForThread(Executor executor)
Set the default update executor for the current thread, or null to revert to the default.

UI application use note: you can set the default updater for your UI toolkit's thread using code like (for SWT in this case):

   Executor entityUpdateExecutor = new Executor ()
   {
     public void execute (Runnable command)
     {
       display.asyncExec (command);
     }
   };
   
   setDefaultUpdaterForThread (entityUpdateExecutor);
 
If you do this, then all UI elements no longer need to worry about thread sync issues, since all entity containers will update their contents using async runnables executed in the same thread as the UI. This invalidates the need for adaptors like DFC's UIPropertyListener.

See Also:
setUpdateExecutor(Executor)

setUpdateExecutor

public void setUpdateExecutor(Executor newExecutor)
Set the update executor for this container, or null to use the default executor. The update executor is an optional delegate that executes asynchronous updates from other clients on behalf of the container: for example, a custom updater can be plugged in to allow updates to be executed in a different thread.

The default executor for a newly-created container is the thread-local one set by setDefaultUpdaterForThread(Executor).


registerEntityTree

protected void registerEntityTree(Object object)
Register any entities found in a tree of data objects. This allows the same entity instance to be used for the same ID across lifecyles. It also sets the container/mutex fields for all Entity and EntityRegistry instances on the tree.

Parameters:
object - An object being added to the registry (not necessarily a top-level entity).

connectionClosed

public void connectionClosed(CloseEvent e)
Specified by:
connectionClosed in interface CloseListener

notificationReceived

public void notificationReceived(NotificationEvent e)
Specified by:
notificationReceived in interface NotificationListener

handleNotification

protected abstract void handleNotification(NotificationEvent e)

emit

protected void emit(Notification ntfn)
             throws IOException
Shortcut to emit a notification.

Throws:
IOException
See Also:
emitAsync(Notification)

emitAsync

protected void emitAsync(Notification ntfn)
Emit a notification asynchronously using a scheduler task.

See Also:
emit(Notification)

getOrCreateEntity

protected Entity getOrCreateEntity(String id,
                                   String entityType)
Find an existing entity in the registry or create a new one if none exists. Does not set the container attribute or add to the registry, which can be used as a way of knowing whether the entity was created.

Parameters:
id - The entity ID.
entityType - The entity type.

createEntity

protected Entity createEntity(String id,
                              String entityType)
Create a new entity or re-use an existing weakly-cached version previously created in this container.

Parameters:
id - The entity ID.
entityType - The entity type.
Returns:
The entity. This may be a previous instance and therefore contain the previous state as it existed when the entity was deleted.

read

protected void read(Entity entity,
                    Notification ntfn,
                    boolean init)
             throws InvalidFormatException
Read and update state from an incoming info notification. This method is for reading the entity-specific state: the ID and name properties will have already been handled by the system. This method should generate property events (ie use setValue () to update properties).

Parameters:
entity - The entity to read into.
ntfn - The info notification to read from.
init - True if this is an initialisation info i.e. contains the entire entity state rather than just a delta. If this is true any properties in entity that aren't present in ntfn are considered to be defunct and are removed.
Throws:
InvalidFormatException
See Also:
write(Entity, Notification)

write

protected void write(Entity entity,
                     Notification ntfn)
              throws InvalidFormatException
Write the entity's significant state into a notification for publication.

The default implementation writes out all the emittable (see shouldPublish(Entity, Object)) properties of the entity using write(Entity, Notification). Subclasses that don't wish to follow this pattern may override.

Throws:
InvalidFormatException
See Also:
read(Entity, Notification, boolean), write(Notification, PropertyPath, Object)

write

protected void write(Notification ntfn,
                     PropertyPath path,
                     Object value)
              throws InvalidFormatException
Write an abbreviated version of the entity's significant state into a notification, given that a specified property has just changed. Note that this is simply an opportunity for optimization: implementors can simply write their entire state using write(livespace.services.Entity, org.avis.client.Notification) if they wish.

The default implementation simply handballs to write(livespace.services.Entity, org.avis.client.Notification).

Parameters:
ntfn - The notification
path - The path to the property that changed.
Throws:
InvalidFormatException - if an error occurred while writing the data to the notification (eg unserializable object).

splitPropertyPath

protected static String[] splitPropertyPath(String str)
Split a property path of the form "prop1/prop2/prop3" into a string array. Supports escaping of /'s.


createXmlInput

protected XmlInput createXmlInput()

createXmlOutput

protected XmlOutput createXmlOutput()

isInResponseToMe

protected boolean isInResponseToMe(Notification ntfn)
Test if a notification was generated in response to something I sent. Currently only makes sense on client containers which receive responses with "In-Response-To" set, but may be useful in future for servers.


shouldPublish

protected static boolean shouldPublish(Entity entity,
                                       Object property)
Test if a given property should be automatically exported/imported by the read ()/write () functions. The default is to skip properties automatically handled by the system and any transient properties.


setContainerRecursively

protected static void setContainerRecursively(IDataObject object,
                                              EntityContainer container)
Set the container property for a tree of data objects.

Parameters:
object - The root object to set the.
container - The new container reference.

setContainerRecursively

protected static void setContainerRecursively(IDataObject object,
                                              EntityContainer container,
                                              boolean shouldEmitNotification)
Set the container property for a tree of data objects.

Parameters:
object - The root object to set the .
container - The new container reference.
shouldEmitNotification - If true, an event notification will fire if the container property on the entity has changed. If false, no event notification will be fired.


Copyright © 2008 Commonwealth of Australia