2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.util.ArrayList;
24 import java.util.Hashtable;
25 import java.util.Vector;
27 import jalview.datamodel.DBRefEntry;
28 import jalview.datamodel.SequenceFeature;
29 import jalview.datamodel.SequenceI;
30 import jalview.util.UrlLink;
33 * generate HTML reports for a sequence
37 public class SequenceAnnotationReport
39 final String linkImageURL;
41 public SequenceAnnotationReport(String linkImageURL)
43 this.linkImageURL = linkImageURL;
47 * appends the features at rpos to the given stringbuffer ready for display in
54 * TODO refactor to Jalview 'utilities' somehow.
56 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
57 SequenceFeature[] features)
59 appendFeatures(tooltipText2, rpos, features, null);
62 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
63 SequenceFeature[] features, Hashtable minmax)
68 for (int i = 0; i < features.length; i++)
70 if (features[i].getType().equals("disulfide bond"))
72 if (features[i].getBegin() == rpos
73 || features[i].getEnd() == rpos)
75 if (tooltipText2.length() > 6)
77 tooltipText2.append("<br>");
79 tooltipText2.append("disulfide bond " + features[i].getBegin()
80 + ":" + features[i].getEnd());
85 if (tooltipText2.length() > 6)
87 tooltipText2.append("<br>");
89 // TODO: remove this hack to display link only features
90 boolean linkOnly = features[i].getValue("linkonly") != null;
93 tooltipText2.append(features[i].getType() + " ");
96 // we are marking a positional feature
97 tooltipText2.append(features[i].begin);
99 if (features[i].begin != features[i].end)
101 tooltipText2.append(" " + features[i].end);
104 if (features[i].getDescription() != null
105 && !features[i].description.equals(features[i]
108 tmpString = features[i].getDescription();
109 String tmp2up = tmpString.toUpperCase();
110 int startTag = tmp2up.indexOf("<HTML>");
113 tmpString = tmpString.substring(startTag + 6);
114 tmp2up = tmp2up.substring(startTag + 6);
116 int endTag = tmp2up.indexOf("</BODY>");
119 tmpString = tmpString.substring(0, endTag);
120 tmp2up = tmp2up.substring(0, endTag);
122 endTag = tmp2up.indexOf("</HTML>");
125 tmpString = tmpString.substring(0, endTag);
130 tooltipText2.append("; " + tmpString);
134 if (tmpString.indexOf("<") > -1
135 || tmpString.indexOf(">") > -1)
137 // The description does not specify html is to
138 // be used, so we must remove < > symbols
139 tmpString = tmpString.replaceAll("<", "<");
140 tmpString = tmpString.replaceAll(">", ">");
142 tooltipText2.append("; ");
143 tooltipText2.append(tmpString);
148 tooltipText2.append("; " + tmpString);
152 // check score should be shown
153 if (features[i].getScore() != Float.NaN)
155 float[][] rng = (minmax == null) ? null : ((float[][]) minmax
156 .get(features[i].getType()));
157 if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
159 tooltipText2.append(" Score=" + features[i].getScore());
162 if (features[i].getValue("status") != null)
164 String status = features[i].getValue("status").toString();
165 if (status.length() > 0)
167 tooltipText2.append("; (" + features[i].getValue("status")
173 if (features[i].links != null)
175 if (linkImageURL != null)
177 tooltipText2.append(" <img src=\"" + linkImageURL + "\">");
181 for (String urlstring : (Vector<String>) features[i].links)
185 for (String[] urllink : createLinksFrom(null, urlstring))
187 tooltipText2.append("<br/> <a href=\""
192 + (urllink[0].toLowerCase().equals(
193 urllink[1].toLowerCase()) ? urllink[0]
194 : (urllink[0] + ":" + urllink[1]))
197 } catch (Exception x)
199 System.err.println("problem when creating links from "
215 * @return String[][] { String[] { link target, link label, dynamic component
216 * inserted (if any), url }}
218 public String[][] createLinksFrom(SequenceI seq, String link)
220 ArrayList<String[]> urlSets = new ArrayList<String[]>();
221 ArrayList<String> uniques = new ArrayList<String>();
222 UrlLink urlLink = new UrlLink(link);
223 if (!urlLink.isValid())
225 System.err.println(urlLink.getInvalidMessage());
228 final String target = urlLink.getTarget(); // link.substring(0,
229 // link.indexOf("|"));
230 final String label = urlLink.getLabel();
231 if (seq != null && urlLink.isDynamic())
234 // collect matching db-refs
235 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),
238 // collect id string too
239 String id = seq.getName();
240 String descr = seq.getDescription();
241 if (descr != null && descr.length() < 1)
247 for (int r = 0; r < dbr.length; r++)
249 if (id != null && dbr[r].getAccessionId().equals(id))
251 // suppress duplicate link creation for the bare sequence ID
252 // string with this link
255 // create Bare ID link for this RUL
256 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
259 for (int u = 0; u < urls.length; u += 2)
261 String unq = urls[u] + "|" + urls[u + 1];
262 if (!uniques.contains(unq))
264 urlSets.add(new String[]
265 { target, label, urls[u], urls[u + 1] });
274 // create Bare ID link for this RUL
275 String[] urls = urlLink.makeUrls(id, true);
278 for (int u = 0; u < urls.length; u += 2)
280 String unq = urls[u] + "|" + urls[u + 1];
281 if (!uniques.contains(unq))
283 urlSets.add(new String[]
284 { target, label, urls[u], urls[u + 1] });
290 if (descr != null && urlLink.getRegexReplace() != null)
292 // create link for this URL from description only if regex matches
293 String[] urls = urlLink.makeUrls(descr, true);
296 for (int u = 0; u < urls.length; u += 2)
298 String unq = urls[u] + "|" + urls[u + 1];
299 if (!uniques.contains(unq))
301 urlSets.add(new String[]
302 { target, label, urls[u], urls[u + 1] });
312 String unq = label + "|" + urlLink.getUrl_prefix();
313 if (!uniques.contains(unq))
316 // Add a non-dynamic link
317 urlSets.add(new String[]
318 { target, label, null, urlLink.getUrl_prefix() });
322 return urlSets.toArray(new String[][]
326 public void createSequenceAnnotationReport(final StringBuffer tip,
327 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
330 createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
334 public void createSequenceAnnotationReport(final StringBuffer tip,
335 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
336 boolean tableWrap, Hashtable minmax)
342 if (sequence.getDescription() != null)
344 tmp = sequence.getDescription();
345 tip.append("<br>" + tmp);
346 maxWidth = Math.max(maxWidth, tmp.length());
348 SequenceI ds = sequence;
349 while (ds.getDatasetSequence() != null)
351 ds = ds.getDatasetSequence();
353 DBRefEntry[] dbrefs = ds.getDBRef();
354 if (showDbRefs && dbrefs != null)
356 for (int i = 0; i < dbrefs.length; i++)
359 tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
361 maxWidth = Math.max(maxWidth, tmp.length());
365 // ADD NON POSITIONAL SEQUENCE INFO
366 SequenceFeature[] features = ds.getSequenceFeatures();
367 SequenceFeature[] tfeat = new SequenceFeature[1];
368 if (showNpFeats && features != null)
370 for (int i = 0; i < features.length; i++)
372 if (features[i].begin == 0 && features[i].end == 0)
374 int sz = -tip.length();
375 tfeat[0] = features[i];
376 appendFeatures(tip, 0, tfeat, minmax);
378 maxWidth = Math.max(maxWidth, sz);
383 if (tableWrap && maxWidth > 60)
385 tip.insert(0, "<table width=350 border=0><tr><td><i>");
386 tip.append("</i></td></tr></table>");