ascii file
authorjprocter <Jim Procter>
Tue, 25 Sep 2007 09:32:33 +0000 (09:32 +0000)
committerjprocter <Jim Procter>
Tue, 25 Sep 2007 09:32:33 +0000 (09:32 +0000)
src/jalview/io/vamsas/DatastoreItem.java
src/jalview/io/vamsas/Dbref.java
src/jalview/io/vamsas/LocalDocSyncObject.java
src/jalview/io/vamsas/Rangetype.java
src/jalview/io/vamsas/Sequencemapping.java
src/jalview/io/vamsas/Tree.java

index 1a57dc3..4cc540d 100644 (file)
-package jalview.io.vamsas;\r
-\r
-import jalview.bin.Cache;\r
-import jalview.gui.TreePanel;\r
-import jalview.io.VamsasAppDatastore;\r
-\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.IdentityHashMap;\r
-import java.util.Vector;\r
-\r
-import uk.ac.vamsas.client.IClientDocument;\r
-import uk.ac.vamsas.client.Vobject;\r
-import uk.ac.vamsas.client.VorbaId;\r
-import uk.ac.vamsas.objects.core.Entry;\r
-import uk.ac.vamsas.objects.core.Provenance;\r
-import uk.ac.vamsas.objects.core.Seg;\r
-\r
-/**\r
- * Holds all the common machinery for binding objects to vamsas objects\r
- * @author JimP\r
- *\r
- */\r
-public class DatastoreItem\r
-{\r
-  /**\r
-   * \r
-   */\r
-  Entry provEntry = null;\r
-\r
-  IClientDocument cdoc;\r
-\r
-  Hashtable vobj2jv;\r
-\r
-  IdentityHashMap jv2vobj;\r
-  /**\r
-   * @return the Vobject bound to Jalview datamodel object\r
-   */\r
-  protected Vobject getjv2vObj(Object jvobj)\r
-  {\r
-    if (jv2vobj.containsKey(jvobj))\r
-    {\r
-      return cdoc.getObject( (VorbaId) jv2vobj.get(jvobj));\r
-    }\r
-    if (Cache.log.isDebugEnabled())\r
-    {\r
-      Cache.log.debug("Returning null VorbaID binding for jalview object "+jvobj);\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   *\r
-   * @param vobj\r
-   * @return Jalview datamodel object bound to the vamsas document object\r
-   */\r
-  protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)\r
-  {\r
-    if (vobj2jv==null)\r
-      return null;\r
-    VorbaId id = vobj.getVorbaId();\r
-    if (id == null)\r
-    {\r
-      id = cdoc.registerObject(vobj);\r
-      Cache.log\r
-          .debug("Registering new object and returning null for getvObj2jv");\r
-      return null;\r
-    }\r
-    if (vobj2jv.containsKey(vobj.getVorbaId()))\r
-    {\r
-      return vobj2jv.get(vobj.getVorbaId());\r
-    }\r
-    return null;\r
-  }\r
-\r
-  protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)\r
-  {\r
-    VorbaId id = vobj.getVorbaId();\r
-    if (id == null)\r
-    {\r
-      id = cdoc.registerObject(vobj);\r
-      if (id == null || vobj.getVorbaId() == null || cdoc.getObject(id)!=vobj)\r
-      {\r
-        Cache.log.error("Failed to get id for " +\r
-                        (vobj.isRegisterable() ? "registerable" :\r
-                         "unregisterable") + " object " + vobj);\r
-      }\r
-    }\r
-\r
-    if (vobj2jv.containsKey(vobj.getVorbaId()) &&\r
-        ! ( (VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj))\r
-    {\r
-      Cache.log.debug("Warning? Overwriting existing vamsas id binding for " +\r
-                      vobj.getVorbaId(),\r
-                      new Exception("Overwriting vamsas id binding."));\r
-    }\r
-    else if (jv2vobj.containsKey(jvobj) &&\r
-             ! ( (VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))\r
-    {\r
-      Cache.log.debug(\r
-          "Warning? Overwriting existing jalview object binding for " + jvobj,\r
-          new Exception("Overwriting jalview object binding."));\r
-    }\r
-    /* 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"));\r
-         }*/\r
-    // we just update the hash's regardless!\r
-    Cache.log.debug("Binding "+vobj.getVorbaId()+" to "+jvobj);\r
-    vobj2jv.put(vobj.getVorbaId(), jvobj);\r
-    // JBPNote - better implementing a hybrid invertible hash.\r
-    jv2vobj.put(jvobj, vobj.getVorbaId());\r
-  }\r
-\r
-  public DatastoreItem() {\r
-    super();\r
-  }\r
-  public DatastoreItem(VamsasAppDatastore datastore)\r
-  {\r
-    this();\r
-    initDatastoreItem(datastore);\r
-    // TODO Auto-generated constructor stub\r
-  }\r
-  VamsasAppDatastore datastore = null;\r
-  public void initDatastoreItem(VamsasAppDatastore ds)\r
-  {\r
-    datastore = ds;\r
-    initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds.getVamsasObjectBinding(), ds.getJvObjectBinding());\r
-  }\r
-  public void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj)\r
-  {\r
-    this.provEntry = provEntry;\r
-    this.cdoc = cdoc;\r
-    this.vobj2jv = vobj2jv;\r
-    this.jv2vobj = jv2vobj;\r
-  }\r
-\r
-  protected boolean isModifiable(String modifiable)\r
-  {\r
-    return modifiable==null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)\r
-  }\r
-\r
-  protected Vector getjv2vObjs(Vector alsq)\r
-  {\r
-    Vector vObjs = new Vector();\r
-    Enumeration elm = alsq.elements();\r
-    while (elm.hasMoreElements())\r
-    {\r
-      vObjs.addElement(getjv2vObj(elm.nextElement()));\r
-    }\r
-    return vObjs;\r
-  }\r
-  // utility functions\r
-  /**\r
-   * get start<end range of segment, adjusting for inclusivity flag and\r
-   * polarity.\r
-   *\r
-   * @param visSeg\r
-   * @param ensureDirection when true - always ensure start is less than end.\r
-   * @return int[] { start, end, direction} where direction==1 for range running from end to start.\r
-   */\r
-  public int[] getSegRange(Seg visSeg, boolean ensureDirection)\r
-  {\r
-    boolean incl = visSeg.getInclusive();\r
-    // adjust for inclusive flag.\r
-    int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of\r
-    // region.\r
-    int start = visSeg.getStart() + (incl ? 0 : pol);\r
-    int end = visSeg.getEnd() + (incl ? 0 : -pol);\r
-    if (ensureDirection && pol == -1)\r
-    {\r
-      // jalview doesn't deal with inverted ranges, yet.\r
-      int t = end;\r
-      end = start;\r
-      start = t;\r
-    }\r
-    return new int[]\r
-        {\r
-        start, end, pol < 0 ? 1 : 0};\r
-  }\r
-  /**\r
-   * provenance bits\r
-   */\r
-  protected jalview.datamodel.Provenance getJalviewProvenance(Provenance prov)\r
-  {\r
-    // TODO: fix App and Action entries and check use of provenance in jalview.\r
-    jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();\r
-    for (int i = 0; i < prov.getEntryCount(); i++)\r
-    {\r
-      jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i).getAction(),\r
-                     prov.getEntry(i).getDate(),\r
-                     prov.getEntry(i).getId());\r
-    }\r
-\r
-    return jprov;\r
-  }\r
-\r
-  /**\r
-   *\r
-   * @return default initial provenance list for a Jalview created vamsas\r
-   *         object.\r
-   */\r
-  Provenance dummyProvenance()\r
-  {\r
-    return dummyProvenance(null);\r
-  }\r
-\r
-  protected Entry dummyPEntry(String action)\r
-  {\r
-    Entry entry = new Entry();\r
-    entry.setApp(this.provEntry.getApp());\r
-    if (action != null)\r
-    {\r
-      entry.setAction(action);\r
-    }\r
-    else\r
-    {\r
-      entry.setAction("created.");\r
-    }\r
-    entry.setDate(new java.util.Date());\r
-    entry.setUser(this.provEntry.getUser());\r
-    return entry;\r
-  }\r
-\r
-  protected Provenance dummyProvenance(String action)\r
-  {\r
-    Provenance prov = new Provenance();\r
-    prov.addEntry(dummyPEntry(action));\r
-    return prov;\r
-  }\r
-\r
-  protected void addProvenance(Provenance p, String action)\r
-  {\r
-    p.addEntry(dummyPEntry(action));\r
-  }\r
-\r
-}\r
+package jalview.io.vamsas;
+
+import jalview.bin.Cache;
+import jalview.gui.TreePanel;
+import jalview.io.VamsasAppDatastore;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Vector;
+
+import uk.ac.vamsas.client.IClientDocument;
+import uk.ac.vamsas.client.Vobject;
+import uk.ac.vamsas.client.VorbaId;
+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
+{
+  /**
+   * 
+   */
+  Entry provEntry = null;
+
+  IClientDocument cdoc;
+
+  Hashtable vobj2jv;
+
+  IdentityHashMap jv2vobj;
+  /**
+   * @return the Vobject bound to Jalview datamodel object
+   */
+  protected Vobject getjv2vObj(Object jvobj)
+  {
+    if (jv2vobj.containsKey(jvobj))
+    {
+      return cdoc.getObject( (VorbaId) jv2vobj.get(jvobj));
+    }
+    if (Cache.log.isDebugEnabled())
+    {
+      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)
+      return null;
+    VorbaId id = vobj.getVorbaId();
+    if (id == null)
+    {
+      id = cdoc.registerObject(vobj);
+      Cache.log
+          .debug("Registering new object and returning null for getvObj2jv");
+      return null;
+    }
+    if (vobj2jv.containsKey(vobj.getVorbaId()))
+    {
+      return vobj2jv.get(vobj.getVorbaId());
+    }
+    return null;
+  }
+
+  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)
+      {
+        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))
+    {
+      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()))
+    {
+      Cache.log.debug(
+          "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"));
+         }*/
+    // we just update the hash's regardless!
+    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());
+  }
+
+  public DatastoreItem() {
+    super();
+  }
+  public DatastoreItem(VamsasAppDatastore datastore)
+  {
+    this();
+    initDatastoreItem(datastore);
+    // TODO Auto-generated constructor stub
+  }
+  VamsasAppDatastore datastore = null;
+  public void initDatastoreItem(VamsasAppDatastore ds)
+  {
+    datastore = ds;
+    initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds.getVamsasObjectBinding(), ds.getJvObjectBinding());
+  }
+  public void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj)
+  {
+    this.provEntry = provEntry;
+    this.cdoc = cdoc;
+    this.vobj2jv = vobj2jv;
+    this.jv2vobj = jv2vobj;
+  }
+
+  protected boolean isModifiable(String modifiable)
+  {
+    return modifiable==null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
+  }
+
+  protected Vector getjv2vObjs(Vector alsq)
+  {
+    Vector vObjs = new Vector();
+    Enumeration elm = alsq.elements();
+    while (elm.hasMoreElements())
+    {
+      vObjs.addElement(getjv2vObj(elm.nextElement()));
+    }
+    return vObjs;
+  }
+  // utility functions
+  /**
+   * get start<end range of segment, adjusting for inclusivity flag and
+   * polarity.
+   *
+   * @param visSeg
+   * @param ensureDirection when true - always ensure start is less than end.
+   * @return int[] { start, end, direction} where direction==1 for range running from end to start.
+   */
+  public int[] getSegRange(Seg visSeg, boolean ensureDirection)
+  {
+    boolean incl = visSeg.getInclusive();
+    // adjust for inclusive flag.
+    int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
+    // region.
+    int start = visSeg.getStart() + (incl ? 0 : pol);
+    int end = visSeg.getEnd() + (incl ? 0 : -pol);
+    if (ensureDirection && pol == -1)
+    {
+      // jalview doesn't deal with inverted ranges, yet.
+      int t = end;
+      end = start;
+      start = t;
+    }
+    return new int[]
+        {
+        start, end, pol < 0 ? 1 : 0};
+  }
+  /**
+   * provenance bits
+   */
+  protected jalview.datamodel.Provenance getJalviewProvenance(Provenance prov)
+  {
+    // TODO: fix App and Action entries and check use of provenance in jalview.
+    jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
+    for (int i = 0; i < prov.getEntryCount(); i++)
+    {
+      jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i).getAction(),
+                     prov.getEntry(i).getDate(),
+                     prov.getEntry(i).getId());
+    }
+
+    return jprov;
+  }
+
+  /**
+   *
+   * @return default initial provenance list for a Jalview created vamsas
+   *         object.
+   */
+  Provenance dummyProvenance()
+  {
+    return dummyProvenance(null);
+  }
+
+  protected Entry dummyPEntry(String action)
+  {
+    Entry entry = new Entry();
+    entry.setApp(this.provEntry.getApp());
+    if (action != null)
+    {
+      entry.setAction(action);
+    }
+    else
+    {
+      entry.setAction("created.");
+    }
+    entry.setDate(new java.util.Date());
+    entry.setUser(this.provEntry.getUser());
+    return entry;
+  }
+
+  protected Provenance dummyProvenance(String action)
+  {
+    Provenance prov = new Provenance();
+    prov.addEntry(dummyPEntry(action));
+    return prov;
+  }
+
+  protected void addProvenance(Provenance p, String action)
+  {
+    p.addEntry(dummyPEntry(action));
+  }
+}
index c5ac44f..c4d72c3 100644 (file)
-package jalview.io.vamsas;\r
-\r
-import jalview.datamodel.DBRefEntry;\r
-import jalview.datamodel.SequenceI;\r
-import uk.ac.vamsas.objects.core.DbRef;\r
-import uk.ac.vamsas.objects.core.Map;\r
-import uk.ac.vamsas.objects.core.Sequence;\r
-import jalview.io.VamsasAppDatastore;\r
-\r
-public class Dbref extends Rangetype\r
-{\r
-  jalview.datamodel.SequenceI sq = null;\r
-  uk.ac.vamsas.objects.core.Sequence sequence = null;\r
-  DbRef dbref = null;\r
-  DBRefEntry dbentry=null;\r
-  public Dbref(VamsasAppDatastore datastore, DBRefEntry dbentry, jalview.datamodel.SequenceI sq2, uk.ac.vamsas.objects.core.Sequence sequence2)\r
-  {\r
-    super(datastore);\r
-    dbref = (DbRef) getjv2vObj(dbentry);\r
-    sq = sq2;\r
-    sequence = sequence2;\r
-    this.dbentry = dbentry;\r
-    if (dbref==null)\r
-    {\r
-      add();\r
-    } else {\r
-      if (dbref.isUpdated())\r
-      {\r
-        conflict();\r
-      } else {\r
-        update();\r
-      }\r
-        \r
-    }\r
-    \r
-  }\r
-\r
-  public Dbref(VamsasAppDatastore datastore, DbRef ref, Sequence vdseq, SequenceI dsseq)\r
-  {\r
-    super(datastore);\r
-    dbref = ref;\r
-    sequence = vdseq;\r
-    sq = dsseq;\r
-    dbentry = (jalview.datamodel.DBRefEntry) getvObj2jv(dbref);\r
-    if (dbentry == null)\r
-    {\r
-      addFromDocument();\r
-    } else {\r
-      if (dbref.isUpdated())\r
-      {\r
-        update();\r
-      }\r
-    }\r
-  }\r
-\r
-  private void update()\r
-  {\r
-    // TODO: verify and update dbrefs in vamsas document\r
-    // there will be trouble when a dataset sequence is modified to\r
-    // contain more residues than were originally referenced - we must\r
-    // then make a number of dataset sequence entries - this info is already stored \r
-    jalview.bin.Cache.log.debug("TODO verify update of dataset sequence database references.");\r
-  }\r
-\r
-  private void conflict()\r
-  {\r
-    jalview.bin.Cache.log.debug("Conflict in dbentry update for "+dbref.getAccessionId()+dbref.getSource()+" "+dbref.getVorbaId());\r
-    // TODO Auto-generated method stub\r
-    \r
-  }\r
-  private void addFromDocument()\r
-  {\r
-    // add new dbref\r
-    sq.addDBRef(dbentry = new jalview.datamodel.DBRefEntry\r
-            (\r
-                    dbref.getSource().toString(),\r
-                 dbref.getVersion().toString(),\r
-                 dbref.getAccessionId().toString()));\r
-    if (dbref.getMapCount()>0)\r
-    {\r
-      // TODO: Jalview ignores all the other maps\r
-      if (dbref.getMapCount()>1)\r
-      {\r
-        jalview.bin.Cache.log.debug("Ignoring additional mappings on DbRef: "+dbentry.getSource()+":"+dbentry.getAccessionId());\r
-      }\r
-      jalview.datamodel.Mapping mp = new jalview.datamodel.Mapping(parsemapType(dbref.getMap(0)));\r
-      dbentry.setMap(mp);\r
-    }\r
-    // TODO: jalview ignores links and properties because it doesn't know what to do with them.\r
-    \r
-    bindjvvobj(dbentry, dbref);\r
-  }\r
-  private void add()\r
-  {\r
-    DbRef dbref = new DbRef();\r
-    bindjvvobj(dbentry, dbref);\r
-    dbref.setAccessionId(dbentry.getAccessionId());\r
-    dbref.setSource(dbentry.getSource());\r
-    dbref.setVersion(dbentry.getVersion());\r
-    if (dbentry.getMap()!=null)\r
-    {\r
-      jalview.datamodel.Mapping mp = dbentry.getMap();\r
-      if (mp.getMap()!=null)\r
-      {\r
-        Map vMap = new Map();\r
-        initMapType(vMap, mp.getMap(), true);\r
-        dbref.addMap(vMap);\r
-      } else {\r
-        jalview.bin.Cache.log.debug("Ignoring mapless DbRef.Map "+dbentry.getSrcAccString());\r
-      }\r
-    }\r
-    sequence.addDbRef(dbref);\r
-  }\r
-\r
-}\r
+package jalview.io.vamsas;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceI;
+import uk.ac.vamsas.objects.core.DbRef;
+import uk.ac.vamsas.objects.core.Map;
+import uk.ac.vamsas.objects.core.Sequence;
+import jalview.io.VamsasAppDatastore;
+
+public class Dbref extends Rangetype
+{
+  jalview.datamodel.SequenceI sq = null;
+  uk.ac.vamsas.objects.core.Sequence sequence = null;
+  DbRef dbref = null;
+  DBRefEntry dbentry=null;
+  public Dbref(VamsasAppDatastore datastore, DBRefEntry dbentry, jalview.datamodel.SequenceI sq2, uk.ac.vamsas.objects.core.Sequence sequence2)
+  {
+    super(datastore);
+    dbref = (DbRef) getjv2vObj(dbentry);
+    sq = sq2;
+    sequence = sequence2;
+    this.dbentry = dbentry;
+    if (dbref==null)
+    {
+      add();
+    } else {
+      if (dbref.isUpdated())
+      {
+        conflict();
+      } else {
+        update();
+      }
+        
+    }
+    
+  }
+
+  public Dbref(VamsasAppDatastore datastore, DbRef ref, Sequence vdseq, SequenceI dsseq)
+  {
+    super(datastore);
+    dbref = ref;
+    sequence = vdseq;
+    sq = dsseq;
+    dbentry = (jalview.datamodel.DBRefEntry) getvObj2jv(dbref);
+    if (dbentry == null)
+    {
+      addFromDocument();
+    } else {
+      if (dbref.isUpdated())
+      {
+        update();
+      }
+    }
+  }
+
+  private void update()
+  {
+    // TODO: verify and update dbrefs in vamsas document
+    // there will be trouble when a dataset sequence is modified to
+    // contain more residues than were originally referenced - we must
+    // then make a number of dataset sequence entries - this info is already stored 
+    jalview.bin.Cache.log.debug("TODO verify update of dataset sequence database references.");
+  }
+
+  private void conflict()
+  {
+    jalview.bin.Cache.log.debug("Conflict in dbentry update for "+dbref.getAccessionId()+dbref.getSource()+" "+dbref.getVorbaId());
+    // TODO Auto-generated method stub
+    
+  }
+  private void addFromDocument()
+  {
+    // add new dbref
+    sq.addDBRef(dbentry = new jalview.datamodel.DBRefEntry
+            (
+                    dbref.getSource().toString(),
+                 dbref.getVersion().toString(),
+                 dbref.getAccessionId().toString()));
+    if (dbref.getMapCount()>0)
+    {
+      // TODO: Jalview ignores all the other maps
+      if (dbref.getMapCount()>1)
+      {
+        jalview.bin.Cache.log.debug("Ignoring additional mappings on DbRef: "+dbentry.getSource()+":"+dbentry.getAccessionId());
+      }
+      jalview.datamodel.Mapping mp = new jalview.datamodel.Mapping(parsemapType(dbref.getMap(0)));
+      dbentry.setMap(mp);
+    }
+    // TODO: jalview ignores links and properties because it doesn't know what to do with them.
+    
+    bindjvvobj(dbentry, dbref);
+  }
+  private void add()
+  {
+    DbRef dbref = new DbRef();
+    bindjvvobj(dbentry, dbref);
+    dbref.setAccessionId(dbentry.getAccessionId());
+    dbref.setSource(dbentry.getSource());
+    dbref.setVersion(dbentry.getVersion());
+    if (dbentry.getMap()!=null)
+    {
+      jalview.datamodel.Mapping mp = dbentry.getMap();
+      if (mp.getMap()!=null)
+      {
+        Map vMap = new Map();
+        initMapType(vMap, mp.getMap(), true);
+        dbref.addMap(vMap);
+      } else {
+        jalview.bin.Cache.log.debug("Ignoring mapless DbRef.Map "+dbentry.getSrcAccString());
+      }
+    }
+    sequence.addDbRef(dbref);
+  }
+
+}
index 344d40b..bfc2123 100644 (file)
@@ -1,85 +1,85 @@
-package jalview.io.vamsas;\r
-\r
-import uk.ac.vamsas.client.Vobject;\r
-\r
-/**\r
- * Implement the basic logic for synchronising changes to or from the Vamsas Document\r
- * @author JimP\r
- */\r
-public abstract class LocalDocSyncObject extends DatastoreItem\r
-{\r
-  /**\r
-   * \r
-   * @return null or the local object that is being worked on. \r
-   */\r
-  public abstract Object getLObject();\r
-  /**\r
-   * \r
-   * @return null or the document object that is being worked on\r
-   */\r
-  public abstract Vobject getVObject();\r
-  \r
-  /**\r
-   * endpoint for synchronize when all opreations are finished.\r
-   */\r
-  public abstract void nextObject();\r
-  /**\r
-   * called if the local object can be safely updated from the bound document object.\r
-   */\r
-  public abstract void updateFromDoc();\r
-  /**\r
-   * called if the associated document object can be safely updated with the local changes\r
-   */\r
-  public abstract void updateToDoc();\r
-  /**\r
-   * @return true if the local object is modified\r
-   */\r
-  public abstract boolean locallyModified();\r
-  /**\r
-   * \r
-   * @return true if the bound document object is modified\r
-   */\r
-  public abstract boolean documentModified();\r
-  /**\r
-   * \r
-   * @return true if the document object is locked  w.r.t. this object's update.\r
-   */\r
-  public abstract boolean documentObjectLocked();\r
-  /**\r
-   * \r
-   * @return a new datastore item instance which binds the local object to a new document object \r
-   */\r
-  public abstract LocalDocSyncObject newDocumentObject(); // could make this constructor(Lobject)\r
-  /**\r
-   * \r
-   * @return a new datastore item instance which binds the document object to a new local object. \r
-   */\r
-  public abstract LocalDocSyncObject newLocalObject(); // make this constructor(Vobject)\r
-  /**\r
-   * apply the update/commit logic as defined in the vamsas paper\r
-   * @param documentIsUpdated true if a document update event is being handled  \r
-   */\r
-  public void synchronize(boolean documentIsUpdated) {\r
-    Object Lobject = getLObject();\r
-    Vobject Vobject = getVObject();\r
-    if (Lobject==null)\r
-    {\r
-      // no local binding for document object\r
-      newLocalObject().synchronize(documentIsUpdated);\r
-      return;\r
-    }\r
-    if (Vobject==null)\r
-    {\r
-      // no document binding for local object\r
-      newDocumentObject().synchronize(documentIsUpdated);\r
-    }\r
-    // Check binding is valid\r
-    if (getjv2vObj(Lobject)!=Vobject)\r
-    {\r
-      // no local binding for document object\r
-      newLocalObject().synchronize(documentIsUpdated);\r
-      // no document binding for local object\r
-      newDocumentObject().synchronize(documentIsUpdated);\r
-    }\r
-  }\r
-}\r
+package jalview.io.vamsas;
+
+import uk.ac.vamsas.client.Vobject;
+
+/**
+ * Implement the basic logic for synchronising changes to or from the Vamsas Document
+ * @author JimP
+ */
+public abstract class LocalDocSyncObject extends DatastoreItem
+{
+  /**
+   * 
+   * @return null or the local object that is being worked on. 
+   */
+  public abstract Object getLObject();
+  /**
+   * 
+   * @return null or the document object that is being worked on
+   */
+  public abstract Vobject getVObject();
+  
+  /**
+   * endpoint for synchronize when all opreations are finished.
+   */
+  public abstract void nextObject();
+  /**
+   * called if the local object can be safely updated from the bound document object.
+   */
+  public abstract void updateFromDoc();
+  /**
+   * called if the associated document object can be safely updated with the local changes
+   */
+  public abstract void updateToDoc();
+  /**
+   * @return true if the local object is modified
+   */
+  public abstract boolean locallyModified();
+  /**
+   * 
+   * @return true if the bound document object is modified
+   */
+  public abstract boolean documentModified();
+  /**
+   * 
+   * @return true if the document object is locked  w.r.t. this object's update.
+   */
+  public abstract boolean documentObjectLocked();
+  /**
+   * 
+   * @return a new datastore item instance which binds the local object to a new document object 
+   */
+  public abstract LocalDocSyncObject newDocumentObject(); // could make this constructor(Lobject)
+  /**
+   * 
+   * @return a new datastore item instance which binds the document object to a new local object. 
+   */
+  public abstract LocalDocSyncObject newLocalObject(); // make this constructor(Vobject)
+  /**
+   * apply the update/commit logic as defined in the vamsas paper
+   * @param documentIsUpdated true if a document update event is being handled  
+   */
+  public void synchronize(boolean documentIsUpdated) {
+    Object Lobject = getLObject();
+    Vobject Vobject = getVObject();
+    if (Lobject==null)
+    {
+      // no local binding for document object
+      newLocalObject().synchronize(documentIsUpdated);
+      return;
+    }
+    if (Vobject==null)
+    {
+      // no document binding for local object
+      newDocumentObject().synchronize(documentIsUpdated);
+    }
+    // Check binding is valid
+    if (getjv2vObj(Lobject)!=Vobject)
+    {
+      // no local binding for document object
+      newLocalObject().synchronize(documentIsUpdated);
+      // no document binding for local object
+      newDocumentObject().synchronize(documentIsUpdated);
+    }
+  }
+}
index f6a6ecc..b7e6f79 100644 (file)
-package jalview.io.vamsas;\r
-\r
-\r
-import java.util.Vector;\r
-\r
-import uk.ac.vamsas.objects.core.Local;\r
-import uk.ac.vamsas.objects.core.Map;\r
-import uk.ac.vamsas.objects.core.MapType;\r
-import uk.ac.vamsas.objects.core.Mapped;\r
-import uk.ac.vamsas.objects.core.RangeType;\r
-import uk.ac.vamsas.objects.core.Seg;\r
-import jalview.datamodel.Mapping;\r
-import jalview.io.VamsasAppDatastore;\r
-\r
-public class Rangetype extends DatastoreItem\r
-{\r
-\r
-  public Rangetype()\r
-  {\r
-    super();\r
-  }\r
-\r
-  public Rangetype(VamsasAppDatastore datastore)\r
-  {\r
-    super(datastore);\r
-  }\r
-\r
-  /**\r
-   * get real bounds of a RangeType's specification. start and end are an\r
-   * inclusive range within which all segments and positions lie.\r
-   * TODO: refactor to vamsas utils\r
-   * @param dseta\r
-   * @return int[] { start, end}\r
-   */\r
-  protected int[] getBounds(RangeType dseta)\r
-  {\r
-    if (dseta != null)\r
-    {\r
-      int[] se = null;\r
-      if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
-      {\r
-        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
-      }\r
-      if (dseta.getSegCount() > 0)\r
-      {\r
-        se = getSegRange(dseta.getSeg(0), true);\r
-        for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)\r
-        {\r
-          int nse[] = getSegRange(dseta.getSeg(s), true);\r
-          if (se[0] > nse[0])\r
-          {\r
-            se[0] = nse[0];\r
-          }\r
-          if (se[1] < nse[1])\r
-          {\r
-            se[1] = nse[1];\r
-          }\r
-        }\r
-      }\r
-      if (dseta.getPosCount() > 0)\r
-      {\r
-        // could do a polarity for pos range too. and pass back indication of discontinuities.\r
-        int pos = dseta.getPos(0).getI();\r
-        se = new int[]\r
-            {\r
-            pos, pos};\r
-        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
-        {\r
-          pos = dseta.getPos(p).getI();\r
-          if (se[0] > pos)\r
-          {\r
-            se[0] = pos;\r
-          }\r
-          if (se[1] < pos)\r
-          {\r
-            se[1] = pos;\r
-          }\r
-        }\r
-      }\r
-      return se;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * map from a rangeType's internal frame to the referenced object's coordinate frame.\r
-   * @param dseta\r
-   * @return int [] { ref(pos)...} for all pos in rangeType's frame.\r
-   */\r
-  protected int[] getMapping(RangeType dseta)\r
-  {\r
-    Vector posList = new Vector();\r
-    if (dseta != null)\r
-    {\r
-      int[] se = null;\r
-      if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
-      {\r
-        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
-      }\r
-      if (dseta.getSegCount() > 0)\r
-      {\r
-        for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)\r
-        {\r
-          se = getSegRange(dseta.getSeg(s), false);\r
-          int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);\r
-          for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)\r
-          {\r
-            posList.add(new Integer(p));\r
-          }\r
-        }\r
-      }\r
-      else if (dseta.getPosCount() > 0)\r
-      {\r
-        int pos = dseta.getPos(0).getI();\r
-  \r
-        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
-        {\r
-          pos = dseta.getPos(p).getI();\r
-          posList.add(new Integer(pos));\r
-        }\r
-      }\r
-    }\r
-    if (posList != null && posList.size() > 0)\r
-    {\r
-      int[] range = new int[posList.size()];\r
-      for (int i = 0; i < range.length; i++)\r
-      {\r
-        range[i] = ( (Integer) posList.elementAt(i)).intValue();\r
-      }\r
-      posList.clear();\r
-      return range;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  protected int[] getIntervals(RangeType range)\r
-  {\r
-    int[] intervals=null;\r
-    Vector posList = new Vector();\r
-    if (range != null)\r
-    {\r
-      int[] se = null;\r
-      if (range.getSegCount() > 0 && range.getPosCount() > 0)\r
-      {\r
-        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
-      }\r
-      if (range.getSegCount() > 0)\r
-      {\r
-        for (int s = 0, sSize = range.getSegCount(); s < sSize; s++)\r
-        {\r
-          se = getSegRange(range.getSeg(s), false);\r
-          posList.addElement(new Integer(se[0]));\r
-          posList.addElement(new Integer(se[1]));\r
-        }\r
-      }\r
-      else if (range.getPosCount() > 0)\r
-      {\r
-        int pos = range.getPos(0).getI();\r
-  \r
-        for (int p = 0, pSize = range.getPosCount(); p < pSize; p++)\r
-        {\r
-          pos = range.getPos(p).getI();\r
-          posList.add(new Integer(pos));\r
-          posList.add(new Integer(pos));\r
-        }\r
-      }\r
-    }\r
-    if (posList != null && posList.size() > 0)\r
-    {\r
-      intervals=new int[posList.size()];\r
-      java.util.Enumeration e = posList.elements();\r
-      int i=0;\r
-      while (e.hasMoreElements())\r
-      {\r
-        intervals[i++] = ((Integer)e.nextElement()).intValue();\r
-      }\r
-    }\r
-    return intervals;\r
-  }\r
-  /**\r
-   * initialise a range type object from a set of start/end inclusive intervals\r
-   * @param mrt\r
-   * @param range\r
-   */\r
-  protected void initRangeType(RangeType mrt, int[] range)\r
-  {\r
-    for (int i=0; i<range.length; i+=2)\r
-    {\r
-      Seg vSeg = new Seg();\r
-      vSeg.setStart(range[i]);\r
-      vSeg.setEnd(range[i+1]);\r
-      vSeg.setInclusive(true);\r
-      mrt.addSeg(vSeg);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * \r
-   * @param maprange where the from range is the local mapped range, and the to range is the 'mapped' range in the MapRangeType\r
-   * @param default unit for local\r
-   * @param default unit for mapped\r
-   * @return MapList\r
-   */\r
-  protected jalview.util.MapList parsemapType(MapType maprange, int localu, int mappedu)\r
-  {\r
-    jalview.util.MapList ml = null;\r
-    int[] localRange = getIntervals(maprange.getLocal());\r
-    int[] mappedRange = getIntervals(maprange.getMapped());\r
-    long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit() : localu;\r
-    long mu = maprange.getMapped().hasUnit() ? maprange.getMapped().getUnit() : mappedu;\r
-    ml = new jalview.util.MapList(localRange, mappedRange, (int)lu, (int)mu);\r
-    return ml;\r
-  }\r
-  protected jalview.util.MapList parsemapType(MapType map)\r
-  {\r
-    if (!map.getLocal().hasUnit() || map.getMapped().hasUnit())\r
-    {\r
-      jalview.bin.Cache.log.warn("using default mapping length of 1:1 for map "\r
-              +(map.isRegistered() ? map.getVorbaId().toString() : ("<no Id registered> "+map.toString())));\r
-    }\r
-    return parsemapType(map, 1, 1); \r
-  }\r
-\r
-  /**\r
-   * initialise a MapType object from a MapList object.\r
-   * @param maprange\r
-   * @param ml\r
-   * @param setUnits\r
-   */\r
-  protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits)\r
-  {\r
-    initMapType(maprange, ml, setUnits, false);\r
-  }\r
-  /**\r
-   * \r
-   * @param maprange\r
-   * @param ml\r
-   * @param setUnits\r
-   * @param reverse - reverse MapList mapping for Local and Mapped ranges and units \r
-   */\r
-  protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits, boolean reverse)\r
-  {\r
-    if (ml==null)\r
-    {\r
-      throw new Error("Implementation error. MapList is null for initMapType.");\r
-    }\r
-    maprange.setLocal(new Local());\r
-    maprange.setMapped(new Mapped());\r
-    if (!reverse)\r
-      {\r
-      initRangeType(maprange.getLocal(), ml.getFromRanges());\r
-      initRangeType(maprange.getMapped(), ml.getToRanges());\r
-      } else {\r
-        initRangeType(maprange.getLocal(), ml.getToRanges());\r
-        initRangeType(maprange.getMapped(), ml.getFromRanges());\r
-      }\r
-    if (setUnits)\r
-    {\r
-      if (!reverse)\r
-      { \r
-        maprange.getLocal().setUnit(ml.getFromRatio());\r
-        maprange.getMapped().setUnit(ml.getToRatio());\r
-      } else {\r
-        maprange.getLocal().setUnit(ml.getToRatio());\r
-        maprange.getMapped().setUnit(ml.getFromRatio());\r
-      }\r
-    }\r
-  }\r
-\r
+package jalview.io.vamsas;
+
+
+import java.util.Vector;
+
+import uk.ac.vamsas.objects.core.Local;
+import uk.ac.vamsas.objects.core.Map;
+import uk.ac.vamsas.objects.core.MapType;
+import uk.ac.vamsas.objects.core.Mapped;
+import uk.ac.vamsas.objects.core.RangeType;
+import uk.ac.vamsas.objects.core.Seg;
+import jalview.datamodel.Mapping;
+import jalview.io.VamsasAppDatastore;
+
+public class Rangetype extends DatastoreItem
+{
+
+  public Rangetype()
+  {
+    super();
+  }
+
+  public Rangetype(VamsasAppDatastore datastore)
+  {
+    super(datastore);
+  }
+
+  /**
+   * get real bounds of a RangeType's specification. start and end are an
+   * inclusive range within which all segments and positions lie.
+   * TODO: refactor to vamsas utils
+   * @param dseta
+   * @return int[] { start, end}
+   */
+  protected int[] getBounds(RangeType dseta)
+  {
+    if (dseta != null)
+    {
+      int[] se = null;
+      if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
+      {
+        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+      }
+      if (dseta.getSegCount() > 0)
+      {
+        se = getSegRange(dseta.getSeg(0), true);
+        for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
+        {
+          int nse[] = getSegRange(dseta.getSeg(s), true);
+          if (se[0] > nse[0])
+          {
+            se[0] = nse[0];
+          }
+          if (se[1] < nse[1])
+          {
+            se[1] = nse[1];
+          }
+        }
+      }
+      if (dseta.getPosCount() > 0)
+      {
+        // could do a polarity for pos range too. and pass back indication of discontinuities.
+        int pos = dseta.getPos(0).getI();
+        se = new int[]
+            {
+            pos, pos};
+        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
+        {
+          pos = dseta.getPos(p).getI();
+          if (se[0] > pos)
+          {
+            se[0] = pos;
+          }
+          if (se[1] < pos)
+          {
+            se[1] = pos;
+          }
+        }
+      }
+      return se;
+    }
+    return null;
+  }
+
+  /**
+   * map from a rangeType's internal frame to the referenced object's coordinate frame.
+   * @param dseta
+   * @return int [] { ref(pos)...} for all pos in rangeType's frame.
+   */
+  protected int[] getMapping(RangeType dseta)
+  {
+    Vector posList = new Vector();
+    if (dseta != null)
+    {
+      int[] se = null;
+      if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
+      {
+        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+      }
+      if (dseta.getSegCount() > 0)
+      {
+        for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
+        {
+          se = getSegRange(dseta.getSeg(s), false);
+          int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);
+          for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)
+          {
+            posList.add(new Integer(p));
+          }
+        }
+      }
+      else if (dseta.getPosCount() > 0)
+      {
+        int pos = dseta.getPos(0).getI();
+  
+        for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
+        {
+          pos = dseta.getPos(p).getI();
+          posList.add(new Integer(pos));
+        }
+      }
+    }
+    if (posList != null && posList.size() > 0)
+    {
+      int[] range = new int[posList.size()];
+      for (int i = 0; i < range.length; i++)
+      {
+        range[i] = ( (Integer) posList.elementAt(i)).intValue();
+      }
+      posList.clear();
+      return range;
+    }
+    return null;
+  }
+
+  protected int[] getIntervals(RangeType range)
+  {
+    int[] intervals=null;
+    Vector posList = new Vector();
+    if (range != null)
+    {
+      int[] se = null;
+      if (range.getSegCount() > 0 && range.getPosCount() > 0)
+      {
+        throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+      }
+      if (range.getSegCount() > 0)
+      {
+        for (int s = 0, sSize = range.getSegCount(); s < sSize; s++)
+        {
+          se = getSegRange(range.getSeg(s), false);
+          posList.addElement(new Integer(se[0]));
+          posList.addElement(new Integer(se[1]));
+        }
+      }
+      else if (range.getPosCount() > 0)
+      {
+        int pos = range.getPos(0).getI();
+  
+        for (int p = 0, pSize = range.getPosCount(); p < pSize; p++)
+        {
+          pos = range.getPos(p).getI();
+          posList.add(new Integer(pos));
+          posList.add(new Integer(pos));
+        }
+      }
+    }
+    if (posList != null && posList.size() > 0)
+    {
+      intervals=new int[posList.size()];
+      java.util.Enumeration e = posList.elements();
+      int i=0;
+      while (e.hasMoreElements())
+      {
+        intervals[i++] = ((Integer)e.nextElement()).intValue();
+      }
+    }
+    return intervals;
+  }
+  /**
+   * initialise a range type object from a set of start/end inclusive intervals
+   * @param mrt
+   * @param range
+   */
+  protected void initRangeType(RangeType mrt, int[] range)
+  {
+    for (int i=0; i<range.length; i+=2)
+    {
+      Seg vSeg = new Seg();
+      vSeg.setStart(range[i]);
+      vSeg.setEnd(range[i+1]);
+      vSeg.setInclusive(true);
+      mrt.addSeg(vSeg);
+    }
+  }
+
+  /**
+   * 
+   * @param maprange where the from range is the local mapped range, and the to range is the 'mapped' range in the MapRangeType
+   * @param default unit for local
+   * @param default unit for mapped
+   * @return MapList
+   */
+  protected jalview.util.MapList parsemapType(MapType maprange, int localu, int mappedu)
+  {
+    jalview.util.MapList ml = null;
+    int[] localRange = getIntervals(maprange.getLocal());
+    int[] mappedRange = getIntervals(maprange.getMapped());
+    long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit() : localu;
+    long mu = maprange.getMapped().hasUnit() ? maprange.getMapped().getUnit() : mappedu;
+    ml = new jalview.util.MapList(localRange, mappedRange, (int)lu, (int)mu);
+    return ml;
+  }
+  protected jalview.util.MapList parsemapType(MapType map)
+  {
+    if (!map.getLocal().hasUnit() || map.getMapped().hasUnit())
+    {
+      jalview.bin.Cache.log.warn("using default mapping length of 1:1 for map "
+              +(map.isRegistered() ? map.getVorbaId().toString() : ("<no Id registered> "+map.toString())));
+    }
+    return parsemapType(map, 1, 1); 
+  }
+
+  /**
+   * initialise a MapType object from a MapList object.
+   * @param maprange
+   * @param ml
+   * @param setUnits
+   */
+  protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits)
+  {
+    initMapType(maprange, ml, setUnits, false);
+  }
+  /**
+   * 
+   * @param maprange
+   * @param ml
+   * @param setUnits
+   * @param reverse - reverse MapList mapping for Local and Mapped ranges and units 
+   */
+  protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits, boolean reverse)
+  {
+    if (ml==null)
+    {
+      throw new Error("Implementation error. MapList is null for initMapType.");
+    }
+    maprange.setLocal(new Local());
+    maprange.setMapped(new Mapped());
+    if (!reverse)
+      {
+      initRangeType(maprange.getLocal(), ml.getFromRanges());
+      initRangeType(maprange.getMapped(), ml.getToRanges());
+      } else {
+        initRangeType(maprange.getLocal(), ml.getToRanges());
+        initRangeType(maprange.getMapped(), ml.getFromRanges());
+      }
+    if (setUnits)
+    {
+      if (!reverse)
+      { 
+        maprange.getLocal().setUnit(ml.getFromRatio());
+        maprange.getMapped().setUnit(ml.getToRatio());
+      } else {
+        maprange.getLocal().setUnit(ml.getToRatio());
+        maprange.getMapped().setUnit(ml.getFromRatio());
+      }
+    }
+  }
+
 }
\ No newline at end of file
index 4cede9a..746a7d0 100644 (file)
-package jalview.io.vamsas;\r
-\r
-import java.util.Vector;\r
-\r
-import jalview.datamodel.AlignedCodonFrame;\r
-import jalview.datamodel.Mapping;\r
-import jalview.datamodel.SequenceI;\r
-import jalview.io.VamsasAppDatastore;\r
-import uk.ac.vamsas.client.Vobject;\r
-import uk.ac.vamsas.objects.core.AlignmentSequence;\r
-import uk.ac.vamsas.objects.core.DataSet;\r
-import uk.ac.vamsas.objects.core.Local;\r
-import uk.ac.vamsas.objects.core.RangeType;\r
-import uk.ac.vamsas.objects.core.Seg;\r
-import uk.ac.vamsas.objects.core.Sequence;\r
-import uk.ac.vamsas.objects.core.SequenceMapping;\r
-import uk.ac.vamsas.objects.core.SequenceType;\r
-\r
-public class Sequencemapping extends Rangetype\r
-{\r
-  public Sequencemapping(VamsasAppDatastore datastore, SequenceMapping sequenceMapping)\r
-  {\r
-    super(datastore);\r
-    Object mjvmapping = getvObj2jv(sequenceMapping);\r
-    if (mjvmapping==null)\r
-    {\r
-      add(sequenceMapping);\r
-    } else {\r
-      if (sequenceMapping.isUpdated())\r
-      {\r
-        update((jalview.util.MapList) mjvmapping, sequenceMapping);\r
-      }\r
-    }\r
-  }\r
-  /**\r
-   * create or update a vamsas sequence mapping corresponding to a jalview\r
-   * Mapping between two dataset sequences\r
-   * \r
-   * @param datastore\r
-   * @param mjvmapping\r
-   * @param from\r
-   * @param ds\r
-   */\r
-  public Sequencemapping(VamsasAppDatastore datastore, jalview.datamodel.Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, uk.ac.vamsas.objects.core.DataSet ds)\r
-  {\r
-    super(datastore);\r
-    SequenceMapping sequenceMapping = (SequenceMapping) getjv2vObj(mjvmapping);\r
-    if (sequenceMapping==null)\r
-    {\r
-      add(mjvmapping, from, ds);\r
-    } else {\r
-      if (from!=null && sequenceMapping.getLoc()!=from)\r
-      {\r
-        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+from+" doesn't match the local mapping sequence.");\r
-      }\r
-      if (ds!=null && sequenceMapping.is__stored_in_document() && sequenceMapping.getV_parent()!=ds)\r
-      {\r
-        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+ds+" doesn't match the parent of the bound sequence mapping object.");\r
-      }\r
-      if (sequenceMapping.isUpdated())\r
-      { \r
-        conflict(mjvmapping, sequenceMapping);\r
-      } else {\r
-        update(mjvmapping, sequenceMapping);\r
-      }\r
-    }\r
-  }\r
-  private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)\r
-  {\r
-    // TODO Auto-generated method stub\r
-\r
-  }\r
-  private void add(Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, DataSet ds)\r
-  {\r
-    SequenceI jvto = mjvmapping.getTo();\r
-    while (jvto.getDatasetSequence()!=null)\r
-    {\r
-      jvto = jvto.getDatasetSequence();\r
-    }\r
-    SequenceType to = (SequenceType) getjv2vObj(jvto);\r
-    if (to==null)\r
-    {\r
-      jalview.bin.Cache.log.warn("NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object");\r
-      return;\r
-    } \r
-    SequenceMapping sequenceMapping = new SequenceMapping();\r
-    sequenceMapping.setLoc(from);\r
-    sequenceMapping.setMap(to);\r
-    boolean dnaToProt=false,sense=false;\r
-    // ensure that we create a mapping with the correct sense\r
-    if (((Sequence) sequenceMapping.getLoc())\r
-            .getDictionary()\r
-            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-    {\r
-      if (((Sequence) sequenceMapping.getMap())\r
-              .getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=true;\r
-      } \r
-    } else {\r
-      if (((Sequence) sequenceMapping.getMap())\r
-              .getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=false;\r
-      } \r
-    }\r
-\r
-    if (!dnaToProt)\r
-    {\r
-      jalview.bin.Cache.log.warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet.");\r
-      return;\r
-    }\r
-    if (ds==null)\r
-    {\r
-      // locate dataset for storage of SequenceMapping\r
-      if (sense)\r
-      {\r
-        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getLoc()).getV_parent();\r
-      } else {\r
-        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getMap()).getV_parent();\r
-      } \r
-    }\r
-    if (sense)\r
-    {\r
-      this.initMapType(sequenceMapping, mjvmapping.getMap(), true);\r
-    } else {\r
-      this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(), true);\r
-    }\r
-    ds.addSequenceMapping(sequenceMapping);\r
-    sequenceMapping.setProvenance(this.dummyProvenance("user defined coding region translation")); // TODO:\r
-    // correctly\r
-    // construct\r
-    // provenance\r
-    // based\r
-    // on\r
-    // source\r
-    // of\r
-    // mapping\r
-    bindjvvobj(mjvmapping, sequenceMapping);\r
-\r
-    jalview.bin.Cache.log.debug("Successfully created mapping "+sequenceMapping.getVorbaId());\r
-  }\r
-  private void update(jalview.util.MapList mjvmapping, SequenceMapping sequenceMapping)\r
-  {\r
-    jalview.bin.Cache.log.error("Not implemented: Jalview Update Alcodon Mapping:TODO!"); \r
-  }\r
-  private void update(jalview.datamodel.Mapping mjvmapping, SequenceMapping sequenceMapping)\r
-  {\r
-    jalview.bin.Cache.log.error("Not implemented: Jalview Update Sequence DBRef Mapping"); \r
-  }\r
-  /**\r
-   * limitations: Currently, jalview only deals with mappings between dataset\r
-   * sequences, and even then, only between those that map from DNA to Protein.\r
-   * \r
-   * @param sequenceMapping\r
-   */\r
-  private void add(SequenceMapping sequenceMapping)\r
-  {\r
-    Object mobj;\r
-    SequenceI from=null,to=null;\r
-    boolean dnaToProt=false,sense=false;\r
-    Sequence sdloc=null, sdmap=null;\r
-    if (sequenceMapping.getLoc() instanceof AlignmentSequence)\r
-    {\r
-      sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc()).getRefid();\r
-    } else {\r
-      sdloc = ((Sequence) sequenceMapping.getLoc());\r
-    }\r
-    if (sequenceMapping.getMap() instanceof AlignmentSequence)\r
-    {\r
-      sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap()).getRefid();\r
-    } else {\r
-      sdmap = ((Sequence) sequenceMapping.getMap());\r
-    }\r
-    if (sdloc==null || sdmap == null)\r
-    {\r
-      jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");\r
-      return;\r
-    }\r
-    mobj = this.getvObj2jv((Vobject) sdloc);\r
-    if (mobj instanceof SequenceI)\r
-    {\r
-      from = (SequenceI) mobj;\r
-    }\r
-    mobj = this.getvObj2jv((Vobject) sdmap);\r
-    if (mobj instanceof SequenceI)\r
-    {\r
-      to = (SequenceI) mobj;\r
-    }\r
-    if (from == null || to == null)\r
-    {\r
-\r
-      jalview.bin.Cache.log.error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!");\r
-      return;\r
-    } \r
-\r
-    if (sdloc.getDictionary()\r
-            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-    {\r
-      if (sdmap.getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=true;\r
-      } \r
-      // else {\r
-\r
-      // }\r
-    } else {\r
-      if (sdmap.getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=false;\r
-      } \r
-    }\r
-    // create mapping storage object and make each dataset alignment reference\r
-    // it.\r
-    jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc.getV_parent());\r
-    jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap.getV_parent());\r
-    AlignedCodonFrame afc = new AlignedCodonFrame(0);\r
-\r
-    if (dsLoc!=null && dsLoc!=dsMap)\r
-    {\r
-      dsLoc.addCodonFrame(afc);\r
-    }\r
-    if (dsMap!=null)\r
-    {\r
-      dsMap.addCodonFrame(afc);\r
-    }\r
-    // create and add the new mapping to (each) dataset's codonFrame\r
-\r
-    jalview.util.MapList mapping = null; \r
-    if (!sense)\r
-    {\r
-      mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense\r
-      mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio());\r
-      afc.addMap(to, from, mapping);\r
-    } else {\r
-      mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense\r
-      afc.addMap(from, to, mapping);\r
-    }\r
-    bindjvvobj(mapping, sequenceMapping);\r
-    jalview.structure.StructureSelectionManager.getStructureSelectionManager().addMappings(new AlignedCodonFrame[] { afc });\r
-    // Try to link up any conjugate database references in the two sequences\r
-    // matchConjugateDBRefs(from, to,  mapping);\r
-    // Try to propagate any dbrefs across this mapping.\r
-\r
-  }\r
-  /**\r
-   * Complete any 'to' references in jalview.datamodel.Mapping objects associated with conjugate DBRefEntry under given mapping  \r
-   * @param from sequence corresponding to from reference for sequence mapping\r
-   * @param to sequence correspondeing to to reference for sequence mapping\r
-   * @param smap maplist parsed in same sense as from and to\r
-   */\r
-  private void matchConjugateDBRefs(SequenceI from, SequenceI to,\r
-          jalview.util.MapList smap)\r
-  {\r
-    if (from.getDBRef()==null && to.getDBRef()==null)\r
-    {\r
-      if (jalview.bin.Cache.log.isDebugEnabled())\r
-      {\r
-        jalview.bin.Cache.log.debug("Not matching conjugate refs for "+from.getName()+" and "+to.getName());\r
-      }\r
-      return; \r
-    }\r
-    if (jalview.bin.Cache.log.isDebugEnabled())\r
-    {\r
-      jalview.bin.Cache.log.debug("Matching conjugate refs for "+from.getName()+" and "+to.getName());\r
-    }\r
-    jalview.datamodel.DBRefEntry[] fdb = from.getDBRef();\r
-    jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to.getDBRef().length];\r
-    int tdblen = to.getDBRef().length;\r
-    System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen);\r
-    Vector matched = new Vector();\r
-    jalview.util.MapList smapI = smap.getInverse();\r
-    for (int f=0;f<fdb.length; f++)\r
-    {\r
-      jalview.datamodel.DBRefEntry fe = fdb[f];\r
-      jalview.datamodel.Mapping fmp = fe.getMap();\r
-      boolean fmpnnl = fmp!=null;\r
-      // if (fmpnnl && fmp.getTo()!=null)\r
-      //{\r
-      //  jalview.bin.Cache.log.debug("Not overwriting existing To reference in "+fe);\r
-      //  continue;\r
-      //}\r
-      // smap from maps from fe.local to fe.map\r
-      boolean smapfromlocal2fe = (fmpnnl) ? smap.equals(fmp.getMap()) : false;\r
-      // smap from maps from fe.map to fe.local.\r
-      boolean smapfromfemap2local = (fmpnnl) ? smapI.equals(fmp.getMap()) : false;\r
-      for (int t=0; t<tdblen; t++)\r
-      {\r
-        jalview.datamodel.DBRefEntry te = tdb[t];\r
-        if (te!=null)\r
-        {\r
-          if (fe.getSource().equals(te.getSource())\r
-              && fe.getAccessionId().equals(te.getAccessionId()))\r
-          {\r
-            jalview.datamodel.Mapping tmp = te.getMap();\r
-            boolean tmpnnl = tmp!=null;\r
-            if (tmpnnl && tmp.getTo()!=null)\r
-            {\r
-              \r
-            }\r
-            // smap to maps from te.local to te.map\r
-            boolean smaptolocal2tm = (tmpnnl) ? smap.equals(tmp.getMap()) : false;\r
-            // smap to maps from te.map to te.local\r
-            boolean smaptotemap2local = (tmpnnl) ? smapI.equals(fmp.getMap()) : false;\r
-            if (smapfromlocal2fe && smaptotemap2local)\r
-            {\r
-              // smap implies mapping from to to from\r
-              fmp.setTo(to);\r
-              tmp.setTo(from);\r
-            } else \r
-              if (smapfromfemap2local && smaptolocal2tm) {\r
-                fmp.setTo(to);\r
-              }\r
-            }\r
-            \r
-        }\r
-      }\r
-    }\r
-    }\r
+package jalview.io.vamsas;
+
+import java.util.Vector;
+
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceI;
+import jalview.io.VamsasAppDatastore;
+import uk.ac.vamsas.client.Vobject;
+import uk.ac.vamsas.objects.core.AlignmentSequence;
+import uk.ac.vamsas.objects.core.DataSet;
+import uk.ac.vamsas.objects.core.Local;
+import uk.ac.vamsas.objects.core.RangeType;
+import uk.ac.vamsas.objects.core.Seg;
+import uk.ac.vamsas.objects.core.Sequence;
+import uk.ac.vamsas.objects.core.SequenceMapping;
+import uk.ac.vamsas.objects.core.SequenceType;
+
+public class Sequencemapping extends Rangetype
+{
+  public Sequencemapping(VamsasAppDatastore datastore, SequenceMapping sequenceMapping)
+  {
+    super(datastore);
+    Object mjvmapping = getvObj2jv(sequenceMapping);
+    if (mjvmapping==null)
+    {
+      add(sequenceMapping);
+    } else {
+      if (sequenceMapping.isUpdated())
+      {
+        update((jalview.util.MapList) mjvmapping, sequenceMapping);
+      }
+    }
+  }
+  /**
+   * create or update a vamsas sequence mapping corresponding to a jalview
+   * Mapping between two dataset sequences
+   * 
+   * @param datastore
+   * @param mjvmapping
+   * @param from
+   * @param ds
+   */
+  public Sequencemapping(VamsasAppDatastore datastore, jalview.datamodel.Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, uk.ac.vamsas.objects.core.DataSet ds)
+  {
+    super(datastore);
+    SequenceMapping sequenceMapping = (SequenceMapping) getjv2vObj(mjvmapping);
+    if (sequenceMapping==null)
+    {
+      add(mjvmapping, from, ds);
+    } else {
+      if (from!=null && sequenceMapping.getLoc()!=from)
+      {
+        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+from+" doesn't match the local mapping sequence.");
+      }
+      if (ds!=null && sequenceMapping.is__stored_in_document() && sequenceMapping.getV_parent()!=ds)
+      {
+        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+ds+" doesn't match the parent of the bound sequence mapping object.");
+      }
+      if (sequenceMapping.isUpdated())
+      { 
+        conflict(mjvmapping, sequenceMapping);
+      } else {
+        update(mjvmapping, sequenceMapping);
+      }
+    }
+  }
+  private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)
+  {
+    // TODO Auto-generated method stub
+
+  }
+  private void add(Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, DataSet ds)
+  {
+    SequenceI jvto = mjvmapping.getTo();
+    while (jvto.getDatasetSequence()!=null)
+    {
+      jvto = jvto.getDatasetSequence();
+    }
+    SequenceType to = (SequenceType) getjv2vObj(jvto);
+    if (to==null)
+    {
+      jalview.bin.Cache.log.warn("NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object");
+      return;
+    } 
+    SequenceMapping sequenceMapping = new SequenceMapping();
+    sequenceMapping.setLoc(from);
+    sequenceMapping.setMap(to);
+    boolean dnaToProt=false,sense=false;
+    // ensure that we create a mapping with the correct sense
+    if (((Sequence) sequenceMapping.getLoc())
+            .getDictionary()
+            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+    {
+      if (((Sequence) sequenceMapping.getMap())
+              .getDictionary()
+              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
+      {
+        dnaToProt=true;
+        sense=true;
+      } 
+    } else {
+      if (((Sequence) sequenceMapping.getMap())
+              .getDictionary()
+              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+      {
+        dnaToProt=true;
+        sense=false;
+      } 
+    }
+
+    if (!dnaToProt)
+    {
+      jalview.bin.Cache.log.warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet.");
+      return;
+    }
+    if (ds==null)
+    {
+      // locate dataset for storage of SequenceMapping
+      if (sense)
+      {
+        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getLoc()).getV_parent();
+      } else {
+        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getMap()).getV_parent();
+      } 
+    }
+    if (sense)
+    {
+      this.initMapType(sequenceMapping, mjvmapping.getMap(), true);
+    } else {
+      this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(), true);
+    }
+    ds.addSequenceMapping(sequenceMapping);
+    sequenceMapping.setProvenance(this.dummyProvenance("user defined coding region translation")); // TODO:
+    // correctly
+    // construct
+    // provenance
+    // based
+    // on
+    // source
+    // of
+    // mapping
+    bindjvvobj(mjvmapping, sequenceMapping);
+
+    jalview.bin.Cache.log.debug("Successfully created mapping "+sequenceMapping.getVorbaId());
+  }
+  private void update(jalview.util.MapList mjvmapping, SequenceMapping sequenceMapping)
+  {
+    jalview.bin.Cache.log.error("Not implemented: Jalview Update Alcodon Mapping:TODO!"); 
+  }
+  private void update(jalview.datamodel.Mapping mjvmapping, SequenceMapping sequenceMapping)
+  {
+    jalview.bin.Cache.log.error("Not implemented: Jalview Update Sequence DBRef Mapping"); 
+  }
+  /**
+   * limitations: Currently, jalview only deals with mappings between dataset
+   * sequences, and even then, only between those that map from DNA to Protein.
+   * 
+   * @param sequenceMapping
+   */
+  private void add(SequenceMapping sequenceMapping)
+  {
+    Object mobj;
+    SequenceI from=null,to=null;
+    boolean dnaToProt=false,sense=false;
+    Sequence sdloc=null, sdmap=null;
+    if (sequenceMapping.getLoc() instanceof AlignmentSequence)
+    {
+      sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc()).getRefid();
+    } else {
+      sdloc = ((Sequence) sequenceMapping.getLoc());
+    }
+    if (sequenceMapping.getMap() instanceof AlignmentSequence)
+    {
+      sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap()).getRefid();
+    } else {
+      sdmap = ((Sequence) sequenceMapping.getMap());
+    }
+    if (sdloc==null || sdmap == null)
+    {
+      jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");
+      return;
+    }
+    mobj = this.getvObj2jv((Vobject) sdloc);
+    if (mobj instanceof SequenceI)
+    {
+      from = (SequenceI) mobj;
+    }
+    mobj = this.getvObj2jv((Vobject) sdmap);
+    if (mobj instanceof SequenceI)
+    {
+      to = (SequenceI) mobj;
+    }
+    if (from == null || to == null)
+    {
+
+      jalview.bin.Cache.log.error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!");
+      return;
+    } 
+
+    if (sdloc.getDictionary()
+            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+    {
+      if (sdmap.getDictionary()
+              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
+      {
+        dnaToProt=true;
+        sense=true;
+      } 
+      // else {
+
+      // }
+    } else {
+      if (sdmap.getDictionary()
+              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+      {
+        dnaToProt=true;
+        sense=false;
+      } 
+    }
+    // create mapping storage object and make each dataset alignment reference
+    // it.
+    jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc.getV_parent());
+    jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap.getV_parent());
+    AlignedCodonFrame afc = new AlignedCodonFrame(0);
+
+    if (dsLoc!=null && dsLoc!=dsMap)
+    {
+      dsLoc.addCodonFrame(afc);
+    }
+    if (dsMap!=null)
+    {
+      dsMap.addCodonFrame(afc);
+    }
+    // create and add the new mapping to (each) dataset's codonFrame
+
+    jalview.util.MapList mapping = null; 
+    if (!sense)
+    {
+      mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense
+      mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio());
+      afc.addMap(to, from, mapping);
+    } else {
+      mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense
+      afc.addMap(from, to, mapping);
+    }
+    bindjvvobj(mapping, sequenceMapping);
+    jalview.structure.StructureSelectionManager.getStructureSelectionManager().addMappings(new AlignedCodonFrame[] { afc });
+    // Try to link up any conjugate database references in the two sequences
+    // matchConjugateDBRefs(from, to,  mapping);
+    // Try to propagate any dbrefs across this mapping.
+
+  }
+  /**
+   * Complete any 'to' references in jalview.datamodel.Mapping objects associated with conjugate DBRefEntry under given mapping  
+   * @param from sequence corresponding to from reference for sequence mapping
+   * @param to sequence correspondeing to to reference for sequence mapping
+   * @param smap maplist parsed in same sense as from and to
+   */
+  private void matchConjugateDBRefs(SequenceI from, SequenceI to,
+          jalview.util.MapList smap)
+  {
+    if (from.getDBRef()==null && to.getDBRef()==null)
+    {
+      if (jalview.bin.Cache.log.isDebugEnabled())
+      {
+        jalview.bin.Cache.log.debug("Not matching conjugate refs for "+from.getName()+" and "+to.getName());
+      }
+      return; 
+    }
+    if (jalview.bin.Cache.log.isDebugEnabled())
+    {
+      jalview.bin.Cache.log.debug("Matching conjugate refs for "+from.getName()+" and "+to.getName());
+    }
+    jalview.datamodel.DBRefEntry[] fdb = from.getDBRef();
+    jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to.getDBRef().length];
+    int tdblen = to.getDBRef().length;
+    System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen);
+    Vector matched = new Vector();
+    jalview.util.MapList smapI = smap.getInverse();
+    for (int f=0;f<fdb.length; f++)
+    {
+      jalview.datamodel.DBRefEntry fe = fdb[f];
+      jalview.datamodel.Mapping fmp = fe.getMap();
+      boolean fmpnnl = fmp!=null;
+      // if (fmpnnl && fmp.getTo()!=null)
+      //{
+      //  jalview.bin.Cache.log.debug("Not overwriting existing To reference in "+fe);
+      //  continue;
+      //}
+      // smap from maps from fe.local to fe.map
+      boolean smapfromlocal2fe = (fmpnnl) ? smap.equals(fmp.getMap()) : false;
+      // smap from maps from fe.map to fe.local.
+      boolean smapfromfemap2local = (fmpnnl) ? smapI.equals(fmp.getMap()) : false;
+      for (int t=0; t<tdblen; t++)
+      {
+        jalview.datamodel.DBRefEntry te = tdb[t];
+        if (te!=null)
+        {
+          if (fe.getSource().equals(te.getSource())
+              && fe.getAccessionId().equals(te.getAccessionId()))
+          {
+            jalview.datamodel.Mapping tmp = te.getMap();
+            boolean tmpnnl = tmp!=null;
+            if (tmpnnl && tmp.getTo()!=null)
+            {
+              
+            }
+            // smap to maps from te.local to te.map
+            boolean smaptolocal2tm = (tmpnnl) ? smap.equals(tmp.getMap()) : false;
+            // smap to maps from te.map to te.local
+            boolean smaptotemap2local = (tmpnnl) ? smapI.equals(fmp.getMap()) : false;
+            if (smapfromlocal2fe && smaptotemap2local)
+            {
+              // smap implies mapping from to to from
+              fmp.setTo(to);
+              tmp.setTo(from);
+            } else 
+              if (smapfromfemap2local && smaptolocal2tm) {
+                fmp.setTo(to);
+              }
+            }
+            
+        }
+      }
+    }
+    }
 }
\ No newline at end of file
index af4e7b7..8ff825c 100644 (file)
-package jalview.io.vamsas;\r
-\r
-import java.io.IOException;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-\r
-import jalview.analysis.NJTree;\r
-import jalview.analysis.SequenceIdMatcher;\r
-import jalview.bin.Cache;\r
-import jalview.datamodel.AlignmentI;\r
-import jalview.datamodel.AlignmentView;\r
-import jalview.datamodel.BinaryNode;\r
-import jalview.datamodel.SeqCigar;\r
-import jalview.datamodel.Sequence;\r
-import jalview.datamodel.SequenceI;\r
-import jalview.datamodel.SequenceNode;\r
-import jalview.gui.AlignFrame;\r
-import jalview.gui.AlignViewport;\r
-import jalview.gui.TreePanel;\r
-import jalview.io.NewickFile;\r
-import jalview.io.VamsasAppDatastore;\r
-import uk.ac.vamsas.client.Vobject;\r
-import uk.ac.vamsas.objects.core.AlignmentSequence;\r
-import uk.ac.vamsas.objects.core.Entry;\r
-import uk.ac.vamsas.objects.core.Input;\r
-import uk.ac.vamsas.objects.core.Newick;\r
-import uk.ac.vamsas.objects.core.Param;\r
-import uk.ac.vamsas.objects.core.Provenance;\r
-import uk.ac.vamsas.objects.core.Seg;\r
-import uk.ac.vamsas.objects.core.Treenode;\r
-import uk.ac.vamsas.objects.core.Vref;\r
-\r
-public class Tree extends DatastoreItem\r
-{\r
-  AlignmentI jal;\r
-\r
-  TreePanel tp;\r
-\r
-  uk.ac.vamsas.objects.core.Tree tree;\r
-\r
-  uk.ac.vamsas.objects.core.Alignment alignment; // may be null => dataset or\r
-\r
-  // other kind of tree\r
-  private NewickFile ntree;\r
-\r
-  private String title;\r
-\r
-  private AlignmentView inputData = null;\r
-\r
-  public static void updateFrom(VamsasAppDatastore datastore,\r
-          jalview.gui.AlignFrame alignFrame,\r
-          uk.ac.vamsas.objects.core.Tree vtree)\r
-  {\r
-    Tree toTree = new Tree(datastore, alignFrame, vtree);\r
-\r
-  }\r
-\r
-  public Tree(VamsasAppDatastore datastore,\r
-          jalview.gui.AlignFrame alignFrame,\r
-          uk.ac.vamsas.objects.core.Tree vtree)\r
-  {\r
-    super(datastore);\r
-    tree = vtree;\r
-    TreePanel tp = (TreePanel) getvObj2jv(tree);\r
-    if (tp != null)\r
-    {\r
-      if (tree.isUpdated())\r
-      {\r
-        Cache.log\r
-                .info("Update from vamsas document to alignment associated tree not implemented yet.");\r
-      }\r
-    }\r
-    else\r
-    {\r
-      // make a new tree\r
-      Object[] idata = recoverInputData(tree.getProvenance());\r
-      try\r
-      {\r
-        if (idata != null && idata[0] != null)\r
-        {\r
-          inputData = (AlignmentView) idata[0];\r
-        }\r
-        ntree = getNtree();\r
-        title = tree.getNewick(0).getTitle();\r
-        if (title == null || title.length() == 0)\r
-        {\r
-          title = tree.getTitle(); // hack!!!!\r
-        }\r
-      } catch (Exception e)\r
-      {\r
-        Cache.log.warn("Problems parsing treefile '"\r
-                + tree.getNewick(0).getContent() + "'", e);\r
-      }\r
-    }\r
-  }\r
-\r
-  private NewickFile getNtree() throws IOException\r
-  {\r
-    return new jalview.io.NewickFile(tree.getNewick(0).getContent());\r
-  }\r
-\r
-  public Tree(VamsasAppDatastore datastore, TreePanel tp2, AlignmentI jal2,\r
-          uk.ac.vamsas.objects.core.Alignment alignment2)\r
-  {\r
-    super(datastore);\r
-\r
-    jal = jal2;\r
-    tp = tp2;\r
-    alignment = alignment2;\r
-\r
-    tree = (uk.ac.vamsas.objects.core.Tree) getjv2vObj(tp);\r
-    if (tree == null)\r
-    {\r
-      add();\r
-    }\r
-    else\r
-    {\r
-      if (isModifiable(tree.getModifiable()))\r
-      {\r
-        // synchronize(); // update();\r
-        // verify any changes.\r
-        System.out.println("Update tree in document.");\r
-      }\r
-      else\r
-      {\r
-        // handle conflict\r
-        System.out.println("Add modified tree as new tree in document.");\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * correctly creates provenance for trees calculated on an alignment by\r
-   * jalview.\r
-   * \r
-   * @param jal\r
-   * @param tp\r
-   * @return\r
-   */\r
-  private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp)\r
-  {\r
-    Cache.log.debug("Making Tree provenance for " + tp.getTitle());\r
-    Provenance prov = new Provenance();\r
-    prov.addEntry(new Entry());\r
-    prov.getEntry(0).setAction("imported " + tp.getTitle());\r
-    prov.getEntry(0).setUser(provEntry.getUser());\r
-    prov.getEntry(0).setApp(provEntry.getApp());\r
-    prov.getEntry(0).setDate(provEntry.getDate());\r
-    if (tp.getTree().hasOriginalSequenceData())\r
-    {\r
-      Input vInput = new Input();\r
-      // LATER: check to see if tree input data is contained in this alignment -\r
-      // or just correctly resolve the tree's seqData to the correct alignment\r
-      // in\r
-      // the document.\r
-      Vector alsqrefs = getjv2vObjs(findAlignmentSequences(jal, tp\r
-              .getTree().seqData.getSequences()));\r
-      Object[] alsqs = new Object[alsqrefs.size()];\r
-      alsqrefs.copyInto(alsqs);\r
-      vInput.setObjRef(alsqs);\r
-      // now create main provenance data\r
-      prov.getEntry(0).setAction("created " + tp.getTitle());\r
-      prov.getEntry(0).addInput(vInput);\r
-      // jalview's special input parameter for distance matrix calculations\r
-      vInput.setName("jalview:seqdist"); // TODO: settle on appropriate name.\r
-      prov.getEntry(0).addParam(new Param());\r
-      prov.getEntry(0).getParam(0).setName("treeType");\r
-      prov.getEntry(0).getParam(0).setType("utf8");\r
-      prov.getEntry(0).getParam(0).setContent("NJ"); // TODO: type of tree is a\r
-                                                      // general parameter\r
-      int ranges[] = tp.getTree().seqData.getVisibleContigs();\r
-      // VisibleContigs are with respect to alignment coordinates. Still need\r
-      // offsets\r
-      int start = tp.getTree().seqData.getAlignmentOrigin();\r
-      for (int r = 0; r < ranges.length; r += 2)\r
-      {\r
-        Seg visSeg = new Seg();\r
-        visSeg.setStart(1 + start + ranges[r]);\r
-        visSeg.setEnd(start + ranges[r + 1]);\r
-        visSeg.setInclusive(true);\r
-        vInput.addSeg(visSeg);\r
-      }\r
-    }\r
-    Cache.log.debug("Finished Tree provenance for " + tp.getTitle());\r
-    return prov;\r
-  }\r
-\r
-  /**\r
-   * look up SeqCigars in an existing alignment.\r
-   * \r
-   * @param jal\r
-   * @param sequences\r
-   * @return vector of alignment sequences in order of SeqCigar array (but\r
-   *         missing unfound seqcigars)\r
-   */\r
-  private Vector findAlignmentSequences(AlignmentI jal, SeqCigar[] sequences)\r
-  {\r
-    SeqCigar[] tseqs = new SeqCigar[sequences.length];\r
-    System.arraycopy(sequences, 0, tseqs, 0, sequences.length);\r
-    Vector alsq = new Vector();\r
-    Enumeration as = jal.getSequences().elements();\r
-    while (as.hasMoreElements())\r
-    {\r
-      SequenceI asq = (SequenceI) as.nextElement();\r
-      for (int t = 0; t < sequences.length; t++)\r
-      {\r
-        if (tseqs[t] != null\r
-                && (tseqs[t].getRefSeq() == asq || tseqs[t].getRefSeq() == asq\r
-                        .getDatasetSequence()))\r
-        // && tseqs[t].getStart()>=asq.getStart() &&\r
-        // tseqs[t].getEnd()<=asq.getEnd())\r
-        {\r
-          tseqs[t] = null;\r
-          alsq.add(asq);\r
-        }\r
-      }\r
-    }\r
-    if (alsq.size() < sequences.length)\r
-      Cache.log\r
-              .warn("Not recovered all alignment sequences for given set of input sequence CIGARS");\r
-    return alsq;\r
-  }\r
-\r
-  /**\r
-   * \r
-   * Update jalview newick representation with TreeNode map\r
-   * \r
-   * @param tp\r
-   *                the treepanel that this tree is bound to.\r
-   */\r
-  public void UpdateSequenceTreeMap(TreePanel tp)\r
-  {\r
-    if (tp == null || tree != null)\r
-      return;\r
-    Vector leaves = new Vector();\r
-    tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves);\r
-    Treenode[] tn = tree.getTreenode(); // todo: select nodes for this\r
-                                        // particular tree\r
-    int sz = tn.length;\r
-    int i = 0;\r
-\r
-    while (i < sz)\r
-    {\r
-      Treenode node = tn[i++];\r
-      BinaryNode mappednode = findNodeSpec(node.getNodespec(), leaves);\r
-      if (mappednode != null && mappednode instanceof SequenceNode)\r
-      {\r
-        SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);\r
-        // check if we can make the specified association\r
-        Object jvseq = null;\r
-        int vrf = 0, refv = 0;\r
-        while (jvseq == null && vrf < node.getVrefCount())\r
-        {\r
-          if (refv < node.getVref(vrf).getRefsCount())\r
-          {\r
-            Object noderef = node.getVref(vrf).getRefs(refv++);\r
-            if (noderef instanceof AlignmentSequence)\r
-            {\r
-              // we only make these kind of associations\r
-              jvseq = getvObj2jv((Vobject) noderef);\r
-            }\r
-          }\r
-          else\r
-          {\r
-            refv = 0;\r
-            vrf++;\r
-          }\r
-        }\r
-        if (jvseq instanceof SequenceI)\r
-        {\r
-          leaf.setElement(jvseq);\r
-          leaf.setPlaceholder(false);\r
-        }\r
-        else\r
-        {\r
-          leaf.setPlaceholder(true);\r
-          leaf\r
-                  .setElement(new Sequence(leaf.getName(),\r
-                          "THISISAPLACEHLDER"));\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  // / TODO: refactor to vamsas :start\r
-  /**\r
-   * construct treenode mappings for mapped sequences\r
-   * \r
-   * @param ntree\r
-   * @param newick \r
-   * @return\r
-   */\r
-  public Treenode[] makeTreeNodes(NJTree ntree, Newick newick)\r
-  {\r
-    Vector leaves = new Vector();\r
-    ntree.findLeaves(ntree.getTopNode(), leaves);\r
-    Vector tnv = new Vector();\r
-    Enumeration l = leaves.elements();\r
-    Hashtable nodespecs = new Hashtable();\r
-    while (l.hasMoreElements())\r
-    {\r
-      jalview.datamodel.BinaryNode tnode = (jalview.datamodel.BinaryNode) l\r
-              .nextElement();\r
-      if (tnode instanceof jalview.datamodel.SequenceNode)\r
-      {\r
-        if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder())\r
-        {\r
-          Object assocseq = ((jalview.datamodel.SequenceNode) tnode)\r
-                  .element();\r
-          if (assocseq instanceof SequenceI)\r
-          {\r
-            Vobject vobj = this.getjv2vObj(assocseq);\r
-            if (vobj != null)\r
-            {\r
-              Treenode node = new Treenode();\r
-              if (newick.isRegisterable())\r
-              {\r
-                this.cdoc.registerObject(newick);\r
-                node.addTreeId(newick);\r
-              }\r
-              node.setNodespec(makeNodeSpec(nodespecs, tnode));\r
-              node.setName(tnode.getName());\r
-              Vref vr = new Vref();\r
-              vr.addRefs(vobj);\r
-              node.addVref(vr);\r
-              tnv.addElement(node);\r
-            }\r
-            else\r
-            {\r
-              System.err.println("WARNING: Unassociated treeNode "\r
-                      + tnode.element().toString()\r
-                      + " "\r
-                      + ((tnode.getName() != null) ? " label "\r
-                              + tnode.getName() : ""));\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-    if (tnv.size() > 0)\r
-    {\r
-      Treenode[] tn = new Treenode[tnv.size()];\r
-      tnv.copyInto(tn);\r
-      return tn;\r
-    }\r
-    return new Treenode[]\r
-    {};\r
-  }\r
-\r
-  private String makeNodeSpec(Hashtable nodespecs,\r
-          jalview.datamodel.BinaryNode tnode)\r
-  {\r
-    String nname = new String(tnode.getName());\r
-    Integer nindx = (Integer) nodespecs.get(nname);\r
-    if (nindx == null)\r
-    {\r
-      nindx = new Integer(1);\r
-    }\r
-    nname = nindx.toString() + " " + nname;\r
-    return nname;\r
-  }\r
-\r
-  /**\r
-   * call to match up Treenode specs to NJTree parsed from document object.\r
-   * \r
-   * @param nodespec\r
-   * @param leaves\r
-   *                as returned from NJTree.findLeaves( .., ..) ..\r
-   * @return\r
-   */\r
-  private jalview.datamodel.BinaryNode findNodeSpec(String nodespec,\r
-          Vector leaves)\r
-  {\r
-    int occurence = -1;\r
-    String nspec = nodespec.substring(nodespec.indexOf(' ') + 1);\r
-    String oval = nodespec.substring(0, nodespec.indexOf(' '));\r
-    try\r
-    {\r
-      occurence = new Integer(oval).intValue();\r
-    } catch (Exception e)\r
-    {\r
-      System.err.println("Invalid nodespec '" + nodespec + "'");\r
-      return null;\r
-    }\r
-    jalview.datamodel.BinaryNode bn = null;\r
-\r
-    int nocc = 0;\r
-    Enumeration en = leaves.elements();\r
-    while (en.hasMoreElements() && nocc < occurence)\r
-    {\r
-      bn = (jalview.datamodel.BinaryNode) en.nextElement();\r
-      if (bn instanceof jalview.datamodel.SequenceNode\r
-              && bn.getName().equals(nspec))\r
-      {\r
-        --occurence;\r
-      }\r
-      else\r
-        bn = null;\r
-    }\r
-    return bn;\r
-  }\r
-\r
-  // todo: end refactor to vamsas library\r
-  /**\r
-   * add jalview object to vamsas document\r
-   * \r
-   */\r
-  public void add()\r
-  {\r
-    tree = new uk.ac.vamsas.objects.core.Tree();\r
-    bindjvvobj(tp, tree);\r
-    tree.setTitle(tp.getTitle());\r
-    Newick newick = new Newick();\r
-    newick.setContent(tp.getTree().toString());\r
-    newick.setTitle(tp.getTitle());\r
-    tree.addNewick(newick);\r
-    tree.setProvenance(makeTreeProvenance(jal, tp));\r
-    tree.setTreenode(makeTreeNodes(tp.getTree(), newick));\r
-\r
-    alignment.addTree(tree);\r
-  }\r
-\r
-  /**\r
-   * note: this function assumes that all sequence and alignment objects\r
-   * referenced in input data has already been associated with jalview objects.\r
-   * \r
-   * @param tp\r
-   * @param alignFrame \r
-   * @return Object[] { AlignmentView, AlignmentI - reference alignment for\r
-   *         input }\r
-   */\r
-  public Object[] recoverInputData(Provenance tp)\r
-  {\r
-    AlignViewport javport = null;\r
-    jalview.datamodel.AlignmentI jal = null;\r
-    jalview.datamodel.CigarArray view = null;\r
-    for (int pe = 0; pe < tp.getEntryCount(); pe++)\r
-    {\r
-      if (tp.getEntry(pe).getInputCount() > 0)\r
-      {\r
-        if (tp.getEntry(pe).getInputCount() > 1)\r
-        {\r
-          Cache.log\r
-                  .warn("Ignoring additional input spec in provenance entry "\r
-                          + tp.getEntry(pe).toString());\r
-        }\r
-        // LATER: deal sensibly with multiple inputs\r
-        Input vInput = tp.getEntry(pe).getInput(0);\r
-        // is this the whole alignment or a specific set of sequences ?\r
-        if (vInput.getObjRefCount() == 0)\r
-        {\r
-          if (tree.getV_parent()!=null && tree.getV_parent() instanceof uk.ac.vamsas.objects.core.Alignment)\r
-          {\r
-            javport = getViewport(tree.getV_parent());\r
-            jal = javport.getAlignment();\r
-            view = javport.getAlignment().getCompactAlignment();\r
-          }\r
-        }\r
-        else\r
-        {\r
-          // Explicit reference - to alignment, sequences or what.\r
-          if (vInput.getObjRefCount() == 1\r
-                  && vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.Alignment)\r
-          {\r
-            // recover an AlignmentView for the input data\r
-            javport = getViewport((Vobject) vInput.getObjRef(0));\r
-            jal = javport.getAlignment();\r
-            view = javport.getAlignment().getCompactAlignment();\r
-          }\r
-          else if (vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.AlignmentSequence)\r
-          {\r
-            // recover an AlignmentView for the input data\r
-            javport = getViewport(((Vobject) vInput.getObjRef(0)).getV_parent());\r
-            jal = javport.getAlignment();\r
-            jalview.datamodel.SequenceI[] seqs = new jalview.datamodel.SequenceI[vInput\r
-                    .getObjRefCount()];\r
-            for (int i = 0, iSize = vInput.getObjRefCount(); i < iSize; i++)\r
-            {\r
-              SequenceI seq = (SequenceI) getvObj2jv((Vobject) vInput\r
-                      .getObjRef(i));\r
-              seqs[i] = seq;\r
-            }\r
-            view = new jalview.datamodel.Alignment(seqs)\r
-                    .getCompactAlignment();\r
-\r
-          }\r
-        }\r
-        int from = 1, to = jal.getWidth();\r
-        int offset = 0; // deleteRange modifies its frame of reference\r
-        for (int r = 0, s = vInput.getSegCount(); r < s; r++)\r
-        {\r
-          Seg visSeg = vInput.getSeg(r);\r
-          int se[] = getSegRange(visSeg, true); // jalview doesn't do\r
-          // bidirection alignments yet.\r
-          if (to < se[1])\r
-          {\r
-            Cache.log.warn("Ignoring invalid segment in InputData spec.");\r
-          }\r
-          else\r
-          {\r
-            if (se[0] > from)\r
-            {\r
-              view.deleteRange(offset + from - 1, offset + se[0] - 2);\r
-              offset -= se[0] - from;\r
-            }\r
-            from = se[1] + 1;\r
-          }\r
-        }\r
-        if (from < to)\r
-        {\r
-          view.deleteRange(offset + from - 1, offset + to - 1); // final\r
-          // deletion -\r
-          // TODO: check\r
-          // off by\r
-          // one for to\r
-        }\r
-        return new Object[]\r
-        { new AlignmentView(view), jal };\r
-      }\r
-    }\r
-    Cache.log\r
-            .debug("Returning null for input data recovery from provenance.");\r
-    return null;\r
-  }\r
-\r
-  private AlignViewport getViewport(Vobject v_parent)\r
-  {\r
-    if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment)\r
-    {\r
-      return datastore\r
-              .findViewport((uk.ac.vamsas.objects.core.Alignment) v_parent);\r
-    }\r
-    return null;\r
-  }\r
-\r
-  public NewickFile getNewickTree()\r
-  {\r
-    return ntree;\r
-  }\r
-\r
-  public String getTitle()\r
-  {\r
-    return title;\r
-  }\r
-\r
-  public AlignmentView getInputData()\r
-  {\r
-    return inputData;\r
-  }\r
-\r
-  public boolean isValidTree()\r
-  {\r
-    try\r
-    {\r
-      ntree.parse();\r
-      if (ntree.getTree() != null)\r
-      {\r
-        ntree = getNtree();\r
-      }\r
-      return true;\r
-    } catch (Exception e)\r
-    {\r
-      Cache.log.debug("Failed to parse newick tree string", e);\r
-    }\r
-    return false;\r
-  }\r
-}\r
+package jalview.io.vamsas;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import jalview.analysis.NJTree;
+import jalview.analysis.SequenceIdMatcher;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.SeqCigar;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.TreePanel;
+import jalview.io.NewickFile;
+import jalview.io.VamsasAppDatastore;
+import uk.ac.vamsas.client.Vobject;
+import uk.ac.vamsas.objects.core.AlignmentSequence;
+import uk.ac.vamsas.objects.core.Entry;
+import uk.ac.vamsas.objects.core.Input;
+import uk.ac.vamsas.objects.core.Newick;
+import uk.ac.vamsas.objects.core.Param;
+import uk.ac.vamsas.objects.core.Provenance;
+import uk.ac.vamsas.objects.core.Seg;
+import uk.ac.vamsas.objects.core.Treenode;
+import uk.ac.vamsas.objects.core.Vref;
+
+public class Tree extends DatastoreItem
+{
+  AlignmentI jal;
+
+  TreePanel tp;
+
+  uk.ac.vamsas.objects.core.Tree tree;
+
+  uk.ac.vamsas.objects.core.Alignment alignment; // may be null => dataset or
+
+  // other kind of tree
+  private NewickFile ntree;
+
+  private String title;
+
+  private AlignmentView inputData = null;
+
+  public static void updateFrom(VamsasAppDatastore datastore,
+          jalview.gui.AlignFrame alignFrame,
+          uk.ac.vamsas.objects.core.Tree vtree)
+  {
+    Tree toTree = new Tree(datastore, alignFrame, vtree);
+
+  }
+
+  public Tree(VamsasAppDatastore datastore,
+          jalview.gui.AlignFrame alignFrame,
+          uk.ac.vamsas.objects.core.Tree vtree)
+  {
+    super(datastore);
+    tree = vtree;
+    TreePanel tp = (TreePanel) getvObj2jv(tree);
+    if (tp != null)
+    {
+      if (tree.isUpdated())
+      {
+        Cache.log
+                .info("Update from vamsas document to alignment associated tree not implemented yet.");
+      }
+    }
+    else
+    {
+      // make a new tree
+      Object[] idata = recoverInputData(tree.getProvenance());
+      try
+      {
+        if (idata != null && idata[0] != null)
+        {
+          inputData = (AlignmentView) idata[0];
+        }
+        ntree = getNtree();
+        title = tree.getNewick(0).getTitle();
+        if (title == null || title.length() == 0)
+        {
+          title = tree.getTitle(); // hack!!!!
+        }
+      } catch (Exception e)
+      {
+        Cache.log.warn("Problems parsing treefile '"
+                + tree.getNewick(0).getContent() + "'", e);
+      }
+    }
+  }
+
+  private NewickFile getNtree() throws IOException
+  {
+    return new jalview.io.NewickFile(tree.getNewick(0).getContent());
+  }
+
+  public Tree(VamsasAppDatastore datastore, TreePanel tp2, AlignmentI jal2,
+          uk.ac.vamsas.objects.core.Alignment alignment2)
+  {
+    super(datastore);
+
+    jal = jal2;
+    tp = tp2;
+    alignment = alignment2;
+
+    tree = (uk.ac.vamsas.objects.core.Tree) getjv2vObj(tp);
+    if (tree == null)
+    {
+      add();
+    }
+    else
+    {
+      if (isModifiable(tree.getModifiable()))
+      {
+        // synchronize(); // update();
+        // verify any changes.
+        System.out.println("Update tree in document.");
+      }
+      else
+      {
+        // handle conflict
+        System.out.println("Add modified tree as new tree in document.");
+      }
+    }
+  }
+
+  /**
+   * correctly creates provenance for trees calculated on an alignment by
+   * jalview.
+   * 
+   * @param jal
+   * @param tp
+   * @return
+   */
+  private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp)
+  {
+    Cache.log.debug("Making Tree provenance for " + tp.getTitle());
+    Provenance prov = new Provenance();
+    prov.addEntry(new Entry());
+    prov.getEntry(0).setAction("imported " + tp.getTitle());
+    prov.getEntry(0).setUser(provEntry.getUser());
+    prov.getEntry(0).setApp(provEntry.getApp());
+    prov.getEntry(0).setDate(provEntry.getDate());
+    if (tp.getTree().hasOriginalSequenceData())
+    {
+      Input vInput = new Input();
+      // LATER: check to see if tree input data is contained in this alignment -
+      // or just correctly resolve the tree's seqData to the correct alignment
+      // in
+      // the document.
+      Vector alsqrefs = getjv2vObjs(findAlignmentSequences(jal, tp
+              .getTree().seqData.getSequences()));
+      Object[] alsqs = new Object[alsqrefs.size()];
+      alsqrefs.copyInto(alsqs);
+      vInput.setObjRef(alsqs);
+      // now create main provenance data
+      prov.getEntry(0).setAction("created " + tp.getTitle());
+      prov.getEntry(0).addInput(vInput);
+      // jalview's special input parameter for distance matrix calculations
+      vInput.setName("jalview:seqdist"); // TODO: settle on appropriate name.
+      prov.getEntry(0).addParam(new Param());
+      prov.getEntry(0).getParam(0).setName("treeType");
+      prov.getEntry(0).getParam(0).setType("utf8");
+      prov.getEntry(0).getParam(0).setContent("NJ"); // TODO: type of tree is a
+                                                      // general parameter
+      int ranges[] = tp.getTree().seqData.getVisibleContigs();
+      // VisibleContigs are with respect to alignment coordinates. Still need
+      // offsets
+      int start = tp.getTree().seqData.getAlignmentOrigin();
+      for (int r = 0; r < ranges.length; r += 2)
+      {
+        Seg visSeg = new Seg();
+        visSeg.setStart(1 + start + ranges[r]);
+        visSeg.setEnd(start + ranges[r + 1]);
+        visSeg.setInclusive(true);
+        vInput.addSeg(visSeg);
+      }
+    }
+    Cache.log.debug("Finished Tree provenance for " + tp.getTitle());
+    return prov;
+  }
+
+  /**
+   * look up SeqCigars in an existing alignment.
+   * 
+   * @param jal
+   * @param sequences
+   * @return vector of alignment sequences in order of SeqCigar array (but
+   *         missing unfound seqcigars)
+   */
+  private Vector findAlignmentSequences(AlignmentI jal, SeqCigar[] sequences)
+  {
+    SeqCigar[] tseqs = new SeqCigar[sequences.length];
+    System.arraycopy(sequences, 0, tseqs, 0, sequences.length);
+    Vector alsq = new Vector();
+    Enumeration as = jal.getSequences().elements();
+    while (as.hasMoreElements())
+    {
+      SequenceI asq = (SequenceI) as.nextElement();
+      for (int t = 0; t < sequences.length; t++)
+      {
+        if (tseqs[t] != null
+                && (tseqs[t].getRefSeq() == asq || tseqs[t].getRefSeq() == asq
+                        .getDatasetSequence()))
+        // && tseqs[t].getStart()>=asq.getStart() &&
+        // tseqs[t].getEnd()<=asq.getEnd())
+        {
+          tseqs[t] = null;
+          alsq.add(asq);
+        }
+      }
+    }
+    if (alsq.size() < sequences.length)
+      Cache.log
+              .warn("Not recovered all alignment sequences for given set of input sequence CIGARS");
+    return alsq;
+  }
+
+  /**
+   * 
+   * Update jalview newick representation with TreeNode map
+   * 
+   * @param tp
+   *                the treepanel that this tree is bound to.
+   */
+  public void UpdateSequenceTreeMap(TreePanel tp)
+  {
+    if (tp == null || tree != null)
+      return;
+    Vector leaves = new Vector();
+    tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves);
+    Treenode[] tn = tree.getTreenode(); // todo: select nodes for this
+                                        // particular tree
+    int sz = tn.length;
+    int i = 0;
+
+    while (i < sz)
+    {
+      Treenode node = tn[i++];
+      BinaryNode mappednode = findNodeSpec(node.getNodespec(), leaves);
+      if (mappednode != null && mappednode instanceof SequenceNode)
+      {
+        SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);
+        // check if we can make the specified association
+        Object jvseq = null;
+        int vrf = 0, refv = 0;
+        while (jvseq == null && vrf < node.getVrefCount())
+        {
+          if (refv < node.getVref(vrf).getRefsCount())
+          {
+            Object noderef = node.getVref(vrf).getRefs(refv++);
+            if (noderef instanceof AlignmentSequence)
+            {
+              // we only make these kind of associations
+              jvseq = getvObj2jv((Vobject) noderef);
+            }
+          }
+          else
+          {
+            refv = 0;
+            vrf++;
+          }
+        }
+        if (jvseq instanceof SequenceI)
+        {
+          leaf.setElement(jvseq);
+          leaf.setPlaceholder(false);
+        }
+        else
+        {
+          leaf.setPlaceholder(true);
+          leaf
+                  .setElement(new Sequence(leaf.getName(),
+                          "THISISAPLACEHLDER"));
+        }
+      }
+    }
+  }
+
+  // / TODO: refactor to vamsas :start
+  /**
+   * construct treenode mappings for mapped sequences
+   * 
+   * @param ntree
+   * @param newick 
+   * @return
+   */
+  public Treenode[] makeTreeNodes(NJTree ntree, Newick newick)
+  {
+    Vector leaves = new Vector();
+    ntree.findLeaves(ntree.getTopNode(), leaves);
+    Vector tnv = new Vector();
+    Enumeration l = leaves.elements();
+    Hashtable nodespecs = new Hashtable();
+    while (l.hasMoreElements())
+    {
+      jalview.datamodel.BinaryNode tnode = (jalview.datamodel.BinaryNode) l
+              .nextElement();
+      if (tnode instanceof jalview.datamodel.SequenceNode)
+      {
+        if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder())
+        {
+          Object assocseq = ((jalview.datamodel.SequenceNode) tnode)
+                  .element();
+          if (assocseq instanceof SequenceI)
+          {
+            Vobject vobj = this.getjv2vObj(assocseq);
+            if (vobj != null)
+            {
+              Treenode node = new Treenode();
+              if (newick.isRegisterable())
+              {
+                this.cdoc.registerObject(newick);
+                node.addTreeId(newick);
+              }
+              node.setNodespec(makeNodeSpec(nodespecs, tnode));
+              node.setName(tnode.getName());
+              Vref vr = new Vref();
+              vr.addRefs(vobj);
+              node.addVref(vr);
+              tnv.addElement(node);
+            }
+            else
+            {
+              System.err.println("WARNING: Unassociated treeNode "
+                      + tnode.element().toString()
+                      + " "
+                      + ((tnode.getName() != null) ? " label "
+                              + tnode.getName() : ""));
+            }
+          }
+        }
+      }
+    }
+    if (tnv.size() > 0)
+    {
+      Treenode[] tn = new Treenode[tnv.size()];
+      tnv.copyInto(tn);
+      return tn;
+    }
+    return new Treenode[]
+    {};
+  }
+
+  private String makeNodeSpec(Hashtable nodespecs,
+          jalview.datamodel.BinaryNode tnode)
+  {
+    String nname = new String(tnode.getName());
+    Integer nindx = (Integer) nodespecs.get(nname);
+    if (nindx == null)
+    {
+      nindx = new Integer(1);
+    }
+    nname = nindx.toString() + " " + nname;
+    return nname;
+  }
+
+  /**
+   * call to match up Treenode specs to NJTree parsed from document object.
+   * 
+   * @param nodespec
+   * @param leaves
+   *                as returned from NJTree.findLeaves( .., ..) ..
+   * @return
+   */
+  private jalview.datamodel.BinaryNode findNodeSpec(String nodespec,
+          Vector leaves)
+  {
+    int occurence = -1;
+    String nspec = nodespec.substring(nodespec.indexOf(' ') + 1);
+    String oval = nodespec.substring(0, nodespec.indexOf(' '));
+    try
+    {
+      occurence = new Integer(oval).intValue();
+    } catch (Exception e)
+    {
+      System.err.println("Invalid nodespec '" + nodespec + "'");
+      return null;
+    }
+    jalview.datamodel.BinaryNode bn = null;
+
+    int nocc = 0;
+    Enumeration en = leaves.elements();
+    while (en.hasMoreElements() && nocc < occurence)
+    {
+      bn = (jalview.datamodel.BinaryNode) en.nextElement();
+      if (bn instanceof jalview.datamodel.SequenceNode
+              && bn.getName().equals(nspec))
+      {
+        --occurence;
+      }
+      else
+        bn = null;
+    }
+    return bn;
+  }
+
+  // todo: end refactor to vamsas library
+  /**
+   * add jalview object to vamsas document
+   * 
+   */
+  public void add()
+  {
+    tree = new uk.ac.vamsas.objects.core.Tree();
+    bindjvvobj(tp, tree);
+    tree.setTitle(tp.getTitle());
+    Newick newick = new Newick();
+    newick.setContent(tp.getTree().toString());
+    newick.setTitle(tp.getTitle());
+    tree.addNewick(newick);
+    tree.setProvenance(makeTreeProvenance(jal, tp));
+    tree.setTreenode(makeTreeNodes(tp.getTree(), newick));
+
+    alignment.addTree(tree);
+  }
+
+  /**
+   * note: this function assumes that all sequence and alignment objects
+   * referenced in input data has already been associated with jalview objects.
+   * 
+   * @param tp
+   * @param alignFrame 
+   * @return Object[] { AlignmentView, AlignmentI - reference alignment for
+   *         input }
+   */
+  public Object[] recoverInputData(Provenance tp)
+  {
+    AlignViewport javport = null;
+    jalview.datamodel.AlignmentI jal = null;
+    jalview.datamodel.CigarArray view = null;
+    for (int pe = 0; pe < tp.getEntryCount(); pe++)
+    {
+      if (tp.getEntry(pe).getInputCount() > 0)
+      {
+        if (tp.getEntry(pe).getInputCount() > 1)
+        {
+          Cache.log
+                  .warn("Ignoring additional input spec in provenance entry "
+                          + tp.getEntry(pe).toString());
+        }
+        // LATER: deal sensibly with multiple inputs
+        Input vInput = tp.getEntry(pe).getInput(0);
+        // is this the whole alignment or a specific set of sequences ?
+        if (vInput.getObjRefCount() == 0)
+        {
+          if (tree.getV_parent()!=null && tree.getV_parent() instanceof uk.ac.vamsas.objects.core.Alignment)
+          {
+            javport = getViewport(tree.getV_parent());
+            jal = javport.getAlignment();
+            view = javport.getAlignment().getCompactAlignment();
+          }
+        }
+        else
+        {
+          // Explicit reference - to alignment, sequences or what.
+          if (vInput.getObjRefCount() == 1
+                  && vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.Alignment)
+          {
+            // recover an AlignmentView for the input data
+            javport = getViewport((Vobject) vInput.getObjRef(0));
+            jal = javport.getAlignment();
+            view = javport.getAlignment().getCompactAlignment();
+          }
+          else if (vInput.getObjRef(0) instanceof uk.ac.vamsas.objects.core.AlignmentSequence)
+          {
+            // recover an AlignmentView for the input data
+            javport = getViewport(((Vobject) vInput.getObjRef(0)).getV_parent());
+            jal = javport.getAlignment();
+            jalview.datamodel.SequenceI[] seqs = new jalview.datamodel.SequenceI[vInput
+                    .getObjRefCount()];
+            for (int i = 0, iSize = vInput.getObjRefCount(); i < iSize; i++)
+            {
+              SequenceI seq = (SequenceI) getvObj2jv((Vobject) vInput
+                      .getObjRef(i));
+              seqs[i] = seq;
+            }
+            view = new jalview.datamodel.Alignment(seqs)
+                    .getCompactAlignment();
+
+          }
+        }
+        int from = 1, to = jal.getWidth();
+        int offset = 0; // deleteRange modifies its frame of reference
+        for (int r = 0, s = vInput.getSegCount(); r < s; r++)
+        {
+          Seg visSeg = vInput.getSeg(r);
+          int se[] = getSegRange(visSeg, true); // jalview doesn't do
+          // bidirection alignments yet.
+          if (to < se[1])
+          {
+            Cache.log.warn("Ignoring invalid segment in InputData spec.");
+          }
+          else
+          {
+            if (se[0] > from)
+            {
+              view.deleteRange(offset + from - 1, offset + se[0] - 2);
+              offset -= se[0] - from;
+            }
+            from = se[1] + 1;
+          }
+        }
+        if (from < to)
+        {
+          view.deleteRange(offset + from - 1, offset + to - 1); // final
+          // deletion -
+          // TODO: check
+          // off by
+          // one for to
+        }
+        return new Object[]
+        { new AlignmentView(view), jal };
+      }
+    }
+    Cache.log
+            .debug("Returning null for input data recovery from provenance.");
+    return null;
+  }
+
+  private AlignViewport getViewport(Vobject v_parent)
+  {
+    if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment)
+    {
+      return datastore
+              .findViewport((uk.ac.vamsas.objects.core.Alignment) v_parent);
+    }
+    return null;
+  }
+
+  public NewickFile getNewickTree()
+  {
+    return ntree;
+  }
+
+  public String getTitle()
+  {
+    return title;
+  }
+
+  public AlignmentView getInputData()
+  {
+    return inputData;
+  }
+
+  public boolean isValidTree()
+  {
+    try
+    {
+      ntree.parse();
+      if (ntree.getTree() != null)
+      {
+        ntree = getNtree();
+      }
+      return true;
+    } catch (Exception e)
+    {
+      Cache.log.debug("Failed to parse newick tree string", e);
+    }
+    return false;
+  }
+}