JAL-2738 update spikes/mungo
[jalview.git] / src / jalview / datamodel / SequenceFeature.java
index 9a6cf2b..4208ce1 100755 (executable)
@@ -25,6 +25,7 @@ import jalview.datamodel.features.FeatureLocationI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.Vector;
 
 /**
@@ -52,6 +53,16 @@ public class SequenceFeature implements FeatureLocationI
   private static final String LOCATION = "!Location";
 
   /*
+   * map of otherDetails special keys, and their value fields' delimiter
+   */
+  private static final Map<String, String> INFO_KEYS = new HashMap<>();
+
+  static
+  {
+    INFO_KEYS.put("CSQ", ",");
+  }
+
+  /*
    * ATTRIBUTES is reserved for the GFF 'column 9' data, formatted as
    * name1=value1;name2=value2,value3;...etc
    */
@@ -143,15 +154,16 @@ public class SequenceFeature implements FeatureLocationI
    * A copy constructor that allows the value of final fields to be 'modified'
    * 
    * @param sf
+   * @param newType
    * @param newBegin
    * @param newEnd
    * @param newGroup
    * @param newScore
    */
-  public SequenceFeature(SequenceFeature sf, int newBegin, int newEnd,
-          String newGroup, float newScore)
+  public SequenceFeature(SequenceFeature sf, String newType, int newBegin,
+          int newEnd, String newGroup, float newScore)
   {
-    this(sf.getType(), sf.getDescription(), newBegin, newEnd, newScore,
+    this(newType, sf.getDescription(), newBegin, newEnd, newScore,
             newGroup);
 
     if (sf.otherDetails != null)
@@ -173,6 +185,21 @@ public class SequenceFeature implements FeatureLocationI
   }
 
   /**
+   * A copy constructor that allows the value of final fields to be 'modified'
+   * 
+   * @param sf
+   * @param newBegin
+   * @param newEnd
+   * @param newGroup
+   * @param newScore
+   */
+  public SequenceFeature(SequenceFeature sf, int newBegin, int newEnd,
+          String newGroup, float newScore)
+  {
+    this(sf, sf.getType(), newBegin, newEnd, newGroup, newScore);
+  }
+
+  /**
    * Two features are considered equal if they have the same type, group,
    * description, start, end, phase, strand, and (if present) 'Name', ID' and
    * 'Parent' attributes.
@@ -217,8 +244,8 @@ public class SequenceFeature implements FeatureLocationI
       return false;
     }
 
-    if (!(type + description + featureGroup + getPhase()).equals(sf.type
-            + sf.description + sf.featureGroup + sf.getPhase()))
+    if (!(type + description + featureGroup + getPhase()).equals(
+            sf.type + sf.description + sf.featureGroup + sf.getPhase()))
     {
       return false;
     }
@@ -519,4 +546,63 @@ public class SequenceFeature implements FeatureLocationI
   {
     return begin == 0 && end == 0;
   }
+
+  /**
+   * Answers a formatted text report of feature details
+   * 
+   * @return
+   */
+  public String getDetailsReport()
+  {
+    StringBuilder sb = new StringBuilder(128);
+    if (begin == end)
+    {
+      sb.append(String.format("%s %d %s", type, begin, description));
+    }
+    else
+    {
+      sb.append(String.format("%s %d-%d %s", type, begin, end, description));
+    }
+    if (!Float.isNaN(score) && score != 0f)
+    {
+      sb.append(" score=").append(score);
+    }
+    if (featureGroup != null)
+    {
+      sb.append(" (").append(featureGroup).append(")");
+    }
+    sb.append("\n\n");
+
+    if (otherDetails != null)
+    {
+      TreeMap<String, Object> ordered = new TreeMap<>(
+              String.CASE_INSENSITIVE_ORDER);
+      ordered.putAll(otherDetails);
+
+      for (Entry<String, Object> entry : ordered.entrySet())
+      {
+        String key = entry.getKey();
+        if (ATTRIBUTES.equals(key))
+        {
+          continue; // to avoid double reporting
+        }
+        if (INFO_KEYS.containsKey(key))
+        {
+          /*
+           * split selected INFO data by delimiter over multiple lines
+           */
+          sb.append(key).append("=\n  ");
+          String delimiter = INFO_KEYS.get(key);
+          String value = entry.getValue().toString();
+          sb.append(value.replace(delimiter, "\n  "));
+        }
+        else
+        {
+          sb.append(key + "=" + entry.getValue().toString() + "\n");
+        }
+      }
+    }
+    String text = sb.toString();
+    return text;
+  }
 }