X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FSequenceFeature.java;h=2dd9cf0d44442e12b3822fed20e61ee1b10f65fe;hb=6200addf078b7f7ace90597dc056dafc7fc602c1;hp=1f2e639cc89408d90056c4c1298a083d406c5474;hpb=4b1c969e87feaefd4fb9c49ba3d6b828b3ce1a9c;p=jalview.git diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java index 1f2e639..2dd9cf0 100755 --- a/src/jalview/datamodel/SequenceFeature.java +++ b/src/jalview/datamodel/SequenceFeature.java @@ -28,7 +28,7 @@ import jalview.datamodel.features.FeatureSources; import jalview.util.StringUtils; import java.util.Comparator; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.SortedMap; @@ -50,10 +50,10 @@ public class SequenceFeature implements FeatureLocationI private static final String STATUS = "status"; - private static final String STRAND = "STRAND"; + public static final String STRAND = "STRAND"; - // private key for Phase designed not to conflict with real GFF data - private static final String PHASE = "!Phase"; + // key for Phase designed not to conflict with real GFF data + public static final String PHASE = "!Phase"; // private key for ENA location designed not to conflict with real GFF data private static final String LOCATION = "!Location"; @@ -61,12 +61,6 @@ public class SequenceFeature implements FeatureLocationI private static final String ROW_DATA = "%s%s%s"; /* - * 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 @@ -174,19 +168,13 @@ public class SequenceFeature implements FeatureLocationI if (sf.otherDetails != null) { - otherDetails = new HashMap<>(); - for (Entry entry : sf.otherDetails.entrySet()) - { - otherDetails.put(entry.getKey(), entry.getValue()); - } + otherDetails = new LinkedHashMap<>(); + otherDetails.putAll(sf.otherDetails); } if (sf.links != null && sf.links.size() > 0) { links = new Vector<>(); - for (int i = 0, iSize = sf.links.size(); i < iSize; i++) - { - links.addElement(sf.links.elementAt(i)); - } + links.addAll(sf.links); } } @@ -217,8 +205,7 @@ public class SequenceFeature implements FeatureLocationI @Override public boolean equals(Object o) { - return (o instanceof SequenceFeature - && equals((SequenceFeature) o, false)); + return equals(o, false); } /** @@ -231,19 +218,47 @@ public class SequenceFeature implements FeatureLocationI * @param ignoreParent * @return */ - public boolean equals(SequenceFeature sf, boolean ignoreParent) + public boolean equals(Object o, boolean ignoreParent) { - return (begin == sf.begin && end == sf.end - && getStrand() == sf.getStrand() - && (Float.isNaN(score) ? Float.isNaN(sf.score) - : score == sf.score) - && (type + description + featureGroup + getPhase()) - .equals(sf.type + sf.description + sf.featureGroup - + sf.getPhase()) - && equalAttribute(getValue("ID"), sf.getValue("ID")) - && equalAttribute(getValue("Name"), sf.getValue("Name")) - && (ignoreParent || equalAttribute(getValue("Parent"), - sf.getValue("Parent")))); + if (o == null || !(o instanceof SequenceFeature)) + { + return false; + } + + SequenceFeature sf = (SequenceFeature) o; + boolean sameScore = Float.isNaN(score) ? Float.isNaN(sf.score) + : score == sf.score; + if (begin != sf.begin || end != sf.end || !sameScore) + { + return false; + } + + if (getStrand() != sf.getStrand()) + { + return false; + } + + if (!(type + description + featureGroup + getPhase()).equals( + sf.type + sf.description + sf.featureGroup + sf.getPhase())) + { + return false; + } + if (!equalAttribute(getValue("ID"), sf.getValue("ID"))) + { + return false; + } + if (!equalAttribute(getValue("Name"), sf.getValue("Name"))) + { + return false; + } + if (!ignoreParent) + { + if (!equalAttribute(getValue("Parent"), sf.getValue("Parent"))) + { + return false; + } + } + return true; } /** @@ -318,6 +333,11 @@ public class SequenceFeature implements FeatureLocationI return featureGroup; } + /** + * Adds a hyperlink for the feature. This should have the format label|url. + * + * @param labelLink + */ public void addLink(String labelLink) { if (links == null) @@ -408,7 +428,10 @@ public class SequenceFeature implements FeatureLocationI { if (otherDetails == null) { - otherDetails = new HashMap<>(); + /* + * LinkedHashMap preserves insertion order of attributes + */ + otherDetails = new LinkedHashMap<>(); } otherDetails.put(key, value); @@ -451,16 +474,6 @@ public class SequenceFeature implements FeatureLocationI return (String) getValue(STATUS); } - public void setAttributes(String attr) - { - setValue(ATTRIBUTES, attr); - } - - public String getAttributes() - { - return (String) getValue(ATTRIBUTES); - } - /** * Return 1 for forward strand ('+' in GFF), -1 for reverse strand ('-' in * GFF), and 0 for unknown or not (validly) specified @@ -575,9 +588,11 @@ public class SequenceFeature implements FeatureLocationI /** * Answers an html-formatted report of feature details * + * @param seqName + * * @return */ - public String getDetailsReport() + public String getDetailsReport(String seqName) { FeatureSourceI metadata = FeatureSources.getInstance() .getSource(source); @@ -585,9 +600,10 @@ public class SequenceFeature implements FeatureLocationI StringBuilder sb = new StringBuilder(128); sb.append("
"); sb.append(""); + sb.append(String.format(ROW_DATA, "Location", seqName, + begin == end ? begin + : begin + (isContactFeature() ? ":" : "-") + end)); sb.append(String.format(ROW_DATA, "Type", type, "")); - sb.append(String.format(ROW_DATA, "Start/end", begin == end ? begin - : begin + (isContactFeature() ? ":" : "-") + end, "")); String desc = StringUtils.stripHtmlTags(description); sb.append(String.format(ROW_DATA, "Description", desc, "")); if (!Float.isNaN(score) && score != 0f) @@ -608,10 +624,6 @@ public class SequenceFeature implements FeatureLocationI for (Entry entry : ordered.entrySet()) { String key = entry.getKey(); - if (ATTRIBUTES.equals(key)) - { - continue; // to avoid double reporting - } Object value = entry.getValue(); if (value instanceof Map) @@ -709,8 +721,6 @@ public class SequenceFeature implements FeatureLocationI { source = theSource; } - - } class SFSortByEnd implements Comparator