import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.TreeMap;
import java.util.Vector;
/**
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
*/
* 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)
}
/**
+ * 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.
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;
}
{
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;
+ }
}