introducing Lock File based locking (for portability) - part implemented.
[vamsas.git] / src / org / vamsas / client / simpleclient / SimpleClient.java
index 2f8103b..e21c359 100644 (file)
@@ -13,6 +13,7 @@ import java.beans.PropertyChangeSupport;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.util.Hashtable;
 import java.util.Vector;
 
@@ -22,10 +23,14 @@ import org.vamsas.client.ClientHandle;
 import org.vamsas.client.Events;
 import org.vamsas.client.IClient;
 import org.vamsas.client.IClientDocument;
+import org.vamsas.client.InvalidSessionUrnException;
 import org.vamsas.client.SessionHandle;
 import org.vamsas.client.UserHandle;
+import org.vamsas.objects.core.ApplicationData;
+import org.vamsas.objects.core.Entry;
 import org.vamsas.objects.core.LockFile;
 import org.vamsas.objects.core.VamsasDocument;
+import org.vamsas.objects.utils.AppDataReference;
 import org.vamsas.objects.utils.ProvenanceStuff;
 import org.vamsas.objects.utils.document.VersionEntries;
 
@@ -42,6 +47,7 @@ public class SimpleClient implements IClient {
   protected VamsasSession _session;
   protected ClientHandle client = null;
   protected EventGeneratorThread evgen = null;
+  protected ClientDocument cdocument = null;
   /**
    * construct a transient IdFactory instance - this should last only as long as the 
    * SimpleClient object holds the lock on the vamsas document being created/manipulated.
@@ -58,12 +64,17 @@ public class SimpleClient implements IClient {
    * @param client
    * @param sess
    */
-  protected SimpleClient(UserHandle user, ClientHandle client, VamsasSession sess) {
+  protected SimpleClient(UserHandle user, ClientHandle client, VamsasSession sess) throws InvalidSessionUrnException {
     // TODO: validate user/client/session
     _session = sess;
     this.user = user;
     this.client = client;
-    session = new SessionUrn(_session);
+    try {
+      session = new SessionUrn(_session);
+    } catch (MalformedURLException e) {
+      log.error("Couldn't form a valid SessionUrn object!",e);
+      throw new InvalidSessionUrnException(_session.toString());
+    }
   }
   /**
    * construct new session by importing objects from an existing vamsas document
@@ -89,10 +100,10 @@ public class SimpleClient implements IClient {
       throw new Exception("Failed to import data from "+importingArchive, e);
     }
   }
-
+  
   /*
    * (non-Javadoc)
-   * TODO: LATER: check that build substitution variables are correct
+   * LATER: check that build substitution variables are correct
    * @see org.vamsas.client.IClient#getAbout()
    */
   public String getAbout() {
@@ -136,7 +147,22 @@ public class SimpleClient implements IClient {
   public UserHandle getUserHandle() {
     return user;
   }
-  
+  /**
+   * 
+   * @return user field for a provenance entry
+   */
+  protected String getProvenanceUser() {
+    return new String(user.getFullName());
+  }
+  /**
+   * construct a provenance entry for this client with the specified action string.
+   * @param action
+   * @return properly completed provenance entry
+   */
+  protected Entry getProvenanceEntry(String action) {
+    Entry prov = ProvenanceStuff.newProvenanceEntry(client.getClientUrn(), getProvenanceUser(), action);
+    return prov;
+  }
   private Hashtable handlers = initHandlers();
   
   private Vector listeners = new Vector();
@@ -192,13 +218,17 @@ public class SimpleClient implements IClient {
    * @see org.vamsas.client.IClient#getClientDocument()
    */
   public IClientDocument getClientDocument() throws IOException {
-    
+    if (cdocument!=null) {
+      // cdocument is non-nill if the ClientDocument.finalise() method hasn't been called.
+      return cdocument;
+    }
     VamsasArchive va = null;
     try {
+      // LATER: bail out if it takes too long to get the lock ?
       va = _session.getVamsasDocument();
     }
     catch (IOException e) {
-      throw new IOException("Failed to get kock on session document");
+      throw new IOException("Failed to get lock on session document");
     }
     VamsasDocument doc=null;
     IdFactory vorba = null;
@@ -208,7 +238,7 @@ public class SimpleClient implements IClient {
       // if session currently holds data - read it in - or get a dummy
       _session.slog.debug("Accessing document");
       doc = 
-        va.getVamsasDocument(user.getFullName()+" using "+client.getClientName(),
+        va.getVamsasDocument(getProvenanceUser(),
             "created new session document.", null);
       if (doc!=null)
         _session.slog.debug("Successfully retrieved document.");
@@ -227,18 +257,41 @@ public class SimpleClient implements IClient {
   
   /*
    * (non-Javadoc)
-   * 
+   * @throws Errors for invalid newdoc parameter
    * @see org.vamsas.client.IClient#updateDocument(org.vamsas.client.IClientDocument)
    */
   public void updateDocument(IClientDocument newdoc) {
     if (!(newdoc instanceof ClientDocument)) {
       throw new Error("Invalid IClientDocument instance for SimpleClient.");
     }
-    
-    // try to update the sessionFile
-    
-    // write the appHandle to the lastupdate file.
-    
+    if (cdocument==null)
+      throw new Error("Client Error - updateDocument() called before getClientDocument().");
+    if (newdoc!=cdocument)
+      throw new Error("Client Error - SimpleClient.updateDocument() can only take the IClientDocument instance returned from SimpleClient.getClientDocument()");
+    if (!cdocument.isModified()) {
+      if (log.isDebugEnabled())
+        log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument.");
+    } else {
+      try {
+        if (!cdocument.updateSessionDocument()) {
+          log.warn("Session document did not update properly for session directory "+_session.sessionDir);
+          // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the archive.
+          _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
+        }
+      }
+      catch (IOException e) {
+        log.warn("IO Problems when updating document!",e);
+        _session.slog.error("IO problems when attempting to update document.");
+      }
+    }
+    // garbage collect the ClientDocument instance.
+    try {
+      cdocument.finalize();
+
+    } catch (Throwable e) {
+      log.error("Exception when trying to garbage collect ClientDocument for "+session.getSessionUrn(), e);
+    }
+    cdocument = null; // this is probably done by finalize
   }
   
   /*
@@ -253,9 +306,11 @@ public class SimpleClient implements IClient {
     // Events.DOCUMENT_FINALIZEAPPDATA
     try {
       _session.writeVamsasDocument(location, vamlock);
+      _session.clearUnsavedFlag();
     } catch (Exception e) {
       log.warn("Exception whilst trying to store document in "+location,e);
     }
+    
     vamlock.release();
   }
   
@@ -286,7 +341,7 @@ public class SimpleClient implements IClient {
     }
     
     if (!evgen.isAlive()) {
-      log.warn("pollUpdate called before joinSession()");
+      log.warn("pollUpdate called before joinSession() - trying to do this.");
       try {
         joinSession();
       } catch (Exception e) {
@@ -318,7 +373,10 @@ public class SimpleClient implements IClient {
       log.warn("Failed to start EventGenerator thread.");
       throw new Exception("Failed to start event generator thread - client cannot be instantiated.");
     }
-    
+    if (evgen.countHandlersFor(Events.DOCUMENT_CREATE)>0) {
+      //TODO: is this application connecting to a newly created session document ?
+      //evgen.raise(Events.DOCUMENT_CREATE);
+    }
   }
   
   
@@ -328,6 +386,6 @@ public class SimpleClient implements IClient {
    */
   public void importDocument(File location) {
     // TODO LATER: implement SimpleClient.importDocument()
-    log.error("importDocument is not implemented for a SimpleClient Session.");
+    log.error("importDocument is not yet implemented for a SimpleClient Session.");
   }
 }