2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3 * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 package jalview.io.vamsas;
21 import jalview.bin.Cache;
22 import jalview.datamodel.DBRefEntry;
23 import jalview.gui.TreePanel;
24 import jalview.io.VamsasAppDatastore;
26 import java.util.Enumeration;
27 import java.util.Hashtable;
28 import java.util.IdentityHashMap;
29 import java.util.Vector;
31 import org.apache.commons.logging.Log;
33 import uk.ac.vamsas.client.IClientDocument;
34 import uk.ac.vamsas.client.Vobject;
35 import uk.ac.vamsas.client.VorbaId;
36 import uk.ac.vamsas.objects.core.DbRef;
37 import uk.ac.vamsas.objects.core.Entry;
38 import uk.ac.vamsas.objects.core.Provenance;
39 import uk.ac.vamsas.objects.core.Seg;
42 * Holds all the common machinery for binding objects to vamsas objects
47 public abstract class DatastoreItem
52 Entry provEntry = null;
58 IdentityHashMap jv2vobj;
60 boolean tojalview=false;
64 protected static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(DatastoreItem.class);
66 * note: this is taken verbatim from jalview.io.VamsasAppDatastore
67 * @return the Vobject bound to Jalview datamodel object
69 protected Vobject getjv2vObj(Object jvobj)
71 if (jv2vobj.containsKey(jvobj))
73 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
75 if (Cache.log.isDebugEnabled())
77 Cache.log.debug("Returning null VorbaID binding for jalview object "
86 * @return Jalview datamodel object bound to the vamsas document object
88 protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)
92 VorbaId id = vobj.getVorbaId();
95 id = cdoc.registerObject(vobj);
97 .debug("Registering new object and returning null for getvObj2jv");
100 if (vobj2jv.containsKey(vobj.getVorbaId()))
102 return vobj2jv.get(vobj.getVorbaId());
108 * note: this is taken verbatim from jalview.io.VamsasAppDatastore
113 protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
115 VorbaId id = vobj.getVorbaId();
118 id = cdoc.registerObject(vobj);
119 if (id == null || vobj.getVorbaId() == null
120 || cdoc.getObject(id) != vobj)
122 Cache.log.error("Failed to get id for "
123 + (vobj.isRegisterable() ? "registerable"
124 : "unregisterable") + " object " + vobj);
128 if (vobj2jv.containsKey(vobj.getVorbaId())
129 && !(vobj2jv.get(vobj.getVorbaId())).equals(jvobj))
132 "Warning? Overwriting existing vamsas id binding for "
133 + vobj.getVorbaId(), new Exception(
134 "Overwriting vamsas id binding."));
136 else if (jv2vobj.containsKey(jvobj)
137 && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
140 "Warning? Overwriting existing jalview object binding for "
141 + jvobj, new Exception(
142 "Overwriting jalview object binding."));
145 * Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id "
146 * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+"
147 * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to
150 // we just update the hash's regardless!
151 Cache.log.debug("Binding " + vobj.getVorbaId() + " to " + jvobj);
152 vobj2jv.put(vobj.getVorbaId(), jvobj);
153 // JBPNote - better implementing a hybrid invertible hash.
154 jv2vobj.put(jvobj, vobj.getVorbaId());
157 * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
159 * note: this is taken verbatim from jalview.io.VamsasAppDatastore
161 * @param newjvobject (may be null to forget the oldjvobject's document mapping)
164 protected void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
166 Object vobject = jv2vobj.remove(oldjvobject);
170 "IMPLEMENTATION ERROR: old jalview object is not bound ! ("
171 + oldjvobject + ")");
173 if (newjvobject!=null)
175 jv2vobj.put(newjvobject, vobject);
176 vobj2jv.put(vobject, newjvobject);
180 public DatastoreItem()
185 public DatastoreItem(VamsasAppDatastore datastore)
188 initDatastoreItem(datastore);
189 // TODO Auto-generated constructor stub
192 * construct and initialise datastore object and retrieve object bound to vobj2 and validate it against boundType
197 public DatastoreItem(VamsasAppDatastore datastore2, Vobject vobj2, Class boundType)
201 jvobj = getvObj2jv(vobj2);
203 if (jvobj!=null && !(boundType.isAssignableFrom(jvobj.getClass())))
205 throw new Error("Implementation Error: Vamsas Document Class "+vobj.getClass()+" should bind to a "+boundType+" (found a "+jvobj.getClass()+")");
207 dsReg.registerDsObj(this);
210 * construct and initialise datastore object and retrieve document object bound to Jalview object jvobj2 and validate it against boundType
211 * @param datastore2 the datastore
212 * @param jvobj2 the jalview object
213 * @param boundToType - the document object class that the bound object should be assignable from
215 public DatastoreItem(VamsasAppDatastore datastore2, Object jvobj2, Class boundToType)
220 vobj = getjv2vObj(jvobj);
221 if (vobj!=null && !(boundToType.isAssignableFrom(vobj.getClass())))
223 throw new Error("Implementation Error: Jalview Class "+jvobj2.getClass()+" should bind to a "+boundToType+" (found a "+vobj.getClass()+")");
225 dsReg.registerDsObj(this);
228 * create a new vobj to be added to the document
229 * for the jalview object jvobj
230 * (jvobj!=null, vobj==null)
232 public abstract void addToDocument();
234 * handle a conflict where both an existing vobj has been updated
235 * and a local jalview object has been updated. This method
236 * is only called from doSync, when an incoming update from the vamsas
237 * session conflicts with local modifications made by the Jalview user.
238 * (jvobj!=null, vobj!=null)
240 public abstract void conflict();
242 * update an existing vobj in the document with the data and settings from jvobj
243 * (jvobj!=null, vobj!=null)
245 public abstract void updateToDoc();
247 * update the local jalview object with the data from an existing vobj in the document
248 * (jvobj!=null, vobj!=null)
250 public abstract void updateFromDoc();
252 * create a new local jvobj bound to the vobj in the document.
253 * (jvobj==null, vobj!=null)
255 public abstract void addFromDocument();
256 boolean addtodoc=false, conflicted=false,updated=false,addfromdoc=false,success=false;
258 private boolean updatedtodoc;
260 private boolean updatedfromdoc;
262 * Sync jalview to document. Enact addToDocument, conflict or update dependent on
263 * existence of a vobj bound to the local jvobj.
265 protected void doSync()
267 dsReg.registerDsObj(this);
270 log.debug("adding new vobject to document.");
276 if (vobj.isUpdated())
278 log.debug("Handling update conflict for existing bound vobject.");
284 log.debug("updating existing vobject in document.");
289 // no exceptions were encountered...
293 * Update jalview from document. enact addFromDocument if no local jvobj exists, or update iff jvobj
294 * exists and the vobj.isUpdated() flag is set.
296 protected void doJvUpdate()
298 dsReg.registerDsObj(this);
301 log.debug("adding new vobject to Jalview from Document");
307 if (vobj.isUpdated())
309 log.debug("updating Jalview from existing bound vObject");
316 VamsasAppDatastore datastore = null;
318 * object in vamsas document
320 protected Vobject vobj = null;
322 * local jalview object
324 protected Object jvobj = null;
326 protected DatastoreRegistry dsReg;
328 public void initDatastoreItem(VamsasAppDatastore ds)
331 dsReg = ds.getDatastoreRegisty();
332 initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds
333 .getVamsasObjectBinding(), ds.getJvObjectBinding());
336 private void initDatastoreItem(Entry provEntry, IClientDocument cdoc,
337 Hashtable vobj2jv, IdentityHashMap jv2vobj)
339 this.provEntry = provEntry;
341 this.vobj2jv = vobj2jv;
342 this.jv2vobj = jv2vobj;
345 protected boolean isModifiable(String modifiable)
347 return modifiable == null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
350 protected Vector getjv2vObjs(Vector alsq)
352 Vector vObjs = new Vector();
353 Enumeration elm = alsq.elements();
354 while (elm.hasMoreElements())
356 vObjs.addElement(getjv2vObj(elm.nextElement()));
363 * get start<end range of segment, adjusting for inclusivity flag and
367 * @param ensureDirection
368 * when true - always ensure start is less than end.
369 * @return int[] { start, end, direction} where direction==1 for range running
372 public int[] getSegRange(Seg visSeg, boolean ensureDirection)
374 boolean incl = visSeg.getInclusive();
375 // adjust for inclusive flag.
376 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
378 int start = visSeg.getStart() + (incl ? 0 : pol);
379 int end = visSeg.getEnd() + (incl ? 0 : -pol);
380 if (ensureDirection && pol == -1)
382 // jalview doesn't deal with inverted ranges, yet.
388 { start, end, pol < 0 ? 1 : 0 };
394 protected jalview.datamodel.Provenance getJalviewProvenance(
397 // TODO: fix App and Action entries and check use of provenance in jalview.
398 jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
399 for (int i = 0; i < prov.getEntryCount(); i++)
401 jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i)
402 .getAction(), prov.getEntry(i).getDate(), prov.getEntry(i)
411 * @return default initial provenance list for a Jalview created vamsas
414 Provenance dummyProvenance()
416 return dummyProvenance(null);
419 protected Entry dummyPEntry(String action)
421 Entry entry = new Entry();
422 entry.setApp(this.provEntry.getApp());
425 entry.setAction(action);
429 entry.setAction("created.");
431 entry.setDate(new java.util.Date());
432 entry.setUser(this.provEntry.getUser());
436 protected Provenance dummyProvenance(String action)
438 Provenance prov = new Provenance();
439 prov.addEntry(dummyPEntry(action));
443 protected void addProvenance(Provenance p, String action)
445 p.addEntry(dummyPEntry(action));
450 * @return true if jalview was being updated from the vamsas document
452 public boolean isTojalview()
458 * @return true if addToDocument() was called.
460 public boolean isAddtodoc()
466 * @return true if conflict() was called
468 public boolean isConflicted()
474 * @return true if updateFromDoc() was called
476 public boolean isUpdatedFromDoc()
478 return updatedfromdoc;
481 * @return true if updateToDoc() was called
483 public boolean isUpdatedToDoc()
489 * @return true if addFromDocument() was called.
491 public boolean isAddfromdoc()
497 * @return true if object sync logic completed normally.
499 public boolean isSuccess()
507 public Vobject getVobj()
515 public Object getJvobj()
520 public boolean docWasUpdated()
522 return (this.addtodoc || this.updated) && this.success;
525 public boolean jvWasUpdated()
527 return (success); // TODO : Implement this properly!