quick commit before refactoring
[vamsas.git] / src / org / vamsas / client / Vobject.java
index 589b7ff..d7bd6eb 100644 (file)
@@ -30,15 +30,19 @@ public abstract class Vobject {
    */
   protected boolean __stored_in_document = false;
   /**
+   * true if Vobject was updated since the vamsas library last read a Vobj with the same VorbaId from a document.
+   */
+  protected boolean __updated_since_last_read = false;
+  /**
    * memory of the last doHash() value computed for the Vobject 
    * @see doHash()
    */
-  protected long __last_hash = 0; 
+  protected int __last_hash = 0; 
   /**
    * set by testInstanceForIdField() if Vobject should have a VorbaId
    */
   protected boolean registerable = false; 
-
+  protected boolean __visited = false;
   /**
    * reference to containing object for this Vobject.
    */
@@ -185,13 +189,24 @@ public abstract class Vobject {
     VorbaId thisid = vorbaId;
     IVorbaIdFactory factory = __vorba;
     boolean stored = __stored_in_document;
+    boolean updated = __updated_since_last_read;
+    boolean visited = __visited;
+    java.lang.reflect.Field idfield = ___id_field;
+    ___id_field=null;
+    __updated_since_last_read=false;
     vorbaId = null;
     __vorba = null;
+    __visited=false;
+    // compute hash
     __last_hash = this.hashCode();
+    // reset houseskeeping variables
+    ___id_field=idfield;
     vorbaId = thisid;
     __vorba = factory;
     __stored_in_document = stored;
+    __updated_since_last_read=updated;
     V_parent=_V_parent;
+    __visited=visited;
     return (__old_hash==0) || (__old_hash == __last_hash);
   }
 
@@ -257,6 +272,21 @@ public abstract class Vobject {
   }
 
   /**
+   * @return true if this object has been updated in the currently stored document since the last time a Vobject with the same ID was read from a Vamsas Document
+   */
+  public boolean is__updated_since_last_read() {
+    return __updated_since_last_read;
+  }
+
+  /**
+   * Set internal flag to indicate this object was updated since the last document read
+   * @param __updated_since_last_read the __updated_since_last_read to set
+   */
+  protected void set__updated_since_last_read(boolean __updated_since_last_read) {
+    this.__updated_since_last_read = __updated_since_last_read;
+  }
+
+  /**
    * for use by Vorba agent to reflect state of vamsas Vobject to client
    * application.
    * Setting stored_in_document on a registerable Vobject without a 
@@ -275,7 +305,7 @@ public abstract class Vobject {
    * 
    * @return Returns the __last_hash.
    */
-  public long get__last_hash() {
+  public int get__last_hash() {
     return __last_hash;
   }
 
@@ -302,18 +332,26 @@ public abstract class Vobject {
    * TODO: FIX CYCLIC __ensure+instance_ids
    * Implementation note for the todo:
    * this works like a depth-first search over all vamsas objects in an vamsasDocument. 
-   * The doHash() function is used as the 'visited' flag - 
+   * __visited is the visited flag, any Vobj who's flag is of a different parity 
+   * to the visited argument will be recursed on. 
+   * note - the doHash() function used to be used as the 'visited' flag - 
    * this *is not* a valid heuristic, although it will work "most of the time".
    * TODO: LATER? Add another method for setDefaultProvenanceField (in the spirit of setInstanceIdField) using the info from the __vorba.getClient/User/Session methods 
    */
   protected void __ensure_instance_ids() {
+    __ensure_instance_ids(!__visited);
+  }
+  protected void __ensure_instance_ids(boolean visited) {
     if (__vorba==null)
       throw new Error("Improperly intialised org.vamsas.client.Vobject - no VorbaFactory given.");
     log.debug("doing "+this.getClass()+".__ensure_instance_ids()");
     if (!__stored_in_document && registerable)
       setInstanceIdField();
-    if (!doHash())
-      return; // nothing has changed in this Vobject - probably visited it before.
+    if (__visited==visited)
+      return;
+    __visited=visited;
+    __vorba.updateHashValue(this);
+    
     Class descriptor = null;
     XMLClassDescriptorImpl descimpl = null;
     try {
@@ -340,7 +378,7 @@ public abstract class Vobject {
                   vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
                 if (vals[k].V_parent==null)
                   vals[k].V_parent=this; // propagate parent reference to this element.
-                vals[k].__ensure_instance_ids();
+                vals[k].__ensure_instance_ids(visited);
               }
             }
           }
@@ -365,7 +403,7 @@ public abstract class Vobject {
                           vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
                         if (vals[k].V_parent==null)
                           vals[k].V_parent=this; // propagate parent reference to this field object
-                        vals[k].__ensure_instance_ids();
+                        vals[k].__ensure_instance_ids(visited);
                       }
                     }
                     catch (Exception e) {
@@ -399,7 +437,7 @@ public abstract class Vobject {
                 rf.__vorba = __vorba; // propagate IVorbaIdFactory
               if (rf.V_parent==null)
                 rf.V_parent=this; // propagate parent reference
-             rf.__ensure_instance_ids();
+             rf.__ensure_instance_ids(visited);
             }
           }
           catch (Exception e) {