JAL-4124 matrix is saved in dataset, with forward references made from alignments
[jalview.git] / src / jalview / project / Jalview2XML.java
index f8be544..627aba3 100644 (file)
@@ -272,7 +272,7 @@ public class Jalview2XML
 
   Map<String, SequenceI> incompleteSeqs = null;
 
-  List<SeqFref> frefedSequence = null;
+  List<forwardRef> frefedSequence = null;
 
   boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
 
@@ -293,6 +293,7 @@ public class Jalview2XML
    */
   private Map<ContactMatrixI,String> contactMatrices = new HashMap<>();
   private Map<String, ContactMatrixI> contactMatrixRefs = new HashMap<>();
+  private List<jalview.xml.binding.jalview.MatrixType> xmlMatrices= new ArrayList<>();
 
   /**
    * A helper method for safely using the value of an optional attribute that
@@ -390,18 +391,17 @@ public class Jalview2XML
   }
 
   /**
-   * base class for resolving forward references to sequences by their ID
+   * base class for resolving forward references to an as-yet unmarshalled object referenced by already unmarshalled objects
    * 
    * @author jprocter
    *
    */
-  abstract class SeqFref
-  {
+  abstract class forwardRef {
     String sref;
 
     String type;
 
-    public SeqFref(String _sref, String type)
+    public forwardRef(String _sref, String type)
     {
       sref = _sref;
       this.type = type;
@@ -412,6 +412,28 @@ public class Jalview2XML
       return sref;
     }
 
+    public abstract boolean isResolvable();
+    /**
+     * @return true if the forward reference was fully resolved
+     */
+    abstract boolean resolve();
+
+    @Override
+    public String toString()
+    {
+      return type + " reference to " + sref;
+    }
+  }
+  /**
+   * resolve forward references to sequences by their ID
+   * @author jprocter
+   */
+  abstract class SeqFref extends forwardRef
+  {
+    public SeqFref(String _sref, String type)
+    {
+      super(_sref, type);
+    }
     public SequenceI getSrefSeq()
     {
       return seqRefIds.get(sref);
@@ -434,17 +456,6 @@ public class Jalview2XML
       }
       return sq;
     }
-
-    /**
-     * @return true if the forward reference was fully resolved
-     */
-    abstract boolean resolve();
-
-    @Override
-    public String toString()
-    {
-      return type + " reference to " + sref;
-    }
   }
 
   /**
@@ -507,15 +518,42 @@ public class Jalview2XML
     };
     return fref;
   }
+  
+  public forwardRef newMatrixFref(final String matRef,
+          final jalview.util.MapList mapping, final AlignmentAnnotation jaa)
+  {
+    forwardRef fref = new forwardRef(matRef,
+            "Matrix Reference for sequence and annotation")
+    {
+
+      @Override
+      boolean resolve()
+      {
+        ContactMatrixI cm = contactMatrixRefs.get(matRef);
+        PAEContactMatrix newpae = new PAEContactMatrix(jaa.sequenceRef,
+                mapping, cm);
+
+        jaa.sequenceRef.addContactListFor(jaa, newpae);
+        return true;
+      }
+
+      @Override
+      public boolean isResolvable()
+      {
+        return (contactMatrixRefs.get(matRef) != null);
+      }
+    };
+    return fref;
+  }
 
   public void resolveFrefedSequences()
   {
-    Iterator<SeqFref> nextFref = frefedSequence.iterator();
+    Iterator<forwardRef> nextFref = frefedSequence.iterator();
     int toresolve = frefedSequence.size();
     int unresolved = 0, failedtoresolve = 0;
     while (nextFref.hasNext())
     {
-      SeqFref ref = nextFref.next();
+      forwardRef ref = nextFref.next();
       if (ref.isResolvable())
       {
         try
@@ -1761,6 +1799,20 @@ public class Jalview2XML
       // jms.addViewport(view);
       object.getViewport().add(view);
     }
+    
+    
+    if (storeDS)
+    {
+      // store matrices referenced by any views or annotation in this dataset
+      if (xmlMatrices!=null && xmlMatrices.size()>0)
+      {
+        Console.debug("Adding "+xmlMatrices.size()+" matrices to dataset.");
+        vamsasSet.getMatrix().addAll(xmlMatrices);
+        xmlMatrices.clear();
+      }
+    }
+
+    
     // object.setJalviewModelSequence(jms);
     // object.getVamsasModel().addSequenceSet(vamsasSet);
     object.getVamsasModel().getSequenceSet().add(vamsasSet);
@@ -2464,10 +2516,13 @@ public class Jalview2XML
       {
         xmlmat.setCutHeight(cm.getCutHeight());
       }
-      xmlmat.setId(cmId = makeHashCode(cm, null));
+      xmlmat.setId(cmId = "m"+contactMatrices.size()+System.currentTimeMillis());
+      Console.trace("Matrix data stored :"+cmId);
       contactMatrices.put(cm, cmId);
       contactMatrixRefs.put(cmId, cm);
-      root.getMatrices().add(xmlmat);
+      xmlMatrices.add(xmlmat);
+    } else {
+      Console.trace("Existing Matrix stored :"+cmId);
     }
 
     // now store mapping
@@ -3534,9 +3589,9 @@ public class Jalview2XML
     // ////////////////////////////////
     // LOAD MATRICES (IF ANY)
     
-    if (vamsasSet.getMatrices()!=null && vamsasSet.getMatrices().size()>0)
+    if (vamsasSet.getMatrix()!=null && vamsasSet.getMatrix().size()>0)
     {
-      importMatrixData(vamsasSet.getMatrices());
+      importMatrixData(vamsasSet.getMatrix());
     }
     
     // ////////////////////////////////
@@ -4356,17 +4411,7 @@ public class Jalview2XML
 
   private void restoreMatrixFor(SequenceI sequenceRef,
           AlignmentAnnotation jaa, MapOnAMatrixType xmlmatmapping)
-  {
-    MatrixType xmlmat;
-
-    // locate matrix data in project XML and import
-    ContactMatrixI cm = contactMatrixRefs.get(xmlmatmapping.getMatrix());
-    if (cm == null)
-    {
-      Console.error("Cannot restore mapping to matrix "
-              + xmlmatmapping.getMatrix() + " - not found in project.");
-    }
-
+  {    
     // restore mapping data to matrix data
     jalview.util.MapList mapping = null;
     if (xmlmatmapping.getMapping() != null)
@@ -4393,10 +4438,22 @@ public class Jalview2XML
       mapping = new jalview.util.MapList(fr, fto,
               m.getMapFromUnit().intValue(), m.getMapToUnit().intValue());
     }
-    PAEContactMatrix newpae = new PAEContactMatrix(jaa.sequenceRef, mapping,
-            cm);
+    
+    // locate matrix data in project XML and import
+    ContactMatrixI cm = contactMatrixRefs.get(xmlmatmapping.getMatrix());
+    if (cm == null)
+    {
+      frefedSequence
+              .add(newMatrixFref(xmlmatmapping.getMatrix(), mapping, jaa));
+    }
+    else
+    {
+      // create the PAEMatrix now
+      PAEContactMatrix newpae = new PAEContactMatrix(jaa.sequenceRef,
+              mapping, cm);
 
-    jaa.sequenceRef.addContactListFor(jaa, newpae);
+      jaa.sequenceRef.addContactListFor(jaa, newpae);
+    }
 
     return;
   }