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;
9 import uk.ac.vamsas.client.IClientAppdata;
10 import uk.ac.vamsas.client.Vobject;
11 import uk.ac.vamsas.client.VorbaId;
12 import uk.ac.vamsas.client.simpleclient.ClientDocument;
13 import uk.ac.vamsas.client.simpleclient.VamsasArchive;
14 import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;
15 import uk.ac.vamsas.objects.core.Entry;
16 import uk.ac.vamsas.objects.core.VAMSAS;
17 import uk.ac.vamsas.objects.core.VamsasDocument;
18 import uk.ac.vamsas.objects.utils.ProvenanceStuff;
20 // simple holder to pass to client.
21 public class ClientDoc extends uk.ac.vamsas.client.ClientDocument {
23 * @see uk.ac.vamsas.client.IClientDocument#getClientAppdata()
25 public IClientAppdata getClientAppdata() {
26 throw new Error("Appdata access is not implemented in the test.simpleclient.ClientDoc instance."); // TODO Auto-generated method stub
28 protected boolean isModified=false;
29 private Log log = LogFactory.getLog(ClientDoc.class);
30 protected VamsasDocument doc;
31 public uk.ac.vamsas.objects.core.VAMSAS[] _VamsasRoots;
32 protected VamsasArchive iohandler=null;
33 protected VamsasArchiveReader reader=null;
34 private String user=null;
35 private String app=null;
44 public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String app, String user, Hashtable objrefs) {
45 super(objrefs, (iohandler!=null) ? iohandler.getVorba() : null);
47 this.iohandler = iohandler;
51 this.objrefs = objrefs;
52 _VamsasRoots = doc.getVAMSAS();
54 // AppDataOutputStream appd;
55 //AppDataOutputStream userd;
57 * @see java.lang.Object#finalize()
59 protected Entry getProvenanceEntry(String action) {
60 // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
61 Entry prov = ProvenanceStuff.newProvenanceEntry(app, user, action);
64 public VAMSAS[] getVamsasRoots() {
66 log.debug("Null document for getVamsasRoots(), returning null");
69 if (iohandler==null) {
70 // LATER: decide on read-only status of ClientDocument object
71 log.warn("getVamsasRoots() called on possibly read-only document.");
73 if (_VamsasRoots!=null)
75 VAMSAS[] roots = doc.getVAMSAS();
77 // Make a new one to return to client to get filled.
78 _VamsasRoots = new VAMSAS[] { new VAMSAS() };
79 // Do provenance now. just in case.
80 doc.getProvenance().addEntry(getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
81 doc.addVAMSAS(_VamsasRoots[0]);
83 _VamsasRoots = new VAMSAS[roots.length];
84 for (int r=0;r<roots.length; r++)
85 _VamsasRoots[r] = roots[r];
90 private int _contains(VAMSAS root, VAMSAS[] docRoots) {
93 if (docRoots==null || docRoots.length==0)
95 VorbaId r_id = root.getVorbaId();
96 for (int i=0,j=docRoots.length; i<j; i++) {
98 if (docRoots[i]==root || (docRoots[i]!=null && (n_id=docRoots[i].getVorbaId())!=null && n_id.equals(r_id)))
104 * verify that newr version is really an intact version of the
105 * @param newVersion (may be modified)
107 * @return true if newVersion is a valid root that preserves original references
109 private boolean isValidUpdate(VAMSAS newVersion, final VAMSAS oldVersion) {
110 // ideal - this cascades down the two structures, ensuring that all ID'd objects in one are present in the other.
111 if (oldVersion==newVersion) {
112 // may be a virgin root element.
113 if (!newVersion.isRegistered())
114 iohandler.getVorba().makeVorbaId(newVersion);
115 // Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
116 // just do internal validation for moment.
117 if (newVersion.isValid())
121 // redundant ? if (oldVersion.is__stored_in_document())
122 if (!newVersion.isRegistered())
123 iohandler.getVorba().makeVorbaId(newVersion);
124 if (newVersion.isValid())
131 * merge old and new root vectors
132 * @param newr This array may be written to
134 * @param the client document (usually this) which this root set belongs to.
135 * @return merged vector of vamsas roots
137 private VAMSAS[] _combineRoots(VAMSAS[] newr, final VAMSAS[] original, ClientDoc modflag) {
138 Vector rts = new Vector();
139 boolean modified=false;
140 for (int i=0,j=original.length; i<j; i++) {
141 int k = _contains(original[i], newr);
143 if (isValidUpdate(newr[k], original[i])) {
148 // LATER: try harder to merge ducument roots.
149 log.warn("Couldn't merge new VAMSAS root "+newr[k].getId());
150 newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD
154 rts.add(original[i]);
157 // add remaining (new) roots
158 for (int i=0,j=newr.length; i<j; i++) {
164 newr = new VAMSAS[rts.size()];
165 for (int i=0,j=rts.size(); i<j; i++)
166 newr[i] = (VAMSAS) rts.get(i);
168 modflag.isModified = modified;
173 * update the document with new roots.
174 * LATER: decide: this affects the next call to getVamsasRoots()
175 * @see org.vamsas.IClientDocument.setVamsasRoots
177 public void setVamsasRoots(VAMSAS[] newroots) {
179 log.debug("setVamsasRoots called on null document.");
183 if (newroots==null) {
184 log.debug("setVamsasRoots(null) - do nothing.");
187 // are we dealing with same array ?
188 if (_VamsasRoots!=newroots) {
189 // merge roots into local version.
190 newr = new VAMSAS[newroots.length];
191 for (int i=0;i<newr.length;i++)
192 newr[i] = newroots[i];
193 newr=_combineRoots(newr,_VamsasRoots,this);
195 newr = new VAMSAS[_VamsasRoots.length];
196 for (int i=0;i<newr.length;i++)
197 newr[i]=_VamsasRoots[i];
199 // actually compare with document root set for final combination (to ensure nothing is lost)
200 _VamsasRoots = _combineRoots(newr, doc.getVAMSAS(), this);
205 * LATER: decide: this affects the next call to getVamsasRoots()
206 * @see uk.ac.vamsas.client.IClientDocument#addVamsasRoot(uk.ac.vamsas.objects.core.VAMSAS)
208 public void addVamsasRoot(VAMSAS newroot) {
210 log.debug("addVamsasRoots called on null document.");
213 VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
214 _VamsasRoots = newroots;
217 public VamsasArchiveReader getReader() {
220 private void _finalize() {
221 log.debug("finalizing clientDoc");
225 if (_VamsasRoots!=null) {
226 for (int i=0; i<_VamsasRoots.length; i++)
227 _VamsasRoots[i]=null;
233 log.debug("Closing and removing reader reference");
237 if (iohandler!=null) {
238 log.debug("Removing ioHandler reference.");
239 iohandler.cancelArchive();
243 protected void finalize() throws Throwable {
247 private java.util.Hashtable objrefs=null;
249 public VorbaId[] registerObjects(Vobject[] unregistered) {
251 log.warn("registerObjects[] called on null document.");
255 log.warn("registerObjects[] called for null objrefs hasharray.");
258 if (unregistered!=null) {
259 VorbaId ids[] = new VorbaId[unregistered.length];
260 for (int i=0,k=unregistered.length; i<k; i++)
261 if (unregistered[i]!=null) {
262 log.warn("Null Vobject passed to registerObject[] at position "+i);
265 ids[i]=registerObject(unregistered[i]);
267 log.debug("Registered "+unregistered.length+" objects - total of "+objrefs.size()+" ids.");
273 * @see uk.ac.vamsas.client.IClientDocument#registerObject(uk.ac.vamsas.client.Vobject)
275 public VorbaId registerObject(Vobject unregistered) {
277 log.warn("registerObjects called on null document.");
281 log.warn("registerObjects called for null objrefs hasharray.");
284 if (iohandler==null) {
285 log.warn("registerObjects called for read only document.");
289 if (unregistered!=null) {
290 VorbaId id = this._registerObject(unregistered);
291 log.debug("Registered object - total of "+objrefs.size()+" ids.");
294 log.warn("Null Vobject passed to registerObject.");
300 * @see uk.ac.vamsas.client.IClientDocument#getObject(uk.ac.vamsas.client.VorbaId)
302 public Vobject getObject(VorbaId id) {
304 log.debug("getObject called on null objrefs list.");
307 if (objrefs.containsKey(id.getId()))
308 return (Vobject) objrefs.get(id.getId());
309 log.debug("Returning null Vobject reference for id "+id.getId());
316 * @see uk.ac.vamsas.client.IClientDocument#getObjects(uk.ac.vamsas.client.VorbaId[])
318 public Vobject[] getObjects(VorbaId[] ids) {
320 log.debug("getObject[] called on null objrefs list.");
323 Vobject[] vo = new Vobject[ids.length];
324 for (int i=0,j=ids.length; i<j;i++)
325 if (objrefs.containsKey(ids[i]))
326 vo[i] = (Vobject) objrefs.get(ids[i]);
328 log.debug("Returning null Vobject reference for id "+ids[i].getId());
331 protected void updateDocumentRoots() {
333 log.error("updateDocumentRoots called on null document. Probably an implementation error.");
337 if (_VamsasRoots!=null) {
338 doc.setVAMSAS(_VamsasRoots);
344 * tell vamsas client to close the document and reset the object. Once closed, nothing can be done with the object.
347 public void closeDoc() {
349 log.debug("Closing open document.");
352 log.warn("Ignoring closeDoc on invalid document.");