X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2FSequenceAnnotationReport.java;h=9ffdf217f9d5f6184f210a40723f9fffd79fd050;hb=08c7bee16c16563cc7cec7ea4d336b3e0c4c937a;hp=0ef4cc22cae38bb9c6d03e832e8342b09ff42f60;hpb=006890b02106eb31841e6e84d75f1027434823e0;p=jalview.git diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java index 0ef4cc2..9ffdf21 100644 --- a/src/jalview/io/SequenceAnnotationReport.java +++ b/src/jalview/io/SequenceAnnotationReport.java @@ -20,6 +20,14 @@ */ package jalview.io; +import java.util.Locale; + +import java.util.Collection; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import jalview.api.FeatureColourI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; @@ -32,13 +40,6 @@ import jalview.util.StringUtils; import jalview.util.UrlLink; import jalview.viewmodel.seqfeatures.FeatureRendererModel; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - /** * generate HTML reports for a sequence * @@ -56,15 +57,15 @@ public class SequenceAnnotationReport private static final int MAX_SOURCES = 40; - // public static final String[][] PRIMARY_SOURCES moved to DBRefSource.java + private static String linkImageURL; - final String linkImageURL; + // public static final String[][] PRIMARY_SOURCES moved to DBRefSource.java /* * Comparator to order DBRefEntry by Source + accession id (case-insensitive), * with 'Primary' sources placed before others, and 'chromosome' first of all */ - private static Comparator comparator = new Comparator<>() + private static Comparator comparator = new Comparator() { @Override @@ -118,14 +119,30 @@ public class SequenceAnnotationReport // } }; - public SequenceAnnotationReport(String linkURL) + private boolean forTooltip; + + /** + * Constructor given a flag which affects behaviour + *
    + *
  • if true, generates feature details suitable to show in a tooltip
  • + *
  • if false, generates feature details in a form suitable for the sequence + * details report
  • + *
+ * + * @param isForTooltip + */ + public SequenceAnnotationReport(boolean isForTooltip) { - this.linkImageURL = linkURL; + this.forTooltip = isForTooltip; + if (linkImageURL == null) + { + linkImageURL = getClass().getResource("/images/link.gif").toString(); + } } /** - * Append text for the list of features to the tooltip Returns number of - * features left if maxlength limit is (or would have been) reached + * Append text for the list of features to the tooltip. Returns the number of + * features not added if maxlength limit is (or would have been) reached. * * @param sb * @param residuePos @@ -133,7 +150,7 @@ public class SequenceAnnotationReport * @param minmax * @param maxlength */ - public int appendFeaturesLengthLimit(final StringBuilder sb, + public int appendFeatures(final StringBuilder sb, int residuePos, List features, FeatureRendererModel fr, int maxlength) { @@ -148,16 +165,10 @@ public class SequenceAnnotationReport return 0; } - public void appendFeatures(final StringBuilder sb, int residuePos, - List features, FeatureRendererModel fr) - { - appendFeaturesLengthLimit(sb, residuePos, features, fr, 0); - } - /** - * Appends text for mapped features (e.g. CDS feature for peptide or vice versa) - * Returns number of features left if maxlength limit is (or would have been) - * reached + * Appends text for mapped features (e.g. CDS feature for peptide or vice + * versa) Returns number of features left if maxlength limit is (or would have + * been) reached. * * @param sb * @param residuePos @@ -165,7 +176,7 @@ public class SequenceAnnotationReport * @param fr * @param maxlength */ - public int appendFeaturesLengthLimit(StringBuilder sb, int residuePos, + public int appendFeatures(StringBuilder sb, int residuePos, MappedFeatures mf, FeatureRendererModel fr, int maxlength) { for (int i = 0; i < mf.features.size(); i++) @@ -179,12 +190,6 @@ public class SequenceAnnotationReport return 0; } - public void appendFeatures(StringBuilder sb, int residuePos, - MappedFeatures mf, FeatureRendererModel fr) - { - appendFeaturesLengthLimit(sb, residuePos, mf, fr, 0); - } - /** * Appends the feature at rpos to the given buffer * @@ -197,19 +202,64 @@ public class SequenceAnnotationReport FeatureRendererModel fr, SequenceFeature feature, MappedFeatures mf, int maxlength) { + int begin = feature.getBegin(); + int end = feature.getEnd(); + + /* + * if this is a virtual features, convert begin/end to the + * coordinates of the sequence it is mapped to + */ + int[] beginRange = null; // feature start in local coordinates + int[] endRange = null; // feature end in local coordinates + if (mf != null) + { + if (feature.isContactFeature()) + { + /* + * map start and end points individually + */ + beginRange = mf.getMappedPositions(begin, begin); + endRange = begin == end ? beginRange + : mf.getMappedPositions(end, end); + } + else + { + /* + * map the feature extent + */ + beginRange = mf.getMappedPositions(begin, end); + endRange = beginRange; + } + if (beginRange == null || endRange == null) + { + // something went wrong + return false; + } + begin = beginRange[0]; + end = endRange[endRange.length - 1]; + } + StringBuilder sb = new StringBuilder(); if (feature.isContactFeature()) { - if (feature.getBegin() == rpos || feature.getEnd() == rpos) + /* + * include if rpos is at start or end position of [mapped] feature + */ + boolean showContact = (mf == null) && (rpos == begin || rpos == end); + boolean showMappedContact = (mf != null) && ((rpos >= beginRange[0] + && rpos <= beginRange[beginRange.length - 1]) + || (rpos >= endRange[0] + && rpos <= endRange[endRange.length - 1])); + if (showContact || showMappedContact) { if (sb0.length() > 6) { sb.append("
"); } - sb.append(feature.getType()).append(" ").append(feature.getBegin()) - .append(":").append(feature.getEnd()); + sb.append(feature.getType()).append(" ").append(begin).append(":") + .append(end); } - return appendTextMaxLengthReached(sb0, sb, maxlength); + return appendText(sb0, sb, maxlength); } if (sb0.length() > 6) @@ -224,11 +274,11 @@ public class SequenceAnnotationReport if (rpos != 0) { // we are marking a positional feature - sb.append(feature.begin); - } - if (feature.begin != feature.end) - { - sb.append(" ").append(feature.end); + sb.append(begin); + if (begin != end) + { + sb.append(" ").append(end); + } } String description = feature.getDescription(); @@ -240,7 +290,7 @@ public class SequenceAnnotationReport * truncate overlong descriptions unless they contain an href * before the truncation point (as truncation could leave corrupted html) */ - int linkindex = description.toLowerCase().indexOf(" -1 && linkindex < MAX_DESCRIPTION_LENGTH; if (description.length() > MAX_DESCRIPTION_LENGTH && !hasLink) @@ -289,27 +339,28 @@ public class SequenceAnnotationReport } } } - return appendTextMaxLengthReached(sb0, sb, maxlength); - } - - void appendFeature(final StringBuilder sb, int rpos, - FeatureRendererModel fr, SequenceFeature feature, - MappedFeatures mf) - { - appendFeature(sb, rpos, fr, feature, mf, 0); + return appendText(sb0, sb, maxlength); } - private static boolean appendTextMaxLengthReached(StringBuilder sb0, - StringBuilder sb, int maxlength) + /** + * Appends sb to sb0, and returns false, unless maxlength is not zero and + * appending would make the result longer than or equal to maxlength, in which + * case the append is not done and returns true + * + * @param sb0 + * @param sb + * @param maxlength + * @return + */ + private static boolean appendText(StringBuilder sb0, StringBuilder sb, + int maxlength) { - boolean ret = false; if (maxlength == 0 || sb0.length() + sb.length() < maxlength) { sb0.append(sb); return false; - } else { - return true; } + return true; } /** @@ -366,8 +417,8 @@ public class SequenceAnnotationReport + "\" target=\"" + urllink.get(0) + "\">" - + (urllink.get(0).toLowerCase() - .equals(urllink.get(1).toLowerCase()) ? urllink + + (urllink.get(0).toLowerCase(Locale.ROOT) + .equals(urllink.get(1).toLowerCase(Locale.ROOT)) ? urllink .get(0) : (urllink.get(0) + ":" + urllink .get(1))) + "
"); @@ -464,7 +515,7 @@ public class SequenceAnnotationReport .getNonPositionalFeatures()) { int sz = -sb.length(); - appendFeature(sb, 0, fr, sf, null); + appendFeature(sb, 0, fr, sf, null, 0); sz += sb.length(); maxWidth = Math.max(maxWidth, sz); }