SimpleClient implementation testable against uk.ac.vamsas.test.ExampleApplication
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / ClientDocument.java
index bc7a7e9..316e112 100644 (file)
@@ -23,14 +23,16 @@ import uk.ac.vamsas.objects.utils.AppDataReference;
 import uk.ac.vamsas.test.objects.Core;
 
 /**
- * Maintains a collection of vamsas objects, appdatas and states, and provides api for a SimpleClient's client.
+ * Maintains a collection of vamsas objects, appdatas and states, 
+ * and provides api for a SimpleClient's client.
+ * TODO: test and migrate ArchiveClient.getAppData methods to here and retest in ExampleApplication
  * @author jimp 
  */
 public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implements IClientDocument {
   private static Log log = LogFactory.getLog(ClientDocument.class);
   private VamsasDocument doc;
   protected SimpleClient sclient;
-  protected VamsasArchive archive = null;
+  protected VamsasArchive iohandler = null;
   /**
    * indicate if new data has been incorporated
    */
@@ -42,10 +44,9 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
   public boolean isModified() {
     return isModified;
   }
-  private Vector updatedObjects=null;
   /**
    *
-   *  prepare Application-side dataset from the vamsas Document archive
+   *  prepare Application-side dataset from the vamsas Document iohandler
    * @param doc - the dataset
    * @param docHandler - the sessionFile IO handler
    * @param Factory - the source of current and new vorbaIds
@@ -56,12 +57,12 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     
     
     /**
-     * prepare Application-side dataset from the vamsas Document archive
+     * prepare Application-side dataset from the vamsas Document iohandler
      */
     this.sclient = sclient;
-    archive = docHandler;
+    iohandler = docHandler;
     this.doc = doc;
-    updatedObjects=null;  /// TODO: correct this line
+    _VamsasRoots=doc.getVAMSAS();
   }
   
   /*
@@ -102,7 +103,20 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
    * internal reference to single copy of Document Roots array
    */
   private VAMSAS[] _VamsasRoots=null;
-  /*
+
+  protected void updateDocumentRoots() {
+    if (doc==null) {
+      log.error("updateDocumentRoots called on null document. Probably an implementation error.");
+      return;
+    }
+    if (isModified) {
+      if (_VamsasRoots!=null) {
+        doc.setVAMSAS(_VamsasRoots);
+        _VamsasRoots=null;
+      }
+    }
+  }
+/*
    * (non-Javadoc)
    * LATER: currently there is only one Vector of roots ever passed to client - decide if this is correct (means this is not thread safe and may behave unexpectedly)
    * @see uk.ac.vamsas.client.IClientDocument#getVamsasRoots()
@@ -112,7 +126,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
       log.debug("Null document for getVamsasRoots(), returning null");
       return null;
     }
-    if (archive==null) {
+    if (iohandler==null) {
       // LATER: decide on read-only status of ClientDocument object
       log.warn("getVamsasRoots() called on possibly read-only document.");
     }
@@ -122,6 +136,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     if (roots == null) {
       // Make a new one to return to client to get filled. 
       _VamsasRoots = new VAMSAS[] { new VAMSAS() };
+      registerObject(_VamsasRoots[0]);
       // Do provenance now. just in case.
       doc.getProvenance().addEntry(sclient.getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
       doc.addVAMSAS(_VamsasRoots[0]);
@@ -138,9 +153,9 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
       return -1;
     if (docRoots==null || docRoots.length==0)
       return -1;
-    String r_id = root.getId();
+    VorbaId d_id=null,r_id = root.getVorbaId();
     for (int i=0,j=docRoots.length; i<j; i++)
-      if (docRoots[i]==root || (docRoots[i]!=null && docRoots[i].getId().equals(r_id)))
+      if (docRoots[i]==root || (docRoots[i]!=null && (d_id=docRoots[i].getVorbaId())!=null) && d_id.equals(r_id))
         return i;
     return -1;
   }
@@ -155,7 +170,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     if (oldVersion==newVersion) {
       // may be a virgin root element.
       if (!newVersion.isRegistered())
-        _registerObject(newVersion);
+        _registerObject(newVersion); // TODO: check - this call hasn't been tested.
       // Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
       // just do internal validation for moment.
       if (newVersion.isValid())
@@ -170,7 +185,8 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     }
     return false;
     /**
-     * LATER isValidUpdate : Ideally. we efficiently walk down, comparing hashes, to deal with merging and verifying provenance for objects
+     * LATER: MUCH LATER! - not needed for simple case and this routine shouldn't live in this class anymore 
+     * isValidUpdate : Ideally. we efficiently walk down, comparing hashes, to deal with merging and verifying provenance for objects
     
     // extract root objects
     if (newroots != null) {
@@ -300,7 +316,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
       log.debug("addVamsasRoots called on null document.");
       return;
     }
-    VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
+    VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, getVamsasRoots(), this);
     _VamsasRoots = newroots;  
   }
   
@@ -344,6 +360,11 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
       log.warn("registerObjects called for null vamsasObjects hasharray.");
       return null;
     }
+    if (iohandler==null)  {
+      log.warn("registerObjects called for read only document.");
+      return null;
+    }
+      
     if (unregistered!=null) {
       VorbaId id = _registerObject(unregistered);
       log.debug("Registered object - total of "+vamsasObjects.size()+" ids.");
@@ -360,6 +381,8 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
    * @see uk.ac.vamsas.client.IClientDocument#getClientAppdata()
    */
   public IClientAppdata getClientAppdata() {
+    // TODO: getClientAppdata not tested in ArchiveClient mockup
+    log.error("TODO: TEST Client Appdata access methods");
     if (doc==null) {
       log.warn("getClientAppdata called on null document.");
       return null;
@@ -390,8 +413,13 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
    * @return
    */
   protected VamsasArchiveReader getVamsasArchiveReader() {
+    if (iohandler==null) {
+      log.error("Near fatal. Null VamsasArchive iohandler so can't get VamsasArchiveReader");
+      return null;
+    }
     try {
-      return archive.getOriginalArchiveReader();
+      log.info("TODO: test getVamsasArchiveReader");
+      return iohandler.getOriginalArchiveReader();
     } catch (Exception e) {
       log.warn("Unable to create OriginalArchiveReader!", e);
     }
@@ -403,8 +431,8 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
       log.warn("updateSessionDocument called on null document.");
       throw new java.io.IOException("Document is closed.");
     }
-    if (archive==null) {
-      log.warn("updateSessionDocument called document archive handler.");
+    if (iohandler==null) {
+      log.warn("updateSessionDocument called document iohandler handler.");
       throw new java.io.IOException("Document is closed.");
     }
     
@@ -417,7 +445,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     // update the VamsasDocument structure with any new appData's.
     // try to update the sessionFile
     log.debug("Attempting to update session "+sclient.session.getSessionUrn());
-    if (scappd.isModified()) {
+    if (scappd!=null && scappd.isModified()) {
       ClientHandle client = sclient.client;
       UserHandle user = sclient.user;
       scappd.closeForWriting();      
@@ -441,7 +469,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
           scappd.appsGlobal.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn()));
         }
         // LATER: use a switch to decide if the data should be written as a reference or as an embedded data chunk
-        scappd.updateAnAppdataEntry(archive, scappd.appsGlobal, scappd.newAppData);
+        scappd.updateAnAppdataEntry(iohandler, scappd.appsGlobal, scappd.newAppData);
         log.debug("...Successfully updated Global Appdata Entry.");
       }
       if (scappd.newUserData!=null && scappd.newUserData.sessionFile.exists()) {
@@ -464,25 +492,31 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
           }
           appd.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn()+safe_username));
         }
-        scappd.updateAnAppdataEntry(archive, scappd.usersData, scappd.newUserData);
+        scappd.updateAnAppdataEntry(iohandler, scappd.usersData, scappd.newUserData);
         log.debug("...Successfully updated user AppData entry.");
       }
     }
+    try {
+      if (iohandler.transferRemainingAppDatas())
+        log.debug("Remaining appdatas were transferred.");
+      else
+        log.debug("No remaining appdatas were transferred. (Correct?)");
+    } catch (Exception e) {
+      log.error("While transferring remaining AppDatas", e);
+    }
     log.debug("Updating Document...");
-    // now update the document.
+    // now update the document. - this was basically the doUpdate method in test.ArchiveClient
+    updateDocumentRoots();
     try {
-      archive.putVamsasDocument(doc);
+      iohandler.putVamsasDocument(doc);
       log.debug("Successfully written document entry.");
     }
     catch (Exception e) {
       log.error("Marshalling error for vamsas document.",e);
       docupdate = false; // pass on the (probable) object validation error 
     }
-    if (archive.transferRemainingAppDatas())
-      log.debug("Remaining appdatas were transferred.");
-    else
-      log.debug("No remaining appdatas were transferred. (Correct?)");
-    archive.closeArchive();
+    iohandler.closeArchive();
+    iohandler=null; // so this method cannot be called again for this instance
     log.debug("...successully finished and closed.");
     return docupdate; // no errors ?
   }
@@ -506,6 +540,7 @@ public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implement
     super.finalize();
   }
   public Vector getUpdatedObjects() {
-    return updatedObjects;
+    // TODO: WALK through the document objects calling the update mechanism for each one, or just pass this vector back to client ?return updatedObjects;
+    return null;
   }
 }