From d2cb3f9a881f6b937adb5c54a4b20a08eb2e99db Mon Sep 17 00:00:00 2001 From: jprocter Date: Thu, 23 Mar 2006 19:27:57 +0000 Subject: [PATCH] still dealing with JarInputStream issues. 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 | 2 +- .../simpleclient/LockedFileOutputStream.java | 6 +- .../vamsas/client/simpleclient/SessionFile.java | 35 ++++ .../client/simpleclient/SimpleClientAppdata.java | 2 +- .../vamsas/client/simpleclient/VamsasArchive.java | 31 +++- .../client/simpleclient/VamsasArchiveReader.java | 181 +++++++++++++++----- .../vamsas/test/simpleclient/VamsasArchive.java | 9 +- 7 files changed, 212 insertions(+), 54 deletions(-) diff --git a/src/org/vamsas/client/simpleclient/Lock.java b/src/org/vamsas/client/simpleclient/Lock.java index b49cdf5..5c052f6 100644 --- a/src/org/vamsas/client/simpleclient/Lock.java +++ b/src/org/vamsas/client/simpleclient/Lock.java @@ -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(); } } diff --git a/src/org/vamsas/client/simpleclient/LockedFileOutputStream.java b/src/org/vamsas/client/simpleclient/LockedFileOutputStream.java index 2c12974..92d9d0c 100644 --- a/src/org/vamsas/client/simpleclient/LockedFileOutputStream.java +++ b/src/org/vamsas/client/simpleclient/LockedFileOutputStream.java @@ -14,14 +14,13 @@ import java.io.IOException; * */ public class LockedFileOutputStream extends FileOutputStream { - + /** * @param file * @throws FileNotFoundException */ public LockedFileOutputStream(File file) throws FileNotFoundException { super(file); - // TODO Auto-generated constructor stub } /** @@ -32,7 +31,6 @@ public class LockedFileOutputStream extends FileOutputStream { public LockedFileOutputStream(File file, boolean append) throws FileNotFoundException { super(file, append); - // TODO Auto-generated constructor stub } /** @@ -40,7 +38,6 @@ public class LockedFileOutputStream extends FileOutputStream { */ public LockedFileOutputStream(FileDescriptor fdObj) { super(fdObj); - // TODO Auto-generated constructor stub } /** @@ -49,7 +46,6 @@ public class LockedFileOutputStream extends FileOutputStream { */ public LockedFileOutputStream(String name) throws FileNotFoundException { super(name); - // TODO Auto-generated constructor stub } /** diff --git a/src/org/vamsas/client/simpleclient/SessionFile.java b/src/org/vamsas/client/simpleclient/SessionFile.java index d33f2f8..9da73c0 100644 --- a/src/org/vamsas/client/simpleclient/SessionFile.java +++ b/src/org/vamsas/client/simpleclient/SessionFile.java @@ -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); + } + } diff --git a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java index 95362aa..91ad33d 100644 --- a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java +++ b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java @@ -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) diff --git a/src/org/vamsas/client/simpleclient/VamsasArchive.java b/src/org/vamsas/client/simpleclient/VamsasArchive.java index ceaf401..4c4fbfd 100644 --- a/src/org/vamsas/client/simpleclient/VamsasArchive.java +++ b/src/org/vamsas/client/simpleclient/VamsasArchive.java @@ -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); } diff --git a/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java b/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java index 8f1e0ea..3d4fbe6 100644 --- a/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java +++ b/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java @@ -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; + } + } diff --git a/src/org/vamsas/test/simpleclient/VamsasArchive.java b/src/org/vamsas/test/simpleclient/VamsasArchive.java index 112a4b2..6793019 100644 --- a/src/org/vamsas/test/simpleclient/VamsasArchive.java +++ b/src/org/vamsas/test/simpleclient/VamsasArchive.java @@ -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); -- 1.7.10.2