From 917d7bbb140b99761a96008a44910bb2a10022f1 Mon Sep 17 00:00:00 2001 From: jprocter Date: Thu, 16 Aug 2007 17:21:32 +0000 Subject: [PATCH] refactored IClientAppdata and implementation has been minimally tested and bugfixed - still outstanding issues are when an app updates an Appdata already written to session (throws a DuplicateZipEntryException). git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@429 be28352e-c001-0410-b1a7-c7978e42abec --- .../client/simpleclient/SimpleClientAppdata.java | 45 ++++---- .../vamsas/client/simpleclient/VamsasArchive.java | 5 + .../client/simpleclient/VamsasArchiveReader.java | 1 + src/uk/ac/vamsas/test/ExampleApplication.java | 113 +++++++++++++++++++- 4 files changed, 140 insertions(+), 24 deletions(-) diff --git a/src/uk/ac/vamsas/client/simpleclient/SimpleClientAppdata.java b/src/uk/ac/vamsas/client/simpleclient/SimpleClientAppdata.java index 18f7d2e..ececd9e 100644 --- a/src/uk/ac/vamsas/client/simpleclient/SimpleClientAppdata.java +++ b/src/uk/ac/vamsas/client/simpleclient/SimpleClientAppdata.java @@ -22,6 +22,8 @@ import java.util.jar.JarOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import uk.ac.vamsas.client.AppDataInputStream; +import uk.ac.vamsas.client.AppDataOutputStream; import uk.ac.vamsas.client.IClientAppdata; import uk.ac.vamsas.objects.core.AppData; import uk.ac.vamsas.objects.core.ApplicationData; @@ -124,16 +126,14 @@ public class SimpleClientAppdata implements IClientAppdata { * @param docreader * @return */ - private JarInputStream getAppDataStream(AppData appdata, VamsasArchiveReader docreader) { + private InputStream getAppDataStream(AppData appdata, VamsasArchiveReader docreader) { String entryRef = appdata.getDataReference(); if (entryRef!=null) { log.debug("Resolving appData reference +"+entryRef); InputStream entry = docreader.getAppdataStream(entryRef); if (entry!=null) { - if (entry instanceof JarInputStream) { - return (JarInputStream) entry; - } - log.warn("Implementation problem - docreader didn't return a JarInputStream entry."); + return entry; + // log.warn("Implementation problem - docreader didn't return a JarInputStream entry."); } } else { log.debug("GetAppDataStream called for an AppData without a data reference."); @@ -158,15 +158,17 @@ public class SimpleClientAppdata implements IClientAppdata { return null; } // resolve and load data - JarInputStream entry = getAppDataStream(appdata, docreader); + InputStream entry = getAppDataStream(appdata, docreader); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); try { byte buff[] = new byte[_TRANSFER_BUFFER]; int olen=0; - while (entry.available()>0) { - int len = entry.read(buff, olen, _TRANSFER_BUFFER); - bytes.write(buff, 0, len); - olen+=len; + while (entry!=null && entry.available()>0) { + int len = entry.read(buff, 0, _TRANSFER_BUFFER); + if (len>-1) + { bytes.write(buff, 0, len); + olen+=len; + } } buff=null; } catch (Exception e) { @@ -191,7 +193,7 @@ public class SimpleClientAppdata implements IClientAppdata { * @param docreader * @return data in object or null if no data is accessible */ - private DataInput getAppDataAsDataInputStream(AppData appdata, VamsasArchiveReader docreader) { + private AppDataInputStream getAppDataAsDataInputStream(AppData appdata, VamsasArchiveReader docreader) { if (appdata!=null && docreader!=null) { String entryRef = appdata.getDataReference(); if (entryRef!=null) { @@ -208,7 +210,7 @@ public class SimpleClientAppdata implements IClientAppdata { byte[] data=appdata.getData(); if (data.length>0) { ByteArrayInputStream stream = new ByteArrayInputStream(data); - return new DataInputStream(stream); + return new AppDataInputStream(stream); } else { log.debug("Returning null input stream for empty Appdata data block in id="+appdata.getVorbaId()); return null; @@ -258,7 +260,7 @@ public class SimpleClientAppdata implements IClientAppdata { * @param clientOrUser - the appData to resolve - false for client, true for user appdata. * @return null or the DataInputStream desired. */ - private DataInput _getappdataInputStream(boolean clientOrUser) { + private AppDataInputStream _getappdataInputStream(boolean clientOrUser) { if (clientdoc==null) throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); String appdName; @@ -292,7 +294,7 @@ public class SimpleClientAppdata implements IClientAppdata { /* (non-Javadoc) * @see uk.ac.vamsas.client.IClientAppdata#getClientInputStream() */ - public DataInput getClientInputStream() { + public AppDataInputStream getClientInputStream() { return _getappdataInputStream(false); } @@ -306,13 +308,13 @@ public class SimpleClientAppdata implements IClientAppdata { /* (non-Javadoc) * @see uk.ac.vamsas.client.IClientAppdata#getUserInputStream() */ - public DataInput getUserInputStream() { + public AppDataInputStream getUserInputStream() { return _getappdataInputStream(true); } /** * methods for writing new AppData entries. */ - private DataOutput _getAppdataOutputStream(boolean clientOrUser) { + private AppDataOutputStream _getAppdataOutputStream(boolean clientOrUser) { String apdname; SessionFile apdfile=null; if (!clientOrUser) { @@ -390,6 +392,7 @@ public class SimpleClientAppdata implements IClientAppdata { if (ref==null) { throw new IOException("Null AppData.DataReference passed."); } + log.debug("Writing appData_entry.dat as "+ref); if (vdoc.writeAppdataFromStream(ref, istrm)) { log.debug("Entry updated successfully."); } else { @@ -403,7 +406,7 @@ public class SimpleClientAppdata implements IClientAppdata { /* (non-Javadoc) * @see uk.ac.vamsas.client.IClientAppdata#getClientOutputStream() */ - public DataOutput getClientOutputStream() { + public AppDataOutputStream getClientOutputStream() { if (clientdoc==null) throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); if (log.isDebugEnabled()) @@ -414,7 +417,7 @@ public class SimpleClientAppdata implements IClientAppdata { /* (non-Javadoc) * @see uk.ac.vamsas.client.IClientAppdata#getUserOutputStream() */ - public DataOutput getUserOutputStream() { + public AppDataOutputStream getUserOutputStream() { if (clientdoc==null) throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); if (log.isDebugEnabled()) @@ -431,6 +434,7 @@ public class SimpleClientAppdata implements IClientAppdata { throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); extractAppData(clientdoc.getVamsasDocument()); // LATER - check validity of a DataReference before we return true + // TODO: return true if usersData is null but we have already written a new data stream if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null)) return true; return false; @@ -444,7 +448,8 @@ public class SimpleClientAppdata implements IClientAppdata { throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); extractAppData(clientdoc.getVamsasDocument()); // LATER - check validity of a DataReference before we return true - if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null)) + // TODO: return true if usersData is null but we have already written a new data stream + if ((usersData!=null) && (usersData.getDataReference()!=null || usersData.getData()!=null)) return true; return false; } @@ -516,7 +521,7 @@ public class SimpleClientAppdata implements IClientAppdata { */ protected boolean isModified() { // LATER differentiate between core xml modification and Jar Entry modification. - if (newAppData.sessionFile.exists() || newUserData.sessionFile.exists()) + if ((newAppData!=null && newAppData.sessionFile.exists()) || (newUserData!=null && newUserData.sessionFile.exists())) return true; return false; } diff --git a/src/uk/ac/vamsas/client/simpleclient/VamsasArchive.java b/src/uk/ac/vamsas/client/simpleclient/VamsasArchive.java index 3f1d31f..2477c70 100644 --- a/src/uk/ac/vamsas/client/simpleclient/VamsasArchive.java +++ b/src/uk/ac/vamsas/client/simpleclient/VamsasArchive.java @@ -20,6 +20,7 @@ import java.util.jar.Manifest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import uk.ac.vamsas.client.AppDataOutputStream; import uk.ac.vamsas.client.ClientHandle; import uk.ac.vamsas.client.IVorbaIdFactory; import uk.ac.vamsas.client.SessionHandle; @@ -279,6 +280,10 @@ public class VamsasArchive { private boolean addEntry(String entry) { if (entries!=null) entries=new Hashtable(); + if (log.isDebugEnabled()) + { + log.debug("validating '"+entry+"' in hash for "+this); + } if (entries.containsKey(entry)) return false; entries.put(entry, new Integer(entries.size())); diff --git a/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java b/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java index 291a28a..819be18 100644 --- a/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java +++ b/src/uk/ac/vamsas/client/simpleclient/VamsasArchiveReader.java @@ -20,6 +20,7 @@ import java.util.zip.ZipInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import uk.ac.vamsas.client.AppDataInputStream; import uk.ac.vamsas.objects.utils.document.VersionEntries; /** * Basic methods for accessing an existing Vamsas Archive, diff --git a/src/uk/ac/vamsas/test/ExampleApplication.java b/src/uk/ac/vamsas/test/ExampleApplication.java index bfb1425..3bebe6d 100644 --- a/src/uk/ac/vamsas/test/ExampleApplication.java +++ b/src/uk/ac/vamsas/test/ExampleApplication.java @@ -10,8 +10,15 @@ import uk.ac.vamsas.test.objects.Core; import java.awt.Event; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.util.Vector; /** @@ -69,6 +76,9 @@ public class ExampleApplication private int totalUpdates = 9; private uk.ac.vamsas.client.VorbaId recover = null; private int calls=0; + private long mdatahash = 0; + private long muserdatahash = 0; + private void processVamsasDocument(IClientDocument doc) { if (doc.getVamsasRoots().length<4) { @@ -90,15 +100,110 @@ public class ExampleApplication System.out.println("Modified Sequence:\n"+alsq.getSequence()); doc.setVamsasRoots(doc.getVamsasRoots()); } catch (Exception ee) { - + } } - vorbaclient.updateDocument(doc); - // merge vamsasObjects with vamsas objects in document // get this apps 'mydata' if it hasn't got it already. + System.out.println("Trying to get appdata and modify it....."); + try { + processAppData(doc); + System.out.println(".....Finished."); + } catch (Exception e) + { + System.err.println("Failed to process appdata for our application."); + e.printStackTrace(System.err); + } + + // .. access this application's 'public' mydata' if there is any. + vorbaclient.updateDocument(doc); + // merge vamsasObjects with vamsas objects in document + + } + private int appdatareads=0; + private void processAppData(IClientDocument doc) throws Exception { + appdatareads++; + boolean writtenonce=false; + if (doc!=null) + { + uk.ac.vamsas.client.IClientAppdata appd = doc.getClientAppdata(); + if (appd.hasClientAppdata() && !(appdatareads % 2==0)) + { + //byte[] cappd = appd.getClientAppdata(); + //if (cappd!=null) + // System.out.println("Client appdata\n"+cappd.toString()+"\nEnd of Appdata\n"); + System.out.println("Testing read from inputstream"); + String cappds = readData(appd.getClientInputStream()); + System.out.println("Client appdata\n"+cappds+"\nEnd of Appdata\n"); + } else { + if (!writtenonce) + { + writtenonce=true; + // appd.setClientAppdata(makeappData("Client Appdata for "+user.toString()+" written")); + writeData(appd.getClientOutputStream(), "Client Appdata for all users written on "+appdatareads+" read by "+vorbaclient.getUserHandle()); + System.out.println("Written to ClientAppdata stream."); + } + } + if (appd.hasUserAppdata() && !(appdatareads % 2==0)) + { + byte[] cappd = appd.getUserAppdata(); + if (cappd!=null) + System.out.println("User appdata\n"+new String(cappd)+"\nEnd of Users' Appdata\n"); + else + { + System.out.println("No user appdata."); + appd.setUserAppdata(("no default - overwritten null byte set on "+appdatareads+" read by "+vorbaclient.getUserHandle()+"").getBytes()); + } + } else + if (!writtenonce) + { + writtenonce=true; + byte[] bts = makeappData("User Appdata for "+user+" written on "+appdatareads+" read at "); + System.out.println("Setting appData bytes to\n"+new String(bts)+"\nEnd."); + appd.setUserAppdata(bts); + System.out.println("Written to UserAppdata stream."); + } + } + } + private byte[] makeappData(String message) + { + StringBuffer sb = new StringBuffer(); + sb.append(message); + sb.append("on "+new java.util.Date()); + return sb.toString().getBytes(); + } + private boolean writeData(AppDataOutputStream os, String message) + { + StringBuffer sb = new StringBuffer(); + sb.append(message); + sb.append("on "+new java.util.Date()); + try { + ObjectOutputStream oos = new ObjectOutputStream(os); + oos.writeObject(sb.toString()); + oos.flush(); + oos.close(); + } + catch (Exception e) { + System.err.println("Problem serialising this message:\n"+sb); + e.printStackTrace(System.err); + return false; + } + return true; + } + private String readData(AppDataInputStream is) + { + try { + ObjectInputStream ois = new ObjectInputStream(is); + String rs = (String) ois.readObject(); + return rs; + } + catch (Exception e) + { + System.err.println("Failed to read a string from input stream!"); + e.printStackTrace(System.err); + } + return ""; } - private void addHandlers(IClient avorbaclient) { // make a non-volatile reference to the client instance. -- 1.7.10.2