/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.io;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.io.gff.GffConstants;
import jalview.util.MessageManager;
import jalview.util.UrlLink;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* generate HTML reports for a sequence
*
* @author jimp
*/
public class SequenceAnnotationReport
{
private static final String COMMA = ",";
private static final String ELLIPSIS = "...";
private static final int MAX_REFS_PER_SOURCE = 4;
private static final int MAX_SOURCES = 40;
private static final String[][] PRIMARY_SOURCES = new String[][] {
DBRefSource.CODINGDBS, DBRefSource.DNACODINGDBS,
DBRefSource.PROTEINDBS };
final String linkImageURL;
/*
* Comparator to order DBRefEntry by Source + accession id (case-insensitive)
*/
private static Comparator comparator = new Comparator()
{
@Override
public int compare(DBRefEntry ref1, DBRefEntry ref2)
{
String s1 = ref1.getSource();
String s2 = ref2.getSource();
boolean s1Primary = isPrimarySource(s1);
boolean s2Primary = isPrimarySource(s2);
if (s1Primary && !s2Primary)
{
return -1;
}
if (!s1Primary && s2Primary)
{
return 1;
}
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;
}
private boolean isPrimarySource(String source)
{
for (String[] primary : PRIMARY_SOURCES)
{
for (String s : primary)
{
if (source.equals(s))
{
return true;
}
}
}
return false;
}
};
public SequenceAnnotationReport(String linkImageURL)
{
this.linkImageURL = linkImageURL;
}
/**
* Append text for the list of features to the tooltip
*
* @param sb
* @param rpos
* @param features
* @param minmax
*/
public void appendFeatures(final StringBuilder sb, int rpos,
List features, Map minmax)
{
if (features != null)
{
for (SequenceFeature feature : features)
{
appendFeature(sb, rpos, minmax, feature);
}
}
}
/**
* Appends the feature at rpos to the given buffer
*
* @param sb
* @param rpos
* @param minmax
* @param feature
*/
void appendFeature(final StringBuilder sb, int rpos,
Map minmax, SequenceFeature feature)
{
if (feature.isContactFeature())
{
if (feature.getBegin() == rpos || feature.getEnd() == rpos)
{
if (sb.length() > 6)
{
sb.append("
");
}
sb.append(feature.getType()).append(" ").append(feature.getBegin())
.append(":").append(feature.getEnd());
}
}
else
{
if (sb.length() > 6)
{
sb.append("
");
}
// TODO: remove this hack to display link only features
boolean linkOnly = feature.getValue("linkonly") != null;
if (!linkOnly)
{
sb.append(feature.getType()).append(" ");
if (rpos != 0)
{
// we are marking a positional feature
sb.append(feature.begin);
}
if (feature.begin != feature.end)
{
sb.append(" ").append(feature.end);
}
if (feature.getDescription() != null
&& !feature.description.equals(feature.getType()))
{
String tmpString = feature.getDescription();
String tmp2up = tmpString.toUpperCase();
int startTag = tmp2up.indexOf("");
if (startTag > -1)
{
tmpString = tmpString.substring(startTag + 6);
tmp2up = tmp2up.substring(startTag + 6);
}
int endTag = tmp2up.indexOf("");
if (endTag > -1)
{
tmpString = tmpString.substring(0, endTag);
tmp2up = tmp2up.substring(0, endTag);
}
endTag = tmp2up.indexOf("