X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FVamsasArchive.java;h=93c775caf209dc7e64236971585013dd10119196;hb=99cfce21cfd9e358f4f5ae628498ebad75c0b932;hp=ea11a81bf243c446ac7d5a0f7d45ed9d787a2643;hpb=ed3c3a256f9dc365f9e287eb8b05cd7930fff568;p=vamsas.git diff --git a/src/org/vamsas/client/simpleclient/VamsasArchive.java b/src/org/vamsas/client/simpleclient/VamsasArchive.java index ea11a81..93c775c 100644 --- a/src/org/vamsas/client/simpleclient/VamsasArchive.java +++ b/src/org/vamsas/client/simpleclient/VamsasArchive.java @@ -24,7 +24,7 @@ import org.vamsas.client.SessionHandle; import org.vamsas.client.UserHandle; import org.vamsas.client.VorbaIdFactory; import org.vamsas.client.VorbaXmlBinder; -import org.vamsas.client.object; +import org.vamsas.client.Vobject; import org.vamsas.objects.core.ApplicationData; import org.vamsas.objects.core.VAMSAS; import org.vamsas.objects.core.VamsasDocument; @@ -44,13 +44,78 @@ import org.vamsas.objects.utils.document.VersionEntries; public class VamsasArchive { private static Log log = LogFactory.getLog(VamsasArchive.class); /** + * Access original document if it exists, and get VAMSAS root objects. + * @return vector of vamsas roots from original document + * @throws IOException + */ + public static Vobject[] getOriginalRoots(VamsasArchive ths) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + VamsasArchiveReader oReader = ths.getOriginalArchiveReader(); + if (oReader!=null) { + + if (oReader.isValid()) { + InputStreamReader vdoc = new InputStreamReader(oReader.getVamsasDocumentStream()); + VamsasDocument doc = VamsasDocument.unmarshal(vdoc); + if (doc!=null) + return doc.getVAMSAS(); + // TODO ensure embedded appDatas are garbage collected to save memory + } else { + InputStream vxmlis = oReader.getVamsasXmlStream(); + if (vxmlis!=null) { // Might be an old vamsas file. + BufferedInputStream ixml = new BufferedInputStream(oReader.getVamsasXmlStream()); + InputStreamReader vxml = new InputStreamReader(ixml); + VAMSAS root[] = new VAMSAS[1]; + root[0] = VAMSAS.unmarshal(vxml); + if (root[0]!=null) + return root; + } + } + } + return null; + } + /** + * Access the original vamsas document for a VamsasArchive class, and return it. + * Users of the VamsasArchive class should use the getVamsasDocument method to retrieve + * the current document - only use this one if you want the 'backup' version. + * TODO: catch OutOfMemoryError - they are likely to occur here. + * NOTE: vamsas.xml datastreams are constructed as 'ALPHA_VERSION' vamsas documents. + * @param ths + * @return null if no document exists. + * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException + */ + public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return VamsasArchive.getOriginalVamsasDocument(ths, null); + } + /** + * Uses VorbaXmlBinder to retrieve the VamsasDocument from the original archive referred to by ths + * @param ths + * @param vorba + * @return + * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException + */ + public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths, VorbaIdFactory vorba) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + VamsasArchiveReader oReader = ths.getOriginalArchiveReader(); + if (oReader!=null) { + ths.setVorba(vorba); + return ths.vorba.getVamsasDocument(oReader); + } + // otherwise - there was no valid original document to read. + return null; + } + /** * destination of new archive data (tempfile if virginarchive=true, original archive location otherwise) */ java.io.File archive=null; /** * locked IO handler for new archive file */ - SessionFile rchive=null; + SessionFile rchive=null; /** * original archive file to be updated (or null if virgin) where new data will finally reside */ @@ -59,6 +124,7 @@ public class VamsasArchive { * original archive IO handler */ SessionFile odoclock = null; + Lock destinationLock = null; /** * Original archive reader class */ @@ -75,10 +141,35 @@ public class VamsasArchive { * JarEntries written to archive */ Hashtable entries = null; + /** * true if we aren't just updating an archive */ private boolean virginArchive=false; + + /** + * name of backup of existing archive that has been updated/overwritten. + * onlu one backup will be made - and this is it. + */ + File originalBackup = null; + + boolean donotdeletebackup=false; + private final int _TRANSFER_BUFFER=4096*4; + protected SimpleDocument vorba = null; + /** + * Access and return current vamsas Document, if it exists, or create a new one + * (without affecting VamsasArchive object state - so is NOT THREAD SAFE) + * TODO: possibly modify internal state to lock low-level files + * (like the IClientDocument interface instance constructer would do) + * @see org.vamsas.simpleclient.VamsasArchive.getOriginalVamsasDocument for additional caveats + * + * @return + * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException + */ + private VamsasDocument _doc=null; + /** * Create a new vamsas archive * File locks are made immediately to avoid contention @@ -88,21 +179,35 @@ public class VamsasArchive { * @throws IOException if call to accessOriginal failed for updates, or openArchive failed. */ public VamsasArchive(File archive, boolean vamsasdocument) throws IOException { - this(archive, vamsasdocument, null); + this(archive, false, vamsasdocument, null); + } + public VamsasArchive(File archive, boolean vamsasdocument, boolean overwrite) throws IOException { + this(archive, overwrite, vamsasdocument, null); } - public VamsasArchive(File archive, boolean vamsasdocument, Lock extantLock) throws IOException { + /** + * + * @param archive file to write + * @param overwrite true if original contents should be deleted + * @param vamsasdocument true if a proper VamsasDocument archive is to be written. + * @param extantLock SessionFile object holding a lock for the archive + * @throws IOException + */ + public VamsasArchive(File archive, boolean overwrite, boolean vamsasdocument, SessionFile extantLock) throws IOException { super(); - if (archive==null || (archive!=null && !(archive.getParentFile().canWrite() && (!archive.exists() || archive.canWrite())))) { log.fatal("Expect Badness! -- Invalid parameters for VamsasArchive constructor:"+((archive!=null) ? "File cannot be overwritten." : "Null Object not valid constructor parameter")); return; } + this.vamsasdocument = vamsasdocument; - if (archive.exists()) { + if (archive.exists() && !overwrite) { this.original = archive; - this.odoclock = new SessionFile(archive); // lock the file *immediatly* - odoclock.lockFile(extantLock); + if (extantLock!=null) + this.odoclock = extantLock; + 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; try { @@ -113,101 +218,31 @@ public class VamsasArchive { } else { this.original = null; this.archive = archive; // archive is written in place. - if (archive!=null) { - archive.createNewFile(); - rchive=new SessionFile(archive); // lock the file *immediatly* - rchive.lockFile(extantLock); - } + if (extantLock!=null) + rchive=extantLock; + else + rchive = new SessionFile(archive); + rchive.lockFile(); + rchive.fileLock.rafile.setLength(0); // empty the archive. virginArchive = true; } this.openArchive(); // open archive } /** - * name of backup of existing archive that has been updated/overwritten. - * onlu one backup will be made - and this is it. - */ - File originalBackup = null; - - private void makeBackup() { - if (!virginArchive) { - if (originalBackup==null && original!=null && original.exists()) { - try { - accessOriginal(); - originalBackup = odoclock.backupSessionFile(null, original.getName(), ".bak", original.getParentFile()); - } - catch (IOException e) { - log.warn("Problem whilst making a backup of original archive.",e); - } - } - } - } - - /** - * called after archive is written to put file in its final place - */ - private void updateOriginal() { - if (!virginArchive) { - // make sure original document really is backed up and then overwrite it. - if (odoc!=null) { - // try to shut the odoc reader. - odoc.close(); - odoc = null; - } - // Make a backup if it isn't done already - makeBackup(); - try { - // copy new Archive data that was writen to a temporary file - odoclock.updateFrom(null, rchive); - } - catch (IOException e) { - // TODO: LATER: decide if leaving nastily named backup files around is necessary. - log.error("Problem updating archive from temporary file! - backup left in '" - +backupFile().getAbsolutePath()+"'",e); - } - // Tidy up if necessary. - removeBackup(); - } else { - - } - } - boolean donotdeletebackup=false; - /** - * called by app to get name of backup if it was made. - * If this is called, the caller app *must* delete the backup themselves. - * @return null or a valid file object + * open original archive file for exclusive (locked) reading. + * @throws IOException */ - public File backupFile() { - - if (!virginArchive) { - makeBackup(); - donotdeletebackup=false; // external reference has been made. - return ((original!=null) ? originalBackup : null); + private void accessOriginal() throws IOException { + if (original!=null && original.exists()) { + if (odoclock==null) + odoclock = new SessionFile(original); + odoclock.lockFile(); + if (odoc == null) + odoc = new VamsasArchiveReader(original); } - return null; - } - /** - * - * @return JarEntry name for the vamsas XML stream in this archive - */ - protected String getDocumentJarEntry() { - if (vamsasdocument) - return VamsasArchiveReader.VAMSASDOC; - return VamsasArchiveReader.VAMSASXML; } /** - * @return true if Vamsas Document has been written to archive - */ - protected boolean isDocumentWritten() { - if (newarchive==null) - log.warn("isDocumentWritten() called for unopened archive."); - if (entries!=null) { - if (entries.containsKey(getDocumentJarEntry())) - return true; - } - return false; - } - /** * Add unique entry strings to internal JarEntries list. * @param entry * @return true if entry was unique and was added. @@ -233,72 +268,17 @@ public class VamsasArchive { newarchive.putNextEntry(je); return true; } - /** - * opens the new archive ready for writing. If the new archive is replacing an existing one, - * then the existing archive will be locked, and the new archive written to a temporary file. - * The new archive will be put in place once close() is called. - * @param doclock TODO - * @throws IOException + * called by app to get name of backup if it was made. + * If this is called, the caller app *must* delete the backup themselves. + * @return null or a valid file object */ - private void openArchive() throws IOException { + public File backupFile() { - if (newarchive!=null) { - log.warn("openArchive() called multiple times."); - throw new IOException("Vamsas Archive '"+archive.getAbsolutePath()+"' is already open."); - } - if (archive==null && (virginArchive || original==null)) { - log.warn("openArchive called on uninitialised VamsasArchive object."); - throw new IOException("Badly initialised VamsasArchive object - no archive file specified."); - } if (!virginArchive) { - // lock the original - accessOriginal(); - // make a temporary file to write to - archive = File.createTempFile(original.getName(), ".new",original.getParentFile()); - } else { - if (archive.exists()) - log.warn("New archive file name already in use! Possible lock failure imminent?"); - } - - if (rchive==null) - rchive = new SessionFile(archive); - if (!rchive.lockFile()) - throw new IOException("Failed to get lock on file "+archive); - newarchive = new JarOutputStream(new BufferedOutputStream(new java.io.FileOutputStream(archive))); - entries = new Hashtable(); - } - /** - * Safely initializes the VAMSAS XML document Jar Entry. - * @return Writer to pass to the marshalling function. - * @throws IOException if a document entry has already been written. - */ - public PrintWriter getDocumentOutputStream() throws IOException { - if (newarchive==null) - openArchive(); - if (!isDocumentWritten()) { - try { - if (addValidEntry(getDocumentJarEntry())) - return new PrintWriter(new java.io.OutputStreamWriter(newarchive, "UTF-8")); - } catch (Exception e) { - log.warn("Problems opening XML document JarEntry stream",e); - } - } else { - throw new IOException("Vamsas Document output stream is already written."); - } - return null; - } - /** - * Opens and returns the applicationData output stream for the appdataReference string. - * @param appdataReference - * @return Output stream to write to - * @throws IOException - */ - public AppDataOutputStream getAppDataStream(String appdataReference) throws IOException { - if (newarchive==null) - throw new IOException("Attempt to write to closed VamsasArchive object."); - if (addValidEntry(appdataReference)) { - return new AppDataOutputStream(newarchive); + makeBackup(); + donotdeletebackup=false; // external reference has been made. + return ((original!=null) ? originalBackup : null); } return null; } @@ -334,37 +314,6 @@ public class VamsasArchive { } /** - * recovers the original file's contents from the (temporary) backup. - * @throws Exception if any SessionFile or file removal operations fail. - */ - private void recoverBackup() throws Exception { - if (originalBackup!=null) { - // backup has been made. - // revert from backup and delete it (changing backup filename) - if (rchive==null) { - rchive = new SessionFile(original); - } - SessionFile bckup = new SessionFile(originalBackup); - - rchive.updateFrom(null, bckup); // recover from backup file. - bckup.unlockFile(); - bckup=null; - removeBackup(); - } - } - /** - * forget about any backup that was made - removing it first if it was only temporary. - */ - private void removeBackup() { - if (originalBackup!=null) { - log.debug("Removing backup in "+originalBackup.getAbsolutePath()); - if (!donotdeletebackup) - if (!originalBackup.delete()) - log.info("VamsasArchive couldn't remove temporary backup "+originalBackup.getAbsolutePath()); - originalBackup=null; - } - } - /** * only do this if you want to destroy the current file output stream * */ @@ -390,23 +339,254 @@ public class VamsasArchive { original=null; entries=null; } + /** + * Tidies up and closes archive, removing any backups that were created. + * NOTE: It is up to the caller to delete the original archive backup obtained from backupFile() + * TODO: ensure all extant AppDataReference jar entries are transferred to new Jar + * TODO: provide convenient mechanism for generating new unique AppDataReferences and adding them to the document + */ + public void closeArchive() throws IOException { + if (newarchive!=null) { + newarchive.closeEntry(); + if (!isDocumentWritten()) + log.warn("Premature closure of archive '"+archive.getAbsolutePath()+"': No document has been written."); + newarchive.close(); + updateOriginal(); + closeAndReset(); + } else { + log.warn("Attempt to close archive that has not been opened for writing."); + } + } + /** + * Opens and returns the applicationData output stream for the appdataReference string. + * @param appdataReference + * @return Output stream to write to + * @throws IOException + */ + public AppDataOutputStream getAppDataStream(String appdataReference) throws IOException { + if (newarchive==null) + throw new IOException("Attempt to write to closed VamsasArchive object."); + if (addValidEntry(appdataReference)) { + return new AppDataOutputStream(newarchive); + } + return null; + } - private final int _TRANSFER_BUFFER=4096*4; /** - * open original archive file for exclusive (locked) reading. + * + * @return JarEntry name for the vamsas XML stream in this archive + */ + protected String getDocumentJarEntry() { + if (vamsasdocument) + return VamsasArchiveReader.VAMSASDOC; + return VamsasArchiveReader.VAMSASXML; + } + /** + * Safely initializes the VAMSAS XML document Jar Entry. + * @return Writer to pass to the marshalling function. + * @throws IOException if a document entry has already been written. + */ + public PrintWriter getDocumentOutputStream() throws IOException { + if (newarchive==null) + openArchive(); + if (!isDocumentWritten()) { + try { + if (addValidEntry(getDocumentJarEntry())) + return new PrintWriter(new java.io.OutputStreamWriter(newarchive, "UTF-8")); + } catch (Exception e) { + log.warn("Problems opening XML document JarEntry stream",e); + } + } else { + throw new IOException("Vamsas Document output stream is already written."); + } + return null; + } + + /** + * Access original archive if it exists, pass the reader to the client + * Note: this is NOT thread safe and a call to closeArchive() will by necessity + * close and invalidate the VamsasArchiveReader object. + * @return null if no original archive exists. + */ + public VamsasArchiveReader getOriginalArchiveReader() throws IOException { + if (!virginArchive) { + accessOriginal(); + return odoc; + } + return null; + } + /** + * returns original document's root vamsas elements. + * @return + * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException + */ + public Vobject[] getOriginalRoots() throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return VamsasArchive.getOriginalRoots(this); + } + /** + * @return original document or a new empty document (with default provenance) * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException */ - private void accessOriginal() throws IOException { - if (original!=null && original.exists()) { - if (odoclock==null) - odoclock = new SessionFile(original); - odoclock.lockFile(); - if (odoc == null) - odoc = new VamsasArchiveReader(original); + public VamsasDocument getVamsasDocument() throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return getVamsasDocument("org.vamsas.simpleclient.VamsasArchive", "Created new empty document", null); + } + /** + * Return the original document or a new empty document with initial provenance entry. + * @param provenance_user (null sets user to be the class name) + * @param provenance_action (null sets action to be 'created new document') + * @param version (null means use latest version) + * @return (original document or a new vamsas document with supplied provenance and version info) + * @throws IOException + * @throws org.exolab.castor.xml.MarshalException + * @throws org.exolab.castor.xml.ValidationException + */ + public VamsasDocument getVamsasDocument(String provenance_user, String provenance_action, String version) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + if (_doc!=null) + return _doc; + _doc = getOriginalVamsasDocument(this, getVorba()); + if (_doc!=null) + return _doc; + // validate parameters + if (provenance_user==null) + provenance_user = "org.vamsas.simpleclient.VamsasArchive"; + if (provenance_action == null) + provenance_action="Created new empty document"; + if (version==null) + version = VersionEntries.latestVersion(); + // Create a new document and return it + _doc = DocumentStuff.newVamsasDocument(new VAMSAS[] { new VAMSAS()}, + ProvenanceStuff.newProvenance(provenance_user, provenance_action), version); + return _doc; + } + /** + * @return Returns the current VorbaIdFactory for the archive. + */ + public VorbaIdFactory getVorba() { + if (vorba==null) + vorba = new SimpleDocument("simpleclient.VamsasArchive"); + return vorba.getVorba(); + } + /** + * @return true if Vamsas Document has been written to archive + */ + protected boolean isDocumentWritten() { + if (newarchive==null) + log.warn("isDocumentWritten() called for unopened archive."); + if (entries!=null) { + if (entries.containsKey(getDocumentJarEntry())) + return true; + } + return false; + } + private void makeBackup() { + if (!virginArchive) { + if (originalBackup==null && original!=null && original.exists()) { + try { + accessOriginal(); + originalBackup = odoclock.backupSessionFile(null, original.getName(), ".bak", original.getParentFile()); + } + catch (IOException e) { + log.warn("Problem whilst making a backup of original archive.",e); + } + } + } + } + /** + * opens the new archive ready for writing. If the new archive is replacing an existing one, + * then the existing archive will be locked, and the new archive written to a temporary file. + * The new archive will be put in place once close() is called. + * @param doclock TODO + * @throws IOException + */ + private void openArchive() throws IOException { + + if (newarchive!=null) { + log.warn("openArchive() called multiple times."); + throw new IOException("Vamsas Archive '"+archive.getAbsolutePath()+"' is already open."); + } + if (archive==null && (virginArchive || original==null)) { + log.warn("openArchive called on uninitialised VamsasArchive object."); + throw new IOException("Badly initialised VamsasArchive object - no archive file specified."); + } + if (!virginArchive) { + // lock the original + accessOriginal(); + // make a temporary file to write to + archive = File.createTempFile(original.getName(), ".new",original.getParentFile()); + } else { + if (archive.exists()) + log.warn("New archive file name already in use! Possible lock failure imminent?"); + } + + if (rchive==null) + rchive = new SessionFile(archive); + if (!rchive.lockFile()) + throw new IOException("Failed to get lock on file "+archive); + newarchive = new JarOutputStream(new BufferedOutputStream(new java.io.FileOutputStream(archive))); + entries = new Hashtable(); + } + public void putVamsasDocument(VamsasDocument doc) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + putVamsasDocument(doc, getVorba()); + } + + public void putVamsasDocument(VamsasDocument doc, VorbaIdFactory vorba) throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + VorbaXmlBinder.putVamsasDocument(getDocumentOutputStream(), vorba, doc); + } + + /** + * recovers the original file's contents from the (temporary) backup. + * @throws Exception if any SessionFile or file removal operations fail. + */ + private void recoverBackup() throws Exception { + if (originalBackup!=null) { + // backup has been made. + // revert from backup and delete it (changing backup filename) + if (rchive==null) { + rchive = new SessionFile(original); + } + SessionFile bckup = new SessionFile(originalBackup); + + rchive.updateFrom(null, bckup); // recover from backup file. + bckup.unlockFile(); + bckup=null; + removeBackup(); } } /** + * forget about any backup that was made - removing it first if it was only temporary. + */ + private void removeBackup() { + if (originalBackup!=null) { + log.debug("Removing backup in "+originalBackup.getAbsolutePath()); + if (!donotdeletebackup) + if (!originalBackup.delete()) + log.info("VamsasArchive couldn't remove temporary backup "+originalBackup.getAbsolutePath()); + originalBackup=null; + } + } + /** + * @param vorba the VorbaIdFactory to use for accessing vamsas objects. + */ + public void setVorba(VorbaIdFactory Vorba) { + if (Vorba!=null) { + if (vorba==null) + vorba = new SimpleDocument(Vorba); + else + vorba.setVorba(Vorba); + } else + getVorba(); + } + /** * Convenience method to copy over the referred entry from the backup to the new version. * Warning messages are raised if no backup exists or the * entry doesn't exist in the backed-up original. @@ -418,6 +598,7 @@ public class VamsasArchive { public boolean transferAppDataEntry(String AppDataReference) throws IOException { return transferAppDataEntry(AppDataReference, AppDataReference); } + /** * Transfers an AppDataReference from old to new vamsas archive, with a name change. * @see transferAppDataEntry(String AppDataReference) @@ -464,6 +645,7 @@ public class VamsasArchive { +AppDataReference+"' as '"+NewAppDataReference+"' ("+count+" bytes)"); return true; } + /** * transfers any AppDataReferences existing in the old document * that haven't already been transferred to the new one @@ -499,170 +681,31 @@ public class VamsasArchive { return transfered; } /** - * Tidies up and closes archive, removing any backups that were created. - * NOTE: It is up to the caller to delete the original archive backup obtained from backupFile() - * TODO: ensure all extant AppDataReference jar entries are transferred to new Jar - * TODO: provide convenient mechanism for generating new unique AppDataReferences and adding them to the document - */ - public void closeArchive() throws IOException { - if (newarchive!=null) { - newarchive.closeEntry(); - if (!isDocumentWritten()) - log.warn("Premature closure of archive '"+archive.getAbsolutePath()+"': No document has been written."); - newarchive.close(); - updateOriginal(); - closeAndReset(); - } else { - log.warn("Attempt to close archive that has not been opened for writing."); - } - } - /** - * Access original archive if it exists, pass the reader to the client - * Note: this is NOT thread safe and a call to closeArchive() will by necessity - * close and invalidate the VamsasArchiveReader object. - * @return null if no original archive exists. + * called after archive is written to put file in its final place */ - public VamsasArchiveReader getOriginalArchiveReader() throws IOException { + private void updateOriginal() { if (!virginArchive) { - accessOriginal(); - return odoc; - } - return null; - } - /** - * returns original document's root vamsas elements. - * @return - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public object[] getOriginalRoots() throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - return VamsasArchive.getOriginalRoots(this); - } - /** - * Access original document if it exists, and get VAMSAS root objects. - * @return vector of vamsas roots from original document - * @throws IOException - */ - public static object[] getOriginalRoots(VamsasArchive ths) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - VamsasArchiveReader oReader = ths.getOriginalArchiveReader(); - if (oReader!=null) { - - if (oReader.isValid()) { - InputStreamReader vdoc = new InputStreamReader(oReader.getVamsasDocumentStream()); - VamsasDocument doc = VamsasDocument.unmarshal(vdoc); - if (doc!=null) - return doc.getVAMSAS(); - // TODO ensure embedded appDatas are garbage collected to save memory - } else { - InputStream vxmlis = oReader.getVamsasXmlStream(); - if (vxmlis!=null) { // Might be an old vamsas file. - BufferedInputStream ixml = new BufferedInputStream(oReader.getVamsasXmlStream()); - InputStreamReader vxml = new InputStreamReader(ixml); - VAMSAS root[] = new VAMSAS[1]; - root[0] = VAMSAS.unmarshal(vxml); - if (root[0]!=null) - return root; - } + // make sure original document really is backed up and then overwrite it. + if (odoc!=null) { + // try to shut the odoc reader. + odoc.close(); + odoc = null; } + // Make a backup if it isn't done already + makeBackup(); + try { + // copy new Archive data that was writen to a temporary file + odoclock.updateFrom(null, rchive); + } + catch (IOException e) { + // TODO: LATER: decide if leaving nastily named backup files around is necessary. + log.error("Problem updating archive from temporary file! - backup left in '" + +backupFile().getAbsolutePath()+"'",e); + } + // Tidy up if necessary. + removeBackup(); + } else { + } - return null; - } - protected SimpleDocument vorba = null; - - /** - * @return Returns the current VorbaIdFactory for the archive. - */ - public VorbaIdFactory getVorba() { - if (vorba==null) - vorba = new SimpleDocument("simpleclient.VamsasArchive"); - return vorba.getVorba(); - } - - /** - * @param vorba the VorbaIdFactory to use for accessing vamsas objects. - */ - public void setVorba(VorbaIdFactory Vorba) { - if (Vorba!=null) { - if (vorba==null) - vorba = new SimpleDocument(Vorba); - else - vorba.setVorba(Vorba); - } else - getVorba(); - } - - /** - * Access and return current vamsas Document, if it exists, or create a new one - * (without affecting VamsasArchive object state - so is NOT THREAD SAFE) - * TODO: possibly modify internal state to lock low-level files - * (like the IClientDocument interface instance constructer would do) - * @see org.vamsas.simpleclient.VamsasArchive.getOriginalVamsasDocument for additional caveats - * - * @return - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - private VamsasDocument _doc=null; - public VamsasDocument getVamsasDocument() throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - if (_doc!=null) - return _doc; - _doc = getOriginalVamsasDocument(this, getVorba()); - if (_doc!=null) - return _doc; - // Create a new document and return it - _doc = DocumentStuff.newVamsasDocument(new VAMSAS[] { new VAMSAS()}, - ProvenanceStuff.newProvenance("org.vamsas.simpleclient.VamsasArchive", "Created new empty document") - , VersionEntries.latestVersion()); - return _doc; - } - /** - * Access the original vamsas document for a VamsasArchive class, and return it. - * Users of the VamsasArchive class should use the getVamsasDocument method to retrieve - * the current document - only use this one if you want the 'backup' version. - * TODO: catch OutOfMemoryError - they are likely to occur here. - * NOTE: vamsas.xml datastreams are constructed as 'ALPHA_VERSION' vamsas documents. - * @param ths - * @return null if no document exists. - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - return VamsasArchive.getOriginalVamsasDocument(ths, null); - } - - /** - * Uses VorbaXmlBinder to retrieve the VamsasDocument from the original archive referred to by ths - * @param ths - * @param vorba - * @return - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths, VorbaIdFactory vorba) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - VamsasArchiveReader oReader = ths.getOriginalArchiveReader(); - if (oReader!=null) { - ths.setVorba(vorba); - return ths.vorba.getVamsasDocument(oReader); - } - // otherwise - there was no valid original document to read. - return null; - } - - public void putVamsasDocument(VamsasDocument doc) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - putVamsasDocument(doc, getVorba()); - } - public void putVamsasDocument(VamsasDocument doc, VorbaIdFactory vorba) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - VorbaXmlBinder.putVamsasDocument(getDocumentOutputStream(), vorba, doc); } }