2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.io.vamsas;
20 import jalview.bin.Cache;
21 import jalview.datamodel.DBRefEntry;
22 import jalview.gui.TreePanel;
23 import jalview.io.VamsasAppDatastore;
25 import java.util.Enumeration;
26 import java.util.Hashtable;
27 import java.util.IdentityHashMap;
28 import java.util.Vector;
30 import org.apache.commons.logging.Log;
32 import uk.ac.vamsas.client.IClientDocument;
33 import uk.ac.vamsas.client.Vobject;
34 import uk.ac.vamsas.client.VorbaId;
35 import uk.ac.vamsas.objects.core.DbRef;
36 import uk.ac.vamsas.objects.core.Entry;
37 import uk.ac.vamsas.objects.core.Provenance;
38 import uk.ac.vamsas.objects.core.Seg;
41 * Holds all the common machinery for binding objects to vamsas objects
46 public abstract class DatastoreItem
51 Entry provEntry = null;
57 IdentityHashMap jv2vobj;
59 boolean tojalview = false;
64 protected static org.apache.log4j.Logger log = org.apache.log4j.Logger
65 .getLogger(DatastoreItem.class);
68 * note: this is taken verbatim from jalview.io.VamsasAppDatastore
70 * @return the Vobject bound to Jalview datamodel object
72 protected Vobject getjv2vObj(Object jvobj)
74 if (jv2vobj.containsKey(jvobj))
76 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
78 if (Cache.log.isDebugEnabled())
80 Cache.log.debug("Returning null VorbaID binding for jalview object "
89 * @return Jalview datamodel object bound to the vamsas document object
91 protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)
95 VorbaId id = vobj.getVorbaId();
98 id = cdoc.registerObject(vobj);
100 .debug("Registering new object and returning null for getvObj2jv");
103 if (vobj2jv.containsKey(vobj.getVorbaId()))
105 return vobj2jv.get(vobj.getVorbaId());
111 * note: this is taken verbatim from jalview.io.VamsasAppDatastore with added
112 * call to updateRegistryEntry
117 protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
119 VorbaId id = vobj.getVorbaId();
122 id = cdoc.registerObject(vobj);
123 if (id == null || vobj.getVorbaId() == null
124 || cdoc.getObject(id) != vobj)
126 Cache.log.error("Failed to get id for "
127 + (vobj.isRegisterable() ? "registerable"
128 : "unregisterable") + " object " + vobj);
131 if (vobj2jv.containsKey(vobj.getVorbaId())
132 && !(vobj2jv.get(vobj.getVorbaId())).equals(jvobj))
135 "Warning? Overwriting existing vamsas id binding for "
136 + vobj.getVorbaId(), new Exception(
137 "Overwriting vamsas id binding."));
139 else if (jv2vobj.containsKey(jvobj)
140 && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
143 "Warning? Overwriting existing jalview object binding for "
144 + jvobj, new Exception(
145 "Overwriting jalview object binding."));
148 * Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id "
149 * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+"
150 * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to
153 // we just update the hash's regardless!
154 Cache.log.debug("Binding " + vobj.getVorbaId() + " to " + jvobj);
155 vobj2jv.put(vobj.getVorbaId(), jvobj);
156 // JBPNote - better implementing a hybrid invertible hash.
157 jv2vobj.put(jvobj, vobj.getVorbaId());
158 if (jvobj == this.jvobj || vobj == this.vobj)
160 updateRegistryEntry(jvobj, vobj);
165 * update the vobj and jvobj references and the registry entry for this
166 * datastore object called by bindjvvobj and replacejvobjmapping
168 private void updateRegistryEntry(Object jvobj, Vobject vobj)
170 if (this.jvobj != null && this.vobj != null)
172 Cache.log.debug("updating dsobj registry. ("
173 + this.getClass().getName() + ")");
177 dsReg.registerDsObj(this);
181 * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
182 * binding tables note: originally taken verbatim from
183 * jalview.io.VamsasAppDatastore with added call to updateRegistryEntry
187 * (may be null to forget the oldjvobject's document mapping)
190 protected void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
192 Object vobject = jv2vobj.remove(oldjvobject);
196 "IMPLEMENTATION ERROR: old jalview object is not bound ! ("
197 + oldjvobject + ")");
199 if (newjvobject != null)
201 jv2vobj.put(newjvobject, vobject);
202 vobj2jv.put(vobject, newjvobject);
203 updateRegistryEntry(newjvobject, vobj);
207 public DatastoreItem()
212 public DatastoreItem(VamsasAppDatastore datastore)
215 initDatastoreItem(datastore);
216 // TODO Auto-generated constructor stub
220 * construct and initialise datastore object and retrieve object bound to
221 * vobj2 and validate it against boundType
227 public DatastoreItem(VamsasAppDatastore datastore2, Vobject vobj2,
232 jvobj = getvObj2jv(vobj2);
234 if (jvobj != null && !(boundType.isAssignableFrom(jvobj.getClass())))
236 throw new Error("Implementation Error: Vamsas Document Class "
237 + vobj.getClass() + " should bind to a " + boundType
238 + " (found a " + jvobj.getClass() + ")");
240 dsReg.registerDsObj(this);
244 * construct and initialise datastore object and retrieve document object
245 * bound to Jalview object jvobj2 and validate it against boundType
252 * - the document object class that the bound object should be
255 public DatastoreItem(VamsasAppDatastore datastore2, Object jvobj2,
261 vobj = getjv2vObj(jvobj);
262 if (vobj != null && !(boundToType.isAssignableFrom(vobj.getClass())))
264 throw new Error("Implementation Error: Jalview Class "
265 + jvobj2.getClass() + " should bind to a " + boundToType
266 + " (found a " + vobj.getClass() + ")");
268 dsReg.registerDsObj(this);
272 * create a new vobj to be added to the document for the jalview object jvobj
273 * (jvobj!=null, vobj==null)
275 public abstract void addToDocument();
278 * handle a conflict where both an existing vobj has been updated and a local
279 * jalview object has been updated. This method is only called from doSync,
280 * when an incoming update from the vamsas session conflicts with local
281 * modifications made by the Jalview user. (jvobj!=null, vobj!=null)
283 public abstract void conflict();
286 * update an existing vobj in the document with the data and settings from
287 * jvobj (jvobj!=null, vobj!=null)
289 public abstract void updateToDoc();
292 * update the local jalview object with the data from an existing vobj in the
293 * document (jvobj!=null, vobj!=null)
295 public abstract void updateFromDoc();
298 * create a new local jvobj bound to the vobj in the document. (jvobj==null,
301 public abstract void addFromDocument();
303 boolean addtodoc = false, conflicted = false, updated = false,
304 addfromdoc = false, success = false;
306 private boolean updatedtodoc;
308 private boolean updatedfromdoc;
311 * Sync jalview to document. Enact addToDocument, conflict or update dependent
312 * on existence of a vobj bound to the local jvobj.
314 protected void doSync()
316 dsReg.registerDsObj(this);
319 log.debug("adding new vobject to document.");
325 if (vobj.isUpdated())
327 log.debug("Handling update conflict for existing bound vobject.");
333 log.debug("updating existing vobject in document.");
338 // no exceptions were encountered...
343 * Update jalview from document. enact addFromDocument if no local jvobj
344 * exists, or update iff jvobj exists and the vobj.isUpdated() flag is set.
346 protected void doJvUpdate()
348 dsReg.registerDsObj(this);
351 log.debug("adding new vobject to Jalview from Document");
357 if (vobj.isUpdated())
359 log.debug("updating Jalview from existing bound vObject");
360 updatedfromdoc = true;
366 VamsasAppDatastore datastore = null;
369 * object in vamsas document
371 protected Vobject vobj = null;
374 * local jalview object
376 protected Object jvobj = null;
378 protected DatastoreRegistry dsReg;
380 public void initDatastoreItem(VamsasAppDatastore ds)
383 dsReg = ds.getDatastoreRegisty();
384 initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(),
385 ds.getVamsasObjectBinding(), ds.getJvObjectBinding());
388 private void initDatastoreItem(Entry provEntry, IClientDocument cdoc,
389 Hashtable vobj2jv, IdentityHashMap jv2vobj)
391 this.provEntry = provEntry;
393 this.vobj2jv = vobj2jv;
394 this.jv2vobj = jv2vobj;
397 protected boolean isModifiable(String modifiable)
399 return modifiable == null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
402 protected Vector getjv2vObjs(Vector alsq)
404 Vector vObjs = new Vector();
405 Enumeration elm = alsq.elements();
406 while (elm.hasMoreElements())
408 vObjs.addElement(getjv2vObj(elm.nextElement()));
415 * get start<end range of segment, adjusting for inclusivity flag and
419 * @param ensureDirection
420 * when true - always ensure start is less than end.
421 * @return int[] { start, end, direction} where direction==1 for range running
424 public int[] getSegRange(Seg visSeg, boolean ensureDirection)
426 boolean incl = visSeg.getInclusive();
427 // adjust for inclusive flag.
428 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
430 int start = visSeg.getStart() + (incl ? 0 : pol);
431 int end = visSeg.getEnd() + (incl ? 0 : -pol);
432 if (ensureDirection && pol == -1)
434 // jalview doesn't deal with inverted ranges, yet.
440 { start, end, pol < 0 ? 1 : 0 };
446 protected jalview.datamodel.Provenance getJalviewProvenance(
449 // TODO: fix App and Action entries and check use of provenance in jalview.
450 jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
451 for (int i = 0; i < prov.getEntryCount(); i++)
453 jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i)
454 .getAction(), prov.getEntry(i).getDate(), prov.getEntry(i)
463 * @return default initial provenance list for a Jalview created vamsas
466 Provenance dummyProvenance()
468 return dummyProvenance(null);
471 protected Entry dummyPEntry(String action)
473 Entry entry = new Entry();
474 entry.setApp(this.provEntry.getApp());
477 entry.setAction(action);
481 entry.setAction("created.");
483 entry.setDate(new java.util.Date());
484 entry.setUser(this.provEntry.getUser());
488 protected Provenance dummyProvenance(String action)
490 Provenance prov = new Provenance();
491 prov.addEntry(dummyPEntry(action));
495 protected void addProvenance(Provenance p, String action)
497 p.addEntry(dummyPEntry(action));
501 * @return true if jalview was being updated from the vamsas document
503 public boolean isTojalview()
509 * @return true if addToDocument() was called.
511 public boolean isAddtodoc()
517 * @return true if conflict() was called
519 public boolean isConflicted()
525 * @return true if updateFromDoc() was called
527 public boolean isUpdatedFromDoc()
529 return updatedfromdoc;
533 * @return true if updateToDoc() was called
535 public boolean isUpdatedToDoc()
541 * @return true if addFromDocument() was called.
543 public boolean isAddfromdoc()
549 * @return true if object sync logic completed normally.
551 public boolean isSuccess()
559 public Vobject getVobj()
567 public Object getJvobj()
572 public boolean docWasUpdated()
574 return (this.addtodoc || this.updated) && this.success;
577 public boolean jvWasUpdated()
579 return (success); // TODO : Implement this properly!