implemented state flags and automatic call to VorbaIdFactory for unregistered (but...
authorjprocter <jprocter@compbio.dundee.ac.uk>
Sun, 25 Sep 2005 19:02:11 +0000 (19:02 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Sun, 25 Sep 2005 19:02:11 +0000 (19:02 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@53 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/SimpleClient.java
src/org/vamsas/client/castor/VorbaIdFieldHandler.java [deleted file]
src/org/vamsas/client/object.java
src/org/vamsas/client/simpleclient/documentHandler.java

index 4533295..90e394f 100644 (file)
@@ -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 <return>sync</return> 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 (file)
index 55fbe8f..0000000
+++ /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;
-  }
-
-}
index 5f49537..fc13b4f 100644 (file)
  * 
  */
 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;
+  }
 }
index fd6e016..433fef1 100644 (file)
@@ -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;
-  }
+  
   
 }