introducing Lock File based locking (for portability) - part implemented.
authorjprocter <jprocter@compbio.dundee.ac.uk>
Wed, 24 May 2006 13:32:33 +0000 (13:32 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Wed, 24 May 2006 13:32:33 +0000 (13:32 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@230 be28352e-c001-0410-b1a7-c7978e42abec

13 files changed:
src/org/vamsas/client/simpleclient/ClientDocument.java
src/org/vamsas/client/simpleclient/ClientsFile.java
src/org/vamsas/client/simpleclient/FileLock.java [new file with mode: 0644]
src/org/vamsas/client/simpleclient/FileWatcher.java
src/org/vamsas/client/simpleclient/Lock.java
src/org/vamsas/client/simpleclient/LockFactory.java [new file with mode: 0644]
src/org/vamsas/client/simpleclient/NativeLock.java [new file with mode: 0644]
src/org/vamsas/client/simpleclient/SessionFile.java
src/org/vamsas/client/simpleclient/SimpleClient.java
src/org/vamsas/test/simpleclient/ArchiveClient.java
src/org/vamsas/test/simpleclient/ArchiveWriter.java
src/org/vamsas/test/simpleclient/ClientDoc.java
src/org/vamsas/test/simpleclient/VamsasArchive.java

index d360085..631c068 100644 (file)
@@ -424,7 +424,7 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements
         // first write for this application - add a new section in document
         ApplicationData appd = scappd.appsGlobal = new ApplicationData();
         appd.setName(client.getClientName());
-        appd.setUrn(client.getClientUrn());
+        // appd.setUrn(client.getClientUrn());
         appd.setVersion(client.getVersion());
         doc.addApplicationData(appd);
         // embed or jarEntry ?  - for now only jarEntry's are dealt with.
index d8abd2b..cab03cd 100644 (file)
@@ -179,6 +179,9 @@ public class ClientsFile extends ListFile {
    */
   protected int addClient(ClientHandle me, boolean disambiguate) {
     int newclient = 0;
+    int tries=5;
+    while (tries-->0 && !lockFile())
+      try { Thread.sleep(1); } catch (Exception e){};
     if (lockFile()) {
       ClientHandle[] clients = retrieveClientHandles();
       if (me.getClientUrn()==null) {
diff --git a/src/org/vamsas/client/simpleclient/FileLock.java b/src/org/vamsas/client/simpleclient/FileLock.java
new file mode 100644 (file)
index 0000000..8cb6808
--- /dev/null
@@ -0,0 +1,130 @@
+package org.vamsas.client.simpleclient;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class FileLock extends Lock {
+  File _lock = null;
+  protected static String _LockSuffix="lck";
+  /**
+   * call to clear up a filelock file after its been made
+   *
+   */
+  private void tidy() {
+    if (_lock!=null) {
+      _lock.delete();
+      _lock=null;
+    }
+  }
+  /**
+   * @param lockfile
+   */
+  public FileLock(File lockfile) {
+    super(lockfile);
+    // try and get a lock.
+    try {
+      _lock = new File(lockfile.getParentFile(), lockfile.getName()+"."+_LockSuffix);
+      if (_lock.exists() || !_lock.createNewFile()) {
+        log.debug("Failed to get lock for "+lockfile+" using lockfile "+_lock);
+        _lock=null;
+        return;
+      }
+      _lock.deleteOnExit(); // safe - all locks should be removed on finalization.
+      // create target file ready to be written to if necessary.
+      if (!lockfile.exists())
+        if (!lockfile.createNewFile()) {
+          log.warn("Failed to create locked file "+lockfile);
+          return;
+        }
+      openRaFile();
+    } catch (FileNotFoundException e) {
+      //
+      log.debug("FileLock failed with target="+lockfile+" and lockfile suffix of "+_LockSuffix);
+      //log.error("Error! Couldn't create a lockfile at "
+      //  + lockfile.getAbsolutePath(), e);
+    } catch (IOException e) {
+      log.error("Error! Problems with IO when creating a lock on "
+          + lockfile.getAbsolutePath(),e);
+    }
+  }
+  
+  private boolean openRaFile() throws IOException {
+    if (target==null)
+      return false;
+    if (_lock==null || !_lock.exists())
+      return false;
+    if (rafile==null)
+      rafile=new RandomAccessFile(target,"rw");
+    return (rafile.getChannel()!=null) && rafile.getChannel().isOpen();
+  }
+  
+  public boolean isLocked() {
+    if (_lock != null) {
+      if (_lock.exists())
+        return true;
+      _lock=null;
+      if (log.isDebugEnabled())
+        log.debug("Lockfile "+_lock+" unexpectedly deleted ?");
+    }
+    return false;
+  }
+  
+  public void release() {
+    release(true);
+  }
+  
+  public void release(boolean closeChannel) {
+    if (_lock==null)
+      return;
+    if (closeChannel) {
+      if (rafile!=null) 
+        try {
+          rafile.close();
+        } catch (Exception e) {
+          log.debug("Unexpected exception whilst closing RandomAccessFile on "+target, e);
+        }
+        rafile=null; 
+    }
+    tidy();
+  }
+  
+  public FileInputStream getFileInputStream(boolean atStart) throws IOException {
+    if (!isLocked())
+      return null;
+    openRaFile();
+    if (atStart)
+      rafile.seek(0);
+    return new FileInputStream(rafile.getFD());
+  }
+  
+  
+  public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
+    if (!isLocked())
+      return null;
+    openRaFile();
+    if (clear)
+      rafile.setLength(0);
+    else
+      rafile.seek(rafile.length());
+    return new LockedFileOutputStream(rafile.getFD());
+  }
+  
+  
+  public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
+    FileOutputStream fos = getFileOutputStream(clear);
+    if (fos!=null)
+      return new BufferedOutputStream(fos);
+    return null;
+  }
+  
+  protected void finalize() throws Throwable {
+    release(true); // we explicitly lose the lock here.
+    super.finalize();
+  }
+  
+}
index 7854b48..29d5979 100644 (file)
@@ -42,7 +42,7 @@ public class FileWatcher {
       if (subjectLock!=null) {
         subjectLock.release();
       }
-      subjectLock = new Lock(subject);
+      subjectLock = LockFactory.getLock(subject);
       if (subjectLock.isLocked()) {
         return false;
       }
index 903214d..9dd472f 100644 (file)
@@ -2,101 +2,57 @@ package org.vamsas.client.simpleclient;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.nio.channels.FileLock;
 
 import org.apache.commons.logging.LogFactory;
 
 /**
  * transient object representing a file lock
  * This lock should hold for all processes interacting in a session.
- * TODO: currently implemented for local filesystem style locking - need a fallback mechanism for systems without file locks.
  * @author jimp
- * 
  */
 
-public class Lock {
-  org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
-  FileLock lock = null;
-  RandomAccessFile rafile=null;
+public abstract class Lock {
+  protected org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
+  File target = null; // The file that is being locked
+  protected RandomAccessFile rafile=null;
+  
   /**
    * creates a valid Lock (test with <method>isLocked</method>)
    * if a lock could be obtained for <param>lockfile</param>
    * @param lockfile
    */
-  public Lock(java.io.File lockfile) {
-    // try and get a lock.
-    lock = null;
-    
-    try {
-      if (!lockfile.exists())
-        if (!lockfile.createNewFile()) {
-          log.warn("Failed to create locked file "+lockfile);
-          return;
-        }
-      
-      lock = (rafile=new RandomAccessFile(lockfile,"rw")).getChannel().tryLock();
-      if (lock==null || !lock.isValid()) {
-        // failed to get lock. Close the file channel
-        log.debug("failed to get lock for "+lockfile);
-        rafile.getChannel().close();
-        lock=null;
-      }
-    } catch (FileNotFoundException e) {
-      //
-      log.debug("Lock failed - normal behaviour for windows locking.");
-      //log.error("Error! Couldn't create a lockfile at "
-      //  + lockfile.getAbsolutePath(), e);
-    } catch (IOException e) {
-      log.error("Error! Problems with IO when creating a lock on "
-          + lockfile.getAbsolutePath(),e);
-    }
-  }
-  
-  boolean isLocked() {
-    if (lock != null && lock.isValid()) {
-      return true;
-    }
-    return false;
+  protected Lock(java.io.File lockfile) {
+    target = lockfile;
   }
-  public void release() {
-    release(true);
-  }
-  public void release(boolean closeChannel) {
-    try {
-      // channel.close should be called before release() for rigourous locking.
-      if (rafile!=null && rafile.getChannel()!=null) {
-        if (rafile.getChannel().isOpen()) {
-          if (closeChannel && rafile.getChannel().isOpen())
-            rafile.getChannel().close();
-          if (lock!=null && lock.isValid())
-            lock.release();
-        }
-      }
-    } catch (IOException e) {
-      log.warn("Whilst releasing lock",e);
-    }
-    lock=null;
-    rafile=null; 
-  }
-  
+  /**
+   * 
+   * @return true if lock is held on the target
+   */
+  public abstract boolean isLocked();
+  /**
+   * release lock and close all managed channels to file
+   *
+   */
+  public abstract void release();
+  /**
+   * optionally close the open random access channel on the file when releasing lock
+   * @param closeChannel
+   */
+  public abstract void release(boolean closeChannel);
+
   /**
    * gets Locked Stream for reading from
    * @param atStart true to start reading at beginning of file.
    * @return null if file not locked
    * @throws IOException
    */
-  public FileInputStream getFileInputStream(boolean atStart) throws IOException {
-    if (!isLocked())
-      return null;
-    if (atStart)
-      rafile.seek(0);
-    return new FileInputStream(rafile.getFD());
-  }
+  public abstract FileInputStream getFileInputStream(boolean atStart) throws IOException;
+
   /**
    * gets Locked stream to write to
    * FileInput always starts at the *end* of the file (after any truncation)
@@ -104,26 +60,17 @@ public class Lock {
    * @return null if file is not locked
    * @throws IOException
    */
-  public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
-    if (!isLocked())
-      return null;
-    if (clear)
-      rafile.setLength(0);
-    rafile.seek(rafile.length());
-    return new LockedFileOutputStream(rafile.getFD());
-  }
+  public abstract FileOutputStream getFileOutputStream(boolean clear) throws IOException;
   /**
    * return buffered output stream to locked file.
    * @param clear - true means file is truncated to 0 length before writing 
    * @return
    */
-  public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
-    FileOutputStream fos = getFileOutputStream(clear);
-    if (fos!=null)
-      return new BufferedOutputStream(fos);
-    return null;
+  public abstract BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException;
+  
+  protected void finalize() throws Throwable {
+    target=null;
   }
-
   /**
    * return buffered input stream for locked file.
    * @param atStart - true means read from begining of file
@@ -135,13 +82,4 @@ public class Lock {
       return new BufferedInputStream(fis);
     return null;
   }
-  /* Explicitly release lock (probably don't need to do this!)
-   * @see java.lang.Object#finalize()
-   */
-  protected void finalize() throws Throwable {
-    release(true); // we explicitly lose the lock here.
-    // log.debug("lock closing through garbage collection ?");
-    super.finalize();
-  }
-  
 }
diff --git a/src/org/vamsas/client/simpleclient/LockFactory.java b/src/org/vamsas/client/simpleclient/LockFactory.java
new file mode 100644 (file)
index 0000000..72cbe66
--- /dev/null
@@ -0,0 +1,34 @@
+package org.vamsas.client.simpleclient;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class LockFactory {
+  protected static Log log = LogFactory.getLog(LockFactory.class);
+  public static int locktype=0; // use file lock by default
+  public static String[] locktypes = {"file","native"};
+  {
+    String lockt = System.getProperty("vamsas.locktype");
+    if (lockt!=null) {
+      int i,j;
+      for (i=0, j=locktypes.length; i<j && locktypes[i].equalsIgnoreCase(lockt); i++)
+        ;
+      if (i>=j) {
+        String lt = "'"+locktypes[0]+"'";
+        for (i=1; i<j; i++)
+          lt += ",'"+locktypes[i]+"'";
+        log.warn("System property vamsas.locktype takes one of "+lt);
+        log.warn("Defaulting to Locktype of "+locktypes[locktype]);
+      }
+    }
+  }
+  
+  public static Lock getLock(java.io.File target) {
+    if (locktype==0)
+      return new FileLock(target);
+    if (locktype==1)
+      return new NativeLock(target);
+    log.fatal("Implementation Error! No valid Locktype value");
+    return null;
+  }
+}
diff --git a/src/org/vamsas/client/simpleclient/NativeLock.java b/src/org/vamsas/client/simpleclient/NativeLock.java
new file mode 100644 (file)
index 0000000..96d9b6b
--- /dev/null
@@ -0,0 +1,129 @@
+package org.vamsas.client.simpleclient;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileLock;
+
+public class NativeLock extends Lock {
+
+  protected FileLock lock = null;
+
+  /**
+   * @param lockfile
+   */
+  public NativeLock(File lockfile) {
+    super(lockfile);
+    // try and get a lock.
+    lock = null;
+    
+    try {
+      if (!lockfile.exists())
+        if (!lockfile.createNewFile()) {
+          log.warn("Failed to create locked file "+lockfile);
+          return;
+        }
+      
+      lock = (rafile=new RandomAccessFile(lockfile,"rw")).getChannel().tryLock();
+      if (lock==null || !lock.isValid()) {
+        // failed to get lock. Close the file channel
+        log.debug("failed to get lock for "+lockfile);
+        rafile.getChannel().close();
+        lock=null;
+      }
+    } catch (FileNotFoundException e) {
+      //
+      log.debug("Lock failed - normal behaviour for windows locking.");
+      //log.error("Error! Couldn't create a lockfile at "
+      //  + lockfile.getAbsolutePath(), e);
+    } catch (IOException e) {
+      log.error("Error! Problems with IO when creating a lock on "
+          + lockfile.getAbsolutePath(),e);
+    }
+  }
+
+  public boolean isLocked() {
+    if (lock != null && lock.isValid()) {
+      return true;
+    }
+    return false;
+  }
+
+  public void release() {
+    release(true);
+  }
+
+  public void release(boolean closeChannel) {
+    try {
+      // channel.close should be called before release() for rigourous locking.
+      if (rafile!=null && rafile.getFD().valid() && rafile.getChannel()!=null && lock.isValid()) {
+        if (closeChannel && rafile.getChannel().isOpen()) {
+            rafile.close();
+            rafile=null; 
+        }
+        if (lock!=null && lock.isValid())
+          lock.release();
+        
+      }
+    } catch (IOException e) {
+      log.warn("Whilst releasing lock",e);
+    }
+    lock=null;
+  }
+
+  /**
+   * gets Locked Stream for reading from
+   * @param atStart true to start reading at beginning of file.
+   * @return null if file not locked
+   * @throws IOException
+   */
+  public FileInputStream getFileInputStream(boolean atStart) throws IOException {
+    if (!isLocked())
+      return null;
+    if (atStart)
+      rafile.seek(0);
+    return new FileInputStream(rafile.getFD());
+  }
+
+  /**
+   * gets Locked stream to write to
+   * FileInput always starts at the *end* of the file (after any truncation)
+   * @param clear true means file will be cleared to zero length
+   * @return null if file is not locked
+   * @throws IOException
+   */
+  public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
+    if (!isLocked())
+      return null;
+    if (clear)
+      rafile.setLength(0);
+    rafile.seek(rafile.length());
+    return new LockedFileOutputStream(rafile.getFD());
+  }
+
+  /**
+   * return buffered output stream to locked file.
+   * @param clear - true means file is truncated to 0 length before writing 
+   * @return
+   */
+  public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
+    FileOutputStream fos = getFileOutputStream(clear);
+    if (fos!=null)
+      return new BufferedOutputStream(fos);
+    return null;
+  }
+  /**
+   * @see org.vamsas.client.simpleclient.Lock#finalize()
+   */
+  protected void finalize() throws Throwable {
+    release(true); // we explicitly lose the lock here.
+    // log.debug("lock closing through garbage collection ?");
+    super.finalize();
+  }
+
+}
index 9da73c0..bd2dc44 100644 (file)
@@ -33,7 +33,7 @@ public class SessionFile {
       fileLock=null;
     }
     if (extantlock!=null)
-      fileLock=extantlock;
+      fileLock=extantlock; // THIS IS BROKEN - lockFile then nulls the lock.
     return lockFile();
   }
 
@@ -49,7 +49,6 @@ public class SessionFile {
       else 
         // lock failed for some reason.
         fileLock.release();
-    fileLock = null;
     if (sessionFile != null) {
       if (!sessionFile.exists()) {
         // create new file
@@ -68,9 +67,11 @@ public class SessionFile {
       long tries=500;
       do {
         tries--;
-        if (fileLock!=null && !fileLock.isLocked())
+        if (fileLock!=null && !fileLock.isLocked()) {
           fileLock.release();
-          fileLock = new Lock(sessionFile); // TODO: wait around if we can't get the lock.
+          try { Thread.sleep(5); } catch (Exception e) {};
+        }
+        fileLock = LockFactory.getLock(sessionFile); // TODO: wait around if we can't get the lock.
       } while (tries>0 && !fileLock.isLocked());
       if (!fileLock.isLocked())
         log.error("Failed to get lock for "+sessionFile);
@@ -134,8 +135,10 @@ public class SessionFile {
     if (newData.sessionFile==null)
       throw new IOException("Null SessionFile in newData.");
       
-    lockFile(extantLock);  
-    newData.lockFile();
+    if (!lockFile(extantLock))
+      log.error("Failed to get write lock for "+sessionFile);
+    if (!newData.lockFile())
+      log.warn("Failed to get lock for updateFrom "+newData.sessionFile);
     fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0, 
         newData.fileLock.rafile.length());
   }
index e824549..e21c359 100644 (file)
@@ -152,7 +152,7 @@ public class SimpleClient implements IClient {
    * @return user field for a provenance entry
    */
   protected String getProvenanceUser() {
-    return new String(user.getFullName()+" ["+client.getClientUrn()+"]");
+    return new String(user.getFullName());
   }
   /**
    * construct a provenance entry for this client with the specified action string.
@@ -160,8 +160,7 @@ public class SimpleClient implements IClient {
    * @return properly completed provenance entry
    */
   protected Entry getProvenanceEntry(String action) {
-    // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
-    Entry prov = ProvenanceStuff.newProvenanceEntry(getProvenanceUser(), action);
+    Entry prov = ProvenanceStuff.newProvenanceEntry(client.getClientUrn(), getProvenanceUser(), action);
     return prov;
   }
   private Hashtable handlers = initHandlers();
index 0ba0a93..d72b43e 100644 (file)
@@ -153,7 +153,7 @@ public class ArchiveClient extends IdFactory {
       d = docb.getVamsasDocument(vreader);
       
       if (d!=null) {
-        ClientDoc creader = new ClientDoc(d, null, vreader, getProvenanceUser(), getVorbaIdHash());
+        ClientDoc creader = new ClientDoc(d, null, vreader, getClientHandle().getClientUrn(), getProvenanceUser(), getVorbaIdHash());
         return creader;
       }
     }
@@ -180,7 +180,7 @@ public class ArchiveClient extends IdFactory {
         varc.cancelArchive();
         return null;
       }      
-      ClientDoc cdoc = new ClientDoc(d, varc, varc.getOriginalArchiveReader(), getProvenanceUser(), getVorbaIdHash());
+      ClientDoc cdoc = new ClientDoc(d, varc, varc.getOriginalArchiveReader(), getClientHandle().getClientUrn(), getProvenanceUser(), getVorbaIdHash());
       return cdoc;
       // do appHandle?
     } catch (Exception e) {
index 1a9bae9..d6f8ee9 100644 (file)
@@ -13,8 +13,10 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.vamsas.client.simpleclient.VamsasArchive;
 import org.vamsas.client.simpleclient.VamsasArchiveReader;
+import org.vamsas.objects.core.Alignment;
 import org.vamsas.objects.core.ApplicationData;
 import org.vamsas.objects.core.Entry;
+import org.vamsas.objects.core.Instance;
 import org.vamsas.objects.core.Provenance;
 import org.vamsas.objects.core.VAMSAS;
 import org.vamsas.objects.core.VamsasDocument;
@@ -38,8 +40,9 @@ public class ArchiveWriter {
   }
   // Merge appDataReferences require transfer of jar entries, perhaps with a renaming of the entry.
   // Merge appDatas require eventually unique URNS
+  // TODO: merging global appdata from different documents where same app has written them causes conflict
   
-  public static Hashtable hashOfAppDatas(Hashtable ht, ApplicationData[] appdatas) {
+  public static Hashtable hashOfAppDatas(Hashtable ht, Instance[] appdatas) {
     if (ht==null)
       ht = new Hashtable();
     for (int i=0, j=appdatas.length; i<j; i++) {
@@ -64,8 +67,8 @@ public class ArchiveWriter {
    * @param entry application data to be copied from source archive
    */
   public static void addAppDataEntry(VamsasArchive darc, VamsasDocument dest,  VamsasArchiveReader sarc, ApplicationData entry) {
-    
-    // check uniqueness of entry.urn amongst dest.ApplicationData[].urn
+    // TODO: fix instances
+    // check uniqueness of instance's[] entry.urn amongst dest.ApplicationData[].getInstances[].urn 
     //  check uniqueness of entry.user[].urn amongst dest.ApplicationData[].user[].urn
     // check uniqueness of entry.user
     // entry.getAppDataChoice().getData() or getDataReference is unique
@@ -73,11 +76,11 @@ public class ArchiveWriter {
     for (int i=0, j=dest.getApplicationDataCount(); i<j; i++) {
       ApplicationData o = dest.getApplicationData()[i];
       // ensure new urn is really unique
-      String urn = entry.getUrn();
+      //String urn = entry.getUrn();
       int v = 1;
-      while (o.getUrn().equals(urn)) {
-        urn = entry.getUrn()+v++;      
-      }
+      //while (o.getUrn().equals(urn)) {
+      //  urn = entry.getUrn()+v++;      
+     // }
       // uniqueness of urn
       // check each user ApplicationData
       // uniqueness (again)
@@ -142,7 +145,7 @@ public class ArchiveWriter {
       VamsasArchive varc = new VamsasArchive(newarch, true);
       VamsasDocument docroot;
       docroot = new VamsasDocument();
-      docroot.setProvenance(ProvenanceStuff.newProvenance("ArchiveWriter", "Created new Vamsas Document"));
+      docroot.setProvenance(ProvenanceStuff.newProvenance("ArchiveWriter", "user", "Created new Vamsas Document"));
       while (++argpos<argv.length) {
         File archive = new File(argv[argpos]);
         InputStream istream;
@@ -161,7 +164,7 @@ public class ArchiveWriter {
               if ((istream = vdoc.getVamsasXmlStream())!=null) {
                 // make a new vamsas document from the vamsas.xml entry
                 VAMSAS root = VAMSAS.unmarshal(new InputStreamReader(istream)); // TODO: verify only one VAMSAS element per vamsas.xml entry.
-                docroot.getProvenance().addEntry(ProvenanceStuff.newProvenanceEntry("user", "added vamsas.xml from "+argv[argpos-1]));
+                docroot.getProvenance().addEntry(ProvenanceStuff.newProvenanceEntry("ArchiveWriter", "user", "added vamsas.xml from "+argv[argpos-1]));
                 docroot.addVAMSAS(root);
               }
           }
index f15eec5..a560c38 100644 (file)
@@ -24,18 +24,21 @@ public class ClientDoc {
   protected VamsasArchive iohandler=null;
   protected VamsasArchiveReader reader=null;
   private String user=null;
+  private String app=null;
   
   /**
    * @param doc
    * @param iohandler
    * @param reader
+   * @param app
    * @param user
    */
-  public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String user, Hashtable objrefs) {
+  public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String app, String user, Hashtable objrefs) {
     super();
     this.doc = doc;
     this.iohandler = iohandler;
     this.reader = reader;
+    this.app = app;
     this.user = user;
     this.objrefs = objrefs;
     _VamsasRoots = doc.getVAMSAS();
@@ -47,7 +50,7 @@ public class ClientDoc {
    */
   protected Entry getProvenanceEntry(String action) {
     // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
-    Entry prov = ProvenanceStuff.newProvenanceEntry(user, action);
+    Entry prov = ProvenanceStuff.newProvenanceEntry(app, user, action);
     return prov;
   }
   public VAMSAS[] getVamsasRoots() {
index 2d5fcbf..3ec7d4d 100644 (file)
@@ -79,7 +79,7 @@ public class VamsasArchive {
     apuser.setDataReference(appdata_ref);
     appdata.addUser(apuser);
     appdata.setVersion("noggin");
-    appdata.setUrn("program:/the.nog/");
+    //TODO: write instance appdata  appdata.setUrn("program:/the.nog/");
     try {
       ObjectOutputStream ost = new ObjectOutputStream(va.getAppDataStream(appdata_ref));
       ost.writeObject(appdata);