+package org.vamsas.test.simpleclient;
+
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.vamsas.client.VorbaId;
+import org.vamsas.client.simpleclient.ClientDocument;
+import org.vamsas.client.simpleclient.VamsasArchive;
+import org.vamsas.client.simpleclient.VamsasArchiveReader;
+import org.vamsas.objects.core.Entry;
+import org.vamsas.objects.core.VAMSAS;
+import org.vamsas.objects.core.VamsasDocument;
+import org.vamsas.objects.utils.ProvenanceStuff;
+
+// simple holder to pass to client.
+public class ClientDoc {
+ protected boolean isModified=false;
+ private Log log = LogFactory.getLog(ClientDoc.class);
+ protected VamsasDocument doc;
+ public org.vamsas.objects.core.VAMSAS[] _VamsasRoots;
+ protected VamsasArchive iohandler=null;
+ protected VamsasArchiveReader reader=null;
+ private String user=null;
+
+ /**
+ * @param doc
+ * @param iohandler
+ * @param reader
+ * @param user
+ */
+ public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String user) {
+ super();
+ this.doc = doc;
+ this.iohandler = iohandler;
+ this.reader = reader;
+ this.user = user;
+ _VamsasRoots = doc.getVAMSAS();
+ }
+ // AppDataOutputStream appd;
+ //AppDataOutputStream userd;
+ /* (non-Javadoc)
+ * @see java.lang.Object#finalize()
+ */
+ protected Entry getProvenanceEntry(String action) {
+ // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
+ Entry prov = ProvenanceStuff.newProvenanceEntry(user, action);
+ return prov;
+ }
+ public VAMSAS[] getVamsasRoots() {
+ if (doc==null) {
+ log.debug("Null document for getVamsasRoots(), returning null");
+ return null;
+ }
+ if (iohandler==null) {
+ // LATER: decide on read-only status of ClientDocument object
+ log.warn("getVamsasRoots() called on possibly read-only document.");
+ }
+ if (_VamsasRoots!=null)
+ return _VamsasRoots;
+ VAMSAS[] roots = doc.getVAMSAS();
+ if (roots == null) {
+ // Make a new one to return to client to get filled.
+ _VamsasRoots = new VAMSAS[] { new VAMSAS() };
+ // Do provenance now. just in case.
+ doc.getProvenance().addEntry(getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
+ doc.addVAMSAS(_VamsasRoots[0]);
+ } else {
+ _VamsasRoots = new VAMSAS[roots.length];
+ for (int r=0;r<roots.length; r++)
+ _VamsasRoots[r] = roots[r];
+ }
+ return _VamsasRoots;
+ }
+
+ private int _contains(VAMSAS root, VAMSAS[] docRoots) {
+ if (root==null)
+ return -1;
+ if (docRoots==null || docRoots.length==0)
+ return -1;
+ VorbaId r_id = root.getVorbaId();
+ for (int i=0,j=docRoots.length; i<j; i++) {
+ VorbaId n_id=null;
+ if (docRoots[i]==root || (docRoots[i]!=null && (n_id=docRoots[i].getVorbaId())!=null && n_id.equals(r_id)))
+ return i;
+ }
+ return -1;
+ }
+/**
+ * verify that newr version is really an intact version of the
+ * @param newVersion (may be modified)
+ * @param oldVersion
+ * @return true if newVersion is a valid root that preserves original references
+ */
+ private boolean isValidUpdate(VAMSAS newVersion, final VAMSAS oldVersion) {
+ // ideal - this cascades down the two structures, ensuring that all ID'd objects in one are present in the other.
+ if (oldVersion==newVersion) {
+ // may be a virgin root element.
+ if (!newVersion.isRegistered())
+ iohandler.getVorba().makeVorbaId(newVersion);
+ // Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
+ // just do internal validation for moment.
+ if (newVersion.isValid())
+ return true;
+ return false;
+ } else {
+ // redundant ? if (oldVersion.is__stored_in_document())
+ if (!newVersion.isRegistered())
+ iohandler.getVorba().makeVorbaId(newVersion);
+ if (newVersion.isValid())
+ return true;
+ }
+ return false;
+ }
+ /**
+ /**
+ * merge old and new root vectors
+ * @param newr This array may be written to
+ * @param original
+ * @param the client document (usually this) which this root set belongs to.
+ * @return merged vector of vamsas roots
+ */
+ private VAMSAS[] _combineRoots(VAMSAS[] newr, final VAMSAS[] original, ClientDoc modflag) {
+ Vector rts = new Vector();
+ boolean modified=false;
+ for (int i=0,j=original.length; i<j; i++) {
+ int k = _contains(original[i], newr);
+ if (k>-1) {
+ if (isValidUpdate(newr[k], original[i])) {
+ modified=true;
+ rts.add(newr[k]);
+ newr[k]=null;
+ } else {
+ // LATER: try harder to merge ducument roots.
+ log.warn("Couldn't merge new VAMSAS root "+newr[k].getId());
+ newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD
+ }
+ } else {
+ // add in order.
+ rts.add(original[i]);
+ }
+ }
+ // add remaining (new) roots
+ for (int i=0,j=newr.length; i<j; i++) {
+ if (newr[i]!=null) {
+ rts.add(newr[i]);
+ modified=true;
+ }
+ }
+ newr = new VAMSAS[rts.size()];
+ for (int i=0,j=rts.size(); i<j; i++)
+ newr[i] = (VAMSAS) rts.get(i);
+ if (modflag!=null)
+ modflag.isModified = modified;
+ return newr;
+ }
+
+ /**
+ * update the document with new roots.
+ * LATER: decide: this affects the next call to getVamsasRoots()
+ * @see org.vamsas.IClientDocument.setVamsasRoots
+ */
+ public void setVamsasRoots(VAMSAS[] newroots) {
+ if (doc==null) {
+ log.debug("setVamsasRoots called on null document.");
+ return;
+ }
+ VAMSAS[] newr;
+ if (newroots==null) {
+ log.debug("setVamsasRoots(null) - do nothing.");
+ return;
+ }
+ // are we dealing with same array ?
+ if (_VamsasRoots!=newroots) {
+ // merge roots into local version.
+ newr = new VAMSAS[newroots.length];
+ for (int i=0;i<newr.length;i++)
+ newr[i] = newroots[i];
+ newr=_combineRoots(newr,_VamsasRoots,this);
+ } else {
+ newr = new VAMSAS[_VamsasRoots.length];
+ for (int i=0;i<newr.length;i++)
+ newr[i]=_VamsasRoots[i];
+ }
+ // actually compare with document root set for final combination (to ensure nothing is lost)
+ _VamsasRoots = _combineRoots(newr, doc.getVAMSAS(), this);
+ }
+
+
+ /* (non-Javadoc)
+ * LATER: decide: this affects the next call to getVamsasRoots()
+ * @see org.vamsas.client.IClientDocument#addVamsasRoot(org.vamsas.objects.core.VAMSAS)
+ */
+ public void addVamsasRoot(VAMSAS newroot) {
+ if (doc==null) {
+ log.debug("addVamsasRoots called on null document.");
+ return;
+ }
+ VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
+ _VamsasRoots = newroots;
+ }
+
+ public VamsasArchiveReader getReader() {
+ return reader;
+ }
+ protected void finalize() throws Throwable {
+ super.finalize();
+ //if (reader!=null)
+ // reader.close();
+ //reader=null;
+// if (iohandler!=null) {
+// iohandler.cancelArchive(); // otherwise the original may be overwritten.
+// }
+ }
+
+}
\ No newline at end of file