From 49874b2de657c9b2cfbb00d7600941f7cb7f2552 Mon Sep 17 00:00:00 2001 From: jprocter Date: Sun, 25 Sep 2005 19:02:11 +0000 Subject: [PATCH 1/1] implemented state flags and automatic call to VorbaIdFactory for unregistered (but registerable) vamsas objects. git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@53 be28352e-c001-0410-b1a7-c7978e42abec --- src/org/vamsas/client/SimpleClient.java | 106 +++++--- .../vamsas/client/castor/VorbaIdFieldHandler.java | 43 ---- src/org/vamsas/client/object.java | 252 +++++++++++++------- .../client/simpleclient/documentHandler.java | 25 +- 4 files changed, 240 insertions(+), 186 deletions(-) delete mode 100644 src/org/vamsas/client/castor/VorbaIdFieldHandler.java diff --git a/src/org/vamsas/client/SimpleClient.java b/src/org/vamsas/client/SimpleClient.java index 4533295..90e394f 100644 --- a/src/org/vamsas/client/SimpleClient.java +++ b/src/org/vamsas/client/SimpleClient.java @@ -37,6 +37,7 @@ public class SimpleClient implements IClient { SessionHandle session = null; ClientHandle client = null; + /* * (non-Javadoc) * @@ -83,7 +84,9 @@ public class SimpleClient implements IClient { } private Hashtable handlers = initHandlers(); + private Vector listeners = new Vector(); + /** * make all the PropertyChangeSupport objects for the * events described in org.vamsas.client.Event @@ -98,6 +101,7 @@ public class SimpleClient implements IClient { } return events; } + /* * (non-Javadoc) * @@ -106,10 +110,10 @@ public class SimpleClient implements IClient { public void addDocumentUpdateHandler(PropertyChangeListener evt) { if (handlers.containsKey(Events.DOCUMENT_UPDATE)) { Object handler; - ((PropertyChangeSupport) (handler - = handlers.get(Events.DOCUMENT_UPDATE))).addPropertyChangeListener(evt); + ((PropertyChangeSupport) (handler = handlers.get(Events.DOCUMENT_UPDATE))) + .addPropertyChangeListener(evt); listeners.add(handler); - listeners.add((Object) evt); + listeners.add((Object) evt); } } @@ -123,29 +127,36 @@ public class SimpleClient implements IClient { // deregister listeners. // mark this instance as finalized } - + /** * writes the VamsasDocument to the given stream. + * TODO: ensure that (at least) default provenance entries are written for objects. * @param outstream * @param doc * @throws IOException * @throws MarshalException * @throws ValidationException */ - private static void setVamsasDocument(Writer outstream, VamsasDocument doc) throws IOException, MarshalException, ValidationException { - Marshaller marshaller = new Marshaller(outstream); + private static void setVamsasDocument(Writer outstream, VamsasDocument doc) + throws IOException, MarshalException, ValidationException { + Marshaller marshaller = new Marshaller(outstream); marshaller.marshal(doc); } - + /** * Unmarshals a vamsasDocument object from a stream, registers - * any VorbaIds, and completes the org.vamsas.client.object housekeeping fields. - * + * unregistered objects, records existing VorbaIds, and completes + * the org.vamsas.client.object housekeeping fields. + * For a valid unmarshalling, the array of returned objects also includes + * a sync parameter which is true if new VorbaIds + * were created. If sync is false, then the caller should ensure that the + * vamsasDocument is written back to disk to propagate the new VorbaIds. + * TODO: ensure that provenance is correct for newly registered objects * @param instream - the XML input stream * @param factory - the SimpleClient's properly configured VorbaId factory to make new references. - * @return null or {(Object) VamsasDocument object, (Object) Hashtable of object references) + * @return null or {(Object) VamsasDocument object, (Object) Hashtable of object references, (Object) Boolean(sync) } */ - private static Object[] getVamsasDocument(Reader instream, +private static Object[] getVamsasDocument(Reader instream, IVorbaIdFactory factory) { Unmarshaller unmarshaller = new Unmarshaller(instream); unmarshaller.setIDResolver(new IDResolver() { @@ -156,8 +167,10 @@ public class SimpleClient implements IClient { } }); Hashtable refbase = new Hashtable(); + Vector unrefed = new Vector(); final Hashtable objrefs = refbase; final IVorbaIdFactory vorbafactory = factory; + final Vector unrefedObj = unrefed; unmarshaller.setUnmarshalListener(new UnmarshalListener() { /* @@ -197,25 +210,36 @@ public class SimpleClient implements IClient { nobj.set__stored_in_document(true); Field fd = null; try { - // look for the id field (should be an NCName string) - fd = nobj.getClass().getField("id"); - String idstring; - if (fd.getType().getClass().equals("astring".getClass())) { + if (nobj.isRegisterable()) { + // look for the id field (should be an NCName string) + nobj.__vorba = vorbafactory; + fd = nobj.getClass().getField("id"); + String idstring; if (fd.get(nobj) != null) { idstring = (String) fd.get(nobj); - if (idstring.length() > 0) + if (idstring.length() > 0) { if (!objrefs.containsKey(idstring)) { objrefs.put(idstring, nobj); nobj.setVorbaId(VorbaId.newId(idstring)); - nobj.__vorba = vorbafactory; + } else { + System.err.println("Serious problem : duplicate id '"+idstring+"' found! expect badness."); + // TODO: HANDLE duplicate XML ids correctly } + } else { + // add to list of objects without a valid vorbaId + unrefedObj.add(nobj); + } + } else { + // add to list of objects without a valid vorbaId + unrefedObj.add(nobj); } - } + nobj.doHash(); + } } catch (Exception e) { return; - } - ; + }; + } } @@ -224,8 +248,23 @@ public class SimpleClient implements IClient { try { while (instream.ready()) { Object obj = unmarshaller.unmarshal(instream); + boolean sync=true; if (obj instanceof VamsasDocument) { - return new Object[] { obj, objrefs}; + if (unrefed.size()>0) { + sync=false; // document is out of sync - ids have been created. + java.util.Iterator newobj = unrefed.listIterator(); + while (newobj.hasNext()) { + object o = (object) newobj.next(); + // forces registration and id field update. + VorbaId id = o.getVorbaId(); + if (!objrefs.containsKey(id)) { + objrefs.put(id.id, o); + } else { + throw new Error("Serious! Duplicate reference made by vorbaIdFactory!"); + } + } + } + return new Object[] { obj, objrefs, new Boolean(sync)}; } } } catch (MarshalException e) { @@ -240,12 +279,13 @@ public class SimpleClient implements IClient { } return null; } -/** - * extract data appropriate for client, session and user - * from vamsas document. - * @return application's byte array - */ + /** + * extract data appropriate for client, session and user + * from vamsas document. + * @return application's byte array + */ private byte[] getApplicationData() { + // TODO: extract correct byte object from Jar and return it to application. return null; } @@ -256,8 +296,8 @@ public class SimpleClient implements IClient { */ public IClientDocument getClientDocument() { Object[] vdoc;// TODO: = getVamsasDocument(new Reader()); - ClientDocument cdoc = new ClientDocument(getApplicationData(), - ((VamsasDocument) vdoc[0]).getVAMSAS(), (Hashtable) vdoc[1], this); + // ClientDocument cdoc = new ClientDocument(getApplicationData(), + // ((VamsasDocument) vdoc[0]).getVAMSAS(), (Hashtable) vdoc[1], this); // return null; } @@ -269,7 +309,7 @@ public class SimpleClient implements IClient { */ public void updateDocument(IClientDocument newdoc) { // TODO Auto-generated method stub - + // } /* @@ -291,10 +331,10 @@ public class SimpleClient implements IClient { public void addVorbaEventHandler(String EventChain, PropertyChangeListener evt) { if (handlers.containsKey(EventChain)) { Object handler; - ((PropertyChangeSupport) (handler - = handlers.get(EventChain))).addPropertyChangeListener(evt); + ((PropertyChangeSupport) (handler = handlers.get(EventChain))) + .addPropertyChangeListener(evt); listeners.add(handler); - listeners.add((Object) evt); + listeners.add((Object) evt); } } @@ -303,7 +343,7 @@ public class SimpleClient implements IClient { */ public void pollUpdate() { // TODO wake up UpdateWatcher thread to check for updates. - + } public static void main(String[] args) { diff --git a/src/org/vamsas/client/castor/VorbaIdFieldHandler.java b/src/org/vamsas/client/castor/VorbaIdFieldHandler.java deleted file mode 100644 index 55fbe8f..0000000 --- a/src/org/vamsas/client/castor/VorbaIdFieldHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * - */ -package org.vamsas.client.castor; - -import org.exolab.castor.mapping.GeneralizedFieldHandler; - -/** - * @author jim - * - */ -public class VorbaIdFieldHandler extends GeneralizedFieldHandler { - - public VorbaIdFieldHandler() { - super(); - // TODO Auto-generated constructor stub - } - - /* (non-Javadoc) - * @see org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponGet(java.lang.Object) - */ - public Object convertUponGet(Object arg0) { - // TODO Auto-generated method stub - return null; - } - - /* (non-Javadoc) - * @see org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponSet(java.lang.Object) - */ - public Object convertUponSet(Object arg0) { - // TODO Auto-generated method stub - return null; - } - - /* (non-Javadoc) - * @see org.exolab.castor.mapping.GeneralizedFieldHandler#getFieldType() - */ - public Class getFieldType() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/src/org/vamsas/client/object.java b/src/org/vamsas/client/object.java index 5f49537..fc13b4f 100644 --- a/src/org/vamsas/client/object.java +++ b/src/org/vamsas/client/object.java @@ -2,100 +2,180 @@ * */ package org.vamsas.client; + /** - * Base class for all Vamsas objects extracted - * from an IClientDocument. - * An object maybe registered or unregistered. + * Base class for all Vamsas objects extracted from an IClientDocument. An + * object maybe registered or unregistered. * * @author jimp - * + * */ public abstract class object { - /** - * unique id for all vamsas objects - * allows unambiguous referencing - * to any object in the vamsas document - */ - protected boolean __stored_in_document=false; - protected long __last_hash=0; - - protected VorbaId vorbaId=null; - protected IVorbaIdFactory __vorba=null; - /** - * calculate a hash - * for the object with all housekeeping - * fields at standard values. - */ - synchronized protected void doHash() { - __last_hash = 0; - VorbaId thisid = vorbaId; - IVorbaIdFactory factory = __vorba; - boolean stored = __stored_in_document; - vorbaId = null; - __vorba = null; - __last_hash = this.hashCode(); - vorbaId = thisid; - __vorba = factory; - __stored_in_document = stored; - } - - /** - * - * @return true if object is registered - */ - public boolean isRegistered() { - return (vorbaId!=null); - } - /** - * Method to get fixed reference for - * the object in the vamsas document. - * @returns null if object is neither registered - * or not associated with a properly instantiated - * VorbaIdFactory. - */ - public VorbaId getVorbaId() { - if (vorbaId==null) { - // Try to use the associated factory. - if (__vorba!=null) - if ((vorbaId = __vorba.makeVorbaId())==null) - return null; // Factory not valid. - else - return null; + /** + * unique id for all vamsas objects allows unambiguous referencing to any + * object in the vamsas document + */ + protected boolean __stored_in_document = false; + + protected long __last_hash = 0; + + protected boolean registerable = false; + + protected VorbaId vorbaId = null; + + protected IVorbaIdFactory __vorba = null; + + /** + * + */ + protected object() { + super(); + testInstanceForIdField(); + } + + /** + * set the isRegisterable flag based on the presence of a 'String id' field in + * the reflected class instance. + */ + private void testInstanceForIdField() { + // look for the id field (should be an NCName string) + // TODO: decide if 'id' is an appropriate reserved attribute name for the + // VorbaId + try { + java.lang.reflect.Field fd = this.getClass().getField("id"); + if (fd.getType().getClass().equals("astring".getClass())) { + this.setRegisterable(true); } - return vorbaId; - } - /** - * used by the IClient implementation - * to generate unique Id based on - * client applications current namespace. - */ - protected void setVorbaId(VorbaId newid) { - vorbaId = newid; + } catch (SecurityException e) { + e.printStackTrace(); + } catch (NoSuchFieldException e) { + this.setRegisterable(false); } - - /** - * @return true if object is present in Vamsas Document. - */ - public boolean is__stored_in_document() { - return __stored_in_document; - } - /** - * for use by Vorba agent to reflect state of - * vamsas object to client application. - * @param __stored_in_document The __stored_in_document to set. - */ - protected void set__stored_in_document(boolean __stored_in_document) { - this.__stored_in_document = __stored_in_document; + } + + /** + * update the object instance's String id field, based on the contents of the + * VorbaId. Only call this if you mean to do it! + */ + protected void setInstanceIdField() { + if (registerable) { + if (vorbaId!=null) + try { + java.lang.reflect.Field fd = this.getClass().getField("id"); + fd.set((Object) this, (Object) new String(vorbaId.id)); + } catch (IllegalAccessException e) { + System.err.println("SourceGeneration of "+this.getClass().toString() + +"\n has resulted in an inaccessible 'id' field!\nCannot set ID from the vorbaId object.") + e.printStackTrace(System.err); + } + catch (SecurityException e) { + e.printStackTrace(System.err); + } catch (NoSuchFieldException e) { + this.setRegisterable(false); + } + } else { + System.err.println("Client error. Trying to setInstanceIdField on a " + +this.getClass().toString()+" (which cannot be given a vorbaId)"); } - /** - * __last_hash is the hash value computed - * when the object was last checked against - * a IClientDocument generated by the - * object's parent IClient instance. - * @return Returns the __last_hash. - */ - public long get__last_hash() { - return __last_hash; + } + /** + * calculate a hash for the object with all housekeeping fields at standard + * values. (isRegisterable is an immutable attribute property) + */ + synchronized protected void doHash() { + __last_hash = 0; + VorbaId thisid = vorbaId; + IVorbaIdFactory factory = __vorba; + boolean stored = __stored_in_document; + vorbaId = null; + __vorba = null; + __last_hash = this.hashCode(); + vorbaId = thisid; + __vorba = factory; + __stored_in_document = stored; + } + + /** + * + * @return true if object is registered + */ + public boolean isRegistered() { + return (registerable) ? (vorbaId != null) : false; + } + + /** + * Method to get fixed reference for the object in the vamsas document. + * + * @returns null if object is neither registered or not associated with a + * properly instantiated VorbaIdFactory. + */ + public VorbaId getVorbaId() { + if (registerable && vorbaId == null) { + // Try to use the associated factory. + if (__vorba != null) + if ((vorbaId = __vorba.makeVorbaId()) == null) + return null; // Factory not valid. + else { + this.setInstanceIdField(); + return vorbaId; + } } + return vorbaId; + } + + /** + * used by the IClient implementation to generate unique Id based on client + * applications current namespace. + */ + protected void setVorbaId(VorbaId newid) { + vorbaId = newid; + } + + /** + * @return true if object is present in Vamsas Document. + */ + public boolean is__stored_in_document() { + return __stored_in_document; + } + + /** + * for use by Vorba agent to reflect state of vamsas object to client + * application. + * + * @param __stored_in_document + * The __stored_in_document to set. + */ + protected void set__stored_in_document(boolean __stored_in_document) { + this.__stored_in_document = __stored_in_document; + } + + /** + * __last_hash is the hash value computed when the object was last checked + * against a IClientDocument generated by the object's parent IClient + * instance. + * + * @return Returns the __last_hash. + */ + public long get__last_hash() { + return __last_hash; + } + + /** + * @return Returns the registerable. + */ + public boolean isRegisterable() { + return registerable; + } + + /** + * Called during unmarshalling - if object has an id string, it is + * registerable. + * + * @param registerable + * The registerable to set. + */ + protected void setRegisterable(boolean registerable) { + this.registerable = registerable; + } } diff --git a/src/org/vamsas/client/simpleclient/documentHandler.java b/src/org/vamsas/client/simpleclient/documentHandler.java index fd6e016..433fef1 100644 --- a/src/org/vamsas/client/simpleclient/documentHandler.java +++ b/src/org/vamsas/client/simpleclient/documentHandler.java @@ -79,29 +79,6 @@ public class documentHandler { } return null; } - /** - * opens a locked UTF-8 stream to the vamsas document. - * @return reader for vamsasdocument.xml enrty - */ - public java.io.PrintWriter getDocumentWriter() { - if (vamsasWriterStream!=null && vamsasWriterStream.checkError()) { - return vamsasWriterStream; - } - - try { - - newVamsasJarLock = new Lock(lockfile); - if (newVamsasJarLock = !=null) { - JarOutputStream session = new JarOutputStream(new FileOutputStream(vamsasJar)); - JarEntry vamsasDocument = session.getJarEntry("vamsasDocument.xml"); - if (vamsasDocument!=null) - return new java.io.PrintWriter(OutputStreamWriter(session.Stream(vamsasDocument)), "UTF-8"); - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } + } -- 1.7.10.2