X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2Fvamsas%2FDatastoreItem.java;h=738d14fd34b1c9cad12b26a86e98e4da0de3792b;hb=5e67396f7f70d20025e8112ce09f2095ebc94584;hp=4cc540d465a1428fd178a380731c06ce738d3e2b;hpb=cfa406a916d754e600c60f7dae29b053bf045ace;p=jalview.git diff --git a/src/jalview/io/vamsas/DatastoreItem.java b/src/jalview/io/vamsas/DatastoreItem.java index 4cc540d..738d14f 100644 --- a/src/jalview/io/vamsas/DatastoreItem.java +++ b/src/jalview/io/vamsas/DatastoreItem.java @@ -1,6 +1,25 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1) + * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ package jalview.io.vamsas; import jalview.bin.Cache; +import jalview.datamodel.DBRefEntry; import jalview.gui.TreePanel; import jalview.io.VamsasAppDatastore; @@ -9,19 +28,23 @@ import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Vector; +import org.apache.commons.logging.Log; + import uk.ac.vamsas.client.IClientDocument; import uk.ac.vamsas.client.Vobject; import uk.ac.vamsas.client.VorbaId; +import uk.ac.vamsas.objects.core.DbRef; import uk.ac.vamsas.objects.core.Entry; import uk.ac.vamsas.objects.core.Provenance; import uk.ac.vamsas.objects.core.Seg; /** * Holds all the common machinery for binding objects to vamsas objects + * * @author JimP - * + * */ -public class DatastoreItem +public abstract class DatastoreItem { /** * @@ -33,37 +56,45 @@ public class DatastoreItem Hashtable vobj2jv; IdentityHashMap jv2vobj; + + boolean tojalview=false; /** + * shared log instance + */ + protected static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(DatastoreItem.class); + /** + * note: this is taken verbatim from jalview.io.VamsasAppDatastore * @return the Vobject bound to Jalview datamodel object */ protected Vobject getjv2vObj(Object jvobj) { if (jv2vobj.containsKey(jvobj)) { - return cdoc.getObject( (VorbaId) jv2vobj.get(jvobj)); + return cdoc.getObject((VorbaId) jv2vobj.get(jvobj)); } if (Cache.log.isDebugEnabled()) { - Cache.log.debug("Returning null VorbaID binding for jalview object "+jvobj); + Cache.log.debug("Returning null VorbaID binding for jalview object " + + jvobj); } return null; } /** - * + * * @param vobj * @return Jalview datamodel object bound to the vamsas document object */ protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj) { - if (vobj2jv==null) + if (vobj2jv == null) return null; VorbaId id = vobj.getVorbaId(); if (id == null) { id = cdoc.registerObject(vobj); Cache.log - .debug("Registering new object and returning null for getvObj2jv"); + .debug("Registering new object and returning null for getvObj2jv"); return null; } if (vobj2jv.containsKey(vobj.getVorbaId())) @@ -73,59 +104,255 @@ public class DatastoreItem return null; } + /** + * note: this is taken verbatim from jalview.io.VamsasAppDatastore + * with added call to updateRegistryEntry + * @param jvobj + * @param vobj + */ protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj) { VorbaId id = vobj.getVorbaId(); if (id == null) { id = cdoc.registerObject(vobj); - if (id == null || vobj.getVorbaId() == null || cdoc.getObject(id)!=vobj) + if (id == null || vobj.getVorbaId() == null + || cdoc.getObject(id) != vobj) { - Cache.log.error("Failed to get id for " + - (vobj.isRegisterable() ? "registerable" : - "unregisterable") + " object " + vobj); + Cache.log.error("Failed to get id for " + + (vobj.isRegisterable() ? "registerable" + : "unregisterable") + " object " + vobj); } } - - if (vobj2jv.containsKey(vobj.getVorbaId()) && - ! ( (VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) + if (vobj2jv.containsKey(vobj.getVorbaId()) + && !(vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) { - Cache.log.debug("Warning? Overwriting existing vamsas id binding for " + - vobj.getVorbaId(), - new Exception("Overwriting vamsas id binding.")); + Cache.log.debug( + "Warning? Overwriting existing vamsas id binding for " + + vobj.getVorbaId(), new Exception( + "Overwriting vamsas id binding.")); } - else if (jv2vobj.containsKey(jvobj) && - ! ( (VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId())) + else if (jv2vobj.containsKey(jvobj) + && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId())) { Cache.log.debug( - "Warning? Overwriting existing jalview object binding for " + jvobj, - new Exception("Overwriting jalview object binding.")); + "Warning? Overwriting existing jalview object binding for " + + jvobj, new Exception( + "Overwriting jalview object binding.")); } - /* Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to bindjvvobj")); - }*/ + /* + * Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " + * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" + * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to + * bindjvvobj")); } + */ // we just update the hash's regardless! - Cache.log.debug("Binding "+vobj.getVorbaId()+" to "+jvobj); + Cache.log.debug("Binding " + vobj.getVorbaId() + " to " + jvobj); vobj2jv.put(vobj.getVorbaId(), jvobj); // JBPNote - better implementing a hybrid invertible hash. jv2vobj.put(jvobj, vobj.getVorbaId()); + if (jvobj==this.jvobj || vobj==this.vobj) + { + updateRegistryEntry(jvobj,vobj); + } + } + /** + * update the vobj and jvobj references and the registry entry for this datastore object + * called by bindjvvobj and replacejvobjmapping + */ + private void updateRegistryEntry(Object jvobj,Vobject vobj) + { + if (this.jvobj!=null && this.vobj!=null) { + Cache.log.debug("updating dsobj registry. ("+this.getClass().getName()+")"); + } + this.jvobj = jvobj; + this.vobj = vobj; + dsReg.registerDsObj(this); + } + + /** + * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID + * binding tables + * note: originally taken verbatim from jalview.io.VamsasAppDatastore with added call to updateRegistryEntry + * @param oldjvobject + * @param newjvobject (may be null to forget the oldjvobject's document mapping) + * + */ + protected void replaceJvObjMapping(Object oldjvobject, Object newjvobject) + { + Object vobject = jv2vobj.remove(oldjvobject); + if (vobject == null) + { + throw new Error( + "IMPLEMENTATION ERROR: old jalview object is not bound ! (" + + oldjvobject + ")"); + } + if (newjvobject!=null) + { + jv2vobj.put(newjvobject, vobject); + vobj2jv.put(vobject, newjvobject); + updateRegistryEntry(newjvobject,(Vobject) vobject); + } } - public DatastoreItem() { + public DatastoreItem() + { super(); } + public DatastoreItem(VamsasAppDatastore datastore) { this(); initDatastoreItem(datastore); // TODO Auto-generated constructor stub } + /** + * construct and initialise datastore object and retrieve object bound to vobj2 and validate it against boundType + * @param datastore2 + * @param vobj2 + * @param boundType + */ + public DatastoreItem(VamsasAppDatastore datastore2, Vobject vobj2, Class boundType) + { + this(datastore2); + vobj = vobj2; + jvobj = getvObj2jv(vobj2); + tojalview=true; + if (jvobj!=null && !(boundType.isAssignableFrom(jvobj.getClass()))) + { + throw new Error("Implementation Error: Vamsas Document Class "+vobj.getClass()+" should bind to a "+boundType+" (found a "+jvobj.getClass()+")"); + } + dsReg.registerDsObj(this); + } + /** + * construct and initialise datastore object and retrieve document object bound to Jalview object jvobj2 and validate it against boundType + * @param datastore2 the datastore + * @param jvobj2 the jalview object + * @param boundToType - the document object class that the bound object should be assignable from + */ + public DatastoreItem(VamsasAppDatastore datastore2, Object jvobj2, Class boundToType) + { + this(datastore2); + jvobj = jvobj2; + tojalview=false; + vobj = getjv2vObj(jvobj); + if (vobj!=null && !(boundToType.isAssignableFrom(vobj.getClass()))) + { + throw new Error("Implementation Error: Jalview Class "+jvobj2.getClass()+" should bind to a "+boundToType+" (found a "+vobj.getClass()+")"); + } + dsReg.registerDsObj(this); + } + /** + * create a new vobj to be added to the document + * for the jalview object jvobj + * (jvobj!=null, vobj==null) + */ + public abstract void addToDocument(); + /** + * handle a conflict where both an existing vobj has been updated + * and a local jalview object has been updated. This method + * is only called from doSync, when an incoming update from the vamsas + * session conflicts with local modifications made by the Jalview user. + * (jvobj!=null, vobj!=null) + */ + public abstract void conflict(); + /** + * update an existing vobj in the document with the data and settings from jvobj + * (jvobj!=null, vobj!=null) + */ + public abstract void updateToDoc(); + /** + * update the local jalview object with the data from an existing vobj in the document + * (jvobj!=null, vobj!=null) + */ + public abstract void updateFromDoc(); + /** + * create a new local jvobj bound to the vobj in the document. + * (jvobj==null, vobj!=null) + */ + public abstract void addFromDocument(); + boolean addtodoc=false, conflicted=false,updated=false,addfromdoc=false,success=false; + + private boolean updatedtodoc; + + private boolean updatedfromdoc; + /** + * Sync jalview to document. Enact addToDocument, conflict or update dependent on + * existence of a vobj bound to the local jvobj. + */ + protected void doSync() + { + dsReg.registerDsObj(this); + if (vobj == null) + { + log.debug("adding new vobject to document."); + addtodoc=true; + addToDocument(); + } + else + { + if (vobj.isUpdated()) + { + log.debug("Handling update conflict for existing bound vobject."); + conflicted=true; + conflict(); + } + else + { + log.debug("updating existing vobject in document."); + updatedtodoc=true; + updateToDoc(); + } + } + // no exceptions were encountered... + success=true; + } + /** + * Update jalview from document. enact addFromDocument if no local jvobj exists, or update iff jvobj + * exists and the vobj.isUpdated() flag is set. + */ + protected void doJvUpdate() + { + dsReg.registerDsObj(this); + if (jvobj == null) + { + log.debug("adding new vobject to Jalview from Document"); + addfromdoc=true; + addFromDocument(); + } + else + { + if (vobj.isUpdated()) + { + log.debug("updating Jalview from existing bound vObject"); + updatedfromdoc=true; + updateFromDoc(); + } + } + } + VamsasAppDatastore datastore = null; + /** + * object in vamsas document + */ + protected Vobject vobj = null; + /** + * local jalview object + */ + protected Object jvobj = null; + + protected DatastoreRegistry dsReg; + public void initDatastoreItem(VamsasAppDatastore ds) { datastore = ds; - initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds.getVamsasObjectBinding(), ds.getJvObjectBinding()); + dsReg = ds.getDatastoreRegisty(); + initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds + .getVamsasObjectBinding(), ds.getJvObjectBinding()); } - public void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj) + + private void initDatastoreItem(Entry provEntry, IClientDocument cdoc, + Hashtable vobj2jv, IdentityHashMap jv2vobj) { this.provEntry = provEntry; this.cdoc = cdoc; @@ -135,7 +362,7 @@ public class DatastoreItem protected boolean isModifiable(String modifiable) { - return modifiable==null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS) + return modifiable == null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS) } protected Vector getjv2vObjs(Vector alsq) @@ -148,14 +375,17 @@ public class DatastoreItem } return vObjs; } + // utility functions /** * get start