still dealing with JarInputStream issues.
authorjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 23 Mar 2006 19:27:57 +0000 (19:27 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 23 Mar 2006 19:27:57 +0000 (19:27 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@205 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/simpleclient/Lock.java
src/org/vamsas/client/simpleclient/LockedFileOutputStream.java
src/org/vamsas/client/simpleclient/SessionFile.java
src/org/vamsas/client/simpleclient/SimpleClientAppdata.java
src/org/vamsas/client/simpleclient/VamsasArchive.java
src/org/vamsas/client/simpleclient/VamsasArchiveReader.java
src/org/vamsas/test/simpleclient/VamsasArchive.java

index b49cdf5..5c052f6 100644 (file)
@@ -70,7 +70,7 @@ public class Lock {
         if (rafile.getChannel().isOpen()) {
           if (lock!=null && lock.isValid())
             lock.release();
-          if (rafile!=null && rafile.getChannel().isOpen())
+          if (rafile.getChannel().isOpen())
             rafile.getChannel().close();
         }
       }
index 2c12974..92d9d0c 100644 (file)
@@ -14,14 +14,13 @@ import java.io.IOException;
  *\r
  */\r
 public class LockedFileOutputStream extends FileOutputStream {\r
-\r
+  \r
   /**\r
    * @param file\r
    * @throws FileNotFoundException\r
    */\r
   public LockedFileOutputStream(File file) throws FileNotFoundException {\r
     super(file);\r
-    // TODO Auto-generated constructor stub\r
   }\r
 \r
   /**\r
@@ -32,7 +31,6 @@ public class LockedFileOutputStream extends FileOutputStream {
   public LockedFileOutputStream(File file, boolean append)\r
       throws FileNotFoundException {\r
     super(file, append);\r
-    // TODO Auto-generated constructor stub\r
   }\r
 \r
   /**\r
@@ -40,7 +38,6 @@ public class LockedFileOutputStream extends FileOutputStream {
    */\r
   public LockedFileOutputStream(FileDescriptor fdObj) {\r
     super(fdObj);\r
-    // TODO Auto-generated constructor stub\r
   }\r
 \r
   /**\r
@@ -49,7 +46,6 @@ public class LockedFileOutputStream extends FileOutputStream {
    */\r
   public LockedFileOutputStream(String name) throws FileNotFoundException {\r
     super(name);\r
-    // TODO Auto-generated constructor stub\r
   }\r
 \r
   /**\r
index d33f2f8..9da73c0 100644 (file)
@@ -1,6 +1,9 @@
 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;
@@ -147,4 +150,36 @@ public class SessionFile {
       sessionFile = null;
     }
   }
+  /* (non-Javadoc)
+   * @see org.vamsas.client.simpleclient.Lock#getBufferedInputStream(boolean)
+   */
+  public BufferedInputStream getBufferedInputStream(boolean atStart) throws IOException {
+    lockFile();
+    return fileLock.getBufferedInputStream(atStart);
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.simpleclient.Lock#getBufferedOutputStream(boolean)
+   */
+  public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
+    lockFile();
+    return fileLock.getBufferedOutputStream(clear);
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.simpleclient.Lock#getFileInputStream(boolean)
+   */
+  public FileInputStream getFileInputStream(boolean atStart) throws IOException {
+    lockFile();
+    return fileLock.getFileInputStream(atStart);
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.simpleclient.Lock#getFileOutputStream(boolean)
+   */
+  public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
+    lockFile();
+    return fileLock.getFileOutputStream(clear);
+  }
+  
 }
index 95362aa..91ad33d 100644 (file)
@@ -377,7 +377,7 @@ public class SimpleClientAppdata implements IClientAppdata {
       throw new IOException("FATAL! NO DOCUMENT TO WRITE TO!");
     }
     log.debug("Recovering AppData entry from "+apdjar.sessionFile);
-    JarInputStream istrm = new JarInputStream(new BufferedInputStream(new FileInputStream(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)
index ceaf401..4c4fbfd 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Iterator;
 import java.util.Vector;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -187,6 +188,16 @@ public class VamsasArchive {
     this(archive, overwrite, vamsasdocument, null);
   }
   /**
+   * Constructor for accessing Files under file-lock management (ie a session file)
+   * @param archive
+   * @param vamsasdocument
+   * @param overwrite
+   * @throws IOException
+   */
+  public VamsasArchive(VamsasFile archive, boolean vamsasdocument, boolean overwrite) throws IOException {
+    this(archive.sessionFile, overwrite, vamsasdocument, archive);
+  }
+  /**
    * 
    * @param archive file to write
    * @param overwrite true if original contents should be deleted
@@ -205,10 +216,13 @@ public class VamsasArchive {
     this.vamsasdocument = vamsasdocument;
     if (archive.exists() && !overwrite) {
       this.original = archive;
-      if (extantLock!=null)
+      if (extantLock!=null) {
         this.odoclock = extantLock;
-      else 
-        this.odoclock = new SessionFile(archive); 
+        if (odoclock.fileLock==null || !odoclock.fileLock.isLocked())
+          odoclock.lockFile();
+      } else { 
+        this.odoclock = new SessionFile(archive);
+      }
       odoclock.lockFile(); // lock the file *immediatly*
       this.archive = null;       // archive will be a temp file when the open method is called
       virginArchive=false;
@@ -225,7 +239,7 @@ public class VamsasArchive {
       else
         rchive = new SessionFile(archive);
       rchive.lockFile();
-      if (rchive.fileLock==null || rchive.fileLock.rafile==null)
+      if (rchive.fileLock==null || rchive.fileLock.rafile==null || !rchive.fileLock.isLocked())
         throw new IOException("Lock failed for new archive"+archive);
       rchive.fileLock.rafile.setLength(0); // empty the archive.
       virginArchive = true;
@@ -269,6 +283,7 @@ public class VamsasArchive {
     JarEntry je = new JarEntry(entry);
     if (!addEntry(entry))
       return false;
+    newarchive.flush();
     newarchive.putNextEntry(je);
     return true;
   }
@@ -354,10 +369,11 @@ public class VamsasArchive {
    */
   public void closeArchive() throws IOException {
     if (newarchive!=null) {
+      newarchive.flush();
       newarchive.closeEntry();
       if (!isDocumentWritten())
         log.warn("Premature closure of archive '"+archive.getAbsolutePath()+"': No document has been written.");
-      newarchive.close();
+      newarchive.finish();
       updateOriginal();
       closeAndReset();
     } else {
@@ -536,7 +552,8 @@ public class VamsasArchive {
       rchive = new SessionFile(archive);
     if (!rchive.lockFile()) 
       throw new IOException("Failed to get lock on file "+archive);
-    newarchive = new JarOutputStream(rchive.fileLock.getBufferedOutputStream(true));  
+    Manifest newmanifest = new Manifest();
+    newarchive = new JarOutputStream(rchive.fileLock.getBufferedOutputStream(true), newmanifest);  
     entries = new Hashtable();
   }
   public void putVamsasDocument(VamsasDocument doc) throws IOException, 
@@ -546,6 +563,8 @@ public class VamsasArchive {
   
   public void putVamsasDocument(VamsasDocument doc, VorbaIdFactory vorba) throws IOException, 
   org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+    if (vamsasdocument)
+      doc.setVersion(VersionEntries.latestVersion()); // LATER: ensure this does the correct thing.
     VorbaXmlBinder.putVamsasDocument(getDocumentOutputStream(), vorba, doc);
   }
   
index 8f1e0ea..3d4fbe6 100644 (file)
@@ -3,17 +3,23 @@ package org.vamsas.client.simpleclient;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
 import java.io.RandomAccessFile;
 import java.util.Enumeration;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Vector;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarInputStream;
 import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.vamsas.objects.utils.document.VersionEntries;
 /**
  * Basic methods for accessing an existing Vamsas Archive, 
  * and Jar entry names for creating new vamsas archives.
@@ -23,10 +29,42 @@ import org.apache.commons.logging.LogFactory;
  */
 public class VamsasArchiveReader {
   private static Log log = LogFactory.getLog(VamsasArchiveReader.class);
-  JarFile jfile;
+  JarFile jfile=null;
   boolean stream=false; // true if we are seeking on the stream.
-  RandomAccessFile rfile; 
-  JarInputStream jstream;
+  RandomAccessFile rfile;
+  ZipInputStream jstream=null;
+  Hashtable strmentries = null;
+  private void streamInit() {
+    if (!stream) {
+      log.debug("Skipping init for Jar Stream input.");
+      return;
+    }
+    strmentries = new Hashtable();
+    log.debug("Jar Stream input Initialisation");
+    try {
+      rfile.seek(0);
+      // no buffering - we need to be able to move around the random access stream.
+      jstream = new ZipInputStream(new FileInputStream(rfile.getFD())); // no manifest (probably)
+      if (jstream.available()==0)
+        log.warn("Can't read from JarInputStream (Locked stream!)");
+      ZipEntry entry=null;
+      do {
+        long pos = rfile.getFilePointer();
+        if ((entry=jstream.getNextEntry())!=null) {
+          if (strmentries.containsKey(entry.getName())) {
+            log.info("Only recording last of duplicate entries '"+entry.getName()+"'");
+          } 
+          strmentries.put(entry.getName(), new Long(pos));
+          jstream.closeEntry();
+        }
+      } while (entry!=null);
+    }
+    catch (Exception e) {
+      log.warn("Exceptions during init!",e);
+      jstream=null;
+    }
+  }
+  
   public VamsasArchiveReader(File vamsasfile) {
     jfile=null;
     if (vamsasfile.exists()) {
@@ -49,16 +87,15 @@ public class VamsasArchiveReader {
   public VamsasArchiveReader(Lock vamsaslock) {
     rfile = vamsaslock.rafile;
     stream = true;
-    // TODO: Implement stream based JarFile access
-    log.error("NOT IMPLEMENTED STREAM-BASED JAR ACCESS");
-    throw new Error("Can't access a locked VamsasArchive file as a random access stream yet.");
-    // rfile.seek(0);
-    
+    streamInit();
+    if (jstream==null)
+      throw new Error("Failed to open archive from Locked random access stream.");
   }
+  
   /**
    * the vamsas document version(s) handled by this Reader
    */
-  final public static String DOCUMENT_VERSION="0.1"; 
+  final public static String DOCUMENT_VERSION=VersionEntries.BETA_VERSION; 
   /**
    * name of the jarEntry containing a well formatted vamsas XML Document
    */
@@ -71,41 +108,63 @@ public class VamsasArchiveReader {
    */
   
   final public static String VAMSASXML="vamsas.xml";
-  
+  /**
+   * seeks jstream to the given entry name and reads it.
+   * @param entryname
+   * @return
+   */
+  private JarEntry seekEntry(String entryname) {
+    if (jstream==null)
+      return null;
+    if (!strmentries.containsKey(entryname)) 
+      return null;
+    Long entrypos = (Long) strmentries.get(entryname);
+    if (entrypos==null) {
+      log.error("Null entry position for "+entryname);
+      return null;
+    }
+    try {
+      rfile.seek(entrypos.longValue());
+      // make a Jar entry from a zip entry.
+      
+      return new JarEntry(jstream.getNextEntry());
+    }
+    catch (Exception e) {
+      log.warn("Whilst seeking for "+entryname, e);
+    }
+    return null;
+  }
   /**
    * 
    * @return JarEntry for VamsasArchiveReader.VAMSASDOC
    */
   protected JarEntry getVamsasDocumentEntry() {
-    if (jfile!=null)
-      return jfile.getJarEntry(VAMSASDOC);
-    return null;
+    return getJarEntry(VAMSASDOC);
   }
   /**
    * 
    * @return JarEntry for VamsasArchiveReader.VAMSASXML
    */
   protected JarEntry getVamsasXmlEntry() {
-    if (jfile!=null)
-      return jfile.getJarEntry(VAMSASXML);
-    return null;
+    return getJarEntry(VAMSASXML);
   }
   /**
    * Test for valid vamsas document archive
    * @return true if getVamsasDocumentStream will return a stream likely to contain valid XML
    */
   public boolean isValid() {
-    if (jfile!=null)
-      // TODO: check if VAMSASDOC is well formed (follows www.vamsas.ac.uk/schemas/vamsasDocument.xsd) and all appData references are resolvable - preferably as jar entries
+    // TODO: check if VAMSASDOC is well formed (follows www.vamsas.ac.uk/schemas/vamsasDocument.xsd) and all appData references are resolvable - preferably as jar entries
+    if (jfile!=null || jstream!=null)
       return (getVamsasDocumentEntry()!=null);
     return false;   
   }
-
+  
   
   protected JarEntry getAppdataEntry(String AppdataRef) {
     JarEntry entry;
-    if (jfile==null || !isValid() || (entry=jfile.getJarEntry(AppdataRef))==null)
+    if ((jfile==null && jstream==null) || !isValid() || (entry=getJarEntry(AppdataRef))==null)
       return null;
+    
     return entry;
   }
   
@@ -113,10 +172,9 @@ public class VamsasArchiveReader {
     JarEntry entry=getAppdataEntry(AppdataRef);
     try {
       if (entry!=null)
-        return jfile.getInputStream(entry);
+        return getInputStream(entry);
     } catch (IOException e) {
-      System.err.println("Failed when opening AppdataStream for "+AppdataRef);
-      e.printStackTrace(System.err);
+      log.error("Failed when opening AppdataStream for "+AppdataRef, e);
     }
     return null;
   }
@@ -126,12 +184,12 @@ public class VamsasArchiveReader {
    */
   public InputStream getVamsasDocumentStream() {
     InputStream vdoc;
-    if (jfile==null || !isValid())
+    if ((jfile==null && jstream==null) || !isValid())
       return null;
     try {
-      vdoc = jfile.getInputStream(getVamsasDocumentEntry());
+      vdoc = getInputStream(getVamsasDocumentEntry());
     } catch (IOException e) {
-      e.printStackTrace(System.err);
+      log.error("Whilst geting document stream",e);
       vdoc=null;
     }
     return vdoc;
@@ -150,9 +208,9 @@ public class VamsasArchiveReader {
     if (xmle==null)
       return null;
     try {
-      vdoc = jfile.getInputStream(xmle);
+      vdoc = getInputStream(xmle);
     } catch (IOException e) {
-      e.printStackTrace(System.err);
+      log.error("Whilst getting VamsasXmlStream",e);
       vdoc=null;
     }
     return vdoc;
@@ -167,7 +225,17 @@ public class VamsasArchiveReader {
       try {
         jfile.close();
       } catch (IOException e) {
-        e.printStackTrace(System.err);
+        log.error("Whilst closing JarFile "+jfile.getName(), e);
+      }
+    }
+    if (jstream!=null) {
+      try {
+        jstream.closeEntry();
+        jstream=null;
+        // LATER: reference counting for random access file instances is necessary.
+      }
+      catch (Exception e) {
+        log.error("Whilst finishing reading from jar input stream",e);
       }
     }
   }
@@ -177,18 +245,53 @@ public class VamsasArchiveReader {
    * @return array of entries.
    */
   public Vector getExtraEntries() {
-    if (jfile==null || !isValid())
+    if ((jfile==null && jstream==null)|| !isValid())
       return null;
-    Enumeration entries = jfile.entries();
-    if (entries!=null && entries.hasMoreElements()) {
-      Vector e = new Vector();
-      do {
-        JarEntry el = (JarEntry) entries.nextElement();
-        if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML))
-          e.add(new String(el.getName())); // avoid references
-      } while (entries.hasMoreElements());
+    Vector e = new Vector();
+    if (jstream!=null) {
+      Enumeration entries = strmentries.keys();
+      if (entries!=null && entries.hasMoreElements()) {
+        do {
+          JarEntry el = (JarEntry) entries.nextElement();
+          if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML))
+            e.add(new String(el.getName())); // avoid references
+        } while (entries.hasMoreElements());
+      }
+    } else {
+      Enumeration entries = jfile.entries();
+      if (entries!=null && entries.hasMoreElements()) {
+        do {
+          JarEntry el = (JarEntry) entries.nextElement();
+          if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML))
+            e.add(new String(el.getName())); // avoid references
+        } while (entries.hasMoreElements());
+      }
       return e;
     }
     return null;
   }
-}
+  
+  /* (non-Javadoc)
+   * @see java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
+   */
+  private InputStream getInputStream(ZipEntry ze) throws IOException {
+    if (jfile!=null)
+      return jfile.getInputStream(ze);
+    if (jstream!=null) {
+      seekEntry(ze.getName());
+      return new AppDataInputStream(jstream);
+    }
+    return null;
+  }
+    
+    /* (non-Javadoc)
+     * @see java.util.jar.JarFile#getJarEntry(java.lang.String)
+     */
+    private JarEntry getJarEntry(String name) {
+      if (jfile!=null)
+        return jfile.getJarEntry(name);
+      if (jstream!=null)
+        return seekEntry(name);
+      return null;
+    }
+  }
index 112a4b2..6793019 100644 (file)
@@ -174,15 +174,20 @@ public class VamsasArchive {
       va.putVamsasDocument(doc);
       va.closeArchive();
       sfile.unLock();
+      System.exit(0);
       log.info("Testing update: ");
       {
         Lock lock=sfile.getLock();
         if (lock==null)
           while ((lock=sfile.getLock())==null)
             log.info("Waiting for lock.");
-        VamsasArchiveReader vreader = new VamsasArchiveReader(newf);
+        VamsasArchiveReader vreader = new VamsasArchiveReader(lock);
         SimpleDocument sdoc = new SimpleDocument("testing vamsas update");
-        ArchiveReports.reportDocument(sdoc.getVamsasDocument(vreader), vreader, true, System.out);
+        VamsasDocument finaldoc = sdoc.getVamsasDocument(vreader);
+        if (finaldoc!=null)
+          ArchiveReports.reportDocument(finaldoc, vreader, true, System.out);
+        else 
+          log.error("Null Document Read from "+newf);
       }
     } catch (Exception e) {
       e.printStackTrace(System.err);