X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Fclient%2Fsimpleclient%2FVamsasArchiveReader.java;h=f863eb772d03629f76b01ac0c59047b4bfbed129;hb=844ccad5a3fcbedec17b2af66d460f31abc7cff1;hp=e8df789fdb07cf2358f3169cf0888eb9f732462e;hpb=5156a824b13ecd091af9f84870f41d83eb59bd71;p=vamsas.git diff --git a/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java b/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java index e8df789..f863eb7 100644 --- a/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java +++ b/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java @@ -1,313 +1,336 @@ -package uk.ac.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. - * - * @author jimp - * - */ -public class VamsasArchiveReader { - private static Log log = LogFactory.getLog(VamsasArchiveReader.class); - JarFile jfile=null; - boolean stream=false; // true if we are seeking on the stream. - RandomAccessFile rfile; - ZipInputStream jstream=null; - Hashtable strmentries = null; - private void streamInit() { - //throw new Error("VamsasArchiveReader(Stream) Not implemented!"); - 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; - long pos=0; - do { - 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()) { - try { - jfile=new JarFile(vamsasfile); - } - catch (Exception e) { - log.debug("non-serious? couldn't open new JarFile on "+vamsasfile,e); - jfile=null; - } - } - - } - /** - * in an ideal world - this constructor will create a reader object - * for the locked file's random access stream. - * - * @param vamsaslock - */ - public VamsasArchiveReader(Lock vamsaslock) { - // LATER: implement or remove - if (vamsaslock==null || !vamsaslock.isLocked()) - throw new Error("IMPLEMENTATION ERROR: Cannot create a VamsasArchiveReader without a valid lock."); - // throw new Error("VamsasArchiveReading from locked IO stream not yet implemented."); - try { - rfile = vamsaslock.getRaFile(); - } catch (Exception e) { - log.warn("Unexpected IO Exception when accessing locked vamsas archive stream "+vamsaslock.target,e); - } - stream = true; - 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=VersionEntries.BETA_VERSION; - /** - * name of the jarEntry containing a well formatted vamsas XML Document - */ - - final public static String VAMSASDOC="vamsasDocument.xml"; - - /** - * name of the jarEntry containing a root VAMSAS element, and containing a - * random sequence of VAMSAS DataSet elements - */ - - 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 { - jstream=null; - rfile.seek(0); - jstream = new ZipInputStream(new FileInputStream(rfile.getFD())); - ZipEntry entry = null; - long epos = entrypos.longValue(); - do { - entry = jstream.getNextEntry(); - } while (entry!=null && --epos>=0); - // rfile.seek(entrypos.longValue()); - // make a Jar entry from a zip entry. - return new JarEntry(entry); - } - catch (Exception e) { - log.warn("Whilst seeking for "+entryname, e); - } - return null; - } - /** - * - * @return JarEntry for VamsasArchiveReader.VAMSASDOC - */ - protected JarEntry getVamsasDocumentEntry() { - return getJarEntry(VAMSASDOC); - } - /** - * - * @return JarEntry for VamsasArchiveReader.VAMSASXML - */ - protected JarEntry getVamsasXmlEntry() { - 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() { - // 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 && jstream==null) || !isValid() || (entry=getJarEntry(AppdataRef))==null) - return null; - - return entry; - } - - public InputStream getAppdataStream(String AppdataRef) { - JarEntry entry=getAppdataEntry(AppdataRef); - try { - if (entry!=null) - return getInputStream(entry); - } catch (IOException e) { - log.error("Failed when opening AppdataStream for "+AppdataRef, e); - } - return null; - } - /** - * get the VamsasDocument input stream, if it exists. - * @return null or valid input stream - */ - public InputStream getVamsasDocumentStream() { - InputStream vdoc; - if ((jfile==null && jstream==null) || !isValid()) - return null; - try { - vdoc = getInputStream(getVamsasDocumentEntry()); - } catch (IOException e) { - log.error("Whilst geting document stream",e); - vdoc=null; - } - return vdoc; - } - - /** - * get the VamsasXML input stream, if it exists. - * Note: Deprecated beyond our prealpha testing. - * @return null or valid input stream. - */ - - public InputStream getVamsasXmlStream() { - // log.warn("Deprecated call"); - JarEntry xmle=getVamsasXmlEntry(); - InputStream vdoc; - if (xmle==null) - return null; - try { - vdoc = getInputStream(xmle); - } catch (IOException e) { - log.error("Whilst getting VamsasXmlStream",e); - vdoc=null; - } - return vdoc; - } - - /** - * silently close the jar file. - * - */ - public void close() { - if (jfile!=null) { - try { - jfile.close(); - } catch (IOException e) { - 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); - } - } - } - - /** - * returns all entries not matching the filespec of a vamsas xml entry - * @return array of entries. - */ - public Vector getExtraEntries() { - if ((jfile==null && jstream==null)|| !isValid()) - return null; - 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; - } - } +/* + * This file is part of the Vamsas Client version 0.1. + * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, + * Andrew Waterhouse and Dominik Lindner. + * + * Earlier versions have also been incorporated into Jalview version 2.4 + * since 2008, and TOPALi version 2 since 2007. + * + * The Vamsas Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Vamsas Client is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the Vamsas Client. If not, see . + */ +package uk.ac.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 org.apache.tools.zip.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import uk.ac.vamsas.client.AppDataInputStream; +import uk.ac.vamsas.objects.utils.document.VersionEntries; + +/** + * Basic methods for accessing an existing Vamsas Archive, and Jar entry names + * for creating new vamsas archives. + * + * @author jimp + * + */ +public class VamsasArchiveReader { + private static final int JARFILE_OPEN_RETRIES = 50; + + private static final int JARFILE_OPEN_RETRYWAIT = 1; + + private static Log log = LogFactory.getLog(VamsasArchiveReader.class); + + ZipFile jfile = null; + + String jfileName = "randomAccessFile"; + + boolean stream = false; // true if we are seeking on the stream. + + RandomAccessFile rfile; + + // ZipInputStream jstream=null; + Hashtable strmentries = null; + + private void streamInit() { + // throw new Error("VamsasArchiveReader(Stream) Not implemented!"); + if (!stream) { + log.debug("Skipping init for Jar Stream input."); + return; + } else { + throw new Error( + "Implementation error - we don't do streams - only files or RA files"); + } + /* + * 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; long pos=0; do { 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; + int retries = JARFILE_OPEN_RETRIES; + Exception ex = null; + if (vamsasfile.exists()) { + while (jfile == null && --retries > 0) { + try { + jfile = new ZipFile(vamsasfile); + jfileName = vamsasfile.toString(); + } catch (Exception e) { + ex = e; + jfile = null; + try { + Thread.sleep(JARFILE_OPEN_RETRYWAIT); + } catch (Exception w) { + } + ; + } + } + if (jfile == null && ex != null) { + log.debug("non-serious? Exceptions when opening JarFile at " + + vamsasfile, ex); + } + } + } + + /** + * in an ideal world - this constructor will create a reader object for the + * locked file's random access stream. + * + * @param vamsaslock + */ + public VamsasArchiveReader(Lock vamsaslock) { + jfile = null; + if (vamsaslock == null || !vamsaslock.isLocked()) + throw new Error( + "IMPLEMENTATION ERROR: Cannot create a VamsasArchiveReader without a valid lock."); + // throw new + // Error("VamsasArchiveReading from locked IO stream not yet implemented."); + try { + rfile = vamsaslock.getRaFile(); + jfile = new ZipFile(rfile); + if (vamsaslock.target != null) + jfileName = vamsaslock.target.toString(); + } catch (Exception e) { + rfile = null; + jfile = null; + log.warn( + "Unexpected IO Exception when accessing locked vamsas archive stream " + + vamsaslock.target, e); + } + /* + * stream = true; 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 = VersionEntries.BETA_VERSION; + + /** + * name of the jarEntry containing a well formatted vamsas XML Document + */ + + final public static String VAMSASDOC = "vamsasDocument.xml"; + + /** + * name of the jarEntry containing a root VAMSAS element, and containing a + * random sequence of VAMSAS DataSet elements + */ + + 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 { jstream=null; rfile.seek(0); jstream = new + * ZipInputStream(new FileInputStream(rfile.getFD())); ZipEntry entry + * = null; long epos = entrypos.longValue(); do { entry = + * jstream.getNextEntry(); } while (entry!=null && --epos>=0); // + * rfile.seek(entrypos.longValue()); // make a Jar entry from a zip + * entry. return new JarEntry(entry); } catch (Exception e) { + * log.warn("Whilst seeking for "+entryname, e); } return null; } + */ + /** + * + * @return JarEntry for VamsasArchiveReader.VAMSASDOC + */ + protected ZipEntry getVamsasDocumentEntry() { + return getJarEntry(VAMSASDOC); + } + + /** + * + * @return JarEntry for VamsasArchiveReader.VAMSASXML + */ + protected ZipEntry getVamsasXmlEntry() { + 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() { + // 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 ZipEntry getAppdataEntry(String AppdataRef) { + ZipEntry entry; + if (jfile == null || !isValid() + || (entry = getJarEntry(AppdataRef)) == null) + return null; + + return entry; + } + + public InputStream getAppdataStream(String AppdataRef) { + ZipEntry entry = getAppdataEntry(AppdataRef); + try { + if (entry != null) + return getInputStream(entry); + } catch (IOException e) { + log.error("Failed when opening AppdataStream for " + AppdataRef, e); + } + return null; + } + + /** + * get the VamsasDocument input stream, if it exists. + * + * @return null or valid input stream + */ + public InputStream getVamsasDocumentStream() { + InputStream vdoc; + if (jfile == null || !isValid()) + return null; + try { + vdoc = getInputStream(getVamsasDocumentEntry()); + } catch (IOException e) { + log.error("Whilst geting document stream", e); + vdoc = null; + } + return vdoc; + } + + /** + * get the VamsasXML input stream, if it exists. Note: Deprecated beyond our + * prealpha testing. + * + * @return null or valid input stream. + */ + + public InputStream getVamsasXmlStream() { + // log.warn("Deprecated call"); + ZipEntry xmle = getVamsasXmlEntry(); + InputStream vdoc; + if (xmle == null) + return null; + try { + vdoc = getInputStream(xmle); + } catch (IOException e) { + log.error("Whilst getting VamsasXmlStream", e); + vdoc = null; + } + return vdoc; + } + + /** + * silently close the jar file. + * + */ + public void close() { + if (jfile != null) { + try { + jfile.close(); + rfile = null; + } catch (Exception e) { + log.error("Whilst closing JarFile " + jfileName, e); + } + } + } + + /** + * returns all entries not matching the filespec of a vamsas xml entry + * + * @return array of entries. + */ + public Vector getExtraEntries() { + if (jfile == null || !isValid()) + return null; + 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.getEntries(); + if (entries != null && entries.hasMoreElements()) { + do { + ZipEntry el = (ZipEntry) entries.nextElement(); + if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML)) + e.add(new String(el.getName())); // avoid references + } while (entries.hasMoreElements()); + } + return e; + } + + /* + * (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); + return null; + } + + /* + * (non-Javadoc) + * + * @see java.util.jar.JarFile#getJarEntry(java.lang.String) + */ + private ZipEntry getJarEntry(String name) { + if (jfile != null) + return jfile.getEntry(name); + return null; + } +}