import jalview.util.UrlLink;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
{
final String linkImageURL;
+ /*
+ * Comparator to order DBRefEntry by Source + accession id (case-insensitive)
+ */
+ private static Comparator<DBRefEntry> comparator = new Comparator<DBRefEntry>()
+ {
+ @Override
+ public int compare(DBRefEntry ref1, DBRefEntry ref2)
+ {
+ String s1 = ref1.getSource();
+ String s2 = ref2.getSource();
+ int comp = s1 == null ? -1 : (s2 == null ? 1 : s1
+ .compareToIgnoreCase(s2));
+ if (comp == 0)
+ {
+ String a1 = ref1.getAccessionId();
+ String a2 = ref2.getAccessionId();
+ comp = a1 == null ? -1 : (a2 == null ? 1 : a1
+ .compareToIgnoreCase(a2));
+ }
+ return comp;
+ }
+ };
+
public SequenceAnnotationReport(String linkImageURL)
{
this.linkImageURL = linkImageURL;
* appends the features at rpos to the given stringbuffer ready for display in
* a tooltip
*
- * @param tooltipText2
+ * @param tooltipText
* @param linkImageURL
* @param rpos
* @param features
+ * @param minmax
* TODO refactor to Jalview 'utilities' somehow.
*/
- public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- List<SequenceFeature> features)
- {
- appendFeatures(tooltipText2, rpos, features, null);
- }
-
- public void appendFeatures(final StringBuffer tooltipText2, int rpos,
+ public void appendFeatures(final StringBuilder tooltipText, int rpos,
List<SequenceFeature> features, Hashtable minmax)
{
String tmpString;
{
if (feature.getBegin() == rpos || feature.getEnd() == rpos)
{
- if (tooltipText2.length() > 6)
+ if (tooltipText.length() > 6)
{
- tooltipText2.append("<br>");
+ tooltipText.append("<br>");
}
- tooltipText2.append("disulfide bond " + feature.getBegin()
+ tooltipText.append("disulfide bond " + feature.getBegin()
+ ":" + feature.getEnd());
}
}
else
{
- if (tooltipText2.length() > 6)
+ if (tooltipText.length() > 6)
{
- tooltipText2.append("<br>");
+ tooltipText.append("<br>");
}
// TODO: remove this hack to display link only features
boolean linkOnly = feature.getValue("linkonly") != null;
if (!linkOnly)
{
- tooltipText2.append(feature.getType() + " ");
+ tooltipText.append(feature.getType() + " ");
if (rpos != 0)
{
// we are marking a positional feature
- tooltipText2.append(feature.begin);
+ tooltipText.append(feature.begin);
}
if (feature.begin != feature.end)
{
- tooltipText2.append(" " + feature.end);
+ tooltipText.append(" " + feature.end);
}
if (feature.getDescription() != null
if (startTag > -1)
{
- tooltipText2.append("; " + tmpString);
+ tooltipText.append("; " + tmpString);
}
else
{
tmpString = tmpString.replaceAll("<", "<");
tmpString = tmpString.replaceAll(">", ">");
- tooltipText2.append("; ");
- tooltipText2.append(tmpString);
+ tooltipText.append("; ");
+ tooltipText.append(tmpString);
}
else
{
- tooltipText2.append("; " + tmpString);
+ tooltipText.append("; " + tmpString);
}
}
}
.get(feature.getType()));
if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
{
- tooltipText2.append(" Score=" + feature.getScore());
+ tooltipText.append(" Score=" + feature.getScore());
}
}
if (feature.getValue("status") != null)
String status = feature.getValue("status").toString();
if (status.length() > 0)
{
- tooltipText2.append("; (" + feature.getValue("status")
+ tooltipText.append("; (" + feature.getValue("status")
+ ")");
}
}
{
if (linkImageURL != null)
{
- tooltipText2.append(" <img src=\"" + linkImageURL + "\">");
+ tooltipText.append(" <img src=\"" + linkImageURL + "\">");
}
else
{
{
for (String[] urllink : createLinksFrom(null, urlstring))
{
- tooltipText2.append("<br/> <a href=\""
+ tooltipText.append("<br/> <a href=\""
+ urllink[3]
+ "\" target=\""
+ urllink[0]
return urlSets.toArray(new String[][] {});
}
- public void createSequenceAnnotationReport(final StringBuffer tip,
+ public void createTooltipAnnotationReport(final StringBuilder tip,
SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
Hashtable minmax)
{
- createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
- true, minmax);
+ int maxWidth = createSequenceAnnotationReport(tip, sequence,
+ showDbRefs, showNpFeats, minmax, true);
+
+ if (maxWidth > 60)
+ {
+ tip.insert(0, "<table width=350 border=0><tr><td><i>");
+ tip.append("</i></td></tr></table>");
+ }
}
- public void createSequenceAnnotationReport(final StringBuffer tip,
+ public int createSequenceAnnotationReport(final StringBuilder tip,
+ SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
+ Hashtable minmax)
+ {
+ return createSequenceAnnotationReport(tip, sequence, showDbRefs,
+ showNpFeats, minmax, false);
+ }
+
+ /**
+ * Adds an html-formatted sequence annotation report to the provided string
+ * buffer, and returns the longest line length added
+ *
+ * @param sb
+ * @param sequence
+ * @param showDbRefs
+ * if true, include database references
+ * @param showNpFeats
+ * if true, include non-positional sequence features
+ * @param minmax
+ * @param summary
+ * if true, build a shortened summary report (for tooltip)
+ * @return
+ */
+ int createSequenceAnnotationReport(final StringBuilder sb,
SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
- boolean tableWrap, Hashtable minmax)
+ Hashtable minmax, boolean summary)
{
String tmp;
- tip.append("<i>");
+ sb.append("<i>");
int maxWidth = 0;
if (sequence.getDescription() != null)
{
tmp = sequence.getDescription();
- tip.append("<br>" + tmp);
+ sb.append("<br>").append(tmp);
maxWidth = Math.max(maxWidth, tmp.length());
}
SequenceI ds = sequence;
ds = ds.getDatasetSequence();
}
DBRefEntry[] dbrefs = ds.getDBRefs();
+ Arrays.sort(dbrefs, comparator);
if (showDbRefs && dbrefs != null)
{
- for (int i = 0; i < dbrefs.length; i++)
+ boolean ellipsis = false;
+ String lastSource = null;
+ int countForSource = 0;
+ for (DBRefEntry ref : dbrefs)
{
- tip.append("<br>");
- tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
- tip.append(tmp);
- maxWidth = Math.max(maxWidth, tmp.length());
+ String source = ref.getSource();
+ if (source == null)
+ {
+ // shouldn't happen
+ continue;
+ }
+ boolean sourceChanged = !source.equals(lastSource);
+ if (sourceChanged)
+ {
+ countForSource = 0;
+ }
+ lastSource = source;
+ countForSource++;
+ if (countForSource == 1 || !summary)
+ {
+ sb.append("<br>");
+ }
+ if (countForSource < 3 || !summary)
+ {
+ String accessionId = ref.getAccessionId();
+ int len = accessionId.length() + 1;
+ if (countForSource > 1 && summary)
+ {
+ sb.append(", ").append(accessionId);
+ len++;
+ }
+ else
+ {
+ sb.append(source).append(" ").append(accessionId);
+ len += source.length();
+ }
+ maxWidth = Math.max(maxWidth, len);
+ }
+ if (countForSource == 3 && summary)
+ {
+ sb.append(", ...");
+ ellipsis = true;
+ }
+ }
+ if (ellipsis) {
+ sb.append("<br>(Output Sequence Details to list all database references)");
}
}
{
if (features[i].begin == 0 && features[i].end == 0)
{
- int sz = -tip.length();
- List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
- tfeat.add(features[i]);
- appendFeatures(tip, 0, tfeat, minmax);
- sz += tip.length();
+ int sz = -sb.length();
+ List<SequenceFeature> tfeat = Collections
+ .singletonList(features[i]);
+ appendFeatures(sb, 0, tfeat, minmax);
+ sz += sb.length();
maxWidth = Math.max(maxWidth, sz);
}
}
}
-
- if (tableWrap && maxWidth > 60)
- {
- tip.insert(0, "<table width=350 border=0><tr><td><i>");
- tip.append("</i></td></tr></table>");
- }
-
+ return maxWidth;
}
}