package org.vamsas.client.simpleclient;
+import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
-import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.vamsas.client.object;
+import org.vamsas.objects.core.VAMSAS;
+import org.vamsas.objects.core.VamsasDocument;
/**
* Class for creating a vamsas archive
virginArchive=false;
} else {
this.original = null;
- this.archive = archive;
+ this.archive = archive; // archive is written in place.
virginArchive = true;
}
}
if (!virginArchive) {
if (originalBackup==null && original!=null && original.exists()) {
try {
- accessBackup();
+ accessOriginal();
originalBackup = odoclock.backupSessionFile(null, original.getName(), ".bak", original.getParentFile());
- // rchive.fileLock.rafile.getChannel().truncate(0);
}
catch (IOException e) {
log.warn("Problem whilst making a backup of original archive.",e);
private void updateOriginal() {
if (original!=null) {
if (!virginArchive) {
+ if (odoc!=null) {
+ odoc.close();
+ odoc=null;
+ }
if (!archive.getAbsolutePath().equals(original)) {
if (originalBackup==null)
makeBackup();
catch (IOException e) {
log.error("Problem updating archive from temporary file!",e);
}
+ } else {
+ log.warn("archive and original are the same file! ("+archive.getAbsolutePath()+")");
}
- } else {
- archive.renameTo(original);
- }
+ } // else virginArchive are put in correct place from the beginning
+
}
}
/**
*/
public File backupFile() {
- if (virginArchive) {
+ if (!virginArchive) {
makeBackup();
return ((original==null) ? originalBackup : null);
return VamsasArchiveReader.VAMSASDOC;
return VamsasArchiveReader.VAMSASXML;
}
+
/**
* @return true if Vamsas Document has been written to archive
*/
return true;
}
- File tempoutput = null;
- SessionFile trchive = null;
+ /**
+ * 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.
+ * @throws IOException
+ */
private void openArchive() throws IOException {
if (newarchive!=null) {
throw new IOException("Badly initialised VamsasArchive object - no archive file specified.");
}
// lock the original
- accessBackup();
- // make a temporary file to write to
- archive = File.createTempFile(original.getName(), "new");
-
+ accessOriginal();
+ // make a temporary file to write to
+ archive = File.createTempFile(original.getName(), "new",original.getParentFile());
}
rchive = new SessionFile(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.
}
/**
* Opens and returns the applicationData output stream for the appdataReference string.
- * TODO: Make a wrapper class to catch calls to OutputStream.close() which normally close the Jar output stream.
* @param appdataReference
* @return Output stream to write to
* @throws IOException
*/
- public OutputStream getAppDataStream(String appdataReference) throws IOException {
+ public AppDataOutputStream getAppDataStream(String appdataReference) throws IOException {
if (newarchive!=null)
openArchive();
if (addValidEntry(appdataReference)) {
- return new DataOutputStream(newarchive);
+ return new AppDataOutputStream(newarchive);
}
return null;
}
* open backup for exclusive (locked) reading.
* @throws IOException
*/
- private void accessBackup() throws IOException {
+ private void accessOriginal() throws IOException {
if (original!=null && original.exists()) {
if (odoclock==null)
odoclock = new SessionFile(original);
* @throws IOException
*/
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)
+ * @param AppDataReference
+ * @param NewAppDataReference - AppDataReference in new Archive
+ * @return
+ * @throws IOException
+ */
+ public boolean transferAppDataEntry(String AppDataReference, String NewAppDataReference) throws IOException {
// TODO: Specify valid AppDataReference form in all VamsasArchive handlers
if (AppDataReference==null)
- throw new IOException("Invalid AppData Reference!");
+ throw new IOException("null AppDataReference!");
if (original==null || !original.exists()) {
log.warn("No backup archive exists.");
return false;
}
- if (entries.containsKey(AppDataReference)) {
- log.warn("Attempt to write '"+AppDataReference+"' twice! - IGNORED");
+ if (entries.containsKey(NewAppDataReference)) {
+ log.warn("Attempt to write '"+NewAppDataReference+"' twice! - IGNORED");
return true;
}
- accessBackup();
+ accessOriginal();
java.io.InputStream adstream = odoc.getAppdataStream(AppDataReference);
return false;
}
- java.io.OutputStream adout = getAppDataStream(AppDataReference);
+ java.io.OutputStream adout = getAppDataStream(NewAppDataReference);
// copy over the bytes
int written=-1;
long count=0;
count+=written;
}
} while (written>-1);
- log.debug("Sucessfully transferred AppData for "+AppDataReference+" ("+count+" bytes)");
+ log.debug("Sucessfully transferred AppData for '"
+ +AppDataReference+"' as '"+NewAppDataReference+"' ("+count+" bytes)");
return true;
}
-
/**
* 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()
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.
+ */
+ public VamsasArchiveReader getOriginalArchiveReader() throws IOException {
+ if (!virginArchive) {
+ accessOriginal();
+ return odoc;
+ }
+ return null;
+ }
+
+ /**
+ * 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();
+
+ } 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;
+ }
+
}