refactored to propery separate addToDocument,addFromDocument, updateToDocument, updat...
[jalview.git] / src / jalview / io / vamsas / DatastoreItem.java
index 42e494f..ce5acd3 100644 (file)
@@ -19,6 +19,7 @@
 package jalview.io.vamsas;
 
 import jalview.bin.Cache;
+import jalview.datamodel.DBRefEntry;
 import jalview.gui.TreePanel;
 import jalview.io.VamsasAppDatastore;
 
@@ -27,9 +28,12 @@ import java.util.Hashtable;
 import java.util.IdentityHashMap;
 import java.util.Vector;
 
+import org.apache.commons.logging.Log;
+
 import uk.ac.vamsas.client.IClientDocument;
 import uk.ac.vamsas.client.Vobject;
 import uk.ac.vamsas.client.VorbaId;
+import uk.ac.vamsas.objects.core.DbRef;
 import uk.ac.vamsas.objects.core.Entry;
 import uk.ac.vamsas.objects.core.Provenance;
 import uk.ac.vamsas.objects.core.Seg;
@@ -40,7 +44,7 @@ import uk.ac.vamsas.objects.core.Seg;
  * @author JimP
  * 
  */
-public class DatastoreItem
+public abstract class DatastoreItem
 {
   /**
    * 
@@ -52,8 +56,14 @@ public class DatastoreItem
   Hashtable vobj2jv;
 
   IdentityHashMap jv2vobj;
-
+  
+  boolean tojalview=false;
+  /**
+   * shared log instance
+   */
+  protected static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(DatastoreItem.class);
   /**
+   * note: this is taken verbatim from jalview.io.VamsasAppDatastore
    * @return the Vobject bound to Jalview datamodel object
    */
   protected Vobject getjv2vObj(Object jvobj)
@@ -94,6 +104,12 @@ public class DatastoreItem
     return null;
   }
 
+  /**
+   * note: this is taken verbatim from jalview.io.VamsasAppDatastore
+
+   * @param jvobj
+   * @param vobj
+   */
   protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
   {
     VorbaId id = vobj.getVorbaId();
@@ -137,6 +153,29 @@ public class DatastoreItem
     // JBPNote - better implementing a hybrid invertible hash.
     jv2vobj.put(jvobj, vobj.getVorbaId());
   }
+  /**
+   * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
+   * binding tables
+   * note: this is taken verbatim from jalview.io.VamsasAppDatastore
+   * @param oldjvobject
+   * @param newjvobject (may be null to forget the oldjvobject's document mapping)
+   * 
+   */
+  protected void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
+  {
+    Object vobject = jv2vobj.remove(oldjvobject);
+    if (vobject == null)
+    {
+      throw new Error(
+              "IMPLEMENTATION ERROR: old jalview object is not bound ! ("
+                      + oldjvobject + ")");
+    }
+    if (newjvobject!=null)
+    {
+      jv2vobj.put(newjvobject, vobject);
+      vobj2jv.put(vobject, newjvobject);
+    }
+  }
 
   public DatastoreItem()
   {
@@ -149,8 +188,137 @@ public class DatastoreItem
     initDatastoreItem(datastore);
     // TODO Auto-generated constructor stub
   }
+  /**
+   * construct and initialise datastore object and retrieve object bound to vobj2 and validate it against boundType
+   * @param datastore2
+   * @param vobj2
+   * @param boundType
+   */
+  public DatastoreItem(VamsasAppDatastore datastore2, Vobject vobj2, Class boundType)
+  {
+    this(datastore2);
+    vobj = vobj2;
+    jvobj = getvObj2jv(vobj2);
+    tojalview=true;
+    if (jvobj!=null && !(boundType.isAssignableFrom(jvobj.getClass())))
+    {
+      throw new Error("Implementation Error: Vamsas Document Class "+vobj.getClass()+" should bind to a "+boundType+" (found a "+jvobj.getClass()+")");
+    }
+  }
+  /**
+   * construct and initialise datastore object and retrieve document object bound to Jalview object jvobj2 and validate it against boundType
+   * @param datastore2 the datastore
+   * @param jvobj2 the jalview object
+   * @param boundToType - the document object class that the bound object should be assignable from
+   */
+  public DatastoreItem(VamsasAppDatastore datastore2, Object jvobj2, Class boundToType)
+  {
+    this(datastore2);
+    jvobj = jvobj2;
+    tojalview=false;
+    vobj = getjv2vObj(jvobj);
+    if (vobj!=null && !(boundToType.isAssignableFrom(vobj.getClass())))
+    {
+      throw new Error("Implementation Error: Jalview Class "+jvobj2.getClass()+" should bind to a "+boundToType+" (found a "+vobj.getClass()+")");
+    }
+  }
+  /**
+   * create a new vobj to be added to the document 
+   * for the jalview object jvobj
+   * (jvobj!=null, vobj==null)
+   */
+  public abstract void addToDocument();
+  /**
+   * handle a conflict where both an existing vobj has been updated
+   *  and a local jalview object has been updated. This method
+   *  is only called from doSync, when an incoming update from the vamsas
+   *  session conflicts with local modifications made by the Jalview user. 
+   *  (jvobj!=null, vobj!=null)
+   */
+  public abstract void conflict();
+  /**
+   * update an existing vobj in the document with the data and settings from jvobj
+   * (jvobj!=null, vobj!=null) 
+   */
+  public abstract void updateToDoc();
+  /**
+   * update the local jalview object with the data from an existing vobj in the document 
+   * (jvobj!=null, vobj!=null) 
+   */
+  public abstract void updateFromDoc();
+  /**
+   * create a new local jvobj bound to the vobj in the document.
+   * (jvobj==null, vobj!=null)
+   */
+  public abstract void addFromDocument();
+  boolean addtodoc=false, conflicted=false,updated=false,addfromdoc=false,success=false;
+
+  private boolean updatedtodoc;
+
+  private boolean updatedfromdoc;
+  /**
+   * Sync jalview to document. Enact addToDocument, conflict or update dependent on
+   * existence of a vobj bound to the local jvobj. 
+   */
+  protected void doSync()
+  {
+    
+    if (vobj == null)
+    {
+      log.debug("adding new vobject to document.");
+      addtodoc=true;
+      addToDocument();
+    }
+    else
+    {
+      if (vobj.isUpdated())
+      {
+        log.debug("Handling update conflict for existing bound vobject.");
+        conflicted=true;
+        conflict();
+      }
+      else
+      {
+        log.debug("updating existing vobject in document.");
+        updatedtodoc=true;
+        updateToDoc();
+      }
+    }
+    // no exceptions were encountered...
+    success=true;
+  }
+  /**
+   * Update jalview from document. enact addFromDocument if no local jvobj exists, or update iff jvobj
+   * exists and the vobj.isUpdated() flag is set. 
+   */
+  protected void doJvUpdate()
+  {
+    if (jvobj == null)
+    {
+      log.debug("adding new vobject to Jalview from Document");
+      addfromdoc=true;
+      addFromDocument();
+    }
+    else
+    {
+      if (vobj.isUpdated())
+      {
+        log.debug("updating Jalview from existing bound vObject");
+        updatedfromdoc=true;
+        updateFromDoc();
+      }
+    }
+  }
 
   VamsasAppDatastore datastore = null;
+  /**
+   * object in vamsas document
+   */
+  protected Vobject vobj = null;
+  /**
+   * local jalview object
+   */
+  protected Object jvobj = null;
 
   public void initDatastoreItem(VamsasAppDatastore ds)
   {
@@ -270,4 +438,77 @@ public class DatastoreItem
   {
     p.addEntry(dummyPEntry(action));
   }
+
+
+  /**
+   * @return true if jalview was being updated from the vamsas document
+   */
+  public boolean isTojalview()
+  {
+    return tojalview;
+  }
+
+  /**
+   * @return true if addToDocument() was called.
+   */
+  public boolean isAddtodoc()
+  {
+    return addtodoc;
+  }
+
+  /**
+   * @return true if conflict() was called
+   */
+  public boolean isConflicted()
+  {
+    return conflicted;
+  }
+
+  /**
+   * @return true if updateFromDoc() was called
+   */
+  public boolean isUpdatedFromDoc()
+  {
+    return updatedfromdoc;
+  }
+  /**
+   * @return true if updateToDoc() was called
+   */
+  public boolean isUpdatedToDoc()
+  {
+    return updatedtodoc;
+  }
+
+  /**
+   * @return true if addFromDocument() was called.
+   */
+  public boolean isAddfromdoc()
+  {
+    return addfromdoc;
+  }
+
+  /**
+   * @return true if object sync logic completed normally.
+   */
+  public boolean isSuccess()
+  {
+    return success;
+  }
+
+  /**
+   * @return the vobj
+   */
+  public Vobject getVobj()
+  {
+    return vobj;
+  }
+
+  /**
+   * @return the jvobj
+   */
+  public Object getJvobj()
+  {
+    return jvobj;
+  }
+
 }