Replicating an object


In order for CORK to be able to replicate instances of a class the class must meet three requirements:
  1. The class must implement java.io.Serializable so that it can be passed over the network. Note that generally implementing this interface does not require adding methods to the class.(If no custom serialization method is defined, Java will use a default mechanism. This is sufficient for most purposes.)
  2. The class must support some sort of event mechanism by which other objects can be notified of changes to the state of one of the class's instances.
  3. The class must include a method for each such type of notification that allows the state of another instance of the class to be updated to reflect the change.
Given a class that meets these requirements, two types of helper classes are needed to support replication:
  1. One or more serializable classes that implement the edu.vt.cs.collab.cork.Change interface and encapsulate the logic for reproducing each replicable state change.
  2. One or more listener classes that can be attached to the object to generate Change objects when state changes occur.
Here is a simple example of a replicable object (TestBean.java):
     1  import java.beans.*;
     2  import java.io.Serializable;
     3
     4  /**
     5   * Simple replicatable object example. This is a JavaBean with a single
     6   * (String) property, "value".
     7   */
     8  public class TestBean implements Serializable {
     9      /**
    10       * Our value
    11       */
    12      private String value = null;
    13
    14      /**
    15       * Registered property change listeners. (This is a standard
    16       * utility class in java.beans)
    17       */
    18      private PropertyChangeSupport listeners = null;
    19
    20      public TestBean() {
    21          listeners = new PropertyChangeSupport(this);
    22      }
    23
    24      public void setValue(String value) {
    25          Object old = this.value;
    26          this.value = value;
    27          listeners.firePropertyChange("value", old, value);
    28      }
    29
    30      public String getValue() {
    31          return value;
    32      }
    33
    34      public void addPropertyChangeListener(PropertyChangeListener l) {
    35          listeners.addPropertyChangeListener(l);
    36      }
    37      public void removePropertyChangeListener(PropertyChangeListener l) {
    38          listeners.removePropertyChangeListener(l);
    39      }
    40  }
    41

Note that this class meets the three requirements. It implements Serializable, so it can be passed over the net. It provides a mechanism for notifying external objects of state changes. When the state is changed (with a setValue call), any listeners that have registered themselves (using addPropertyChangeListener(...)) will be notified. Finally, the setValue method provides a means for an external object to update the state.
A example of a Change object for reproducing a change to a TestBean's value property is shown below (TestBeanChange.java):
     1  import edu.vt.cs.collab.cork.Change;
     2
     3  /**
     4   * Change class for updating the "value" property of a TestBean.
     5   */
     6  public class TestBeanChange implements Change, java.io.Serializable {
     7      /**
     8       * The new value of the "value" property
     9       */
    10      private String newValue = null;
    11
    12      public TestBeanChange(String newValue) {
    13          this.newValue = newValue;
    14      }
    15
    16      public void applyChange(Object target) {
    17          ((TestBean)target).setValue(newValue);
    18      }
    19  }
    20
In order to replicate modifications to the state of a TestBean, an instance of TestBeanChange needs to be created and passed to CORK any time a change to the TestBean's state is detected. A listener class that does this (TestBeanListener.java) is shown below:
     1  import java.beans.*;
     2  import edu.vt.cs.collab.cork.ReplicatedObjectClient;
     3  import edu.vt.cs.collab.cork.ObjectID;
     4
     5  /**
     6   * Listener class for a TestBean. When a property change is detected,
     7   * a TestBeanChange object is created and passed to a CORK
     8   * ReplicatedObjectClient.
     9   */
    10  public class TestBeanListener implements PropertyChangeListener {
    11      /**
    12       * The ReplicatedObjectClient that we're using to communicate
    13       * with CORK.
    14       */
    15      private ReplicatedObjectClient client = null;
    16
    17      public TestBeanListener(ReplicatedObjectClient client) {
    18          this.client = client;
    19      }
    20
    21      public void propertyChange(PropertyChangeEvent pce) {
    22          String prop = pce.getPropertyName();
    23          if (prop.equals("value")) {
    24              TestBean src = (TestBean) pce.getSource();
    25
    26              // Find our TestBean's object identifier
    27              ObjectID id = client.getObjectID(src);
    28              if (id != null) {
    29                  // Construct a Change object that knows how to set
    30                  // the "value" property to the new value.
    31                  TestBeanChange ch =
    32                      new TestBeanChange((String)pce.getNewValue());
    33
    34                  // Broadcast the change to the server and to any other
    35                  // active replicas of this object
    36                  client.broadcastChange(ch, id);
    37              }
    38              else {
    39                  // If we didn't have an ObjectID, then CORK doesn't
    40                  // know about the TestBean that we're attached to
    41                  System.err.println("WARNING: TestBean not replicated");
    42              }
    43          }
    44      }
    45  }

An example of attaching the listener to a replicated TestBean is shown in the next section.

Note that in practice, listener and Change classes tend to be very general and re-usable. For example, utility class edu.vt.cs.collab.util.PropertySupport implements support for a generic JavaBean property replicator. For classes like TestBean one would typically not write custom, class-specific listener and Change implementations like those shown above.


/public/chci/howto/cork/replicating.html Login | Web Editor | Full Editor
Last modified 5/22/03 3:26 PM by isenhour (history)
Site contents