<echo message="build - compiles all necessary files for Application" />
<echo message="makedist - compiles and places all necessary jar files into directory dist" />
<echo message="makefulldist - signs all jar files and builds jnlp file for full distribution" />
- <echo message=" this needs a keystore and key. Add -Dtimestamp to timestamp signed jars"/>
+ <echo message=" this needs a keystore and key."/>
+ <echo message=" Add -Dtimestamp to timestamp signed jars"/>
+ <echo message=" -Djalview.keyalg and -Djalview.keydig are SHA1/SHA1withRSA"/>
<echo message=" See docs/building.html for more information." />
<echo message="compileApplet - compiles all necessary files for Applet" />
<echo message="makeApplet - compiles, then packages and obfuscates the Applet" />
<!-- locally valid proxy for signing with external time server -->
<property name="proxyPort" value="80"/>
<property name="proxyHost" value="sqid"/>
+ <!-- key sign/digest algorithms -->
+ <property name="jalview.keyalg" value="SHA1withRSA" description="key algorithm for signing"/>
+ <property name="jalview.keydig" value="SHA1" description="algorithm for jar digest"/>
<!-- default TestNG groups to run -->
<property name="testng-groups" value="Functional" />
</target>
<target name="-jarsignwithtsa" depends="makedist,preparejnlp" if="timestamp">
- <signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="SHA1withRSA"
+ <signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="${jalview.keyalg}" digestalg="${jalview.keydig}"
tsaproxyhost="${proxyHost}" tsaproxyport="${proxyPort}" tsaurl="${jalview.tsaurl}">
<fileset dir="${packageDir}">
<include name="*.jar" />
</signjar>
</target>
<target name="-jarsignnotsa" depends="makedist,preparejnlp" unless="timestamp">
- <signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="SHA1withRSA">
+ <signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="${jalview.keyalg}" digestalg="${jalview.keydig}">
<fileset dir="${packageDir}">
<include name="*.jar" />
</fileset>
<p>
You will need the following (hopefully):<br>
<ul>
-<li>Java development kit (JDK1.6 is the recommended platform for developing with Jalview, although JDK1.7 seems to work too!).</li>
-<li>Ant (we think 1.5.4 is quite sufficient to use the simple build
-file supplied, and it seems to work with later versions e.g. 1.7).</li>
+<li>Java development kit (JDK1.8 is now the recommended platform for developing with Jalview.</li>
+<li>Ant (1.7 or later will be needed for some of the jarsigning tools).</li>
</ul>
With any luck, after setting your paths and JAVA_HOME correctly, you
just need to change to the Jalview directory and run ant (this works
-from JBuilder and eclipse too, but NetBeans is a bit trickier).
+from eclipse too, but NetBeans is a bit trickier).
<pre>
ant
</pre>
dist. But first you need to make your own key:
<p><strong>Making your own key</strong></p>
-<p>The ant 'makefulldist' target assumes that a keystore exists in a
-directory 'keys'. To make a key accessible using the default settings
-in the build.xml file then make the keys directory and add the
-jarsigner key with the following :
-</p>
-<pre>
-mkdir keys
-keytool -genkey -keystore keys/.keystore -keypass alignmentisfun
--storepass alignmentisfun -alias jalview
- (you will have to answer some personal questions here)
-ant makedist
- (should eventually generate a Jalview.jnlp file
- in ./dist along with a set of signed jars using the jalview
- key)
-</pre>
-
- <p>
+ <p>The ant 'makefulldist' target assumes that a keystore exists in
+ a directory 'keys'. To make a key accessible using the default
+ settings in the build.xml file then make the keys directory and add
+ the jarsigner key with the following :</p>
+ <pre>mkdir keys</pre>
+ <pre>keytool -genkey -keystore keys/.keystore -keypass alignmentisfun
+ -storepass alignmentisfun -sigalg SHA1withRSA -keyalg RSA -alias jalview</pre>
+ <em>(you will have to answer some personal questions here)</em>
+ <pre>ant makedist -DWebStartLocation="file://.pathtojalviewsource./dist" -Dapplication.codebase="*"</pre>
+ <p>This should eventually generate a jalview.jnlp file in ./dist
+ along with a set of signed jars using the jalview key). In order to
+ test locally via webstart you'll now need to add 'file:/' to your
+ java webstart security exception list. Then:</p>
+ <pre>javaws file://.pathtojalviewsource./dist/jalview.jnlp</pre>
+ <p>Please remember to remove that entry afterwards, since it will leave
+ your system vulnerable to malicious code.
+ </p>
+ <p>
<strong>Building the JalviewLite applet<br>
</strong> The JalviewLite applet is compiled using a subset of the packages in
the src directory (specifically: MCView, and jalview.{datamodel,
ST-MOTIF ac25a1
STARTGROUP uniprot
+<html><a href="http://pfam.xfam.org/family/PF00111">Pfam family</a></html> FER_CAPAA -1 0 0 Pfam
Iron-sulfur (2Fe-2S) FER_CAPAA -1 39 39 METAL
Iron-sulfur (2Fe-2S) FER_CAPAA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER_CAPAA -1 47 47 METAL
Iron-sulfur (2Fe-2S) FER_CAPAA -1 77 77 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_8</a></html> FER_CAPAA -1 8 83 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html> FER_CAPAA -1 8 83 Pfam
Ferredoxin_fold Status: True Positive FER_CAPAA -1 3 93 Cath
Iron-sulfur (2Fe-2S) FER_CAPAN -1 86 86 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 94 94 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 124 124 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_13</a></html> FER_CAPAN -1 55 130 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_13</a></html> FER_CAPAN -1 55 130 Pfam
Ferredoxin_fold Status: True Positive FER_CAPAN -1 45 140 Cath
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 86 86 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 94 94 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 124 124 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_13</a></html> FER1_SOLLC -1 55 130 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_13</a></html> FER1_SOLLC -1 55 130 Pfam
Ferredoxin_fold Status: True Positive FER1_SOLLC -1 45 140 Cath
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_13</a></html> Q93XJ9_SOLTU -1 55 130 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_13</a></html> Q93XJ9_SOLTU -1 55 130 Pfam
Ferredoxin_fold Status: True Positive Q93XJ9_SOLTU -1 45 140 Cath
Iron-sulfur (2Fe-2S) FER1_PEA -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER1_PEA -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER1_PEA -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER1_PEA -1 129 129 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_13</a></html> FER1_PEA -1 60 135 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html> FER1_PEA -1 60 135 Pfam
Ferredoxin_fold Status: True Positive FER1_PEA -1 50 145 Cath
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 63_13</a></html> Q7XA98_TRIPR -1 63 138 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 63_13</a></html> Q7XA98_TRIPR -1 63 138 Pfam
Ferredoxin_fold Status: True Positive Q7XA98_TRIPR -1 53 148 Cath
Iron-sulfur (2Fe-2S) FER1_MESCR -1 90 90 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 95 95 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 98 98 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 128 128 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 59_13</a></html> FER1_MESCR -1 59 134 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 59_13</a></html> FER1_MESCR -1 59 134 Pfam
Ferredoxin_fold Status: True Positive FER1_MESCR -1 49 144 Cath
Iron-sulfur (2Fe-2S) FER1_SPIOL -1 89 89 METAL
Iron-sulfur (2Fe-2S) FER1_SPIOL -1 94 94 METAL
Iron-sulfur (2Fe-2S) FER1_SPIOL -1 97 97 METAL
Iron-sulfur (2Fe-2S) FER1_SPIOL -1 127 127 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 58_13</a></html> FER1_SPIOL -1 58 133 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 58_13</a></html> FER1_SPIOL -1 58 133 Pfam
Ferredoxin_fold Status: True Positive FER1_SPIOL -1 48 143 Cath
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 39 39 METAL
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 47 47 METAL
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 77 77 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_8</a></html> FER3_RAPSA -1 8 83 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html> FER3_RAPSA -1 8 83 Pfam
Ferredoxin_fold Status: True Positive FER3_RAPSA -1 3 93 Cath
Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_8</a></html> FER_BRANA -1 8 83 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html> FER_BRANA -1 8 83 Pfam
Ferredoxin_fold Status: True Positive FER_BRANA -1 2 96 Cath
Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_13</a></html> FER2_ARATH -1 60 135 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html> FER2_ARATH -1 60 135 Pfam
Ferredoxin_fold Status: True Positive FER2_ARATH -1 50 145 Cath
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_11</a></html> Q93Z60_ARATH -1 60 118 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_11</a></html> Q93Z60_ARATH -1 60 118 Pfam
Ferredoxin_fold Status: True Positive Q93Z60_ARATH -1 52 118 Cath
Iron-sulfur (2Fe-2S) FER1_MAIZE -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER1_MAIZE -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER1_MAIZE -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER1_MAIZE -1 129 129 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_13</a></html> FER1_MAIZE -1 60 135 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html> FER1_MAIZE -1 60 135 Pfam
Ferredoxin_fold Status: True Positive FER1_MAIZE -1 50 145 Cath
-<html>Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 52_12</a></html> O80429_MAIZE -1 52 127 Pfam
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 52_12</a></html> O80429_MAIZE -1 52 127 Pfam
Ferredoxin_fold Status: True Positive O80429_MAIZE -1 42 137 Cath
ENDGROUP uniprot
Iron-sulfur (2Fe-2S) FER_CAPAA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER_CAPAA -1 47 47 METAL
Iron-sulfur (2Fe-2S) FER_CAPAA -1 77 77 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_83</a></html> FER_CAPAA -1 8 83 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER_CAPAA -1 8 83 Pfam
Chloroplast FER_CAPAN -1 1 47 TRANSIT
Iron-sulfur (2Fe-2S) FER_CAPAN -1 86 86 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 94 94 METAL
Iron-sulfur (2Fe-2S) FER_CAPAN -1 124 124 METAL
Phosphothreonine FER_CAPAN -1 136 136 MOD_RES
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_130</a></html> FER_CAPAN -1 55 130 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_130</a></html> FER_CAPAN -1 55 130 Pfam
Chloroplast FER1_SOLLC -1 1 47 TRANSIT
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 86 86 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 94 94 METAL
Iron-sulfur (2Fe-2S) FER1_SOLLC -1 124 124 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_130</a></html> FER1_SOLLC -1 55 130 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_130</a></html> FER1_SOLLC -1 55 130 Pfam
Evidence: EI4 Q93XJ9_SOLTU -1 1 48 SIGNAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 55_130</a></html> Q93XJ9_SOLTU -1 55 130 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 55_130</a></html> Q93XJ9_SOLTU -1 55 130 Pfam
Chloroplast FER1_PEA -1 1 52 TRANSIT
L -> I (in strain: cv. Onward) FER1_PEA -1 59 59 VARIANT
I -> L (in strain: cv. Onward) FER1_PEA -1 85 85 VARIANT
Iron-sulfur (2Fe-2S) FER1_PEA -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER1_PEA -1 129 129 METAL
YPTS -> PPPA (in Ref. 2) FER1_PEA -1 132 135 CONFLICT
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_135</a></html> FER1_PEA -1 60 135 Pfam
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 63_138</a></html> Q7XA98_TRIPR -1 63 138 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER1_PEA -1 60 135 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 63_138</a></html> Q7XA98_TRIPR -1 63 138 Pfam
Chloroplast FER1_MESCR -1 1 51 TRANSIT
Iron-sulfur (2Fe-2S) FER1_MESCR -1 90 90 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 95 95 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 98 98 METAL
Iron-sulfur (2Fe-2S) FER1_MESCR -1 128 128 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 59_134</a></html> FER1_MESCR -1 59 134 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 59_134</a></html> FER1_MESCR -1 59 134 Pfam
Chloroplast FER1_SPIOL -1 1 50 TRANSIT
STRAND FER1_SPIOL -1 52 59 STRAND
TURN FER1_SPIOL -1 60 61 TURN
STRAND FER1_SPIOL -1 130 133 STRAND
STRAND FER1_SPIOL -1 135 138 STRAND
HELIX FER1_SPIOL -1 142 144 HELIX
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 58_133</a></html> FER1_SPIOL -1 58 133 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 58_133</a></html> FER1_SPIOL -1 58 133 Pfam
I -> V FER3_RAPSA -1 8 8 VARIANT
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 39 39 METAL
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER3_RAPSA -1 77 77 METAL
R -> K FER3_RAPSA -1 91 91 VARIANT
M -> V FER3_RAPSA -1 95 95 VARIANT
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_83</a></html> FER3_RAPSA -1 8 83 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER3_RAPSA -1 8 83 Pfam
Chloroplast FER1_ARATH -1 1 52 TRANSIT
Iron-sulfur (2Fe-2S) FER1_ARATH -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER1_ARATH -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER1_ARATH -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER1_ARATH -1 129 129 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_135</a></html> FER1_ARATH -1 60 135 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER1_ARATH -1 60 135 Pfam
Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL
Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 8_83</a></html> FER_BRANA -1 8 83 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER_BRANA -1 8 83 Pfam
Chloroplast FER2_ARATH -1 1 52 TRANSIT
Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_135</a></html> FER2_ARATH -1 60 135 Pfam
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_118</a></html> Q93Z60_ARATH -1 60 118 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER2_ARATH -1 60 135 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_118</a></html> Q93Z60_ARATH -1 60 118 Pfam
Chloroplast FER1_MAIZE -1 1 52 TRANSIT
STRAND FER1_MAIZE -1 57 59 STRAND
STRAND FER1_MAIZE -1 72 74 STRAND
STRAND FER1_MAIZE -1 132 135 STRAND
STRAND FER1_MAIZE -1 137 141 STRAND
TURN FER1_MAIZE -1 142 142 TURN
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 60_135</a></html> FER1_MAIZE -1 60 135 Pfam
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.sanger.ac.uk/family/PF00111">Pfam 52_127</a></html> O80429_MAIZE -1 52 127 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER1_MAIZE -1 60 135 Pfam
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 52_127</a></html> O80429_MAIZE -1 52 127 Pfam
ENDGROUP uniprot
followed by a <em>description</em> for the row, which is shown in a
tooltip when the user mouses over the annotation row's label. Since
Jalview 2.7, the description field may also contain HTML tags (in
- the same way as a <a href="featuresFile.html">sequence feature's</a>
+ the same way as a <a href="featuresFormat.html">sequence feature's</a>
label), providing the text is enclosed in an <html/> tag.
<ul>
<em>Please note: URL links embedded in HTML descriptions are
the bottom of the list is rendered <em>below</em> a feature higher
up in the list.<br> <em><strong>You can change
the order of a feature by dragging it up and down the list with
- the mouse</strong></em>.
+ the mouse (not applet)</strong></em>.
</p>
<p>
The <strong><em>Optimise order</em></strong> button (currently only
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>mmCIF File Format</title>
+</head>
+<body>
+ <strong>mmCIF File Format</strong>
+ <p>The mmCIF file format (macromolecular Crystallographic
+ Information) was developed under the auspices of the International Union of Crystallography (IUCr) to extend the Crystallographic Information
+ File (CIF) data representation used for describing small molecule
+ structures and associated diffraction experiments.</p>
+ <strong>Merits of mmCIF file format</strong>
+ <ul>
+ <li>Large structures (containing >62 chains and/or 99999 ATOM
+ records) that cannot be fully represented in the PDB file format are
+ available in the PDB archive as single PDBx/mmCIF files.</li>
+ <li>PDBx/mmCIF file format provides richer data annotation</li>
+ <li>PDBx/mmCIF became the standard PDB archive format in 2014.
+ Since 2016 the PDB File Format is no longer being modified or
+ extended to support new content.
+ </li>
+ </ul>
+
+ <em>mmCIF file format support for importing 3D structure data from
+ flat file and EMBL-PDBe via mmCIF was added in Jalview 2.9.1</em>
+</body>
+</html>
\ No newline at end of file
retrieved by the <a href="seqfetch.html">Sequence Fetcher</a>, and
allows sequence features to be mapped directly from Uniprot das
sources to their coding region on EMBL sequence records.
+ </p>
+ <p>In Jalview 2.9.1 <a href="siftsmapping.html">SIFTS Mapping</a> was added as a better means for explicitly identifying the coordinates corresponding to a displayed sequence when viewing a PDB structure associated with a sequence </p>
</body>
</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>SIFTS Mapping</title>
+</head>
+<body>
+
+ <p><strong>SIFTS Mapping</strong></p>
+
+ <p>
+ SIFTS (Structure integration with function, taxonomy
+ and sequences) provides an up-to-date resource for residue-level
+ mapping between Uniprot and PDB entries. The information is updated and
+ released weekly simultaneously with the release of new PDB entries.
+ SIFTS Entries are published as XML files and made publicly available via an FTP
+ site hosted at the European Bioinformatics Institute.
+ </p>
+
+ <p>
+ At the point of viewing a PDB structure, Jalview downloads a SIFTS file
+ for the target entry and uses it to accurately map the sequence residues with the
+ structure residue. Prior to SIFTS integration, Jalview uses Needleman and Wunsch
+ Alignment algorithm to map sequence residues to structure residues, and that may not
+ always result to a correct mapping since it is computational determined.
+ </p>
+
+ <p>
+ The default method for 'Sequence ↔ Structure' mapping can be configured
+ in the Structure tab in the <strong>Tools → Preferences</strong> dialog box. When 'SIFTS'
+ is enabled as the default, all mappings between 'Sequence ↔ Structure' is
+ performed via SIFTS provided that there is a valid SIFTS entry for PDB structure. If no
+ valid SIFTS resource is available, then the 'Sequence ↔ Structure' mapping falls
+ back to Needleman and Wunsch Alignment algorithm.
+ </p>
+
+ <p>To verify the mapping method used, you can view the mapping output via the structure viewer menu <strong>File → View mapping.</strong> A sample mapping output can be seen in the screenshot below. The highlighted position shows the method used. </p>
+ <p>
+ <img src="sifts_mapping_output.png" align="left" alt="SIFTS mapping output" />
+ </p>
+
+ <p><em>SIFTS Mapping integration was added in Jalview 2.9.1</em></p>
+
+</body>
+</html>
\ No newline at end of file
<li>On selecting rows, columns or regions in one alignment, the
corresponding selection is made in the other</li>
<li>Sequence ordering in one alignment (using the cursor, or <strong><a
- href="../calculate/sorting.html"
+ href="../calculations/sorting.html"
>"Calculate→Sort")</a></strong> is also applied to the other
</li>
<li>Editing (gap insertion / deletion) in the protein alignment
panels.</li>
<li>Panel heights are adjusted dragging the divider between
them using the mouse</li>
- <li><a href="menus/alwview.html"><strong>"View→New
+ <li><a href="../menus/alwview.html"><strong>"View→New
View / Expand Views / Gather Views"</strong></a> behave as for a normal
alignment window, but always create new views as Split Frames</li>
</ul>
<li><strong>Bulk Uniprot retrieval</strong><br>
Firstly, switch the search target to Uniprot Id, then enter multiple IDs by separating them with a semi-colon.
- e.g. fila_human; mnt_human; mnt_mouse<br />Hitting Return or OK will automatically
+ e.g. fila_human; mnt_human; mnt_mouse.<br />Hitting Return or OK will automatically
fetch those IDs, like the default Sequence Fetcher interface.</li>
<li><strong>Advanced / Custom querying</strong>
<strong>Result pagination</strong>
</p>
The query results returned from the Uniprot server are paginated for performance optimisation.
- The button labelled <strong>' << '</strong> and <strong>' >> '</strong> can be used to navigate to the next or previous result page respectively.
+ The button labelled <strong>' << '</strong> and <strong>' >> '</strong> can be used to navigate to the next or previous result page respectively.
The page range is shown on the title bar of the Free Text Search interface. Jalview's pagination implementation supports multiple selection of entries across multiple pages.
</p>
<p>
+ <strong>Importing PDB Entries or files in mmCIF format</strong><br>
+ <a href="mmcif.html">mmCIF file format</a> provides an alternative means for
+ importing 3D structure data from flat file and EMBL-PDBe
+ web-service. To enable mmCIF as the default format for
+ importing PBD sequences from the PDB sequence fetcher, add or modify the
+ property
+ <code>DEFAULT_STRUCTURE_FORMAT=mmCIF</code> in Jalview properties file.
+ Once this is done, the steps followed in retrieving PDB format files above can
+ be followed to obtain the same data with mmCIF. <em>mmCIF format file support was added in Jalview 2.9.1.</em></p>
+
+
+
+ <p>
<strong>Associating a large number of PDB files to
sequences in an alignment</strong><br /> It is often the case when working
with structure alignments that you will have a directory of PDB
<td>Both</td>
<td>Cuts the (fully) selected sequences from the alignment. <!-- not yet in this version
This will not happen if only some
-columns are selected, you should use the <a href="features/regionHiding.html">Hide Regions feature</a> instead.-->
+columns are selected, you should use the <a href="features/hiddenRegions.html">Hide Regions feature</a> instead.-->
</td>
</tr>
<tr>
and sequence description to be entered. Press OK to accept
your edit. To save sequence descriptions, you must save in
Fasta, PIR or Jalview File format.</em></li>
- <li><a href="sqaddrefannot"><strong>Add
- Reference Annotations<br>
- </strong><em>When enabled, copies any available alignment
+ <li><strong>Add <a href="../features/annotation.html#seqannots">Reference Annotations</a></strong><br>
+ <em>When enabled, copies any available alignment
annotation for this sequence to the current view.</em></li>
<li><strong>Set as Reference</strong> or <strong>Unmark
as Reference</strong><br /> Sets or unsets the reference sequence for
<tr>
<td width="60" nowrap>
<div align="center">
- <strong><a name="Jalview.2.9.1">2.9.1</a><br /> <em>1/6/2016</em></strong>
+ <strong><a name="Jalview.2.9.1">2.9.1</a><br /> <em>14/6/2016</em></strong>
</div>
</td>
<td><em>General</em>
<div align="left">
<em>General</em>
<ul>
- <li></li>
+ <li><!-- JAL-2077 -->reinstate CTRL-click for opening pop-up menu on OSX</li>
</ul>
<em>Application</em>
<ul>
between different screens.</li>
<li>New preference items for sequence ID tooltip and
consensus annotation</li>
- <li>Client to submit sequences and IDs to <a
- href="webServices/index.html#envision2">Envision2</a>
- Workflows
- </li>
+ <li>Client to submit sequences and IDs to Envision2 Workflows</li>
<li><em>Vamsas Capabilities</em>
<ul>
<li>Improved VAMSAS synchronization (Jalview archive
Function, and Genetics</em> 43(2): 227-241. <a
href="http://www.ncbi.nlm.nih.gov/pubmed/12112692"
>PubMed</a> or available on the <a
- href="http://www.well.ox.ac.uk/~valdar/publications.html"
+ href="http://valdarlab.unc.edu/publications.html"
>Valdar Group publications page</a>), but the SMERFs score was
developed later and described by Manning et al. in 2008 (<a
href="http://www.biomedcentral.com/1471-2105/9/51"
>REST</a> web services exposing sequence alignment, analysis, and
secondary structure prediction programs. Originally, Jalview 2's
services were maintained by the Barton group at the University of
- Dundee, and ran programs on the Life Sciences High-performace
+ Dundee, and ran programs on the Life Sciences High-performance
Computing Cluster. With the advent of <a
href="http://www.compbio.dundee.ac.uk/JABAWS"
>JABAWS</a>, however, it is possible for anyone to host Jalview web
<em>Please Note:
<ul>
<li>The regular expressions supported by Jalview are those
- provided by the <a href="www.javaregex.com">Stevesoft
+ provided by the <a href="http://www.javaregex.com">Stevesoft
javaregex package</a>.
</li>
<li>Some characters must be escaped when specifying them as
<!--
History: Originally created from EMBL_common_V1.0
Updated on 24th April 2007 for WsDBFetch Service move to EMBL_Services_V1.1.xsd
+ Updated May 2016 for EMBL XML 1.2 JAL-2113 JAL-2114
+ see ftp://ftp.sra.ebi.ac.uk/meta/xsd/sra_1_5/ENA.embl.xsd
+ see http://www.ebi.ac.uk/ena/submit/data-formats
-->
<class name="jalview.datamodel.xdb.embl.EmblFile">
- <map-to xml="EMBL_Services"/>
+ <map-to xml="ROOT"/>
<field name="entries" type="jalview.datamodel.xdb.embl.EmblEntry" collection="vector">
<bind-xml name="entry"/>
</field>
-
<field name="errors" type="jalview.datamodel.xdb.embl.EmblError" collection="vector">
<bind-xml name="Error"/>
</field>
</class>
<class name="jalview.datamodel.xdb.embl.EmblEntry">
<field name="accession" type="string">
- <bind-xml location="accession" node="attribute"/>
+ <bind-xml name="accession" node="attribute"/>
</field>
- <!-- May 2015 changed from last-updated to match xml -->
- <field name="lastUpdated" type="string">
- <bind-xml location="lastUpdated" node="attribute"/>
+ <!--
+ in EMBL XML 1.2 sequence/@version became entry/version
+ entry/@version became entry/@entryVersion
+ -->
+ <field name="sequenceVersion" type="string">
+ <bind-xml name="version" node="attribute"/>
</field>
- <field name="version" type="string">
- <bind-xml location="version" node="attribute"/>
+ <field name="entryVersion" type="string">
+ <bind-xml name="entryVersion" node="attribute"/>
+ </field>
+ <field name="dataClass" type="string">
+ <bind-xml name="dataClass" node="attribute"/>
+ </field>
+ <field name="taxonomicDivision" type="string">
+ <bind-xml name="taxonomicDivision" node="attribute"/>
+ </field>
+ <field name="moleculeType" type="string">
+ <bind-xml name="moleculeType" node="attribute"/>
+ </field>
+ <field name="sequenceLength" type="string">
+ <bind-xml name="sequenceLength" node="attribute"/>
+ </field>
+ <field name="topology" type="string">
+ <bind-xml name="topology" node="attribute" location="type"/>
+ </field>
+ <field name="firstPublicDate" type="string">
+ <bind-xml name="firstPublic" node="attribute"/>
</field>
- <field name="rCreated" type="string">
- <bind-xml location="releaseCreated" node="attribute"/>
+ <field name="firstPublicRelease" type="string">
+ <bind-xml name="firstPublicRelease" node="attribute"/>
</field>
- <field name="rLastUpdated" type="string">
- <bind-xml location="releaseLastUpdated" node="attribute"/>
+ <field name="lastUpdatedDate" type="string">
+ <bind-xml name="lastUpdated" node="attribute"/>
</field>
- <field name="desc" type="string">
+ <field name="lastUpdatedRelease" type="string">
+ <bind-xml name="lastUpdatedRelease" node="attribute"/>
+ </field>
+ <field name="description" type="string">
<bind-xml name="description" node="element"/>
</field>
<field name="keywords" type="string" collection="vector">
<bind-xml name="feature"/>
</field>
<field name="dbRefs" type="jalview.datamodel.DBRefEntry" collection="vector">
- <bind-xml name="dbreference" />
+ <bind-xml name="xref" />
</field>
<field name="sequence" type="jalview.datamodel.xdb.embl.EmblSequence">
<bind-xml name="sequence"/>
</field>
</class>
<class name="jalview.datamodel.xdb.embl.EmblSequence">
- <field name="type" type="string">
- <bind-xml name="type" node="attribute" location="type"/>
- </field>
- <field name="version" type="string">
- <bind-xml name="version" node="attribute" location="version"/>
- </field>
<field name="sequence" type="string">
<bind-xml node="text"/>
</field>
<field name="name" type="string">
<bind-xml name="name" node="attribute"/>
</field>
+ <field name="location" type="string">
+ <bind-xml name="location" node="attribute"/>
+ </field>
<field name="dbRefs" type="jalview.datamodel.DBRefEntry" collection="vector">
- <bind-xml name="dbreference" node="element"/>
+ <bind-xml name="xref" node="element"/>
</field>
<field name="qualifiers" type="jalview.datamodel.xdb.embl.Qualifier" collection="vector">
<bind-xml name="qualifier"/>
</field>
- <field name="locations" type="jalview.datamodel.xdb.embl.EmblFeatureLocations" collection="vector">
- <bind-xml name="location"/>
- </field>
</class>
<class name="jalview.datamodel.DBRefEntry" verify-constructable="false">
<field name="accessionId" type="java.lang.String">
- <bind-xml name="primary" node="attribute"/>
+ <bind-xml name="id" node="attribute"/>
</field>
<field name="source" type="java.lang.String">
<bind-xml name="db" node="attribute"/>
</field>
<field name="version" type="string">
- <bind-xml name="secondary" node="attribute"/>
+ <bind-xml name="secondaryId" node="attribute"/>
</field>
</class>
<class name="jalview.datamodel.xdb.embl.Qualifier" verify-constructable="false">
<bind-xml name="value" node="element"/>
</field>
</class>
- <class name="jalview.datamodel.xdb.embl.EmblFeatureLocations">
- <field name="locationType" type="string">
- <bind-xml name="type" node="attribute"/>
- </field>
- <field name="locationComplement" type="boolean">
- <bind-xml name="complement" node="attribute"/>
- </field>
- <field name="locElements" type="jalview.datamodel.xdb.embl.EmblFeatureLocElement" collection="vector">
- <bind-xml name="locationElement"/>
- </field>
- </class>
- <class name="jalview.datamodel.xdb.embl.EmblFeatureLocElement">
- <field name="type" type="string">
- <bind-xml name="type" node="attribute"/>
- </field>
- <field name="accession" type="string">
- <bind-xml name="accession" node="attribute"/>
- </field>
- <field name="version" type="string">
- <bind-xml name="version" node="attribute"/>
- </field>
- <field name="complement" type="boolean">
- <bind-xml name="complement"/>
- </field>
- <field name="basePositions" type="jalview.datamodel.xdb.embl.BasePosition" collection="array">
- <bind-xml name="basePosition" node="element"/>
- </field>
- </class>
- <class name="jalview.datamodel.xdb.embl.BasePosition">
- <field name="type">
- <bind-xml name="type" node="attribute"/>
- </field>
- <field name="pos">
- <bind-xml node="text"/>
- </field>
- </class>
</mapping>
label.nw_mapping = Needleman & Wunsch Alignment
label.sifts_mapping = SIFTs Mapping
label.mapping_method = Sequence \u27f7 Structure mapping method
-label.mapping_method = Sequence \u27f7 Structure mapping method
-status.waiting_for_user_to_select_output_file = Waiting for user to select {0} file.
-status.cancelled_image_export_operation = Cancelled {0} export operation.
-info.error_creating_file = Error creating {0} file.
+status.waiting_for_user_to_select_output_file = Waiting for user to select {0} file
+status.cancelled_image_export_operation = Cancelled {0} export operation
+info.error_creating_file = Error creating {0} file
exception.outofmemory_loading_mmcif_file = Out of memory loading mmCIF File
-info.error_creating_file = Error creating {0} file.
label.run_groovy = Run Groovy console script
label.run_groovy_tip = Run the script in the Groovy console over this alignment
label.couldnt_run_groovy_script = Failed to run Groovy script
label.uniprot_sequence_fetcher = UniProt Sequence Fetcher
action.next_page= >>
action.prev_page= <<
-label.next_page_tooltop=Next Page
-label.prev_page_tooltop=Previous Page
+label.next_page_tooltip=Next Page
+label.prev_page_tooltip=Previous Page
exception.bad_request=Bad request. There is a problem with your input.
exception.service_not_available=Service not available. The server is being updated, try again later.
label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión.
label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada
label.groovy_console = Consola Groovy
-label.lineart = lineart
+label.lineart = Lineart
label.dont_ask_me_again = No volver a preguntar
label.select_eps_character_rendering_style = Seleccionar el carácter EPS como estilo de visualización
label.invert_selection = Invertir selección
{
EBIFetchClient ebi = new EBIFetchClient();
String query = "pdb:" + pdbentry.getId();
- pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "raw", ".xml")
+ pdbentry.setFile(ebi.fetchDataAsFile(query, "default", ".xml")
.getAbsolutePath());
if (pdbentry.getFile() != null)
return null;
}
- List<ChimeraModel> newModelList = getModelList();
- for (ChimeraModel newModel : newModelList)
+ // patch for Jalview - set model name in Chimera
+ // TODO: find a variant that works for sub-models
+ for (ChimeraModel newModel : getModelList())
{
if (!modelList.contains(newModel))
{
"setattr M name " + modelName + " #"
+ newModel.getModelNumber(), false);
modelList.add(newModel);
-
}
}
// assign color and residues to open models
for (ChimeraModel chimeraModel : modelList)
{
- // // patch for Jalview - set model name in Chimera
- // // TODO: find a variant that works for sub-models
// get model color
Color modelColor = getModelColor(chimeraModel);
if (modelColor != null)
*/
public List<String> sendChimeraCommand(String command, boolean reply)
{
- // System.out.println("chimeradebug>> " + command);
+ // System.out.println("chimeradebug>> " + command);
if (!isChimeraLaunched() || command == null
|| "".equals(command.trim()))
{
{
AlignmentI copy = new Alignment(new Alignment(seqs));
+ /*
+ * add mappings between sequences to the new alignment
+ */
+ AlignedCodonFrame mappings = new AlignedCodonFrame();
+ copy.addCodonFrame(mappings);
+ for (int i = 0; i < copy.getHeight(); i++)
+ {
+ SequenceI from = seqs[i];
+ SequenceI to = copy.getSequenceAt(i);
+ if (to.getDatasetSequence() != null)
+ {
+ to = to.getDatasetSequence();
+ }
+ int start = from.getStart();
+ int end = from.getEnd();
+ MapList map = new MapList(new int[] { start, end }, new int[] {
+ start, end }, 1, 1);
+ mappings.addMap(to, from, map);
+ }
+
SequenceIdMatcher matcher = new SequenceIdMatcher(seqs);
if (xrefs != null)
{
c = '-';
}
- if (!canonicaliseAa && 'a' <= c && c <= 'z')
- {
- c -= (32); // 32 = 'a' - 'A'
- }
+ c = toUpperCase(c);
}
values[c]++;
}
}
else
{
+ c = toUpperCase(c);
nres++;
if (nres == 1)
}
/**
+ * Returns the upper-cased character if between 'a' and 'z', else the
+ * unchanged value
+ *
+ * @param c
+ * @return
+ */
+ char toUpperCase(char c)
+ {
+ if ('a' <= c && c <= 'z')
+ {
+ c -= (32); // 32 = 'a' - 'A'
+ }
+ return c;
+ }
+
+ /**
* Calculates the conservation sequence
*
* @param consflag
{
if (s != null)
{
- id = new String(s);
+ id = new String(s.toLowerCase());
}
else
{
}
if (s instanceof SeqIdName)
{
- return this.equals(((SeqIdName) s).id);
+ return this.stringequals(((SeqIdName) s).id);
}
else
{
if (s instanceof String)
{
- return this.equals((String) s);
+ return this.stringequals(((String) s).toLowerCase());
}
}
* @param s
* @return boolean
*/
- public boolean equals(String s)
+ private boolean stringequals(String s)
{
if (id.length() > s.length())
{
* This method returns the visible alignment as text, as seen on the GUI, ie
* if columns are hidden they will not be returned in the result. Use this for
* calculating trees, PCA, redundancy etc on views which contain hidden
+ * columns. This method doesn't exclude hidden sequences from the output.
+ *
+ * @param selectedRegionOnly
+ * - determines if only the selected region or entire alignment is
+ * exported
+ * @return String[]
+ */
+ String[] getViewAsString(boolean selectedRegionOnly);
+
+ /**
+ * This method returns the visible alignment as text, as seen on the GUI, ie
+ * if columns are hidden they will not be returned in the result. Use this for
+ * calculating trees, PCA, redundancy etc on views which contain hidden
* columns.
*
+ * @param selectedRegionOnly
+ * - determines if only the selected region or entire alignment is
+ * exported
+ * @param isExportHiddenSeqs
+ * - determines if hidden sequences would be exported or not.
+ *
* @return String[]
*/
- String[] getViewAsString(boolean selectedRegionOnly);
+ String[] getViewAsString(boolean selectedRegionOnly, boolean isExportHiddenSeqs);
void setSelectionGroup(SequenceGroup sg);
*/
void setFollowHighlight(boolean b);
+
public void applyFeaturesStyle(FeatureSettingsModelI featureSettings);
}
import jalview.datamodel.Mapping;
+//JBPComment: this is a datamodel API - so it should be in datamodel (it's a peer of SequenceI)
public interface DBRefEntryI
{
*/
public int getEndRes();
+ /**
+ * access a mapping, if present that can be used to map positions from the
+ * associated dataset sequence to the DBRef's sequence frame.
+ *
+ * @return null or a valid mapping.
+ */
public Mapping getMap();
+
+ /**
+ * Answers true if this object is either equivalent to, or can be 'improved'
+ * by, the given entry. Specifically, answers true if
+ * <ul>
+ * <li>source and accession are identical</li>
+ * <li>version is identical, or this version is of the format "someSource:0",
+ * in which case the version for the other entry replaces it</li>
+ * <li>mappings are not compared but if this entry has no mapping, replace
+ * with that for the other entry</li>
+ * </ul>
+ *
+ * @param otherEntry
+ * @return
+ */
+ public boolean updateFrom(DBRefEntryI otherEntry);
}
import java.util.HashMap;
import java.util.HashSet;
+// JBPComment: this isn't a top-level Jalview API - should be in its own package api
+
public interface SiftsClientI
{
/**
return row;
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation();
boolean resizePanel = false;
+ @Override
public void mouseMoved(MouseEvent evt)
{
resizePanel = evt.getY() < 10 && evt.getX() < 14;
dragCancelled = true;
}
+ @Override
public void mouseDragged(MouseEvent evt)
{
if (dragCancelled)
}
}
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
+ @Override
public void mouseReleased(MouseEvent evt)
{
if (!resizePanel && !dragCancelled)
ap.annotationPanel.repaint();
}
+ @Override
public void mouseEntered(MouseEvent evt)
{
if (evt.getY() < 10 && evt.getX() < 14)
}
}
+ @Override
public void mouseExited(MouseEvent evt)
{
dragCancelled = false;
repaint();
}
+ @Override
public void mousePressed(MouseEvent evt)
{
oldY = evt.getY();
final AlignmentAnnotation aaa = aa[selectedRow];
cbmi.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
if (aaa.groupRef != null)
aa[selectedRow].groupRef.isShowConsensusHistogram());
chist.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
aa[selectedRow].groupRef.isShowSequenceLogo());
cprofl.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
aa[selectedRow].groupRef.isNormaliseSequenceLogo());
cprofn.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
av.isShowConsensusHistogram());
chist.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
av.isShowSequenceLogo());
cprof.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
av.isNormaliseSequenceLogo());
cprofn.addItemListener(new ItemListener()
{
+ @Override
public void itemStateChanged(ItemEvent e)
{
// TODO: pass on reference
// todo: make the ap scroll to the selection - not necessary, first
// click highlights/scrolls, second selects
ap.seqPanel.ap.idPanel.highlightSearchResults(null);
- ap.av.setSelectionGroup(// new SequenceGroup(
- aa[selectedRow].groupRef); // );
- ap.av.sendSelection();
+ // process modifiers
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg == null
+ || sg == aa[selectedRow].groupRef
+ || !(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
+ {
+ if (jalview.util.Platform.isControlDown(evt)
+ || evt.isShiftDown())
+ {
+ // clone a new selection group from the associated group
+ ap.av.setSelectionGroup(new SequenceGroup(
+ aa[selectedRow].groupRef));
+ }
+ else
+ {
+ // set selection to the associated group so it can be edited
+ ap.av.setSelectionGroup(aa[selectedRow].groupRef);
+ }
+ }
+ else
+ {
+ // modify current selection with associated group
+ int remainToAdd = aa[selectedRow].groupRef.getSize();
+ for (SequenceI sgs : aa[selectedRow].groupRef.getSequences())
+ {
+ if (jalview.util.Platform.isControlDown(evt))
+ {
+ sg.addOrRemove(sgs, --remainToAdd == 0);
+ }
+ else
+ {
+ // notionally, we should also add intermediate sequences from
+ // last added sequence ?
+ sg.addSequence(sgs, --remainToAdd == 0);
+ }
+ }
+ }
ap.paintAlignment(false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
+ ap.av.sendSelection();
}
else
{
// we make a copy rather than edit the current selection if no
// modifiers pressed
// see Enhancement JAL-1557
- if (!(evt.isControlDown() || evt.isShiftDown()))
+ if (!(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
{
sg = new SequenceGroup(sg);
sg.clear();
}
else
{
- if (evt.isControlDown())
+ if (jalview.util.Platform.isControlDown(evt))
{
sg.addOrRemove(aa[selectedRow].sequenceRef, true);
}
}
}
+ @Override
public void update(Graphics g)
{
paint(g);
}
+ @Override
public void paint(Graphics g)
{
int w = getSize().width;
Tooltip tooltip;
+ @Override
public void mouseMoved(MouseEvent e)
{
int seq = alignPanel.seqPanel.findSeq(e);
tooltiptext = null;
}
+ @Override
public void mouseDragged(MouseEvent e)
{
mouseDragging = true;
alignPanel.paintAlignment(false);
}
+ @Override
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() < 2)
}
}
+ @Override
public void mouseEntered(MouseEvent e)
{
if (scrollThread != null)
}
}
+ @Override
public void mouseExited(MouseEvent e)
{
if (av.getWrapAlignment())
}
}
+ @Override
public void mousePressed(MouseEvent e)
{
if (e.getClickCount() > 1)
}
if ((av.getSelectionGroup() == null)
- || ((!e.isControlDown() && !e.isShiftDown()) && av
+ || ((!jalview.util.Platform.isControlDown(e) && !e
+ .isShiftDown()) && av
.getSelectionGroup() != null))
{
av.setSelectionGroup(new SequenceGroup());
}
+ @Override
public void mouseReleased(MouseEvent e)
{
if (scrollThread != null)
running = false;
}
+ @Override
public void run()
{
running = true;
// do we want to thread this ? (contention with seqsel and colsel locks, I
// suspect)
- // rules are: colsel is copied if there is a real intersection between
- // sequence selection
- boolean repaint = false, copycolsel = true;
+ /*
+ * only copy colsel if there is a real intersection between
+ * sequence selection and this panel's alignment
+ */
+ boolean repaint = false;
+ boolean copycolsel = false;
if (av.getSelectionGroup() == null || !av.isSelectionGroupChanged(true))
{
SequenceGroup sgroup = null;
}
sgroup = seqsel.intersect(av.getAlignment(),
(av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- && (colsel == null || colsel.isEmpty()))
+ if ((sgroup != null && sgroup.getSize() > 0))
{
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
+ copycolsel = true;
}
}
if (sgroup != null && sgroup.getSize() > 0)
ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
av);
av.setColumnSelection(cs);
- av.isColSelChanged(true);
ap.scalePanelHolder.repaint();
ap.repaint();
System.out
.println("Jalview Version: " + codeVersion + codeInstallation);
- Pdb.setCurrentDefaultFomart(jalview.bin.Cache.getDefault(
+ Pdb.setCurrentDefaultFormat(jalview.bin.Cache.getDefault(
"DEFAULT_STRUCTURE_FORMAT", DEFAULT_STRUCTURE_FORMAT));
// jnlpVersion will be null if we're using InstallAnywhere
// Dont do this check if running in headless mode
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
}
}
+ /**
+ * adds a set of mappings (while ignoring any duplicates)
+ */
+ @Override
+ public void addCodonFrames(Iterable<AlignedCodonFrame> codons)
+ {
+ if (codons != null)
+ {
+ Iterator<AlignedCodonFrame> it = codons.iterator();
+ while (it.hasNext())
+ {
+ addCodonFrame(it.next());
+ }
+ }
+ }
+
/*
* (non-Javadoc)
*
void addCodonFrame(AlignedCodonFrame codons);
/**
+ * add a set of aligned codons mappings for this alignment, apart from any
+ * duplicates which are ignored
+ *
+ * @param codons
+ */
+ void addCodonFrames(Iterable<AlignedCodonFrame> codons);
+
+ /**
* remove a particular codon frame reference from this alignment
*
* @param codons
import java.util.Vector;
/**
- * NOTE: Columns are zero based.
+ * Data class holding the selected columns and hidden column ranges for a view.
+ * Ranges are base 1.
*/
public class ColumnSelection
{
+ /**
+ * A class to hold an efficient representation of selected columns
+ */
private class IntList
{
/*
}
return rlist;
}
+
+ @Override
+ public int hashCode()
+ {
+ // TODO Auto-generated method stub
+ return selected.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof IntList)
+ {
+ return ((IntList) obj).selected.equals(selected);
+ }
+ return false;
+ }
}
- IntList selected = new IntList();
+ IntList selection = new IntList();
/*
* list of hidden column [start, end] ranges; the list is maintained in
*/
public void addElement(int col)
{
- selected.add(col);
+ selection.add(col);
}
/**
*/
public void clear()
{
- selected.clear();
+ selection.clear();
}
/**
*/
public void removeElement(int col)
{
- selected.remove(col);
+ selection.remove(col);
}
/**
for (int i = start; i < end; i++)
{
colInt = new Integer(i);
- if (selected.contains(colInt))
+ if (selection.contains(colInt))
{
- selected.remove(colInt);
+ selection.remove(colInt);
}
}
}
*/
public List<Integer> getSelected()
{
- return selected.getList();
+ return selection.getList();
}
/**
*/
public List<int[]> getSelectedRanges()
{
- return selected.getRanges();
+ return selection.getRanges();
}
/**
*/
public boolean contains(int col)
{
- return (col > -1) ? selected.isSelected(col) : false;
+ return (col > -1) ? selection.isSelected(col) : false;
}
/**
*/
public boolean isEmpty()
{
- return selected == null || selected.isEmpty();
+ return selection == null || selection.isEmpty();
}
/**
*/
public int getMax()
{
- if (selected.isEmpty())
+ if (selection.isEmpty())
{
return -1;
}
- return selected.getMaxColumn();
+ return selection.getMaxColumn();
}
/**
*/
public int getMin()
{
- if (selected.isEmpty())
+ if (selection.isEmpty())
{
return 1000000000;
}
- return selected.getMinColumn();
+ return selection.getMinColumn();
}
/**
public List<int[]> compensateForEdit(int start, int change)
{
List<int[]> deletedHiddenColumns = null;
- selected.compensateForEdits(start, change);
+ selection.compensateForEdits(start, change);
if (hiddenColumns != null)
{
private void compensateForDelEdits(int start, int change)
{
- selected.compensateForEdits(start, change);
+ selection.compensateForEdits(start, change);
if (hiddenColumns != null)
{
hiddenColumns = null;
}
}
- if (selected != null && selected.size() > 0)
+ if (selection != null && selection.size() > 0)
{
- selected.pruneColumnList(shifts);
- if (selected != null && selected.size() == 0)
+ selection.pruneColumnList(shifts);
+ if (selection != null && selection.size() == 0)
{
- selected = null;
+ selection = null;
}
}
// and shift the rest.
public void hideSelectedColumns()
{
- synchronized (selected)
+ synchronized (selection)
{
- for (int[] selregions : selected.getRanges())
+ for (int[] selregions : selection.getRanges())
{
hideColumns(selregions[0], selregions[1]);
}
- selected.clear();
+ selection.clear();
}
}
{
if (copy != null)
{
- if (copy.selected != null)
+ if (copy.selection != null)
{
- selected = new IntList();
- for (int i = 0, j = copy.selected.size(); i < j; i++)
+ selection = new IntList();
+ for (int i = 0, j = copy.selection.size(); i < j; i++)
{
- selected.add(copy.selected.elementAt(i));
+ selection.add(copy.selection.elementAt(i));
}
}
if (copy.hiddenColumns != null)
{
if (hiddenColumns != null && isVisible(col.intValue()))
{
- selected.add(col);
+ selection.add(col);
}
}
}
*/
public void setElementsFrom(ColumnSelection colsel)
{
- selected = new IntList();
- if (colsel.selected != null && colsel.selected.size() > 0)
+ selection = new IntList();
+ if (colsel.selection != null && colsel.selection.size() > 0)
{
if (hiddenColumns != null && hiddenColumns.size() > 0)
{
*/
public boolean hasSelectedColumns()
{
- return (selected != null && selected.size() > 0);
+ return (selection != null && selection.size() > 0);
}
/**
return false;
}
+ /**
+ * Returns a hashCode built from selected columns and hidden column ranges
+ */
+ @Override
+ public int hashCode()
+ {
+ int hashCode = selection.hashCode();
+ if (hiddenColumns != null)
+ {
+ for (int[] hidden : hiddenColumns)
+ {
+ hashCode = 31 * hashCode + hidden[0];
+ hashCode = 31 * hashCode + hidden[1];
+ }
+ }
+ return hashCode;
+ }
+
+ /**
+ * Answers true if comparing to a ColumnSelection with the same selected
+ * columns and hidden columns, else false
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ColumnSelection))
+ {
+ return false;
+ }
+ ColumnSelection that = (ColumnSelection) obj;
+
+ /*
+ * check columns selected are either both null, or match
+ */
+ if (this.selection == null)
+ {
+ if (that.selection != null)
+ {
+ return false;
+ }
+ }
+ if (!this.selection.equals(that.selection))
+ {
+ return false;
+ }
+
+ /*
+ * check hidden columns are either both null, or match
+ */
+ if (this.hiddenColumns == null)
+ {
+ return (that.hiddenColumns == null);
+ }
+ if (that.hiddenColumns == null
+ || that.hiddenColumns.size() != this.hiddenColumns.size())
+ {
+ return false;
+ }
+ int i = 0;
+ for (int[] thisRange : hiddenColumns)
+ {
+ int[] thatRange = that.hiddenColumns.get(i++);
+ if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
}
}
/**
+ * Answers true if this object is either equivalent to, or can be 'improved'
+ * by, the given entry. Specifically, answers true if
+ * <ul>
+ * <li>source and accession are identical (ignoring case)</li>
+ * <li>version is identical (ignoring case), or this version is of the format
+ * "someSource:0", in which case the version for the other entry replaces it</li>
+ * <li>mappings are not compared but if this entry has no mapping, replace
+ * with that for the other entry</li>
+ * </ul>
+ *
+ * @param other
+ * @return
+ */
+ @Override
+ public boolean updateFrom(DBRefEntryI other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+ if (other == this)
+ {
+ return true;
+ }
+
+ /*
+ * source must either match or be both null
+ */
+ String otherSource = other.getSource();
+ if ((source == null && otherSource != null)
+ || (source != null && otherSource == null)
+ || (source != null && !source.equalsIgnoreCase(otherSource)))
+ {
+ return false;
+ }
+
+ /*
+ * accession id must either match or be both null
+ */
+ String otherAccession = other.getAccessionId();
+ if ((accessionId == null && otherAccession != null)
+ || (accessionId != null && otherAccession == null)
+ || (accessionId != null && !accessionId.equalsIgnoreCase(otherAccession)))
+ {
+ return false;
+ }
+
+ /*
+ * if my version is null, "0" or "source:0" then replace with other version,
+ * otherwise the versions have to match
+ */
+ String otherVersion = other.getVersion();
+ if ((version == null || version.equals("0") || version.endsWith(":0"))
+ && otherVersion != null)
+ {
+ setVersion(otherVersion);
+ }
+ else
+ {
+ if (!version.equalsIgnoreCase(otherVersion))
+ {
+ return false;
+ }
+ }
+
+ /*
+ * if I have no mapping, take that of the other dbref
+ */
+ if (map == null)
+ {
+ setMap(other.getMap());
+ }
+ return true;
+ }
+
+ /**
* test for similar DBRef attributes, except for the map object.
*
* @param entry
@Override
public boolean equalRef(DBRefEntryI entry)
{
+ // TODO is this method and equals() not needed?
if (entry == null)
{
return false;
*/
public class FeatureProperties
{
-
- private static final String EMBL_CODING_FEATURE = "CDS";
+ public static final String EMBL_CODING_FEATURE = "CDS";
public static final String EXONPOS = "exon number";
dbrefs = new DBRefEntry[0];
}
- int i, iSize = dbrefs.length;
-
- for (i = 0; i < iSize; i++)
+ for (DBRefEntryI dbr : dbrefs)
{
- if (dbrefs[i].equalRef(entry))
+ if (dbr.updateFrom(entry))
{
- if (entry.getMap() != null)
- {
- if (dbrefs[i].getMap() == null)
- {
- // overwrite with 'superior' entry that contains a mapping.
- dbrefs[i] = entry;
- }
- }
+ /*
+ * found a dbref that either matched, or could be
+ * updated from, the new entry - no need to add it
+ */
return;
}
}
- DBRefEntry[] temp = new DBRefEntry[iSize + 1];
- System.arraycopy(dbrefs, 0, temp, 0, iSize);
+ /*
+ * extend the array to make room for one more
+ */
+ // TODO use an ArrayList instead
+ int j = dbrefs.length;
+ DBRefEntry[] temp = new DBRefEntry[j + 1];
+ System.arraycopy(dbrefs, 0, temp, 0, j);
temp[temp.length - 1] = entry;
dbrefs = temp;
// private key for Phase designed not to conflict with real GFF data
private static final String PHASE = "!Phase";
+ // private key for ENA location designed not to conflict with real GFF data
+ private static final String LOCATION = "!Location";
+
/*
* ATTRIBUTES is reserved for the GFF 'column 9' data, formatted as
* name1=value1;name2=value2,value3;...etc
public String description;
+ /*
+ * a map of key-value pairs; may be populated from GFF 'column 9' data,
+ * other data sources (e.g. GenBank file), or programmatically
+ */
public Map<String, Object> otherDetails;
public Vector<String> links;
}
/**
+ * Sets the 'raw' ENA format location specifier e.g. join(12..45,89..121)
+ *
+ * @param loc
+ */
+ public void setEnaLocation(String loc)
+ {
+ setValue(LOCATION, loc);
+ }
+
+ /**
+ * Gets the 'raw' ENA format location specifier e.g. join(12..45,89..121)
+ *
+ * @param loc
+ */
+ public String getEnaLocation()
+ {
+ return (String) getValue(LOCATION);
+ }
+
+ /**
* Readable representation, for debug only, not guaranteed not to change
* between versions
*/
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.datamodel.xdb.embl;
-
-/**
- * Data model for a feature/location/locationElement/basePosition read from an
- * EMBL query reply
- *
- * @see embl_mapping.xml
- */
-public class BasePosition
-{
- String type;
-
- String pos;
-
- /**
- * @return the pos
- */
- public String getPos()
- {
- return pos;
- }
-
- /**
- * @param pos
- * the pos to set
- */
- public void setPos(String pos)
- {
- this.pos = pos;
- }
-
- /**
- * @return the type
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * @param type
- * the type to set
- */
- public void setType(String type)
- {
- this.type = type;
- }
-}
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
+import jalview.util.DnaUtils;
import jalview.util.MapList;
import jalview.util.MappingUtils;
import jalview.util.StringUtils;
String accession;
- String version;
+ String entryVersion;
- String taxDivision;
+ String sequenceVersion;
- String desc;
+ String dataClass;
- String rCreated;
+ String moleculeType;
- String rLastUpdated;
+ String topology;
- String lastUpdated;
+ String sequenceLength;
+
+ String taxonomicDivision;
+
+ String description;
+
+ String firstPublicDate;
+
+ String firstPublicRelease;
+
+ String lastUpdatedDate;
+
+ String lastUpdatedRelease;
Vector<String> keywords;
}
/**
- * @return the desc
- */
- public String getDesc()
- {
- return desc;
- }
-
- /**
- * @param desc
- * the desc to set
- */
- public void setDesc(String desc)
- {
- this.desc = desc;
- }
-
- /**
* @return the features
*/
public Vector<EmblFeature> getFeatures()
}
/**
- * @return the lastUpdated
- */
- public String getLastUpdated()
- {
- return lastUpdated;
- }
-
- /**
- * @param lastUpdated
- * the lastUpdated to set
- */
- public void setLastUpdated(String lastUpdated)
- {
- this.lastUpdated = lastUpdated;
- }
-
- /**
- * @return the releaseCreated
- */
- public String getRCreated()
- {
- return rCreated;
- }
-
- /**
- * @param releaseCreated
- * the releaseCreated to set
- */
- public void setRCreated(String releaseCreated)
- {
- this.rCreated = releaseCreated;
- }
-
- /**
- * @return the releaseLastUpdated
- */
- public String getRLastUpdated()
- {
- return rLastUpdated;
- }
-
- /**
- * @param releaseLastUpdated
- * the releaseLastUpdated to set
- */
- public void setRLastUpdated(String releaseLastUpdated)
- {
- this.rLastUpdated = releaseLastUpdated;
- }
-
- /**
* @return the sequence
*/
public EmblSequence getSequence()
}
/**
- * @return the taxDivision
- */
- public String getTaxDivision()
- {
- return taxDivision;
- }
-
- /**
- * @param taxDivision
- * the taxDivision to set
- */
- public void setTaxDivision(String taxDivision)
- {
- this.taxDivision = taxDivision;
- }
-
- /**
- * @return the version
- */
- public String getVersion()
- {
- return version;
- }
-
- /**
- * @param version
- * the version to set
- */
- public void setVersion(String version)
- {
- this.version = version;
- }
-
- /**
* Recover annotated sequences from EMBL file
*
* @param sourceDb
{
SequenceI dna = new Sequence(sourceDb + "|" + accession,
sequence.getSequence());
- dna.setDescription(desc);
- DBRefEntry retrievedref = new DBRefEntry(sourceDb, version, accession);
+ dna.setDescription(description);
+ DBRefEntry retrievedref = new DBRefEntry(sourceDb,
+ getSequenceVersion(), accession);
dna.addDBRef(retrievedref);
// add map to indicate the sequence is a valid coordinate frame for the
// dbref
DBRefEntry pcdnaref = new DBRefEntry();
pcdnaref.setAccessionId(prid);
pcdnaref.setSource(DBRefSource.EMBLCDS);
- pcdnaref.setVersion(getVersion()); // same as parent EMBL version.
+ pcdnaref.setVersion(getSequenceVersion()); // same as parent EMBL
+ // version.
MapList mp = new MapList(new int[] { 1, prseq.length() },
new int[] { 1 + (codonStart - 1),
(codonStart - 1) + 3 * prseq.length() }, 1, 3);
SequenceFeature sf = makeCdsFeature(exon, xint, prname, prid, vals,
codonStart);
sf.setType(feature.getName()); // "CDS"
+ sf.setEnaLocation(feature.getLocation());
sf.setFeatureGroup(sourceDb);
dna.addSequenceFeature(sf);
}
if (map != null)
{
Mapping pmap = new Mapping(dna, map.getMap().getInverse());
- pref = new DBRefEntry(sourceDb, getVersion(),
+ pref = new DBRefEntry(sourceDb, getSequenceVersion(),
this.getAccession());
pref.setMap(pmap);
if (map.getTo() != null)
protEMBLCDS = new DBRefEntry();
protEMBLCDS.setAccessionId(prid);
protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct);
- protEMBLCDS.setVersion(getVersion());
+ protEMBLCDS.setVersion(getSequenceVersion());
protEMBLCDS
.setMap(new Mapping(product, map.getMap().getInverse()));
}
*/
protected int[] getCdsRanges(EmblFeature feature)
{
- if (feature.locations == null)
+ if (feature.location == null)
{
return new int[] {};
}
- int cdsBoundaryCount = 0; // count of all start/stop locations
- int[][] cdsLocations = new int[feature.locations.size()][];
- int locationNumber = 0;
- for (EmblFeatureLocations loc : feature.locations)
- {
- int[] locationRanges = loc.getElementRanges(accession);
- cdsLocations[locationNumber++] = locationRanges;
- cdsBoundaryCount += locationRanges.length;
- }
- int[] cdsRanges = new int[cdsBoundaryCount];
- int copyTo = 0;
- for (int[] ranges : cdsLocations)
+ List<int[]> ranges = DnaUtils.parseLocation(feature.location);
+ return ranges == null ? new int[] {} : listToArray(ranges);
+ }
+
+ /**
+ * Converts a list of [start, end] ranges to a single array of [start, end,
+ * start, end ...]
+ *
+ * @param ranges
+ * @return
+ */
+ int[] listToArray(List<int[]> ranges)
+ {
+ int[] result = new int[ranges.size() * 2];
+ int i = 0;
+ for (int[] range : ranges)
{
- System.arraycopy(ranges, 0, cdsRanges, copyTo, ranges.length);
- copyTo += ranges.length;
+ result[i++] = range[0];
+ result[i++] = range[1];
}
- return cdsRanges;
-
+ return result;
}
/**
}
return exon;
}
+
+ public String getSequenceVersion()
+ {
+ return sequenceVersion;
+ }
+
+ public void setSequenceVersion(String sequenceVersion)
+ {
+ this.sequenceVersion = sequenceVersion;
+ }
+
+ public String getSequenceLength()
+ {
+ return sequenceLength;
+ }
+
+ public void setSequenceLength(String sequenceLength)
+ {
+ this.sequenceLength = sequenceLength;
+ }
+
+ public String getEntryVersion()
+ {
+ return entryVersion;
+ }
+
+ public void setEntryVersion(String entryVersion)
+ {
+ this.entryVersion = entryVersion;
+ }
+
+ public String getMoleculeType()
+ {
+ return moleculeType;
+ }
+
+ public void setMoleculeType(String moleculeType)
+ {
+ this.moleculeType = moleculeType;
+ }
+
+ public String getTopology()
+ {
+ return topology;
+ }
+
+ public void setTopology(String topology)
+ {
+ this.topology = topology;
+ }
+
+ public String getTaxonomicDivision()
+ {
+ return taxonomicDivision;
+ }
+
+ public void setTaxonomicDivision(String taxonomicDivision)
+ {
+ this.taxonomicDivision = taxonomicDivision;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ public String getFirstPublicDate()
+ {
+ return firstPublicDate;
+ }
+
+ public void setFirstPublicDate(String firstPublicDate)
+ {
+ this.firstPublicDate = firstPublicDate;
+ }
+
+ public String getFirstPublicRelease()
+ {
+ return firstPublicRelease;
+ }
+
+ public void setFirstPublicRelease(String firstPublicRelease)
+ {
+ this.firstPublicRelease = firstPublicRelease;
+ }
+
+ public String getLastUpdatedDate()
+ {
+ return lastUpdatedDate;
+ }
+
+ public void setLastUpdatedDate(String lastUpdatedDate)
+ {
+ this.lastUpdatedDate = lastUpdatedDate;
+ }
+
+ public String getLastUpdatedRelease()
+ {
+ return lastUpdatedRelease;
+ }
+
+ public void setLastUpdatedRelease(String lastUpdatedRelease)
+ {
+ this.lastUpdatedRelease = lastUpdatedRelease;
+ }
+
+ public String getDataClass()
+ {
+ return dataClass;
+ }
+
+ public void setDataClass(String dataClass)
+ {
+ this.dataClass = dataClass;
+ }
}
Vector<Qualifier> qualifiers;
- Vector<EmblFeatureLocations> locations;
+ String location;
/**
* @return the dbRefs
}
/**
- * @return the locations
+ * @return the location
*/
- public Vector<EmblFeatureLocations> getLocations()
+ public String getLocation()
{
- return locations;
+ return location;
}
/**
- * @param locations
- * the locations to set
+ * @param loc
*/
- public void setLocations(Vector<EmblFeatureLocations> locations)
+ public void setLocation(String loc)
{
- this.locations = locations;
+ this.location = loc;
}
/**
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.datamodel.xdb.embl;
-
-/**
- * Data model for a feature/location/locationElement read from an EMBL query
- * reply
- *
- * @see embl_mapping.xml
- */
-public class EmblFeatureLocElement
-{
- String type;
-
- String accession;
-
- String version;
-
- boolean complement;
-
- BasePosition basePositions[];
-
- /**
- * @return the accession
- */
- public String getAccession()
- {
- return accession;
- }
-
- /**
- * @param accession
- * the accession to set
- */
- public void setAccession(String accession)
- {
- this.accession = accession;
- }
-
- /**
- * @return the basePositions
- */
- public BasePosition[] getBasePositions()
- {
- return basePositions;
- }
-
- /**
- * @param basePositions
- * the basePositions to set
- */
- public void setBasePositions(BasePosition[] basePositions)
- {
- this.basePositions = basePositions;
- }
-
- /**
- * @return the complement
- */
- public boolean isComplement()
- {
- return complement;
- }
-
- /**
- * @param complement
- * the complement to set
- */
- public void setComplement(boolean complement)
- {
- this.complement = complement;
- }
-
- /**
- * @return the type
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * @param type
- * the type to set
- */
- public void setType(String type)
- {
- this.type = type;
- }
-
- /**
- * @return the version
- */
- public String getVersion()
- {
- return version;
- }
-
- /**
- * @param version
- * the version to set
- */
- public void setVersion(String version)
- {
- this.version = version;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.datamodel.xdb.embl;
-
-import jalview.bin.Cache;
-import jalview.util.ArrayUtils;
-
-import java.util.Arrays;
-import java.util.Vector;
-
-/**
- * Data model for a <location> child element of a <feature> read
- * from an EMBL query reply
- *
- * @see embl_mapping.xml
- * @see http://www.insdc.org/files/feature_table.html#3.4.2
- */
-public class EmblFeatureLocations
-{
- Vector<EmblFeatureLocElement> locElements;
-
- String locationType;
-
- boolean locationComplement;
-
- /**
- * @return the locationComplement
- */
- public boolean isLocationComplement()
- {
- return locationComplement;
- }
-
- /**
- * @param locationComplement
- * the locationComplement to set
- */
- public void setLocationComplement(boolean locationComplement)
- {
- this.locationComplement = locationComplement;
- }
-
- /**
- * @return the locationType
- */
- public String getLocationType()
- {
- return locationType;
- }
-
- /**
- * @param locationType
- * the locationType to set
- */
- public void setLocationType(String locationType)
- {
- this.locationType = locationType;
- }
-
- /**
- * @return the locElements
- */
- public Vector<EmblFeatureLocElement> getLocElements()
- {
- return locElements;
- }
-
- /**
- * @param locElements
- * the locElements to set
- */
- public void setLocElements(Vector<EmblFeatureLocElement> locElements)
- {
- this.locElements = locElements;
- }
-
- /**
- * Return all location elements as start-end pairs (without accessions) TODO:
- * pass back complement and 'less than or more than' range information Note:
- * do not use this since it throws away any accessionIds associated with each
- * location!
- *
- * @return int[] { start1, end1, ... }
- */
- public int[] getElementRanges()
- {
- return getElementRanges(null);
- }
-
- /**
- * Return all location elements concerning given accession as start-end pairs.
- * If the CDS feature is on the forward strand, then start <= end, if on the
- * reverse strand then start > end.
- *
- * @param accession
- * the accession string for which locations are requested, or null
- * for all locations
- * @return int[] { start1, end1, ... }
- */
- int[] getElementRanges(String accession)
- {
- int sepos = 0;
- int[] se = new int[locElements.size() * 2];
- if ("single".equalsIgnoreCase(locationType)
- || "join".equalsIgnoreCase(locationType))
- {
- for (EmblFeatureLocElement loce : locElements)
- {
- if (accession == null || loce.accession != null
- && accession.equals(loce.accession))
- {
- BasePosition bp[] = loce.getBasePositions();
- if (bp.length == 2)
- {
- try
- {
- int start = Integer.parseInt(bp[0].getPos());
- int end = Integer.parseInt(bp[1].getPos());
- se[sepos++] = start;
- se[sepos++] = end;
- } catch (NumberFormatException e)
- {
- System.err
- .println("format error in EMBL CDS location basePosition: "
- + e.getMessage());
- }
- }
- else
- {
- System.err
- .println("format error in EMBL CDS location, basePosition count = "
- + bp.length);
- }
- }
- }
- }
- else if (locationType != null)
- {
- if (Cache.log != null)
- {
- Cache.log
- .error("EmblFeatureLocations.getElementRanges cannot deal with locationType=='"
- + locationType + "'");
- }
- else
- {
- System.err
- .println("EmblFeatureLocations.getElementRanges cannot deal with locationType=='"
- + locationType + "'");
- }
- }
-
- if (sepos != se.length)
- {
- /*
- * we failed to parse something - trim off null values
- */
- se = Arrays.copyOf(se, sepos);
- }
-
- /*
- * If on the complement, reverse the ranges to [end, start, ...end1, start1].
- * For an example of a joined complement, see (tRNA feature) CAGL0B00165r on
- * http://www.ebi.ac.uk/ena/data/view/CR380948&display=xml
- * http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/embl/CR380948/emblxml
- */
- if (locationComplement)
- {
- ArrayUtils.reverseIntArray(se);
- }
- return se;
- }
-}
*/
public class EmblSequence
{
- String version;
-
String sequence;
- String type;
-
/**
* @return the sequence
*/
*/
public void setSequence(String sequence)
{
- this.sequence = sequence;
- }
-
- /**
- * @return the type
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * @param type
- * the type to set
- */
- public void setType(String type)
- {
- this.type = type;
- }
-
- /**
- * @return the version
- */
- public String getVersion()
- {
- return version;
- }
-
- /**
- * @param version
- * the version to set
- */
- public void setVersion(String version)
- {
- this.version = version;
+ // remove spaces introduced by unmarshalling of newline characters
+ this.sequence = sequence.replace(" ", "");
}
}
private String lastCommand;
- private boolean loadedInline;
-
- /**
+ /*
* current set of model filenames loaded
*/
String[] modelFileNames = null;
String lastHighlightCommand;
- private List<String> lastReply;
-
/*
* incremented every time a load notification is successfully handled -
* lightweight mechanism for other threads to detect when they can start
if (lastCommand == null || !lastCommand.equals(command))
{
// trim command or it may never find a match in the replyLog!!
- lastReply = viewer.sendChimeraCommand(command.trim(), logResponse);
+ List<String> lastReply = viewer.sendChimeraCommand(command.trim(),
+ logResponse);
if (logResponse && debug)
{
log("Response from command ('" + command + "') was:\n" + lastReply);
// End StructureListener
// //////////////////////////
- public Color getColour(int atomIndex, int pdbResNum, String chain,
- String pdbfile)
- {
- if (getModelNum(pdbfile) < 0)
- {
- return null;
- }
- log("get model / residue colour attribute unimplemented");
- return null;
- }
-
/**
* returns the current featureRenderer that should be used to colour the
* structures
}
/**
- * map from string to applet
- */
- public Map getRegistryInfo()
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- /**
* returns the current sequenceRenderer that should be used to colour the
* structures
*
AlignmentViewPanel alignment);
/**
- * Construct and send a command to highlight zero, one or more atoms.
- *
- * <pre>
- * Done by generating a command like (to 'highlight' positions 44 and 46)
- * show #0:44,46.C
- * </pre>
+ * Construct and send a command to highlight zero, one or more atoms. We do
+ * this by sending an "rlabel" command to show the residue label at that
+ * position.
*/
@Override
public void highlightAtoms(List<AtomSpec> atoms)
{
- if (atoms == null)
+ if (atoms == null || atoms.size() == 0)
{
return;
}
+
StringBuilder cmd = new StringBuilder(128);
boolean first = true;
boolean found = false;
{
if (first)
{
- cmd.append("show #").append(cms.get(0).getModelNumber())
+ cmd.append("rlabel #").append(cms.get(0).getModelNumber())
.append(":");
}
else
cmd.append(",");
}
first = false;
- cmd.append(cms.get(0).getModelNumber()).append(":");
cmd.append(pdbResNum);
if (!chain.equals(" "))
{
String command = cmd.toString();
/*
- * Avoid repeated commands for the same residue
+ * avoid repeated commands for the same residue
*/
if (command.equals(lastHighlightCommand))
{
return;
}
- viewerCommandHistory(false);
+ /*
+ * unshow the label for the previous residue
+ */
+ if (lastHighlightCommand != null)
+ {
+ viewer.sendChimeraCommand("~" + lastHighlightCommand, false);
+ }
if (found)
{
- viewer.sendChimeraCommand(command.toString(), false);
+ viewer.sendChimeraCommand(command, false);
}
- viewerCommandHistory(true);
this.lastHighlightCommand = command;
}
});
btn_next_page.setEnabled(false);
btn_next_page.setToolTipText(MessageManager
- .getString("label.next_page_tooltop"));
+ .getString("label.next_page_tooltip"));
btn_next_page.setFont(new java.awt.Font("Verdana", 0, 12));
btn_next_page.setText(MessageManager.getString("action.next_page"));
btn_next_page.addActionListener(new java.awt.event.ActionListener()
btn_prev_page.setEnabled(false);
btn_prev_page.setToolTipText(MessageManager
- .getString("label.prev_page_tooltop"));
+ .getString("label.prev_page_tooltip"));
btn_prev_page.setFont(new java.awt.Font("Verdana", 0, 12));
btn_prev_page.setText(MessageManager.getString("action.prev_page"));
btn_prev_page.addActionListener(new java.awt.event.ActionListener()
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
-import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns())
{
- omitHidden = viewport.getViewAsString(false);
+ omitHidden = viewport.getViewAsString(false,
+ settings.isExportHiddenSequences());
}
int[] alignmentStartEnd = new int[2];
alignmentToExport = viewport.getAlignment();
alignmentStartEnd = viewport.getAlignment()
.getVisibleStartAndEndIndex(
- viewport
- .getColumnSelection().getHiddenColumns());
+ viewport.getColumnSelection().getHiddenColumns());
}
AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
omitHidden, alignmentStartEnd, settings);
return ed;
}
-
/**
* DOCUMENT ME!
*
return showp;
}
+ /**
+ * Finds and displays cross-references for the selected sequences (protein
+ * products for nucleotide sequences, dna coding sequences for peptides).
+ *
+ * @param sel
+ * the sequences to show cross-references for
+ * @param dna
+ * true if from a nucleotide alignment (so showing proteins)
+ * @param source
+ * the database to show cross-references for
+ */
protected void showProductsFor(final SequenceI[] sel, final boolean dna,
final String source)
{
System.err.println("Failed to make CDS alignment");
}
al.getCodonFrames().clear();
- al.getCodonFrames().addAll(copyAlignment.getCodonFrames());
+ al.addCodonFrames(copyAlignment.getCodonFrames());
+ al.addCodonFrames(cf);
/*
* pending getting Embl transcripts to 'align',
{
copyAlignment = AlignmentUtils.makeCopyAlignment(
sequenceSelection, xrefs.getSequencesArray());
- copyAlignment.getCodonFrames().addAll(cf);
+ copyAlignment.addCodonFrames(cf);
+ al.addCodonFrames(copyAlignment.getCodonFrames());
+ al.addCodonFrames(cf);
}
copyAlignment.setGapCharacter(AlignFrame.this.viewport
.getGapCharacter());
}
} catch (Exception e)
{
- Cache.log.error(
- "Exception when finding crossreferences", e);
+ Cache.log.error("Exception when finding crossreferences", e);
} catch (OutOfMemoryError e)
{
new OOMWarning("whilst fetching crossreferences", e);
} catch (Throwable e)
{
- Cache.log.error("Error when finding crossreferences",
- e);
+ Cache.log.error("Error when finding crossreferences", e);
} finally
{
AlignFrame.this.setProgressBar(MessageManager.formatMessage(
.getString("label.error_when_translating_sequences_submit_bug_report");
final String errorTitle = MessageManager
.getString("label.implementation_error")
- + MessageManager.getString("translation_failed");
+ + MessageManager.getString("label.translation_failed");
JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
JOptionPane.ERROR_MESSAGE);
return;
public void drop(DropTargetDropEvent evt)
{
Transferable t = evt.getTransferable();
- java.util.List files = null;
+ java.util.List<String> files = new ArrayList<String>(), protocols = new ArrayList<String>();
try
{
- DataFlavor uriListFlavor = new DataFlavor(
- "text/uri-list;class=java.lang.String");
- if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
- {
- // Works on Windows and MacOSX
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
- files = (java.util.List) t
- .getTransferData(DataFlavor.javaFileListFlavor);
- }
- else if (t.isDataFlavorSupported(uriListFlavor))
- {
- // This is used by Unix drag system
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
- String data = (String) t.getTransferData(uriListFlavor);
- files = new java.util.ArrayList(1);
- for (java.util.StringTokenizer st = new java.util.StringTokenizer(
- data, "\r\n"); st.hasMoreTokens();)
- {
- String s = st.nextToken();
- if (s.startsWith("#"))
- {
- // the line is a comment (as per the RFC 2483)
- continue;
- }
-
- java.net.URI uri = new java.net.URI(s);
- // check to see if we can handle this kind of URI
- if (uri.getScheme().toLowerCase().startsWith("http"))
- {
- files.add(uri.toString());
- }
- else
- {
- // otherwise preserve old behaviour: catch all for file objects
- java.io.File file = new java.io.File(uri);
- files.add(file.toString());
- }
- }
- }
+ Desktop.transferFromDropTarget(files, protocols, evt, t);
} catch (Exception e)
{
e.printStackTrace();
AlignFrame.this.setMenusForViewport();
}
});
- dbRefFetcher
- .fetchDBRefs(false);
+ dbRefFetcher.fetchDBRefs(false);
}
}).start();
try
{
Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
-
al = dna.reverseCdna(complement);
viewport.addAlignment(al, "");
+ addHistoryItem(new EditCommand(
+ MessageManager.getString("label.add_sequences"),
+ Action.PASTE, al.getSequencesArray(), 0, al.getWidth(),
+ viewport.getAlignment()));
} catch (Exception ex)
{
System.err.println(ex.getMessage());
// todo: make the ap scroll to the selection - not necessary, first
// click highlights/scrolls, second selects
ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null);
- ap.av.setSelectionGroup(// new SequenceGroup(
- aa[selectedRow].groupRef); // );
+ // process modifiers
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg == null
+ || sg == aa[selectedRow].groupRef
+ || !(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
+ {
+ if (jalview.util.Platform.isControlDown(evt)
+ || evt.isShiftDown())
+ {
+ // clone a new selection group from the associated group
+ ap.av.setSelectionGroup(new SequenceGroup(
+ aa[selectedRow].groupRef));
+ }
+ else
+ {
+ // set selection to the associated group so it can be edited
+ ap.av.setSelectionGroup(aa[selectedRow].groupRef);
+ }
+ }
+ else
+ {
+ // modify current selection with associated group
+ int remainToAdd = aa[selectedRow].groupRef.getSize();
+ for (SequenceI sgs : aa[selectedRow].groupRef.getSequences())
+ {
+ if (jalview.util.Platform.isControlDown(evt))
+ {
+ sg.addOrRemove(sgs, --remainToAdd == 0);
+ }
+ else
+ {
+ // notionally, we should also add intermediate sequences from
+ // last added sequence ?
+ sg.addSequence(sgs, --remainToAdd == 0);
+ }
+ }
+ }
+
ap.paintAlignment(false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
// we make a copy rather than edit the current selection if no
// modifiers pressed
// see Enhancement JAL-1557
- if (!(evt.isControlDown() || evt.isShiftDown()))
+ if (!(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
{
sg = new SequenceGroup(sg);
sg.clear();
}
else
{
- if (evt.isControlDown())
+ if (jalview.util.Platform.isControlDown(evt))
{
sg.addOrRemove(aa[selectedRow].sequenceRef, true);
}
sg.addSequence(aa[selectedRow].sequenceRef, false);
}
ap.av.setSelectionGroup(sg);
- ap.av.sendSelection();
ap.paintAlignment(false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
+ ap.av.sendSelection();
}
}
{
boolean success = true;
Transferable t = evt.getTransferable();
- java.util.List files = null;
- java.util.List protocols = null;
+ java.util.List<String> files = new ArrayList<String>();
+ java.util.List<String> protocols = new ArrayList<String>();
try
{
- DataFlavor uriListFlavor = new DataFlavor(
- "text/uri-list;class=java.lang.String");
- if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
- {
- // Works on Windows and MacOSX
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
- files = (java.util.List) t
- .getTransferData(DataFlavor.javaFileListFlavor);
- }
- else if (t.isDataFlavorSupported(uriListFlavor))
- {
- // This is used by Unix drag system
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
- String data = (String) t.getTransferData(uriListFlavor);
- files = new java.util.ArrayList(1);
- protocols = new java.util.ArrayList(1);
- for (java.util.StringTokenizer st = new java.util.StringTokenizer(
- data, "\r\n"); st.hasMoreTokens();)
- {
- String s = st.nextToken();
- if (s.startsWith("#"))
- {
- // the line is a comment (as per the RFC 2483)
- continue;
- }
- java.net.URI uri = new java.net.URI(s);
- if (uri.getScheme().toLowerCase().startsWith("http"))
- {
- protocols.add(FormatAdapter.URL);
- files.add(uri.toString());
- }
- else
- {
- // otherwise preserve old behaviour: catch all for file objects
- java.io.File file = new java.io.File(uri);
- protocols.add(FormatAdapter.FILE);
- files.add(file.toString());
- }
- }
- }
+ Desktop.transferFromDropTarget(files, protocols, evt, t);
} catch (Exception e)
{
+ e.printStackTrace();
success = false;
}
return groovyConsole;
}
+ public static void transferFromDropTarget(List<String> files,
+ List<String> protocols, DropTargetDropEvent evt, Transferable t)
+ throws Exception
+ {
+
+ DataFlavor uriListFlavor = new DataFlavor(
+ "text/uri-list;class=java.lang.String");
+ if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+ {
+ // Works on Windows and MacOSX
+ Cache.log.debug("Drop handled as javaFileListFlavor");
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+ for (Object file : (List) t
+ .getTransferData(DataFlavor.javaFileListFlavor))
+ {
+ files.add(((File)file).toString());
+ protocols.add(FormatAdapter.FILE);
+ }
+ }
+ else
+ {
+ // Unix like behaviour
+ boolean added = false;
+ String data = null;
+ if (t.isDataFlavorSupported(uriListFlavor))
+ {
+ Cache.log.debug("Drop handled as uriListFlavor");
+ // This is used by Unix drag system
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+ data = (String) t.getTransferData(uriListFlavor);
+ }
+ if (data == null)
+ {
+ // fallback to text: workaround - on OSX where there's a JVM bug
+ Cache.log.debug("standard URIListFlavor failed. Trying text");
+ // try text fallback
+ data = (String) t.getTransferData(new DataFlavor(
+ "text/plain;class=java.lang.String"));
+ if (Cache.log.isDebugEnabled())
+ {
+ Cache.log.debug("fallback returned " + data);
+ }
+ }
+ while (protocols.size() < files.size())
+ {
+ Cache.log.debug("Adding missing FILE protocol for "
+ + files.get(protocols.size()));
+ protocols.add(FormatAdapter.FILE);
+ }
+ for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+ data, "\r\n"); st.hasMoreTokens();)
+ {
+ added = true;
+ String s = st.nextToken();
+ if (s.startsWith("#"))
+ {
+ // the line is a comment (as per the RFC 2483)
+ continue;
+ }
+ java.net.URI uri = new java.net.URI(s);
+ if (uri.getScheme().toLowerCase().startsWith("http"))
+ {
+ protocols.add(FormatAdapter.URL);
+ files.add(uri.toString());
+ }
+ else
+ {
+ // otherwise preserve old behaviour: catch all for file objects
+ java.io.File file = new java.io.File(uri);
+ protocols.add(FormatAdapter.FILE);
+ files.add(file.toString());
+ }
+ }
+ if (Cache.log.isDebugEnabled())
+ {
+ if (data == null || !added)
+ {
+ Cache.log
+ .debug("Couldn't resolve drop data. Here are the supported flavors:");
+ for (DataFlavor fl : t.getTransferDataFlavors())
+ {
+ Cache.log.debug("Supported transfer dataflavor: "
+ + fl.toString());
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+ Object df = t.getTransferData(fl);
+ if (df != null)
+ {
+ Cache.log.debug("Retrieves: " + df);
+ }
+ else
+ {
+ Cache.log.debug("Retrieved nothing");
+ }
+ }
+ }
+ }
+ }
+ }
}
*
* @return vector of selected das source nicknames
*/
- public Vector getSelectedSources()
+ public Vector<jalviewSourceI> getSelectedSources()
{
return dassourceBrowser.getSelectedSources();
}
return;
}
-
if ((av.getSelectionGroup() == null)
- || ((!e.isControlDown() && !e.isShiftDown()) && av
- .getSelectionGroup() != null))
+ || (!jalview.util.Platform.isControlDown(e)
+ && !e.isShiftDown() && av.getSelectionGroup() != null))
{
av.setSelectionGroup(new SequenceGroup());
av.getSelectionGroup().setStartRes(0);
.wrapTooltip(
true,
((desc == null || desc.trim().length() == 0) ? MessageManager
- .getString("label.opt_and_params_further_details ")
+ .getString("label.opt_and_params_further_details")
: desc)
+ "<br><img src=\"" + linkImageURL + "\"/>"));
enabled.addMouseListener(this);
+ linkImageURL
+ "\"/>"
+ MessageManager
- .getString("label.opt_and_params_further_detail")
+ .getString("label.opt_and_params_further_details")
: "")));
}
import jalview.util.GroupUrlLink.UrlStringTooLongException;
import jalview.util.MessageManager;
import jalview.util.UrlLink;
+import jalview.ws.DBRefFetcher;
import java.awt.Color;
import java.awt.event.ActionEvent;
@Override
public void run()
{
- boolean isNuclueotide = ap.alignFrame.getViewport().getAlignment()
+ boolean isNucleotide = ap.alignFrame.getViewport().getAlignment()
.isNucleotide();
- new jalview.ws.DBRefFetcher(sequences, ap.alignFrame, null,
- ap.alignFrame.featureSettings, isNuclueotide)
+ new DBRefFetcher(sequences, ap.alignFrame, null,
+ ap.alignFrame.featureSettings, isNucleotide)
.fetchDBRefs(false);
}
private WsPreferences wsPrefs;
+ private OptionsParam promptEachTimeOpt = new OptionsParam(
+ MessageManager.getString("label.prompt_each_time"),
+ "Prompt each time");
+
+ private OptionsParam lineArtOpt = new OptionsParam(
+ MessageManager.getString("label.lineart"), "Lineart");
+
+ private OptionsParam textOpt = new OptionsParam(
+ MessageManager.getString("action.text"), "Text");
+
/**
* Creates a new Preferences object.
*/
/*
* Set Output tab defaults
*/
- epsRendering
- .addItem(MessageManager.getString("label.prompt_each_time"));
- epsRendering.addItem(MessageManager.getString("label.lineart"));
- epsRendering.addItem(MessageManager.getString("action.text"));
- epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING",
- "Prompt each time"));
+ epsRendering.addItem(promptEachTimeOpt);
+ epsRendering.addItem(lineArtOpt);
+ epsRendering.addItem(textOpt);
+ String defaultEPS = Cache.getDefault("EPS_RENDERING",
+ "Prompt each time");
+ if (defaultEPS.equalsIgnoreCase("Text"))
+ {
+ epsRendering.setSelectedItem(textOpt);
+ }
+ else if (defaultEPS.equalsIgnoreCase("Lineart"))
+ {
+ epsRendering.setSelectedItem(lineArtOpt);
+ }
+ else
+ {
+ epsRendering.setSelectedItem(promptEachTimeOpt);
+ }
autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
userIdWidth.setEnabled(!autoIdWidth.isSelected());
userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
/*
* Save Output settings
*/
- if (epsRendering.getSelectedItem().equals("Prompt each time"))
- {
- Cache.applicationProperties.remove("EPS_RENDERING");
- }
- else
- {
- Cache.applicationProperties.setProperty("EPS_RENDERING", epsRendering
- .getSelectedItem().toString());
- }
+ Cache.applicationProperties.setProperty("EPS_RENDERING",
+ ((OptionsParam) epsRendering.getSelectedItem()).getCode());
/*
* Save Connections settings
}
}
+ public class OptionsParam
+ {
+ private String name;
+
+ private String code;
+
+ public OptionsParam(String name, String code)
+ {
+ this.name = name;
+ this.code = code;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getCode()
+ {
+ return code;
+ }
+
+ public void setCode(String code)
+ {
+ this.code = code;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object that)
+ {
+ if (!(that instanceof OptionsParam))
+ {
+ return false;
+ }
+ return this.code.equalsIgnoreCase(((OptionsParam) that).code);
+ }
+
+ @Override
+ public int hashCode(){
+ return name.hashCode() + code.hashCode();
+ }
+ }
}
import javax.swing.ToolTipManager;
/**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * The panel containing the sequence ruler (when not in wrapped mode), and
+ * supports a range of mouse operations to select, hide or reveal columns.
*/
public class ScalePanel extends JPanel implements MouseMotionListener,
MouseListener
{
protected int offy = 4;
- /** DOCUMENT ME!! */
public int width;
protected AlignViewport av;
boolean stretchingGroup = false;
- int min; // used by mouseDragged to see if user
+ /*
+ * min, max hold the extent of a mouse drag action
+ */
+ int min;
- int max; // used by mouseDragged to see if user
+ int max;
boolean mouseDragging = false;
- // wants to delete columns
+ /*
+ * holds a hidden column range when the mouse is over an adjacent column
+ */
+ int[] reveal;
+
+ /**
+ * Constructor
+ *
+ * @param av
+ * @param ap
+ */
public ScalePanel(AlignViewport av, AlignmentPanel ap)
{
this.av = av;
@Override
public void mouseMoved(MouseEvent evt)
{
+ this.setToolTipText(null);
+ reveal = null;
if (!av.hasHiddenColumns())
{
return;
res = av.getColumnSelection().adjustForHiddenColumns(res);
- reveal = null;
if (av.getColumnSelection().getHiddenColumns() != null)
{
for (int[] region : av.getColumnSelection().getHiddenColumns())
.getString("label.reveal_hidden_columns"));
break;
}
- else
- {
- this.setToolTipText(null);
- }
}
}
repaint();
}
- int[] reveal;
-
/**
* DOCUMENT ME!
*
// do we want to thread this ? (contention with seqsel and colsel locks, I
// suspect)
- // rules are: colsel is copied if there is a real intersection between
- // sequence selection
+ /*
+ * only copy colsel if there is a real intersection between
+ * sequence selection and this panel's alignment
+ */
boolean repaint = false;
- boolean copycolsel = true;
+ boolean copycolsel = false;
SequenceGroup sgroup = null;
if (seqsel != null && seqsel.getSize() > 0)
}
sgroup = seqsel.intersect(av.getAlignment(),
(av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- || (colsel == null || colsel.isEmpty()))
+ if ((sgroup != null && sgroup.getSize() > 0))
{
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
+ copycolsel = true;
}
}
if (sgroup != null && sgroup.getSize() > 0)
ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
av);
av.setColumnSelection(cs);
- av.isColSelChanged(true);
PaintRefresher.Refresh(this, av.getSequenceSetId());
this.add(jPanel2, java.awt.BorderLayout.NORTH);
jScrollPane1.getViewport().add(textArea);
+ /*
+ * open the database tree
+ */
+ database.waitForInput();
}
private void pdbSourceAction()
import jalview.jbgui.GStructureChooser;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
+import jalview.ws.DBRefFetcher;
import jalview.ws.sifts.SiftsSettings;
import java.awt.event.ItemEvent;
if (pdbEntry == null)
{
pdbEntry = new PDBEntry();
+ if (pdbIdStr.split(":").length > 1)
+ {
+ pdbEntry.setChainCode(pdbIdStr.split(":")[1]);
+ }
pdbEntry.setId(pdbIdStr);
pdbEntry.setType(PDBEntry.Type.PDB);
selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
{
ssm.setProgressBar(null);
ssm.setProgressBar("Fetching Database refs..");
- new jalview.ws.DBRefFetcher(sequences, null, null, null, false)
- .fetchDBRefs(true);
+ new DBRefFetcher(sequences).fetchDBRefs(true);
break;
}
}
}
- if (pdbEntriesToView.length > 1)
- {
- ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
- for (SequenceI seq : sequences)
- {
- seqsMap.add(new SequenceI[] { seq });
- }
- SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
+ if (pdbEntriesToView.length > 1)
+ {
+ ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
+ for (SequenceI seq : sequences)
+ {
+ seqsMap.add(new SequenceI[] { seq });
+ }
+ SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
ssm.setProgressBar(null);
ssm.setProgressBar("Fetching PDB Structures for selected entries..");
- sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
- }
- else
- {
+ sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
+ }
+ else
+ {
ssm.setProgressBar(null);
ssm.setProgressBar("Fetching PDB Structure for "
+ pdbEntriesToView[0].getId());
- sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
- }
+ sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
+ }
}
/**
isValidPBDEntry = false;
if (txt_search.getText().length() > 0)
{
+ String searchTerm = txt_search.getText().toLowerCase();
+ searchTerm = searchTerm.split(":")[0];
+ System.out.println(">>>>> search term : " + searchTerm);
List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
FTSRestRequest pdbRequest = new FTSRestRequest();
pdbRequest.setAllowEmptySeq(false);
pdbRequest.setFieldToSearchBy("(pdb_id:");
pdbRequest.setWantedFields(wantedFields);
pdbRequest
- .setSearchTerm(txt_search.getText().toLowerCase() + ")");
+.setSearchTerm(searchTerm + ")");
pdbRequest.setAssociatedSequence(selectedSequence);
pdbRestCleint = PDBFTSRestClient.getInstance();
wantedFields.add(pdbRestCleint.getPrimaryKeyColumn());
final JPanel col2 = new JPanel();
col2.setPreferredSize(new Dimension(40, 20));
col2.setBorder(BorderFactory.createEtchedBorder());
- col2.setToolTipText(MessageManager.getString("label.ligth_colour"));
+ col2.setToolTipText(MessageManager.getString("label.light_colour"));
col2.setBackground(new Color(original2));
final JPanel bigpanel = new JPanel(new BorderLayout());
JPanel panel = new JPanel();
col1.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
Color col = JColorChooser.showDialog(bigpanel,
col2.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
Color col = JColorChooser.showDialog(bigpanel,
slider.addChangeListener(new ChangeListener()
{
+ @Override
public void stateChanged(ChangeEvent evt)
{
thresholdChanged(slider.getValue());
av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
{
+ @Override
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals("alignment"))
}
+ @Override
public void viewMenu_menuSelected()
{
buildAssociatedViewMenu();
buttonGroup.add(item);
item.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
treeCanvas.applyToAllViews = false;
itemf.setSelected(treeCanvas.applyToAllViews);
itemf.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
treeCanvas.applyToAllViews = itemf.isSelected();
}
}
+ @Override
public void run()
{
* @param e
* DOCUMENT ME!
*/
+ @Override
public void textbox_actionPerformed(ActionEvent e)
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
* @param e
* DOCUMENT ME!
*/
+ @Override
public void saveAsNewick_actionPerformed(ActionEvent e)
{
JalviewFileChooser chooser = new JalviewFileChooser(
* @param e
* DOCUMENT ME!
*/
+ @Override
public void printMenu_actionPerformed(ActionEvent e)
{
// Putting in a thread avoids Swing painting problems
treeCanvas.startPrinting();
}
+ @Override
public void originalSeqData_actionPerformed(ActionEvent e)
{
if (!tree.hasOriginalSequenceData())
* @param e
* DOCUMENT ME!
*/
+ @Override
public void fitToWindow_actionPerformed(ActionEvent e)
{
treeCanvas.fitToWindow = fitToWindow.isSelected();
* @param e
* DOCUMENT ME!
*/
+ @Override
public void font_actionPerformed(ActionEvent e)
{
if (treeCanvas == null)
* @param e
* DOCUMENT ME!
*/
+ @Override
public void distanceMenu_actionPerformed(ActionEvent e)
{
treeCanvas.setShowDistances(distanceMenu.isSelected());
* @param e
* DOCUMENT ME!
*/
+ @Override
public void bootstrapMenu_actionPerformed(ActionEvent e)
{
treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());
* @param e
* DOCUMENT ME!
*/
+ @Override
public void placeholdersMenu_actionPerformed(ActionEvent e)
{
treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());
* @param e
* DOCUMENT ME!
*/
+ @Override
public void epsTree_actionPerformed(ActionEvent e)
{
boolean accurateText = true;
* @param e
* DOCUMENT ME!
*/
+ @Override
public void pngTree_actionPerformed(ActionEvent e)
{
int width = treeCanvas.getWidth();
tree.applyToNodes(new NodeTransformI()
{
+ @Override
public void transform(BinaryNode node)
{
if (node instanceof SequenceNode
}
}
- if (renderStyle.equalsIgnoreCase("lineart"))
+ if (renderStyle.equalsIgnoreCase("Lineart"))
{
g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
/*
* Output tab components
*/
- protected JComboBox<String> epsRendering = new JComboBox<String>();
+ protected JComboBox<Object> epsRendering = new JComboBox<Object>();
protected JLabel userIdWidthlabel = new JLabel();
.getString("label.open_overview"));
openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
- openoverv.setText(MessageManager.getString(("label.open_overview")));
+ openoverv.setText(MessageManager.getString("label.open_overview"));
JPanel jPanel2 = new JPanel();
jPanel2.setBounds(new Rectangle(7, 17, 158, 310));
jPanel2.setLayout(new GridLayout(14, 1));
}
}
- if (renderStyle.equalsIgnoreCase("lineart"))
+ if (renderStyle.equalsIgnoreCase("Lineart"))
{
ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
*/
package jalview.util;
+import java.awt.Toolkit;
+import java.awt.event.MouseEvent;
+
/**
* System platform information used by Applet and Application
*
f.append(file.substring(lastp));
return f.toString();
}
+
+ public static boolean isControlDown(MouseEvent e)
+ {
+ return (jalview.util.Platform.isAMac() ? (Toolkit.getDefaultToolkit()
+ .getMenuShortcutKeyMask() & e.getModifiers()) != 0 : e
+ .isControlDown());
+ }
}
{
updateHiddenColumns();
}
+ isColSelChanged(true);
}
/**
*/
public boolean isColSelChanged(boolean b)
{
- int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel
- .hashCode();
+ int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
if (hc != -1 && hc != colselhash)
{
if (b)
colSel.hideSelectedColumns();
setSelectionGroup(null);
-
+ isColSelChanged(true);
}
public void hideColumns(int start, int end)
{
colSel.hideColumns(start, end);
}
+ isColSelChanged(true);
}
public void showColumn(int col)
{
colSel.revealHiddenColumns(col);
-
+ isColSelChanged(true);
}
public void showAllHiddenColumns()
{
colSel.revealAllHiddenColumns();
+ isColSelChanged(true);
}
// common hide/show seq stuff
@Override
public String[] getViewAsString(boolean selectedRegionOnly)
{
+ return getViewAsString(selectedRegionOnly, true);
+ }
+
+ @Override
+ public String[] getViewAsString(boolean selectedRegionOnly,
+ boolean exportHiddenSeqs)
+ {
String[] selection = null;
SequenceI[] seqs = null;
int i, iSize;
}
else
{
- if (hasHiddenRows())
+ if (hasHiddenRows() && exportHiddenSeqs)
{
- iSize = alignment.getHiddenSequences().getFullAlignment()
- .getHeight();
- seqs = alignment.getHiddenSequences().getFullAlignment()
- .getSequencesArray();
- end = alignment.getHiddenSequences().getFullAlignment().getWidth();
+ AlignmentI fullAlignment = alignment.getHiddenSequences()
+ .getFullAlignment();
+ iSize = fullAlignment.getHeight();
+ seqs = fullAlignment.getSequencesArray();
+ end = fullAlignment.getWidth();
}
else
{
}
}
}
+
+
}
String[] defdb = null, otherdb = sfetcher
.getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
- Vector dasselsrc = (featureSettings != null) ? featureSettings
+ Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
.getSelectedSources() : new jalview.gui.DasSourceBrowser()
.getSelectedSources();
Enumeration<jalviewSourceI> en = dasselsrc.elements();
}
/**
+ * Constructor with only sequences provided
+ *
+ * @param sequences
+ */
+ public DBRefFetcher(SequenceI[] sequences)
+ {
+ this(sequences, null, null, null, false);
+ }
+
+ /**
* Add a listener to be notified when sequence fetching is complete
*
* @param l
import jalview.bin.Cache;
import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.FeatureSettings;
+import jalview.util.DBRefUtils;
import jalview.util.MessageManager;
import jalview.util.UrlLink;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
{
for (int j = 0; j < dbref.length; j++)
{
- if (dbref[j].getSource().equals(
- jalview.datamodel.DBRefSource.UNIPROT))
+ if (dbref[j].getSource().equals(DBRefSource.UNIPROT))
{
refCount++;
break;
public void run()
{
running = true;
- boolean isNuclueotide = af.getViewport().getAlignment()
+ boolean isNucleotide = af.getViewport().getAlignment()
.isNucleotide();
- new jalview.ws.DBRefFetcher(sequences, af, null, af.featureSettings,
- isNuclueotide).fetchDBRefs(true);
+ new DBRefFetcher(sequences, af, null, af.featureSettings,
+ isNucleotide).fetchDBRefs(true);
startFetching();
setGuiFetchComplete();
{
jalviewSourceI[] sources = sourceRegistry.getSources().toArray(
new jalviewSourceI[0]);
- String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",
+ String active = Cache.getDefault("DAS_ACTIVE_SOURCE",
"uniprot");
StringTokenizer st = new StringTokenizer(active, "\t");
selectedSources = new Vector();
{
return null;
}
- DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
+ DBRefEntry[] uprefs = DBRefUtils.selectRefs(
seq.getDBRefs(), new String[] {
// jalview.datamodel.DBRefSource.PDB,
- jalview.datamodel.DBRefSource.UNIPROT,
+ DBRefSource.UNIPROT,
// jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord
// sys sources
});
for (COORDINATES csys : dasSource.getVersion().getCOORDINATES())
{
- if (jalview.util.DBRefUtils.isDasCoordinateSystem(
+ if (DBRefUtils.isDasCoordinateSystem(
csys.getAuthority(), uprefs[j]))
{
debug("Launched fetcher for coordinate system "
try
{
reply = dbFetch.fetchDataAsFile(
- emprefx.toLowerCase() + ":" + query.trim(), "emblxml", null,
+ emprefx.toLowerCase() + ":" + query.trim(), "display=xml",
".xml");
} catch (Exception e)
{
+
/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
public static final String FEATURE_RES_NUM = "RESNUM";
- private static String currentDefaultFomart = DBRefSource.PDB;
+ private static String currentDefaultFormat = DBRefSource.PDB;
/*
* (non-Javadoc)
stopQuery();
return null;
}
- String ext = getCurrentDefaultFomart().equalsIgnoreCase("mmcif") ? ".cif"
+ String ext = getCurrentDefaultFormat().equalsIgnoreCase("mmcif") ? ".cif"
: ".xml";
EBIFetchClient ebi = new EBIFetchClient();
file = ebi.fetchDataAsFile("pdb:" + id,
- getCurrentDefaultFomart().toLowerCase(), "raw", ext)
+ getCurrentDefaultFormat().toLowerCase(), ext)
.getAbsolutePath();
stopQuery();
if (file == null)
pdbAlignment = new FormatAdapter().readFile(file,
jalview.io.AppletFormatAdapter.FILE,
- getCurrentDefaultFomart());
+ getCurrentDefaultFormat());
if (pdbAlignment != null)
{
List<SequenceI> toremove = new ArrayList<SequenceI>();
return 0;
}
- public static String getCurrentDefaultFomart()
+ public static String getCurrentDefaultFormat()
{
- return currentDefaultFomart;
+ return currentDefaultFormat;
}
- public static void setCurrentDefaultFomart(String currentDefaultFomart)
+ public static void setCurrentDefaultFormat(String currentDefaultFomart)
{
- Pdb.currentDefaultFomart = currentDefaultFomart;
+ Pdb.currentDefaultFormat = currentDefaultFomart;
}
/**
// uniprotxml parameter required since december 2007
// uniprotkb dbname changed introduced december 2008
File file = ebi.fetchDataAsFile("uniprotkb:" + queries, "uniprotxml",
- null, ".xml");
+ ".xml");
Vector<UniprotEntry> entries = getUniprotEntries(new FileReader(file));
if (entries != null)
*/
public class EBIFetchClient
{
- String format = "default";
-
- String style = "raw";
/**
* Creates a new EBIFetchClient object.
* the query formatted as db:query1;query2;query3
* @param format
* the format wanted
- * @param s
- * - unused parameter
+ * @param extension
+ * for the temporary file to hold response
* @return the file holding the response
* @throws OutOfMemoryError
*/
- public File fetchDataAsFile(String ids, String format, String s,
- String ext)
+ public File fetchDataAsFile(String ids, String format, String ext)
throws OutOfMemoryError
{
File outFile = null;
{
outFile = File.createTempFile("jalview", ext);
outFile.deleteOnExit();
- fetchData(ids, format, s, outFile);
+ fetchData(ids, format, outFile);
if (outFile.length() == 0)
{
outFile.delete();
}
/**
- * Single DB multiple record retrieval
+ * Fetches queries and either saves the response to a file or returns as
+ * string data
*
* @param ids
- * db:query1;query2;query3
* @param format
- * raw/xml
- * @param s
- * not used - remove?
- *
- * @return Raw string array result of query set
+ * @param outFile
+ * @return
+ * @throws OutOfMemoryError
*/
- public String[] fetchData(String ids, String format, String s)
+ String[] fetchData(String ids, String format, File outFile)
throws OutOfMemoryError
{
- return fetchData(ids, format, s, null);
+ StringBuilder querystring = new StringBuilder(ids.length());
+ String database = parseIds(ids, querystring);
+ if (database == null)
+ {
+ System.err.println("Invalid Query string : '" + ids + "'");
+ System.err.println("Should be of form 'dbname:q1;q2;q3;q4'");
+ return null;
+ }
+
+ // note: outFile is currently always specified, so return value is null
+ String[] rslt = fetchBatch(querystring.toString(), database, format, outFile);
+
+ return (rslt != null && rslt.length > 0 ? rslt : null);
}
- String[] fetchData(String ids, String f, String s, File outFile)
- throws OutOfMemoryError
+ /**
+ * Parses ids formatted as dbname:q1;q2;q3, returns the dbname and adds
+ * queries as comma-separated items to the querystring. dbname must be
+ * specified for at least one queryId. Returns null if a mixture of different
+ * dbnames is found (ignoring case).
+ *
+ * @param ids
+ * @param queryString
+ * @return
+ */
+ static String parseIds(String ids, StringBuilder queryString)
{
- // Need to split
- // ids of the form uniprot:25KD_SARPE;ADHR_DROPS;
- String[] rslts = new String[0];
+ String database = null;
StringTokenizer queries = new StringTokenizer(ids, ";");
- String db = null;
- StringBuffer querystring = null;
- int nq = 0;
+ boolean appending = queryString.length() > 0;
while (queries.hasMoreTokens())
{
String query = queries.nextToken();
- int p;
- if ((p = query.indexOf(':')) > -1)
+ int p = query.indexOf(':');
+ if (p > -1)
{
- db = query.substring(0, p);
+ String db = query.substring(0, p);
+ if (database != null && !db.equalsIgnoreCase(database))
+ {
+ /*
+ * different databases mixed in together - invalid
+ */
+ return null;
+ }
+ database = db;
query = query.substring(p + 1);
}
- if (querystring == null)
- {
- querystring = new StringBuffer(query);
- nq++;
- }
- else
- {
- querystring.append("," + query);
- nq++;
- }
- }
- if (db == null)
- {
- System.err.println("Invalid Query string : '" + ids
- + "'\nShould be of form 'dbname:q1;q2;q3;q4'");
- return null;
- }
- String[] rslt = fetchBatch(querystring.toString(), db, f, s, outFile);
- if (rslt != null)
- {
- String[] nrslts = new String[rslt.length + rslts.length];
- System.arraycopy(rslts, 0, nrslts, 0, rslts.length);
- System.arraycopy(rslt, 0, nrslts, rslts.length, rslt.length);
- rslts = nrslts;
+ queryString.append(appending ? "," : "");
+ queryString.append(query);
+ appending = true;
}
-
- return (rslts.length == 0 ? null : rslts);
+ return database;
}
- public String[] fetchBatch(String ids, String dbPath, String format, String s,
+ /**
+ * Fetches queries and either saves the response to a file or (if no file
+ * specified) returns as string data
+ *
+ * @param ids
+ * @param database
+ * @param format
+ * @param outFile
+ * @return
+ * @throws OutOfMemoryError
+ */
+ String[] fetchBatch(String ids, String database, String format,
File outFile) throws OutOfMemoryError
{
// long time = System.currentTimeMillis();
- /*
- * JAL-1855 dbfetch from ena_sequence, ena_coding
- */
- if (dbPath.equalsIgnoreCase(DBRefSource.EMBL))
- {
- dbPath = "ena_sequence";
- }
- else if (dbPath.equalsIgnoreCase(DBRefSource.EMBLCDS))
- {
- dbPath = "ena_coding";
- }
+ String url = buildUrl(ids, database, format);
try
{
- URL rcall = new URL("http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
- + dbPath.toLowerCase() + "/" + ids.toLowerCase()
- + (format != null ? "/" + format : ""));
+ URL rcall = new URL(url);
InputStream is = new BufferedInputStream(rcall.openStream());
if (outFile != null)
}
} catch (OutOfMemoryError er)
{
-
- System.out.println("OUT OF MEMORY DOWNLOADING QUERY FROM " + dbPath
+ System.out.println("OUT OF MEMORY DOWNLOADING QUERY FROM " + database
+ ":\n" + ids);
throw er;
} catch (Exception ex)
return null;
}
System.err.println("Unexpected exception when retrieving from "
- + dbPath
+ + database
+ "\nQuery was : '" + ids + "'");
ex.printStackTrace(System.err);
return null;
}
return null;
}
+
+ /**
+ * Constructs the URL to fetch from
+ *
+ * @param ids
+ * @param database
+ * @param format
+ * @return
+ */
+ static String buildUrl(String ids, String database, String format)
+ {
+ String url;
+ if (database.equalsIgnoreCase(DBRefSource.EMBL)
+ || database.equalsIgnoreCase(DBRefSource.EMBLCDS))
+ {
+ url = "http://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
+ + (format != null ? "&" + format : "");
+ }
+ else
+ {
+ url = "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
+ + database.toLowerCase() + "/" + ids.toLowerCase()
+ + (format != null ? "/" + format : "");
+ }
+ return url;
+ }
}
assertTrue(testee.equals("A12345,"));
assertTrue(testee.equals("A12345?"));
assertTrue(testee.equals("A12345_"));
+ /*
+ * case insensitive matching
+ */
+ assertTrue(testee.equals("a12345"));
/*
* matcher name = target name + word separator...
assertTrue(testee.equals("A12345"));
/*
+ * case insensitive matching
+ */
+ assertTrue(testee.equals("a12345"));
+
+ /*
* miscellaneous failing cases
*/
testee = sequenceIdMatcher.new SeqIdName("A12345");
assertFalse(testee.equals((Object) null));
assertFalse(testee.equals(""));
- assertFalse(testee.equals("a12345"));
assertFalse(testee.equals("A12346|A12345"));
+ /*
+ * case insensitive matching
+ */
+ assertTrue(testee.equals("a12345"));
testee = sequenceIdMatcher.new SeqIdName("A12345?B23456");
assertFalse(testee.equals("B23456"));
testee = sequenceIdMatcher.new SeqIdName("A12345<");
assertFalse(testee.equals("A12345?"));
assertTrue(testee.equals("A12345<")); // bug? inconsistent
+ /*
+ * case insensitive matching
+ */
+ assertTrue(testee.equals("a12345"));
}
}
cs.addElement(0);
assertEquals(0, cs.getMin());
}
+
+ @Test(groups = { "Functional" })
+ public void testEquals()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(0);
+ cs.addElement(513);
+ cs.addElement(1);
+ cs.hideColumns(3);
+ cs.hideColumns(7);
+ cs.hideColumns(5,9);
+
+ // same selections added in a different order
+ ColumnSelection cs2 = new ColumnSelection();
+ cs2.addElement(1);
+ cs2.addElement(513);
+ cs2.addElement(0);
+
+ // with no hidden columns
+ assertFalse(cs.equals(cs2));
+ assertFalse(cs2.equals(cs));
+
+ // with hidden columns added in a different order
+ cs2.hideColumns(6, 9);
+ cs2.hideColumns(5, 8);
+ cs2.hideColumns(3);
+
+ assertTrue(cs.equals(cs2));
+ assertTrue(cs.equals(cs));
+ assertTrue(cs2.equals(cs));
+ assertTrue(cs2.equals(cs2));
+
+ cs2.addElement(12);
+ assertFalse(cs.equals(cs2));
+ assertFalse(cs2.equals(cs));
+
+ cs2.removeElement(12);
+ assertTrue(cs.equals(cs2));
+
+ cs2.hideColumns(88);
+ assertFalse(cs.equals(cs2));
+ /*
+ * unhiding a column adds it to selection!
+ */
+ cs2.revealHiddenColumns(88);
+ assertFalse(cs.equals(cs2));
+ cs.addElement(88);
+ assertTrue(cs.equals(cs2));
+ }
}
*/
package jalview.datamodel;
+import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
import jalview.util.MapList;
assertTrue(ref1.equalRef(ref2));
assertTrue(ref2.equalRef(ref1));
}
+
+ /**
+ * Tests for the method that may update a DBRefEntry from another with a
+ * mapping or 'real' version
+ */
+ @Test(groups = { "Functional" })
+ public void testUpdateFrom()
+ {
+ DBRefEntry ref1 = new DBRefEntry("UNIPROT", "1", "V71633");
+
+ assertFalse(ref1.updateFrom(null));
+
+ /*
+ * equivalent other dbref
+ */
+ DBRefEntry ref2 = new DBRefEntry("uniprot", "1", "v71633");
+ assertTrue(ref1.updateFrom(ref2));
+ assertEquals("UNIPROT", ref1.getSource()); // unchanged
+ assertEquals("V71633", ref1.getAccessionId()); // unchanged
+
+ /*
+ * ref1 has no mapping, acquires mapping from ref2
+ */
+ Mapping map = new Mapping(new MapList(new int[] { 1, 3 }, new int[] {
+ 1, 1 }, 3, 1));
+ ref2.setMap(map);
+ assertTrue(ref1.updateFrom(ref2));
+ assertSame(map, ref1.getMap()); // null mapping updated
+
+ /*
+ * ref1 has a mapping, does not acquire mapping from ref2
+ */
+ ref2.setMap(new Mapping(map));
+ assertTrue(ref1.updateFrom(ref2));
+ assertSame(map, ref1.getMap()); // non-null mapping not updated
+
+ /*
+ * ref2 has a different source, accession or version
+ */
+ ref2.setSource("pdb");
+ assertFalse(ref1.updateFrom(ref2));
+ ref2.setSource(ref1.getSource());
+ ref2.setAccessionId("P12345");
+ assertFalse(ref1.updateFrom(ref2));
+ ref2.setAccessionId(ref1.getAccessionId());
+ ref1.setVersion("2");
+ assertFalse(ref1.updateFrom(ref2));
+
+ /*
+ * a non-null version supersedes "0" or "source:0"
+ */
+ ref2.setVersion(null);
+ assertFalse(ref1.updateFrom(ref2));
+ assertEquals("2", ref1.getVersion());
+ ref2.setVersion("3");
+ ref1.setVersion("0");
+ assertTrue(ref1.updateFrom(ref2));
+ assertEquals("3", ref1.getVersion());
+ ref1.setVersion("UNIPROT:0");
+ assertTrue(ref1.updateFrom(ref2));
+ assertEquals("3", ref1.getVersion());
+
+ /*
+ * version "source:n" with n>0 is not superseded
+ */
+ ref1.setVersion("UNIPROT:1");
+ assertFalse(ref1.updateFrom(ref2));
+ assertEquals("UNIPROT:1", ref1.getVersion());
+
+ /*
+ * version "10" is not superseded
+ */
+ ref1.setVersion("10");
+ assertFalse(ref1.updateFrom(ref2));
+ assertEquals("10", ref1.getVersion());
+ }
}
import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
import jalview.datamodel.PDBEntry.Type;
+import jalview.util.MapList;
import java.util.ArrayList;
import java.util.Arrays;
assertEquals(' ', sq.getCharAt(5));
assertEquals(' ', sq.getCharAt(-1));
}
+
+ /**
+ * Tests for adding (or updating) dbrefs
+ *
+ * @see DBRefEntry#updateFrom(DBRefEntry)
+ */
+ @Test(groups = { "Functional" })
+ public void testAddDBRef()
+ {
+ SequenceI sq = new Sequence("", "abcde");
+ assertNull(sq.getDBRefs());
+ DBRefEntry dbref = new DBRefEntry("Uniprot", "1", "P00340");
+ sq.addDBRef(dbref);
+ assertEquals(1, sq.getDBRefs().length);
+ assertSame(dbref, sq.getDBRefs()[0]);
+
+ /*
+ * change of version - new entry
+ */
+ DBRefEntry dbref2 = new DBRefEntry("Uniprot", "2", "P00340");
+ sq.addDBRef(dbref2);
+ assertEquals(2, sq.getDBRefs().length);
+ assertSame(dbref, sq.getDBRefs()[0]);
+ assertSame(dbref2, sq.getDBRefs()[1]);
+
+ /*
+ * matches existing entry - not added
+ */
+ sq.addDBRef(new DBRefEntry("UNIPROT", "1", "p00340"));
+ assertEquals(2, sq.getDBRefs().length);
+
+ /*
+ * different source = new entry
+ */
+ DBRefEntry dbref3 = new DBRefEntry("UniRef", "1", "p00340");
+ sq.addDBRef(dbref3);
+ assertEquals(3, sq.getDBRefs().length);
+ assertSame(dbref3, sq.getDBRefs()[2]);
+
+ /*
+ * different ref = new entry
+ */
+ DBRefEntry dbref4 = new DBRefEntry("UniRef", "1", "p00341");
+ sq.addDBRef(dbref4);
+ assertEquals(4, sq.getDBRefs().length);
+ assertSame(dbref4, sq.getDBRefs()[3]);
+
+ /*
+ * matching ref with a mapping - map updated
+ */
+ DBRefEntry dbref5 = new DBRefEntry("UniRef", "1", "p00341");
+ Mapping map = new Mapping(new MapList(new int[] { 1, 3 }, new int[] {
+ 1, 1 }, 3, 1));
+ dbref5.setMap(map);
+ sq.addDBRef(dbref5);
+ assertEquals(4, sq.getDBRefs().length);
+ assertSame(dbref4, sq.getDBRefs()[3]);
+ assertSame(map, dbref4.getMap());
+
+ /*
+ * 'real' version replaces "0" version
+ */
+ dbref2.setVersion("0");
+ DBRefEntry dbref6 = new DBRefEntry(dbref2.getSource(), "3",
+ dbref2.getAccessionId());
+ sq.addDBRef(dbref6);
+ assertEquals(4, sq.getDBRefs().length);
+ assertSame(dbref2, sq.getDBRefs()[1]);
+ assertEquals("3", dbref2.getVersion());
+
+ /*
+ * 'real' version replaces "source:0" version
+ */
+ dbref3.setVersion("Uniprot:0");
+ DBRefEntry dbref7 = new DBRefEntry(dbref3.getSource(), "3",
+ dbref3.getAccessionId());
+ sq.addDBRef(dbref7);
+ assertEquals(4, sq.getDBRefs().length);
+ assertSame(dbref3, sq.getDBRefs()[2]);
+ assertEquals("3", dbref2.getVersion());
+ }
}
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertSame;
-import jalview.util.MappingUtils;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Vector;
+import java.util.List;
import org.testng.annotations.Test;
* Make a (CDS) Feature with 4 locations
*/
EmblFeature cds = new EmblFeature();
- Vector<EmblFeatureLocations> locs = new Vector<EmblFeatureLocations>();
- cds.setLocations(locs);
-
- /*
- * single range [10-20]
- */
- EmblFeatureLocations loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- Vector<EmblFeatureLocElement> elements = new Vector<EmblFeatureLocElement>();
- EmblFeatureLocElement locElement = new EmblFeatureLocElement();
- BasePosition b1 = new BasePosition();
- b1.setPos("10");
- BasePosition b2 = new BasePosition();
- b2.setPos("20");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * complement range [30-40]
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(true);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("30");
- b2 = new BasePosition();
- b2.setPos("40");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * join range [50-60], [70-80]
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("join");
- loc.setLocationComplement(false);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("50");
- b2 = new BasePosition();
- b2.setPos("60");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("70");
- b2 = new BasePosition();
- b2.setPos("80");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * complement range [90-100], [110-120]
- * this should be the same as complement(join(90..100,110.120))
- * which is "join 90-100 and 110-120, then complement"
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("join");
- loc.setLocationComplement(true);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("90");
- b2 = new BasePosition();
- b2.setPos("100");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("110");
- b2 = new BasePosition();
- b2.setPos("120");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
+ cds.setLocation("join(10..20,complement(30..40),50..60,70..80,complement(110..120))");
int[] exons = testee.getCdsRanges(cds);
- assertEquals("[10, 20, 40, 30, 50, 60, 70, 80, 120, 110, 100, 90]",
+ assertEquals("[10, 20, 40, 30, 50, 60, 70, 80, 120, 110]",
Arrays.toString(exons));
}
@Test(groups = "Functional")
- public void testGetCdsRanges_badData()
+ public void testParseCodingFeature()
{
- EmblEntry testee = new EmblEntry();
+ // not the whole sequence but enough for this test...
+ SequenceI dna = new Sequence("J03321", "GGATCCGTAAGTTAGACGAAATT");
+ List<SequenceI> peptides = new ArrayList<SequenceI>();
+ EmblFile ef = EmblTestHelper.getEmblFile();
/*
- * Make a (CDS) Feature with 4 locations
- */
- EmblFeature cds = new EmblFeature();
- Vector<EmblFeatureLocations> locs = new Vector<EmblFeatureLocations>();
- cds.setLocations(locs);
-
- /*
- * single range [10-20]
- */
- EmblFeatureLocations loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- Vector<EmblFeatureLocElement> elements = new Vector<EmblFeatureLocElement>();
- EmblFeatureLocElement locElement = new EmblFeatureLocElement();
- BasePosition b1 = new BasePosition();
- b1.setPos("10");
- BasePosition b2 = new BasePosition();
- b2.setPos("20");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * single range with missing end position - should be skipped
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("30");
- locElement.setBasePositions(new BasePosition[] { b1 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * single range with extra base position - should be skipped
+ * parse two CDS features, one with two Uniprot cross-refs,
+ * the other with one
*/
- loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("30");
- locElement.setBasePositions(new BasePosition[] { b1, b1, b1 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * single valid range [50-60] to finish
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("50");
- b2 = new BasePosition();
- b2.setPos("60");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- int[] exons = testee.getCdsRanges(cds);
- assertEquals("[10, 20, 50, 60]", Arrays.toString(exons));
- }
-
- /**
- * Test retrieval of exon locations matching an accession id
- */
- @Test(groups = "Functional")
- public void testGetCdsRanges_forAccession()
- {
EmblEntry testee = new EmblEntry();
- String accession = "A1234";
- testee.setAccession(accession);
- /*
- * Make a (CDS) Feature with 4 locations
- */
- EmblFeature cds = new EmblFeature();
- Vector<EmblFeatureLocations> locs = new Vector<EmblFeatureLocations>();
- cds.setLocations(locs);
-
- /*
- * single range [10-20] for 'this' accession
- */
- EmblFeatureLocations loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(false);
- Vector<EmblFeatureLocElement> elements = new Vector<EmblFeatureLocElement>();
- EmblFeatureLocElement locElement = new EmblFeatureLocElement();
- locElement.setAccession(accession);
- BasePosition b1 = new BasePosition();
- b1.setPos("10");
- BasePosition b2 = new BasePosition();
- b2.setPos("20");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * complement range [30-40] - no accession
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("single");
- loc.setLocationComplement(true);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- b1 = new BasePosition();
- b1.setPos("30");
- b2 = new BasePosition();
- b2.setPos("40");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * join range [50-60] this accession, [70-80] another
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("join");
- loc.setLocationComplement(false);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- locElement.setAccession(accession);
- b1 = new BasePosition();
- b1.setPos("50");
- b2 = new BasePosition();
- b2.setPos("60");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- locElement = new EmblFeatureLocElement();
- locElement.setAccession("notme");
- b1 = new BasePosition();
- b1.setPos("70");
- b2 = new BasePosition();
- b2.setPos("80");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * complement range [90-100] wrong accession, [110-120] good
- * this should be the same as complement(join(90..100,110.120))
- * which is "join 90-100 and 110-120, then complement"
- */
- loc = new EmblFeatureLocations();
- loc.setLocationType("join");
- loc.setLocationComplement(true);
- elements = new Vector<EmblFeatureLocElement>();
- locElement = new EmblFeatureLocElement();
- locElement.setAccession("wrong");
- b1 = new BasePosition();
- b1.setPos("90");
- b2 = new BasePosition();
- b2.setPos("100");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- locElement = new EmblFeatureLocElement();
- locElement.setAccession(accession);
- b1 = new BasePosition();
- b1.setPos("110");
- b2 = new BasePosition();
- b2.setPos("120");
- locElement.setBasePositions(new BasePosition[] { b1, b2 });
- elements.add(locElement);
- loc.setLocElements(elements);
- locs.add(loc);
-
- /*
- * verify we pick out only ranges for A1234
- */
- int[] exons = testee.getCdsRanges(cds);
- assertEquals("[10, 20, 50, 60, 120, 110]",
- Arrays.toString(exons));
+ for (EmblFeature feature : ef.getEntries().get(0).getFeatures())
+ {
+ if ("CDS".equals(feature.getName()))
+ {
+ testee.parseCodingFeature(feature, "EMBL", dna, peptides);
+ }
+ }
+
+ /*
+ * peptides should now have five entries:
+ * EMBL product and two Uniprot accessions for the first CDS / translation
+ * EMBL product and one Uniprot accession for the second CDS / translation
+ */
+ assertEquals(5, peptides.size());
+ assertEquals("CAA30420.1", peptides.get(0).getName());
+ assertEquals("MLCF", peptides.get(0).getSequenceAsString());
+ assertEquals("UNIPROT|B0BCM4", peptides.get(1).getName());
+ assertEquals("MLCF", peptides.get(1).getSequenceAsString());
+ assertEquals("UNIPROT|P0CE20", peptides.get(2).getName());
+ assertEquals("MLCF", peptides.get(2).getSequenceAsString());
+ assertEquals("CAA30421.1", peptides.get(3).getName());
+ assertEquals("MSSS", peptides.get(3).getSequenceAsString());
+ assertEquals("UNIPROT|B0BCM3", peptides.get(4).getName());
+ assertEquals("MSSS", peptides.get(4).getSequenceAsString());
+
+ /*
+ * verify dna sequence has dbrefs with mappings to the peptide 'products'
+ */
+ DBRefEntry[] dbrefs = dna.getDBRefs();
+ assertEquals(3, dbrefs.length);
+ DBRefEntry dbRefEntry = dbrefs[0];
+ assertEquals("UNIPROT", dbRefEntry.getSource());
+ assertEquals("B0BCM4", dbRefEntry.getAccessionId());
+ assertSame(peptides.get(1), dbRefEntry.getMap().getTo());
+ List<int[]> fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
+ assertEquals(1, fromRanges.size());
+ assertEquals(57, fromRanges.get(0)[0]);
+ assertEquals(46, fromRanges.get(0)[1]);
+ List<int[]> toRanges = dbRefEntry.getMap().getMap().getToRanges();
+ assertEquals(1, toRanges.size());
+ assertEquals(1, toRanges.get(0)[0]);
+ assertEquals(4, toRanges.get(0)[1]);
+
+ dbRefEntry = dbrefs[1];
+ assertEquals("UNIPROT", dbRefEntry.getSource());
+ assertEquals("P0CE20", dbRefEntry.getAccessionId());
+ assertSame(peptides.get(2), dbRefEntry.getMap().getTo());
+ fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
+ assertEquals(1, fromRanges.size());
+ assertEquals(57, fromRanges.get(0)[0]);
+ assertEquals(46, fromRanges.get(0)[1]);
+ toRanges = dbRefEntry.getMap().getMap().getToRanges();
+ assertEquals(1, toRanges.size());
+ assertEquals(1, toRanges.get(0)[0]);
+ assertEquals(4, toRanges.get(0)[1]);
+
+ dbRefEntry = dbrefs[2];
+ assertEquals("UNIPROT", dbRefEntry.getSource());
+ assertEquals("B0BCM3", dbRefEntry.getAccessionId());
+ assertSame(peptides.get(4), dbRefEntry.getMap().getTo());
+ fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
+ assertEquals(1, fromRanges.size());
+ assertEquals(4, fromRanges.get(0)[0]);
+ assertEquals(15, fromRanges.get(0)[1]);
+ toRanges = dbRefEntry.getMap().getMap().getToRanges();
+ assertEquals(1, toRanges.size());
+ assertEquals(1, toRanges.get(0)[0]);
+ assertEquals(4, toRanges.get(0)[1]);
}
}
package jalview.datamodel.xdb.embl;
import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNull;
-import static org.testng.AssertJUnit.assertTrue;
import jalview.datamodel.DBRefEntry;
-import java.io.StringReader;
import java.util.Vector;
import org.testng.annotations.Test;
public class EmblFileTest
{
- // adapted from http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/embl/x53828/emblxml
- private static final String TESTDATA = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
- + "<EMBL_Services>"
- + "<entry accession=\"X53828\" version=\"3\" lastUpdated=\"2005-04-18\" releaseCreated=\"25\" releaseLastUpdated=\"83\">"
- + "<description>Chicken LDH-A mRNA for lactate dehydrogenase A chain (EC 1.1.1.27)</description>"
- + "<keyword>L-lactate dehydrogenase</keyword><keyword>chutney</keyword>"
- + "<dbreference db=\"EuropePMC\" primary=\"PMC1460223\" secondary=\"9649548\" />"
- + "<dbreference db=\"MD5\" primary=\"d3b68\" />"
- + "<feature name=\"CDS\"><dbreference db=\"GOA\" primary=\"P00340\" secondary=\"2.1\" /><dbreference db=\"InterPro\" primary=\"IPR001236\" />"
- + "<qualifier name=\"note\"><value>L-lactate dehydrogenase A-chain</value><value>pickle</value></qualifier>"
- + "<qualifier name=\"translation\"><value>MSLKDHLIHN</value><evidence>Keith</evidence></qualifier>"
- + "<location type=\"single\" complement=\"true\">"
- + "<locationElement type=\"range\" accession=\"X53828\" version=\"1\" complement=\"false\">"
- + "<basePosition type=\"simple\">60</basePosition><basePosition type=\"join\">1058</basePosition>"
- + "</locationElement></location></feature>"
- + "<sequence type=\"mRNA\" version=\"2\">GTGACG</sequence></entry></EMBL_Services>";
@Test(groups = { "Functional" })
public void testGetEmblFile()
{
- Vector<EmblEntry> entries = EmblFile.getEmblFile(
- new StringReader(TESTDATA)).getEntries();
+ Vector<EmblEntry> entries = EmblTestHelper.getEmblFile().getEntries();
assertEquals(1, entries.size());
EmblEntry entry = entries.get(0);
- assertEquals("X53828", entry.getAccession());
- assertEquals(
- "Chicken LDH-A mRNA for lactate dehydrogenase A chain (EC 1.1.1.27)",
- entry.getDesc());
- assertEquals("2005-04-18", entry.getLastUpdated());
+ assertEquals("X07547", entry.getAccession());
+ assertEquals("C. trachomatis plasmid", entry.getDescription());
+ assertEquals("STD", entry.getDataClass());
+ assertEquals("PRO", entry.getTaxonomicDivision());
+ assertEquals("1999-02-10", entry.getLastUpdatedDate());
+ assertEquals("58", entry.getLastUpdatedRelease());
+ assertEquals("1988-11-10", entry.getFirstPublicDate());
+ assertEquals("18", entry.getFirstPublicRelease());
+ assertEquals("genomic DNA", entry.getMoleculeType());
+ assertEquals("1", entry.getSequenceVersion());
+ assertEquals("8", entry.getEntryVersion());
+ assertEquals("linear", entry.getTopology());
+ assertEquals("7499", entry.getSequenceLength());
/*
* FIXME these assertions fail - values are null - why?? Adding or removing
* attributes in the test XML modifies behaviour. eg. inserting an attribute
* _before_ lastUpdated results in a null value in this field.
*/
- // assertEquals("25", entry.getRCreated());
- // assertEquals("83", entry.getRLastUpdated());
+ assertEquals("1988-11-10", entry.getFirstPublicDate());
+ assertEquals("18", entry.getFirstPublicRelease());
assertEquals(2, entry.getKeywords().size());
- assertEquals("L-lactate dehydrogenase", entry.getKeywords().get(0));
- assertEquals("chutney", entry.getKeywords().get(1));
+ assertEquals("plasmid", entry.getKeywords().get(0));
+ assertEquals("unidentified reading frame", entry.getKeywords().get(1));
/*
* dbrefs
assertEquals(2, entry.getDbRefs().size());
DBRefEntry dbref = entry.getDbRefs().get(0);
assertEquals("EuropePMC", dbref.getSource());
- assertEquals("PMC1460223", dbref.getAccessionId());
- assertEquals("9649548", dbref.getVersion());
+ assertEquals("PMC107176", dbref.getAccessionId());
+ assertEquals("9573186", dbref.getVersion());
dbref = entry.getDbRefs().get(1);
assertEquals("MD5", dbref.getSource());
- assertEquals("d3b68", dbref.getAccessionId());
+ assertEquals("ac73317", dbref.getAccessionId());
// blank version has been converted to "0"
assertEquals("0", dbref.getVersion());
/*
- * sequence features
+ * two sequence features for CDS
+ */
+ assertEquals(2, entry.getFeatures().size());
+ /*
+ * first CDS
*/
- assertEquals(1, entry.getFeatures().size());
EmblFeature ef = entry.getFeatures().get(0);
assertEquals("CDS", ef.getName());
+ assertEquals("complement(46..57)", ef.getLocation());
assertEquals(2, ef.getDbRefs().size());
dbref = ef.getDbRefs().get(0);
- assertEquals("GOA", dbref.getSource());
- assertEquals("P00340", dbref.getAccessionId());
+ assertEquals("UniProtKB/Swiss-Prot", dbref.getSource());
+ assertEquals("B0BCM4", dbref.getAccessionId());
assertEquals("2.1", dbref.getVersion());
dbref = ef.getDbRefs().get(1);
- assertEquals("InterPro", dbref.getSource());
- assertEquals("IPR001236", dbref.getAccessionId());
- // blank version converted to "0":
+ assertEquals("UniProtKB/Swiss-Prot", dbref.getSource());
+ assertEquals("P0CE20", dbref.getAccessionId());
+ // blank version gets converted to "0":
assertEquals("0", dbref.getVersion());
- assertEquals(2, ef.getQualifiers().size());
-
- // feature qualifiers
+ // CDS feature qualifiers
+ assertEquals(3, ef.getQualifiers().size());
Qualifier q = ef.getQualifiers().get(0);
assertEquals("note", q.getName());
assertEquals(2, q.getValues().length);
- assertEquals("L-lactate dehydrogenase A-chain", q.getValues()[0]);
+ assertEquals("ORF 8 (AA 1-330)", q.getValues()[0]);
assertEquals("pickle", q.getValues()[1]);
assertNull(q.getEvidence());
q = ef.getQualifiers().get(1);
+ assertEquals("protein_id", q.getName());
+ assertEquals(1, q.getValues().length);
+ assertEquals("CAA30420.1", q.getValues()[0]);
+ q = ef.getQualifiers().get(2);
assertEquals("translation", q.getName());
assertEquals(1, q.getValues().length);
- assertEquals("MSLKDHLIHN", q.getValues()[0]);
+ assertEquals("MLCF", q.getValues()[0]);
assertEquals(1, q.getEvidence().length);
assertEquals("Keith", q.getEvidence()[0]);
- // feature locations
- assertEquals(1, ef.getLocations().size());
- EmblFeatureLocations fl = ef.getLocations().get(0);
- assertEquals("single", fl.getLocationType());
- assertTrue(fl.isLocationComplement());
- assertEquals(1, fl.getLocElements().size());
- EmblFeatureLocElement le = fl.getLocElements().get(0);
- assertEquals("range", le.getType());
- assertEquals("X53828", le.getAccession());
- assertEquals("1", le.getVersion());
- assertFalse(le.isComplement());
- assertEquals(2, le.getBasePositions().length);
- BasePosition bp = le.getBasePositions()[0];
- assertEquals("simple", bp.getType());
- assertEquals("60", bp.getPos());
- bp = le.getBasePositions()[1];
- assertEquals("join", bp.getType());
- assertEquals("1058", bp.getPos());
+ /*
+ * second CDS
+ */
+ ef = entry.getFeatures().get(1);
+ assertEquals("CDS", ef.getName());
+ assertEquals("4..15", ef.getLocation());
+ assertEquals(1, ef.getDbRefs().size());
+ dbref = ef.getDbRefs().get(0);
+ assertEquals("UniProtKB/Swiss-Prot", dbref.getSource());
+ assertEquals("B0BCM3", dbref.getAccessionId());
+ assertEquals("0", dbref.getVersion());
+ assertEquals(2, ef.getQualifiers().size());
+ q = ef.getQualifiers().get(0);
+ assertEquals("protein_id", q.getName());
+ assertEquals(1, q.getValues().length);
+ assertEquals("CAA30421.1", q.getValues()[0]);
+ q = ef.getQualifiers().get(1);
+ assertEquals("translation", q.getName());
+ assertEquals(1, q.getValues().length);
+ assertEquals("MSSS", q.getValues()[0]);
/*
- * Sequence
+ * Sequence - verify newline not converted to space (JAL-2029)
*/
EmblSequence seq = entry.getSequence();
- assertEquals("mRNA", seq.getType());
- assertEquals("2", seq.getVersion());
- assertEquals("GTGACG", seq.getSequence());
+ assertEquals(
+ "GGTATGTCCTCTAGTACAAACACCCCCAATATTGTGATATAATTAAAAACATAGCAT",
+ seq.getSequence());
/*
* getSequence() converts empty DBRefEntry.version to "0"
--- /dev/null
+package jalview.datamodel.xdb.embl;
+
+import java.io.StringReader;
+
+public class EmblTestHelper
+{
+ // adapted from http://www.ebi.ac.uk/ena/data/view/X07547&display=xml
+ // dna and translations truncated for convenience
+ private static final String TESTDATA = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
+ + "<ROOT>"
+ + "<entry accession=\"X07547\" version=\"1\" entryVersion=\"8\""
+ + " dataClass=\"STD\" taxonomicDivision=\"PRO\""
+ + " moleculeType=\"genomic DNA\" sequenceLength=\"7499\" topology=\"linear\""
+ + " firstPublic=\"1988-11-10\" firstPublicRelease=\"18\""
+ + " lastUpdated=\"1999-02-10\" lastUpdatedRelease=\"58\">"
+ + "<secondaryAccession>X07574</secondaryAccession>"
+ + "<description>C. trachomatis plasmid</description>"
+ + "<keyword>plasmid</keyword><keyword>unidentified reading frame</keyword>"
+ + "<xref db=\"EuropePMC\" id=\"PMC107176\" secondaryId=\"9573186\" />"
+ + "<xref db=\"MD5\" id=\"ac73317\" />"
+ /*
+ * first CDS (range and translation changed to keep test data manageable)
+ */
+ + "<feature name=\"CDS\" location=\"complement(46..57)\">"
+ // test the case of >1 cross-ref to the same database (JAL-2029)
+ + "<xref db=\"UniProtKB/Swiss-Prot\" id=\"B0BCM4\" secondaryId=\"2.1\" />"
+ + "<xref db=\"UniProtKB/Swiss-Prot\" id=\"P0CE20\" />"
+ + "<qualifier name=\"note\"><value>ORF 8 (AA 1-330)</value><value>pickle</value></qualifier>"
+ + "<qualifier name=\"protein_id\"><value>CAA30420.1</value></qualifier>"
+ + "<qualifier name=\"translation\"><value>MLCF</value><evidence>Keith</evidence></qualifier>"
+ + "</feature>"
+ /*
+ * second CDS (range and translation changed to keep test data manageable)
+ */
+ + "<feature name=\"CDS\" location=\"4..15\">"
+ + "<xref db=\"UniProtKB/Swiss-Prot\" id=\"B0BCM3\" />"
+ + "<qualifier name=\"protein_id\"><value>CAA30421.1</value></qualifier>"
+ + "<qualifier name=\"translation\"><value>MSSS</value></qualifier>"
+ + "</feature>"
+ /*
+ * sequence (modified for test purposes)
+ * emulates EMBL XML 1.2 which splits sequence data every 60 characters
+ * see EmblSequence.setSequence
+ */
+ + "<sequence>GGTATGTCCTCTAGTACAAAC\n"
+ + "ACCCCCAATATTGTGATATAATTAAAAACATAGCAT"
+ + "</sequence></entry></ROOT>";
+
+ static EmblFile getEmblFile()
+ {
+ return EmblFile.getEmblFile(new StringReader(TESTDATA));
+ }
+}
*/
SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence()
.getSequenceFeatures(); // FER_CAPAA
- assertEquals(7, sfs.length);
+ assertEquals(8, sfs.length);
SequenceFeature sf = sfs[0];
+ assertEquals("Pfam family%LINK%", sf.description);
+ assertEquals(0, sf.begin);
+ assertEquals(0, sf.end);
+ assertEquals("uniprot", sf.featureGroup);
+ assertEquals("Pfam", sf.type);
+ assertEquals(1, sf.links.size());
+ assertEquals("Pfam family|http://pfam.xfam.org/family/PF00111",
+ sf.links.get(0));
+
+ sf = sfs[1];
assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
assertEquals(39, sf.begin);
assertEquals(39, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("METAL", sf.type);
- sf = sfs[1];
+ sf = sfs[2];
assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
assertEquals(44, sf.begin);
assertEquals(44, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("METAL", sf.type);
- sf = sfs[2];
+ sf = sfs[3];
assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
assertEquals(47, sf.begin);
assertEquals(47, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("METAL", sf.type);
- sf = sfs[3];
+ sf = sfs[4];
assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
assertEquals(77, sf.begin);
assertEquals(77, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("METAL", sf.type);
- sf = sfs[4];
+ sf = sfs[5];
assertEquals("Fer2 Status: True Positive Pfam 8_8%LINK%",
sf.description);
- assertEquals("Pfam 8_8|http://pfam.sanger.ac.uk/family/PF00111",
- sf.links.get(0).toString());
+ assertEquals("Pfam 8_8|http://pfam.xfam.org/family/PF00111",
+ sf.links.get(0));
assertEquals(8, sf.begin);
assertEquals(83, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("Pfam", sf.type);
- sf = sfs[5];
+ sf = sfs[6];
assertEquals("Ferredoxin_fold Status: True Positive ", sf.description);
assertEquals(3, sf.begin);
assertEquals(93, sf.end);
assertEquals("uniprot", sf.featureGroup);
assertEquals("Cath", sf.type);
- sf = sfs[6];
+ sf = sfs[7];
assertEquals(
"High confidence server. Only hits with scores over 0.8 are reported. PHOSPHORYLATION (T) 89_8%LINK%",
sf.description);
assertEquals(
"PHOSPHORYLATION (T) 89_8|http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P83527&service=NetPhos-2.0",
- sf.links.get(0).toString());
+ sf.links.get(0));
assertEquals(89, sf.begin);
assertEquals(89, sf.end);
assertEquals("netphos", sf.featureGroup);
+ "STARTGROUP\tuniprot\n"
+ "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\n"
+ "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\n"
- + "<html>Pfam domain<a href=\"http://pfam.sanger.ac.uk/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\n"
+ + "<html>Pfam domain<a href=\"http://pfam.xfam.org/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\n"
+ "ENDGROUP\tuniprot\n";
FeaturesFile featuresFile = new FeaturesFile(features,
FormatAdapter.PASTE);
+ "\nSTARTGROUP\tuniprot\n"
+ "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\t0.0\n"
+ "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\t0.0\n"
- + "<html>Pfam domain<a href=\"http://pfam.sanger.ac.uk/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\t0.0\n"
+ + "<html>Pfam domain<a href=\"http://pfam.xfam.org/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\t0.0\n"
+ "ENDGROUP\tuniprot\n";
assertEquals(expected, exported);
}
--- /dev/null
+package jalview.ws.ebi;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+
+import org.testng.annotations.Test;
+
+public class EBIFetchClientTest
+{
+ /**
+ * Test method that constructs URL to fetch from
+ */
+ @Test(groups = "Functional")
+ public void testBuildUrl()
+ {
+ /*
+ * EMBL
+ */
+ assertEquals("http://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
+ EBIFetchClient.buildUrl("X53838", "EMBL", "display=xml"));
+
+ /*
+ * EMBLCDS
+ */
+ assertEquals("http://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
+ EBIFetchClient.buildUrl("CAA37824", "EMBL", "display=xml"));
+
+ /*
+ * Uniprot
+ */
+ assertEquals(
+ "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/uniprot/p00340/uniprotxml",
+ EBIFetchClient.buildUrl("P00340", "UNIPROT", "uniprotxml"));
+
+ /*
+ * PDB / pdb
+ */
+ assertEquals("http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/pdb",
+ EBIFetchClient.buildUrl("3A6S", "PDB", "pdb"));
+
+ /*
+ * PDB / mmCIF
+ */
+ assertEquals(
+ "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/mmCIF",
+ EBIFetchClient.buildUrl("3A6S", "PDB", "mmCIF"));
+ }
+
+ /**
+ * Test method that parses db:id;id;id
+ */
+ @Test(groups = "Functional")
+ public void testParseIds()
+ {
+ /*
+ * pdb, two accessions
+ */
+ StringBuilder queries = new StringBuilder();
+ String db = EBIFetchClient.parseIds("pdb:3a6s;1A70", queries);
+ assertEquals("pdb", db);
+ assertEquals("3a6s,1A70", queries.toString());
+
+ /*
+ * pdb specified on second accession
+ */
+ queries.setLength(0);
+ queries = new StringBuilder();
+ db = EBIFetchClient.parseIds("3a6s;pdb:1A70", queries);
+ assertEquals("pdb", db);
+ assertEquals("3a6s,1A70", queries.toString());
+
+ /*
+ * uniprot, one accession
+ */
+ queries.setLength(0);
+ db = EBIFetchClient.parseIds("uniprot:P00340", queries);
+ assertEquals("uniprot", db);
+ assertEquals("P00340", queries.toString());
+
+ /*
+ * uniprot, one accession, appending to existing queries
+ */
+ queries.setLength(0);
+ queries.append("P30419");
+ db = EBIFetchClient.parseIds("uniprot:P00340", queries);
+ assertEquals("uniprot", db);
+ assertEquals("P30419,P00340", queries.toString());
+
+ /*
+ * pdb and uniprot mixed - rejected
+ */
+ queries.setLength(0);
+ db = EBIFetchClient.parseIds("pdb:3a6s;1a70;uniprot:P00340", queries);
+ assertNull(db);
+ assertEquals("3a6s,1a70", queries.toString());
+
+ /*
+ * pdb and PDB mixed - ok
+ */
+ queries.setLength(0);
+ db = EBIFetchClient.parseIds("pdb:3a6s;pdb:1a70;PDB:1QIP", queries);
+ assertEquals("PDB", db);
+ assertEquals("3a6s,1a70,1QIP", queries.toString());
+
+ /*
+ * no database (improper format)
+ */
+ queries.setLength(0);
+ db = EBIFetchClient.parseIds("P00340", queries);
+ assertNull(db);
+ assertEquals("P00340", queries.toString());
+ }
+}
--- /dev/null
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A class to check help file cross-references, and external URLs if internet
+ * access is available
+ *
+ * @author gmcarstairs
+ *
+ */
+public class HelpLinksChecker
+{
+ private static final String HELP_HS = "help.hs";
+
+ private static final String HELP_TOC_XML = "helpTOC.xml";
+
+ private static final String HELP_JHM = "help.jhm";
+
+ private static boolean internetAvailable = true;
+
+ private int targetCount = 0;
+
+ private int mapCount = 0;
+
+ private int internalHrefCount = 0;
+
+ private int anchorRefCount = 0;
+
+ private int externalHrefCount = 0;
+
+ private int invalidMapUrlCount = 0;
+
+ private int invalidTargetCount = 0;
+
+ private int invalidImageCount = 0;
+
+ private int invalidInternalHrefCount = 0;
+
+ private int invalidExternalHrefCount = 0;
+
+ /**
+ * The only parameter should be a path to the root of the help directory in
+ * the workspace
+ *
+ * @param args
+ * [0] path to the /html folder in the workspace
+ * @param args
+ * [1] (optional) -nointernet to suppress external link checking for
+ * a fast check of internal links only
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException
+ {
+ if (args.length == 0 || args.length > 2
+ || (args.length == 2 && !args[1].equals("-nointernet")))
+ {
+ System.out.println("Usage: <pathToHelpFolder> [-nointernet]");
+ return;
+ }
+
+ if (args.length == 2)
+ {
+ internetAvailable = false;
+ }
+
+ new HelpLinksChecker().checkLinks(args[0]);
+ }
+
+ /**
+ * Checks help links and reports results
+ *
+ * @param helpDirectoryPath
+ * @throws IOException
+ */
+ void checkLinks(String helpDirectoryPath) throws IOException
+ {
+ System.out.println("Checking help file links");
+ File helpFolder = new File(helpDirectoryPath);
+ if (!helpFolder.exists())
+ {
+ System.out.println("Can't find " + helpDirectoryPath);
+ return;
+ }
+
+ internetAvailable &= connectToUrl("http://www.example.com");
+
+ Map<String, String> tocTargets = checkHelpMappings(helpFolder);
+
+ Map<String, String> unusedTargets = new HashMap<String, String>(
+ tocTargets);
+
+ checkTableOfContents(helpFolder, tocTargets, unusedTargets);
+
+ checkHelpSet(helpFolder, tocTargets, unusedTargets);
+
+ checkHtmlFolder(new File(helpFolder, "html"));
+
+ reportResults(unusedTargets);
+ }
+
+ /**
+ * Checks all html files in the given directory or its sub-directories
+ *
+ * @param folder
+ * @throws IOException
+ */
+ private void checkHtmlFolder(File folder) throws IOException
+ {
+ File[] files = folder.listFiles();
+ for (File f : files)
+ {
+ if (f.isDirectory())
+ {
+ checkHtmlFolder(f);
+ }
+ else
+ {
+ if (f.getAbsolutePath().endsWith(".html"))
+ {
+ checkHtmlFile(f, folder);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks that any image attribute in help.hs is a valid target
+ *
+ * @param helpFolder
+ * @param tocTargets
+ * @param unusedTargets
+ * used targets are removed from here
+ */
+ private void checkHelpSet(File helpFolder,
+ Map<String, String> tocTargets, Map<String, String> unusedTargets)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(new File(
+ helpFolder, HELP_HS)));
+ String data = br.readLine();
+ int lineNo = 0;
+
+ while (data != null)
+ {
+ lineNo++;
+ String image = getAttribute(data, "image");
+ if (image != null)
+ {
+ unusedTargets.remove(image);
+ if (!tocTargets.containsKey(image))
+ {
+ System.out.println(String.format(
+ "Invalid image '%s' at line %d of %s", image, lineNo,
+ HELP_HS));
+ invalidImageCount++;
+ }
+ }
+ data = br.readLine();
+ }
+ br.close();
+ }
+
+ /**
+ * Print counts to sysout
+ *
+ * @param unusedTargets
+ */
+ private void reportResults(Map<String, String> unusedTargets)
+ {
+ System.out.println("\nResults:");
+ System.out.println(targetCount + " distinct help targets");
+ System.out.println(mapCount + " help mappings");
+ System.out.println(invalidTargetCount + " invalid targets");
+ System.out.println(unusedTargets.size() + " unused targets");
+ for (String target : unusedTargets.keySet())
+ {
+ System.out.println(String.format(" %s: %s", target,
+ unusedTargets.get(target)));
+ }
+ System.out.println(invalidMapUrlCount + " invalid map urls");
+ System.out.println(invalidImageCount + " invalid image attributes");
+ System.out.println(String.format(
+ "%d internal href links (%d with anchors - not checked)",
+ internalHrefCount, anchorRefCount));
+ System.out.println(invalidInternalHrefCount
+ + " invalid internal href links");
+ System.out.println(externalHrefCount + " external href links");
+ if (internetAvailable)
+ {
+ System.out.println(invalidExternalHrefCount
+ + " invalid external href links");
+ }
+ else
+ {
+ System.out
+ .println("External links not verified as internet not available");
+ }
+
+ }
+
+ /**
+ * Reads the given html file and checks any href attibute values are either
+ * <ul>
+ * <li>a valid relative file path, or</li>
+ * <li>a valid absolute URL (if external link checking is enabled)</li>
+ * </ul>
+ *
+ * @param htmlFile
+ * @param htmlFolder
+ * the parent folder (for validation of relative paths)
+ */
+ private void checkHtmlFile(File htmlFile, File htmlFolder)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(htmlFile));
+ String data = br.readLine();
+ int lineNo = 0;
+ while (data != null)
+ {
+ lineNo++;
+ String href = getAttribute(data, "href");
+ if (href != null)
+ {
+ String anchor = null;
+ int anchorPos = href.indexOf("#");
+ if (anchorPos != -1)
+ {
+ anchor = href.substring(anchorPos + 1);
+ href = href.substring(0, anchorPos);
+ }
+ boolean badLink = false;
+ if (href.startsWith("http"))
+ {
+ externalHrefCount++;
+ if (internetAvailable)
+ {
+ if (!connectToUrl(href))
+ {
+ badLink = true;
+ invalidExternalHrefCount++;
+ }
+ }
+ }
+ else
+ {
+ internalHrefCount++;
+ File hrefFile = href.equals("") ? htmlFile : new File(htmlFolder,
+ href);
+ if (!hrefFile.exists())
+ {
+ badLink = true;
+ invalidInternalHrefCount++;
+ }
+ if (anchor != null)
+ {
+ anchorRefCount++;
+ if (!badLink)
+ {
+ if (!checkAnchorExists(hrefFile, anchor))
+ {
+ System.out.println(String.format(
+ "Invalid anchor: %s at line %d of %s", anchor,
+ lineNo, getPath(htmlFile)));
+ }
+ }
+ }
+ }
+ if (badLink)
+ {
+ System.out.println(String.format(
+ "Invalid href %s at line %d of %s", href, lineNo,
+ getPath(htmlFile)));
+ }
+ }
+ data = br.readLine();
+ }
+ br.close();
+ }
+
+ /**
+ * Reads the file and checks for the presence of the given html anchor
+ *
+ * @param hrefFile
+ * @param anchor
+ * @return true if anchor is found else false
+ */
+ private boolean checkAnchorExists(File hrefFile, String anchor)
+ {
+ String nameAnchor = "<a name=\"" + anchor + "\"";
+ String idAnchor = "<a id=\"" + anchor + "\"";
+ boolean found = false;
+ try
+ {
+ BufferedReader br = new BufferedReader(new FileReader(hrefFile));
+ String data = br.readLine();
+ while (data != null)
+ {
+ if (data.contains(nameAnchor) || data.contains(idAnchor))
+ {
+ found = true;
+ break;
+ }
+ data = br.readLine();
+ }
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ return found;
+ }
+
+ /**
+ * Returns the part of the file path starting from /help/
+ *
+ * @param helpFile
+ * @return
+ */
+ private String getPath(File helpFile)
+ {
+ String path = helpFile.getPath();
+ int helpPos = path.indexOf("/help/");
+ return helpPos == -1 ? path : path.substring(helpPos);
+ }
+
+ /**
+ * Returns true if the URL returns an input stream, or false if the URL
+ * returns an error code or we cannot connect to it (e.g. no internet
+ * available)
+ *
+ * @param url
+ * @return
+ */
+ private boolean connectToUrl(String url)
+ {
+ try
+ {
+ URL u = new URL(url);
+ InputStream connection = u.openStream();
+ connection.close();
+ return true;
+ } catch (Throwable t)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Reads file help.jhm and checks that
+ * <ul>
+ * <li>each target attribute is in tocTargets</li>
+ * <li>each url attribute is a valid relative file link</li>
+ * </ul>
+ *
+ * @param helpFolder
+ */
+ private Map<String, String> checkHelpMappings(File helpFolder)
+ throws IOException
+ {
+ Map<String, String> targets = new HashMap<String, String>();
+ BufferedReader br = new BufferedReader(new FileReader(new File(
+ helpFolder, HELP_JHM)));
+ String data = br.readLine();
+ int lineNo = 0;
+ while (data != null)
+ {
+ lineNo++;
+
+ /*
+ * record target, check for duplicates
+ */
+ String target = getAttribute(data, "target");
+ if (target != null)
+ {
+ mapCount++;
+ if (targets.containsKey(target))
+ {
+ System.out.println(String.format(
+ "Duplicate target mapping to %s at line %d of %s",
+ target, lineNo, HELP_JHM));
+ }
+ else
+ {
+ targetCount++;
+ }
+ }
+
+ /*
+ * validate url
+ */
+ String url = getAttribute(data, "url");
+ if (url != null)
+ {
+ targets.put(target, url);
+ int anchorPos = url.indexOf("#");
+ if (anchorPos != -1)
+ {
+ url = url.substring(0, anchorPos);
+ }
+ if (!new File(helpFolder, url).exists())
+ {
+ System.out.println(String.format(
+ "Invalid url path '%s' at line %d of %s", url, lineNo,
+ HELP_JHM));
+ invalidMapUrlCount++;
+ }
+ }
+ data = br.readLine();
+ }
+ br.close();
+ return targets;
+ }
+
+ /**
+ * Reads file helpTOC.xml and reports any invalid targets
+ *
+ * @param helpFolder
+ * @param tocTargets
+ * @param unusedTargets
+ * used targets are removed from this map
+ *
+ * @return
+ * @throws IOException
+ */
+ private void checkTableOfContents(File helpFolder,
+ Map<String, String> tocTargets, Map<String, String> unusedTargets)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(new File(
+ helpFolder, HELP_TOC_XML)));
+ String data = br.readLine();
+ int lineNo = 0;
+ while (data != null)
+ {
+ lineNo++;
+ /*
+ * assuming no more than one "target" per line of file here
+ */
+ String target = getAttribute(data, "target");
+ if (target != null)
+ {
+ unusedTargets.remove(target);
+ if (!tocTargets.containsKey(target))
+ {
+ System.out.println(String.format(
+ "Invalid target '%s' at line %d of %s", target, lineNo,
+ HELP_TOC_XML));
+ invalidTargetCount++;
+ }
+ }
+ data = br.readLine();
+ }
+ br.close();
+ }
+
+ /**
+ * Returns the value of an attribute if found in the data, else null
+ *
+ * @param data
+ * @param attName
+ * @return
+ */
+ private static String getAttribute(String data, String attName)
+ {
+ /*
+ * make a partial attempt at ignoring within <!-- html comments -->
+ * (doesn't work if multi-line)
+ */
+ int commentStartPos = data.indexOf("<!--");
+ int commentEndPos = commentStartPos == -1 ? -1 : data.substring(
+ commentStartPos + 4).indexOf("-->");
+ String value = null;
+ String match = attName + "=\"";
+ int attPos = data.indexOf(match);
+ if (attPos > 0
+ && (commentStartPos == -1 || attPos < commentStartPos || attPos > commentEndPos))
+ {
+ data = data.substring(attPos + match.length());
+ value = data.substring(0, data.indexOf("\""));
+ }
+ return value;
+ }
+}
</property>
</object>
</method>
+ <method name="addElement">
+ <object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="1000ddddfab939">
+ <property name="belongsToUninstallPhase">
+ <boolean>false</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ <property name="unixPermissions">
+ <string><![CDATA[664]]></string>
+ </property>
+ <property name="sourceName">
+ <string><![CDATA[servlet-api-3.1.jar]]></string>
+ </property>
+ <property name="overrideUnixPermissions">
+ <boolean>false</boolean>
+ </property>
+ <property name="sourcePath">
+ <string><![CDATA[/home/cruisecontrol/jalview/lib/]]></string>
+ </property>
+ <property name="shouldUninstall">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="destinationName">
+ <string><![CDATA[servlet-api-3.1.jar]]></string>
+ </property>
+ <property name="fileSize">
+ <long>16046</long>
+ </property>
+ <property name="macBinary">
+ <boolean>false</boolean>
+ </property>
+ <property name="targetCheckKind">
+ <int>0</int>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ </object>
+ </method>
</object>
</property>
<property name="rulesFailedMessage">
<object refID="1f46efeefab93"/>
<object refID="1936efeefab93"/>
<object refID="1000ddddfab93"/>
+ <object refID="1000ddddfab939"/>
<object refID="10936efeefab93"/>
<object refID="11936efeefab93"/>
<object refID="12936efeefab93"/>
<object refID="1f46efeefab93"/>
<object refID="1936efeefab93"/>
<object refID="1000ddddfab93"/>
+ <object refID="1000ddddfab939"/>
<object refID="10936efeefab93"/>
<object refID="11936efeefab93"/>
<object refID="12936efeefab93"/>
--- /dev/null
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.TreeSet;
+
+/**
+ * This class scans Java source files for calls to MessageManager and reports
+ * <ul>
+ * <li>calls using keys not found in Messages.properties</li>
+ * <li>any unused keys in Messages.properties</li>
+ * </ul>
+ * It does not handle dynamically constructed keys, these are reported as
+ * possible errors for manual inspection. <br>
+ * For comparing translated bundles with Messages.properties, see i18nAnt.xml
+ *
+ * @author gmcarstairs
+ *
+ */
+public class MessageBundleChecker
+{
+ /*
+ * number of text lines to read at a time in order to parse
+ * code that is split over several lines
+ */
+ static int bufferSize = 3;
+
+ static final String METHOD1 = "MessageManager.getString(";
+
+ static final String METHOD2 = "MessageManager.getStringOrReturn(";
+
+ static final String METHOD3 = "MessageManager.formatMessage(";
+
+ static final String[] METHODS = { METHOD1, METHOD2, METHOD3 };
+
+ /*
+ * root of the Java source folders we want to scan
+ */
+ String sourcePath;
+
+ /*
+ * contents of Messages.properties
+ */
+ private Properties messages;
+
+ /*
+ * keys from Messages.properties
+ * we remove entries from here as they are found to be used
+ * any left over are unused entries
+ */
+ private TreeSet<String> messageKeys;
+
+ private int javaCount;
+
+ private HashSet<String> invalidKeys;
+
+ /**
+ * Runs the scan given the path to the root of Java source directories
+ *
+ * @param args
+ * [0] path to the source folder to scan
+ * @param args
+ * [1] (optional) read buffer size (default is 3); increasing this
+ * may detect more results but will give higher error counts due to
+ * double counting of the same code
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException
+ {
+ if (args.length != 1 && args.length != 2)
+ {
+ System.out.println("Usage: <pathToSourceFolder> [readBufferSize]");
+ return;
+ }
+ if (args.length == 2)
+ {
+ bufferSize = Integer.valueOf(args[1]);
+ }
+ new MessageBundleChecker().doMain(args[0]);
+ }
+
+ /**
+ * Main method to perform the work
+ *
+ * @param srcPath
+ * @throws IOException
+ */
+ private void doMain(String srcPath) throws IOException
+ {
+ System.out.println("Scanning " + srcPath
+ + " for calls to MessageManager");
+ sourcePath = srcPath;
+ loadMessages();
+ File dir = new File(srcPath);
+ if (!dir.exists())
+ {
+ System.out.println(srcPath + " not found");
+ return;
+ }
+ invalidKeys = new HashSet<String>();
+ if (dir.isDirectory())
+ {
+ scanDirectory(dir);
+ }
+ else
+ {
+ scanFile(dir);
+ }
+ reportResults();
+ }
+
+ /**
+ * Prints out counts to sysout
+ */
+ private void reportResults()
+ {
+ System.out.println("\nScanned " + javaCount + " source files");
+ System.out.println("Message.properties has " + messages.size()
+ + " keys");
+ System.out.println("Found " + invalidKeys.size()
+ + " possibly invalid parameter calls");
+
+ System.out.println(messageKeys.size()
+ + " keys not found, possibly unused");
+ for (String key : messageKeys)
+ {
+ System.out.println(" " + key);
+ }
+ }
+
+ /**
+ * Scan all files within a directory
+ *
+ * @param dir
+ * @throws IOException
+ */
+ private void scanDirectory(File dir) throws IOException
+ {
+ File[] files = dir.listFiles();
+ if (files != null)
+ {
+ for (File f : files)
+ {
+ if (f.isDirectory())
+ {
+ scanDirectory(f);
+ }
+ else
+ {
+ scanFile(f);
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan a Java file
+ *
+ * @param f
+ */
+ private void scanFile(File f) throws IOException
+ {
+ String path = f.getPath();
+ if (!path.endsWith(".java"))
+ {
+ return;
+ }
+ javaCount++;
+
+ String[] lines = new String[bufferSize];
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ for (int i = 0; i < bufferSize; i++)
+ {
+ String readLine = br.readLine();
+ lines[i] = stripCommentsAndTrim(readLine);
+ }
+
+ int lineNo = 0;
+
+ while (lines[bufferSize - 1] != null)
+ {
+ lineNo++;
+ inspectSourceLines(path, lineNo, lines);
+
+ for (int i = 0; i < bufferSize - 1; i++)
+ {
+ lines[i] = lines[i + 1];
+ }
+ lines[bufferSize - 1] = stripCommentsAndTrim(br.readLine());
+ }
+ br.close();
+
+ }
+
+ /*
+ * removes anything after (and including) '//'
+ */
+ private String stripCommentsAndTrim(String line)
+ {
+ if (line != null)
+ {
+ int pos = line.indexOf("//");
+ if (pos != -1)
+ {
+ line = line.substring(0, pos);
+ }
+ line = line.replace("\t", " ").trim();
+ }
+ return line;
+ }
+
+ /**
+ * Look for calls to MessageManager methods, possibly split over two or more
+ * lines
+ *
+ * @param path
+ * @param lineNo
+ * @param lines
+ */
+ private void inspectSourceLines(String path, int lineNo, String[] lines)
+ {
+ String lineNos = String.format("%d-%d", lineNo, lineNo + lines.length
+ - 1);
+ String combined = combineLines(lines);
+ for (String method : METHODS)
+ {
+ int pos = combined.indexOf(method);
+ if (pos == -1)
+ {
+ continue;
+ }
+ String methodArgs = combined.substring(pos + method.length());
+ if ("".equals(methodArgs))
+ {
+ /*
+ * continues on next line - catch in the next read loop iteration
+ */
+ continue;
+ }
+ if (!methodArgs.startsWith("\""))
+ {
+ System.out.println(String.format(
+ "Possible dynamic key at %s line %s %s",
+ path.substring(sourcePath.length()), lineNos, combined));
+ continue;
+ }
+ methodArgs = methodArgs.substring(1);
+ int quotePos = methodArgs.indexOf("\"");
+ if (quotePos == -1)
+ {
+ System.out.println(String.format("Trouble parsing %s line %s %s",
+ path.substring(sourcePath.length()), lineNos, combined));
+ continue;
+ }
+ String messageKey = methodArgs.substring(0, quotePos);
+ if (!this.messages.containsKey(messageKey))
+ {
+ System.out.println(String.format(
+ "Unmatched key '%s' at line %s of %s", messageKey, lineNos,
+ path.substring(sourcePath.length())));
+ if (!invalidKeys.contains(messageKey))
+ {
+ invalidKeys.add(messageKey);
+ }
+ }
+ messageKeys.remove(messageKey);
+ }
+ }
+
+ private String combineLines(String[] lines)
+ {
+ String combined = "";
+ if (lines != null)
+ {
+ for (String line : lines)
+ {
+ if (line != null)
+ {
+ combined += line;
+ }
+ }
+ }
+ return combined;
+ }
+
+ /**
+ * Loads properties from Message.properties
+ *
+ * @throws IOException
+ */
+ void loadMessages() throws IOException
+ {
+ messages = new Properties();
+ FileReader reader = new FileReader(new File(sourcePath,
+ "../resources/lang/Messages.properties"));
+ messages.load(reader);
+ reader.close();
+
+ messageKeys = new TreeSet<String>();
+ for (Object key : messages.keySet())
+ {
+ messageKeys.add((String) key);
+ }
+
+ }
+
+}