1 package org.vamsas.test.simpleclient;
3 import java.util.Hashtable;
4 import java.util.Vector;
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.vamsas.client.Vobject;
9 import org.vamsas.client.VorbaId;
10 import org.vamsas.client.simpleclient.ClientDocument;
11 import org.vamsas.client.simpleclient.VamsasArchive;
12 import org.vamsas.client.simpleclient.VamsasArchiveReader;
13 import org.vamsas.objects.core.Entry;
14 import org.vamsas.objects.core.VAMSAS;
15 import org.vamsas.objects.core.VamsasDocument;
16 import org.vamsas.objects.utils.ProvenanceStuff;
18 // simple holder to pass to client.
19 public class ClientDoc {
20 protected boolean isModified=false;
21 private Log log = LogFactory.getLog(ClientDoc.class);
22 protected VamsasDocument doc;
23 public org.vamsas.objects.core.VAMSAS[] _VamsasRoots;
24 protected VamsasArchive iohandler=null;
25 protected VamsasArchiveReader reader=null;
26 private String user=null;
27 private String app=null;
36 public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String app, String user, Hashtable objrefs) {
39 this.iohandler = iohandler;
43 this.objrefs = objrefs;
44 _VamsasRoots = doc.getVAMSAS();
46 // AppDataOutputStream appd;
47 //AppDataOutputStream userd;
49 * @see java.lang.Object#finalize()
51 protected Entry getProvenanceEntry(String action) {
52 // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
53 Entry prov = ProvenanceStuff.newProvenanceEntry(app, user, action);
56 public VAMSAS[] getVamsasRoots() {
58 log.debug("Null document for getVamsasRoots(), returning null");
61 if (iohandler==null) {
62 // LATER: decide on read-only status of ClientDocument object
63 log.warn("getVamsasRoots() called on possibly read-only document.");
65 if (_VamsasRoots!=null)
67 VAMSAS[] roots = doc.getVAMSAS();
69 // Make a new one to return to client to get filled.
70 _VamsasRoots = new VAMSAS[] { new VAMSAS() };
71 // Do provenance now. just in case.
72 doc.getProvenance().addEntry(getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
73 doc.addVAMSAS(_VamsasRoots[0]);
75 _VamsasRoots = new VAMSAS[roots.length];
76 for (int r=0;r<roots.length; r++)
77 _VamsasRoots[r] = roots[r];
82 private int _contains(VAMSAS root, VAMSAS[] docRoots) {
85 if (docRoots==null || docRoots.length==0)
87 VorbaId r_id = root.getVorbaId();
88 for (int i=0,j=docRoots.length; i<j; i++) {
90 if (docRoots[i]==root || (docRoots[i]!=null && (n_id=docRoots[i].getVorbaId())!=null && n_id.equals(r_id)))
96 * verify that newr version is really an intact version of the
97 * @param newVersion (may be modified)
99 * @return true if newVersion is a valid root that preserves original references
101 private boolean isValidUpdate(VAMSAS newVersion, final VAMSAS oldVersion) {
102 // ideal - this cascades down the two structures, ensuring that all ID'd objects in one are present in the other.
103 if (oldVersion==newVersion) {
104 // may be a virgin root element.
105 if (!newVersion.isRegistered())
106 iohandler.getVorba().makeVorbaId(newVersion);
107 // Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
108 // just do internal validation for moment.
109 if (newVersion.isValid())
113 // redundant ? if (oldVersion.is__stored_in_document())
114 if (!newVersion.isRegistered())
115 iohandler.getVorba().makeVorbaId(newVersion);
116 if (newVersion.isValid())
123 * merge old and new root vectors
124 * @param newr This array may be written to
126 * @param the client document (usually this) which this root set belongs to.
127 * @return merged vector of vamsas roots
129 private VAMSAS[] _combineRoots(VAMSAS[] newr, final VAMSAS[] original, ClientDoc modflag) {
130 Vector rts = new Vector();
131 boolean modified=false;
132 for (int i=0,j=original.length; i<j; i++) {
133 int k = _contains(original[i], newr);
135 if (isValidUpdate(newr[k], original[i])) {
140 // LATER: try harder to merge ducument roots.
141 log.warn("Couldn't merge new VAMSAS root "+newr[k].getId());
142 newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD
146 rts.add(original[i]);
149 // add remaining (new) roots
150 for (int i=0,j=newr.length; i<j; i++) {
156 newr = new VAMSAS[rts.size()];
157 for (int i=0,j=rts.size(); i<j; i++)
158 newr[i] = (VAMSAS) rts.get(i);
160 modflag.isModified = modified;
165 * update the document with new roots.
166 * LATER: decide: this affects the next call to getVamsasRoots()
167 * @see org.vamsas.IClientDocument.setVamsasRoots
169 public void setVamsasRoots(VAMSAS[] newroots) {
171 log.debug("setVamsasRoots called on null document.");
175 if (newroots==null) {
176 log.debug("setVamsasRoots(null) - do nothing.");
179 // are we dealing with same array ?
180 if (_VamsasRoots!=newroots) {
181 // merge roots into local version.
182 newr = new VAMSAS[newroots.length];
183 for (int i=0;i<newr.length;i++)
184 newr[i] = newroots[i];
185 newr=_combineRoots(newr,_VamsasRoots,this);
187 newr = new VAMSAS[_VamsasRoots.length];
188 for (int i=0;i<newr.length;i++)
189 newr[i]=_VamsasRoots[i];
191 // actually compare with document root set for final combination (to ensure nothing is lost)
192 _VamsasRoots = _combineRoots(newr, doc.getVAMSAS(), this);
197 * LATER: decide: this affects the next call to getVamsasRoots()
198 * @see org.vamsas.client.IClientDocument#addVamsasRoot(org.vamsas.objects.core.VAMSAS)
200 public void addVamsasRoot(VAMSAS newroot) {
202 log.debug("addVamsasRoots called on null document.");
205 VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
206 _VamsasRoots = newroots;
209 public VamsasArchiveReader getReader() {
212 protected void finalize() throws Throwable {
217 // if (iohandler!=null) {
218 // iohandler.cancelArchive(); // otherwise the original may be overwritten.
221 private java.util.Hashtable objrefs=null;
223 public VorbaId[] registerObjects(Vobject[] unregistered) {
225 log.warn("registerObjects[] called on null document.");
229 log.warn("registerObjects[] called for null objrefs hasharray.");
232 if (unregistered!=null) {
233 VorbaId ids[] = new VorbaId[unregistered.length];
234 for (int i=0,k=unregistered.length; i<k; i++)
235 if (unregistered[i]!=null) {
236 log.warn("Null Vobject passed to registerObject[] at position "+i);
239 ids[i]=registerObject(unregistered[i]);
241 log.debug("Registered "+unregistered.length+" objects - total of "+objrefs.size()+" ids.");
247 * @see org.vamsas.client.IClientDocument#registerObject(org.vamsas.client.Vobject)
249 public VorbaId registerObject(Vobject unregistered) {
251 log.warn("registerObjects called on null document.");
255 log.warn("registerObjects called for null objrefs hasharray.");
258 if (iohandler==null) {
259 log.warn("registerObjects called for read only document.");
263 if (unregistered!=null) {
264 VorbaId id = iohandler.getVorba().makeVorbaId(unregistered);
265 log.debug("Registered object - total of "+objrefs.size()+" ids.");
268 log.warn("Null Vobject passed to registerObject.");
275 * @see org.vamsas.client.IClientDocument#getObject(org.vamsas.client.VorbaId)
277 public Vobject getObject(VorbaId id) {
279 log.debug("getObject called on null objrefs list.");
282 if (objrefs.containsKey(id))
283 return (Vobject) objrefs.get(id);
284 log.debug("Returning null Vobject reference for id "+id.getId());
291 * @see org.vamsas.client.IClientDocument#getObjects(org.vamsas.client.VorbaId[])
293 public Vobject[] getObjects(VorbaId[] ids) {
295 log.debug("getObject[] called on null objrefs list.");
298 Vobject[] vo = new Vobject[ids.length];
299 for (int i=0,j=ids.length; i<j;i++)
300 if (objrefs.containsKey(ids[i]))
301 vo[i] = (Vobject) objrefs.get(ids[i]);
303 log.debug("Returning null Vobject reference for id "+ids[i].getId());