Merge branch 'bug/JAL-2541cutWithFeatures' into features/JAL-2446NCList
[jalview.git] / src / jalview / datamodel / Sequence.java
index 21f7830..9f3e7b8 100755 (executable)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
- * Copyright (C) 2015 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -22,6 +22,8 @@ package jalview.datamodel;
 
 import jalview.analysis.AlignSeq;
 import jalview.api.DBRefEntryI;
+import jalview.datamodel.features.SequenceFeatures;
+import jalview.datamodel.features.SequenceFeaturesI;
 import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
@@ -34,6 +36,8 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.Vector;
 
+import com.stevesoft.pat.Regex;
+
 import fr.orsay.lri.varna.models.rna.RNA;
 
 /**
@@ -45,6 +49,11 @@ import fr.orsay.lri.varna.models.rna.RNA;
  */
 public class Sequence extends ASequence implements SequenceI
 {
+  private static final Regex limitrx = new Regex(
+          "[/][0-9]{1,}[-][0-9]{1,}$");
+
+  private static final Regex endrx = new Regex("[0-9]{1,}$");
+
   SequenceI datasetSequence;
 
   String name;
@@ -81,6 +90,8 @@ public class Sequence extends ASequence implements SequenceI
   /** array of sequence features - may not be null for a valid sequence object */
   public SequenceFeature[] sequenceFeatures;
 
+  private SequenceFeatures sequenceFeatureStore;
+
   /**
    * Creates a new Sequence object.
    * 
@@ -120,15 +131,11 @@ public class Sequence extends ASequence implements SequenceI
     this.sequence = sequence2;
     this.start = start2;
     this.end = end2;
+    sequenceFeatureStore = new SequenceFeatures();
     parseId();
     checkValidRange();
   }
 
-  com.stevesoft.pat.Regex limitrx = new com.stevesoft.pat.Regex(
-          "[/][0-9]{1,}[-][0-9]{1,}$");
-
-  com.stevesoft.pat.Regex endrx = new com.stevesoft.pat.Regex("[0-9]{1,}$");
-
   void parseId()
   {
     if (name == null)
@@ -230,23 +237,28 @@ public class Sequence extends ASequence implements SequenceI
   protected void initSeqFrom(SequenceI seq,
           AlignmentAnnotation[] alAnnotation)
   {
-    {
-      char[] oseq = seq.getSequence();
-      initSeqAndName(seq.getName(), Arrays.copyOf(oseq, oseq.length),
-              seq.getStart(), seq.getEnd());
-    }
+    char[] oseq = seq.getSequence();
+    initSeqAndName(seq.getName(), Arrays.copyOf(oseq, oseq.length),
+            seq.getStart(), seq.getEnd());
+
     description = seq.getDescription();
     if (seq != datasetSequence)
     {
       setDatasetSequence(seq.getDatasetSequence());
     }
-    if (datasetSequence == null && seq.getDBRefs() != null)
+    
+    /*
+     * only copy DBRefs and seqfeatures if we really are a dataset sequence
+     */
+    if (datasetSequence == null)
     {
-      // only copy DBRefs and seqfeatures if we really are a dataset sequence
-      DBRefEntry[] dbr = seq.getDBRefs();
-      for (int i = 0; i < dbr.length; i++)
+      if (seq.getDBRefs() != null)
       {
-        addDBRef(new DBRefEntry(dbr[i]));
+        DBRefEntry[] dbr = seq.getDBRefs();
+        for (int i = 0; i < dbr.length; i++)
+        {
+          addDBRef(new DBRefEntry(dbr[i]));
+        }
       }
       if (seq.getSequenceFeatures() != null)
       {
@@ -257,6 +269,7 @@ public class Sequence extends ASequence implements SequenceI
         }
       }
     }
+
     if (seq.getAnnotation() != null)
     {
       AlignmentAnnotation[] sqann = seq.getAnnotation();
@@ -314,12 +327,18 @@ public class Sequence extends ASequence implements SequenceI
   }
 
   @Override
-  public synchronized void addSequenceFeature(SequenceFeature sf)
+  public synchronized boolean addSequenceFeature(SequenceFeature sf)
   {
+    if (sf.getType() == null)
+    {
+      System.err.println("SequenceFeature type may not be null: "
+              + sf.toString());
+      return false;
+    }
+
     if (sequenceFeatures == null && datasetSequence != null)
     {
-      datasetSequence.addSequenceFeature(sf);
-      return;
+      return datasetSequence.addSequenceFeature(sf);
     }
     if (sequenceFeatures == null)
     {
@@ -330,7 +349,7 @@ public class Sequence extends ASequence implements SequenceI
     {
       if (sequenceFeatures[i].equals(sf))
       {
-        return;
+        return false;
       }
     }
 
@@ -339,6 +358,9 @@ public class Sequence extends ASequence implements SequenceI
     temp[sequenceFeatures.length] = sf;
 
     sequenceFeatures = temp;
+
+    sequenceFeatureStore.add(sf);
+    return true;
   }
 
   @Override
@@ -353,6 +375,14 @@ public class Sequence extends ASequence implements SequenceI
       return;
     }
 
+    /*
+     * new way
+     */
+    sequenceFeatureStore.delete(sf);
+
+    /*
+     * old way - to be removed
+     */
     int index = 0;
     for (index = 0; index < sequenceFeatures.length; index++)
     {
@@ -412,6 +442,13 @@ public class Sequence extends ASequence implements SequenceI
   }
 
   @Override
+  public SequenceFeaturesI getFeatures()
+  {
+    return datasetSequence != null ? datasetSequence.getFeatures()
+            : sequenceFeatureStore;
+  }
+
+  @Override
   public boolean addPDBId(PDBEntry entry)
   {
     if (pdbIds == null)
@@ -1156,6 +1193,8 @@ public class Sequence extends ASequence implements SequenceI
       // move features and database references onto dataset sequence
       dsseq.sequenceFeatures = sequenceFeatures;
       sequenceFeatures = null;
+      dsseq.sequenceFeatureStore = sequenceFeatureStore;
+      sequenceFeatureStore = null;
       dsseq.dbrefs = dbrefs;
       dbrefs = null;
       // TODO: search and replace any references to this sequence with
@@ -1214,11 +1253,11 @@ public class Sequence extends ASequence implements SequenceI
       return null;
     }
 
-    Vector subset = new Vector();
-    Enumeration e = annotation.elements();
+    Vector<AlignmentAnnotation> subset = new Vector<AlignmentAnnotation>();
+    Enumeration<AlignmentAnnotation> e = annotation.elements();
     while (e.hasMoreElements())
     {
-      AlignmentAnnotation ann = (AlignmentAnnotation) e.nextElement();
+      AlignmentAnnotation ann = e.nextElement();
       if (ann.label != null && ann.label.equals(label))
       {
         subset.addElement(ann);
@@ -1233,7 +1272,7 @@ public class Sequence extends ASequence implements SequenceI
     e = subset.elements();
     while (e.hasMoreElements())
     {
-      anns[i++] = (AlignmentAnnotation) e.nextElement();
+      anns[i++] = e.nextElement();
     }
     subset.removeAllElements();
     return anns;
@@ -1304,10 +1343,10 @@ public class Sequence extends ASequence implements SequenceI
     // transfer PDB entries
     if (entry.getAllPDBEntries() != null)
     {
-      Enumeration e = entry.getAllPDBEntries().elements();
+      Enumeration<PDBEntry> e = entry.getAllPDBEntries().elements();
       while (e.hasMoreElements())
       {
-        PDBEntry pdb = (PDBEntry) e.nextElement();
+        PDBEntry pdb = e.nextElement();
         addPDBId(pdb);
       }
     }
@@ -1475,4 +1514,17 @@ public class Sequence extends ASequence implements SequenceI
     }
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public List<SequenceFeature> findFeatures(int from, int to,
+          String... types)
+  {
+    if (datasetSequence != null)
+    {
+      return datasetSequence.findFeatures(from, to, types);
+    }
+    return sequenceFeatureStore.findFeatures(from, to, types);
+  }
 }