From e250d82e9bbb629690b3e45b0f064ab091fa6460 Mon Sep 17 00:00:00 2001 From: jprocter Date: Mon, 20 Mar 2006 17:11:43 +0000 Subject: [PATCH] half implemented the SimpleClientAppdata interface. git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@192 be28352e-c001-0410-b1a7-c7978e42abec --- .../vamsas/client/simpleclient/ClientDocument.java | 16 ++ .../client/simpleclient/SimpleClientAppdata.java | 253 ++++++++++++++++++-- 2 files changed, 245 insertions(+), 24 deletions(-) diff --git a/src/org/vamsas/client/simpleclient/ClientDocument.java b/src/org/vamsas/client/simpleclient/ClientDocument.java index e6ef1f5..de197e7 100644 --- a/src/org/vamsas/client/simpleclient/ClientDocument.java +++ b/src/org/vamsas/client/simpleclient/ClientDocument.java @@ -197,4 +197,20 @@ public class ClientDocument extends org.vamsas.client.ClientDocument implements super.finalize(); } + /** + * access the vamsas document + * @return the session's vamsas document + */ + protected VamsasDocument getVamsasDocument() { + // TODO: IMPLEMENT + return null; + } + /** + * returns the read-only IO interface for the vamsas document Jar file + * @return + */ + protected VamsasArchiveReader getVamsasArchiveReader() { + // TODO: IMPLEMENT getVamsasArchiveReader + return null; + } } diff --git a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java index 9f6b27f..d488782 100644 --- a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java +++ b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java @@ -3,9 +3,14 @@ */ package org.vamsas.client.simpleclient; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.DataInput; +import java.io.DataInputStream; import java.io.DataOutput; +import java.io.InputStream; import java.util.Vector; +import java.util.jar.JarInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -19,10 +24,23 @@ import org.vamsas.objects.utils.AppDataReference; * @author jimp * Access interface to data chunks read from a VamsasArchiveReader stream * (or byte buffer input stream) or written to a VamsasArchive stream. + * // TODO: get VamsasArchiveReader from sclient */ public class SimpleClientAppdata implements IClientAppdata { private static Log log = LogFactory.getLog(SimpleClientAppdata.class); - + /** + * has the session's document been accessed to get the AppData entrys? + */ + protected boolean accessedDocument = false; + /** + * has the user datablock been modified ? + */ + protected boolean modifiedUserData = false; + /** + * has the apps global datablock been modified ? + */ + protected boolean modifiedAppData = false; + ClientDocument clientdoc; /** * state flags @@ -46,70 +64,247 @@ public class SimpleClientAppdata implements IClientAppdata { this.clientdoc = clientdoc; } /** + * set by extractAppData + */ + protected ApplicationData appsGlobal = null; + /** + * set by extractAppData + */ + protected User usersData = null; + /** * gets appropriate app data for the application, if it exists in this dataset - * + * Called by every accessor to ensure data has been retrieved from document. */ - private void extractAppData() { - org.vamsas.objects.core.VamsasDocument doc = null; + private void extractAppData(org.vamsas.objects.core.VamsasDocument doc) { + if (doc==null) { + log.debug("extractAppData called for null document object"); + return; + } + if (accessedDocument) { + return; + } Vector apldataset = AppDataReference.getUserandApplicationsData( doc, clientdoc.sclient.getUserHandle(), clientdoc.sclient.getClientHandle()); - ApplicationData appsglobal=null; - User usersdata = null; + accessedDocument = true; if (apldataset!=null) { if (apldataset.size()>0) { AppData clientdat = (AppData) apldataset.get(0); if (clientdat instanceof ApplicationData) { - appsglobal = (ApplicationData) clientdat; + appsGlobal = (ApplicationData) clientdat; + modifiedAppData = false; if (apldataset.size()>1) { clientdat = (AppData) apldataset.get(1); - if (clientdat instanceof User) - usersdata = (User) clientdat; + if (clientdat instanceof User) { + usersData = (User) clientdat; + modifiedUserData = false; + } if (apldataset.size()>2) log.info("Ignoring additional ("+(apldataset.size()-2)+") AppDatas returned by document appdata query."); } } else { log.warn("Unexpected entry in AppDataReference query: id="+clientdat.getVorbaId()+" type="+clientdat.getClass().getName()); } + apldataset.removeAllElements(); // destroy references. } } } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientAppdata() + /** + * LATER: generalize this for different low-level session implementations (it may not always be a Jar) + * @param appdata + * @param docreader + * @return */ - public byte[] getClientAppdata() { - // TODO Auto-generated method stub + private JarInputStream 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."); + } + } else { + log.debug("GetAppDataStream called for an AppData without a data reference."); + } return null; } + /** + * yuk - size of buffer used for slurping appData JarEntry into a byte array. + */ + private final int _TRANSFER_BUFFER=4096*4; - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientInputStream() + /** + * Resolve AppData object to a byte array. + * @param appdata + * @param archiveReader + * @return null or the application data as a byte array */ - public DataInput getClientInputStream() { - // TODO Auto-generated method stub + private byte[] getAppDataAsByteArray(AppData appdata, VamsasArchiveReader docreader) { + if (appdata.getData()==null) { + // resolve and load data + JarInputStream 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; + } + buff=null; + } catch (Exception e) { + log.warn("Unexpected exception - probable truncation when accessing VamsasDocument entry "+appdata.getDataReference(), e); + } + if (bytes.size()>0) { + // LATER: deal with probable OutOfMemoryErrors here + log.debug("Got "+bytes.size()+" bytes from AppDataReference "+appdata.getDataReference()); + byte data[] = bytes.toByteArray(); + bytes = null; + return data; + } + return null; + } else { + log.debug("Returning inline AppData block for "+appdata.getVorbaId()); + return appdata.getData(); + } + } + /** + * internal method for getting a DataInputStream from an AppData object. + * @param appdata + * @param docreader + * @return data in object or null if no data is accessible + */ + private DataInput getAppDataAsDataInputStream(AppData appdata, VamsasArchiveReader docreader) { + if (appdata!=null) { + String entryRef = appdata.getDataReference(); + if (entryRef!=null) { + log.debug("Resolving AppData reference for "+entryRef); + InputStream jstrm = docreader.getAppdataStream(entryRef); + if (jstrm!=null) + return new AppDataInputStream(jstrm); + else { + log.debug("Returning null input stream for unresolved reference ("+entryRef+") id="+appdata.getVorbaId()); + return null; + } + } else { + // return a byteArray input stream + byte[] data=appdata.getData(); + if (data.length>0) { + ByteArrayInputStream stream = new ByteArrayInputStream(data); + return new DataInputStream(stream); + } else { + log.debug("Returning null input stream for empty Appdata data block in id="+appdata.getVorbaId()); + return null; + } + } + } else { + log.debug("Returning null DataInputStream for appdata entry:"+appdata.getVorbaId()); + } return null; } - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientOutputStream() + /** + * internal method for getting ByteArray from AppData object + * @param clientOrUser - true for returning userData, otherwise return Client AppData. + * @return null or byte array */ - public DataOutput getClientOutputStream() { - // TODO Auto-generated method stub + private byte[] _getappdataByteArray(boolean clientOrUser) { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); + byte[] data=null; + String appdName; + if (!clientOrUser) { + appdName = "Client's Appdata"; + } else { + appdName = "User's Appdata"; + } + log.debug("getting "+appdName+" as a byte array"); + extractAppData(clientdoc.getVamsasDocument());// TODO: get VamsasArchiveReader from sclient + AppData object; + if (!clientOrUser) { + object = appsGlobal; + } else { + object = usersData; + } + if (object!=null) { + log.debug("Trying to resolve "+appdName+" object to byte array."); + data = getAppDataAsByteArray(object, clientdoc.getVamsasArchiveReader()); + } + if (data == null) + log.debug("Returning null for "+appdName+"ClientAppdata byte[] array"); + return data; + + } + + /** + * common method for Client and User AppData->InputStream accessor + * @param clientOrUser - the appData to resolve - false for client, true for user appdata. + * @return null or the DataInputStream desired. + */ + private DataInput _getappdataInputStream(boolean clientOrUser) { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); + String appdName; + if (!clientOrUser) { + appdName = "Client's Appdata"; + } else { + appdName = "User's Appdata"; + } + if (log.isDebugEnabled()) + log.debug("getting "+appdName+" as an input stream."); + extractAppData(clientdoc.getVamsasDocument()); + AppData object; + if (!clientOrUser) { + object = appsGlobal; + } else { + object = usersData; + } + if (object!=null) { + log.debug("Trying to resolve ClientAppdata object to an input stream."); + return getAppDataAsDataInputStream(object, clientdoc.getVamsasArchiveReader()); + } + log.debug("getClientInputStream returning null."); return null; } + /* (non-Javadoc) + * @see org.vamsas.client.IClientAppdata#getClientAppdata() + */ + public byte[] getClientAppdata() { + return _getappdataByteArray(false); + } + /* (non-Javadoc) + * @see org.vamsas.client.IClientAppdata#getClientInputStream() + */ + public DataInput getClientInputStream() { + return _getappdataInputStream(false); + } /* (non-Javadoc) * @see org.vamsas.client.IClientAppdata#getUserAppdata() */ public byte[] getUserAppdata() { - // TODO Auto-generated method stub - return null; + return _getappdataByteArray(true); } /* (non-Javadoc) * @see org.vamsas.client.IClientAppdata#getUserInputStream() */ public DataInput getUserInputStream() { + return _getappdataInputStream(true); + } + /** + * methods for writing new AppData entries. + */ + + /* (non-Javadoc) + * @see org.vamsas.client.IClientAppdata#getClientOutputStream() + */ + public DataOutput getClientOutputStream() { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub return null; } @@ -118,6 +313,8 @@ public class SimpleClientAppdata implements IClientAppdata { * @see org.vamsas.client.IClientAppdata#getUserOutputStream() */ public DataOutput getUserOutputStream() { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub return null; } @@ -126,6 +323,8 @@ public class SimpleClientAppdata implements IClientAppdata { * @see org.vamsas.client.IClientAppdata#hasClientAppdata() */ public boolean hasClientAppdata() { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub return false; } @@ -134,6 +333,8 @@ public class SimpleClientAppdata implements IClientAppdata { * @see org.vamsas.client.IClientAppdata#hasUserAppdata() */ public boolean hasUserAppdata() { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub return false; } @@ -142,6 +343,8 @@ public class SimpleClientAppdata implements IClientAppdata { * @see org.vamsas.client.IClientAppdata#setClientAppdata(byte[]) */ public void setClientAppdata(byte[] data) { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub } @@ -150,6 +353,8 @@ public class SimpleClientAppdata implements IClientAppdata { * @see org.vamsas.client.IClientAppdata#setUserAppdata(byte[]) */ public void setUserAppdata(byte[] data) { + if (clientdoc==null) + throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); // TODO Auto-generated method stub } -- 1.7.10.2