2 * This file is part of the Vamsas Client version 0.2.
\r
3 * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite,
\r
4 * Andrew Waterhouse and Dominik Lindner.
\r
6 * Earlier versions have also been incorporated into Jalview version 2.4
\r
7 * since 2008, and TOPALi version 2 since 2007.
\r
9 * The Vamsas Client is free software: you can redistribute it and/or modify
\r
10 * it under the terms of the GNU Lesser General Public License as published by
\r
11 * the Free Software Foundation, either version 3 of the License, or
\r
12 * (at your option) any later version.
\r
14 * The Vamsas Client is distributed in the hope that it will be useful,
\r
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 * GNU Lesser General Public License for more details.
\r
19 * You should have received a copy of the GNU Lesser General Public License
\r
20 * along with the Vamsas Client. If not, see <http://www.gnu.org/licenses/>.
\r
22 package uk.ac.vamsas.test.simpleclient;
\r
24 import java.util.Hashtable;
\r
25 import java.util.Vector;
\r
27 import org.apache.commons.logging.Log;
\r
28 import org.apache.commons.logging.LogFactory;
\r
30 import uk.ac.vamsas.client.IClientAppdata;
\r
31 import uk.ac.vamsas.client.Vobject;
\r
32 import uk.ac.vamsas.client.VorbaId;
\r
33 import uk.ac.vamsas.client.simpleclient.ClientDocument;
\r
34 import uk.ac.vamsas.client.simpleclient.VamsasArchive;
\r
35 import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;
\r
36 import uk.ac.vamsas.objects.core.Entry;
\r
37 import uk.ac.vamsas.objects.core.VAMSAS;
\r
38 import uk.ac.vamsas.objects.core.VamsasDocument;
\r
39 import uk.ac.vamsas.objects.utils.ProvenanceStuff;
\r
41 // simple holder to pass to client.
\r
42 public class ClientDoc extends uk.ac.vamsas.client.ClientDocument {
\r
46 * @see uk.ac.vamsas.client.IClientDocument#getClientAppdata()
\r
48 public IClientAppdata getClientAppdata() {
\r
50 "Appdata access is not implemented in the test.simpleclient.ClientDoc instance."); // TODO
\r
56 protected boolean isModified = false;
\r
58 private Log log = LogFactory.getLog(ClientDoc.class);
\r
60 protected VamsasDocument doc;
\r
62 public uk.ac.vamsas.objects.core.VAMSAS[] _VamsasRoots;
\r
64 protected VamsasArchive iohandler = null;
\r
66 protected VamsasArchiveReader reader = null;
\r
68 private String user = null;
\r
70 private String app = null;
\r
79 public ClientDoc(VamsasDocument doc, VamsasArchive iohandler,
\r
80 VamsasArchiveReader reader, String app, String user, Hashtable objrefs) {
\r
81 super(objrefs, (iohandler != null) ? iohandler.getVorba() : null);
\r
83 this.iohandler = iohandler;
\r
84 this.reader = reader;
\r
87 this.objrefs = objrefs;
\r
88 _VamsasRoots = doc.getVAMSAS();
\r
91 // AppDataOutputStream appd;
\r
92 // AppDataOutputStream userd;
\r
96 * @see java.lang.Object#finalize()
\r
98 protected Entry getProvenanceEntry(String action) {
\r
99 // VAMSAS: modify schema to allow referencing of user field (plus other
\r
100 // issues, ClientUrn field, machine readable action, input parameters,
\r
101 // additional data generated notes
\r
102 Entry prov = ProvenanceStuff.newProvenanceEntry(app, user, action);
\r
106 public VAMSAS[] getVamsasRoots() {
\r
108 log.debug("Null document for getVamsasRoots(), returning null");
\r
111 if (iohandler == null) {
\r
112 // LATER: decide on read-only status of ClientDocument object
\r
113 log.warn("getVamsasRoots() called on possibly read-only document.");
\r
115 if (_VamsasRoots != null)
\r
116 return _VamsasRoots;
\r
117 VAMSAS[] roots = doc.getVAMSAS();
\r
118 if (roots == null) {
\r
119 // Make a new one to return to client to get filled.
\r
120 _VamsasRoots = new VAMSAS[] { new VAMSAS() };
\r
121 // Do provenance now. just in case.
\r
122 doc.getProvenance().addEntry(
\r
123 getProvenanceEntry("Created new document root [id="
\r
124 + _VamsasRoots[0].getId() + "]"));
\r
125 doc.addVAMSAS(_VamsasRoots[0]);
\r
127 _VamsasRoots = new VAMSAS[roots.length];
\r
128 for (int r = 0; r < roots.length; r++)
\r
129 _VamsasRoots[r] = roots[r];
\r
131 return _VamsasRoots;
\r
134 private int _contains(VAMSAS root, VAMSAS[] docRoots) {
\r
137 if (docRoots == null || docRoots.length == 0)
\r
139 VorbaId r_id = root.getVorbaId();
\r
140 for (int i = 0, j = docRoots.length; i < j; i++) {
\r
141 VorbaId n_id = null;
\r
142 if (docRoots[i] == root
\r
143 || (docRoots[i] != null && (n_id = docRoots[i].getVorbaId()) != null && n_id
\r
151 * verify that newr version is really an intact version of the
\r
153 * @param newVersion
\r
154 * (may be modified)
\r
155 * @param oldVersion
\r
156 * @return true if newVersion is a valid root that preserves original
\r
159 private boolean isValidUpdate(VAMSAS newVersion, final VAMSAS oldVersion) {
\r
160 // ideal - this cascades down the two structures, ensuring that all ID'd
\r
161 // objects in one are present in the other.
\r
162 if (oldVersion == newVersion) {
\r
163 // may be a virgin root element.
\r
164 if (!newVersion.isRegistered())
\r
165 iohandler.getVorba().makeVorbaId(newVersion);
\r
166 // Should retrieve original version and compare - unless local hashes can
\r
167 // be used to determine if resultSet has been truncated.
\r
168 // just do internal validation for moment.
\r
169 if (newVersion.isValid())
\r
173 // redundant ? if (oldVersion.is__stored_in_document())
\r
174 if (!newVersion.isRegistered())
\r
175 iohandler.getVorba().makeVorbaId(newVersion);
\r
176 if (newVersion.isValid())
\r
183 * /** merge old and new root vectors
\r
186 * This array may be written to
\r
189 * client document (usually this) which this root set belongs to.
\r
190 * @return merged vector of vamsas roots
\r
192 private VAMSAS[] _combineRoots(VAMSAS[] newr, final VAMSAS[] original,
\r
193 ClientDoc modflag) {
\r
194 Vector rts = new Vector();
\r
195 boolean modified = false;
\r
196 for (int i = 0, j = original.length; i < j; i++) {
\r
197 int k = _contains(original[i], newr);
\r
199 if (isValidUpdate(newr[k], original[i])) {
\r
204 // LATER: try harder to merge ducument roots.
\r
205 log.warn("Couldn't merge new VAMSAS root " + newr[k].getId());
\r
206 newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD
\r
210 rts.add(original[i]);
\r
213 // add remaining (new) roots
\r
214 for (int i = 0, j = newr.length; i < j; i++) {
\r
215 if (newr[i] != null) {
\r
220 newr = new VAMSAS[rts.size()];
\r
221 for (int i = 0, j = rts.size(); i < j; i++)
\r
222 newr[i] = (VAMSAS) rts.get(i);
\r
223 if (modflag != null)
\r
224 modflag.isModified = modified;
\r
229 * update the document with new roots. LATER: decide: this affects the next
\r
230 * call to getVamsasRoots()
\r
232 * @see org.vamsas.IClientDocument.setVamsasRoots
\r
234 public void setVamsasRoots(VAMSAS[] newroots) {
\r
236 log.debug("setVamsasRoots called on null document.");
\r
240 if (newroots == null) {
\r
241 log.debug("setVamsasRoots(null) - do nothing.");
\r
244 // are we dealing with same array ?
\r
245 if (_VamsasRoots != newroots) {
\r
246 // merge roots into local version.
\r
247 newr = new VAMSAS[newroots.length];
\r
248 for (int i = 0; i < newr.length; i++)
\r
249 newr[i] = newroots[i];
\r
250 newr = _combineRoots(newr, _VamsasRoots, this);
\r
252 newr = new VAMSAS[_VamsasRoots.length];
\r
253 for (int i = 0; i < newr.length; i++)
\r
254 newr[i] = _VamsasRoots[i];
\r
256 // actually compare with document root set for final combination (to ensure
\r
257 // nothing is lost)
\r
258 _VamsasRoots = _combineRoots(newr, doc.getVAMSAS(), this);
\r
262 * (non-Javadoc) LATER: decide: this affects the next call to getVamsasRoots()
\r
265 * uk.ac.vamsas.client.IClientDocument#addVamsasRoot(uk.ac.vamsas.objects.
\r
268 public void addVamsasRoot(VAMSAS newroot) {
\r
270 log.debug("addVamsasRoots called on null document.");
\r
273 VAMSAS[] newroots = _combineRoots(new VAMSAS[] { newroot }, _VamsasRoots,
\r
275 _VamsasRoots = newroots;
\r
278 public VamsasArchiveReader getReader() {
\r
282 private void _finalize() {
\r
283 log.debug("finalizing clientDoc");
\r
287 if (_VamsasRoots != null) {
\r
288 for (int i = 0; i < _VamsasRoots.length; i++)
\r
289 _VamsasRoots[i] = null;
\r
290 _VamsasRoots = null;
\r
294 if (reader != null) {
\r
295 log.debug("Closing and removing reader reference");
\r
299 if (iohandler != null) {
\r
300 log.debug("Removing ioHandler reference.");
\r
301 iohandler.cancelArchive();
\r
306 protected void finalize() throws Throwable {
\r
311 private java.util.Hashtable objrefs = null;
\r
313 public VorbaId[] registerObjects(Vobject[] unregistered) {
\r
315 log.warn("registerObjects[] called on null document.");
\r
318 if (objrefs == null) {
\r
319 log.warn("registerObjects[] called for null objrefs hasharray.");
\r
322 if (unregistered != null) {
\r
323 VorbaId ids[] = new VorbaId[unregistered.length];
\r
324 for (int i = 0, k = unregistered.length; i < k; i++)
\r
325 if (unregistered[i] != null) {
\r
326 log.warn("Null Vobject passed to registerObject[] at position " + i);
\r
329 ids[i] = registerObject(unregistered[i]);
\r
331 log.debug("Registered " + unregistered.length + " objects - total of "
\r
332 + objrefs.size() + " ids.");
\r
342 * uk.ac.vamsas.client.IClientDocument#registerObject(uk.ac.vamsas.client.
\r
345 public VorbaId registerObject(Vobject unregistered) {
\r
347 log.warn("registerObjects called on null document.");
\r
350 if (objrefs == null) {
\r
351 log.warn("registerObjects called for null objrefs hasharray.");
\r
354 if (iohandler == null) {
\r
355 log.warn("registerObjects called for read only document.");
\r
359 if (unregistered != null) {
\r
360 VorbaId id = this._registerObject(unregistered);
\r
361 log.debug("Registered object - total of " + objrefs.size() + " ids.");
\r
364 log.warn("Null Vobject passed to registerObject.");
\r
372 * uk.ac.vamsas.client.IClientDocument#getObject(uk.ac.vamsas.client.VorbaId)
\r
374 public Vobject getObject(VorbaId id) {
\r
375 if (objrefs == null) {
\r
376 log.debug("getObject called on null objrefs list.");
\r
379 if (objrefs.containsKey(id.getId()))
\r
380 return (Vobject) objrefs.get(id.getId());
\r
381 log.debug("Returning null Vobject reference for id " + id.getId());
\r
389 * uk.ac.vamsas.client.IClientDocument#getObjects(uk.ac.vamsas.client.VorbaId
\r
392 public Vobject[] getObjects(VorbaId[] ids) {
\r
393 if (objrefs == null) {
\r
394 log.debug("getObject[] called on null objrefs list.");
\r
397 Vobject[] vo = new Vobject[ids.length];
\r
398 for (int i = 0, j = ids.length; i < j; i++)
\r
399 if (objrefs.containsKey(ids[i]))
\r
400 vo[i] = (Vobject) objrefs.get(ids[i]);
\r
402 log.debug("Returning null Vobject reference for id " + ids[i].getId());
\r
406 protected void updateDocumentRoots() {
\r
409 .error("updateDocumentRoots called on null document. Probably an implementation error.");
\r
413 if (_VamsasRoots != null) {
\r
414 doc.setVAMSAS(_VamsasRoots);
\r
415 _VamsasRoots = null;
\r
421 * tell vamsas client to close the document and reset the object. Once closed,
\r
422 * nothing can be done with the object.
\r
425 public void closeDoc() {
\r
427 log.debug("Closing open document.");
\r
430 log.warn("Ignoring closeDoc on invalid document.");
\r