SimpleClientAppdata implemented but untested.
authorjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 20 Mar 2006 22:57:05 +0000 (22:57 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 20 Mar 2006 22:57:05 +0000 (22:57 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@193 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/simpleclient/ClientDocument.java
src/org/vamsas/client/simpleclient/SessionFile.java
src/org/vamsas/client/simpleclient/SimpleClientAppdata.java
src/org/vamsas/client/simpleclient/VamsasSession.java

index de197e7..dd1d695 100644 (file)
@@ -28,9 +28,6 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements
   private static Log log = LogFactory.getLog(ClientDocument.class);
   private VamsasDocument doc;
   protected SimpleClient sclient;
-  protected ApplicationData appsglobal=null;
-  protected User usersdata=null;
-  protected byte[] appData=null;
   protected VamsasArchive archive = null;
   /**
    *
@@ -166,6 +163,9 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements
     // TODO: add provenance stuff to newly registered Vobject
     return _registerObject(unregistered);
   }
+  /**
+   * IClientAppdata instance - if it exists.
+   */
   SimpleClientAppdata scappd = null;
   /* (non-Javadoc)
    * @see org.vamsas.client.IClientDocument#getClientAppdata()
index 30abd99..0ff306e 100644 (file)
@@ -120,4 +120,15 @@ public class SessionFile {
     fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0, 
         newData.fileLock.rafile.length());
   }
+  /**
+   * remove all trace of the sessionFile file
+   *
+   */
+  protected void eraseExistence() {
+    unlockFile();
+    if (sessionFile!=null) {
+      sessionFile.delete();
+      sessionFile = null;
+    }
+  }
 }
index d488782..99dc336 100644 (file)
@@ -3,14 +3,18 @@
  */
 package org.vamsas.client.simpleclient;
 
+import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInput;
 import java.io.DataInputStream;
 import java.io.DataOutput;
+import java.io.DataOutputStream;
 import java.io.InputStream;
 import java.util.Vector;
+import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -33,14 +37,17 @@ public class SimpleClientAppdata implements IClientAppdata {
    */
   protected boolean accessedDocument = false;
   /**
-   * has the user datablock been modified ?
+   * has the user datablock been modified ? 
+   * temporary file containing new user specific application data chunk
    */
-  protected boolean modifiedUserData = false;
+  SessionFile newUserData=null;
+  JarOutputStream newUserDataStream = null;
   /**
    * has the apps global datablock been modified ?
+   * temporary file containing new global application data chunk
    */
-  protected boolean modifiedAppData = false;
-  
+  SessionFile newAppData=null;
+  JarOutputStream newAppDataStream=null;
   ClientDocument clientdoc;
   /**
    * state flags
@@ -91,12 +98,10 @@ public class SimpleClientAppdata implements IClientAppdata {
         AppData clientdat = (AppData) apldataset.get(0);
         if (clientdat instanceof ApplicationData) {
           appsGlobal = (ApplicationData) clientdat;
-          modifiedAppData = false;
           if (apldataset.size()>1) {
             clientdat = (AppData) apldataset.get(1);
             if (clientdat instanceof User) {
               usersData = (User) clientdat;
-              modifiedUserData = false;
             }
             if (apldataset.size()>2)
               log.info("Ignoring additional ("+(apldataset.size()-2)+") AppDatas returned by document appdata query.");
@@ -222,7 +227,7 @@ public class SimpleClientAppdata implements IClientAppdata {
       appdName = "User's Appdata";
     }    
     log.debug("getting "+appdName+" as a byte array");
-    extractAppData(clientdoc.getVamsasDocument());// TODO: get VamsasArchiveReader from sclient
+    extractAppData(clientdoc.getVamsasDocument());
     AppData object;
     if (!clientOrUser) {
       object = appsGlobal;
@@ -298,15 +303,64 @@ public class SimpleClientAppdata implements IClientAppdata {
   /**
    * methods for writing new AppData entries.
    */
-  
+  private DataOutput _getAppdataOutputStream(boolean clientOrUser) {
+    String apdname;
+    SessionFile apdfile=null;
+    if (!clientOrUser) {
+      apdname = "clientAppData";
+      apdfile = newAppData;
+    } else {
+      apdname = "userAppData";
+      apdfile = newUserData;
+    }
+    try {
+      if (apdfile==null) {
+        apdfile=clientdoc.sclient._session.getTempSessionFile(apdname,".jar");
+        log.debug("Successfully made temp appData file for "+apdname);
+      } else {
+        // truncate to remove existing data.
+        apdfile.fileLock.rafile.setLength(0);
+        log.debug("Successfully truncated existing temp appData for "+apdname);
+      }
+      } catch (Exception e) {
+      log.error("Whilst opening temp file in directory "+clientdoc.sclient._session.sessionDir, e);
+    }
+    // we do not make another file for the new entry if one exists already
+    if (!clientOrUser) {
+      newAppData = apdfile;
+    } else {
+      newUserData = apdfile;
+    }
+    try {
+      apdfile.lockFile();
+      JarOutputStream dstrm = 
+        new JarOutputStream(
+            new BufferedOutputStream(new java.io.FileOutputStream(apdfile.sessionFile)));
+      if (!clientOrUser) {
+        newAppDataStream = dstrm;
+      } else {
+        newUserDataStream = dstrm;
+      }
+      dstrm.putNextEntry(new JarEntry("appData_entry.dat"));
+      // LATER: there may be trouble ahead if an AppDataOutputStream is written to by one thread when another truncates the file. This situation should be prevented if possible
+      return new AppDataOutputStream(dstrm);
+    }
+    catch (Exception e) {
+      log.error("Whilst opening jar output stream for file "+apdfile.sessionFile);
+    }
+    // tidy up and return null
+    apdfile.unlockFile();
+    return null;
+   }
   /* (non-Javadoc)
    * @see org.vamsas.client.IClientAppdata#getClientOutputStream()
    */
   public DataOutput getClientOutputStream() {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
-    return null;
+    if (log.isDebugEnabled())
+      log.debug("trying to getClientOutputStream for "+clientdoc.sclient.client.getClientUrn());   
+    return _getAppdataOutputStream(false);
   }
 
   /* (non-Javadoc)
@@ -315,8 +369,10 @@ public class SimpleClientAppdata implements IClientAppdata {
   public DataOutput getUserOutputStream() {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
-    return null;
+    if (log.isDebugEnabled())
+      log.debug("trying to getUserOutputStream for ("
+          +clientdoc.sclient.getUserHandle().getFullName()+")"+clientdoc.sclient.client.getClientUrn());   
+    return _getAppdataOutputStream(true);
   }
 
   /* (non-Javadoc)
@@ -325,7 +381,10 @@ public class SimpleClientAppdata implements IClientAppdata {
   public boolean hasClientAppdata() {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
+    extractAppData(clientdoc.getVamsasDocument());
+    // LATER - check validity of a DataReference before we return true
+    if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null))
+      return true;
     return false;
   }
 
@@ -335,18 +394,38 @@ public class SimpleClientAppdata implements IClientAppdata {
   public boolean hasUserAppdata() {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
+    extractAppData(clientdoc.getVamsasDocument());
+    // LATER - check validity of a DataReference before we return true
+    if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null))
+      return true;
+    return false;
+  }
+  private boolean _writeAppDataStream(JarOutputStream ostrm, byte[] data) {
+    try {
+      if (data!=null && data.length>0) 
+        ostrm.write(data);
+      ostrm.closeEntry();
+      return true;
+    }
+    catch (Exception e) {
+      log.error("Serious! - IO error when writing AppDataStream to file "+newAppData.sessionFile, e);
+    }
     return false;
   }
-
   /* (non-Javadoc)
    * @see org.vamsas.client.IClientAppdata#setClientAppdata(byte[])
    */
   public void setClientAppdata(byte[] data) {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
-    
+    _getAppdataOutputStream(false);
+    if (newAppDataStream==null) {
+      // LATER: define an exception for this ? - operation may fail even if file i/o not involved
+      log.error("Serious! - couldn't open new AppDataStream in session directory "+clientdoc.sclient._session.sessionDir);
+    } else {
+      _writeAppDataStream(newAppDataStream, data);
+      // LATER: deal with error case - do we make session read only, or what ?
+    }
   }
 
   /* (non-Javadoc)
@@ -355,14 +434,33 @@ public class SimpleClientAppdata implements IClientAppdata {
   public void setUserAppdata(byte[] data) {
     if (clientdoc==null)
       throw new Error("Implementation error, Improperly initialized SimpleClientAppdata.");
-    // TODO Auto-generated method stub
-    
+    _getAppdataOutputStream(true);
+    if (newUserDataStream==null) {
+      // LATER: define an exception for this ? - operation may fail even if file i/o not involved
+      log.error("Serious! - couldn't open new UserDataStream in session directory "+clientdoc.sclient._session.sessionDir);
+    } else {
+      _writeAppDataStream(newUserDataStream, data);
+      // LATER: deal with error case - do we make session read only, or what ?
+    }
   }
   /* (non-Javadoc)
    * @see java.lang.Object#finalize()
    */
   protected void finalize() throws Throwable {
-    // TODO Auto-generated method stub
+    if (newAppDataStream!=null) {
+      newAppDataStream = null;
+    }
+    if (newAppDataStream!=null) {
+      newUserDataStream = null;
+    }
+    if (newAppData!=null) {
+      newAppData.eraseExistence();
+      newAppData = null;
+    }
+    if (newUserData!=null) {
+      newUserData.eraseExistence();
+      newUserData = null;
+    }
     super.finalize();
   }
 
index 6f41fb7..365311d 100644 (file)
@@ -292,7 +292,19 @@ public class VamsasSession {
     
     return va;
   }
-  
+  /**
+   * create a uniquely named file in the session Directory
+   * @see java.io.File.createTempFile
+   * @param pref Prefix for name
+   * @param suff Suffix for name
+   * @return SessionFile object configured for the new file (of length zero)
+   * @throws IOException
+   */
+  protected SessionFile getTempSessionFile(String pref, String suff) throws IOException {
+    File tfile = File.createTempFile(pref,suff,sessionDir);
+    SessionFile tempFile = new SessionFile(tfile);
+    return tempFile;
+  }
 }