refactored org to uk
[vamsas.git] / src / org / vamsas / client / simpleclient / SimpleClientAppdata.java
index 52d5890..84bc48a 100644 (file)
@@ -3,6 +3,7 @@
  */
 package org.vamsas.client.simpleclient;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -10,6 +11,8 @@ import java.io.DataInput;
 import java.io.DataInputStream;
 import java.io.DataOutput;
 import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Vector;
 import java.util.jar.JarEntry;
@@ -48,6 +51,15 @@ public class SimpleClientAppdata implements IClientAppdata {
    */
   SessionFile newAppData=null;
   JarOutputStream newAppDataStream=null;
+  /**
+   * set by extractAppData
+   */
+  protected ApplicationData appsGlobal = null;
+  /**
+   * set by extractAppData
+   */
+  protected User usersData = null;
+  
   ClientDocument clientdoc;
   /**
    * state flags
@@ -71,14 +83,6 @@ public class SimpleClientAppdata implements IClientAppdata {
     this.clientdoc = clientdoc;
   }
   /**
-   * set by extractAppData
-   */
-  protected ApplicationData appsGlobal = null;
-  /**
-   * set by extractAppData
-   */
-  protected User usersData = null;
-  /**
    * gets appropriate app data for the application, if it exists in this dataset
    * Called by every accessor to ensure data has been retrieved from document.
    */
@@ -323,7 +327,7 @@ public class SimpleClientAppdata implements IClientAppdata {
         log.debug("Successfully made temp appData file for "+apdname);
       } else {
         // truncate to remove existing data.
-        apdfile.fileLock.rafile.setLength(0);
+        apdfile.fileLock.getRaFile().setLength(0);
         log.debug("Successfully truncated existing temp appData for "+apdname);
       }
       } catch (Exception e) {
@@ -337,9 +341,9 @@ public class SimpleClientAppdata implements IClientAppdata {
     }
     try {
       apdfile.lockFile();
+      // LATER: Refactor these local AppDatastream IO stuff to their own class.
       JarOutputStream dstrm = 
-        new JarOutputStream(
-            new BufferedOutputStream(new java.io.FileOutputStream(apdfile.sessionFile)));
+        new JarOutputStream(apdfile.fileLock.getBufferedOutputStream(true));
       if (!clientOrUser) {
         newAppDataStream = dstrm;
       } else {
@@ -356,6 +360,45 @@ public class SimpleClientAppdata implements IClientAppdata {
     apdfile.unlockFile();
     return null;
    }
+  /**
+   * copy data from the appData jar file to an appropriately 
+   * referenced jar or Data entry for the given ApplicationData
+   * Assumes the JarFile is properly closed. 
+   * @param vdoc session Document handler
+   * @param appd the AppData whose block is being updated
+   * @param apdjar the new data in a Jar written by this class
+   */
+  protected void updateAnAppdataEntry(VamsasArchive vdoc, AppData appd, SessionFile apdjar) throws IOException {
+    if (apdjar==null || apdjar.sessionFile==null || !apdjar.sessionFile.exists()) {
+      throw new IOException("No temporary Appdata to recover and transfer.");
+    }
+    if (vdoc==null) {
+      log.fatal("FATAL! NO DOCUMENT TO WRITE TO!");
+      throw new IOException("FATAL! NO DOCUMENT TO WRITE TO!");
+    }
+    log.debug("Recovering AppData entry from "+apdjar.sessionFile);
+    JarInputStream istrm = new JarInputStream(apdjar.getBufferedInputStream(true));
+    JarEntry je=null;
+    while (istrm.available()>0 && (je=istrm.getNextJarEntry())!=null && !je.getName().equals("appData_entry.dat")) {
+      if (je!=null)
+        log.debug("Ignoring extraneous entry "+je.getName());
+    }
+    if (istrm.available()>0 && je!=null) {
+      log.debug("Found appData_entry.dat in Jar");
+      String ref = appd.getDataReference();
+      if (ref==null) {
+        throw new IOException("Null AppData.DataReference passed.");
+      }
+      if (vdoc.writeAppdataFromStream(ref, istrm)) {
+        log.debug("Entry updated successfully.");
+      } else {
+        throw new IOException("writeAppdataFromStream did not return true - expect future badness."); // LATER - verify why this might occur.
+      }
+    } else {
+      throw new IOException("Couldn't find appData_entry.dat in temporary jar file "+apdjar.sessionFile.getAbsolutePath());
+    }
+    istrm.close();
+  }
   /* (non-Javadoc)
    * @see org.vamsas.client.IClientAppdata#getClientOutputStream()
    */
@@ -447,6 +490,35 @@ public class SimpleClientAppdata implements IClientAppdata {
       // LATER: deal with error case - do we make session read only, or what ?
     }
   }
+  /**
+   * flush and close outstanding output streams. 
+   *  - do this before checking data length.
+   * @throws IOException
+   */
+  protected void closeForWriting() throws IOException {
+    if (newAppDataStream!=null) {
+      newAppDataStream.flush();
+      newAppDataStream.closeEntry();
+      newAppDataStream.close();
+    }
+    if (newUserDataStream!=null) {
+      newUserDataStream.flush();
+      newUserDataStream.closeEntry();
+      newUserDataStream.close();
+    }
+  }
+
+
+  /**
+   * 
+   * @return true if any AppData blocks have to be updated in session Jar
+   */
+  protected boolean isModified() {
+    // LATER differentiate between core xml modification and Jar Entry modification.
+    if (newAppData.sessionFile.exists() || newUserData.sessionFile.exists())
+      return true;
+    return false;
+  }
   /* (non-Javadoc)
    * @see java.lang.Object#finalize()
    */