From 6c5cb4f0a004422ee6a73fcbd5f54ff6cc89ab05 Mon Sep 17 00:00:00 2001 From: jprocter Date: Sun, 15 Jan 2006 17:58:15 +0000 Subject: [PATCH] debugging. git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@132 be28352e-c001-0410-b1a7-c7978e42abec --- .../vamsas/client/simpleclient/SessionFile.java | 2 +- .../vamsas/client/simpleclient/VamsasArchive.java | 203 ++++++++++++++------ 2 files changed, 148 insertions(+), 57 deletions(-) diff --git a/src/org/vamsas/client/simpleclient/SessionFile.java b/src/org/vamsas/client/simpleclient/SessionFile.java index b73a47f..30abd99 100644 --- a/src/org/vamsas/client/simpleclient/SessionFile.java +++ b/src/org/vamsas/client/simpleclient/SessionFile.java @@ -112,7 +112,7 @@ public class SessionFile { log.debug("Updating "+sessionFile.getAbsolutePath()+" from "+newData.sessionFile.getAbsolutePath()); if (newData==null) throw new IOException("Null newData object."); - if (newData.sessionFile!=null) + if (newData.sessionFile==null) throw new IOException("Null SessionFile in newData."); lockFile(extantLock); diff --git a/src/org/vamsas/client/simpleclient/VamsasArchive.java b/src/org/vamsas/client/simpleclient/VamsasArchive.java index dcd0f54..fab9ef2 100644 --- a/src/org/vamsas/client/simpleclient/VamsasArchive.java +++ b/src/org/vamsas/client/simpleclient/VamsasArchive.java @@ -18,10 +18,13 @@ import org.vamsas.client.object; import org.vamsas.objects.core.ApplicationData; import org.vamsas.objects.core.VAMSAS; import org.vamsas.objects.core.VamsasDocument; +import org.vamsas.objects.utils.DocumentStuff; +import org.vamsas.objects.utils.ProvenanceStuff; +import org.vamsas.objects.utils.document.VersionEntries; /** - * Class for creating a vamsas archive - * (with backups) + * Class for high-level io and Jar manipulation involved in creating + * or updating a vamsas archive (with backups). * Writes to a temporary file and then swaps new file for backup. * uses the sessionFile locking mechanism for safe I/O * @author jimp @@ -30,7 +33,7 @@ import org.vamsas.objects.core.VamsasDocument; public class VamsasArchive { private static Log log = LogFactory.getLog(VamsasArchive.class); /** - * destination of new archive data + * destination of new archive data (tempfile if virginarchive=true, original archive location otherwise) */ java.io.File archive=null; /** @@ -38,7 +41,7 @@ public class VamsasArchive { */ SessionFile rchive=null; /** - * original archive file that is to be updated + * original archive file to be updated (or null if virgin) where new data will finally reside */ java.io.File original=null; /** @@ -67,13 +70,15 @@ public class VamsasArchive { private boolean virginArchive=false; /** * Create a new vamsas archive - * nb. No file locks are made until open() is called. + * File locks are made immediately to avoid contention + * * @param archive - file spec for new vamsas archive * @param vamsasdocument true if archive is to be a fully fledged vamsas document archive + * @throws IOException if call to accessOriginal failed for updates, or openArchive failed. */ - public VamsasArchive(File archive, boolean vamsasdocument) { + public VamsasArchive(File archive, boolean vamsasdocument) throws IOException { super(); - if (archive==null || (archive!=null && archive.canWrite())) { + if (archive==null || (archive!=null && !archive.canWrite())) { log.fatal("Invalid parameters for VamsasArchive constructor:"+((archive!=null) ? "File cannot be overwritten." : "Null Object not valid constructor parameter")); } @@ -82,14 +87,21 @@ public class VamsasArchive { this.original = archive; this.archive = null; // archive will be a temp file when the open method is called virginArchive=false; + try { + this.accessOriginal(); + } catch (IOException e) { + throw new IOException("Lock failed for existing archive"+archive); + } } else { this.original = null; this.archive = archive; // archive is written in place. virginArchive = true; } + this.openArchive(); } /** * name of backup of existing archive that has been updated/overwritten. + * onlu one backup will be made - and this is it. */ File originalBackup = null; @@ -106,31 +118,32 @@ public class VamsasArchive { } } } + /** * called after archive is written to put file in its final place - * TODO: FINISH original should have sessionFile, and archive should also have sessionFile + * TODO: FINISH ?? original should have sessionFile, and archive should also have sessionFile */ private void updateOriginal() { - if (original!=null) { - if (!virginArchive) { + 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; + odoc = null; } - if (!archive.getAbsolutePath().equals(original)) { - if (originalBackup==null) - makeBackup(); - try { - odoclock.updateFrom(null, rchive); - } - catch (IOException e) { - log.error("Problem updating archive from temporary file!",e); - } - } else { - log.warn("archive and original are the same file! ("+archive.getAbsolutePath()+")"); + // Make a backup if it isn't done already + if (originalBackup==null) + makeBackup(); + try { + // copy new Archive data that was writen to a temporary file + odoclock.updateFrom(null, rchive); } - } // else virginArchive are put in correct place from the beginning - + catch (IOException e) { + log.error("Problem updating archive from temporary file! - backup in '" + +backupFile().getAbsolutePath()+"'",e); + } + } else { + // don't need to do anything. } } /** @@ -141,12 +154,15 @@ public class VamsasArchive { if (!virginArchive) { makeBackup(); - return ((original==null) ? originalBackup : null); - + return ((original!=null) ? originalBackup : null); + } return null; } - + /** + * + * @return JarEntry name for the vamsas XML stream in this archive + */ protected String getDocumentJarEntry() { if (vamsasdocument) return VamsasArchiveReader.VAMSASDOC; @@ -161,7 +177,7 @@ public class VamsasArchive { log.warn("isDocumentWritten called for unopened archive."); if (entries!=null) { if (entries.containsKey(getDocumentJarEntry())) - return true; + return true; } return false; } @@ -204,16 +220,18 @@ public class VamsasArchive { log.warn("openArchive() called multiple times."); throw new IOException("Vamsas Archive '"+archive.getAbsolutePath()+"' is already open."); } - - if (archive==null) { - if (original==null) { - log.warn("openArchive called on uninitialised VamsasArchive object."); - throw new IOException("Badly initialised VamsasArchive object - no archive file specified."); - } + 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()); + 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?"); } rchive = new SessionFile(archive); @@ -264,6 +282,7 @@ public class VamsasArchive { if (newarchive!=null) { try { newarchive.close(); + } catch (Exception e) {}; if (!virginArchive) { // then there is something to recover. @@ -275,21 +294,23 @@ public class VamsasArchive { } SessionFile bckup = new SessionFile(originalBackup); - try { - rchive.updateFrom(null,bckup); // recover from backup file. - bckup.unlockFile(); - bckup=null; - originalBackup.delete(); - } - catch (Exception e) { - log.warn("Problems when trying to cancel Archive "+archive.getAbsolutePath(), e); - return false; - } + try { + rchive.updateFrom(null, bckup); // recover from backup file. + bckup.unlockFile(); + bckup=null; + originalBackup.delete(); + originalBackup=null; + } + catch (Exception e) { + log.warn("Problems when trying to cancel Archive "+archive.getAbsolutePath(), e); + return false; + } } // original is untouched // just delete temp files - } + + } } else { log.info("cancelArchive called before archive("+original.getAbsolutePath()+") has been opened!"); } @@ -302,14 +323,17 @@ public class VamsasArchive { * */ private void closeAndReset() { - rchive.unlockFile(); - rchive = null; + if (rchive!=null) { + rchive.unlockFile(); + rchive = null; + } if (original!=null) { if (odoc!=null) { odoc.close(); odoc=null; } - archive.delete(); + if (archive!=null) + archive.delete(); if (odoclock!=null) { odoclock.unlockFile(); odoclock = null; @@ -319,10 +343,10 @@ public class VamsasArchive { original=null; entries=null; } - + private final int _TRANSFER_BUFFER=4096*4; /** - * open backup for exclusive (locked) reading. + * open original archive file for exclusive (locked) reading. * @throws IOException */ private void accessOriginal() throws IOException { @@ -334,7 +358,7 @@ public class VamsasArchive { odoc = new VamsasArchiveReader(original); } } - + /** * 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 @@ -439,7 +463,7 @@ public class VamsasArchive { * @throws IOException */ public static object[] getOriginalRoots(VamsasArchive ths) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { VamsasArchiveReader oReader = ths.getOriginalArchiveReader(); if (oReader!=null) { @@ -448,7 +472,7 @@ public class VamsasArchive { VamsasDocument doc = VamsasDocument.unmarshal(vdoc); if (doc!=null) return doc.getVAMSAS(); - // TODO ensure embedded appDatas are garbage collected + // TODO ensure embedded appDatas are garbage collected to save memory } else { InputStream vxmlis = oReader.getVamsasXmlStream(); if (vxmlis!=null) { // Might be an old vamsas file. @@ -463,6 +487,73 @@ public class VamsasArchive { } return 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 + */ + public VamsasDocument getVamsasDocument() throws IOException, + org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + VamsasDocument doc = getOriginalVamsasDocument(this); + 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 { + 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; + } else { + // deprecated data handler + 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) { + log.debug("Reading old format vamsas.xml into a dummy document."); + VamsasDocument doc = DocumentStuff.newVamsasDocument(root, + ProvenanceStuff.newProvenance( + "org.vamsas.simpleclient.VamsasArchive", // TODO: VAMSAS: decide on 'system' operations provenance form + "Vamsas Document constructed from vamsas.xml in " + // TODO: VAMSAS: decide on machine readable info embedding in provenance should be done + +ths.original+""), VersionEntries.ALPHA_VERSION); + root[0]=null; + root=null; + return doc; + } + } + } + } // otherwise - there was no valid original document to read. + return null; + } } -- 1.7.10.2