2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.util.ArrayList;
21 import java.util.Hashtable;
22 import java.util.Vector;
24 import jalview.datamodel.DBRefEntry;
25 import jalview.datamodel.SequenceFeature;
26 import jalview.datamodel.SequenceI;
27 import jalview.util.UrlLink;
30 * generate HTML reports for a sequence
34 public class SequenceAnnotationReport
36 final String linkImageURL;
38 public SequenceAnnotationReport(String linkImageURL)
40 this.linkImageURL = linkImageURL;
44 * appends the features at rpos to the given stringbuffer ready for display in
51 * TODO refactor to Jalview 'utilities' somehow.
53 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
54 SequenceFeature[] features)
56 appendFeatures(tooltipText2, rpos, features, null);
59 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
60 SequenceFeature[] features, Hashtable minmax)
65 for (int i = 0; i < features.length; i++)
67 if (features[i].getType().equals("disulfide bond"))
69 if (features[i].getBegin() == rpos
70 || features[i].getEnd() == rpos)
72 if (tooltipText2.length() > 6)
74 tooltipText2.append("<br>");
76 tooltipText2.append("disulfide bond " + features[i].getBegin()
77 + ":" + features[i].getEnd());
82 if (tooltipText2.length() > 6)
84 tooltipText2.append("<br>");
86 // TODO: remove this hack to display link only features
87 boolean linkOnly = features[i].getValue("linkonly") != null;
90 tooltipText2.append(features[i].getType() + " ");
93 // we are marking a positional feature
94 tooltipText2.append(features[i].begin);
96 if (features[i].begin != features[i].end)
98 tooltipText2.append(" " + features[i].end);
101 if (features[i].getDescription() != null
102 && !features[i].description.equals(features[i]
105 tmpString = features[i].getDescription();
106 String tmp2up = tmpString.toUpperCase();
107 int startTag = tmp2up.indexOf("<HTML>");
110 tmpString = tmpString.substring(startTag + 6);
111 tmp2up = tmp2up.substring(startTag + 6);
113 int endTag = tmp2up.indexOf("</BODY>");
116 tmpString = tmpString.substring(0, endTag);
117 tmp2up = tmp2up.substring(0, endTag);
119 endTag = tmp2up.indexOf("</HTML>");
122 tmpString = tmpString.substring(0, endTag);
127 tooltipText2.append("; " + tmpString);
131 if (tmpString.indexOf("<") > -1
132 || tmpString.indexOf(">") > -1)
134 // The description does not specify html is to
135 // be used, so we must remove < > symbols
136 tmpString = tmpString.replaceAll("<", "<");
137 tmpString = tmpString.replaceAll(">", ">");
139 tooltipText2.append("; ");
140 tooltipText2.append(tmpString);
145 tooltipText2.append("; " + tmpString);
149 // check score should be shown
150 if (features[i].getScore() != Float.NaN)
152 float[][] rng = (minmax == null) ? null : ((float[][]) minmax
153 .get(features[i].getType()));
154 if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
156 tooltipText2.append(" Score=" + features[i].getScore());
159 if (features[i].getValue("status") != null)
161 String status = features[i].getValue("status").toString();
162 if (status.length() > 0)
164 tooltipText2.append("; (" + features[i].getValue("status")
170 if (features[i].links != null)
172 if (linkImageURL != null)
174 tooltipText2.append(" <img src=\"" + linkImageURL + "\">");
178 for (String urlstring : (Vector<String>) features[i].links)
182 for (String[] urllink : createLinksFrom(null, urlstring))
184 tooltipText2.append("<br/> <a href=\""
189 + (urllink[0].toLowerCase().equals(
190 urllink[1].toLowerCase()) ? urllink[0]
191 : (urllink[0] + ":" + urllink[1]))
194 } catch (Exception x)
196 System.err.println("problem when creating links from "
212 * @return String[][] { String[] { link target, link label, dynamic component
213 * inserted (if any), url }}
215 public String[][] createLinksFrom(SequenceI seq, String link)
217 ArrayList<String[]> urlSets = new ArrayList<String[]>();
218 ArrayList<String> uniques = new ArrayList<String>();
219 UrlLink urlLink = new UrlLink(link);
220 if (!urlLink.isValid())
222 System.err.println(urlLink.getInvalidMessage());
225 final String target = urlLink.getTarget(); // link.substring(0,
226 // link.indexOf("|"));
227 final String label = urlLink.getLabel();
228 if (seq != null && urlLink.isDynamic())
231 // collect matching db-refs
232 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),
235 // collect id string too
236 String id = seq.getName();
237 String descr = seq.getDescription();
238 if (descr != null && descr.length() < 1)
244 for (int r = 0; r < dbr.length; r++)
246 if (id != null && dbr[r].getAccessionId().equals(id))
248 // suppress duplicate link creation for the bare sequence ID
249 // string with this link
252 // create Bare ID link for this RUL
253 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
256 for (int u = 0; u < urls.length; u += 2)
258 String unq = urls[u] + "|" + urls[u + 1];
259 if (!uniques.contains(unq))
261 urlSets.add(new String[]
262 { target, label, urls[u], urls[u + 1] });
271 // create Bare ID link for this RUL
272 String[] urls = urlLink.makeUrls(id, true);
275 for (int u = 0; u < urls.length; u += 2)
277 String unq = urls[u] + "|" + urls[u + 1];
278 if (!uniques.contains(unq))
280 urlSets.add(new String[]
281 { target, label, urls[u], urls[u + 1] });
287 if (descr != null && urlLink.getRegexReplace() != null)
289 // create link for this URL from description only if regex matches
290 String[] urls = urlLink.makeUrls(descr, true);
293 for (int u = 0; u < urls.length; u += 2)
295 String unq = urls[u] + "|" + urls[u + 1];
296 if (!uniques.contains(unq))
298 urlSets.add(new String[]
299 { target, label, urls[u], urls[u + 1] });
309 String unq = label + "|" + urlLink.getUrl_prefix();
310 if (!uniques.contains(unq))
313 // Add a non-dynamic link
314 urlSets.add(new String[]
315 { target, label, null, urlLink.getUrl_prefix() });
319 return urlSets.toArray(new String[][]
323 public void createSequenceAnnotationReport(final StringBuffer tip,
324 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
327 createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
331 public void createSequenceAnnotationReport(final StringBuffer tip,
332 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
333 boolean tableWrap, Hashtable minmax)
339 if (sequence.getDescription() != null)
341 tmp = sequence.getDescription();
342 tip.append("<br>" + tmp);
343 maxWidth = Math.max(maxWidth, tmp.length());
345 SequenceI ds = sequence;
346 while (ds.getDatasetSequence() != null)
348 ds = ds.getDatasetSequence();
350 DBRefEntry[] dbrefs = ds.getDBRef();
351 if (showDbRefs && dbrefs != null)
353 for (int i = 0; i < dbrefs.length; i++)
356 tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
358 maxWidth = Math.max(maxWidth, tmp.length());
362 // ADD NON POSITIONAL SEQUENCE INFO
363 SequenceFeature[] features = ds.getSequenceFeatures();
364 SequenceFeature[] tfeat = new SequenceFeature[1];
365 if (showNpFeats && features != null)
367 for (int i = 0; i < features.length; i++)
369 if (features[i].begin == 0 && features[i].end == 0)
371 int sz = -tip.length();
372 tfeat[0] = features[i];
373 appendFeatures(tip, 0, tfeat, minmax);
375 maxWidth = Math.max(maxWidth, sz);
380 if (tableWrap && maxWidth > 60)
382 tip.insert(0, "<table width=350 border=0><tr><td><i>");
383 tip.append("</i></td></tr></table>");