1 package org.vamsas.client.simpleclient;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.BufferedInputStream;
7 import java.io.FileInputStream;
8 import java.io.RandomAccessFile;
9 import java.util.Enumeration;
10 import java.util.Hashtable;
11 import java.util.Iterator;
12 import java.util.Vector;
13 import java.util.jar.JarEntry;
14 import java.util.jar.JarFile;
15 import java.util.jar.JarInputStream;
16 import java.util.jar.JarOutputStream;
17 import java.util.zip.ZipEntry;
18 import java.util.zip.ZipInputStream;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.vamsas.objects.utils.document.VersionEntries;
24 * Basic methods for accessing an existing Vamsas Archive,
25 * and Jar entry names for creating new vamsas archives.
30 public class VamsasArchiveReader {
31 private static Log log = LogFactory.getLog(VamsasArchiveReader.class);
33 boolean stream=false; // true if we are seeking on the stream.
34 RandomAccessFile rfile;
35 ZipInputStream jstream=null;
36 Hashtable strmentries = null;
37 private void streamInit() {
39 log.debug("Skipping init for Jar Stream input.");
42 strmentries = new Hashtable();
43 log.debug("Jar Stream input Initialisation");
46 // no buffering - we need to be able to move around the random access stream.
47 jstream = new ZipInputStream(new FileInputStream(rfile.getFD())); // no manifest (probably)
48 if (jstream.available()==0)
49 log.warn("Can't read from JarInputStream (Locked stream!)");
52 long pos = rfile.getFilePointer();
53 if ((entry=jstream.getNextEntry())!=null) {
54 if (strmentries.containsKey(entry.getName())) {
55 log.info("Only recording last of duplicate entries '"+entry.getName()+"'");
57 strmentries.put(entry.getName(), new Long(pos));
60 } while (entry!=null);
63 log.warn("Exceptions during init!",e);
68 public VamsasArchiveReader(File vamsasfile) {
70 if (vamsasfile.exists()) {
72 jfile=new JarFile(vamsasfile);
75 log.debug("non-serious? couldn't open new JarFile on "+vamsasfile,e);
82 * in an ideal world - this constructor will create a reader object
83 * for the locked file's random access stream.
87 public VamsasArchiveReader(Lock vamsaslock) {
88 rfile = vamsaslock.rafile;
92 throw new Error("Failed to open archive from Locked random access stream.");
96 * the vamsas document version(s) handled by this Reader
98 final public static String DOCUMENT_VERSION=VersionEntries.BETA_VERSION;
100 * name of the jarEntry containing a well formatted vamsas XML Document
103 final public static String VAMSASDOC="vamsasDocument.xml";
106 * name of the jarEntry containing a root VAMSAS element, and containing a
107 * random sequence of VAMSAS DataSet elements
110 final public static String VAMSASXML="vamsas.xml";
112 * seeks jstream to the given entry name and reads it.
116 private JarEntry seekEntry(String entryname) {
119 if (!strmentries.containsKey(entryname))
121 Long entrypos = (Long) strmentries.get(entryname);
122 if (entrypos==null) {
123 log.error("Null entry position for "+entryname);
128 ZipEntry entry = null;
129 long epos = entrypos.longValue();
131 entry = jstream.getNextEntry();
132 } while (entry!=null && epos-->0);
133 // rfile.seek(entrypos.longValue());
134 // make a Jar entry from a zip entry.
135 return new JarEntry(entry);
137 catch (Exception e) {
138 log.warn("Whilst seeking for "+entryname, e);
144 * @return JarEntry for VamsasArchiveReader.VAMSASDOC
146 protected JarEntry getVamsasDocumentEntry() {
147 return getJarEntry(VAMSASDOC);
151 * @return JarEntry for VamsasArchiveReader.VAMSASXML
153 protected JarEntry getVamsasXmlEntry() {
154 return getJarEntry(VAMSASXML);
157 * Test for valid vamsas document archive
158 * @return true if getVamsasDocumentStream will return a stream likely to contain valid XML
160 public boolean isValid() {
161 // 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
162 if (jfile!=null || jstream!=null)
163 return (getVamsasDocumentEntry()!=null);
168 protected JarEntry getAppdataEntry(String AppdataRef) {
170 if ((jfile==null && jstream==null) || !isValid() || (entry=getJarEntry(AppdataRef))==null)
176 public InputStream getAppdataStream(String AppdataRef) {
177 JarEntry entry=getAppdataEntry(AppdataRef);
180 return getInputStream(entry);
181 } catch (IOException e) {
182 log.error("Failed when opening AppdataStream for "+AppdataRef, e);
187 * get the VamsasDocument input stream, if it exists.
188 * @return null or valid input stream
190 public InputStream getVamsasDocumentStream() {
192 if ((jfile==null && jstream==null) || !isValid())
195 vdoc = getInputStream(getVamsasDocumentEntry());
196 } catch (IOException e) {
197 log.error("Whilst geting document stream",e);
204 * get the VamsasXML input stream, if it exists.
205 * Note: Deprecated beyond our prealpha testing.
206 * @return null or valid input stream.
209 public InputStream getVamsasXmlStream() {
210 // log.warn("Deprecated call");
211 JarEntry xmle=getVamsasXmlEntry();
216 vdoc = getInputStream(xmle);
217 } catch (IOException e) {
218 log.error("Whilst getting VamsasXmlStream",e);
225 * silently close the jar file.
228 public void close() {
232 } catch (IOException e) {
233 log.error("Whilst closing JarFile "+jfile.getName(), e);
238 jstream.closeEntry();
240 // LATER: reference counting for random access file instances is necessary.
242 catch (Exception e) {
243 log.error("Whilst finishing reading from jar input stream",e);
249 * returns all entries not matching the filespec of a vamsas xml entry
250 * @return array of entries.
252 public Vector getExtraEntries() {
253 if ((jfile==null && jstream==null)|| !isValid())
255 Vector e = new Vector();
257 Enumeration entries = strmentries.keys();
258 if (entries!=null && entries.hasMoreElements()) {
260 JarEntry el = (JarEntry) entries.nextElement();
261 if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML))
262 e.add(new String(el.getName())); // avoid references
263 } while (entries.hasMoreElements());
266 Enumeration entries = jfile.entries();
267 if (entries!=null && entries.hasMoreElements()) {
269 JarEntry el = (JarEntry) entries.nextElement();
270 if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML))
271 e.add(new String(el.getName())); // avoid references
272 } while (entries.hasMoreElements());
280 * @see java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
282 private InputStream getInputStream(ZipEntry ze) throws IOException {
284 return jfile.getInputStream(ze);
286 seekEntry(ze.getName());
287 return new AppDataInputStream(jstream);
293 * @see java.util.jar.JarFile#getJarEntry(java.lang.String)
295 private JarEntry getJarEntry(String name) {
297 return jfile.getJarEntry(name);
299 return seekEntry(name);