2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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.List;
26 import java.util.Vector;
28 import jalview.datamodel.DBRefEntry;
29 import jalview.datamodel.SequenceFeature;
30 import jalview.datamodel.SequenceI;
31 import jalview.util.UrlLink;
34 * generate HTML reports for a sequence
38 public class SequenceAnnotationReport
40 final String linkImageURL;
42 public SequenceAnnotationReport(String linkImageURL)
44 this.linkImageURL = linkImageURL;
48 * appends the features at rpos to the given stringbuffer ready for display in
55 * TODO refactor to Jalview 'utilities' somehow.
57 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
58 List<SequenceFeature> features)
60 appendFeatures(tooltipText2, rpos, features, null);
63 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
64 List<SequenceFeature> features, Hashtable minmax)
69 for (SequenceFeature feature:features)
71 if (feature.getType().equals("disulfide bond"))
73 if (feature.getBegin() == rpos
74 || feature.getEnd() == rpos)
76 if (tooltipText2.length() > 6)
78 tooltipText2.append("<br>");
80 tooltipText2.append("disulfide bond " + feature.getBegin()
81 + ":" + feature.getEnd());
86 if (tooltipText2.length() > 6)
88 tooltipText2.append("<br>");
90 // TODO: remove this hack to display link only features
91 boolean linkOnly = feature.getValue("linkonly") != null;
94 tooltipText2.append(feature.getType() + " ");
97 // we are marking a positional feature
98 tooltipText2.append(feature.begin);
100 if (feature.begin != feature.end)
102 tooltipText2.append(" " + feature.end);
105 if (feature.getDescription() != null
106 && !feature.description.equals(feature
109 tmpString = feature.getDescription();
110 String tmp2up = tmpString.toUpperCase();
111 int startTag = tmp2up.indexOf("<HTML>");
114 tmpString = tmpString.substring(startTag + 6);
115 tmp2up = tmp2up.substring(startTag + 6);
117 int endTag = tmp2up.indexOf("</BODY>");
120 tmpString = tmpString.substring(0, endTag);
121 tmp2up = tmp2up.substring(0, endTag);
123 endTag = tmp2up.indexOf("</HTML>");
126 tmpString = tmpString.substring(0, endTag);
131 tooltipText2.append("; " + tmpString);
135 if (tmpString.indexOf("<") > -1
136 || tmpString.indexOf(">") > -1)
138 // The description does not specify html is to
139 // be used, so we must remove < > symbols
140 tmpString = tmpString.replaceAll("<", "<");
141 tmpString = tmpString.replaceAll(">", ">");
143 tooltipText2.append("; ");
144 tooltipText2.append(tmpString);
149 tooltipText2.append("; " + tmpString);
153 // check score should be shown
154 if (feature.getScore() != Float.NaN)
156 float[][] rng = (minmax == null) ? null : ((float[][]) minmax
157 .get(feature.getType()));
158 if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
160 tooltipText2.append(" Score=" + feature.getScore());
163 if (feature.getValue("status") != null)
165 String status = feature.getValue("status").toString();
166 if (status.length() > 0)
168 tooltipText2.append("; (" + feature.getValue("status")
174 if (feature.links != null)
176 if (linkImageURL != null)
178 tooltipText2.append(" <img src=\"" + linkImageURL + "\">");
182 for (String urlstring : (Vector<String>) feature.links)
186 for (String[] urllink : createLinksFrom(null, urlstring))
188 tooltipText2.append("<br/> <a href=\""
193 + (urllink[0].toLowerCase().equals(
194 urllink[1].toLowerCase()) ? urllink[0]
195 : (urllink[0] + ":" + urllink[1]))
198 } catch (Exception x)
200 System.err.println("problem when creating links from "
216 * @return String[][] { String[] { link target, link label, dynamic component
217 * inserted (if any), url }}
219 public String[][] createLinksFrom(SequenceI seq, String link)
221 ArrayList<String[]> urlSets = new ArrayList<String[]>();
222 ArrayList<String> uniques = new ArrayList<String>();
223 UrlLink urlLink = new UrlLink(link);
224 if (!urlLink.isValid())
226 System.err.println(urlLink.getInvalidMessage());
229 final String target = urlLink.getTarget(); // link.substring(0,
230 // link.indexOf("|"));
231 final String label = urlLink.getLabel();
232 if (seq != null && urlLink.isDynamic())
235 // collect matching db-refs
236 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),
239 // collect id string too
240 String id = seq.getName();
241 String descr = seq.getDescription();
242 if (descr != null && descr.length() < 1)
248 for (int r = 0; r < dbr.length; r++)
250 if (id != null && dbr[r].getAccessionId().equals(id))
252 // suppress duplicate link creation for the bare sequence ID
253 // string with this link
256 // create Bare ID link for this RUL
257 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
260 for (int u = 0; u < urls.length; u += 2)
262 String unq = urls[u] + "|" + urls[u + 1];
263 if (!uniques.contains(unq))
265 urlSets.add(new String[]
266 { target, label, urls[u], urls[u + 1] });
275 // create Bare ID link for this RUL
276 String[] urls = urlLink.makeUrls(id, true);
279 for (int u = 0; u < urls.length; u += 2)
281 String unq = urls[u] + "|" + urls[u + 1];
282 if (!uniques.contains(unq))
284 urlSets.add(new String[]
285 { target, label, urls[u], urls[u + 1] });
291 if (descr != null && urlLink.getRegexReplace() != null)
293 // create link for this URL from description only if regex matches
294 String[] urls = urlLink.makeUrls(descr, true);
297 for (int u = 0; u < urls.length; u += 2)
299 String unq = urls[u] + "|" + urls[u + 1];
300 if (!uniques.contains(unq))
302 urlSets.add(new String[]
303 { target, label, urls[u], urls[u + 1] });
313 String unq = label + "|" + urlLink.getUrl_prefix();
314 if (!uniques.contains(unq))
317 // Add a non-dynamic link
318 urlSets.add(new String[]
319 { target, label, null, urlLink.getUrl_prefix() });
323 return urlSets.toArray(new String[][]
327 public void createSequenceAnnotationReport(final StringBuffer tip,
328 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
331 createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
335 public void createSequenceAnnotationReport(final StringBuffer tip,
336 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
337 boolean tableWrap, Hashtable minmax)
343 if (sequence.getDescription() != null)
345 tmp = sequence.getDescription();
346 tip.append("<br>" + tmp);
347 maxWidth = Math.max(maxWidth, tmp.length());
349 SequenceI ds = sequence;
350 while (ds.getDatasetSequence() != null)
352 ds = ds.getDatasetSequence();
354 DBRefEntry[] dbrefs = ds.getDBRef();
355 if (showDbRefs && dbrefs != null)
357 for (int i = 0; i < dbrefs.length; i++)
360 tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
362 maxWidth = Math.max(maxWidth, tmp.length());
366 // ADD NON POSITIONAL SEQUENCE INFO
367 SequenceFeature[] features = ds.getSequenceFeatures();
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 List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
376 tfeat.add(features[i]);
377 appendFeatures(tip, 0, tfeat, minmax);
379 maxWidth = Math.max(maxWidth, sz);
384 if (tableWrap && maxWidth > 60)
386 tip.insert(0, "<table width=350 border=0><tr><td><i>");
387 tip.append("</i></td></tr></table>");