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.
24 import jalview.datamodel.DBRefEntry;
25 import jalview.datamodel.SequenceFeature;
26 import jalview.datamodel.SequenceI;
27 import jalview.util.DBRefUtils;
28 import jalview.util.UrlLink;
30 import java.util.ArrayList;
31 import java.util.Hashtable;
32 import java.util.List;
36 * generate HTML reports for a sequence
40 public class SequenceAnnotationReport
42 final String linkImageURL;
44 public SequenceAnnotationReport(String linkImageURL)
46 this.linkImageURL = linkImageURL;
50 * appends the features at rpos to the given stringbuffer ready for display in
57 * TODO refactor to Jalview 'utilities' somehow.
59 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
60 List<SequenceFeature> features)
62 appendFeatures(tooltipText2, rpos, features, null);
65 public void appendFeatures(final StringBuffer tooltipText2, int rpos,
66 List<SequenceFeature> features, Hashtable minmax)
71 for (SequenceFeature feature:features)
73 if (feature.getType().equals("disulfide bond"))
75 if (feature.getBegin() == rpos
76 || feature.getEnd() == rpos)
78 if (tooltipText2.length() > 6)
80 tooltipText2.append("<br>");
82 tooltipText2.append("disulfide bond " + feature.getBegin()
83 + ":" + feature.getEnd());
88 if (tooltipText2.length() > 6)
90 tooltipText2.append("<br>");
92 // TODO: remove this hack to display link only features
93 boolean linkOnly = feature.getValue("linkonly") != null;
96 tooltipText2.append(feature.getType() + " ");
99 // we are marking a positional feature
100 tooltipText2.append(feature.begin);
102 if (feature.begin != feature.end)
104 tooltipText2.append(" " + feature.end);
107 if (feature.getDescription() != null
108 && !feature.description.equals(feature
111 tmpString = feature.getDescription();
112 String tmp2up = tmpString.toUpperCase();
113 int startTag = tmp2up.indexOf("<HTML>");
116 tmpString = tmpString.substring(startTag + 6);
117 tmp2up = tmp2up.substring(startTag + 6);
119 int endTag = tmp2up.indexOf("</BODY>");
122 tmpString = tmpString.substring(0, endTag);
123 tmp2up = tmp2up.substring(0, endTag);
125 endTag = tmp2up.indexOf("</HTML>");
128 tmpString = tmpString.substring(0, endTag);
133 tooltipText2.append("; " + tmpString);
137 if (tmpString.indexOf("<") > -1
138 || tmpString.indexOf(">") > -1)
140 // The description does not specify html is to
141 // be used, so we must remove < > symbols
142 tmpString = tmpString.replaceAll("<", "<");
143 tmpString = tmpString.replaceAll(">", ">");
145 tooltipText2.append("; ");
146 tooltipText2.append(tmpString);
151 tooltipText2.append("; " + tmpString);
155 // check score should be shown
156 if (feature.getScore() != Float.NaN)
158 float[][] rng = (minmax == null) ? null : ((float[][]) minmax
159 .get(feature.getType()));
160 if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
162 tooltipText2.append(" Score=" + feature.getScore());
165 if (feature.getValue("status") != null)
167 String status = feature.getValue("status").toString();
168 if (status.length() > 0)
170 tooltipText2.append("; (" + feature.getValue("status")
176 if (feature.links != null)
178 if (linkImageURL != null)
180 tooltipText2.append(" <img src=\"" + linkImageURL + "\">");
184 for (String urlstring : feature.links)
188 for (String[] urllink : createLinksFrom(null, urlstring))
190 tooltipText2.append("<br/> <a href=\""
195 + (urllink[0].toLowerCase().equals(
196 urllink[1].toLowerCase()) ? urllink[0]
197 : (urllink[0] + ":" + urllink[1]))
200 } catch (Exception x)
202 System.err.println("problem when creating links from "
218 * @return String[][] { String[] { link target, link label, dynamic component
219 * inserted (if any), url }}
221 public String[][] createLinksFrom(SequenceI seq, String link)
223 ArrayList<String[]> urlSets = new ArrayList<String[]>();
224 ArrayList<String> uniques = new ArrayList<String>();
225 UrlLink urlLink = new UrlLink(link);
226 if (!urlLink.isValid())
228 System.err.println(urlLink.getInvalidMessage());
231 final String target = urlLink.getTarget(); // link.substring(0,
232 // link.indexOf("|"));
233 final String label = urlLink.getLabel();
234 if (seq != null && urlLink.isDynamic())
237 // collect matching db-refs
238 DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRef(),
241 // collect id string too
242 String id = seq.getName();
243 String descr = seq.getDescription();
244 if (descr != null && descr.length() < 1)
250 for (int r = 0; r < dbr.length; r++)
252 if (id != null && dbr[r].getAccessionId().equals(id))
254 // suppress duplicate link creation for the bare sequence ID
255 // string with this link
258 // create Bare ID link for this RUL
259 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
262 for (int u = 0; u < urls.length; u += 2)
264 String unq = urls[u] + "|" + urls[u + 1];
265 if (!uniques.contains(unq))
267 urlSets.add(new String[]
268 { target, label, urls[u], urls[u + 1] });
277 // create Bare ID link for this RUL
278 String[] urls = urlLink.makeUrls(id, true);
281 for (int u = 0; u < urls.length; u += 2)
283 String unq = urls[u] + "|" + urls[u + 1];
284 if (!uniques.contains(unq))
286 urlSets.add(new String[]
287 { target, label, urls[u], urls[u + 1] });
293 if (descr != null && urlLink.getRegexReplace() != null)
295 // create link for this URL from description only if regex matches
296 String[] urls = urlLink.makeUrls(descr, true);
299 for (int u = 0; u < urls.length; u += 2)
301 String unq = urls[u] + "|" + urls[u + 1];
302 if (!uniques.contains(unq))
304 urlSets.add(new String[]
305 { target, label, urls[u], urls[u + 1] });
315 String unq = label + "|" + urlLink.getUrl_prefix();
316 if (!uniques.contains(unq))
319 // Add a non-dynamic link
320 urlSets.add(new String[]
321 { target, label, null, urlLink.getUrl_prefix() });
325 return urlSets.toArray(new String[][]
329 public void createSequenceAnnotationReport(final StringBuffer tip,
330 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
333 createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
337 public void createSequenceAnnotationReport(final StringBuffer tip,
338 SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
339 boolean tableWrap, Hashtable minmax)
345 if (sequence.getDescription() != null)
347 tmp = sequence.getDescription();
348 tip.append("<br>" + tmp);
349 maxWidth = Math.max(maxWidth, tmp.length());
351 SequenceI ds = sequence;
352 while (ds.getDatasetSequence() != null)
354 ds = ds.getDatasetSequence();
356 DBRefEntry[] dbrefs = ds.getDBRef();
357 if (showDbRefs && dbrefs != null)
359 for (int i = 0; i < dbrefs.length; i++)
362 tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
364 maxWidth = Math.max(maxWidth, tmp.length());
368 // ADD NON POSITIONAL SEQUENCE INFO
369 SequenceFeature[] features = sequence.getSequenceFeatures();
370 if (showNpFeats && features != null)
372 for (int i = 0; i < features.length; i++)
374 if (features[i].begin == 0 && features[i].end == 0)
376 int sz = -tip.length();
377 List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
378 tfeat.add(features[i]);
379 appendFeatures(tip, 0, tfeat, minmax);
381 maxWidth = Math.max(maxWidth, sz);
386 if (tableWrap && maxWidth > 60)
388 tip.insert(0, "<table width=350 border=0><tr><td><i>");
389 tip.append("</i></td></tr></table>");