minimally debugged idFactory and vorbaId mechanism. Inelegant!
authorjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 16 Jan 2006 20:05:03 +0000 (20:05 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 16 Jan 2006 20:05:03 +0000 (20:05 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@138 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/SessionHandle.java
src/org/vamsas/client/VorbaIdFactory.java
src/org/vamsas/client/VorbaXmlBinder.java
src/org/vamsas/client/object.java
src/org/vamsas/client/simpleclient/IdFactory.java [new file with mode: 0644]
src/org/vamsas/client/simpleclient/VamsasArchive.java
src/org/vamsas/objects/utils/Seq.java
src/org/vamsas/test/simpleclient/VamsasArchive.java

index 1c26bfe..736fee3 100644 (file)
@@ -12,6 +12,13 @@ package org.vamsas.client;
 public class SessionHandle {
   
   /**
+   * @param sessionUrn
+   */
+  public SessionHandle(String sessionUrn) {
+    super();
+    SessionUrn = sessionUrn;
+  }
+  /**
    * @return Returns the sessionUrn.
    */
   public String getSessionUrn() {
index ece1357..335c710 100644 (file)
@@ -6,6 +6,8 @@
  */
 package org.vamsas.client;
 
+import java.util.Hashtable;
+
 /**
  * A VorbaIdFactory is constructed by an IClient instance.
  * It guarantees that any new VorbaId objects are unique 
@@ -14,6 +16,7 @@ package org.vamsas.client;
  * @author jimp
  */
 public abstract class VorbaIdFactory implements IVorbaIdFactory {
+  protected Hashtable extantids=null;
   /**
    * construct a new id appropriate for this client in the vamsas session.
    * 
@@ -21,6 +24,25 @@ public abstract class VorbaIdFactory implements IVorbaIdFactory {
    *         correctly.
    */
   public abstract VorbaId makeVorbaId();
+  
+  /**
+   * internal method to access the protected VorbaId object constructor
+   * This shennanigan is to prevent casual generation of VorbaIds 
+   * (which may destroy the integrity of a Vamsas Document!)
+   * @param id
+   * @return new VorbaId object
+   */
+  protected VorbaId newId(String id) {
+    return VorbaId.newId(id);
+  }
+  /**
+   * Called by VorbaXmlBinder so the record of newly unmarshalled object Ids
+   * is accessible to the Document's VorbaIdFactory instance. 
+   * @param idtable
+   */
+  protected void setNewIdHash(Hashtable idtable) {
+    extantids = idtable;
+  }
   /**
    * TODO: decide if these are needed.
    * 
index 9fc6965..ec6c7f4 100644 (file)
@@ -4,6 +4,7 @@
 package org.vamsas.client;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Reader;
 import java.io.Writer;
 import java.lang.reflect.Field;
@@ -11,8 +12,12 @@ import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Vector;
 
+import org.exolab.castor.mapping.FieldHandler;
+import org.exolab.castor.mapping.GeneralizedFieldHandler;
+import org.exolab.castor.mapping.ValidityException;
 import org.exolab.castor.xml.IDResolver;
 import org.exolab.castor.xml.MarshalException;
+import org.exolab.castor.xml.MarshalListener;
 import org.exolab.castor.xml.Marshaller;
 import org.exolab.castor.xml.UnmarshalListener;
 import org.exolab.castor.xml.Unmarshaller;
@@ -25,7 +30,7 @@ import org.vamsas.objects.core.VamsasDocument;
  * to avoid validation exceptions when marshalling new objects
  * into the vamsas document.
  */
-public class VorbaXmlBinder implements UnmarshalListener {
+public class VorbaXmlBinder extends GeneralizedFieldHandler implements UnmarshalListener, MarshalListener {
   private final IVorbaIdFactory vorbafactory;
 
   private final Vector obj;
@@ -62,7 +67,7 @@ public class VorbaXmlBinder implements UnmarshalListener {
    */
   public void initialized(Object object) {
   }
-
+  
   /*
    * Check if the object has an 'id' field - if it does, copy the value into
    * the VorbaId field of object, and add the object to the VorbaId hash.
@@ -112,17 +117,46 @@ public class VorbaXmlBinder implements UnmarshalListener {
    * writes the VamsasDocument to the given stream.
    * TODO: ensure that (at least) default provenance entries are written for objects.
    * @param outstream
+   * @param vorba valid VorbaIdFactory to construct any missing IDs 
    * @param doc
    * @throws IOException
    * @throws MarshalException
    * @throws ValidationException
    */
-  private static void setVamsasDocument(Writer outstream, VamsasDocument doc)
+  public static void putVamsasDocument(PrintWriter outstream, VorbaIdFactory vorba, VamsasDocument doc)
       throws IOException, MarshalException, ValidationException {
+    // Ensure references
+    if (vorba==null)
+      throw new Error("Null VorbaIdVactory Parameter");
+    if (doc.__vorba==null)
+      doc.__vorba = vorba;
+    doc.__ensure_instance_ids(); // this may take a while. Do we allow for cyclic references ? 
+    final Vector refstomake = new Vector();
+    VorbaXmlBinder binder = new VorbaXmlBinder(vorba, refstomake, vorba.extantids);
     Marshaller marshaller = new Marshaller(outstream);
+    marshaller.setMarshalAsDocument(true);
+    marshaller.setMarshalListener(binder);
     marshaller.marshal(doc);
   }
 
+  private static boolean ensure_references(Vector unrefed, Hashtable objrefs) {
+    boolean sync=true;
+    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 sync;
+  }
   /**
      * Unmarshals a vamsasDocument object from a stream, registers
      * unregistered objects, records existing VorbaIds, and completes 
@@ -133,12 +167,13 @@ public class VorbaXmlBinder implements UnmarshalListener {
      * 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.
+   * @param factory - the SimpleClient's properly configured VorbaId factory to make new references.
+   * @param root the root element's org.vamsas.objects.core object.
      * @return null or {(Object) VamsasDocument object, (Object) Hashtable of object references, (Object) Boolean(sync) }
      */
-  public static Object[] getVamsasDocument(Reader instream,
-        IVorbaIdFactory factory) {
-      Unmarshaller unmarshaller = new Unmarshaller(instream);
+  public static Object[] getVamsasObjects(Reader instream,
+        IVorbaIdFactory factory, object root) {
+      Unmarshaller unmarshaller = new Unmarshaller(root);
       unmarshaller.setIDResolver(new IDResolver() {
         public Object resolve(String id) {
           System.err.println("Warning - id " + id
@@ -156,25 +191,11 @@ public class VorbaXmlBinder implements UnmarshalListener {
       try {
         while (instream.ready()) {
           Object obj = unmarshaller.unmarshal(instream);
-          boolean sync=true;
-          if (obj instanceof VamsasDocument) {
-            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)};
+          boolean sync=ensure_references(unrefed, objrefs);
+          if (!(obj instanceof object))
+            return null;
+          return new Object[] { obj, objrefs, new Boolean(sync)};
           }
-        }
       } catch (MarshalException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
@@ -187,4 +208,103 @@ public class VorbaXmlBinder implements UnmarshalListener {
       }
       return null;
     }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.xml.MarshalListener#postMarshal(java.lang.Object)
+   */
+  public void postMarshal(Object object) {
+    // TODO Auto-generated method stub
+    
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.xml.MarshalListener#preMarshal(java.lang.Object)
+   */
+  public boolean preMarshal(Object newobj) {
+    if (newobj instanceof object) {
+      object nobj = (object) newobj;
+      nobj.set__stored_in_document(true);
+      Field fd = null;
+      try {
+        if (nobj.isRegisterable()) {
+          // make sure the id field is set
+          nobj.__vorba = vorbafactory;
+          fd = nobj.getClass().getField("_id");
+          if (fd.get(nobj) != null) {
+            fd.set(nobj, nobj.getVorbaId().getId());
+            /* all thats needed perhaps
+             * 
+             *if (idstring.length() > 0) {
+              if (!objrefs.containsKey(idstring)) {
+                objrefs.put(idstring, nobj);
+                nobj.setVorbaId(VorbaId.newId(idstring));
+              } else {
+                System.err.println("Serious problem : duplicate id '"+idstring+"' found! expect badness.");
+                return false; // TODO: HANDLE duplicate XML ids correctly
+              }*/
+          }
+        }
+      } catch (Exception e) {
+        return false;
+      };
+      
+    }
+    return false;
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponGet(java.lang.Object)
+   */
+  public Object convertUponGet(Object value) {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponSet(java.lang.Object)
+   */
+  public Object convertUponSet(Object value) {
+    // 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;
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.GeneralizedFieldHandler#newInstance(java.lang.Object, java.lang.Object[])
+   */
+  public Object newInstance(Object parent, Object[] args) throws IllegalStateException {
+    // TODO Auto-generated method stub
+    return super.newInstance(parent, args);
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.GeneralizedFieldHandler#newInstance(java.lang.Object)
+   */
+  public Object newInstance(Object parent) throws IllegalStateException {
+    // TODO Auto-generated method stub
+    return super.newInstance(parent);
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.GeneralizedFieldHandler#setCollectionIteration(boolean)
+   */
+  public void setCollectionIteration(boolean autoCollectionIteration) {
+    // TODO Auto-generated method stub
+    super.setCollectionIteration(autoCollectionIteration);
+  }
+
+  /* (non-Javadoc)
+   * @see org.exolab.castor.mapping.AbstractFieldHandler#hasValue(java.lang.Object)
+   */
+  public boolean hasValue(Object object) {
+    // TODO Auto-generated method stub
+    return super.hasValue(object);
+  }
 }
\ No newline at end of file
index 040222a..6498d70 100644 (file)
@@ -3,6 +3,18 @@
  */
 package org.vamsas.client;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.exolab.castor.mapping.FieldDescriptor;
+import org.exolab.castor.mapping.FieldHandler;
+import org.exolab.castor.xml.util.XMLClassDescriptorImpl;
+import org.vamsas.test.simpleclient.VamsasArchive;
+
 /**
  * Base class for all Vamsas objects extracted from an IClientDocument. An
  * object maybe registered or unregistered.
@@ -11,7 +23,8 @@ package org.vamsas.client;
  * 
  */
 public abstract class object {
-
+  static Log log = LogFactory.getLog(object.class);
+  
   /**
    * unique id for all vamsas objects allows unambiguous referencing to any
    * object in the vamsas document
@@ -40,11 +53,10 @@ public abstract class object {
    */
   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
+    // 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())) {
+      java.lang.reflect.Field fd = this.getClass().getDeclaredField("_id");
+      if (String.class.isAssignableFrom(fd.getType())) {
         this.setRegisterable(true);
       }
     } catch (SecurityException e) {
@@ -60,19 +72,27 @@ public abstract class object {
    */
   protected void setInstanceIdField() {
     if (registerable) {
-      if (vorbaId != null)
+      if (__vorba != null)
         try {
-          java.lang.reflect.Field fd = this.getClass().getField("id");
-          fd.set((Object) this, (Object) new String(vorbaId.id));
-        } catch (IllegalAccessException e) {
+          Method fd = this.getClass().getMethod("setId", new Class[] { String.class });
+          fd.invoke((Object) this, new Object[] {new String(this.getVorbaId().id)});
+          log.info(this.getClass().getName()+" called setInstanceIdField!");
+        } catch (InvocationTargetException e) { 
+          System.err
+          .println("SourceGeneration of "
+              + this.getClass().toString()
+              + "\n has resulted in an inaccessible 'setId' method!\nCannot set ID from the vorbaId object.");
+          e.printStackTrace(System.err);
+        }
+        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.");
+                  + "\n has resulted in an inaccessible 'setId' method!\nCannot set ID from the vorbaId object.");
           e.printStackTrace(System.err);
         } catch (SecurityException e) {
           e.printStackTrace(System.err);
-        } catch (NoSuchFieldException e) {
+        } catch (NoSuchMethodException e) {
           this.setRegisterable(false);
         }
     } else {
@@ -193,4 +213,103 @@ public abstract class object {
   protected void setRegisterable(boolean registerable) {
     this.registerable = registerable;
   }
+  /**
+   * ensure's internal id field corresponds to vorbaId and
+   * cascade through all fields referring to an instance of object
+   * calling the same method on them.
+   * TODO: LATER: properly apply castors own field mechanisms to get at accessors
+   *
+   */
+  protected void __ensure_instance_ids() {
+    if (__vorba==null)
+      throw new Error("Improperly intialised org.vamsas.client.object - no VorbaFactory given.");
+    log.info(this.getClass()+".__ensure_instance_ids()");
+    if (!__stored_in_document && registerable)
+      setInstanceIdField();
+    Class descriptor = null;
+    XMLClassDescriptorImpl descimpl = null;
+    try {
+      // castor descriptor resolver magic
+      descriptor = this.getClass().getClassLoader().loadClass(this.getClass().getName()+"Descriptor");
+      descimpl = (XMLClassDescriptorImpl) descriptor.getConstructor(null).newInstance(null);
+    } catch (Exception e) {
+      log.error("Couldn't resolve descriptor for "+this.getClass().getName());
+      return;
+    }
+    FieldDescriptor fields[] = descimpl.getFields();
+    for (int i=0,j=fields.length; i<j; i++) {
+      Class type= fields[i].getFieldType();
+      if (type.isArray()) {
+        if (object[].class.isAssignableFrom(type)) {
+          try {
+            Object val = fields[i].getHandler().getValue(this);
+            if (val!=null) {
+              object vals[] = (object[]) val; 
+              for (int k=0, l=vals.length; k<l; k++) {
+                if (vals[k].__vorba==null)
+                  vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
+                vals[k].__ensure_instance_ids();
+              }
+            }
+          }
+          catch (Exception e) {
+            log.error("Client error - could not access array "+type.getName()+" in "+this.getClass().getName(), e);
+          }
+        }
+      } else
+        if (object.class.isAssignableFrom(type)) {
+          try {
+            FieldHandler fh = fields[i].getHandler();
+            object rf = null;
+            if (fh != null) {
+              Object fval = fh.getValue(this);
+              if (fval!=null) {
+                if (fval.getClass().isArray()) {
+                  //if (object[].class.isAssignableFrom(type)) {
+                    try {
+                      object vals[] = (object[]) fval; 
+                      for (int k=0, l=vals.length; k<l; k++) {
+                        if (vals[k].__vorba==null)
+                          vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
+                        vals[k].__ensure_instance_ids();
+                      }
+                    }
+                    catch (Exception e) {
+                      log.error("Client error - could not access (fhval)array "+type.getName()+" in "+this.getClass().getName(), e);
+                    }
+                  //}
+                } else {
+                  rf = (object) fval;
+                  log.info("Got value for "+fields[i].getFieldName());
+                }
+              }
+            } else {
+              // fuck around, fuck around, jump up jump up and get down! */
+              Object o = fields[i].getClassDescriptor();
+              if (o!=null) {
+                // XMLClassDescriptorImpl fclasdes = (XMLClassDescriptorImpl) o;
+                String methname = "get"+fields[i].getFieldName();
+                Method fgetmeth = this.getClass().getMethod(methname,null);
+                if (fgetmeth!=null) {
+                  Object fval = fgetmeth.invoke(this,null);
+                  if (fval!=null)
+                    rf = (object) fval;
+                } else {
+                  log.warn("Couldn't find "+this.getClass().getName()+"."+methname);
+                }
+              }
+            }
+            if (rf!=null) {
+              if (rf.__vorba==null)
+                rf.__vorba = __vorba; // propagate IVorbaIdFactory
+              rf.__ensure_instance_ids();
+            }
+          }
+          catch (Exception e) {
+            log.error("Client error - could not access "+type.getName()+" in "+this.getClass().getName(), e);
+          }
+        }
+    }
+    
+  }
 }
diff --git a/src/org/vamsas/client/simpleclient/IdFactory.java b/src/org/vamsas/client/simpleclient/IdFactory.java
new file mode 100644 (file)
index 0000000..c046af5
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ * 
+ */
+package org.vamsas.client.simpleclient;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.vamsas.client.ClientHandle;
+import org.vamsas.client.SessionHandle;
+import org.vamsas.client.UserHandle;
+import org.vamsas.client.VorbaId;
+import org.vamsas.client.VorbaIdFactory;
+import org.vamsas.objects.utils.document.VersionEntries;
+
+import java.util.Hashtable;
+import java.util.zip.CRC32;
+/**
+ * Simplest VorbaId constructor
+ * @author jimp
+ *
+ */
+public class IdFactory extends VorbaIdFactory {
+  static Log log = LogFactory.getLog(IdFactory.class);
+  private SessionHandle session=null;
+  private ClientHandle client;
+  private UserHandle user;
+  private CRC32 unique=new CRC32(); // used to attempt a unique but predictable stream for IDs
+  private String idstring;
+  int sequence=0; // incrementing value for next new ID
+  /**
+   * 
+   */
+  public IdFactory() {
+    super();
+    // TODO Auto-generated constructor stub
+  }
+  
+  /**
+   * @param session
+   * @param client
+   * @param user
+   */
+  protected IdFactory(SessionHandle session, ClientHandle client, UserHandle user) {
+    super();
+    this.session = session;
+    this.client = client;
+    this.user = user;
+    unique.reset();
+    unique.update(new Object[] { session, client, user}.toString().getBytes());
+    idstring = "vamsas:"+session.getSessionUrn()+":"+unique.getValue()+":"+client.getClientUrn()+"/";
+    sequence=0;
+    extantids=new Hashtable();
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#makeVorbaId()
+   */
+  public VorbaId makeVorbaId() {
+    if (session==null)
+      throw new Error("makeVorbaId called on improperly initialised IdFactory object!");
+    String newidstring;
+    do {
+      if (sequence!=0) {
+        sequence++;
+      } else {
+        idstring+="1/";
+      }
+      newidstring=idstring+Integer.toString(sequence);
+    } while (extantids.containsKey(newidstring));
+    VorbaId id = newId(newidstring);
+    return id;
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#setSession(org.vamsas.client.SessionHandle)
+   */
+  protected void setSession(SessionHandle sessionhandle) {
+    if (sessionhandle!=null)
+      session=sessionhandle;
+    else
+      log.warn("setSession(null) called.");
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#getSessionHandle()
+   */
+  public SessionHandle getSessionHandle() {
+    return session;
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#setClient(org.vamsas.client.ClientHandle)
+   */
+  protected void setClient(ClientHandle appHandle) {
+    if (appHandle!=null)
+      client = appHandle;
+    else
+      log.warn("setClient(null) called.");
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#getClientHandle()
+   */
+  public ClientHandle getClientHandle() {
+    return client;
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#setUser(org.vamsas.client.UserHandle)
+   */
+  protected void setUser(UserHandle userHandle) {
+  if (userHandle!=null)
+    user = userHandle;
+  else
+    log.warn("setUser(null) called.");
+  }
+
+  /* (non-Javadoc)
+   * @see org.vamsas.client.VorbaIdFactory#getUserHandle()
+   */
+  public UserHandle getUserHandle() {
+    return user;
+  }
+  /**
+   * Convenience method used for default behaviour in testing 
+   * and any anonymous internal vamsasDocument unmarshalling
+   * @param clientname
+   * @return
+   */
+  protected  static IdFactory getDummyFactory(String clientname) {
+    if (clientname==null)
+      clientname="org.vamsas.client.simpleclient.IdFactory";
+    return new IdFactory(new SessionHandle("dummy.session"), 
+        new ClientHandle(clientname,VersionEntries.latestVersion()), 
+        new UserHandle("arnoldUser", "none"));
+  }
+}
index ec42a33..721cdf9 100644 (file)
@@ -7,6 +7,8 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.Hashtable;
 import java.util.jar.JarEntry;
@@ -14,6 +16,12 @@ import java.util.jar.JarOutputStream;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.vamsas.client.ClientHandle;
+import org.vamsas.client.IVorbaIdFactory;
+import org.vamsas.client.SessionHandle;
+import org.vamsas.client.UserHandle;
+import org.vamsas.client.VorbaIdFactory;
+import org.vamsas.client.VorbaXmlBinder;
 import org.vamsas.client.object;
 import org.vamsas.objects.core.ApplicationData;
 import org.vamsas.objects.core.VAMSAS;
@@ -118,7 +126,7 @@ public class VamsasArchive {
       }
     }
   }
-
+  
   /**
    * called after archive is written to put file in its final place
    * TODO: FINISH ?? original should have sessionFile, and archive should also have sessionFile
@@ -126,22 +134,22 @@ public class VamsasArchive {
   private void updateOriginal() {
     if (!virginArchive) {
       // make sure original document really is backed up and then overwrite it.
-        if (odoc!=null) {
-          // try to shut the odoc reader.
-          odoc.close();
-          odoc = null;
-        }
-        // Make a backup if it isn't done already
-        if (originalBackup==null)
-          makeBackup();
-        try {
-          // copy new Archive data that was writen to a temporary file
-          odoclock.updateFrom(null, rchive);
-        }
-        catch (IOException e) {
-          log.error("Problem updating archive from temporary file! - backup in '"
-              +backupFile().getAbsolutePath()+"'",e);
-        }
+      if (odoc!=null) {
+        // try to shut the odoc reader.
+        odoc.close();
+        odoc = null;
+      }
+      // Make a backup if it isn't done already
+      if (originalBackup==null)
+        makeBackup();
+      try {
+        // copy new Archive data that was writen to a temporary file
+        odoclock.updateFrom(null, rchive);
+      }
+      catch (IOException e) {
+        log.error("Problem updating archive from temporary file! - backup in '"
+            +backupFile().getAbsolutePath()+"'",e);
+      }
     } else {
       // don't need to do anything.
     }
@@ -484,6 +492,22 @@ public class VamsasArchive {
     }
     return null;
   }
+  protected VorbaIdFactory vorba = null;
+  
+  /**
+   * @return Returns the current VorbaIdFactory for the archive.
+   */
+  public VorbaIdFactory getVorba() {
+    return vorba;
+  }
+
+  /**
+   * @param vorba the VorbaIdFactory to use for accessing vamsas objects.
+   */
+  public void setVorba(VorbaIdFactory vorba) {
+    this.vorba = vorba;
+  }
+
   /**
    * Access and return current vamsas Document, if it exists, or create a new one 
    * (without affecting VamsasArchive object state - so is NOT THREAD SAFE)
@@ -498,7 +522,7 @@ public class VamsasArchive {
    */
   public VamsasDocument getVamsasDocument() throws IOException, 
   org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
-    VamsasDocument doc = getOriginalVamsasDocument(this);
+    VamsasDocument doc = getOriginalVamsasDocument(this, getVorba());
     if (doc!=null)
       return doc;
     // Create a new document and return it
@@ -521,23 +545,64 @@ public class VamsasArchive {
    */
   public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths) throws IOException, 
   org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+    return VamsasArchive.getOriginalVamsasDocument(ths, null);
+  }
+  private VorbaIdFactory makeDefaultFactory(VorbaIdFactory vorba) {
+    if (vorba==null) {
+      vorba = getVorba();
+      if (vorba==null) {
+        vorba = IdFactory.getDummyFactory("simpleclient.VamsasArchive");
+        setVorba(vorba); // save for later use
+      }
+    }
+    return vorba;
+  }
+  /**
+   * Uses VorbaXmlBinder to retrieve the VamsasDocument from the original archive referred to by ths
+   * @param ths
+   * @param vorba
+   * @return
+   * @throws IOException
+   * @throws org.exolab.castor.xml.MarshalException
+   * @throws org.exolab.castor.xml.ValidationException
+   */
+  public static VamsasDocument getOriginalVamsasDocument(VamsasArchive ths, VorbaIdFactory vorba) throws IOException, 
+  org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
     VamsasArchiveReader oReader = ths.getOriginalArchiveReader();
     if (oReader!=null) {
+      // check the factory
+      vorba = ths.makeDefaultFactory(vorba);
       if (oReader.isValid()) {
         InputStreamReader vdoc = new InputStreamReader(oReader.getVamsasDocumentStream());
-        VamsasDocument doc = VamsasDocument.unmarshal(vdoc);
-        if (doc!=null) 
-          return doc;
-      } else {
+        Object unmarsh[] = VorbaXmlBinder.getVamsasObjects(vdoc, vorba, new VamsasDocument());
+        if (unmarsh==null)
+          log.fatal("Couldn't unmarshall document!");
+        
+        object[] vobjs = (object[]) unmarsh[0];
+        if (vobjs!=null) { 
+          VamsasDocument doc=(VamsasDocument) vobjs[0];
+          if (doc!=null)
+            return doc;
+        }
+        log.debug("Found no VamsasDocument object in properly formatted Vamsas Archive.");
+      } else {        
         // deprecated data handler
         InputStream vxmlis = oReader.getVamsasXmlStream();
         if (vxmlis!=null) { // Might be an old vamsas file.
           BufferedInputStream ixml = new BufferedInputStream(oReader.getVamsasXmlStream());
           InputStreamReader vxml = new InputStreamReader(ixml);
-          VAMSAS root[] = new VAMSAS[1];
-          root[0] = VAMSAS.unmarshal(vxml);
-          if (root[0]!=null) {
-            log.debug("Reading old format vamsas.xml into a dummy document.");
+          Object unmarsh[] = VorbaXmlBinder.getVamsasObjects(vxml, vorba, new VAMSAS());
+          
+          if (unmarsh==null)
+            log.fatal("Couldn't unmarshall document!");
+
+          VAMSAS root[]= new VAMSAS[] { null};
+          root[0] = (VAMSAS) unmarsh[0]; 
+          
+          if (root[0]==null) {
+            log.debug("Found no VAMSAS object in VamsasXML stream.");
+          } else {
+            log.debug("Making new VamsasDocument from VamsasXML stream.");
             VamsasDocument doc = DocumentStuff.newVamsasDocument(root, 
                 ProvenanceStuff.newProvenance(
                     "org.vamsas.simpleclient.VamsasArchive", // TODO: VAMSAS: decide on 'system' operations provenance form
@@ -550,7 +615,13 @@ public class VamsasArchive {
           }
         }
       }
-    } // otherwise - there was no valid original document to read.
+    }
+    // otherwise - there was no valid original document to read.
     return null;    
   }
+  public void putVamsasDocument(VamsasDocument doc) throws IOException, 
+  org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+    VorbaIdFactory vorba = makeDefaultFactory(null);
+    VorbaXmlBinder.putVamsasDocument(getDocumentOutputStream(), vorba, doc);
+  }
 }
index 7564f1d..ca83223 100644 (file)
@@ -87,7 +87,6 @@ public class Seq {
        if ((start-end)!=Sequence.length())
          seq.setEnd(end+Sequence.length());
      }
-     seq.getVorbaId();
      return seq;
   }
   public static AlignmentSequence newAlignmentSequence(String name, String alSequence, Sequence refseq, int start, int end) {
index 0b85bfc..df18387 100644 (file)
@@ -62,7 +62,13 @@ public class VamsasArchive {
         apuser.setOrganization("disOrganised");
         String appdata_ref = "vamsas:org.vamsas.test.simpleclient.VamsasArchive/"+apuser.getOrganization()+"/"+apuser.getFullname();
         org.vamsas.client.simpleclient.VamsasArchive va = new org.vamsas.client.simpleclient.VamsasArchive(backup, true);
+        log.info("Getting the document from the backup-original.");
+        VamsasDocument vadoc;
         VamsasArchiveReader vread = va.getOriginalArchiveReader();
+        
+        vadoc = va.getVamsasDocument();
+        log.info("Got document. Adding stuff.");
+        
         if (vread.getAppdataStream(appdata_ref)!=null) {
           int i=0;
           while (vread.getAppdataStream(appdata_ref+"/"+Integer.toString(++i))!=null)
@@ -76,19 +82,19 @@ public class VamsasArchive {
         apdos.writeObject(appdata_ref);
         apdos.writeObject(apuser); // some random content
         apdos.close(); // this should *not* close the archive!
+        log.info("Written Appdata Stream");
         log.info("Preparing to write new document.");
         doc.addApplicationData(appdata);
         doc.addVAMSAS(Core.getDemoVamsas());
-        PrintWriter vxml = varchive.getDocumentOutputStream();
-        doc.marshal(vxml);
+        va.putVamsasDocument(doc); // gets stream and puts it.
         // TODO: verify that the vxml stream close method overridden ?
         va.closeArchive();
         log.info("Dump of new vamsas document :");
         va = new org.vamsas.client.simpleclient.VamsasArchive(backup, true); // TODO - refactor Reader class to have deserializing helpers
         ArchiveReports.reportDocument(va.getVamsasDocument(), va.getOriginalArchiveReader(), true);
-        backup.delete(); // tidy up
+        // backup.delete(); // tidy up
       }
-      log.info("Cancelling write to original archive "+av);
+      log.info("Now Cancelling write to original archive "+av);
       varchive.cancelArchive();
 
     } catch (Exception e) {