X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2Fvamsas%2FDatastoreItem.java;h=de82beb1e164359b449fbfaa92383fc37ff065d4;hb=838e4f91d4a53dd315640dbc9ff6ef7a815ee576;hp=42e494f9fb76cc27f9a6d70a0b9aff7e70486f18;hpb=506d60f0e188723ddc91c26824b41ac7034df3fe;p=jalview.git diff --git a/src/jalview/io/vamsas/DatastoreItem.java b/src/jalview/io/vamsas/DatastoreItem.java index 42e494f..de82beb 100644 --- a/src/jalview/io/vamsas/DatastoreItem.java +++ b/src/jalview/io/vamsas/DatastoreItem.java @@ -1,26 +1,28 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4) - * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b1) + * Copyright (C) 2015 The Jalview Authors * - * 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 file is part of Jalview. * - * 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. + * Jalview 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 3 + * of the License, or (at your option) any later version. + * + * Jalview 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 + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.io.vamsas; import jalview.bin.Cache; -import jalview.gui.TreePanel; import jalview.io.VamsasAppDatastore; +import jalview.util.MessageManager; import java.util.Enumeration; import java.util.Hashtable; @@ -40,7 +42,7 @@ import uk.ac.vamsas.objects.core.Seg; * @author JimP * */ -public class DatastoreItem +public abstract class DatastoreItem { /** * @@ -53,7 +55,17 @@ public class DatastoreItem 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) @@ -94,6 +106,13 @@ 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(); @@ -108,22 +127,25 @@ public class DatastoreItem : "unregisterable") + " object " + vobj); } } - if (vobj2jv.containsKey(vobj.getVorbaId()) - && !((VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) + && !(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( + MessageManager + .getString("exception.overwriting_vamsas_id_binding"))); } 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.")); + Cache.log + .debug("Warning? Overwriting existing jalview object binding for " + + jvobj, + new Exception( + MessageManager + .getString("exception.overwriting_jalview_id_binding"))); } /* * Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " @@ -136,6 +158,53 @@ public class DatastoreItem 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(MessageManager.formatMessage( + "error.implementation_error_old_jalview_object_not_bound", + new String[] { oldjvobject.toString() })); + } + if (newjvobject != null) + { + jv2vobj.put(newjvobject, vobject); + vobj2jv.put(vobject, newjvobject); + updateRegistryEntry(newjvobject, vobj); + } } public DatastoreItem() @@ -150,16 +219,184 @@ public class DatastoreItem // 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( + MessageManager + .formatMessage( + "error.implementation_error_vamsas_doc_class_should_bind_to_type", + new String[] { vobj.getClass().toString(), + boundType.toString(), + jvobj.getClass().toString() })); + } + 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( + MessageManager + .formatMessage( + "error.implementation_error_vamsas_doc_class_should_bind_to_type", + new String[] { jvobj2.getClass().toString(), + boundToType.toString(), + vobj.getClass().toString() })); + } + 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, + private void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj) { this.provEntry = provEntry; @@ -191,7 +428,7 @@ public class DatastoreItem * * @param visSeg * @param ensureDirection - * when true - always ensure start is less than end. + * when true - always ensure start is less than end. * @return int[] { start, end, direction} where direction==1 for range running * from end to start. */ @@ -210,8 +447,7 @@ public class DatastoreItem end = start; start = t; } - return new int[] - { start, end, pol < 0 ? 1 : 0 }; + return new int[] { start, end, pol < 0 ? 1 : 0 }; } /** @@ -270,4 +506,87 @@ public class DatastoreItem { p.addEntry(dummyPEntry(action)); } + + /** + * @return true if jalview was being updated from the vamsas document + */ + public boolean isTojalview() + { + return tojalview; + } + + /** + * @return true if addToDocument() was called. + */ + public boolean isAddtodoc() + { + return addtodoc; + } + + /** + * @return true if conflict() was called + */ + public boolean isConflicted() + { + return conflicted; + } + + /** + * @return true if updateFromDoc() was called + */ + public boolean isUpdatedFromDoc() + { + return updatedfromdoc; + } + + /** + * @return true if updateToDoc() was called + */ + public boolean isUpdatedToDoc() + { + return updatedtodoc; + } + + /** + * @return true if addFromDocument() was called. + */ + public boolean isAddfromdoc() + { + return addfromdoc; + } + + /** + * @return true if object sync logic completed normally. + */ + public boolean isSuccess() + { + return success; + } + + /** + * @return the vobj + */ + public Vobject getVobj() + { + return vobj; + } + + /** + * @return the jvobj + */ + public Object getJvobj() + { + return jvobj; + } + + public boolean docWasUpdated() + { + return (this.addtodoc || this.updated) && this.success; + } + + public boolean jvWasUpdated() + { + return (success); // TODO : Implement this properly! + } + }