From 05cfd5783f5307bbcedb0b9205cebef11dae22df Mon Sep 17 00:00:00 2001 From: jprocter Date: Wed, 22 Mar 2006 14:12:54 +0000 Subject: [PATCH] finished the Appdata/ClientDocument update mechanism. Untested! git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@198 be28352e-c001-0410-b1a7-c7978e42abec --- .../vamsas/client/simpleclient/ClientDocument.java | 79 +++++++++++++------- .../vamsas/client/simpleclient/SimpleClient.java | 15 +++- .../client/simpleclient/SimpleClientAppdata.java | 53 ++++++++++--- 3 files changed, 109 insertions(+), 38 deletions(-) diff --git a/src/org/vamsas/client/simpleclient/ClientDocument.java b/src/org/vamsas/client/simpleclient/ClientDocument.java index 6b1d7fc..f89f713 100644 --- a/src/org/vamsas/client/simpleclient/ClientDocument.java +++ b/src/org/vamsas/client/simpleclient/ClientDocument.java @@ -3,6 +3,7 @@ */ package org.vamsas.client.simpleclient; +import java.io.IOException; import java.util.Vector; import org.apache.commons.logging.Log; @@ -10,9 +11,11 @@ import org.apache.commons.logging.LogFactory; import org.vamsas.client.ClientHandle; import org.vamsas.client.IClientAppdata; import org.vamsas.client.IClientDocument; +import org.vamsas.client.UserHandle; import org.vamsas.client.Vobject; import org.vamsas.client.VorbaId; import org.vamsas.objects.core.ApplicationData; +import org.vamsas.objects.core.User; import org.vamsas.objects.core.VAMSAS; import org.vamsas.objects.core.VamsasDocument; import org.vamsas.objects.utils.AppDataReference; @@ -346,8 +349,11 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements return null; } protected boolean updateSessionDocument() throws java.io.IOException { - if (!isModified() && !scappd.isModified()) + boolean docupdate = true; // 'non-serious' problems below set this false + if (!isModified() && !scappd.isModified()) { + log.debug("Document update not necessary. returning false."); return false; + } VamsasSession session = sclient._session; log.debug("updating Session Document in "+session.sessionDir); // update the VamsasDocument structure with any new appData's. @@ -355,10 +361,11 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements log.debug("Attempting to update session "+sclient.session.getSessionUrn()); if (scappd.isModified()) { ClientHandle client = sclient.client; + UserHandle user = sclient.user; scappd.closeForWriting(); - long newAppd = scappd.newAppData.sessionFile.length(); - if (scappd.appsGlobal==null) { + log.debug("Creating new appData entry for this application..."); + // first write for this application - add a new section in document ApplicationData appd = scappd.appsGlobal = new ApplicationData(); appd.setName(client.getClientName()); appd.setUrn(client.getClientUrn()); @@ -366,40 +373,61 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements doc.addApplicationData(appd); // embed or jarEntry ? - for now only jarEntry's are dealt with. appd.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn())); + log.debug("... created."); } if (scappd.newAppData!=null && scappd.newAppData.sessionFile.exists()) { + log.debug("Beginning update for new Global Appdata..."); + // new global appdata to write. if (scappd.appsGlobal.getData()!=null) { scappd.appsGlobal.setData(null); scappd.appsGlobal.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn())); } - - - + // LATER: use a switch to decide if the data should be written as a reference or as an embedded data chunk + scappd.updateAnAppdataEntry(archive, scappd.appsGlobal, scappd.newAppData); + log.debug("...Successfully updated Global Appdata Entry."); } - if (scappd.usersData==null) { - + if (scappd.newUserData!=null && scappd.newUserData.sessionFile.exists()) { + log.debug("Beginning to update Users Appdata entry...."); + if (scappd.usersData==null) { + // create new user appdata + scappd.usersData = new User(); + scappd.usersData.setFullname(user.getFullName()); + scappd.usersData.setOrganization(user.getOrganization()); + scappd.appsGlobal.addUser(scappd.usersData); + } + User appd = scappd.usersData; + if (appd.getData()!=null || appd.getDataReference()==null) { + // LATER make standard appDataReference constructor for client+user + appd.setData(null); + String safe_username = user.getFullName(); + int t = safe_username.indexOf(" "); + if (t!=-1) { + safe_username = safe_username.substring(t); + } + appd.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn()+safe_username)); + } + scappd.updateAnAppdataEntry(archive, scappd.usersData, scappd.newUserData); + log.debug("...Successfully updated user AppData entry."); } - } - cdocument.archive.putVamsasDocument(vdoc); - // write the appHandle to the lastupdate file. - } - if (scappd!=null) { - if (scappd.accessedDocument) + log.debug("Updating Document..."); + // now update the document. + try { + archive.putVamsasDocument(doc); + log.debug("Successfully written document entry."); } - va = new org.vamsas.client.simpleclient.VamsasArchive(newf, false, true, sfile); - doc = va.getVamsasDocument(); - doc.addVAMSAS(Core.getDemoVamsas()); - doc.addApplicationData(makeDemoAppdata(va, - "org.vamsas.test.simpleclient.VamsasArchive", "another old Bugger esq", "rescinded")); - if (va.transferRemainingAppDatas()) - log.info("Remain appdatas were transferred."); + catch (Exception e) { + log.error("Marshalling error for vamsas document.",e); + docupdate = false; // pass on the (probable) object validation error + } + if (archive.transferRemainingAppDatas()) + log.debug("Remaining appdatas were transferred."); else - log.warn("No appdatas were transferred. This is wrong."); - va.putVamsasDocument(doc); - va.closeArchive(); + log.debug("No remaining appdatas were transferred. (Correct?)"); + archive.closeArchive(); + log.debug("...successully finished and closed."); - return true; // successfully updated. + return docupdate; // no errors ? } /* (non-Javadoc) * @see java.lang.Object#finalize() @@ -411,6 +439,7 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements scappd = null; } // TODO local garbage collection + super.finalize(); } diff --git a/src/org/vamsas/client/simpleclient/SimpleClient.java b/src/org/vamsas/client/simpleclient/SimpleClient.java index 084c7f5..970bcfa 100644 --- a/src/org/vamsas/client/simpleclient/SimpleClient.java +++ b/src/org/vamsas/client/simpleclient/SimpleClient.java @@ -100,7 +100,7 @@ public class SimpleClient implements IClient { throw new Exception("Failed to import data from "+importingArchive, e); } } - + /* * (non-Javadoc) * LATER: check that build substitution variables are correct @@ -273,8 +273,17 @@ public class SimpleClient implements IClient { if (log.isDebugEnabled()) log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument."); } else { - if (cdocument.updateSessionDocument()) - log.warn("Session document did not update properly for session directory "+_session.sessionDir); + try { + if (!cdocument.updateSessionDocument()) { + log.warn("Session document did not update properly for session directory "+_session.sessionDir); + // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the archive. + _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()"); + } + } + catch (IOException e) { + log.warn("IO Problems when updating document!",e); + _session.slog.error("IO problems when attempting to update document."); + } } // garbage collect the ClientDocument instance. try { diff --git a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java index 5bda46e..a2d8912 100644 --- a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java +++ b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java @@ -3,6 +3,7 @@ */ package org.vamsas.client.simpleclient; +import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -10,6 +11,7 @@ import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; @@ -339,6 +341,7 @@ public class SimpleClientAppdata implements IClientAppdata { } try { apdfile.lockFile(); + // LATER: Refactor these local AppDatastream IO stuff to their own class. JarOutputStream dstrm = new JarOutputStream( new BufferedOutputStream(new java.io.FileOutputStream(apdfile.sessionFile))); @@ -358,6 +361,45 @@ public class SimpleClientAppdata implements IClientAppdata { apdfile.unlockFile(); return null; } + /** + * copy data from the appData jar file to an appropriately + * referenced jar or Data entry for the given ApplicationData + * Assumes the JarFile is properly closed. + * @param vdoc session Document handler + * @param appd the AppData whose block is being updated + * @param apdjar the new data in a Jar written by this class + */ + protected void updateAnAppdataEntry(VamsasArchive vdoc, AppData appd, SessionFile apdjar) throws IOException { + if (apdjar==null || apdjar.sessionFile==null || !apdjar.sessionFile.exists()) { + throw new IOException("No temporary Appdata to recover and transfer."); + } + if (vdoc==null) { + log.fatal("FATAL! NO DOCUMENT TO WRITE TO!"); + throw new IOException("FATAL! NO DOCUMENT TO WRITE TO!"); + } + log.debug("Recovering AppData entry from "+apdjar.sessionFile); + JarInputStream istrm = new JarInputStream(new BufferedInputStream(new FileInputStream(apdjar.sessionFile))); + JarEntry je=null; + while (istrm.available()>0 && (je=istrm.getNextJarEntry())!=null && !je.getName().equals("appData_entry.dat")) { + if (je!=null) + log.debug("Ignoring extraneous entry "+je.getName()); + } + if (istrm.available()>0 && je!=null) { + log.debug("Found appData_entry.dat in Jar"); + String ref = appd.getDataReference(); + if (ref==null) { + throw new IOException("Null AppData.DataReference passed."); + } + if (vdoc.writeAppdataFromStream(ref, istrm)) { + log.debug("Entry updated successfully."); + } else { + throw new IOException("writeAppdataFromStream did not return true - expect future badness."); // LATER - verify why this might occur. + } + } else { + throw new IOException("Couldn't find appData_entry.dat in temporary jar file "+apdjar.sessionFile.getAbsolutePath()); + } + istrm.close(); + } /* (non-Javadoc) * @see org.vamsas.client.IClientAppdata#getClientOutputStream() */ @@ -466,16 +508,7 @@ public class SimpleClientAppdata implements IClientAppdata { newUserDataStream.close(); } } - /** - * copy data from the appData jar file to an appropriately - * referenced jar or Data entry for the given ApplicationData - * @param vdoc session Document handler - * @param appd the AppData whose block is being updated - * @param apdjar the new data in a Jar written by this class - */ - protected void updateAnAppdataEntry(VamsasArchive vdoc, AppData appd, SessionFile apdjar) { - - } + /** * -- 1.7.10.2