- public int begin;
- public int end;
- public float score;
- public String type;
- public String description;
- public Hashtable otherDetails;
- public java.util.Vector links;
-
- // Feature group can be set from a features file
- // as a group of features between STARTGROUP and ENDGROUP markers
- public String featureGroup;
-
- public SequenceFeature()
- {}
- public SequenceFeature(SequenceFeature cpy) {
- if (cpy!=null) {
- begin = cpy.begin;
- end = cpy.end;
- score = cpy.score;
- type = new String(cpy.type);
- description = new String(cpy.description);
- featureGroup = new String(cpy.featureGroup);
- if (cpy.otherDetails!=null) {
- try {
- otherDetails = (Hashtable) cpy.otherDetails.clone();
- } catch (Exception e) {
- // Uncloneable objects in the otherDetails - don't complain
- }
- }
- if (cpy.links!=null && cpy.links.size()>0) {
- links=new Vector();
- for (int i=0,iSize=cpy.links.size(); i<iSize; i++) {
- links.setElementAt(cpy.links.elementAt(i), i);
- }
- }
- }
- }
- public SequenceFeature(String type,
- String desc,
- String status,
- int begin, int end,
- String featureGroup)
+ /*
+ * score value if none is set; preferably Float.Nan, but see
+ * JAL-2060 and JAL-2554 for a couple of blockers to that
+ */
+ private static final float NO_SCORE = 0f;
+
+ private static final String STATUS = "status";
+
+ private static final String STRAND = "STRAND";
+
+ // private key for Phase designed not to conflict with real GFF data
+ private static final String PHASE = "!Phase";
+
+ // private key for ENA location designed not to conflict with real GFF data
+ private static final String LOCATION = "!Location";
+
+ private static final String ROW_DATA = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>";
+
+ /*
+ * ATTRIBUTES is reserved for the GFF 'column 9' data, formatted as
+ * name1=value1;name2=value2,value3;...etc
+ */
+ private static final String ATTRIBUTES = "ATTRIBUTES";
+
+ /*
+ * type, begin, end, featureGroup, score and contactFeature are final
+ * to ensure that the integrity of SequenceFeatures data store
+ * can't be broken by direct update of these fields
+ */
+ public final String type;
+
+ public final int begin;
+
+ public final int end;
+
+ public final String featureGroup;
+
+ public final float score;
+
+ private final boolean contactFeature;
+
+ public String description;
+
+ /*
+ * a map of key-value pairs; may be populated from GFF 'column 9' data,
+ * other data sources (e.g. GenBank file), or programmatically
+ */
+ public Map<String, Object> otherDetails;
+
+ public Vector<String> links;
+
+ /*
+ * the identifier (if known) for the FeatureSource held in FeatureSources,
+ * as a provider of metadata about feature attributes
+ */
+ private String source;
+
+ /**
+ * Constructs a duplicate feature. Note: Uses makes a shallow copy of the
+ * otherDetails map, so the new and original SequenceFeature may reference the
+ * same objects in the map.
+ *
+ * @param cpy
+ */
+ public SequenceFeature(SequenceFeature cpy)
+ {
+ this(cpy, cpy.getBegin(), cpy.getEnd(), cpy.getFeatureGroup(), cpy
+ .getScore());
+ }
+
+ /**
+ * Constructor
+ *
+ * @param theType
+ * @param theDesc
+ * @param theBegin
+ * @param theEnd
+ * @param group
+ */
+ public SequenceFeature(String theType, String theDesc, int theBegin,
+ int theEnd, String group)
+ {
+ this(theType, theDesc, theBegin, theEnd, NO_SCORE, group);
+ }
+
+ /**
+ * Constructor including a score value
+ *
+ * @param theType
+ * @param theDesc
+ * @param theBegin
+ * @param theEnd
+ * @param theScore
+ * @param group
+ */
+ public SequenceFeature(String theType, String theDesc, int theBegin,
+ int theEnd, float theScore, String group)
+ {
+ this.type = theType;
+ this.description = theDesc;
+ this.begin = theBegin;
+ this.end = theEnd;
+ this.featureGroup = group;
+ this.score = theScore;
+
+ /*
+ * for now, only "Disulfide/disulphide bond" is treated as a contact feature
+ */
+ this.contactFeature = "disulfide bond".equalsIgnoreCase(type)
+ || "disulphide bond".equalsIgnoreCase(type);
+ }
+
+ /**
+ * 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, String newType, int newBegin,
+ int newEnd, String newGroup, float newScore)
+ {
+ this(newType, sf.getDescription(), newBegin, newEnd, newScore,
+ newGroup);
+
+ this.source = sf.source;
+
+ if (sf.otherDetails != null)