jalview.release=releases/Release_2_11_1_Branch
-jalview.version=2.11.1.0
+jalview.version=2.11.1.1
+/* Convention for properties. Read from gradle.properties, use lower_case_underlines for property names.
+ * For properties set within build.gradle, use camelCaseNoSpace.
+ */
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.internal.os.OperatingSystem
import org.gradle.plugins.ide.eclipse.model.Output
mavenCentral()
mavenLocal()
}
- dependencies {
- classpath 'org.openclover:clover:4.4.1'
- }
}
sourceDir = string("${jalviewDir}/${bareSourceDir}")
resourceDir = string("${jalviewDir}/${resource_dir}")
bareTestSourceDir = string(test_source_dir)
- testSourceDir = string("${jalviewDir}/${bareTestSourceDir}")
+ testDir = string("${jalviewDir}/${bareTestSourceDir}")
- // clover
- cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
- cloverDb = string("${buildDir}/clover/clover.db")
classesDir = string("${jalviewDir}/${classes_dir}")
- if (clover.equals("true")) {
- use_clover = true
- classesDir = string("${buildDir}/${cloverClassesDir}")
- } else {
- use_clover = false
- classesDir = string("${jalviewDir}/${classes_dir}")
- }
- classes = classesDir
+ // clover
+ useClover = clover.equals("true")
+ cloverBuildDir = "${buildDir}/clover"
+ cloverInstrDir = file("${cloverBuildDir}/clover-instr")
+ cloverClassesDir = file("${cloverBuildDir}/clover-classes")
+ cloverReportDir = file("${buildDir}/reports/clover")
+ cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
+ cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
+ //cloverTestClassesDir = cloverClassesDir
+ cloverDb = string("${cloverBuildDir}/clover.db")
+
+ resourceClassesDir = useClover ? cloverClassesDir : classesDir
+
+ testSourceDir = useClover ? cloverTestInstrDir : testDir
+ testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
buildDist = true
getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
jvlChannelName += "_${getdownChannelName}"
// automatically add the test group Not-bamboo for exclusion
- if ("".equals(testngExcludedGroups)) {
- testngExcludedGroups = "Not-bamboo"
+ if ("".equals(testng_excluded_groups)) {
+ testng_excluded_groups = "Not-bamboo"
}
install4jExtraScheme = "jalviewb"
break
getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
- if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
+ if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
} else {
- packageDir = string("${ARCHIVEDIR}/${packageDir}")
+ package_dir = string("${ARCHIVEDIR}/${package_dir}")
buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
buildDist = false
}
getdownChannelName = string("archive/${JALVIEW_VERSION}")
getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
getdownAppBase = file(getdownWebsiteDir).toURI().toString()
- if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
+ if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
} else {
- packageDir = string("${ARCHIVEDIR}/${packageDir}")
+ package_dir = string("${ARCHIVEDIR}/${package_dir}")
buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
buildDist = false
}
- buildingHTML = string("${jalviewDir}/${docDir}/building.html")
- helpFile = string("${classesDir}/${help_dir}/help.jhm")
+ buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
+ helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
helpParentDir = string("${jalviewDir}/${help_parent_dir}")
helpSourceDir = string("${helpParentDir}/${help_dir}")
srcDirs += helpParentDir
}
- jar.destinationDir = file("${jalviewDir}/${packageDir}")
+ jar.destinationDir = file("${jalviewDir}/${package_dir}")
compileClasspath = files(sourceSets.main.java.outputDir)
- //compileClasspath += files(sourceSets.main.resources.srcDirs)
compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
runtimeClasspath = compileClasspath
clover {
java {
- srcDirs = [ cloverInstrDir ]
- outputDir = file("${buildDir}/${cloverClassesDir}")
+ srcDirs cloverInstrDir
+ outputDir = cloverClassesDir
}
resources {
srcDirs = sourceSets.main.resources.srcDirs
}
- compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
- compileClasspath += files(sourceSets.main.java.outputDir)
- compileClasspath += sourceSets.main.compileClasspath
- compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
+
+ compileClasspath = files( sourceSets.clover.java.outputDir )
+ //compileClasspath += files( testClassesDir )
compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
+ compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
+ compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
runtimeClasspath = compileClasspath
}
test {
java {
srcDirs testSourceDir
- outputDir = file("${jalviewDir}/${testOutputDir}")
+ outputDir = file(testClassesDir)
}
resources {
- srcDirs = sourceSets.main.resources.srcDirs
+ srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
}
compileClasspath = files( sourceSets.test.java.outputDir )
-
- if (use_clover) {
- compileClasspath = sourceSets.clover.compileClasspath
- } else {
- compileClasspath += files(sourceSets.main.java.outputDir)
- }
-
- compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
- compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
- compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
+ compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
+ compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
runtimeClasspath = compileClasspath
}
-}
-
-
-// clover bits
-dependencies {
- if (use_clover) {
- cloverCompile 'org.openclover:clover:4.4.1'
- testCompile 'org.openclover:clover:4.4.1'
- }
-}
-configurations {
- cloverRuntime
- cloverRuntime.extendsFrom cloverCompile
}
}
-task cloverInstr {
- // only instrument source, we build test classes as normal
- inputs.files files (sourceSets.main.allJava,sourceSets.test.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
- outputs.dir cloverInstrDir
+// clover bits
+
+task cleanClover {
doFirst {
- delete cloverInstrDir
- def argsList = [
- "--initstring",
- cloverDb,
- "-d",
- cloverInstrDir.getPath(),
- ]
- argsList.addAll(
- inputs.files.files.collect(
- { file -> file.absolutePath }
- )
+ delete cloverBuildDir
+ delete cloverReportDir
+ }
+}
+
+
+task cloverInstrJava(type: JavaExec) {
+ group = "Verification"
+ description = "Create clover instrumented source java files"
+
+ dependsOn cleanClover
+
+ inputs.files(sourceSets.main.allJava)
+ outputs.dir(cloverInstrDir)
+
+ //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
+ classpath = sourceSets.clover.compileClasspath
+ main = "com.atlassian.clover.CloverInstr"
+
+ def argsList = [
+ "--encoding",
+ "UTF-8",
+ "--initstring",
+ cloverDb,
+ "--destdir",
+ cloverInstrDir.getPath(),
+ ]
+ def srcFiles = sourceSets.main.allJava.files
+ argsList.addAll(
+ srcFiles.collect(
+ { file -> file.absolutePath }
)
- String[] args = argsList.toArray()
- println("About to instrument "+args.length +" files")
- com.atlassian.clover.CloverInstr.mainImpl(args)
+ )
+ args argsList.toArray()
+
+ doFirst {
+ delete cloverInstrDir
+ println("Clover: About to instrument "+srcFiles.size() +" files")
}
}
+task cloverInstrTests(type: JavaExec) {
+ group = "Verification"
+ description = "Create clover instrumented source test files"
+
+ dependsOn cleanClover
+
+ inputs.files(testDir)
+ outputs.dir(cloverTestInstrDir)
+
+ classpath = sourceSets.clover.compileClasspath
+ main = "com.atlassian.clover.CloverInstr"
+
+ def argsList = [
+ "--encoding",
+ "UTF-8",
+ "--initstring",
+ cloverDb,
+ "--srcdir",
+ testDir,
+ "--destdir",
+ cloverTestInstrDir.getPath(),
+ ]
+ args argsList.toArray()
+
+ doFirst {
+ delete cloverTestInstrDir
+ println("Clover: About to instrument test files")
+ }
+}
+
+
+task cloverInstr {
+ group = "Verification"
+ description = "Create clover instrumented all source files"
+
+ dependsOn cloverInstrJava
+ dependsOn cloverInstrTests
+}
+
+
cloverClasses.dependsOn cloverInstr
-task cloverReport {
+task cloverConsoleReport(type: JavaExec) {
group = "Verification"
- description = "Creates the Clover report"
- inputs.dir "${buildDir}/clover"
- outputs.dir "${reportsDir}/clover"
+ description = "Creates clover console report"
+
onlyIf {
file(cloverDb).exists()
}
- doFirst {
- def argsList = [
- "--initstring",
- cloverDb,
- "-o",
- "${reportsDir}/clover"
- ]
- String[] args = argsList.toArray()
- com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
-
- // and generate ${reportsDir}/clover/clover.xml
- args = [
- "--initstring",
- cloverDb,
- "-o",
- "${reportsDir}/clover/clover.xml"
- ].toArray()
- com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
+
+ inputs.dir cloverClassesDir
+
+ classpath = sourceSets.clover.runtimeClasspath
+ main = "com.atlassian.clover.reporters.console.ConsoleReporter"
+
+ if (cloverreport_mem.length() > 0) {
+ maxHeapSize = cloverreport_mem
+ }
+ if (cloverreport_jvmargs.length() > 0) {
+ jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
+ }
+
+ def argsList = [
+ "--alwaysreport",
+ "--initstring",
+ cloverDb,
+ "--unittests"
+ ]
+
+ args argsList.toArray()
+}
+
+
+task cloverHtmlReport(type: JavaExec) {
+ group = "Verification"
+ description = "Creates clover HTML report"
+
+ onlyIf {
+ file(cloverDb).exists()
+ }
+
+ def cloverHtmlDir = cloverReportDir
+ inputs.dir cloverClassesDir
+ outputs.dir cloverHtmlDir
+
+ classpath = sourceSets.clover.runtimeClasspath
+ main = "com.atlassian.clover.reporters.html.HtmlReporter"
+
+ if (cloverreport_mem.length() > 0) {
+ maxHeapSize = cloverreport_mem
+ }
+ if (cloverreport_jvmargs.length() > 0) {
+ jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
+ }
+
+ def argsList = [
+ "--alwaysreport",
+ "--initstring",
+ cloverDb,
+ "--outputdir",
+ cloverHtmlDir
+ ]
+
+ if (cloverreport_html_options.length() > 0) {
+ argsList += cloverreport_html_options.split(" ")
+ }
+
+ args argsList.toArray()
+}
+
+
+task cloverXmlReport(type: JavaExec) {
+ group = "Verification"
+ description = "Creates clover XML report"
+
+ onlyIf {
+ file(cloverDb).exists()
}
+
+ def cloverXmlFile = "${cloverReportDir}/clover.xml"
+ inputs.dir cloverClassesDir
+ outputs.file cloverXmlFile
+
+ classpath = sourceSets.clover.runtimeClasspath
+ main = "com.atlassian.clover.reporters.xml.XMLReporter"
+
+ if (cloverreport_mem.length() > 0) {
+ maxHeapSize = cloverreport_mem
+ }
+ if (cloverreport_jvmargs.length() > 0) {
+ jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
+ }
+
+ def argsList = [
+ "--alwaysreport",
+ "--initstring",
+ cloverDb,
+ "--outfile",
+ cloverXmlFile
+ ]
+
+ if (cloverreport_xml_options.length() > 0) {
+ argsList += cloverreport_xml_options.split(" ")
+ }
+
+ args argsList.toArray()
+}
+
+
+task cloverReport {
+ group = "Verification"
+ description = "Creates clover reports"
+
+ dependsOn cloverXmlReport
+ dependsOn cloverHtmlReport
}
options.compilerArgs += additional_compiler_args
print ("Setting target compatibility to "+targetCompatibility+"\n")
}
- classpath += configurations.cloverRuntime
-}
-
-
-task cleanClover {
- doFirst {
- delete cloverInstrDir
- delete cloverDb
- }
+ //classpath += configurations.cloverRuntime
}
// end clover bits
compileTestJava {
- if (use_clover) {
- dependsOn compileCloverJava
- classpath += configurations.cloverRuntime
- } else {
- classpath += sourceSets.main.runtimeClasspath
- }
doFirst {
sourceCompatibility = compile_source_compatibility
targetCompatibility = compile_target_compatibility
task convertBuildingMD(type: Exec) {
dependsOn cleanBuildingHTML
- def buildingMD = "${jalviewDir}/${docDir}/building.md"
- def css = "${jalviewDir}/${docDir}/github.css"
+ def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
+ def css = "${jalviewDir}/${doc_dir}/github.css"
def pandoc = null
pandoc_exec.split(",").each {
task syncDocs(type: Sync) {
dependsOn convertBuildingMD
- def syncDir = "${classesDir}/${docDir}"
- from fileTree("${jalviewDir}/${docDir}")
+ def syncDir = "${resourceClassesDir}/${doc_dir}"
+ from fileTree("${jalviewDir}/${doc_dir}")
into syncDir
}
task copyHelp(type: Copy) {
def inputDir = helpSourceDir
- def outputDir = "${classesDir}/${help_dir}"
+ def outputDir = "${resourceClassesDir}/${help_dir}"
from(inputDir) {
exclude '**/*.gif'
exclude '**/*.jpg'
task syncLib(type: Sync) {
- def syncDir = "${classesDir}/${libDistDir}"
+ def syncDir = "${resourceClassesDir}/${libDistDir}"
from fileTree("${jalviewDir}/${libDistDir}")
into syncDir
}
task syncResources(type: Sync) {
from resourceDir
include "**/*.*"
- into "${classesDir}"
+ into "${resourceClassesDir}"
preserve {
include "**"
}
//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
test {
dependsOn prepare
- dependsOn compileJava
- if (use_clover) {
- dependsOn cloverInstr
- }
+ //dependsOn compileJava ////? DELETE
- if (use_clover) {
- print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
+ if (useClover) {
+ dependsOn cloverClasses
+ } else { //?
+ dependsOn compileJava //?
}
useTestNG() {
- includeGroups testngGroups
- excludeGroups testngExcludedGroups
+ includeGroups testng_groups
+ excludeGroups testng_excluded_groups
preserveOrder true
useDefaultListeners=true
}
workingDir = jalviewDir
//systemProperties 'clover.jar' System.properties.clover.jar
+ def testLaf = project.findProperty("test_laf")
+ if (testLaf != null) {
+ println("Setting Test LaF to '${testLaf}'")
+ systemProperty "laf", testLaf
+ }
+ def testHiDPIScale = project.findProperty("test_HiDPIScale")
+ if (testHiDPIScale != null) {
+ println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
+ systemProperty "sun.java2d.uiScale", testHiDPIScale
+ }
sourceCompatibility = compile_source_compatibility
targetCompatibility = compile_target_compatibility
jvmArgs += additional_compiler_args
+ doFirst {
+ if (useClover) {
+ println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
+ }
+ }
}
task compileLinkCheck(type: JavaCompile) {
options.fork = true
- classpath = files("${jalviewDir}/${utilsDir}")
- destinationDir = file("${jalviewDir}/${utilsDir}")
- source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
-
- inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
- inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
- outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
- outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
+ classpath = files("${jalviewDir}/${utils_dir}")
+ destinationDir = file("${jalviewDir}/${utils_dir}")
+ source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
+
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
+ outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
}
task linkCheck(type: JavaExec) {
dependsOn prepare, compileLinkCheck
- def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
- classpath = files("${jalviewDir}/${utilsDir}")
+ def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
+ classpath = files("${jalviewDir}/${utils_dir}")
main = "HelpLinksChecker"
workingDir = jalviewDir
args = [ "${classesDir}/${help_dir}", "-nointernet" ]
// import the pubhtmlhelp target
ant.properties.basedir = "${jalviewDir}"
ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
-ant.importBuild "${utilsDir}/publishHelp.xml"
+ant.importBuild "${utils_dir}/publishHelp.xml"
task cleanPackageDir(type: Delete) {
doFirst {
- delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
+ delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
}
}
dependsOn createBuildProperties
manifest {
- attributes "Main-Class": mainClass,
+ attributes "Main-Class": main_class,
"Permissions": "all-permissions",
"Application-Name": "Jalview Desktop",
"Codebase": application_codebase
}
- destinationDir = file("${jalviewDir}/${packageDir}")
+ destinationDir = file("${jalviewDir}/${package_dir}")
archiveName = rootProject.name+".jar"
exclude "cache*/**"
exclude "**/*.jar.*"
inputs.dir(classesDir)
- outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
+ outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
}
task copyJars(type: Copy) {
from fileTree(dir: classesDir, include: "**/*.jar").files
- into "${jalviewDir}/${packageDir}"
+ into "${jalviewDir}/${package_dir}"
}
// doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
task syncJars(type: Sync) {
from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
- into "${jalviewDir}/${packageDir}"
+ into "${jalviewDir}/${package_dir}"
preserve {
include jar.archiveName
}
dependsOn cleanPackageDir
dependsOn syncJars
dependsOn jar
- outputs.dir("${jalviewDir}/${packageDir}")
+ outputs.dir("${jalviewDir}/${package_dir}")
}
manifest {
attributes 'Implementation-Version': JALVIEW_VERSION
}
- mainClassName = shadowJarMainClass
+ mainClassName = shadow_jar_main_class
mergeServiceFiles()
classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
minimize()
}
def codeFiles = []
- fileTree(file(packageDir)).each{ f ->
+ fileTree(file(package_dir)).each{ f ->
if (f.isDirectory()) {
def files = fileTree(dir: f, include: ["*"]).getFiles()
codeFiles += files
// getdown-launcher.jar should not be in main application class path so the main application can move it when updated. Listed as a resource so it gets updated.
//getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
getdownTextString += "resource = ${getdown_launcher_new}\n"
- getdownTextString += "class = ${mainClass}\n"
+ getdownTextString += "class = ${main_class}\n"
def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
getdown_txt.write(getdownTextString)
}
if (buildDist) {
- inputs.dir("${jalviewDir}/${packageDir}")
+ inputs.dir("${jalviewDir}/${package_dir}")
}
outputs.dir(getdownWebsiteDir)
outputs.dir(getdownFilesDir)
-1.8.3-1.2.4_FJVL
+1.8.3-1.2.6_FJVL
-1.8.3-1.2.4_JVL
+1.8.3-1.2.6_JVL
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.2.4_FJVL</version>
+ <version>1.8.3-1.2.6_FJVL</version>
</parent>
<artifactId>getdown-ant</artifactId>
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.2.4_FJVL</version>
+ <version>1.8.3-1.2.6_FJVL</version>
</parent>
<artifactId>getdown-core</artifactId>
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
+import jalview.bin.HiDPISetting;
import jalview.bin.MemorySetting;
//import com.install4j.api.launcher.Variables;
args.add("-Dinstaller_template_version=" + System.getProperty("installer_template_version"));
args.add("-Dlauncher_version=" + Build.version());
+ // set HiDPI property if wanted
+ String scalePropertyArg = HiDPISetting.getScalePropertyArg();
+ if (scalePropertyArg != null)
+ {
+ args.add(scalePropertyArg);
+ }
+
// set the native library path if we have native resources
// @TODO optional getdown.txt parameter to set addCurrentLibraryPath to true or false?
ClassPath javaLibPath = PathBuilder.buildLibsPath(this, true);
+/*
+ * 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.bin;
import java.lang.management.ManagementFactory;
--- /dev/null
+package jalview.bin;
+
+import java.awt.HeadlessException;
+import java.awt.Toolkit;
+
+public class HiDPISetting
+{
+ private static final int hidpiThreshold = 160;
+
+ private static final int hidpiMultiThreshold = 240;
+
+ private static final int bigScreenThreshold = 1400;
+
+ private static final String scalePropertyName = "sun.java2d.uiScale";
+
+ private static final boolean isLinux;
+
+ // private static final boolean isAMac;
+
+ // private static final boolean isWindows;
+
+ public static final String setHiDPIPropertyName = "setHiDPI";
+
+ public static final String setHiDPIScalePropertyName = "setHiDPIScale";
+
+ private static boolean setHiDPI = false;
+
+ private static int setHiDPIScale = 0;
+
+ public static int dpi = 0;
+
+ public static int mindimension = 0;
+
+ public static int width = 0;
+
+ public static int scale = 0;
+
+ private static boolean doneInit = false;
+
+ private static boolean allowScalePropertyArg = false;
+
+ static
+ {
+ String system = System.getProperty("os.name") == null ? null
+ : System.getProperty("os.name").toLowerCase();
+ if (system != null)
+ {
+ isLinux = system.indexOf("linux") > -1;
+ // isAMac = system.indexOf("mac") > -1;
+ // isWindows = system.indexOf("windows") > -1;
+ }
+ else
+ {
+ isLinux = false;
+ // isAMac = isWindows = false;
+ }
+ }
+
+ private static void init()
+ {
+ if (doneInit)
+ {
+ return;
+ }
+
+ // get and use command line property values first
+ String setHiDPIProperty = System.getProperty(setHiDPIPropertyName);
+ setHiDPI = setHiDPIProperty != null
+ && setHiDPIProperty.equalsIgnoreCase("true");
+
+ String setHiDPIScaleProperty = System
+ .getProperty(setHiDPIScalePropertyName);
+ if (setHiDPIScaleProperty != null)
+ {
+ try
+ {
+ setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty);
+ } catch (NumberFormatException e)
+ {
+ System.err.println(setHiDPIScalePropertyName + " property give ("
+ + setHiDPIScaleProperty + ") but not parseable as integer");
+ }
+ }
+ if (setHiDPI && setHiDPIScale > 0)
+ {
+ setHiDPIScale(setHiDPIScale);
+ return;
+ }
+
+ // check to see if the scale property has already been set by something else
+ // (e.g. the OS)
+ String existingProperty = System.getProperty(scalePropertyName);
+ if (existingProperty != null)
+ {
+ try
+ {
+ int existingPropertyVal = Integer.parseInt(existingProperty);
+ System.out.println("Existing " + scalePropertyName + " is "
+ + existingPropertyVal);
+ if (existingPropertyVal > 1)
+ {
+ setHiDPIScale(existingPropertyVal);
+ return;
+ }
+ } catch (NumberFormatException e)
+ {
+ System.out.println("Could not convert property " + scalePropertyName
+ + " vale '" + existingProperty + "' to number");
+ }
+ }
+
+ // Try and auto guess a good scale based on reported DPI (not trustworthy)
+ // and screen resolution (more trustworthy)
+
+ // get screen dpi
+ try
+ {
+ dpi = Toolkit.getDefaultToolkit().getScreenResolution();
+ } catch (HeadlessException e)
+ {
+ System.err.println("Cannot get screen resolution: " + e.getMessage());
+ }
+
+ // try and get screen size height and width
+ try
+ {
+ int height = Toolkit.getDefaultToolkit().getScreenSize().height;
+ int width = Toolkit.getDefaultToolkit().getScreenSize().width;
+ // using mindimension in case of portrait screens
+ mindimension = Math.min(height, width);
+ } catch (HeadlessException e)
+ {
+ System.err.println(
+ "Cannot get screen size height and width:" + e.getMessage());
+ }
+
+ // attempt at a formula for scaling based on screen dpi and mindimension.
+ // scale will be an integer >=1. This formula is based on some testing and
+ // guesswork!
+
+ // scale based on reported dpi. if dpi>hidpiThreshold then scale=2+multiples
+ // of hidpiMultiThreshold (else scale=1)
+ // (e.g. dpi of 110 scales 1. dpi of 120 scales 2. dpi of 360 scales 3)
+ int dpiScale = (dpi - hidpiThreshold > 0)
+ ? 2 + ((dpi - hidpiThreshold) / hidpiMultiThreshold)
+ : 1;
+
+ int dimensionScale = 1 + (mindimension / bigScreenThreshold);
+
+ // choose larger of dimensionScale or dpiScale (most likely dimensionScale
+ // as dpiScale often misreported)
+ int autoScale = Math.max(dpiScale, dimensionScale);
+
+ // only make an automatic change if scale is changed and other conditions
+ // (OS is linux) apply, or if setHiDPI has been specified
+ if ((autoScale > 1 && isLinux) || setHiDPI)
+ {
+ setHiDPIScale(autoScale);
+ return;
+ }
+
+ // looks like we're not doing any scaling
+ doneInit = true;
+ }
+
+ public static void setHiDPIScale(int s)
+ {
+ scale = s;
+ allowScalePropertyArg = true;
+ doneInit = true;
+ }
+
+ public static String getScalePropertyArg()
+ {
+ init();
+ // HiDPI setting. Just looking at Linux to start with. Test with Windows.
+ return allowScalePropertyArg ? "-D" + scalePropertyName + "=" + scale
+ : 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.bin;
/**
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.2.4_FJVL</version>
+ <version>1.8.3-1.2.6_FJVL</version>
</parent>
<artifactId>getdown-launcher</artifactId>
if [ x$JVLVERSION != x ]; then
export VERSION=$JVLVERSION
else
- export VERSION=1.8.3-1.2.4_JVL
+ export VERSION=1.8.3-1.2.6_JVL
fi
if [ x${VERSION%_JVL} = x$VERSION ]; then
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
<packaging>pom</packaging>
- <version>1.8.3-1.2.4_FJVL</version>
+ <version>1.8.3-1.2.6_FJVL</version>
<name>getdown</name>
<description>An application installer and updater.</description>
-org.gradle.jvmargs=-Xmx1536m -Xms512m
+# Convention for properties. Read from gradle.properties, use lower_case_underlines for property names.
+# For properties set within build.gradle, use camelCaseNoSpace.
+#
jalviewDir = .
jalview_keyalg = SHA1withRSA
jalview_keydig = SHA1
-testngGroups = Functional
-testngExcludedGroups =
+testng_groups = Functional
+testng_excluded_groups =
j8libDir = j8lib
j11libDir = j11lib
resource_dir = resources
help_parent_dir = help
help_dir = help
-docDir = doc
-schemaDir = schemas
+doc_dir = doc
classes_dir = classes
-examplesDir = examples
clover = false
-use_clover = false
-cloverReportJVMHeap = 2g
-cloverReportJVMArgs = -Dfile.encoding=UTF-8
-cloverReportHTMLOptions =
-cloverReportXMLOptions =
-cloverClassesDir = clover-classes
-cloverSourcesInstrDir = sources-instr
-packageDir = dist
+clover_classes_dir = clover-classes
+clover_sources_instr_dir = clover-instr
+clover_report_dir = clover-report
+clover_lib_dir = utils/clover/lib
+cloverreport_mem = 2g
+cloverreport_jvmargs = -Dfile.encoding=UTF-8
+cloverreport_html_options =
+cloverreport_xml_options =
+package_dir = dist
ARCHIVEDIR =
-outputJar = jalview.jar
-testOutputDir = tests
-utilsDir = utils
+test_output_dir = tests
+utils_dir = utils
build_properties_file = .build_properties
application_codebase = *.jalview.org
-mainClass = jalview.bin.Jalview
-shadowJarMainClass = jalview.bin.Launcher
-launcherClass = jalview.bin.Jalview
+main_class = jalview.bin.Jalview
+shadow_jar_main_class = jalview.bin.Launcher
jalview_name = Jalview
parameters, then include it at the beginning of the command line to
ensure they are processed before any remaining arguments.
<br>
+ Typical command line execution follows the following pattern:
+ <pre>
+ jalview -open <Alignment File/URL> [additional import arguments] [export arguments]
+ </pre>
+
<table width="100%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="27%"><div align="center">-nodisplay</div></td>
User Interface. (automatically disables questionnaire, version
and usage stats checks)</div></td>
</tr>
-
+ <tr>
+ <td><div align="center">-open FILE/URL</div></td>
+ <td><div align="left">Specify the alignment file to
+ open or process by providing additional arguments.</div></td>
+ </tr>
<tr>
<td><div align="center">-props FILE/URL</div></td>
<td><div align="left">Use the given Jalview properties
</div>
</td>
</tr>
+ <tr>
+ <td><div align="center">-jvmmempc=PERCENT</div></td>
+ <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
+ Limit maximum heap size (memory) to PERCENT% of total physical memory detected.
+ This defaults to 90 if total physical memory can be detected.
+ See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><div align="center">-jvmmemmax=MAXMEMORY</div></td>
+ <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
+ Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m),
+ gigabytes(g) or if you're lucky enough, terabytes(t).
+ This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected.
+ See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+ </div>
+ </td>
+ </tr>
</table>
</body>
</html>
</p>
<p>
<strong>Passing JVM Arguments to Jalview</strong><br /> If you need
- to modify parameters for Jalview's Java Virtual Machine, then take a
- look at the instructions for how to <a href="../memory.html#jvm">setting
- the JVM's maximum memory</a>.
+ to modify parameters for Jalview's Java Virtual Machine, or
+ configure system properties, then take a look at the instructions
+ for how to <a href="../memory.html#jvm">setting the JVM's
+ maximum memory</a>.<br />
+ <p>
+ <strong>Changing Jalview's 'Look and Feel'</strong> <br />If you
+ are experiencing issues with the font size or layout of Jalview's
+ GUI, you can try changing Jalview's 'Look and feel' by
+ specifying a custom system property 'laf' on startup (see <a
+ href="../memory.html#jvm">setting the JVM's memory</a> for
+ instructions on how to do this for your platform). <br />For the
+ Jalview standalone executable jar, simply provide one of the
+ property settings before the -jar argument
</p>
+ <ul>
+ <li>-Dlaf=system (default look and feel for the OS)</li>
+ <li>-Dlaf=crossplatform (Java's Metal Look and Feel)</li>
+ <li>-Dlaf=nimbus (Java's alternative Nimbus Look and Feel)</li>
+ <li>-Dlaf=mac (only has an effect on OSX)</li>
+ <li>-Dlaf=gtk (only has an effect on Linux)</li>
+ </ul>
+ The currently configured look and feel is logged to Jalview's console.
+ Once the look and feel has been changed, it will be stored in
+ Jalview's .jalview_properties file for future Jalview sessions.
+
<p> </p>
<p> </p>
</body>
<p>
For more information, you might also want to take a look at the
documentation section of the Jalview website (<a
- href="http://www-test.jalview.org/about/documentation">http://www.jalview.org/about/documentation</a>).
+ href="http://www.jalview.org/about/documentation">http://www.jalview.org/about/documentation</a>).
</p>
<p>
If you are using the Jalview Desktop application and are looking for
</tr>
<tr>
<td><strong>Up Arrow</strong></td>
- <td>Normal</td>
- <td>Moves selected sequence(s) up the alignment</td>
+ <td>Both</td>
+ <td>Moves selected sequence(s) up the alignment.<br />In
+ Cursor mode press Alt key to move selection or sequence under
+ cursor.
+ </td>
</tr>
<tr>
<td><strong>Down Arrow</strong></td>
- <td>Normal</td>
- <td>Moves selected sequence(s) down the alignment.</td>
+ <td>Both</td>
+ <td>Moves selected sequence(s) down the alignment.<br />In
+ Cursor mode press Alt key to move selection or sequence under
+ cursor.
+ </td>
</tr>
<tr>
<td><strong>Left Arrow</strong></td>
<td><strong>Cursor Keys<br> (Arrow Keys)
</strong></td>
<td>Cursor</td>
- <td>Move cursor around alignment</td>
+ <td>Move cursor around alignment.<br /> Press SHIFT to move
+ cursor from an aligned region to next gap, or to the next
+ aligned region when at a gap.
+ </td>
</tr>
<tr>
<td><strong>Page Up</strong></td>
<li><em><font size="3">Maximum memory limit</em><br/>
Since 2.11.1.0, Jalview's configuration includes a 'maximum memory limit':
<pre>jalview.jvmmemmax = 32G</pre>
- Adjusting this default (via a JVL file, above) will allow larger amounts of memory to be allocated to Jalview in connjunction with the jalview.jvmmempc setting.
+ Adjusting this default (via a JVL file, above) will allow larger amounts (or can limit the amount) of memory to be allocated to Jalview in conjunction with the jalview.jvmmempc setting.
+ <br/><br/>
+ </li>
+ <li><em><font size="3"><a name="jar">Command line arguments when using the executable jar (jalview-all.jar) or jalview.bin.Launcher</a></em><br/>
+ If you are using the Jalview standalone executable jar (usually named <em>jalview-all-....jar</em> with a Jalview and Java version designation) or using <em>jalview.bin.Launcher</em> to start Jalview,
+ then you can set the <em>jvmmempc</em> and <em>jvmmemmax</em> values using application command line arguments <em>-jvmmempc=PERCENT</em>
+ and <em>-jvmmemmax=MAXMEMORY</em> respectively. <em>PERCENT</em> should be an integer between 1 and 100, and MAXMEMORY should be an amount of memory in bytes, or you can append a "k", "m", "g", or "t" to use units of kilobytes, megabytes, gigabytes or terabytes, e.g.
+ <pre>java -jar jalview-all-2.11.1.0-j1.8.jar -jvmmempc=50 -jvmmemmax=20g</pre>
+ (this example will launch Jalview with a maximum heap size of the smaller of 20GB or 50% of physical memory detected).
+ <br/>The default value for jvmmempc is 90, whilst the default value for jvmmemmax is 32g if Jalview can determine a total physical memory size of the host system, and a more cautious 8g if Jalview is unable to determine a total physical memory size.
+ <br/><br/>
</li>
<li><em><font size="3"><a name="jvm"/>Directly opening Jalview
with a JVM</font></em> <br /> Launching Jalview directly with a JVM is
</tr>
<tr>
<td width="60" align="center" nowrap><strong><a
+ id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.1">.1</a><br />
+ <em>11/08/2020</em></strong></td>
+ <td align="left" valign="top">
+ <ul>
+ <!-- -->
+ <li>
+ <!-- JAL-3638 -->Shift+arrow keys navigate to next gap or
+ residue in cursor mode
+ </li>
+ <li>
+ <!-- JAL-3695 -->Support import of VCF 4.3 by updating
+ HTSJDK from 2.12 to 2.23
+ </li>
+ <li>
+ <!-- JAL-3621 -->IntervalStore library updated to v.1.1:
+ optimisations and improvements suggested by Bob Hanson and
+ improved compatibility with JalviewJS
+ </li>
+ <li>
+ <!-- JAL-3615 -->Retrieve GZipped stockholm formatted
+ alignments from Pfam and Rfam
+ </li>
+ <li>
+ <!-- JAL-2656 -->Recognise GZipped content for URLs and File
+ import (no longer based on .gz extension)
+ </li>
+ <li>
+ <!-- JAL-3570 -->Updated Spanish Translation for 2.11.1
+ </li>
+ <li>
+ <!-- JAL-3692 -->Migrate EMBL record retrieval to use latest
+ ENA Browser (https://www.ebi.ac.uk/ena/browser/home) and
+ EMBL flat file
+ </li>
+ <li>
+ <!-- JAL-3667 -->Improved warning messages, debug logging
+ and fixed Retry action when Jalview encounters errors when
+ saving or making backup files.
+ </li>
+ <li>
+ <!-- JAL-3676 -->Enhanced Jalview Java Console:
+ <ul>
+ <li>Jalview's logging level can be configured</li>
+ <li>Copy to Clipboard Buttion</li>
+ </ul>
+ </li>
+ <li>
+ <!-- JAL-3541 -->Improved support for Hi-DPI (4K) screens
+ when running on Linux (Requires Java 11+)
+ </li>
+ </ul> <em>Launching Jalview</em>
+ <ul>
+ <li>
+ <!-- JAL-3608 -->Configure Jalview Desktop's look and feel
+ through a system property
+ </li>
+ <li>
+ <!-- JAL-3477 -->Improved built-in documentation and command
+ line help for configuring Jalview's memory
+ </li>
+ </ul>
+ </td>
+ <td align="left" valign="top">
+ <ul>
+ <li>
+ <!-- JAL-3493 -->Escape does not clear highlights on the
+ alignment (Since Jalview 2.10.3)
+ </li>
+ <li>
+ <!-- JAL-3680 -->Alt+Left or Right arrow in cursor mode
+ doesn't slide selected sequences, just sequence under cursor
+ </li>
+ <li>
+ <!-- JAL-3613 -->Peptide-to-CDS tracking broken when
+ multiple EMBL gene products shown for a single contig
+ </li>
+ <li>
+ <!-- JAL-3696 -->Errors encountered when processing variants
+ from VCF files yield "Error processing VCF: Format specifier
+ '%s'" on the console
+ </li>
+ <li>
+ <!-- JAL-3697 -->Count of features not shown can be wrong
+ when there are both local and complementary features mapped
+ to the position under the cursor
+ </li>
+ <li>
+ <!-- JAL-3673 -->Sequence ID for reference sequence is
+ clipped when Right align Sequence IDs enabled
+ </li>
+ <li>
+ <!-- JAL-2983 -->Slider with negative range values not
+ rendered correctly in VAqua4 (Since 2.10.4)
+ </li>
+ <li>
+ <!-- JAL-3685 -->Single quotes not displayed correctly in
+ internationalised text for some messages and log output
+ </li>
+ <li>
+ <!-- JAL-3597 -->Resolved memory leaks in Tree and PCA
+ panels, Alignment viewport and annotation renderer.
+ </li>
+ </ul> <em>Developing Jalview</em>
+ <ul>
+ <li>
+ <!-- JAL-3541 -->Fixed issue with cleaning up old coverage
+ data, causing cloverReport gradle task to fail with an
+ OutOfMemory error.
+ </li>
+ </ul> <em>New Known defects</em>
+ <ul>
+ <li>
+ <!-- JAL-3576 -->Co-located features exported and re-imported
+ are ordered differently when shown on alignment and in
+ tooltips. (Also affects v2.11.1.0)
+ </li>
+ <li>
+ <!-- JAL-3667 -->Windows 10: For a minority of users, if
+ backups are not enabled, Jalview sometimes fails to
+ overwrite an existing file and raises a warning dialog.
+ Workaround is to try to save the file again, and if that
+ fails, delete the original file and save in place.
+ </li>
+ <li>
+ <!-- JAL-3701 -->Stale build data in jalview standalone jar
+ builds (only affects 2.11.1.1 branch)
+ </li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" align="center" nowrap><strong><a
id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.0">.0</a><br />
<em>22/04/2020</em></strong></td>
<td align="left" valign="top">
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://valdarlab.unc.edu/publications.html">Valdar
+ href="http://valdarlab.unc.edu/publications">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">BMC
<ul>
<li><a href="http://www.clustal.org/omega">Clustal Omega</a> (version 1.2.4)</li>
<li><a href="http://www.clustal.org/clustal2">ClustalW</a> (version 2.1)</li>
- <li><a href="http://align.bmr.kyushu-u.ac.jp/mafft/software/">Mafft</a> (version 7.310)</li>
+ <li><a href="https://mafft.cbrc.jp/alignment/software/index.html">Mafft</a> (version 7.310)</li>
<li><a href="http://www.drive5.com/muscle">Muscle</a> (version 3.8.31)</li>
<li><a href="http://www.tcoffee.org/Projects_home_page/t_coffee_home_page.html">T-coffee</a> (version 11.00.8cbe486)</li>
<li><a href="http://probcons.stanford.edu/">Probcons</a> (version 1.12)</li>
label.example_param = Example: {0}
label.select_file_format_before_saving = You must select a file format before saving!
label.file_format_not_specified = File format not specified
-label.couldnt_save_file = Couldn't save file: {0}
+label.couldnt_save_file = Couldn''t save file: {0}
label.error_saving_file = Error Saving File
label.remove_from_default_list = Remove from default list?
label.remove_user_defined_colour = Remove user defined colour
label.couldnt_load_file = Couldn't load file
label.couldnt_find_pdb_id_in_file = Couldn't find a PDB id in the file supplied. Please enter an Id to identify this structure.
label.no_pdb_id_in_file = No PDB Id in File
-label.couldnt_read_pasted_text = Couldn't read the pasted text {0}
+label.couldnt_read_pasted_text = Couldn''t read the pasted text {0}
label.error_parsing_text = Error parsing text
label.input_alignment_from_url = Input Alignment From URL
label.input_alignment = Input Alignment
-label.couldnt_import_as_vamsas_session = Couldn't import {0} as a new vamsas session.
+label.couldnt_import_as_vamsas_session = Couldn''t import {0} as a new vamsas session.
label.vamsas_document_import_failed = Vamsas Document Import Failed
label.couldnt_locate = Could not locate {0}
label.url_not_found = URL not found
label.set_proxy_settings = Please set up your proxy settings in the 'Connections' tab of the Preferences window
label.proxy_authorization_failed = Proxy Authorization Failed
label.internal_jalview_error = Internal Jalview Error
-label.secondary_structure_prediction_service_couldnt_be_located = The Secondary Structure Prediction Service named {0} at {1} couldn't be located.
+label.secondary_structure_prediction_service_couldnt_be_located = The Secondary Structure Prediction Service named {0} at {1} couldn''t be located.
label.service_called_is_not_msa_service = The Service called \n{0}\nis not a \nMultiple Sequence Alignment Service\!
label.msa_service_is_unknown = The Multiple Sequence Alignment Service named {0} is unknown
label.service_called_is_not_seq_search_service = The Service called \n{0}\nis not a \nSequence Search Service\!
error.implementation_error_runner_config_not_available = Implementation Error: Runner Config not available for a JABAWS service of type {0} ({1})
error.implementation_error_cannot_handle_jaba_param = Implementation Error: Cannot handle Jaba parameter object {0}
error.implementation_error_attempt_to_delete_service_preset = Implementation error: Attempt to delete a service preset!
-error.implementation_error_cannot_locate_oldname_presetname = Implementation error: Can't locate either oldname ({0}) or presetName ({1}in the datastore!"
+error.implementation_error_cannot_locate_oldname_presetname = Implementation error: Can''t locate either oldname ({0}) or presetName ({1}in the datastore!"
error.implementation_error_jabaws_param_set_only_handled_by = Implementation error: JabaWsParamSets can only be handled by JabaParamStore
error.cannot_set_source_file_for = Cannot set source file for {0}
error.mismatch_service_instance_preset = Probable mismatch between service instance and preset!
error.implementation_error_can_only_instantiate_jaba_param_sets = Implementation error: Can only instantiate Jaba parameter sets
error.no_aacon_service_found = No AACon service found
error.implementation_error_couldnt_copy_value_constraint = Implementation error: could not copy ValueConstrain!
-error.couldnt_encode_as_utf8 = Couldn't encode {0} as UTF-8.
+error.couldnt_encode_as_utf8 = Couldn''t encode {0} as UTF-8.
error.tree_inputtype_not_yet_implemented = Tree InputType not yet implemented
error.implementation_error_need_to_have_httpresponse = Implementation Error: need to have an HttpResponse to process
error.dbrefsource_implementation_exception =DBRefSource Implementation Exception
exception.number_of_residues_in_query_sequence_differ_from_prediction = Number of residues in {0} supposed query sequence ({1}\n{2})\ndiffer from number of prediction sites in prediction ({3})
label.mapped = mapped
exception.jpredconcide_entry_has_unexpected_number_of_columns = JPredConcise: Entry ({0}) has an unexpected number of columns
-exception.couldnt_parse_concise_annotation_for_prediction = Couldn't parse concise annotation for prediction profile.\n{0}
+exception.couldnt_parse_concise_annotation_for_prediction = Couldn''t parse concise annotation for prediction profile.\n{0}
exception.newfile = NewickFile\: {0}\n
label.no_tree_read_in = No Tree read in
-exception.rnaml_couldnt_access_datasource = Couldn't access datasource ({0})
-exception.ranml_couldnt_process_data = Couldn't process data as RNAML file ({0})
+exception.rnaml_couldnt_access_datasource = Couldn''t access datasource ({0})
+exception.ranml_couldnt_process_data = Couldn''t process data as RNAML file ({0})
exception.ranml_invalid_file = Invalid RNAML file ({0})
exception.ranml_problem_parsing_data = Problem parsing data as RNAML ({0})
exception.pfam_no_sequences_found = No sequences found (PFAM input)
exception.stockholm_invalid_format = This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'
exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
-exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
+exception.couldnt_store_sequence_mappings = Couldn''t store sequence mappings for {0}
exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
exception.browser_not_found = Exception in finding browser: {0}
exception.browser_unable_to_locate = Unable to locate browser: {0}
exception.invocation_target_calling_url = InvocationTargetException while calling openURL: {0}
exception.illegal_access_calling_url = IllegalAccessException while calling openURL: {0}
exception.interrupted_launching_browser = InterruptedException while launching browser: {0}
-exception.ebiembl_retrieval_failed_on = EBI EMBL XML retrieval failed on {0}:{1}
exception.no_pdb_records_for_chain = No PDB Records for {0} chain {1}
exception.unexpected_handling_rnaml_translation_for_pdb = Unexpected exception when handling RNAML translation of PDB data
exception.couldnt_recover_sequence_properties_for_alignment = Couldn't recover sequence properties for alignment
warn.input_is_too_big = Input is too big!
warn.invalid_job_param_set = Invalid job parameter set!
warn.oneseq_msainput_selection = The current selection only contains a single sequence. Do you want to submit all sequences for alignment instead ?
-info.job_couldnt_be_run_server_doesnt_support_program = Job could not be run because the server doesn't support this program.\n{0}
+info.job_couldnt_be_run_server_doesnt_support_program = Job could not be run because the server doesn''t support this program.\n{0}
info.job_couldnt_be_run_exceeded_hard_limit = Job could not be run because it exceeded a hard limit on the server.\n{0}
info.job_couldnt_be_run_incorrect_param_setting = Job could not be run because some of the parameter settings are not supported by the server.\n{0}\nPlease check to make sure you have used the correct parameter set for this service\!\n
info.no_jobs_ran = No jobs ran
label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Something possibly went wrong with the backups of this file.
label.backupfiles_confirm_save_new_saved_file_ok = The new saved file seems okay.
label.backupfiles_confirm_save_new_saved_file_not_ok = The new saved file might not be okay.
+label.continue_operation = Continue operation?
label.backups = Backups
label.backup = Backup
label.backup_files = Backup Files
label.include_linked_tooltip = Include visible {0} features<br>converted to local sequence coordinates
label.features_not_shown = {0} feature(s) not shown
label.no_features_to_sort_by = No features to sort by
+label.log_level = Log level
+label.log_level_tooltip = Temporarily set the log level for this console. The log level will revert to {0} when this Java console is closed.
+label.copy_to_clipboard = Copy to clipboard
+label.copy_to_clipboard_tooltip = Copy all of the log text in this console to the system clipboard
label.ignore_hidden = Ignore hidden columns
label.ignore_hidden_tooltip = Ignore any characters in hidden columns when matching
-
label.overview_window = Ventana resumen
label.none = Ninguno
label.above_identity_threshold = Por encima del umbral de identidad
-label.show_sequence_features = Mostrar las caracterÃsticas de las secuencias
+label.show_sequence_features = Mostrar las caracterÃsticas de secuencia
label.nucleotide = Nucleótido
label.to_new_alignment = A nuevo alineamiento
label.to_this_alignment = Añadir a este alineamiento
label.generating_features_for_params = Generando caracterÃsticas de - {0}
label.generating_annotations_for_params = Generando anotaciones de - {0}
label.varna_params = VARNA - {0}
-label.sequence_feature_settings = Configuración de las caracterÃsticas de la secuencia
+label.sequence_feature_settings = Configuración de las caracterÃsticas de secuencia
+label.sequence_feature_settings_for = Configuración de las caracterÃsticas de secuencia para {0}
+label.sequence_feature_settings_for_view = Configuración de las caracterÃsticas de secuencia para vista "{0}"
+label.sequence_feature_settings_for_CDS_and_Protein = Configuración de las caracterÃsticas de secuencia para CDS y ProteÃna
+action.undo_changes_to_feature_settings = Deshacer todos los cambios no aplicados
+action.undo_changes_to_feature_settings_and_close_the_dialog = Deshacer cambios pendientes, cerrar diálogo
label.pairwise_aligned_sequences = Secuencias alineadas a pares
label.original_data_for_params = Datos originales de {0}
label.points_for_params = Puntos de {0}
exception.invocation_target_calling_url = InvocationTargetException mientras se invocaba openURL: {0}
exception.illegal_access_calling_url = IllegalAccessException mientras se invocaba openURL: {0}
exception.interrupted_launching_browser = InterruptedException mientras se lanzaba el navegador: {0}
-exception.ebiembl_retrieval_failed_on = La recuperación de datos EBI EMBL XML ha fallado en {0}:{1}
exception.no_pdb_records_for_chain = No se han encontrado registros {0} para la cadena {1}
exception.unexpected_handling_rnaml_translation_for_pdb = Excepcion inesperada cuando se traducÃan a RNAML los datos PDB
exception.couldnt_recover_sequence_properties_for_alignment = No es posible recuperar las propiedades de la secuencia para el alineamiento
label.prot_alignment_colour=Color del Alineamiento Proteico
info.associate_wit_sequence=Asociar con secuencia
label.protein=ProteÃna
+label.CDS=CDS
warn.oneseq_msainput_selection=La selección actual sólo contiene una única secuencia. ¿Quieres enviar todas las secuencias para la alineación en su lugar?
label.use_rnaview=Usar RNAView para estructura secondaria
label.search_all=Introducir uno o más valores de búsqueda separados por punto y coma ";" (Nota: buscará en toda la base de datos PDB)
label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Posiblemente algo está mal con los archivos de respaldos.
label.backupfiles_confirm_save_new_saved_file_ok = El nuevo archivo guardado parece estar bien.
label.backupfiles_confirm_save_new_saved_file_not_ok = El nuevo archivo guardado podrÃa no estar bien.
+label.continue_operation = ¿Continuar operación?
label.backups = Respaldos
label.backup = Respaldo
label.backup_files = Archivos de respaldos
label.include_linked_tooltip = Incluir caracterÃsticas de {0}<br>convertidas a coordenadas de secuencia local
label.features_not_shown = {0} caracterÃstica(s) no mostradas
label.no_features_to_sort_by = No hay caracterÃsticas para ordenar
+label.log_level = Nivel del registro
+label.log_level_tooltip = Establezca temporalmente el nivel de registro para esta consola. El nivel de registro volverá a {0} cuando se cierre esta consola de Java.
+label.copy_to_clipboard = Copiar en el portapapeles
+label.copy_to_clipboard_tooltip = Copie todo el texto de registro en esta consola al portapapeles del sistema
label.ignore_hidden = Ignorar columnas ocultas
label.ignore_hidden_tooltip = Ignorar caracteres en columnas ocultas
*/
package jalview.bin;
-import jalview.datamodel.PDBEntry;
-import jalview.gui.UserDefinedColours;
-import jalview.schemes.ColourSchemeLoader;
-import jalview.schemes.ColourSchemes;
-import jalview.schemes.UserColourScheme;
-import jalview.structure.StructureImportSettings;
-import jalview.urls.IdOrgSettings;
-import jalview.util.ColorUtils;
-import jalview.ws.sifts.SiftsSettings;
-
import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import javax.swing.LookAndFeel;
+import javax.swing.UIManager;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
+import jalview.datamodel.PDBEntry;
+import jalview.gui.UserDefinedColours;
+import jalview.schemes.ColourSchemeLoader;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.UserColourScheme;
+import jalview.structure.StructureImportSettings;
+import jalview.urls.IdOrgSettings;
+import jalview.util.ColorUtils;
+import jalview.ws.sifts.SiftsSettings;
+
/**
* Stores and retrieves Jalview Application Properties Lists and fields within
* list entries are separated by '|' symbols unless otherwise stated (|) clauses
String jnlpVersion = System.getProperty("jalview.version");
- // jnlpVersion will be null if a latest version check for the channel needs to
- // be done
+ // jnlpVersion will be null if a latest version check for the channel needs
+ // to be done
// Dont do this check if running in headless mode
if (jnlpVersion == null && getDefault("VERSION_CHECK", true)
new BuildDetails(codeVersion, null, codeInstallation);
if (printV && reportVersion)
{
- System.out
- .println("Jalview Version: " + codeVersion + codeInstallation);
+ System.out.println(
+ "Jalview Version: " + codeVersion + codeInstallation);
}
}
public static String getVersionDetailsForConsole()
{
StringBuilder sb = new StringBuilder();
- sb.append("Jalview Version: " + jalview.bin.Cache.getDefault("VERSION", "TEST"));
+ sb.append("Jalview Version: ");
+ sb.append(jalview.bin.Cache.getDefault("VERSION", "TEST"));
sb.append("\n");
- sb.append("Jalview Installation: "
- + jalview.bin.Cache.getDefault("INSTALLATION", "unknown"));
+ sb.append("Jalview Installation: ");
+ sb.append(jalview.bin.Cache.getDefault("INSTALLATION", "unknown"));
sb.append("\n");
- sb.append("Build Date: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
+ sb.append("Build Date: ");
+ sb.append(jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
sb.append("\n");
- sb.append("Java version: " + System.getProperty("java.version"));
+ sb.append("Java version: ");
+ sb.append(System.getProperty("java.version"));
sb.append("\n");
- sb.append(System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version"));
+ sb.append(System.getProperty("os.arch"));
+ sb.append(" ");
+ sb.append(System.getProperty("os.name"));
+ sb.append(" ");
+ sb.append(System.getProperty("os.version"));
sb.append("\n");
appendIfNotNull(sb, "Install4j version: ",
System.getProperty("sys.install4jVersion"), "\n", null);
System.getProperty("installer_template_version"), "\n", null);
appendIfNotNull(sb, "Launcher version: ",
System.getProperty("launcher_version"), "\n", null);
- if (jalview.bin.Cache.getDefault("VERSION", "TEST").equals("DEVELOPMENT")) {
+ LookAndFeel laf = UIManager.getLookAndFeel();
+ String lafName = laf == null ? "Not obtained" : laf.getName();
+ String lafClass = laf == null ? "unknown" : laf.getClass().getName();
+ sb.append("LookAndFeel: ");
+ sb.append(lafName);
+ sb.append(" (");
+ sb.append(lafClass);
+ sb.append(")\n");
+ // Not displayed in release version ( determined by possible version number
+ // regex 9[9.]*9[.-_a9]* )
+ if (Pattern.matches("^\\d[\\d\\.]*\\d[\\.\\-\\w]*$",
+ jalview.bin.Cache.getDefault("VERSION", "TEST")))
+ {
appendIfNotNull(sb, "Getdown appdir: ",
System.getProperty("getdownappdir"), "\n", null);
appendIfNotNull(sb, "Java home: ", System.getProperty("java.home"),
// eg 'built from Source' or update channel
return jalview.bin.Cache.getDefault("INSTALLATION", "unknown");
}
+
+ public static String getStackTraceString(Throwable t)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ t.printStackTrace(pw);
+ return sw.toString();
+ }
}
--- /dev/null
+package jalview.bin;
+
+import java.awt.HeadlessException;
+import java.awt.Toolkit;
+
+public class HiDPISetting
+{
+ private static final int hidpiThreshold = 160;
+
+ private static final int hidpiMultiThreshold = 240;
+
+ private static final int bigScreenThreshold = 1400;
+
+ private static final String scalePropertyName = "sun.java2d.uiScale";
+
+ private static final boolean isLinux;
+
+ // private static final boolean isAMac;
+
+ // private static final boolean isWindows;
+
+ public static final String setHiDPIPropertyName = "setHiDPI";
+
+ public static final String setHiDPIScalePropertyName = "setHiDPIScale";
+
+ private static boolean setHiDPI = false;
+
+ private static int setHiDPIScale = 0;
+
+ public static int dpi = 0;
+
+ public static int mindimension = 0;
+
+ public static int width = 0;
+
+ public static int scale = 0;
+
+ private static boolean doneInit = false;
+
+ private static boolean allowScalePropertyArg = false;
+
+ static
+ {
+ String system = System.getProperty("os.name") == null ? null
+ : System.getProperty("os.name").toLowerCase();
+ if (system != null)
+ {
+ isLinux = system.indexOf("linux") > -1;
+ // isAMac = system.indexOf("mac") > -1;
+ // isWindows = system.indexOf("windows") > -1;
+ }
+ else
+ {
+ isLinux = false;
+ // isAMac = isWindows = false;
+ }
+ }
+
+ private static void init()
+ {
+ if (doneInit)
+ {
+ return;
+ }
+
+ // get and use command line property values first
+ String setHiDPIProperty = System.getProperty(setHiDPIPropertyName);
+ setHiDPI = setHiDPIProperty != null
+ && setHiDPIProperty.equalsIgnoreCase("true");
+
+ String setHiDPIScaleProperty = System
+ .getProperty(setHiDPIScalePropertyName);
+ if (setHiDPIScaleProperty != null)
+ {
+ try
+ {
+ setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty);
+ } catch (NumberFormatException e)
+ {
+ System.err.println(setHiDPIScalePropertyName + " property give ("
+ + setHiDPIScaleProperty + ") but not parseable as integer");
+ }
+ }
+ if (setHiDPI && setHiDPIScale > 0)
+ {
+ setHiDPIScale(setHiDPIScale);
+ return;
+ }
+
+ // check to see if the scale property has already been set by something else
+ // (e.g. the OS)
+ String existingProperty = System.getProperty(scalePropertyName);
+ if (existingProperty != null)
+ {
+ try
+ {
+ int existingPropertyVal = Integer.parseInt(existingProperty);
+ System.out.println("Existing " + scalePropertyName + " is "
+ + existingPropertyVal);
+ if (existingPropertyVal > 1)
+ {
+ setHiDPIScale(existingPropertyVal);
+ return;
+ }
+ } catch (NumberFormatException e)
+ {
+ System.out.println("Could not convert property " + scalePropertyName
+ + " vale '" + existingProperty + "' to number");
+ }
+ }
+
+ // Try and auto guess a good scale based on reported DPI (not trustworthy)
+ // and screen resolution (more trustworthy)
+
+ // get screen dpi
+ try
+ {
+ dpi = Toolkit.getDefaultToolkit().getScreenResolution();
+ } catch (HeadlessException e)
+ {
+ System.err.println("Cannot get screen resolution: " + e.getMessage());
+ }
+
+ // try and get screen size height and width
+ try
+ {
+ int height = Toolkit.getDefaultToolkit().getScreenSize().height;
+ int width = Toolkit.getDefaultToolkit().getScreenSize().width;
+ // using mindimension in case of portrait screens
+ mindimension = Math.min(height, width);
+ } catch (HeadlessException e)
+ {
+ System.err.println(
+ "Cannot get screen size height and width:" + e.getMessage());
+ }
+
+ // attempt at a formula for scaling based on screen dpi and mindimension.
+ // scale will be an integer >=1. This formula is based on some testing and
+ // guesswork!
+
+ // scale based on reported dpi. if dpi>hidpiThreshold then scale=2+multiples
+ // of hidpiMultiThreshold (else scale=1)
+ // (e.g. dpi of 110 scales 1. dpi of 120 scales 2. dpi of 360 scales 3)
+ int dpiScale = (dpi - hidpiThreshold > 0)
+ ? 2 + ((dpi - hidpiThreshold) / hidpiMultiThreshold)
+ : 1;
+
+ int dimensionScale = 1 + (mindimension / bigScreenThreshold);
+
+ // choose larger of dimensionScale or dpiScale (most likely dimensionScale
+ // as dpiScale often misreported)
+ int autoScale = Math.max(dpiScale, dimensionScale);
+
+ // only make an automatic change if scale is changed and other conditions
+ // (OS is linux) apply, or if setHiDPI has been specified
+ if ((autoScale > 1 && isLinux) || setHiDPI)
+ {
+ setHiDPIScale(autoScale);
+ return;
+ }
+
+ // looks like we're not doing any scaling
+ doneInit = true;
+ }
+
+ public static void setHiDPIScale(int s)
+ {
+ scale = s;
+ allowScalePropertyArg = true;
+ doneInit = true;
+ }
+
+ public static String getScalePropertyArg()
+ {
+ init();
+ // HiDPI setting. Just looking at Linux to start with. Test with Windows.
+ return allowScalePropertyArg ? "-D" + scalePropertyName + "=" + scale
+ : null;
+ }
+}
*/
package jalview.bin;
-import jalview.ext.so.SequenceOntology;
-import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.gui.PromptUserConfig;
-import jalview.io.AppletFormatAdapter;
-import jalview.io.BioJsHTMLOutput;
-import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
-import jalview.io.FileFormatException;
-import jalview.io.FileFormatI;
-import jalview.io.FileLoader;
-import jalview.io.HtmlSvgOutput;
-import jalview.io.IdentifyFile;
-import jalview.io.NewickFile;
-import jalview.io.gff.SequenceOntologyFactory;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.ws.jws2.Jws2Discoverer;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Vector;
-import javax.swing.LookAndFeel;
import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
import com.threerings.getdown.util.LaunchUtil;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
+import jalview.ext.so.SequenceOntology;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.PromptUserConfig;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.BioJsHTMLOutput;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
+import jalview.io.FileLoader;
+import jalview.io.HtmlSvgOutput;
+import jalview.io.IdentifyFile;
+import jalview.io.NewickFile;
+import jalview.io.gff.SequenceOntologyFactory;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.ws.jws2.Jws2Discoverer;
/**
* Main class for Jalview Application <br>
* main class for Jalview application
*
* @param args
- * open <em>filename</em>
+ * open <em>filename</em>
*/
public static void main(String[] args)
{
{
System.setSecurityManager(null);
System.out
- .println("Java version: "
- + System.getProperty("java.version"));
+ .println("Java version: " + System.getProperty("java.version"));
System.out.println("Java Home: " + System.getProperty("java.home"));
System.out.println(System.getProperty("os.arch") + " "
+ System.getProperty("os.name") + " "
+ System.getProperty("os.version"));
String val = System.getProperty("sys.install4jVersion");
- if (val != null) {
- System.out.println("Install4j version: " + val);
+ if (val != null)
+ {
+ System.out.println("Install4j version: " + val);
}
val = System.getProperty("installer_template_version");
- if (val != null) {
+ if (val != null)
+ {
System.out.println("Install4j template version: " + val);
}
val = System.getProperty("launcher_version");
- if (val != null) {
+ if (val != null)
+ {
System.out.println("Launcher version: " + val);
}
desktop = null;
- try
- {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception ex)
- {
- System.err.println("Unexpected Look and Feel Exception");
- ex.printStackTrace();
- }
- if (Platform.isAMac())
- {
-
- LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
- .getLookAndFeel();
- System.setProperty("com.apple.mrj.application.apple.menu.about.name",
- "Jalview");
- System.setProperty("apple.laf.useScreenMenuBar", "true");
- if (lookAndFeel != null)
- {
- try
- {
- UIManager.setLookAndFeel(lookAndFeel);
- } catch (Throwable e)
- {
- System.err.println(
- "Failed to set QuaQua look and feel: " + e.toString());
- }
- }
- if (lookAndFeel == null
- || !(lookAndFeel.getClass().isAssignableFrom(
- UIManager.getLookAndFeel().getClass()))
- || !UIManager.getLookAndFeel().getClass().toString()
- .toLowerCase().contains("quaqua"))
- {
- try
- {
- System.err.println(
- "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
- UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
- } catch (Throwable e)
- {
- System.err.println(
- "Failed to reset look and feel: " + e.toString());
- }
- }
- }
+ setLookAndFeel();
/*
* configure 'full' SO model if preferences say to, else use the default (SO
if (!headless)
{
+
desktop = new Desktop();
desktop.setInBatchMode(true); // indicate we are starting up
JalviewTaskbar.setTaskbar(this);
} catch (Exception e)
{
- System.out.println("Cannot set Taskbar");
+ Cache.log.info("Cannot set Taskbar");
+ Cache.log.error(e.getMessage());
// e.printStackTrace();
} catch (Throwable t)
{
- System.out.println("Cannot set Taskbar");
+ Cache.log.info("Cannot set Taskbar");
+ Cache.log.error(t.getMessage());
// t.printStackTrace();
}
}
}
+ private static void setLookAndFeel()
+ {
+ // property laf = "crossplatform", "system", "gtk", "metal", "nimbus" or
+ // "mac"
+ // If not set (or chosen laf fails), use the normal SystemLaF and if on Mac,
+ // try Quaqua/Vaqua.
+ String lafProp = System.getProperty("laf");
+ String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
+ String laf = "none";
+ if (lafProp != null)
+ {
+ laf = lafProp;
+ }
+ else if (lafSetting != null)
+ {
+ laf = lafSetting;
+ }
+ boolean lafSet = false;
+ switch (laf)
+ {
+ case "crossplatform":
+ lafSet = setCrossPlatformLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "system":
+ lafSet = setSystemLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "gtk":
+ lafSet = setGtkLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "metal":
+ lafSet = setMetalLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "nimbus":
+ lafSet = setNimbusLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "quaqua":
+ lafSet = setQuaquaLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "vaqua":
+ lafSet = setVaquaLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "mac":
+ lafSet = setMacLookAndFeel();
+ if (!lafSet)
+ {
+ Cache.log.error("Could not set requested laf=" + laf);
+ }
+ break;
+ case "none":
+ break;
+ default:
+ Cache.log.error("Requested laf=" + laf + " not implemented");
+ }
+ if (!lafSet)
+ {
+ setSystemLookAndFeel();
+ if (Platform.isLinux())
+ {
+ setMetalLookAndFeel();
+ }
+ if (Platform.isAMac())
+ {
+ setMacLookAndFeel();
+ }
+ }
+ }
+
+ private static boolean setCrossPlatformLookAndFeel()
+ {
+ return setGenericLookAndFeel(false);
+ }
+
+ private static boolean setSystemLookAndFeel()
+ {
+ return setGenericLookAndFeel(true);
+ }
+
+ private static boolean setGenericLookAndFeel(boolean system)
+ {
+ boolean set = false;
+ try
+ {
+ UIManager.setLookAndFeel(
+ system ? UIManager.getSystemLookAndFeelClassName()
+ : UIManager.getCrossPlatformLookAndFeelClassName());
+ set = true;
+ } catch (Exception ex)
+ {
+ Cache.log.error("Unexpected Look and Feel Exception");
+ Cache.log.error(ex.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(ex));
+ }
+ return set;
+ }
+
+ private static boolean setSpecificLookAndFeel(String name,
+ String className, boolean nameStartsWith)
+ {
+ boolean set = false;
+ try
+ {
+ for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
+ {
+ if (info.getName() != null && nameStartsWith
+ ? info.getName().toLowerCase()
+ .startsWith(name.toLowerCase())
+ : info.getName().toLowerCase().equals(name.toLowerCase()))
+ {
+ className = info.getClassName();
+ break;
+ }
+ }
+ UIManager.setLookAndFeel(className);
+ set = true;
+ } catch (Exception ex)
+ {
+ Cache.log.error("Unexpected Look and Feel Exception");
+ Cache.log.error(ex.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(ex));
+ }
+ return set;
+ }
+
+ private static boolean setGtkLookAndFeel()
+ {
+ return setSpecificLookAndFeel("gtk",
+ "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
+ }
+
+ private static boolean setMetalLookAndFeel()
+ {
+ return setSpecificLookAndFeel("metal",
+ "javax.swing.plaf.metal.MetalLookAndFeel", false);
+ }
+
+ private static boolean setNimbusLookAndFeel()
+ {
+ return setSpecificLookAndFeel("nimbus",
+ "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
+ }
+
+ private static boolean setQuaquaLookAndFeel()
+ {
+ return setSpecificLookAndFeel("quaqua",
+ ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel().getClass()
+ .getName(),
+ false);
+ }
+
+ private static boolean setVaquaLookAndFeel()
+ {
+ return setSpecificLookAndFeel("vaqua",
+ "org.violetlib.aqua.AquaLookAndFeel", false);
+ }
+
+ private static boolean setMacLookAndFeel()
+ {
+ boolean set = false;
+ System.setProperty("com.apple.mrj.application.apple.menu.about.name",
+ "Jalview");
+ System.setProperty("apple.laf.useScreenMenuBar", "true");
+ set = setQuaquaLookAndFeel();
+ if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
+ .toLowerCase().contains("quaqua"))
+ {
+ set = setVaquaLookAndFeel();
+ }
+ return set;
+ }
+
private static void showUsage()
{
System.out.println(
+ "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
+ "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
+ "-groovy FILE\tExecute groovy script in FILE, after all other arguments have been processed (if FILE is the text 'STDIN' then the file will be read from STDIN)\n"
+ + "-jvmmempc=PERCENT\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to PERCENT% of total physical memory detected. This defaults to 90 if total physical memory can be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
+ + "-jvmmemmax=MAXMEMORY\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m), gigabytes(g) or if you're lucky enough, terabytes(t). This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
+ "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
}
* Locate the given string as a file and pass it to the groovy interpreter.
*
* @param groovyscript
- * the script to execute
+ * the script to execute
* @param jalviewContext
- * the Jalview Desktop object passed in to the groovy
- * binding as the 'Jalview' object.
+ * the Jalview Desktop object passed in to the groovy binding as the
+ * 'Jalview' object.
*/
private void executeGroovyScript(String groovyscript, AlignFrame af)
{
}
/**
- * Quit method delegates to Desktop.quit - unless running in headless mode when
- * it just ends the JVM
+ * Quit method delegates to Desktop.quit - unless running in headless mode
+ * when it just ends the JVM
*/
public void quit()
{
/**
* main method for jalview.bin.Launcher. This restarts the same JRE's JVM with
- * the same arguments but with memory adjusted based on extracted -jvmmempc and
- * -jvmmemmax application arguments. If on a Mac then extra dock:icon and
+ * the same arguments but with memory adjusted based on extracted -jvmmempc
+ * and -jvmmemmax application arguments. If on a Mac then extra dock:icon and
* dock:name arguments are also set.
*
* @param args
if (!memSet)
{
long maxMemLong = MemorySetting.getMemorySetting(jvmmemmax, jvmmempc);
-
+
if (maxMemLong > 0)
{
memSetting = "-Xmx" + Long.toString(maxMemLong);
}
}
+ String scalePropertyArg = HiDPISetting.getScalePropertyArg();
+ if (scalePropertyArg != null)
+ {
+ System.out.println("Running " + startClass + " with scale setting "
+ + scalePropertyArg);
+ command.add(scalePropertyArg);
+ }
+
command.add(startClass);
command.addAll(arguments);
// System.out.println("COMMAND: " + String.join(" ", builder.command()));
System.out.println("Running " + startClass + " with "
- + (memSetting == null ? "no memory setting" : memSetting));
+ + (memSetting == null ? "no memory setting"
+ : ("memory setting " + memSetting)));
if (Boolean.parseBoolean(System.getProperty("launcherstop")))
{
if (e.getMessage().toLowerCase().contains("memory"))
{
System.out.println("Caught a memory exception: " + e.getMessage());
- // Probably the "Cannot allocate memory" error, try without the memory setting
+ // Probably the "Cannot allocate memory" error, try without the memory
+ // setting
ArrayList<String> commandNoMem = new ArrayList<>();
for (int i = 0; i < command.size(); i++)
{
*/
package jalview.datamodel.features;
-import jalview.datamodel.SequenceFeature;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import intervalstore.api.IntervalStoreI;
import intervalstore.impl.BinarySearcher;
+import intervalstore.impl.BinarySearcher.Compare;
import intervalstore.impl.IntervalStore;
+import jalview.datamodel.SequenceFeature;
/**
* A data store for a set of sequence features that supports efficient lookup of
* binary search the sorted list to find the insertion point
*/
int insertPosition = BinarySearcher.findFirst(contactFeatureStarts,
- f -> f.getBegin() >= feature.getBegin());
+ true, Compare.GE, feature.getBegin());
contactFeatureStarts.add(insertPosition, feature);
* binary search the sorted list to find the insertion point
*/
insertPosition = BinarySearcher.findFirst(contactFeatureEnds,
- f -> f.getEnd() >= feature.getEnd());
+ false, Compare.GE, feature.getEnd());
contactFeatureEnds.add(insertPosition, feature);
return true;
*/
// int pos = binarySearch(features,
// SearchCriterion.byFeature(feature, RangeComparator.BY_START_POSITION));
- int pos = BinarySearcher.findFirst(features,
- val -> val.getBegin() >= feature.getBegin());
+ int pos = BinarySearcher.findFirst(features, true, Compare.GE,
+ feature.getBegin());
int len = features.size();
while (pos < len)
{
* whose end point is not before the target range
*/
int index = BinarySearcher.findFirst(contactFeatureEnds,
- f -> f.getEnd() >= from);
+ false, Compare.GE, (int) from);
while (index < contactFeatureEnds.size())
{
List<SequenceFeature> result)
{
int index = BinarySearcher.findFirst(contactFeatureStarts,
- f -> f.getBegin() >= from);
+ true, Compare.GE, (int) from);
while (index < contactFeatureStarts.size())
{
*/
package jalview.datamodel.features;
-import jalview.datamodel.SequenceFeature;
-import jalview.io.gff.SequenceOntologyFactory;
-import jalview.io.gff.SequenceOntologyI;
-
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import intervalstore.api.IntervalI;
+import jalview.datamodel.SequenceFeature;
+import jalview.io.gff.SequenceOntologyFactory;
+import jalview.io.gff.SequenceOntologyI;
/**
* A class that stores sequence features in a way that supports efficient
*/
public class SequenceFeatures implements SequenceFeaturesI
{
-
/*
* map from feature type to structured store of features for that type
* null types are permitted (but not a good idea!)
public static void sortFeatures(List<? extends IntervalI> features,
final boolean forwardStrand)
{
- IntervalI.sortIntervals(features, forwardStrand);
+ Collections.sort(features,
+ forwardStrand
+ ? IntervalI.COMPARE_BEGIN_ASC_END_DESC
+ : IntervalI.COMPARE_END_DESC);
}
/**
*/
package jalview.gui;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+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;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JEditorPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
import jalview.analysis.AlignmentSorter;
import jalview.analysis.AlignmentUtils;
import jalview.analysis.CrossRef;
import jalview.schemes.ResidueColourScheme;
import jalview.schemes.TCoffeeColourScheme;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.ViewportRanges;
import jalview.ws.DBRefFetcher;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.seqfetcher.DbSourceProxy;
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-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;
-import java.awt.dnd.DropTargetListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.print.PageFormat;
-import java.awt.print.PrinterJob;
-import java.beans.PropertyChangeEvent;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JEditorPane;
-import javax.swing.JInternalFrame;
-import javax.swing.JLayeredPane;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
/**
* DOCUMENT ME!
*
}
if (viewport.cursorMode)
{
- alignPanel.getSeqPanel().moveCursor(0, 1);
+ alignPanel.getSeqPanel().moveCursor(0, 1,
+ evt.isShiftDown() && !evt.isAltDown());
}
break;
}
if (viewport.cursorMode)
{
- alignPanel.getSeqPanel().moveCursor(0, -1);
+ alignPanel.getSeqPanel().moveCursor(0, -1,
+ evt.isShiftDown() && !evt.isAltDown());
}
-
break;
case KeyEvent.VK_LEFT:
}
else
{
- alignPanel.getSeqPanel().moveCursor(-1, 0);
+ alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
}
break;
}
else
{
- alignPanel.getSeqPanel().moveCursor(1, 0);
+ alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
}
break;
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format", new Object[]
- { fileName, format }));
+ { file, format }));
}
else
else
{
// create backupfiles object and get new temp filename destination
+ Cache.log.trace("ALIGNFRAME making backupfiles object for " + file);
BackupFiles backupfiles = new BackupFiles(file);
try
{
- PrintWriter out = new PrintWriter(
- new FileWriter(backupfiles.getTempFilePath()));
+ String tempFilePath = backupfiles.getTempFilePath();
+ Cache.log.trace(
+ "ALIGNFRAME setting PrintWriter to " + tempFilePath);
+ PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
+
+ Cache.log.trace(
+ "ALIGNFRAME about to write to temp file " + tempFilePath);
out.print(output);
+ Cache.log.trace("ALIGNFRAME about to close file");
out.close();
+ Cache.log.trace("ALIGNFRAME closed file");
this.setTitle(file);
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format", new Object[]
- { fileName, format.getName() }));
+ { file, format.getName() }));
+ } catch (IOException e)
+ {
+ success = false;
+ Cache.log.error(
+ "ALIGNFRAME Something happened writing the temp file");
+ Cache.log.error(e.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(e));
+
} catch (Exception ex)
{
success = false;
- ex.printStackTrace();
+ Cache.log.error(
+ "ALIGNFRAME Something unexpected happened writing the temp file");
+ Cache.log.error(ex.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(ex));
}
backupfiles.setWriteSuccess(success);
+ Cache.log.debug("ALIGNFRAME writing temp file was "
+ + (success ? "" : "NOT ") + "successful");
// do the backup file roll and rename the temp file to actual file
+ Cache.log.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
success = backupfiles.rollBackupsAndRenameTempFile();
+ Cache.log.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
+ + (success ? "" : "un") + "successfully");
}
}
if (!success)
{
- JvOptionPane.showInternalMessageDialog(this, MessageManager
- .formatMessage("label.couldnt_save_file", new Object[]
- { fileName }),
- MessageManager.getString("label.error_saving_file"),
- JvOptionPane.WARNING_MESSAGE);
+ if (!Platform.isHeadless())
+ {
+ JvOptionPane.showInternalMessageDialog(this, MessageManager
+ .formatMessage("label.couldnt_save_file", new Object[]
+ { file }),
+ MessageManager.getString("label.error_saving_file"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
}
return success;
synchronized void slideSequences(boolean right, int size)
{
List<SequenceI> sg = new ArrayList<>();
- if (viewport.cursorMode)
- {
- sg.add(viewport.getAlignment()
- .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
- }
- else if (viewport.getSelectionGroup() != null
- && viewport.getSelectionGroup().getSize() != viewport
- .getAlignment().getHeight())
+ if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup()
+ .getSize() != viewport.getAlignment().getHeight())
{
sg = viewport.getSelectionGroup()
.getSequences(viewport.getHiddenRepSequences());
}
+ if (sg.size() == 0 && viewport.cursorMode)
+ {
+ sg.add(viewport.getAlignment()
+ .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
+ }
+
if (sg.size() < 1)
{
return;
}
viewport.setSelectionGroup(null);
viewport.getColumnSelection().clear();
- viewport.setSelectionGroup(null);
+ viewport.setSearchResults(null);
alignPanel.getIdPanel().getIdCanvas().searchResults = null;
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
if (viewport.getViewName() == null)
{
- viewport.setViewName(MessageManager
- .getString("label.view_name_original"));
+ viewport.setViewName(
+ MessageManager.getString("label.view_name_original"));
}
/*
* otherwise set the chosen colour scheme (or null for 'None')
*/
ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
- viewport,
- viewport.getAlignment(), viewport.getHiddenRepSequences());
+ viewport, viewport.getAlignment(),
+ viewport.getHiddenRepSequences());
changeColour(cs);
}
}
private Rectangle lastFeatureSettingsBounds = null;
+
@Override
public void setFeatureSettingsGeometry(Rectangle bounds)
{
@SuppressWarnings("serial")
public class AnnotationColourChooser extends AnnotationRowFilter
{
- private static final int ONETHOUSAND = 1000;
-
private ColourSchemeI oldcs;
private JButton defColours;
"error.implementation_error_dont_know_about_threshold_setting"));
}
thresholdIsMin.setSelected(acg.isThresholdIsMinMax());
- thresholdValue.setText("" + acg.getAnnotationThreshold());
+ thresholdValue
+ .setText(String.valueOf(acg.getAnnotationThreshold()));
}
jbInit();
{
updateView();
}
- getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
+ getCurrentAnnotation().threshold.value = getSliderValue();
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
ap.paintAlignment(false, false);
thresholdValue.setEnabled(true);
thresholdIsMin.setEnabled(!useOriginalColours.isSelected());
+ final AlignmentAnnotation currentAnnotation = getCurrentAnnotation();
if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
{
slider.setEnabled(false);
thresholdIsMin.setEnabled(false);
}
else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD
- && getCurrentAnnotation().threshold == null)
+ && currentAnnotation.threshold == null)
{
- getCurrentAnnotation().setThreshold(new GraphLine(
- (getCurrentAnnotation().graphMax
- - getCurrentAnnotation().graphMin) / 2f,
+ currentAnnotation.setThreshold(new GraphLine(
+ (currentAnnotation.graphMax - currentAnnotation.graphMin)
+ / 2f,
"Threshold", Color.black));
}
if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
{
adjusting = true;
- float range = getCurrentAnnotation().graphMax * ONETHOUSAND
- - getCurrentAnnotation().graphMin * ONETHOUSAND;
-
- slider.setMinimum(
- (int) (getCurrentAnnotation().graphMin * ONETHOUSAND));
- slider.setMaximum(
- (int) (getCurrentAnnotation().graphMax * ONETHOUSAND));
- slider.setValue(
- (int) (getCurrentAnnotation().threshold.value * ONETHOUSAND));
- thresholdValue.setText(getCurrentAnnotation().threshold.value + "");
- slider.setMajorTickSpacing((int) (range / 10f));
+ setSliderModel(currentAnnotation.graphMin, currentAnnotation.graphMax,
+ currentAnnotation.threshold.value);
slider.setEnabled(true);
+
+ setThresholdValueText();
thresholdValue.setEnabled(true);
adjusting = false;
}
- colorAlignmentContaining(getCurrentAnnotation(), selectedThresholdItem);
+ colorAlignmentContaining(currentAnnotation, selectedThresholdItem);
ap.alignmentChanged();
}
package jalview.gui;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.HiddenColumns;
import jalview.io.cache.JvCacheableInputBox;
import jalview.schemes.AnnotationColourGradient;
{
if (slider.isEnabled())
{
- getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
+ getCurrentAnnotation().threshold.value = getSliderValue();
updateView();
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
thresholdValue.setEnabled(true);
percentThreshold.setEnabled(true);
+ final AlignmentAnnotation currentAnnotation = getCurrentAnnotation();
if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
{
slider.setEnabled(false);
}
else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
{
- if (getCurrentAnnotation().threshold == null)
+ if (currentAnnotation.threshold == null)
{
- getCurrentAnnotation().setThreshold(new jalview.datamodel.GraphLine(
- (getCurrentAnnotation().graphMax
- - getCurrentAnnotation().graphMin) / 2f,
+ currentAnnotation.setThreshold(new jalview.datamodel.GraphLine(
+ (currentAnnotation.graphMax
+ - currentAnnotation.graphMin) / 2f,
"Threshold", Color.black));
}
adjusting = true;
- float range = getCurrentAnnotation().graphMax * 1000
- - getCurrentAnnotation().graphMin * 1000;
- slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000));
- slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000));
- slider.setValue(
- (int) (getCurrentAnnotation().threshold.value * 1000));
+ setSliderModel(currentAnnotation.graphMin,
+ currentAnnotation.graphMax,
+ currentAnnotation.threshold.value);
setThresholdValueText();
- slider.setMajorTickSpacing((int) (range / 10f));
slider.setEnabled(true);
thresholdValue.setEnabled(true);
adjusting = false;
// build filter params
filterParams.setThresholdType(
AnnotationFilterParameter.ThresholdType.NO_THRESHOLD);
- if (getCurrentAnnotation().isQuantitative())
+ if (currentAnnotation.isQuantitative())
{
filterParams
- .setThresholdValue(getCurrentAnnotation().threshold.value);
+ .setThresholdValue(currentAnnotation.threshold.value);
if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD)
{
// adding them to the selection
av.showAllHiddenColumns();
av.getColumnSelection().filterAnnotations(
- getCurrentAnnotation().annotations, filterParams);
+ currentAnnotation.annotations, filterParams);
boolean hideCols = getActionOption() == ACTION_OPTION_HIDE;
if (hideCols)
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.math.BigDecimal;
+import java.math.MathContext;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
-import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@SuppressWarnings("serial")
public abstract class AnnotationRowFilter extends JPanel
{
+ private static final String TWO_DP = "%.2f";
+
+ private final static MathContext FOUR_SIG_FIG = new MathContext(4);
+
protected AlignViewport av;
protected AlignmentPanel ap;
protected JCheckBox percentThreshold = new JCheckBox();
- protected JSlider slider = new JSlider();
+ protected Slider slider;
protected JTextField thresholdValue = new JTextField(20);
{
this.av = viewport;
this.ap = alignPanel;
+ this.slider = new Slider(0f, 100f, 50f);
+
thresholdValue.addFocusListener(new FocusAdapter()
{
@Override
adjusting = true;
if (percentThreshold.isSelected())
{
- thresholdValue.setText("" + (slider.getValue() - slider.getMinimum())
- * 100f / (slider.getMaximum() - slider.getMinimum()));
+ thresholdValue
+ .setText(String.format(TWO_DP, getSliderPercentageValue()));
}
else
{
- thresholdValue.setText((slider.getValue() / 1000f) + "");
+ /*
+ * round to 4 significant digits without trailing zeroes
+ */
+ float f = getSliderValue();
+ BigDecimal formatted = new BigDecimal(f).round(FOUR_SIG_FIG)
+ .stripTrailingZeros();
+ thresholdValue.setText(formatted.toPlainString());
}
adjusting = oldadj;
}
+ /**
+ * Answers the value of the slider position (descaled to 'true' value)
+ *
+ * @return
+ */
+ protected float getSliderValue()
+ {
+ return slider.getSliderValue();
+ }
+
+ /**
+ * Sets the slider value (scaled from the true value to the slider range)
+ *
+ * @param value
+ */
+ protected void setSliderValue(float value)
+ {
+ slider.setSliderValue(value);
+ }
+ /**
+ * Answers the value of the slider position as a percentage between minimum and
+ * maximum of its range
+ *
+ * @return
+ */
+ protected float getSliderPercentageValue()
+ {
+ return slider.getSliderPercentageValue();
+ }
+
+ /**
+ * Sets the slider position for a given percentage value of its min-max range
+ *
+ * @param pct
+ */
+ protected void setSliderPercentageValue(float pct)
+ {
+ slider.setSliderPercentageValue(pct);
+ }
+
protected void addSliderMouseListeners()
{
updateView();
}
+ /**
+ * Updates the slider position, and the display, for an update in the slider's
+ * text input field
+ */
protected void thresholdValue_actionPerformed()
{
try
float f = Float.parseFloat(thresholdValue.getText());
if (percentThreshold.isSelected())
{
- slider.setValue(slider.getMinimum() + ((int) ((f / 100f)
- * (slider.getMaximum() - slider.getMinimum()))));
+ setSliderPercentageValue(f);
}
else
{
- slider.setValue((int) (f * 1000));
+ setSliderValue(f);
}
updateView();
} catch (NumberFormatException ex)
valueChanged(true);
}
}
+
+ /**
+ * Sets the min-max range and current value of the slider, with rescaling from
+ * true values to slider range as required
+ *
+ * @param min
+ * @param max
+ * @param value
+ */
+ protected void setSliderModel(float min, float max, float value)
+ {
+ slider.setSliderModel(min, max, value);
+
+ /*
+ * tick mark every 10th position
+ */
+ slider.setMajorTickSpacing(
+ (slider.getMaximum() - slider.getMinimum()) / 10);
+ }
}
*/
package jalview.gui;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.PrintStream;
import javax.swing.JButton;
+import javax.swing.JComboBox;
import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
+import org.apache.log4j.Level;
import org.apache.log4j.SimpleLayout;
+import jalview.bin.Cache;
+import jalview.util.MessageManager;
+
/**
* Simple Jalview Java Console. Version 1 - allows viewing of console output
* after desktop is created. Acquired with thanks from RJHM's site
private int MIN_HEIGHT = 250;
+ private JComboBox<Level> logLevelCombo = new JComboBox<Level>();
+
+ protected Level startingLogLevel = Level.INFO;
+
public Console()
{
// create all components and add them
// textArea = cpt.getTextArea();
textArea = new JTextArea();
textArea.setEditable(false);
- JButton button = new JButton(MessageManager.getString("action.clear"));
+ JButton clearButton = new JButton(
+ MessageManager.getString("action.clear"));
+ JButton copyToClipboardButton = new JButton(
+ MessageManager.getString("label.copy_to_clipboard"));
+ copyToClipboardButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ copyConsoleTextToClipboard();
+ }
+ });
+ copyToClipboardButton.addMouseListener(new MouseAdapter()
+ {
+ private Color bg = textArea.getBackground();
+
+ private Color fg = textArea.getForeground();
+
+ public void mousePressed(MouseEvent e)
+ {
+ textArea.setBackground(textArea.getSelectionColor());
+ textArea.setForeground(textArea.getSelectedTextColor());
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ textArea.setBackground(bg);
+ textArea.setForeground(fg);
+ }
+
+ });
+ copyToClipboardButton.setToolTipText(
+ MessageManager.getString("label.copy_to_clipboard_tooltip"));
+
+ JLabel logLevelLabel = new JLabel(
+ MessageManager.getString("label.log_level") + ":");
+
+ // logLevelCombo.addItem(Level.ALL);
+ logLevelCombo.addItem(Level.TRACE);
+ logLevelCombo.addItem(Level.DEBUG);
+ logLevelCombo.addItem(Level.INFO);
+ logLevelCombo.addItem(Level.WARN);
+ // logLevelCombo.addItem(Level.ERROR);
+ // logLevelCombo.addItem(Level.FATAL);
+ // logLevelCombo.addItem(Level.OFF);
+ // set startingLogLevel
+ startingLogLevel = Cache.log == null ? Level.INFO
+ : Cache.log.getLevel();
+ setChosenLogLevelCombo();
+ logLevelCombo.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ if (Cache.log != null)
+ {
+ Cache.log.setLevel((Level) logLevelCombo.getSelectedItem());
+ }
+ }
+
+ });
// frame = cpt;
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(new JScrollPane(textArea),
BorderLayout.CENTER);
- frame.getContentPane().add(button, BorderLayout.SOUTH);
+ JPanel southPanel = new JPanel();
+ southPanel.setLayout(new GridBagLayout());
+
+ JPanel logLevelPanel = new JPanel();
+ logLevelPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
+ logLevelPanel.add(logLevelLabel);
+ logLevelPanel.add(logLevelCombo);
+ String logLevelTooltip = MessageManager.formatMessage(
+ "label.log_level_tooltip", startingLogLevel.toString());
+ logLevelLabel.setToolTipText(logLevelTooltip);
+ logLevelCombo.setToolTipText(logLevelTooltip);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.gridwidth = 1;
+ gbc.gridheight = 1;
+ gbc.weightx = 0.1;
+ southPanel.add(logLevelPanel, gbc);
+
+ gbc.gridx++;
+ gbc.weightx = 0.8;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ southPanel.add(clearButton, gbc);
+
+ gbc.gridx++;
+ gbc.weightx = 0.1;
+ gbc.fill = GridBagConstraints.NONE;
+ southPanel.add(copyToClipboardButton, gbc);
+
+ southPanel.setVisible(true);
+ frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
frame.setVisible(visible);
updateConsole = visible;
frame.addWindowListener(this);
- button.addActionListener(this);
+ clearButton.addActionListener(this);
+
if (redirect)
{
redirectStreams();
textAppender.start();
}
+ private void setChosenLogLevelCombo()
+ {
+ setChosenLogLevelCombo(startingLogLevel);
+ }
+
+ private void setChosenLogLevelCombo(Level setLogLevel)
+ {
+ logLevelCombo.setSelectedItem(setLogLevel);
+ if (!logLevelCombo.getSelectedItem().equals(setLogLevel))
+ {
+ // setLogLevel not (yet) in list
+ if (setLogLevel != null && setLogLevel instanceof Level)
+ {
+ // add new item to list (might be set via .jalview_properties)
+ boolean added = false;
+ for (int i = 0; i < logLevelCombo.getItemCount(); i++)
+ {
+ Level l = (Level) logLevelCombo.getItemAt(i);
+ if (l.isGreaterOrEqual(setLogLevel))
+ {
+ logLevelCombo.insertItemAt(setLogLevel, i);
+ added = true;
+ break;
+ }
+ }
+ if (!added) // lower priority than others or some confusion -- add to
+ // end of list
+ {
+ logLevelCombo.addItem(setLogLevel);
+ }
+ logLevelCombo.setSelectedItem(setLogLevel);
+ }
+ else
+ {
+ logLevelCombo.setSelectedItem(Level.INFO);
+ }
+ }
+ }
+
+ private void copyConsoleTextToClipboard()
+ {
+ String consoleText = textArea.getText();
+ StringSelection consoleTextSelection = new StringSelection(consoleText);
+ Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+ cb.setContents(consoleTextSelection, null);
+ }
+
PipedOutputStream pout = null, perr = null;
public void redirectStreams()
frame.setVisible(selected);
if (selected == true)
{
+ setChosenLogLevelCombo();
redirectStreams();
updateConsole = true;
frame.toFront();
}
else
{
+ // reset log level to what it was before
+ if (Cache.log != null)
+ {
+ Cache.log.setLevel(startingLogLevel);
+ }
+
unredirectStreams();
updateConsole = false;
}
JPanel groupPanel;
- JSlider transparency = new JSlider();
+ JSlider transparency= new JSlider();
private JCheckBox showComplementOnTop;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.math.BigDecimal;
+import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
-import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
*/
public class FeatureTypeSettings extends JalviewDialog
{
+ private final static MathContext FOUR_SIG_FIG = new MathContext(4);
+
private final static String LABEL_18N = MessageManager
.getString("label.label");
private float max;
/*
- * scale factor for conversion between absolute min-max and slider
- */
- private float scaleFactor;
-
- /*
* radio button group, to select what to colour by:
* simple colour, by category (text), or graduated
*/
private JComboBox<Object> threshold = new JComboBox<>();
- private JSlider slider = new JSlider();
+ private Slider slider;
private JTextField thresholdValue = new JTextField(20);
* update min-max scaling if there is a range to work with,
* else disable the widgets (this shouldn't happen if only
* valid options are offered in the combo box)
+ * offset slider to have only non-negative values if necessary (JAL-2983)
*/
- scaleFactor = (max == min) ? 1f : 100f / (max - min);
- float range = (max - min) * scaleFactor;
- slider.setMinimum((int) (min * scaleFactor));
- slider.setMaximum((int) (max * scaleFactor));
- slider.setMajorTickSpacing((int) (range / 10f));
+ slider.setSliderModel(min, max, min);
+ slider.setMajorTickSpacing(
+ (int) ((slider.getMaximum() - slider.getMinimum()) / 10f));
threshline = new GraphLine((max - min) / 2f, "Threshold",
Color.black);
fc.isAboveThreshold() ? ABOVE_THRESHOLD_OPTION
: BELOW_THRESHOLD_OPTION);
slider.setEnabled(true);
- slider.setValue((int) (fc.getThreshold() * scaleFactor));
- thresholdValue.setText(String.valueOf(fc.getThreshold()));
+ slider.setSliderValue(fc.getThreshold());
+ setThresholdValueText(fc.getThreshold());
thresholdValue.setEnabled(true);
thresholdIsMin.setEnabled(true);
}
thresholdValue_actionPerformed();
}
});
+ slider = new Slider(0f, 100f, 50f);
slider.setPaintLabels(false);
slider.setPaintTicks(true);
slider.setBackground(Color.white);
{
if (!adjusting)
{
- thresholdValue
- .setText(String.valueOf(slider.getValue() / scaleFactor));
+ setThresholdValueText(slider.getSliderValue());
thresholdValue.setBackground(Color.white); // to reset red for invalid
sliderValueChanged();
}
float f = Float.parseFloat(thresholdValue.getText());
f = Float.max(f, this.min);
f = Float.min(f, this.max);
- thresholdValue.setText(String.valueOf(f));
- slider.setValue((int) (f * scaleFactor));
+ setThresholdValueText(f);
+ slider.setSliderValue(f);
threshline.value = f;
thresholdValue.setBackground(Color.white); // ok
adjusting = false;
}
/**
+ * Sets the text field for threshold value, rounded to four significant figures
+ *
+ * @param f
+ */
+ void setThresholdValueText(float f)
+ {
+ BigDecimal formatted = new BigDecimal(f).round(FOUR_SIG_FIG)
+ .stripTrailingZeros();
+ thresholdValue.setText(formatted.toPlainString());
+ }
+
+ /**
* Action on change of threshold slider value. This may be done interactively
* (by moving the slider), or programmatically (to update the slider after
* manual input of a threshold value).
*/
protected void sliderValueChanged()
{
- threshline.value = getRoundedSliderValue();
+ threshline.value = slider.getSliderValue();
/*
* repaint alignment, but not Overview or structure,
colourChanged(false);
}
- /**
- * Converts the slider value to its absolute value by dividing by the
- * scaleFactor. Rounding errors are squashed by forcing min/max of slider
- * range to the actual min/max of feature score range
- *
- * @return
- */
- private float getRoundedSliderValue()
- {
- int value = slider.getValue();
- float f = value == slider.getMaximum() ? max
- : (value == slider.getMinimum() ? min : value / scaleFactor);
- return f;
- }
-
void addActionListener(ActionListener listener)
{
if (featureSettings != null)
if (hasHiddenRows || alignViewport.isDisplayReferenceSeq())
{
g.setFont(getHiddenFont(sequence, alignViewport));
+ fm = g.getFontMetrics();
}
// Selected sequence colours
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
-import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
JLabel optlabel = new JLabel();
- JComboBox val = new JComboBox();
+ JComboBox<String> val = new JComboBox<>();
public OptionBox(OptionI opt)
{
}
}
add(enabled, BorderLayout.NORTH);
- for (Object str : opt.getPossibleValues())
+ for (String str : opt.getPossibleValues())
{
val.addItem(str);
}
boolean choice = false;
- JComboBox choicebox;
+ JComboBox<String> choicebox;
JPanel controlPanel = new JPanel();
boolean integ = false;
- Object lastVal;
+ String lastVal;
ParameterI parameter;
JButton showDesc = new JButton();
- JSlider slider = null;
+ Slider slider = null;
JTextArea string = new JTextArea();
validate();
}
- private void makeExpanderParam(ParameterI parm)
+ private void makeExpanderParam(final ParameterI parm)
{
setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT));
setBorder(new TitledBorder(parm.getName()));
validate();
}
+ /**
+ * Action on input in text field
+ */
@Override
public void actionPerformed(ActionEvent e)
{
private void checkIfModified()
{
- Object cstate = updateSliderFromValueField();
- boolean notmod = false;
- if (cstate.getClass() == lastVal.getClass())
- {
- if (cstate instanceof int[])
- {
- notmod = (((int[]) cstate)[0] == ((int[]) lastVal)[0]);
- }
- else if (cstate instanceof float[])
- {
- notmod = (((float[]) cstate)[0] == ((float[]) lastVal)[0]);
- }
- else if (cstate instanceof String[])
- {
- notmod = (((String[]) cstate)[0].equals(((String[]) lastVal)[0]));
- }
- }
- pmdialogbox.argSetModified(this, !notmod);
+ Object cstate = getCurrentValue();
+ boolean modified = !cstate.equals(lastVal);
+ pmdialogbox.argSetModified(this, modified);
+ }
+
+ /**
+ * Answers the current value of the parameter, as text
+ *
+ * @return
+ */
+ private String getCurrentValue()
+ {
+ return choice ? (String) choicebox.getSelectedItem()
+ : valueField.getText();
}
@Override
}
+ /**
+ * Action on change of slider value
+ */
@Override
public void stateChanged(ChangeEvent e)
{
if (!adjusting)
{
- valueField.setText("" + ((integ) ? ("" + slider.getValue())
- : ("" + slider.getValue() / 1000f)));
+ float value = slider.getSliderValue();
+ valueField.setText(
+ integ ? Integer.toString((int) value)
+ : Float.toString(value));
checkIfModified();
}
-
}
public void updateControls(ParameterI parm)
{
if (choice)
{
- choicebox = new JComboBox();
+ choicebox = new JComboBox<>();
choicebox.addActionListener(this);
controlPanel.add(choicebox, BorderLayout.CENTER);
}
else
{
- slider = new JSlider();
- slider.addChangeListener(this);
valueField = new JTextField();
valueField.addActionListener(this);
valueField.addKeyListener(new KeyListener()
}
});
valueField.setPreferredSize(new Dimension(60, 25));
+ valueField.setText(parm.getValue());
+ slider = makeSlider(parm.getValidValue());
+ updateSliderFromValueField();
+ slider.addChangeListener(this);
+
controlPanel.add(slider, BorderLayout.WEST);
controlPanel.add(valueField, BorderLayout.EAST);
-
}
}
{
if (init)
{
- List vals = parm.getPossibleValues();
- for (Object val : vals)
+ List<String> vals = parm.getPossibleValues();
+ for (String val : vals)
{
choicebox.addItem(val);
}
valueField.setText(parm.getValue());
}
}
- lastVal = updateSliderFromValueField();
+ lastVal = getCurrentValue();
adjusting = false;
}
- public Object updateSliderFromValueField()
+ private Slider makeSlider(ValueConstrainI validValue)
+ {
+ if (validValue != null)
+ {
+ final Number minValue = validValue.getMin();
+ final Number maxValue = validValue.getMax();
+ if (minValue != null && maxValue != null)
+ {
+ return new Slider(minValue.floatValue(), maxValue.floatValue(),
+ minValue.floatValue());
+ }
+ }
+
+ /*
+ * otherwise, a nominal slider which will not be visible
+ */
+ return new Slider(0, 100, 50);
+ }
+
+ public void updateSliderFromValueField()
{
- int iVal;
- float fVal;
if (validator != null)
{
+ final Number minValue = validator.getMin();
+ final Number maxValue = validator.getMax();
if (integ)
{
- iVal = 0;
+ int iVal = 0;
try
{
valueField.setText(valueField.getText().trim());
iVal = Integer.valueOf(valueField.getText());
- if (validator.getMin() != null
- && validator.getMin().intValue() > iVal)
+ if (minValue != null
+ && minValue.intValue() > iVal)
{
- iVal = validator.getMin().intValue();
+ iVal = minValue.intValue();
// TODO: provide visual indication that hard limit was reached for
// this parameter
}
- if (validator.getMax() != null
- && validator.getMax().intValue() < iVal)
+ if (maxValue != null && maxValue.intValue() < iVal)
{
- iVal = validator.getMax().intValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
+ iVal = maxValue.intValue();
}
- } catch (Exception e)
+ } catch (NumberFormatException e)
{
+ System.err.println(e.toString());
}
- ;
- // update value field to reflect any bound checking we performed.
- valueField.setText("" + iVal);
- if (validator.getMin() != null && validator.getMax() != null)
+ if (minValue != null || maxValue != null)
{
- slider.getModel().setRangeProperties(iVal, 1,
- validator.getMin().intValue(),
- validator.getMax().intValue() + 1, true);
+ valueField.setText(String.valueOf(iVal));
+ slider.setSliderValue(iVal);
}
else
{
slider.setVisible(false);
}
- return new int[] { iVal };
}
else
{
- fVal = 0f;
+ float fVal = 0f;
try
{
valueField.setText(valueField.getText().trim());
fVal = Float.valueOf(valueField.getText());
- if (validator.getMin() != null
- && validator.getMin().floatValue() > fVal)
+ if (minValue != null
+ && minValue.floatValue() > fVal)
{
- fVal = validator.getMin().floatValue();
+ fVal = minValue.floatValue();
// TODO: provide visual indication that hard limit was reached for
// this parameter
// update value field to reflect any bound checking we performed.
valueField.setText("" + fVal);
}
- if (validator.getMax() != null
- && validator.getMax().floatValue() < fVal)
+ if (maxValue != null
+ && maxValue.floatValue() < fVal)
{
- fVal = validator.getMax().floatValue();
+ fVal = maxValue.floatValue();
// TODO: provide visual indication that hard limit was reached for
// this parameter
// update value field to reflect any bound checking we performed.
valueField.setText("" + fVal);
}
- } catch (Exception e)
+ } catch (NumberFormatException e)
{
+ System.err.println(e.toString());
}
- ;
- if (validator.getMin() != null && validator.getMax() != null)
+ if (minValue != null && maxValue != null)
{
- slider.getModel().setRangeProperties((int) (fVal * 1000f), 1,
- (int) (validator.getMin().floatValue() * 1000f),
- 1 + (int) (validator.getMax().floatValue() * 1000f),
- true);
+ slider.setSliderModel(minValue.floatValue(),
+ maxValue.floatValue(), fVal);
}
else
{
slider.setVisible(false);
}
- return new float[] { fVal };
}
}
else
if (!choice)
{
slider.setVisible(false);
- return new String[] { valueField.getText().trim() };
- }
- else
- {
- return new String[] { (String) choicebox.getSelectedItem() };
}
}
-
}
}
URL linkImageURL = getClass().getResource("/images/link.gif");
- Map<String, OptionBox> optSet = new java.util.LinkedHashMap<String, OptionBox>();
+ Map<String, OptionBox> optSet = new java.util.LinkedHashMap<>();
- Map<String, ParamBox> paramSet = new java.util.LinkedHashMap<String, ParamBox>();
+ Map<String, ParamBox> paramSet = new java.util.LinkedHashMap<>();
public Map<String, OptionBox> getOptSet()
{
*/
public List<ArgumentI> getCurrentSettings()
{
- List<ArgumentI> argSet = new ArrayList<ArgumentI>();
+ List<ArgumentI> argSet = new ArrayList<>();
for (OptionBox opts : getOptSet().values())
{
OptionI opt = opts.getOptionIfEnabled();
protected void close_actionPerformed()
{
setPcaModel(null);
+ if (this.rc != null)
+ {
+ this.rc.sequencePoints = null;
+ this.rc.setAxisEndPoints(null);
+ this.rc = null;
+ }
}
@Override
void moveCursor(int dx, int dy)
{
- seqCanvas.cursorX += dx;
- seqCanvas.cursorY += dy;
-
+ moveCursor(dx, dy,false);
+ }
+ void moveCursor(int dx, int dy, boolean nextWord)
+ {
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- if (av.hasHiddenColumns() && !hidden.isVisible(seqCanvas.cursorX))
+ if (nextWord)
{
- int original = seqCanvas.cursorX - dx;
int maxWidth = av.getAlignment().getWidth();
-
- if (!hidden.isVisible(seqCanvas.cursorX))
- {
- int visx = hidden.absoluteToVisibleColumn(seqCanvas.cursorX - dx);
- int[] region = hidden.getRegionWithEdgeAtRes(visx);
-
- if (region != null) // just in case
+ int maxHeight=av.getAlignment().getHeight();
+ SequenceI seqAtRow = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
+ // look for next gap or residue
+ boolean isGap = Comparison.isGap(seqAtRow.getCharAt(seqCanvas.cursorX));
+ int p = seqCanvas.cursorX,lastP,r=seqCanvas.cursorY,lastR;
+ do
+ {
+ lastP = p;
+ lastR = r;
+ if (dy != 0)
{
- if (dx == 1)
+ r += dy;
+ if (r < 0)
{
- // moving right
- seqCanvas.cursorX = region[1] + 1;
+ r = 0;
}
- else if (dx == -1)
+ if (r >= maxHeight)
{
- // moving left
- seqCanvas.cursorX = region[0] - 1;
+ r = maxHeight - 1;
}
+ seqAtRow = av.getAlignment().getSequenceAt(r);
}
- seqCanvas.cursorX = (seqCanvas.cursorX < 0) ? 0 : seqCanvas.cursorX;
- }
+ p = nextVisible(hidden, maxWidth, p, dx);
+ } while ((dx != 0 ? p != lastP : r != lastR)
+ && isGap == Comparison.isGap(seqAtRow.getCharAt(p)));
+ seqCanvas.cursorX=p;
+ seqCanvas.cursorY=r;
+ } else {
+ int maxWidth = av.getAlignment().getWidth();
+ seqCanvas.cursorX = nextVisible(hidden, maxWidth, seqCanvas.cursorX, dx);
+ seqCanvas.cursorY += dy;
+ }
+ scrollToVisible(false);
+ }
- if (seqCanvas.cursorX >= maxWidth
- || !hidden.isVisible(seqCanvas.cursorX))
+ private int nextVisible(HiddenColumns hidden,int maxWidth, int original, int dx)
+ {
+ int newCursorX=original+dx;
+ if (av.hasHiddenColumns() && !hidden.isVisible(newCursorX))
+ {
+ int visx = hidden.absoluteToVisibleColumn(newCursorX - dx);
+ int[] region = hidden.getRegionWithEdgeAtRes(visx);
+
+ if (region != null) // just in case
{
- seqCanvas.cursorX = original;
+ if (dx == 1)
+ {
+ // moving right
+ newCursorX = region[1] + 1;
+ }
+ else if (dx == -1)
+ {
+ // moving left
+ newCursorX = region[0] - 1;
+ }
}
}
-
- scrollToVisible(false);
+ newCursorX = (newCursorX < 0) ? 0 : newCursorX;
+ if (newCursorX >= maxWidth
+ || !hidden.isVisible(newCursorX))
+ {
+ newCursorX = original;
+ }
+ return newCursorX;
}
-
/**
* Scroll to make the cursor visible in the viewport.
*
pos);
if (mf != null)
{
- unshownFeatures = seqARep.appendFeatures(tooltipText,
+ unshownFeatures += seqARep.appendFeatures(tooltipText,
pos, mf, fr2, MAX_TOOLTIP_LENGTH);
}
}
--- /dev/null
+package jalview.gui;
+
+import javax.swing.JSlider;
+
+/**
+ * A modified {@code javax.swing.JSlider} that
+ * <ul>
+ * <li>supports float valued numbers (by scaling up integer values)</li>
+ * <li>rescales 'true' value range to avoid negative values, as these are not
+ * rendered correctly by some look and feel libraries</li>
+ * </ul>
+ *
+ * @author gmcarstairs
+ */
+@SuppressWarnings("serial")
+public class Slider extends JSlider
+{
+ /*
+ * the number of nominal positions the slider represents
+ * (higher number = more fine-grained positioning)
+ */
+ private static final int SCALE_TICKS = 1000;
+
+ /*
+ * 'true' value corresponding to zero on the slider
+ */
+ private float trueMin;
+
+ /*
+ * 'true' value corresponding to slider maximum
+ */
+ private float trueMax;
+
+ /*
+ * scaleFactor applied to true value range to give a
+ * slider range of 0 - 100
+ */
+ private float sliderScaleFactor;
+
+ /**
+ * Constructor that rescales min - max to 0 - 100 for the slider
+ *
+ * @param min
+ * @param max
+ * @param value
+ */
+ public Slider(float min, float max, float value)
+ {
+ super();
+ setSliderModel(min, max, value);
+ }
+
+ /**
+ * Sets the min-max range and current value of the slider, with rescaling from
+ * true values to slider range as required
+ *
+ * @param min
+ * @param max
+ * @param value
+ */
+ public void setSliderModel(float min, float max, float value)
+ {
+ trueMin = min;
+ trueMax = max;
+ setMinimum(0);
+ sliderScaleFactor = SCALE_TICKS / (max - min);
+ int sliderMax = (int) ((max - min) * sliderScaleFactor);
+ setMaximum(sliderMax);
+ setSliderValue(value);
+ }
+
+ /**
+ * Answers the value of the slider position (descaled to 'true' value)
+ *
+ * @return
+ */
+ public float getSliderValue()
+ {
+ /*
+ * convert slider max to 'true max' in case of rounding errors
+ */
+ int value = getValue();
+ return value == getMaximum() ? trueMax
+ : value / sliderScaleFactor + trueMin;
+ }
+
+ /**
+ * Sets the slider value (scaled from the true value to the slider range)
+ *
+ * @param value
+ */
+ public void setSliderValue(float value)
+ {
+ setValue(Math.round((value - trueMin) * sliderScaleFactor));
+ }
+
+ /**
+ * Answers the value of the slider position as a percentage between minimum and
+ * maximum of its range
+ *
+ * @return
+ */
+ public float getSliderPercentageValue()
+ {
+ return (getValue() - getMinimum()) * 100f
+ / (getMaximum() - getMinimum());
+ }
+
+ /**
+ * Sets the slider position for a given percentage value of its min-max range
+ *
+ * @param pct
+ */
+ public void setSliderPercentageValue(float pct)
+ {
+ float pc = pct / 100f * getMaximum();
+ setValue((int) pc);
+ }
+}
{
getViewport().removePropertyChangeListener(listener);
}
+ releaseReferences();
}
});
}
/**
+ * Ensure any potentially large object references are nulled
+ */
+ public void releaseReferences()
+ {
+ this.tree = null;
+ this.treeCanvas.tree = null;
+ this.treeCanvas.nodeHash = null;
+ this.treeCanvas.nameHash = null;
+ }
+
+ /**
* @return
*/
protected PropertyChangeListener addAlignmentListener()
*/
package jalview.io;
-import jalview.bin.Cache;
-import jalview.gui.Desktop;
-import jalview.gui.JvOptionPane;
-import jalview.util.MessageManager;
-
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
+import jalview.bin.Cache;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
/*
* BackupFiles used for manipulating (naming rolling/deleting) backup/version files when an alignment or project file is saved.
* User configurable options are:
private static final SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
+ private static final String newTempFileSuffix = "_newfile";
+
+ private static final String oldTempFileSuffix = "_oldfile_tobedeleted";
+
public BackupFiles(String filename)
{
this(new File(filename));
{
classInit();
this.file = file;
- BackupFilesPresetEntry bfpe = BackupFilesPresetEntry.getSavedBackupEntry();
+ BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
+ .getSavedBackupEntry();
this.suffix = bfpe.suffix;
this.noMax = bfpe.keepAll;
this.max = bfpe.rollMax;
{
String tempfilename = file.getName();
File tempdir = file.getParentFile();
- temp = File.createTempFile(tempfilename, TEMP_FILE_EXT + "_newfile",
- tempdir);
+ Cache.log.trace(
+ "BACKUPFILES [file!=null] attempting to create temp file for "
+ + tempfilename + " in dir " + tempdir);
+ temp = File.createTempFile(tempfilename,
+ TEMP_FILE_EXT + newTempFileSuffix, tempdir);
+ Cache.log.debug(
+ "BACKUPFILES using temp file " + temp.getAbsolutePath());
}
else
{
+ Cache.log.trace(
+ "BACKUPFILES [file==null] attempting to create default temp file "
+ + DEFAULT_TEMP_FILE + " with extension "
+ + TEMP_FILE_EXT);
temp = File.createTempFile(DEFAULT_TEMP_FILE, TEMP_FILE_EXT);
}
} catch (IOException e)
{
- System.out.println(
- "Could not create temp file to save into (IOException)");
+ Cache.log
+ .error("Could not create temp file to save to (IOException)");
+ Cache.log.error(e.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(e));
} catch (Exception e)
{
- System.out.println("Exception ctreating temp file for saving");
+ Cache.log.error("Exception ctreating temp file for saving");
+ Cache.log.debug(Cache.getStackTraceString(e));
}
this.setTempFile(temp);
}
public static void classInit()
{
- setEnabled(Cache.getDefault(ENABLED, true));
+ Cache.initLogger();
+ Cache.log.trace("BACKUPFILES classInit");
+ boolean e = Cache.getDefault(ENABLED, true);
+ setEnabled(e);
+ Cache.log.trace("BACKUPFILES " + (e ? "enabled" : "disabled"));
BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
.getSavedBackupEntry();
+ Cache.log.trace("BACKUPFILES preset scheme " + bfpe.toString());
setConfirmDelete(bfpe.confirmDelete);
+ Cache.log.trace("BACKUPFILES confirm delete " + bfpe.confirmDelete);
}
public static void setEnabled(boolean flag)
path = this.getTempFile().getCanonicalPath();
} catch (IOException e)
{
- System.out.println(
+ Cache.log.error(
"IOException when getting Canonical Path of temp file '"
+ this.getTempFile().getName() + "'");
+ Cache.log.debug(Cache.getStackTraceString(e));
}
return path;
}
public boolean renameTempFile()
{
- return tempFile.renameTo(file);
+ return moveFileToFile(tempFile, file);
}
// roll the backupfiles
|| suffix.length() == 0)
{
// nothing to do
+ Cache.log.debug("BACKUPFILES rollBackupFiles nothing to do." + ", "
+ + "filename: " + (file != null ? file.getName() : "null")
+ + ", " + "file exists: " + file.exists() + ", " + "enabled: "
+ + enabled + ", " + "max: " + max + ", " + "suffix: '" + suffix
+ + "'");
return true;
}
+ Cache.log.trace("BACKUPFILES rollBackupFiles starting");
+
String dir = "";
File dirFile;
try
{
dirFile = file.getParentFile();
dir = dirFile.getCanonicalPath();
+ Cache.log.trace("BACKUPFILES dir: " + dir);
} catch (Exception e)
{
- System.out.println(
+ Cache.log.error(
"Could not get canonical path for file '" + file + "'");
+ Cache.log.error(e.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(e));
return false;
}
String filename = file.getName();
String basename = filename;
+ Cache.log.trace("BACKUPFILES filename is " + filename);
boolean ret = true;
// Create/move backups up one
File[] backupFiles = dirFile.listFiles(bff);
int nextIndexNum = 0;
+ Cache.log
+ .trace("BACKUPFILES backupFiles.length: " + backupFiles.length);
if (backupFiles.length == 0)
{
// No other backup files. Just need to move existing file to backupfile_1
+ Cache.log.trace(
+ "BACKUPFILES no existing backup files, setting index to 1");
nextIndexNum = 1;
}
else
if (reverseOrder)
{
// backup style numbering
-
+ Cache.log.trace("BACKUPFILES rolling files in reverse order");
int tempMax = noMax ? -1 : max;
// noMax == true means no limits
tempMax = i;
}
}
-
+
File previousFile = null;
File fileToBeDeleted = null;
for (int n = tempMax; n > 0; n--)
// no "oldest" file to delete
previousFile = backupfile_n;
fileToBeDeleted = null;
+ Cache.log.trace("BACKUPFILES No oldest file to delete");
continue;
}
File replacementFile = backupfile_n;
long fileToBeDeletedLMT = fileToBeDeleted.lastModified();
long replacementFileLMT = replacementFile.lastModified();
+ Cache.log.trace("BACKUPFILES fileToBeDeleted is "
+ + fileToBeDeleted.getAbsolutePath());
+ Cache.log.trace("BACKUPFILES replacementFile is "
+ + backupfile_n.getAbsolutePath());
try
{
File oldestTempFile = nextTempFile(fileToBeDeleted.getName(),
dirFile);
-
+
if (fileToBeDeletedLMT > replacementFileLMT)
{
String fileToBeDeletedLMTString = sdf
.format(fileToBeDeletedLMT);
String replacementFileLMTString = sdf
.format(replacementFileLMT);
- System.out.println("WARNING! I am set to delete backupfile "
+ Cache.log.warn("WARNING! I am set to delete backupfile "
+ fileToBeDeleted.getName()
+ " has modification time "
+ fileToBeDeletedLMTString
boolean delete = confirmNewerDeleteFile(fileToBeDeleted,
replacementFile, true);
+ Cache.log.trace("BACKUPFILES "
+ + (delete ? "confirmed" : "not") + " deleting file "
+ + fileToBeDeleted.getAbsolutePath()
+ + " which is newer than "
+ + replacementFile.getAbsolutePath());
if (delete)
{
}
else
{
- fileToBeDeleted.renameTo(oldestTempFile);
+ Cache.log.debug("BACKUPFILES moving "
+ + fileToBeDeleted.getAbsolutePath() + " to "
+ + oldestTempFile.getAbsolutePath());
+ moveFileToFile(fileToBeDeleted, oldestTempFile);
}
}
else
{
- fileToBeDeleted.renameTo(oldestTempFile);
+ Cache.log.debug("BACKUPFILES going to move "
+ + fileToBeDeleted.getAbsolutePath() + " to "
+ + oldestTempFile.getAbsolutePath());
+ moveFileToFile(fileToBeDeleted, oldestTempFile);
addDeleteFile(oldestTempFile);
}
} catch (Exception e)
{
- System.out.println(
+ Cache.log.error(
"Error occurred, probably making new temp file for '"
+ fileToBeDeleted.getName() + "'");
- e.printStackTrace();
+ Cache.log.error(Cache.getStackTraceString(e));
}
// reset
{
if (previousFile != null)
{
- ret = ret && backupfile_n.renameTo(previousFile);
+ // using boolean '&' instead of '&&' as don't want moveFileToFile
+ // attempt to be conditional (short-circuit)
+ ret = ret & moveFileToFile(backupfile_n, previousFile);
}
}
// index to use for the latest backup
nextIndexNum = 1;
}
- else
+ else // not reverse numbering
{
// version style numbering (with earliest file deletion if max files
// reached)
bfTreeMap.values().toArray(backupFiles);
+ StringBuilder bfsb = new StringBuilder();
+ for (int i = 0; i < backupFiles.length; i++)
+ {
+ if (bfsb.length() > 0)
+ {
+ bfsb.append(", ");
+ }
+ bfsb.append(backupFiles[i].getName());
+ }
+ Cache.log.trace("BACKUPFILES backupFiles: " + bfsb.toString());
// noMax == true means keep all backup files
if ((!noMax) && bfTreeMap.size() >= max)
{
+ Cache.log.trace("BACKUPFILES noMax: " + noMax + ", " + "max: "
+ + max + ", " + "bfTreeMap.size(): " + bfTreeMap.size());
// need to delete some files to keep number of backups to designated
- // max
- int numToDelete = bfTreeMap.size() - max + 1;
+ // max.
+ // Note that if the suffix is not numbered then do not delete any
+ // backup files later or we'll delete the new backup file (there can
+ // be only one).
+ int numToDelete = suffix.indexOf(NUM_PLACEHOLDER) > -1
+ ? bfTreeMap.size() - max + 1
+ : 0;
+ Cache.log.trace("BACKUPFILES numToDelete: " + numToDelete);
// the "replacement" file is the latest backup file being kept (it's
// not replacing though)
File replacementFile = numToDelete < backupFiles.length
File fileToBeDeleted = backupFiles[i];
boolean delete = true;
+ Cache.log.trace(
+ "BACKUPFILES fileToBeDeleted: " + fileToBeDeleted);
+
boolean newer = false;
if (replacementFile != null)
{
String replacementFileLMTString = sdf
.format(replacementFileLMT);
- System.out
- .println("WARNING! I am set to delete backupfile '"
- + fileToBeDeleted.getName()
- + "' has modification time "
+ Cache.log.warn("WARNING! I am set to delete backupfile '"
+ + fileToBeDeleted.getName()
+ + "' has modification time "
+ fileToBeDeletedLMTString
- + " which is newer than the oldest backupfile being kept '"
+ + " which is newer than the oldest backupfile being kept '"
+ replacementFile.getName()
- + "' with modification time "
+ + "' with modification time "
+ replacementFileLMTString);
delete = confirmNewerDeleteFile(fileToBeDeleted,
{
// User has confirmed delete -- no need to add it to the list
fileToBeDeleted.delete();
+ Cache.log.debug("BACKUPFILES deleting fileToBeDeleted: "
+ + fileToBeDeleted);
delete = false;
}
else
{
// keeping file, nothing to do!
+ Cache.log.debug("BACKUPFILES keeping fileToBeDeleted: "
+ + fileToBeDeleted);
}
}
}
if (delete)
{
addDeleteFile(fileToBeDeleted);
+ Cache.log.debug("BACKUPFILES addDeleteFile(fileToBeDeleted): "
+ + fileToBeDeleted);
}
}
String latestBackupFilename = dir + File.separatorChar
+ BackupFilenameParts.getBackupFilename(nextIndexNum, basename,
suffix, digits);
- ret |= file.renameTo(new File(latestBackupFilename));
-
+ Cache.log.trace("BACKUPFILES Moving old file [" + file
+ + "] to latestBackupFilename [" + latestBackupFilename + "]");
+ // using boolean '&' instead of '&&' as don't want moveFileToFile attempt to
+ // be conditional (short-circuit)
+ ret = ret & moveFileToFile(file, new File(latestBackupFilename));
+ Cache.log.debug(
+ "BACKUPFILES moving " + file + " to " + latestBackupFilename
+ + " was " + (ret ? "" : "NOT ") + "successful");
if (tidyUp)
{
+ Cache.log.debug("BACKUPFILES tidying up files");
tidyUpFiles();
}
saveFile = nextTempFile(ftbd.getName(), ftbd.getParentFile());
} catch (Exception e)
{
- System.out.println(
+ Cache.log.error(
"Error when confirming to keep backup file newer than other backup files.");
e.printStackTrace();
}
"label.newerdelete_replacement_line", new String[]
{ ftbd.getName(), rf.getName(), ftbdLMT, rfLMT, ftbdSize,
rfSize }));
+ // "Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted and
+ // replaced by apparently older file \n''{1}''\t(modified {3}, size
+ // {5}).""
messageSB.append("\n\n");
messageSB.append(MessageManager.formatMessage(
"label.confirm_deletion_or_rename", new String[]
{ ftbd.getName(), saveFile.getName() }));
+ // "Confirm deletion of ''{0}'' or rename to ''{1}''?"
String[] options = new String[] {
MessageManager.getString("label.delete"),
MessageManager.getString("label.rename") };
- confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop,
- messageSB.toString(),
- MessageManager.getString("label.backupfiles_confirm_delete"),
- JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
- null, options, options[0]);
+ confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
+ : JvOptionPane.showOptionDialog(Desktop.desktop,
+ messageSB.toString(),
+ MessageManager.getString(
+ "label.backupfiles_confirm_delete"),
+ // "Confirm delete"
+ JvOptionPane.YES_NO_OPTION,
+ JvOptionPane.WARNING_MESSAGE, null, options,
+ options[0]);
}
else
{
.formatMessage("label.newerdelete_line", new String[]
{ ftbd.getName(), rf.getName(), ftbdLMT, rfLMT, ftbdSize,
rfSize }));
+ // "Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted but
+ // is newer than the oldest remaining backup file \n''{1}''\t(modified
+ // {3}, size {5})."
messageSB.append("\n\n");
messageSB.append(MessageManager
.formatMessage("label.confirm_deletion", new String[]
{ ftbd.getName() }));
+ // "Confirm deletion of ''{0}''?"
String[] options = new String[] {
MessageManager.getString("label.delete"),
MessageManager.getString("label.keep") };
- confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop,
- messageSB.toString(),
- MessageManager.getString("label.backupfiles_confirm_delete"),
- JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
- null, options, options[0]);
+ confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
+ : JvOptionPane.showOptionDialog(Desktop.desktop,
+ messageSB.toString(),
+ MessageManager.getString(
+ "label.backupfiles_confirm_delete"),
+ // "Confirm delete"
+ JvOptionPane.YES_NO_OPTION,
+ JvOptionPane.WARNING_MESSAGE, null, options,
+ options[0]);
}
-
// return should be TRUE if file is to be deleted
return (confirmButton == JvOptionPane.YES_OPTION);
}
messageSB = new StringBuilder();
messageSB.append(MessageManager
.getString("label.backupfiles_confirm_delete_old_files"));
+ // "Delete the following older backup files? (see the Backups tab in
+ // Preferences for more options)"
for (int i = 0; i < deleteFiles.size(); i++)
{
File df = deleteFiles.get(i);
new String[]
{ sdf.format(df.lastModified()),
Long.toString(df.length()) }));
+ // "(modified {0}, size {1})"
}
- int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop,
- messageSB.toString(),
- MessageManager
- .getString("label.backupfiles_confirm_delete"),
- JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
+ int confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
+ : JvOptionPane.showConfirmDialog(Desktop.desktop,
+ messageSB.toString(),
+ MessageManager.getString(
+ "label.backupfiles_confirm_delete"),
+ // "Confirm delete"
+ JvOptionPane.YES_NO_OPTION,
+ JvOptionPane.WARNING_MESSAGE);
doDelete = (confirmButton == JvOptionPane.YES_OPTION);
}
for (int i = 0; i < deleteFiles.size(); i++)
{
File fileToDelete = deleteFiles.get(i);
+ Cache.log.trace("BACKUPFILES about to delete fileToDelete:"
+ + fileToDelete);
fileToDelete.delete();
- System.out.println("DELETING '" + fileToDelete.getName() + "'");
+ Cache.log.warn("deleted '" + fileToDelete.getName() + "'");
}
}
}
private TreeMap<Integer, File> sortBackupFilesAsTreeMap(
- File[] backupFiles,
- String basename)
+ File[] backupFiles, String basename)
{
// sort the backup files (based on integer found in the suffix) using a
// precomputed Hashmap for speed
boolean rename = false;
if (write)
{
- roll = this.rollBackupFiles(false);
+ roll = this.rollBackupFiles(false); // tidyUpFiles at the end
rename = this.renameTempFile();
}
if (!okay)
{
StringBuilder messageSB = new StringBuilder();
- messageSB.append(MessageManager.getString( "label.backupfiles_confirm_save_file_backupfiles_roll_wrong"));
+ messageSB.append(MessageManager.getString(
+ "label.backupfiles_confirm_save_file_backupfiles_roll_wrong"));
+ // "Something possibly went wrong with the backups of this file."
if (rename)
{
if (messageSB.length() > 0)
}
messageSB.append(MessageManager.getString(
"label.backupfiles_confirm_save_new_saved_file_ok"));
+ // "The new saved file seems okay."
}
else
{
}
messageSB.append(MessageManager.getString(
"label.backupfiles_confirm_save_new_saved_file_not_ok"));
+ // "The new saved file might not be okay."
}
-
- int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop,
- messageSB.toString(),
- MessageManager
- .getString("label.backupfiles_confirm_save_file"),
- JvOptionPane.OK_OPTION, JvOptionPane.WARNING_MESSAGE);
+ if (messageSB.length() > 0)
+ {
+ messageSB.append("\n");
+ }
+ messageSB
+ .append(MessageManager.getString("label.continue_operation"));
+
+ int confirmButton = Platform.isHeadless() ? JvOptionPane.OK_OPTION
+ : JvOptionPane.showConfirmDialog(Desktop.desktop,
+ messageSB.toString(),
+ MessageManager.getString(
+ "label.backupfiles_confirm_save_file"),
+ // "Confirm save file"
+ JvOptionPane.OK_OPTION, JvOptionPane.WARNING_MESSAGE);
okay = confirmButton == JvOptionPane.OK_OPTION;
}
if (okay)
dirFile = file.getParentFile();
} catch (Exception e)
{
- System.out.println(
+ Cache.log.error(
"Could not get canonical path for file '" + file + "'");
return new TreeMap<>();
}
int pos = deleteFiles.indexOf(fileToBeDeleted);
if (pos > -1)
{
+ Cache.log.debug("BACKUPFILES not adding file "
+ + fileToBeDeleted.getAbsolutePath()
+ + " to the delete list (already at index" + pos + ")");
return true;
}
else
{
+ Cache.log.debug("BACKUPFILES adding file "
+ + fileToBeDeleted.getAbsolutePath() + " to the delete list");
deleteFiles.add(fileToBeDeleted);
}
return ret;
}
+ public static boolean moveFileToFile(File oldFile, File newFile)
+ {
+ Cache.initLogger();
+ boolean ret = false;
+ Path oldPath = Paths.get(oldFile.getAbsolutePath());
+ Path newPath = Paths.get(newFile.getAbsolutePath());
+ try
+ {
+ // delete destination file - not usually necessary but Just In Case...
+ Cache.log.trace("BACKUPFILES deleting " + newFile.getAbsolutePath());
+ newFile.delete();
+ Cache.log.trace("BACKUPFILES moving " + oldFile.getAbsolutePath()
+ + " to " + newFile.getAbsolutePath());
+ Files.move(oldPath, newPath, StandardCopyOption.REPLACE_EXISTING);
+ ret = true;
+ Cache.log.trace("BACKUPFILES move seems to have succeeded");
+ } catch (IOException e)
+ {
+ Cache.log.warn("Could not move file '" + oldPath.toString() + "' to '"
+ + newPath.toString() + "'");
+ Cache.log.error(e.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(e));
+ ret = false;
+ } catch (Exception e)
+ {
+ Cache.log.error(e.getMessage());
+ Cache.log.debug(Cache.getStackTraceString(e));
+ ret = false;
+ }
+ return ret;
+ }
}
*/
package jalview.io;
-import jalview.bin.Cache;
-import jalview.util.MessageManager;
-
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
+import jalview.bin.Cache;
+import jalview.util.MessageManager;
+
public class BackupFilesPresetEntry
{
--- /dev/null
+package jalview.io;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import jalview.bin.Cache;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.FeatureProperties;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.util.DBRefUtils;
+import jalview.util.DnaUtils;
+import jalview.util.MapList;
+import jalview.util.MappingUtils;
+
+/**
+ * A class that provides selective parsing of the EMBL flatfile format.
+ * <p>
+ * The initial implementation is limited to extracting fields used by Jalview
+ * after fetching an EMBL or EMBLCDS entry:
+ *
+ * <pre>
+ * accession, version, sequence, xref
+ * and (for CDS feature) location, protein_id, product, codon_start, translation
+ * </pre>
+ *
+ * For a complete parser, it may be best to adopt that provided in
+ * https://github.com/enasequence/sequencetools/tree/master/src/main/java/uk/ac/ebi/embl/flatfile
+ * (but note this has a dependency on the Apache Commons library)
+ *
+ * @author gmcarstairs
+ * @see ftp://ftp.ebi.ac.uk/pub/databases/ena/sequence/release/doc/usrman.txt
+ * @see ftp://ftp.ebi.ac.uk/pub/databases/embl/doc/FT_current.html
+ */
+public class EmblFlatFile extends AlignFile // FileParse
+{
+ private static final String QUOTE = "\"";
+
+ private static final String DOUBLED_QUOTE = QUOTE + QUOTE;
+
+ /**
+ * A data bean class to hold values parsed from one CDS Feature (FT)
+ */
+ class CdsData
+ {
+ String translation; // from CDS feature /translation
+
+ String cdsLocation; // CDS /location raw value
+
+ int codonStart = 1; // from CDS /codon_start
+
+ String proteinName; // from CDS /product; used for protein description
+
+ String proteinId; // from CDS /protein_id
+
+ List<DBRefEntry> xrefs = new ArrayList<>(); // from CDS /db_xref qualifiers
+
+ Map<String, String> cdsProps = new Hashtable<>(); // CDS other qualifiers
+ }
+
+ private static final String WHITESPACE = "\\s+";
+
+ private String sourceDb;
+
+ /*
+ * values parsed from the EMBL flatfile record
+ */
+ private String accession; // from ID (first token)
+
+ private String version; // from ID (second token)
+
+ private String description; // from (first) DE line
+
+ private int length = 128; // from ID (7th token), with usable default
+
+ private List<DBRefEntry> dbrefs; // from DR
+
+ private String sequenceString; // from SQ lines
+
+ /*
+ * parsed CDS data fields, keyed by protein_id
+ */
+ private Map<String, CdsData> cds;
+
+ /**
+ * Constructor
+ *
+ * @param fp
+ * @param sourceId
+ * @throws IOException
+ */
+ public EmblFlatFile(FileParse fp, String sourceId) throws IOException
+ {
+ super(false, fp); // don't parse immediately
+ this.sourceDb = sourceId;
+ dbrefs = new ArrayList<>();
+
+ /*
+ * using TreeMap gives CDS sequences in alphabetical, so readable, order
+ */
+ cds = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ }
+
+ /**
+ * Parses the flatfile, and if successful, saves as an annotated sequence
+ * which may be retrieved by calling {@code getSequence()}
+ *
+ * @throws IOException
+ */
+ public void parse() throws IOException
+ {
+ String line = nextLine();
+ while (line != null)
+ {
+ if (line.startsWith("ID"))
+ {
+ line = parseID(line);
+ }
+ else if (line.startsWith("DE"))
+ {
+ line = parseDE(line);
+ }
+ else if (line.startsWith("DR"))
+ {
+ line = parseDR(line);
+ }
+ else if (line.startsWith("SQ"))
+ {
+ line = parseSQ();
+ }
+ else if (line.startsWith("FT"))
+ {
+ line = parseFT(line);
+ }
+ else
+ {
+ line = nextLine();
+ }
+ }
+ buildSequence();
+ }
+
+ /**
+ * Extracts and saves the primary accession and version (SV value) from an ID
+ * line, or null if not found. Returns the next line after the one processed.
+ *
+ * @param line
+ * @throws IOException
+ */
+ String parseID(String line) throws IOException
+ {
+ String[] tokens = line.substring(2).split(";");
+
+ /*
+ * first is primary accession
+ */
+ String token = tokens[0].trim();
+ if (!token.isEmpty())
+ {
+ this.accession = token;
+ }
+
+ /*
+ * second token is 'SV versionNo'
+ */
+ if (tokens.length > 1)
+ {
+ token = tokens[1].trim();
+ if (token.startsWith("SV"))
+ {
+ String[] bits = token.trim().split(WHITESPACE);
+ this.version = bits[bits.length - 1];
+ }
+ }
+
+ /*
+ * seventh token is 'length BP'
+ */
+ if (tokens.length > 6)
+ {
+ token = tokens[6].trim();
+ String[] bits = token.trim().split(WHITESPACE);
+ try
+ {
+ this.length = Integer.valueOf(bits[0]);
+ } catch (NumberFormatException e)
+ {
+ Cache.log.error("bad length read in flatfile, line: " + line);
+ }
+ }
+
+ return nextLine();
+ }
+
+ /**
+ * Reads sequence description from the first DE line found. Any trailing
+ * period is discarded. If there are multiple DE lines, only the first (short
+ * description) is read, the rest are ignored.
+ *
+ * @param line
+ * @return
+ * @throws IOException
+ */
+ String parseDE(String line) throws IOException
+ {
+ String desc = line.substring(2).trim();
+ if (desc.endsWith("."))
+ {
+ desc = desc.substring(0, desc.length() - 1);
+ }
+ this.description = desc;
+
+ /*
+ * pass over any additional DE lines
+ */
+ while ((line = nextLine()) != null)
+ {
+ if (!line.startsWith("DE"))
+ {
+ break;
+ }
+ }
+
+ return line;
+ }
+
+ /**
+ * Processes one DR line and saves as a DBRefEntry cross-reference. Returns
+ * the line following the line processed.
+ *
+ * @param line
+ * @throws IOException
+ */
+ String parseDR(String line) throws IOException
+ {
+ String[] tokens = line.substring(2).split(";");
+ if (tokens.length > 1)
+ {
+ /*
+ * ensure UniProtKB/Swiss-Prot converted to UNIPROT
+ */
+ String db = tokens[0].trim();
+ db = DBRefUtils.getCanonicalName(db);
+ String acc = tokens[1].trim();
+ if (acc.endsWith("."))
+ {
+ acc = acc.substring(0, acc.length() - 1);
+ }
+ String version = "0";
+ if (tokens.length > 2)
+ {
+ String secondaryId = tokens[2].trim();
+ if (!secondaryId.isEmpty())
+ {
+ // todo: is this right? secondary id is not a version number
+ // version = secondaryId;
+ }
+ }
+ this.dbrefs.add(new DBRefEntry(db, version, acc));
+ }
+
+ return nextLine();
+ }
+
+ /**
+ * Reads and saves the sequence, read from the lines following the SQ line.
+ * Whitespace and position counters are discarded. Returns the next line
+ * following the sequence data (the next line that doesn't start with
+ * whitespace).
+ *
+ * @throws IOException
+ */
+ String parseSQ() throws IOException
+ {
+ StringBuilder sb = new StringBuilder(this.length);
+ String line = nextLine();
+ while (line != null && line.startsWith(" "))
+ {
+ line = line.trim();
+ String[] blocks = line.split(WHITESPACE);
+
+ /*
+ * omit the last block (position counter) on each line
+ */
+ for (int i = 0; i < blocks.length - 1; i++)
+ {
+ sb.append(blocks[i]);
+ }
+ line = nextLine();
+ }
+ this.sequenceString = sb.toString();
+
+ return line;
+ }
+
+ /**
+ * Processes an FT line. If it declares a feature type of interest (currently,
+ * only CDS is processed), processes all of the associated lines (feature
+ * qualifiers), and returns the next line after that, otherwise simply returns
+ * the next line.
+ *
+ * @param line
+ * @return
+ * @throws IOException
+ */
+ String parseFT(String line) throws IOException
+ {
+ String[] tokens = line.split(WHITESPACE);
+ if (tokens.length < 3 || !"CDS".equals(tokens[1]))
+ {
+ return nextLine();
+ }
+
+ CdsData data = new CdsData();
+ data.cdsLocation = tokens[2];
+ // TODO location can be over >1 line e.g. EAW51554
+
+ line = nextLine();
+ while (line != null)
+ {
+ if (!line.startsWith("FT ")) // 4 spaces
+ {
+ // e.g. start of next feature "FT source..."
+ break;
+ }
+
+ /*
+ * extract qualifier, e.g. FT /protein_id="CAA37824.1"
+ * - the value may extend over more than one line
+ * - if the value has enclosing quotes, these are removed
+ * - escaped double quotes ("") are reduced to a single character
+ */
+ int slashPos = line.indexOf('/');
+ if (slashPos == -1)
+ {
+ Cache.log.error("Unexpected EMBL line ignored: " + line);
+ line = nextLine();
+ continue;
+ }
+ int eqPos = line.indexOf('=', slashPos + 1);
+ if (eqPos == -1)
+ {
+ // can happen, e.g. /ribosomal_slippage
+ // Cache.log.error("Unexpected EMBL line ignored: " + line);
+ line = nextLine();
+ continue;
+ }
+ String qualifier = line.substring(slashPos + 1, eqPos);
+ String value = line.substring(eqPos + 1);
+ value = removeQuotes(value);
+ StringBuilder sb = new StringBuilder().append(value);
+ line = parseFeatureQualifier(sb, qualifier);
+ String featureValue = sb.toString();
+
+ if ("protein_id".equals(qualifier))
+ {
+ data.proteinId = featureValue;
+ }
+ else if ("codon_start".equals(qualifier))
+ {
+ try
+ {
+ data.codonStart = Integer.parseInt(featureValue.trim());
+ } catch (NumberFormatException e)
+ {
+ Cache.log.error("Invalid codon_start in XML for " + this.accession
+ + ": " + e.getMessage());
+ }
+ }
+ else if ("db_xref".equals(qualifier))
+ {
+ String[] parts = featureValue.split(":");
+ if (parts.length == 2)
+ {
+ String db = parts[0].trim();
+ db = DBRefUtils.getCanonicalName(db);
+ DBRefEntry dbref = new DBRefEntry(db, "0", parts[1].trim());
+ data.xrefs.add(dbref);
+ }
+ }
+ else if ("product".equals(qualifier))
+ {
+ data.proteinName = featureValue;
+ }
+ else if ("translation".equals(qualifier))
+ {
+ data.translation = featureValue;
+ }
+ else if (!"".equals(featureValue))
+ {
+ // throw anything else into the additional properties hash
+ data.cdsProps.put(qualifier, featureValue);
+ }
+ }
+
+ if (data.proteinId != null)
+ {
+ this.cds.put(data.proteinId, data);
+ }
+ else
+ {
+ Cache.log.error("Ignoring CDS feature with no protein_id for "
+ + sourceDb + ":" + accession);
+ }
+
+ return line;
+ }
+
+ /**
+ * Removes leading or trailing double quotes (") unless doubled, and changes
+ * any 'escaped' (doubled) double quotes to single characters. As per the
+ * Feature Table specification for Qualifiers, Free Text.
+ *
+ * @param value
+ * @return
+ */
+ static String removeQuotes(String value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+ if (value.startsWith(QUOTE) && !value.startsWith(DOUBLED_QUOTE))
+ {
+ value = value.substring(1);
+ }
+ if (value.endsWith(QUOTE) && !value.endsWith(DOUBLED_QUOTE))
+ {
+ value = value.substring(0, value.length() - 1);
+ }
+ value = value.replace(DOUBLED_QUOTE, QUOTE);
+ return value;
+ }
+
+ /**
+ * Reads the value of a feature (FT) qualifier from one or more lines of the
+ * file, and returns the next line after that. Values are appended to the
+ * string buffer, which should be already primed with the value read from the
+ * first line for the qualifier (with any leading double quote removed).
+ * Enclosing double quotes are removed, and escaped (repeated) double quotes
+ * reduced to one only. For example for
+ *
+ * <pre>
+ * FT /note="gene_id=hCG28070.3
+ * FT ""foobar"" isoform=CRA_b"
+ * the returned value is
+ * gene_id=hCG28070.3 "foobar" isoform=CRA_b
+ * </pre>
+ *
+ * Note the side-effect of this method, to advance data reading to the next
+ * line after the feature qualifier.
+ *
+ * @param sb
+ * a string buffer primed with the first line of the value
+ * @param qualifierName
+ * @return
+ * @throws IOException
+ */
+ String parseFeatureQualifier(StringBuilder sb, String qualifierName)
+ throws IOException
+ {
+ String line;
+ while ((line = nextLine()) != null)
+ {
+ if (!line.startsWith("FT "))
+ {
+ break; // reached next feature or other input line
+ }
+ String[] tokens = line.split(WHITESPACE);
+ if (tokens.length < 2)
+ {
+ Cache.log.error("Ignoring bad EMBL line for " + this.accession
+ + ": " + line);
+ break;
+ }
+ if (tokens[1].startsWith("/"))
+ {
+ break; // next feature qualifier
+ }
+
+ /*
+ * heuristic rule: most multi-line value (e.g. /product) are text,
+ * so add a space for word boundary at a new line; not for translation
+ */
+ if (!"translation".equals(qualifierName))
+ {
+ sb.append(" ");
+ }
+
+ /*
+ * remove trailing " and unescape doubled ""
+ */
+ String data = removeQuotes(tokens[1]);
+ sb.append(data);
+ }
+
+ return line;
+ }
+
+ /**
+ * Constructs and saves the sequence from parsed components
+ */
+ void buildSequence()
+ {
+ if (this.accession == null || this.sequenceString == null)
+ {
+ Cache.log.error("Failed to parse data from EMBL");
+ return;
+ }
+
+ String name = this.accession;
+ if (this.sourceDb != null)
+ {
+ name = this.sourceDb + "|" + name;
+ }
+ SequenceI seq = new Sequence(name, this.sequenceString);
+ seq.setDescription(this.description);
+
+ /*
+ * add a DBRef to itself
+ */
+ DBRefEntry selfRef = new DBRefEntry(sourceDb, version, accession);
+ int[] startEnd = new int[] { 1, seq.getLength() };
+ selfRef.setMap(new Mapping(null, startEnd, startEnd, 1, 1));
+ seq.addDBRef(selfRef);
+
+ for (DBRefEntry dbref : this.dbrefs)
+ {
+ seq.addDBRef(dbref);
+ }
+
+ processCDSFeatures(seq);
+
+ seq.deriveSequence();
+
+ addSequence(seq);
+ }
+
+ /**
+ * Process the CDS features, including generation of cross-references and
+ * mappings to the protein products (translation)
+ *
+ * @param seq
+ */
+ protected void processCDSFeatures(SequenceI seq)
+ {
+ /*
+ * record protein products found to avoid duplication i.e. >1 CDS with
+ * the same /protein_id [though not sure I can find an example of this]
+ */
+ Map<String, SequenceI> proteins = new HashMap<>();
+ for (CdsData data : cds.values())
+ {
+ processCDSFeature(seq, data, proteins);
+ }
+ }
+
+ /**
+ * Processes data for one parsed CDS feature to
+ * <ul>
+ * <li>create a protein product sequence for the translation</li>
+ * <li>create a cross-reference to protein with mapping from dna</li>
+ * <li>add a CDS feature to the sequence for each CDS start-end range</li>
+ * <li>add any CDS dbrefs to the sequence and to the protein product</li>
+ * </ul>
+ *
+ * @param SequenceI
+ * dna
+ * @param proteins
+ * map of protein products so far derived from CDS data
+ */
+ void processCDSFeature(SequenceI dna, CdsData data,
+ Map<String, SequenceI> proteins)
+ {
+ /*
+ * parse location into a list of [start, end, start, end] positions
+ */
+ int[] exons = getCdsRanges(this.accession, data.cdsLocation);
+
+ MapList maplist = buildMappingToProtein(dna, exons, data);
+
+ int exonNumber = 0;
+
+ for (int xint = 0; exons != null && xint < exons.length - 1; xint += 2)
+ {
+ int exonStart = exons[xint];
+ int exonEnd = exons[xint + 1];
+ int begin = Math.min(exonStart, exonEnd);
+ int end = Math.max(exonStart, exonEnd);
+ exonNumber++;
+ String desc = String.format("Exon %d for protein EMBLCDS:%s",
+ exonNumber, data.proteinId);
+
+ SequenceFeature sf = new SequenceFeature("CDS", desc, begin, end,
+ this.sourceDb);
+ for (Entry<String, String> val : data.cdsProps.entrySet())
+ {
+ sf.setValue(val.getKey(), val.getValue());
+ }
+
+ sf.setEnaLocation(data.cdsLocation);
+ boolean forwardStrand = exonStart <= exonEnd;
+ sf.setStrand(forwardStrand ? "+" : "-");
+ sf.setPhase(String.valueOf(data.codonStart - 1));
+ sf.setValue(FeatureProperties.EXONPOS, exonNumber);
+ sf.setValue(FeatureProperties.EXONPRODUCT, data.proteinName);
+
+ dna.addSequenceFeature(sf);
+ }
+
+ boolean hasUniprotDbref = false;
+ for (DBRefEntry xref : data.xrefs)
+ {
+ dna.addDBRef(xref);
+ if (xref.getSource().equals(DBRefSource.UNIPROT))
+ {
+ /*
+ * construct (or find) the sequence for (data.protein_id, data.translation)
+ */
+ SequenceI protein = buildProteinProduct(dna, xref, data, proteins);
+ Mapping map = new Mapping(protein, maplist);
+ map.setMappedFromId(data.proteinId);
+ xref.setMap(map);
+
+ /*
+ * add DBRefs with mappings from dna to protein and the inverse
+ */
+ DBRefEntry db1 = new DBRefEntry(sourceDb, version, accession);
+ db1.setMap(new Mapping(dna, maplist.getInverse()));
+ protein.addDBRef(db1);
+
+ hasUniprotDbref = true;
+ }
+ }
+
+ /*
+ * if we have a product (translation) but no explicit Uniprot dbref
+ * (example: EMBL M19487 protein_id AAB02592.1)
+ * then construct mappings to an assumed EMBLCDSPROTEIN accession
+ */
+ if (!hasUniprotDbref)
+ {
+ SequenceI protein = proteins.get(data.proteinId);
+ if (protein == null)
+ {
+ protein = new Sequence(data.proteinId, data.translation);
+ protein.setDescription(data.proteinName);
+ proteins.put(data.proteinId, protein);
+ }
+ // assuming CDSPROTEIN sequence version = dna version (?!)
+ DBRefEntry db1 = new DBRefEntry(DBRefSource.EMBLCDSProduct,
+ this.version, data.proteinId);
+ protein.addDBRef(db1);
+
+ DBRefEntry dnaToEmblProteinRef = new DBRefEntry(
+ DBRefSource.EMBLCDSProduct, this.version, data.proteinId);
+ Mapping map = new Mapping(protein, maplist);
+ map.setMappedFromId(data.proteinId);
+ dnaToEmblProteinRef.setMap(map);
+ dna.addDBRef(dnaToEmblProteinRef);
+ }
+
+ /*
+ * comment brought forward from EmblXmlSource, lines 447-451:
+ * TODO: if retrieved from EMBLCDS, add a DBRef back to the parent EMBL
+ * sequence with the exon map; if given a dataset reference, search
+ * dataset for parent EMBL sequence if it exists and set its map;
+ * make a new feature annotating the coding contig
+ */
+ }
+
+ /**
+ * Computes a mapping from CDS positions in DNA sequence to protein product
+ * positions, with allowance for stop codon or incomplete start codon
+ *
+ * @param dna
+ * @param exons
+ * @param data
+ * @return
+ */
+ MapList buildMappingToProtein(final SequenceI dna, final int[] exons,
+ final CdsData data)
+ {
+ MapList dnaToProteinMapping = null;
+ int peptideLength = data.translation.length();
+
+ int[] proteinRange = new int[] { 1, peptideLength };
+ if (exons != null && exons.length > 0)
+ {
+ /*
+ * We were able to parse 'location'; do a final
+ * product length truncation check
+ */
+ int[] cdsRanges = adjustForProteinLength(peptideLength, exons);
+ dnaToProteinMapping = new MapList(cdsRanges, proteinRange, 3, 1);
+ }
+ else
+ {
+ /*
+ * workaround until we handle all 'location' formats fully
+ * e.g. X53828.1:60..1058 or <123..>289
+ */
+ Cache.log.error(String.format(
+ "Implementation Notice: EMBLCDS location '%s'not properly supported yet"
+ + " - Making up the CDNA region of (%s:%s)... may be incorrect",
+ data.cdsLocation, sourceDb, this.accession));
+
+ int completeCodonsLength = 1 - data.codonStart + dna.getLength();
+ int mappedDnaEnd = dna.getEnd();
+ if (peptideLength * 3 == completeCodonsLength)
+ {
+ // this might occur for CDS sequences where no features are marked
+ Cache.log.warn("Assuming no stop codon at end of cDNA fragment");
+ mappedDnaEnd = dna.getEnd();
+ }
+ else if ((peptideLength + 1) * 3 == completeCodonsLength)
+ {
+ Cache.log.warn("Assuming stop codon at end of cDNA fragment");
+ mappedDnaEnd = dna.getEnd() - 3;
+ }
+
+ if (mappedDnaEnd != -1)
+ {
+ int[] cdsRanges = new int[] {
+ dna.getStart() + (data.codonStart - 1), mappedDnaEnd };
+ dnaToProteinMapping = new MapList(cdsRanges, proteinRange, 3, 1);
+ }
+ }
+
+ return dnaToProteinMapping;
+ }
+
+ /**
+ * Constructs a sequence for the protein product for the CDS data (if there is
+ * one), and dbrefs with mappings from CDS to protein and the reverse
+ *
+ * @param dna
+ * @param xref
+ * @param data
+ * @param proteins
+ * @return
+ */
+ SequenceI buildProteinProduct(SequenceI dna, DBRefEntry xref,
+ CdsData data, Map<String, SequenceI> proteins)
+ {
+ /*
+ * check we have some data to work with
+ */
+ if (data.proteinId == null || data.translation == null)
+ {
+ return null;
+ }
+
+ /*
+ * Construct the protein sequence (if not already seen)
+ */
+ String proteinSeqName = xref.getSource() + "|" + xref.getAccessionId();
+ SequenceI protein = proteins.get(proteinSeqName);
+ if (protein == null)
+ {
+ protein = new Sequence(proteinSeqName, data.translation, 1,
+ data.translation.length());
+ protein.setDescription(data.proteinName != null ? data.proteinName
+ : "Protein Product from " + sourceDb);
+ proteins.put(proteinSeqName, protein);
+ }
+
+ return protein;
+ }
+
+ /**
+ * Returns the CDS location as a single array of [start, end, start, end...]
+ * positions. If on the reverse strand, these will be in descending order.
+ *
+ * @param accession
+ * @param location
+ * @return
+ */
+ protected int[] getCdsRanges(String accession, String location)
+ {
+ if (location == null)
+ {
+ return new int[] {};
+ }
+
+ try
+ {
+ List<int[]> ranges = DnaUtils.parseLocation(location);
+ return MappingUtils.listToArray(ranges);
+ } catch (ParseException e)
+ {
+ Cache.log.warn(
+ String.format("Not parsing inexact CDS location %s in ENA %s",
+ location, accession));
+ return new int[] {};
+ }
+ }
+
+ /**
+ * Output (print) is not implemented for EMBL flat file format
+ */
+ @Override
+ public String print(SequenceI[] seqs, boolean jvsuffix)
+ {
+ return null;
+ }
+
+ /**
+ * Truncates (if necessary) the exon intervals to match 3 times the length of
+ * the protein; also accepts 3 bases longer (for stop codon not included in
+ * protein)
+ *
+ * @param proteinLength
+ * @param exon
+ * an array of [start, end, start, end...] intervals
+ * @return the same array (if unchanged) or a truncated copy
+ */
+ static int[] adjustForProteinLength(int proteinLength, int[] exon)
+ {
+ if (proteinLength <= 0 || exon == null)
+ {
+ return exon;
+ }
+ int expectedCdsLength = proteinLength * 3;
+ int exonLength = MappingUtils.getLength(Arrays.asList(exon));
+
+ /*
+ * if exon length matches protein, or is shorter, or longer by the
+ * length of a stop codon (3 bases), then leave it unchanged
+ */
+ if (expectedCdsLength >= exonLength
+ || expectedCdsLength == exonLength - 3)
+ {
+ return exon;
+ }
+
+ int origxon[];
+ int sxpos = -1;
+ int endxon = 0;
+ origxon = new int[exon.length];
+ System.arraycopy(exon, 0, origxon, 0, exon.length);
+ int cdspos = 0;
+ for (int x = 0; x < exon.length; x += 2)
+ {
+ cdspos += Math.abs(exon[x + 1] - exon[x]) + 1;
+ if (expectedCdsLength <= cdspos)
+ {
+ // advanced beyond last codon.
+ sxpos = x;
+ if (expectedCdsLength != cdspos)
+ {
+ // System.err
+ // .println("Truncating final exon interval on region by "
+ // + (cdspos - cdslength));
+ }
+
+ /*
+ * shrink the final exon - reduce end position if forward
+ * strand, increase it if reverse
+ */
+ if (exon[x + 1] >= exon[x])
+ {
+ endxon = exon[x + 1] - cdspos + expectedCdsLength;
+ }
+ else
+ {
+ endxon = exon[x + 1] + cdspos - expectedCdsLength;
+ }
+ break;
+ }
+ }
+
+ if (sxpos != -1)
+ {
+ // and trim the exon interval set if necessary
+ int[] nxon = new int[sxpos + 2];
+ System.arraycopy(exon, 0, nxon, 0, sxpos + 2);
+ nxon[sxpos + 1] = endxon; // update the end boundary for the new exon
+ // set
+ exon = nxon;
+ }
+ return exon;
+ }
+}
import jalview.api.FeatureSettingsModelI;
import jalview.util.MessageManager;
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
+import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
import java.util.zip.GZIPInputStream;
+
/**
* implements a random access wrapper around a particular datasource, for
* passing to identifyFile and AlignFile objects.
public File inFile = null;
+
/**
* a viewport associated with the current file operation. May be null. May
* move to different object.
}
if (!error)
{
- if (fileStr.toLowerCase().endsWith(".gz"))
+ try
{
- try
- {
- dataIn = tryAsGzipSource(new FileInputStream(fileStr));
- dataName = fileStr;
- return error;
- } catch (Exception x)
- {
- warningMessage = "Failed to resolve as a GZ stream ("
- + x.getMessage() + ")";
- // x.printStackTrace();
- }
- ;
+ dataIn = checkForGzipStream(new FileInputStream(fileStr));
+ dataName = fileStr;
+ } catch (Exception x)
+ {
+ warningMessage = "Failed to resolve " + fileStr
+ + " as a data source. (" + x.getMessage() + ")";
+ // x.printStackTrace();
+ error = true;
}
-
- dataIn = new BufferedReader(new FileReader(fileStr));
- dataName = fileStr;
+ ;
}
return error;
}
+
+ /**
+ * Recognise the 2-byte magic header for gzip streams
+ *
+ * https://recalll.co/ask/v/topic/java-How-to-check-if-InputStream-is-Gzipped/555aadd62bd27354438b90f6
+ *
+ * @param bytes - at least two bytes
+ * @return
+ */
+ private static boolean isGzipStream(byte[] bytes) {
+ int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
+ return (GZIPInputStream.GZIP_MAGIC == head);
+ }
- private BufferedReader tryAsGzipSource(InputStream inputStream)
+ /**
+ * Returns a Reader for the given input after wrapping it in a buffered input
+ * stream, and then checking if it needs to be wrapped by a GZipInputStream
+ *
+ * @param input
+ * @return
+ */
+ private BufferedReader checkForGzipStream(InputStream input) throws Exception {
+
+ // NB: stackoverflow https://stackoverflow.com/questions/4818468/how-to-check-if-inputstream-is-gzipped
+ // could use a PushBackInputStream rather than a BufferedInputStream
+
+ BufferedInputStream bufinput;
+ if (!input.markSupported()) {
+ bufinput= new BufferedInputStream(input,16);
+ input = bufinput;
+ }
+ input.mark(4);
+ byte[] bytes=input.readNBytes(2);
+ input.reset();
+ if (bytes.length==2 && isGzipStream(bytes)) {
+ return getGzipReader(input);
+ }
+ // return a buffered reader for the stream.
+ InputStreamReader isReader= new InputStreamReader(input);
+ BufferedReader toReadFrom=new BufferedReader(isReader);
+ return toReadFrom;
+ }
+ /**
+ * Returns a {@code BufferedReader} which wraps the input stream with a
+ * GZIPInputStream. Throws a {@code ZipException} if a GZIP format error
+ * occurs or the compression method used is unsupported.
+ *
+ * @param inputStream
+ * @return
+ * @throws Exception
+ */
+ private BufferedReader getGzipReader(InputStream inputStream)
throws Exception
{
BufferedReader inData = new BufferedReader(
return inData;
}
- private boolean checkURLSource(String fileStr)
+ /**
+ * Tries to read from the given URL. If successful, saves a reader to the
+ * response in field {@code dataIn}, otherwise (on exception, or HTTP response
+ * status not 200), throws an exception.
+ * <p>
+ * If the response status includes
+ *
+ * <pre>
+ * Content-Type : application/x-gzip
+ * </pre>
+ *
+ * then tries to read as gzipped content.
+ *
+ * @param urlStr
+ * @throws IOException
+ * @throws MalformedURLException
+ */
+ private void checkURLSource(String urlStr)
throws IOException, MalformedURLException
{
errormessage = "URL NOT FOUND";
- URL url = new URL(fileStr);
- //
- // GZIPInputStream code borrowed from Aquaria (soon to be open sourced) via
- // Kenny Sabir
- Exception e = null;
- if (fileStr.toLowerCase().endsWith(".gz"))
+ URL url = new URL(urlStr);
+ URLConnection _conn = url.openConnection();
+ if (_conn instanceof HttpURLConnection)
{
- try
+ HttpURLConnection conn = (HttpURLConnection) _conn;
+ int rc = conn.getResponseCode();
+ if (rc != HttpURLConnection.HTTP_OK)
{
- InputStream inputStream = url.openStream();
- dataIn = tryAsGzipSource(inputStream);
- dataName = fileStr;
- return false;
+ throw new IOException(
+ "Response status from " + urlStr + " was " + rc);
+ }
+ } else {
+ try {
+ dataIn = checkForGzipStream(_conn.getInputStream());
+ dataName=urlStr;
+ } catch (IOException ex)
+ {
+ throw new IOException("Failed to handle non-HTTP URI stream",ex);
} catch (Exception ex)
{
- e = ex;
+ throw new IOException("Failed to determine type of input stream for given URI",ex);
}
+ return;
}
-
- try
- {
- dataIn = new BufferedReader(new InputStreamReader(url.openStream()));
- } catch (IOException q)
+ String encoding = _conn.getContentEncoding();
+ String contentType = _conn.getContentType();
+ boolean isgzipped = "application/x-gzip".equalsIgnoreCase(contentType)
+ || "gzip".equals(encoding);
+ Exception e = null;
+ InputStream inputStream = _conn.getInputStream();
+ if (isgzipped)
{
- if (e != null)
+ try
+ {
+ dataIn = getGzipReader(inputStream);
+ dataName = urlStr;
+ } catch (Exception e1)
{
throw new IOException(MessageManager
.getString("exception.failed_to_resolve_gzip_stream"), e);
}
- throw q;
+ return;
}
- // record URL as name of datasource.
- dataName = fileStr;
- return false;
+
+ dataIn = new BufferedReader(new InputStreamReader(inputStream));
+ dataName = urlStr;
+ return;
}
/**
* RuntimeException throwable by htsjdk
*/
String msg = String.format("Error reading VCF for %s:%d-%d: %s ",
- map.chromosome, vcfStart, vcfEnd);
+ map.chromosome, vcfStart, vcfEnd,e.getLocalizedMessage());
Cache.log.error(msg);
}
}
*/
public void dispose()
{
+ hiddenColumns = null;
hconsensus = null;
complementConsensus = null;
hStrucConsensus = null;
}
}
}
+
+ /**
+ * Converts a list of [start, end] ranges to a single array of [start, end,
+ * start, end ...]
+ *
+ * @param ranges
+ * @return
+ */
+ public static int[] listToArray(List<int[]> ranges)
+ {
+ int[] result = new int[ranges.size() * 2];
+ int i = 0;
+ for (int[] range : ranges)
+ {
+ result[i++] = range[0];
+ result[i++] = range[1];
+ }
+ return result;
+ }
}
*/
public class Platform
{
- private static Boolean isAMac = null, isWindows = null;
+ private static Boolean isAMac = null, isWindows = null, isLinux = null;
private static Boolean isHeadless = null;
/**
+ * added to check LaF for Linux
+ *
+ * @return
+ */
+ public static boolean isLinux()
+ {
+ return (isLinux == null
+ ? (isLinux = (System.getProperty("os.name").indexOf("Linux") >= 0))
+ : isLinux);
+ }
+
+ /**
* sorry folks - Macs really are different
*
* @return true if we do things in a special way.
{
return false;
}
- return (jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx() // .getMenuShortcutKeyMaskEx()
+ return (jalview.util.ShortcutKeyMaskExWrapper
+ .getMenuShortcutKeyMaskEx() // .getMenuShortcutKeyMaskEx()
& jalview.util.ShortcutKeyMaskExWrapper
.getModifiersEx(e)) != 0; // getModifiers()) != 0;
}
}
/**
- * A (case sensitive) file path comparator that ignores the difference between /
- * and \
+ * A (case sensitive) file path comparator that ignores the difference between
+ * / and \
*
* @param path1
* @param path2
ranges = null;
currentTree = null;
selectionGroup = null;
+ colSel = null;
setAlignment(null);
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefSource;
-import com.stevesoft.pat.Regex;
-
-public class EmblCdsSource extends EmblXmlSource
+public class EmblCdsSource extends EmblFlatfileSource // was EmblXmlSource
{
public EmblCdsSource()
}
@Override
- public String getAccessionSeparator()
- {
- return null;
- }
-
- @Override
- public Regex getAccessionValidator()
- {
- return new Regex("^[A-Z]+[0-9]+");
- }
-
- @Override
public String getDbSource()
{
return DBRefSource.EMBLCDS;
}
@Override
- public String getDbVersion()
- {
- return "0"; // TODO : this is dynamically set for a returned record - not
- // tied to proxy
- }
-
- @Override
public AlignmentI getSequenceRecords(String queries) throws Exception
{
if (queries.indexOf(".") > -1)
return getEmblSequenceRecords(DBRefSource.EMBLCDS, queries);
}
- @Override
- public boolean isValidReference(String accession)
- {
- // most embl CDS refs look like ..
- // TODO: improve EMBLCDS regex
- return (accession == null || accession.length() < 2) ? false
- : getAccessionValidator().search(accession);
- }
-
/**
* cDNA for LDHA_CHICK swissprot sequence
*/
return "EMBL (CDS)";
}
- @Override
- public int getTier()
- {
- return 0;
- }
-
}
--- /dev/null
+package jalview.ws.dbsources;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.stevesoft.pat.Regex;
+
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.EmblFlatFile;
+import jalview.io.FileParse;
+import jalview.ws.ebi.EBIFetchClient;
+
+/**
+ * A class that does partial parsing of an EMBL flatfile.
+ *
+ * @author gmcarstairs
+ *
+ */
+public abstract class EmblFlatfileSource extends EbiFileRetrievedProxy
+{
+ private static final Regex ACCESSION_REGEX = new Regex("^[A-Z]+[0-9]+");
+
+ @Override
+ public String getDbVersion()
+ {
+ return "0";
+ }
+
+ @Override
+ public String getAccessionSeparator()
+ {
+ return null;
+ }
+
+ @Override
+ public Regex getAccessionValidator()
+ {
+ return ACCESSION_REGEX;
+ }
+
+ @Override
+ public boolean isValidReference(String accession)
+ {
+ if (accession == null || accession.length() < 2)
+ {
+ return false;
+ }
+ return getAccessionValidator().search(accession);
+ }
+
+ @Override
+ public AlignmentI getSequenceRecords(String queries) throws Exception
+ {
+ return null;
+ }
+
+ @Override
+ public int getTier()
+ {
+ return 0;
+ }
+
+ protected AlignmentI getEmblSequenceRecords(String dbName, String query)
+ throws Exception
+ {
+ startQuery();
+ EBIFetchClient dbFetch = new EBIFetchClient();
+ File reply;
+ try
+ {
+ reply = dbFetch.fetchDataAsFile(
+ dbName.toLowerCase() + ":" + query.trim(), null, "gz");
+ } catch (Exception e)
+ {
+ stopQuery();
+ throw new Exception(
+ String.format("EBI EMBL retrieval failed for %s:%s",
+ dbName.toLowerCase(), query.trim()),
+ e);
+ }
+ return getEmblSequenceRecords(dbName, query, reply);
+ }
+
+ private AlignmentI getEmblSequenceRecords(String dbName, String query,
+ File reply) throws IOException
+ {
+ AlignmentI al = null;
+
+ if (reply != null && reply.exists())
+ {
+ file = reply.getAbsolutePath();
+ FileParse fp = new FileParse(file, DataSourceType.FILE);
+ EmblFlatFile emblParser = new EmblFlatFile(fp, getDbSource());
+ emblParser.parse();
+ SequenceI[] seqs = emblParser.getSeqsAsArray();
+ if (seqs.length > 0)
+ {
+ al = new Alignment(seqs);
+ }
+
+ if (al == null)
+ {
+ Cache.log.error(
+ "No record found for '" + dbName + ":" + query + "'");
+ }
+ }
+
+ stopQuery();
+ return al;
+ }
+
+ @Override
+ public boolean isDnaCoding()
+ {
+ return true;
+ }
+}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefSource;
-import com.stevesoft.pat.Regex;
-
/**
* @author JimP
*
*/
-public class EmblSource extends EmblXmlSource
+public class EmblSource extends EmblFlatfileSource // was EmblXmlSource
{
public EmblSource()
/*
* (non-Javadoc)
*
- * @see jalview.ws.DbSourceProxy#getAccessionSeparator()
- */
- @Override
- public String getAccessionSeparator()
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.DbSourceProxy#getAccessionValidator()
- */
- @Override
- public Regex getAccessionValidator()
- {
- return new Regex("^[A-Z]+[0-9]+");
- }
-
- /*
- * (non-Javadoc)
- *
* @see jalview.ws.DbSourceProxy#getDbSource()
*/
@Override
/*
* (non-Javadoc)
*
- * @see jalview.ws.DbSourceProxy#getDbVersion()
- */
- @Override
- public String getDbVersion()
- {
- // TODO Auto-generated method stub
- return "0";
- }
-
- /*
- * (non-Javadoc)
- *
* @see jalview.ws.DbSourceProxy#getSequenceRecords(java.lang.String[])
*/
@Override
return getEmblSequenceRecords(DBRefSource.EMBL, queries);
}
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.DbSourceProxy#isValidReference(java.lang.String)
- */
- @Override
- public boolean isValidReference(String accession)
- {
- // most embl refs look like ..
-
- return (accession == null || accession.length() < 2) ? false
- : getAccessionValidator().search(accession);
-
- }
-
/**
* return LHD_CHICK coding gene
*/
{
return "EMBL"; // getDbSource();
}
-
- @Override
- public int getTier()
- {
- return 0;
- }
}
*/
package jalview.ws.dbsources;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import com.stevesoft.pat.Regex;
+
import jalview.analysis.SequenceIdMatcher;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.util.DnaUtils;
import jalview.util.MapList;
import jalview.util.MappingUtils;
-import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
import jalview.xml.binding.embl.EntryType;
import jalview.xml.binding.embl.EntryType.Feature;
import jalview.xml.binding.embl.EntryType.Feature.Qualifier;
+import jalview.xml.binding.embl.ROOT;
import jalview.xml.binding.embl.XrefType;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-
+/**
+ * Provides XML binding and parsing of EMBL or EMBLCDS records retrieved from
+ * (e.g.) {@code https://www.ebi.ac.uk/ena/data/view/x53828&display=xml}.
+ *
+ * @deprecated endpoint withdrawn August 2020 (JAL-3692), use EmblFlatfileSource
+ */
public abstract class EmblXmlSource extends EbiFileRetrievedProxy
{
+ private static final Regex ACCESSION_REGEX = new Regex("^[A-Z]+[0-9]+");
+
/*
* JAL-1856 Embl returns this text for query not found
*/
} catch (Exception e)
{
stopQuery();
- throw new Exception(MessageManager.formatMessage(
- "exception.ebiembl_retrieval_failed_on", new String[]
- { emprefx.toLowerCase(), query.trim() }), e);
+ throw new Exception(
+ String.format("EBI EMBL XML retrieval failed for %s:%s",
+ emprefx.toLowerCase(), query.trim()),
+ e);
}
return getEmblSequenceRecords(emprefx, query, reply);
}
XMLStreamReader streamReader = XMLInputFactory.newInstance()
.createXMLStreamReader(is);
javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
- jalview.xml.binding.embl.ROOT root = (jalview.xml.binding.embl.ROOT) um
- .unmarshal(streamReader);
+ JAXBElement<ROOT> rootElement = um.unmarshal(streamReader,
+ ROOT.class);
+ ROOT root = rootElement.getValue();
/*
* document root contains either "entry" or "entrySet"
proteinSeq = new Sequence(proteinSeqName,
product.getSequenceAsString());
matcher.add(proteinSeq);
+ proteinSeq.setDescription(product.getDescription());
peptides.add(proteinSeq);
}
dnaToProteinMapping.setTo(proteinSeq);
&& dnaToProteinMapping.getTo() != null)
{
DBRefEntry dnaToEmblProteinRef = new DBRefEntry(
- DBRefSource.EMBLCDSProduct, sequenceVersion,
- proteinId);
+ DBRefSource.EMBLCDSProduct, sequenceVersion, proteinId);
dnaToEmblProteinRef.setMap(dnaToProteinMapping);
dnaToProteinMapping.setMappedFromId(proteinId);
dna.addDBRef(dnaToEmblProteinRef);
{
return new int[] {};
}
-
+
try
{
List<int[]> ranges = DnaUtils.parseLocation(location);
return sf;
}
+ @Override
+ public String getAccessionSeparator()
+ {
+ return null;
+ }
+
+ @Override
+ public Regex getAccessionValidator()
+ {
+ return ACCESSION_REGEX;
+ }
+
+ @Override
+ public String getDbVersion()
+ {
+ return "0";
+ }
+
+ @Override
+ public int getTier()
+ {
+ return 0;
+ }
+
+ @Override
+ public boolean isValidReference(String accession)
+ {
+ if (accession == null || accession.length() < 2)
+ {
+ return false;
+ }
+ return getAccessionValidator().search(accession);
+ }
+
/**
* Truncates (if necessary) the exon intervals to match 3 times the length of
* the protein; also accepts 3 bases longer (for stop codon not included in
}
int expectedCdsLength = proteinLength * 3;
int exonLength = MappingUtils.getLength(Arrays.asList(exon));
-
+
/*
* if exon length matches protein, or is shorter, or longer by the
* length of a stop codon (3 bases), then leave it unchanged
{
return exon;
}
-
+
int origxon[];
int sxpos = -1;
int endxon = 0;
// .println("Truncating final exon interval on region by "
// + (cdspos - cdslength));
}
-
+
/*
* shrink the final exon - reduce end position if forward
* strand, increase it if reverse
break;
}
}
-
+
if (sxpos != -1)
{
// and trim the exon interval set if necessary
*/
abstract public class Pfam extends Xfam
{
+ /*
+ * append to URLs to retrieve as a gzipped file
+ */
+ protected static final String GZIPPED = "/gzipped";
+
static final String PFAM_BASEURL_KEY = "PFAM_BASEURL";
private static final String DEFAULT_PFAM_BASEURL = "https://pfam.xfam.org";
@Override
public String getURLSuffix()
{
- return "/alignment/full";
+ return "/alignment/full" + GZIPPED;
}
/*
@Override
public String getURLSuffix()
{
- return "/alignment/seed";
+ return "/alignment/seed" + GZIPPED;
}
/*
private static final String DEFAULT_RFAM_BASEURL = "https://rfam.xfam.org";
+ /*
+ * append to URLs to retrieve as a gzipped file
+ */
+ protected static final String GZIPPED = "?gzip=1&download=1";
+
@Override
protected String getURLPrefix()
{
@Override
public String getURLSuffix()
{
- return "/alignment/full";
+ return "/alignment/full" + GZIPPED;
}
/*
@Override
public String getURLSuffix()
{
- // to download gzipped file add '?gzip=1'
- return "/alignment/stockholm";
+ return "/alignment/stockholm" + GZIPPED;
}
/*
*/
public abstract class Xfam extends DbSourceProxyImpl
{
-
public Xfam()
{
super();
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
* the query formatted as db:query1;query2;query3
* @param format
* the format wanted
- * @param extension
+ * @param ext
* for the temporary file to hold response (without separator)
* @return the file holding the response
* @throws OutOfMemoryError
{
// long time = System.currentTimeMillis();
String url = buildUrl(ids, database, format);
-
+ InputStream is = null;
+ BufferedReader br = null;
try
{
URL rcall = new URL(url);
System.err.println("Warning: response code " + responseCode
+ " for " + url);
}
- InputStream is = new BufferedInputStream(conn.getInputStream());
+ is = new BufferedInputStream(conn.getInputStream());
if (outFile != null)
{
FileOutputStream fio = new FileOutputStream(outFile);
}
else
{
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ br = new BufferedReader(new InputStreamReader(is));
String rtn;
List<String> arl = new ArrayList<String>();
while ((rtn = br.readLine()) != null)
{
// System.err.println("EBIFetch took " + (System.currentTimeMillis() -
// time) + " ms");
+ if (is != null)
+ {
+ try
+ {
+ is.close();
+ } catch (IOException e)
+ {
+ }
+ }
+ if (br != null)
+ {
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ }
+ }
}
return null;
}
if (database.equalsIgnoreCase(DBRefSource.EMBL)
|| database.equalsIgnoreCase(DBRefSource.EMBLCDS))
{
- url = "https://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
- + (format != null ? "&" + format : "");
+ url = "https://www.ebi.ac.uk/ena/browser/api/embl/"
+ + ids.toLowerCase() + "?download=true&gzip=true";
}
else
{
*/
package jalview.ws.sifts;
-import jalview.analysis.AlignSeq;
-import jalview.analysis.scoremodels.ScoreMatrix;
-import jalview.analysis.scoremodels.ScoreModels;
-import jalview.api.DBRefEntryI;
-import jalview.api.SiftsClientI;
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.SequenceI;
-import jalview.io.StructureFile;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureMapping;
-import jalview.util.Comparison;
-import jalview.util.DBRefUtils;
-import jalview.util.Format;
-import jalview.xml.binding.sifts.Entry;
-import jalview.xml.binding.sifts.Entry.Entity;
-import jalview.xml.binding.sifts.Entry.Entity.Segment;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import MCview.Atom;
import MCview.PDBChain;
+import jalview.analysis.AlignSeq;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.DBRefEntryI;
+import jalview.api.SiftsClientI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceI;
+import jalview.io.BackupFiles;
+import jalview.io.StructureFile;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
+import jalview.util.Format;
+import jalview.xml.binding.sifts.Entry;
+import jalview.xml.binding.sifts.Entry.Entity;
+import jalview.xml.binding.sifts.Entry.Entity.Segment;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
public class SiftsClient implements SiftsClientI
{
private enum CoordinateSys
{
UNIPROT("UniProt"), PDB("PDBresnum"), PDBe("PDBe");
+
private String name;
private CoordinateSys(String name)
{
NAME_SEC_STRUCTURE("nameSecondaryStructure"),
CODE_SEC_STRUCTURE("codeSecondaryStructure"), ANNOTATION("Annotation");
+
private String code;
private ResidueDetailType(String code)
SiftsSettings.getCacheThresholdInDays()))
{
File oldSiftsFile = new File(siftsFileName + "_old");
- siftsFile.renameTo(oldSiftsFile);
+ BackupFiles.moveFileToFile(siftsFile, oldSiftsFile);
try
{
siftsFile = downloadSiftsFile(pdbId.toLowerCase());
} catch (IOException e)
{
e.printStackTrace();
- oldSiftsFile.renameTo(siftsFile);
+ BackupFiles.moveFileToFile(oldSiftsFile, siftsFile);
return new File(siftsFileName);
}
}
SequenceI seq, java.io.PrintStream os) throws SiftsException
{
List<Integer> omitNonObserved = new ArrayList<>();
- int nonObservedShiftIndex = 0,pdbeNonObserved=0;
+ int nonObservedShiftIndex = 0, pdbeNonObserved = 0;
// System.out.println("Generating mappings for : " + entityId);
Entity entity = null;
entity = getEntityById(entityId);
TreeMap<Integer, String> resNumMap = new TreeMap<Integer, String>();
List<Segment> segments = entity.getSegment();
SegmentHelperPojo shp = new SegmentHelperPojo(seq, mapping, resNumMap,
- omitNonObserved, nonObservedShiftIndex,pdbeNonObserved);
+ omitNonObserved, nonObservedShiftIndex, pdbeNonObserved);
processSegments(segments, shp);
try
{
{
throw new SiftsException("SIFTS mapping failed");
}
- // also construct a mapping object between the seq-coord sys and the PDB seq's coord sys
+ // also construct a mapping object between the seq-coord sys and the PDB
+ // seq's coord sys
Integer[] keys = mapping.keySet().toArray(new Integer[0]);
Arrays.sort(keys);
seqStart = keys[0];
seqEnd = keys[keys.length - 1];
- List<int[]> from=new ArrayList<>(),to=new ArrayList<>();
- int[]_cfrom=null,_cto=null;
+ List<int[]> from = new ArrayList<>(), to = new ArrayList<>();
+ int[] _cfrom = null, _cto = null;
String matchedSeq = originalSeq;
- if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb sequence that starts <-1
+ if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb
+ // sequence that starts <-1
{
- for (int seqps:keys)
+ for (int seqps : keys)
{
int pdbpos = mapping.get(seqps)[PDBE_POS];
if (pdbpos == UNASSIGNED)
// not correct - pdbpos might be -1, but leave it for now
continue;
}
- if (_cfrom==null || seqps!=_cfrom[1]+1)
+ if (_cfrom == null || seqps != _cfrom[1] + 1)
{
- _cfrom = new int[] { seqps,seqps};
+ _cfrom = new int[] { seqps, seqps };
from.add(_cfrom);
_cto = null; // discontinuity
- } else {
- _cfrom[1]= seqps;
}
- if (_cto==null || pdbpos!=1+_cto[1])
+ else
+ {
+ _cfrom[1] = seqps;
+ }
+ if (_cto == null || pdbpos != 1 + _cto[1])
{
- _cto = new int[] { pdbpos,pdbpos};
+ _cto = new int[] { pdbpos, pdbpos };
to.add(_cto);
- } else {
+ }
+ else
+ {
_cto[1] = pdbpos;
}
}
;
seqFromPdbMapping = new jalview.datamodel.Mapping(null, _cto, _cfrom,
- 1,
- 1);
+ 1, 1);
pdbStart = mapping.get(seqStart)[PDB_RES_POS];
pdbEnd = mapping.get(seqEnd)[PDB_RES_POS];
int orignalSeqStart = seq.getStart();
}
// if (currSeqIndex >= seq.getStart() && currSeqIndex <= seqlength) //
// true
- // numbering
- // is
- // not
- // up
- // to
- // seq.getEnd()
+ // numbering
+ // is
+ // not
+ // up
+ // to
+ // seq.getEnd()
{
int resNum = (pdbRefDb == null)
{
return pdbeNonObserved;
}
+
public SequenceI getSeq()
{
return seq;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
-import jalview.datamodel.SequenceFeature;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.testng.annotations.Test;
+import jalview.datamodel.SequenceFeature;
import junit.extensions.PA;
public class SequenceFeaturesTest
public void testSortFeatures()
{
List<SequenceFeature> sfs = new ArrayList<>();
- SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, 80,
+ SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30,
+ 60,
Float.NaN, null);
sfs.add(sf1);
SequenceFeature sf2 = new SequenceFeature("Rfam", "desc", 40, 50,
SequenceFeature sf3 = new SequenceFeature("Rfam", "desc", 50, 60,
Float.NaN, null);
sfs.add(sf3);
+ SequenceFeature sf4 = new SequenceFeature("Xfam", "desc", 30,
+ 80,
+ Float.NaN, null);
+ sfs.add(sf4);
+ SequenceFeature sf5 = new SequenceFeature("Xfam", "desc", 30,
+ 90,
+ Float.NaN, null);
+ sfs.add(sf5);
- // sort by end position descending
+ /*
+ * sort by end position descending, order unchanged if matched
+ */
SequenceFeatures.sortFeatures(sfs, false);
- assertSame(sfs.get(0), sf1);
- assertSame(sfs.get(1), sf3);
- assertSame(sfs.get(2), sf2);
+ assertSame(sfs.get(0), sf5); // end 90
+ assertSame(sfs.get(1), sf4); // end 80
+ assertSame(sfs.get(2), sf1); // end 60, start 50
+ assertSame(sfs.get(3), sf3); // end 60, start 30
+ assertSame(sfs.get(4), sf2); // end 50
- // sort by start position ascending
+ /*
+ * resort {5, 4, 1, 3, 2} by start position ascending, end descending
+ */
SequenceFeatures.sortFeatures(sfs, true);
- assertSame(sfs.get(0), sf1);
- assertSame(sfs.get(1), sf2);
- assertSame(sfs.get(2), sf3);
+ assertSame(sfs.get(0), sf5); // start 30, end 90
+ assertSame(sfs.get(1), sf4); // start 30, end 80
+ assertSame(sfs.get(2), sf1); // start 30, end 60
+ assertSame(sfs.get(3), sf2); // start 40
+ assertSame(sfs.get(4), sf3); // start 50
}
@Test(groups = "Functional")
package jalview.gui;
-import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
-import jalview.analysis.AlignmentGenerator;
-import jalview.bin.Cache;
-import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SequenceGroup;
-import jalview.io.DataSourceType;
-import jalview.io.FileLoader;
-
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import jalview.analysis.AlignmentGenerator;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
import junit.extensions.PA;
+/**
+ * Provides a simple test that memory is released when all windows are closed.
+ * <ul>
+ * <li>generates a reasonably large alignment and loads it</li>
+ * <li>performs various operations on the alignment</li>
+ * <li>closes all windows</li>
+ * <li>requests garbage collection</li>
+ * <li>asserts that the remaining memory footprint (heap usage) is 'not large'
+ * </li>
+ * </ul>
+ * If the test fails, this means that reference(s) to large object(s) have
+ * failed to be garbage collected. In this case:
+ * <ul>
+ * <li>set a breakpoint just before the test assertion in
+ * {@code checkUsedMemory}</li>
+ * <li>if the test fails intermittently, make this breakpoint conditional on
+ * {@code usedMemory > expectedMax}</li>
+ * <li>run the test to this point (and check that it is about to fail i.e.
+ * {@code usedMemory > expectedMax})</li>
+ * <li>use <a href="https://visualvm.github.io/">visualvm</a> to obtain a heap
+ * dump from the suspended process (and kill the test or let it fail)</li>
+ * <li>inspect the heap dump using visualvm for large objects and their
+ * referers</li>
+ * <li>Tips:</li>
+ * <ul>
+ * <li>Perform GC from the Monitor view in visualvm before requesting the heap
+ * dump - test failure might be simply a delay to GC</li>
+ * <li>View 'Objects' and filter classes to {@code jalview}. Sort columns by
+ * Count, or Size, and look for anything suspicious. For example, if the object
+ * count for {@code Sequence} is non-zero (it shouldn't be), pick any instance,
+ * and follow the chain of {@code references} to find which class(es) still hold
+ * references to sequence objects</li>
+ * <li>If this chain is impracticably long, re-run the test with a smaller
+ * alignment (set width=100, height=10 in {@code generateAlignment()}), to
+ * capture a heap which is qualitatively the same, but much smaller, so easier
+ * to analyse; note this requires an unconditional breakpoint</li>
+ * </ul>
+ * </ul>
+ * <p>
+ * <h2>Fixing memory leaks</h2>
+ * <p>
+ * Experience shows that often a reference is retained (directly or indirectly)
+ * by a Swing (or related) component (for example a {@code MouseListener} or
+ * {@code ActionListener}). There are two possible approaches to fixing:
+ * <ul>
+ * <li>Purist: ensure that all listeners and similar objects are removed when no
+ * longer needed. May be difficult, to achieve and to maintain as code
+ * changes.</li>
+ * <li>Pragmatic: null references to potentially large objects from Jalview
+ * application classes when no longer needed, typically when a panel is closed.
+ * This ensures that even if the JVM keeps a reference to a panel or viewport,
+ * it does not retain a large heap footprint. This is the approach taken in, for
+ * example, {@code AlignmentPanel.closePanel()} and
+ * {@code AnnotationPanel.dispose()}.</li>
+ * <li>Adjust code if necessary; for example an {@code ActionListener} should
+ * act on {@code av.getAlignment()} and not directly on {@code alignment}, as
+ * the latter pattern could leave persistent references to the alignment</li>
+ * </ul>
+ * Add code to 'null unused large object references' until the test passes. For
+ * a final sanity check, capture the heap dump for a passing test, and satisfy
+ * yourself that only 'small' or 'harmless' {@code jalview} object instances
+ * (such as enums or singletons) are left in the heap.
+ */
public class FreeUpMemoryTest
{
private static final int ONE_MB = 1000 * 1000;
+ /*
+ * maximum retained heap usage (in MB) for a passing test
+ */
+ private static int MAX_RESIDUAL_HEAP = 45;
+
/**
* Configure (read-only) Jalview property settings for test
*/
@BeforeClass(alwaysRun = true)
public void setUp()
{
- Jalview.main(new String[] { "-nonews", "-props",
- "test/jalview/testProps.jvprops" });
+ Jalview.main(
+ new String[]
+ { "-nonews", "-props", "test/jalview/testProps.jvprops" });
String True = Boolean.TRUE.toString();
Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", True);
Cache.applicationProperties.setProperty("SHOW_QUALITY", True);
Cache.applicationProperties.setProperty("SHOW_IDENTITY", True);
}
- /**
- * A simple test that memory is released when all windows are closed.
- * <ul>
- * <li>generates a reasonably large alignment and loads it</li>
- * <li>performs various operations on the alignment</li>
- * <li>closes all windows</li>
- * <li>requests garbage collection</li>
- * <li>asserts that the remaining memory footprint (heap usage) is 'not large'
- * </li>
- * </ul>
- * If the test fails, this suggests that a reference to some large object
- * (perhaps the alignment data, or some annotation / Tree / PCA data) has
- * failed to be garbage collected. If this is the case, the heap will need to
- * be inspected manually (suggest using jvisualvm) in order to track down
- * where large objects are still referenced. The code (for example
- * AlignmentViewport.dispose()) should then be updated to ensure references to
- * large objects are set to null when they are no longer required.
- *
- * @throws IOException
- */
@Test(groups = "Memory")
public void testFreeMemoryOnClose() throws IOException
{
File f = generateAlignment();
f.deleteOnExit();
- long expectedMin = 35L;
- long usedMemoryAtStart=getUsedMemory();
- if (usedMemoryAtStart>expectedMin)
- {
- System.err.println("used memory before test is "+usedMemoryAtStart+" > "+expectedMin+"MB .. adjusting minimum.");
- expectedMin = usedMemoryAtStart;
- }
doStuffInJalview(f);
Desktop.instance.closeAll_actionPerformed(null);
- checkUsedMemory(expectedMin);
+ checkUsedMemory(MAX_RESIDUAL_HEAP);
}
- private static long getUsedMemory()
+ /**
+ * Returns the current total used memory (available memory - free memory),
+ * rounded down to the nearest MB
+ *
+ * @return
+ */
+ private static int getUsedMemory()
{
- long availableMemory = Runtime.getRuntime().totalMemory() / ONE_MB;
- long freeMemory = Runtime.getRuntime().freeMemory() / ONE_MB;
+ long availableMemory = Runtime.getRuntime().totalMemory();
+ long freeMemory = Runtime.getRuntime().freeMemory();
long usedMemory = availableMemory - freeMemory;
- return usedMemory;
+
+ return (int) (usedMemory / ONE_MB);
}
+
/**
* Requests garbage collection and then checks whether remaining memory in use
* is less than the expected value (in Megabytes)
*
* @param expectedMax
*/
- protected void checkUsedMemory(long expectedMax)
+ protected void checkUsedMemory(int expectedMax)
{
/*
- * request garbage collection and wait for it to run;
+ * request garbage collection and wait for it to run (up to 3 times);
* NB there is no guarantee when, or whether, it will do so
- * wait time depends on JRE/processor, generous allowance here
*/
- System.gc();
- waitFor(1500);
-
- /*
- * a second gc() call should not be necessary - but it is!
- * the test passes with it, and fails without it
- */
- System.gc();
- waitFor(1500);
-
- /*
- * check used memory is 'reasonably low'
- */
- long usedMemory = getUsedMemory();
- /*
- * sanity check - fails if any frame was added after
- * closeAll_actionPerformed
- */
- assertEquals(Desktop.instance.getAllFrames().length, 0);
+ long usedMemory = 0L;
+ Long minUsedMemory = null;
+ int gcCount = 0;
+ while (gcCount < 3)
+ {
+ gcCount++;
+ System.gc();
+ waitFor(1500);
+ usedMemory = getUsedMemory();
+ if (minUsedMemory == null || usedMemory < minUsedMemory)
+ {
+ minUsedMemory = usedMemory;
+ }
+ if (usedMemory < expectedMax)
+ {
+ break;
+ }
+ }
/*
- * if this assertion fails
- * - set a breakpoint here
- * - run jvisualvm to inspect a heap dump of Jalview
- * - identify large objects in the heap and their referers
+ * if this assertion fails (reproducibly!)
+ * - set a breakpoint here, conditional on (usedMemory > expectedMax)
+ * - run VisualVM to inspect the heap usage, and run GC from VisualVM to check
+ * it is not simply delayed garbage collection causing the test failure
+ * - take a heap dump and identify large objects in the heap and their referers
* - fix code as necessary to null the references on close
*/
- System.out.println("Used memory after gc = " + usedMemory + "MB");
- assertTrue(usedMemory < expectedMax, String.format(
+ System.out.println("(Minimum) Used memory after " + gcCount
+ + " call(s) to gc() = " + minUsedMemory + "MB (should be <="
+ + expectedMax + ")");
+ assertTrue(usedMemory <= expectedMax, String.format(
"Used memory %d should be less than %d (Recommend running test manually to verify)",
- usedMemory,
- expectedMax));
+ usedMemory, expectedMax));
}
/**
* wait until Tree and PCA have been computed
*/
while (af.viewport.getCurrentTree() == null
- && dialog.getPcaPanel().isWorking())
+ || dialog.getPcaPanel().isWorking())
{
waitFor(10);
}
int width = 100000;
int height = 100;
ag.generate(width, height, 0, 10, 15);
+ ps.close();
return f;
}
}
package jalview.gui;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
"wrappedRepeatHeightPx");
assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
}
+
+ @Test(groups = "Functional")
+ public void testClear_HighlightAndSelection()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ SearchResultsI highlight = new SearchResults();
+ highlight.addResult(
+ av.getAlignment().getSequenceAt(1).getDatasetSequence(), 50,
+ 80);
+ af.alignPanel.highlightSearchResults(highlight);
+ af.avc.markHighlightedColumns(false, false, false);
+ assertNotNull(av.getSearchResults(),
+ "No highlight was created on alignment");
+ assertFalse(av.getColumnSelection().isEmpty(),
+ "No selection was created from highlight");
+ af.deselectAllSequenceMenuItem_actionPerformed(null);
+ assertTrue(av.getColumnSelection().isEmpty(),
+ "No Selection should be present after deselecting all.");
+ assertNull(av.getSearchResults(),
+ "No higlighted search results should be present after deselecting all.");
+ }
}
boolean noMax)
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Cache.initLogger();
BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
reverse, noMax, rollMax, false);
--- /dev/null
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.fail;
+import static org.testng.AssertJUnit.assertNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.SequenceFeatures;
+import jalview.util.MapList;
+
+public class EmblFlatFileTest
+{
+ /**
+ * A fairly tough test, using J03321 (circular DNA), which has 8 CDS features,
+ * one of them reverse strand
+ *
+ * @throws MalformedURLException
+ * @throws IOException
+ */
+ @Test(groups = "Functional")
+ public void testParse() throws MalformedURLException, IOException
+ {
+ File dataFile = new File("test/jalview/io/J03321.embl.txt");
+ FileParse fp = new FileParse(dataFile.getAbsolutePath(), DataSourceType.FILE);
+ EmblFlatFile parser = new EmblFlatFile(fp, "EmblTest");
+ parser.parse();
+ List<SequenceI> seqs = parser.getSeqs();
+
+ assertEquals(seqs.size(), 1);
+ SequenceI seq = seqs.get(0);
+ assertEquals(seq.getName(), "EmblTest|J03321");
+ assertEquals(seq.getLength(), 7502);
+ assertEquals(seq.getDescription(),
+ "Chlamydia trachomatis plasmid pCHL1, complete sequence");
+
+ /*
+ * should be 9 CDS features (one is a 'join' of two exons)
+ */
+ Set<String> featureTypes = seq.getFeatures().getFeatureTypes();
+ assertEquals(featureTypes.size(), 1);
+ assertTrue(featureTypes.contains("CDS"));
+
+ /*
+ * inspect some features (sorted just for convenience of test assertions)
+ */
+ List<SequenceFeature> features = seq.getFeatures()
+ .getAllFeatures("CDS");
+ SequenceFeatures.sortFeatures(features, true);
+ assertEquals(features.size(), 9);
+
+ SequenceFeature sf = features.get(0);
+ assertEquals(sf.getBegin(), 1);
+ assertEquals(sf.getEnd(), 437);
+ assertEquals(sf.getDescription(),
+ "Exon 2 for protein EMBLCDS:AAA91567.1");
+ assertEquals(sf.getFeatureGroup(), "EmblTest");
+ assertEquals(sf.getEnaLocation(), "join(7022..7502,1..437)");
+ assertEquals(sf.getPhase(), "0");
+ assertEquals(sf.getStrand(), 1);
+ assertEquals(sf.getValue("note"), "pGP7-D");
+ // this is the second exon of circular CDS!
+ assertEquals(sf.getValue("exon number"), 2);
+ assertEquals(sf.getValue("product"), "hypothetical protein");
+ assertEquals(sf.getValue("transl_table"), "11");
+
+ sf = features.get(1);
+ assertEquals(sf.getBegin(), 488);
+ assertEquals(sf.getEnd(), 1480);
+ assertEquals(sf.getDescription(),
+ "Exon 1 for protein EMBLCDS:AAA91568.1");
+ assertEquals(sf.getFeatureGroup(), "EmblTest");
+ assertEquals(sf.getEnaLocation(), "complement(488..1480)");
+ assertEquals(sf.getPhase(), "0");
+ assertEquals(sf.getStrand(), -1); // reverse strand!
+ assertEquals(sf.getValue("note"), "pGP8-D");
+ assertEquals(sf.getValue("exon number"), 1);
+ assertEquals(sf.getValue("product"), "hypothetical protein");
+
+ sf = features.get(7);
+ assertEquals(sf.getBegin(), 6045);
+ assertEquals(sf.getEnd(), 6788);
+ assertEquals(sf.getDescription(),
+ "Exon 1 for protein EMBLCDS:AAA91574.1");
+ assertEquals(sf.getFeatureGroup(), "EmblTest");
+ assertEquals(sf.getEnaLocation(), "6045..6788");
+ assertEquals(sf.getPhase(), "0");
+ assertEquals(sf.getStrand(), 1);
+ assertEquals(sf.getValue("note"), "pGP6-D (gtg start codon)");
+ assertEquals(sf.getValue("exon number"), 1);
+ assertEquals(sf.getValue("product"), "hypothetical protein");
+
+ /*
+ * CDS at 7022-7502 is the first exon of the circular CDS
+ */
+ sf = features.get(8);
+ assertEquals(sf.getBegin(), 7022);
+ assertEquals(sf.getEnd(), 7502);
+ assertEquals(sf.getDescription(),
+ "Exon 1 for protein EMBLCDS:AAA91567.1");
+ assertEquals(sf.getFeatureGroup(), "EmblTest");
+ assertEquals(sf.getEnaLocation(), "join(7022..7502,1..437)");
+ assertEquals(sf.getPhase(), "0");
+ assertEquals(sf.getStrand(), 1);
+ assertEquals(sf.getValue("note"), "pGP7-D");
+ assertEquals(sf.getValue("exon number"), 1);
+ assertEquals(sf.getValue("product"), "hypothetical protein");
+
+ /*
+ * Verify DBRefs, whether declared in the file or added by Jalview.
+ * There are 4 'direct' (DR) dbrefs, and numerous CDS /db_xref entries
+ * (some e.g. INTERPRO are duplicates). Jalview adds a dbref to 'self'.
+ * Sample a few here. Note DBRefEntry constructor capitalises source.
+ */
+ List<DBRefEntry> dbrefs = Arrays.asList(seq.getDBRefs());
+
+ assertEquals(dbrefs.size(), 32);
+ // xref to 'self':
+ DBRefEntry selfRef = new DBRefEntry("EMBLTEST", "1", "J03321");
+ int[] range = new int[] { 1, seq.getLength() };
+ selfRef.setMap(new Mapping(null, range, range, 1, 1));
+ assertTrue(dbrefs.contains(selfRef));
+
+ // 1st DR line; note trailing period is removed
+ assertTrue(dbrefs.contains(new DBRefEntry("MD5", "0",
+ "d4c4942a634e3df4995fd5ac75c26a61")));
+ // the 4th DR line:
+ assertTrue(
+ dbrefs.contains(new DBRefEntry("EUROPEPMC", "0", "PMC87941")));
+ // from the first CDS feature
+ assertTrue(dbrefs.contains(new DBRefEntry("GOA", "0", "P0CE19")));
+ // from the last CDS feature
+ assertTrue(
+ dbrefs.contains(new DBRefEntry("INTERPRO", "0", "IPR005350")));
+
+ /*
+ * verify mappings to, and sequences for, UNIPROT proteins
+ */
+ int uniprotCount = 0;
+ List<int[]> ranges;
+ for (DBRefEntry dbref : dbrefs)
+ {
+ if ("UNIPROT".equals(dbref.getSource()))
+ {
+ uniprotCount++;
+ Mapping mapping = dbref.getMap();
+ assertNotNull(mapping);
+ MapList map = mapping.getMap();
+ String mappedToName = mapping.getTo().getName();
+ if ("UNIPROT|P0CE16".equals(mappedToName))
+ {
+ assertEquals((ranges = map.getFromRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1579);
+ assertEquals(ranges.get(0)[1], 2934);
+ assertEquals((ranges = map.getToRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1);
+ assertEquals(ranges.get(0)[1], 451);
+ // CDS /product carries over as protein product description
+ assertEquals(mapping.getTo().getDescription(),
+ "hypothetical protein");
+ }
+ else if ("UNIPROT|P0CE17".equals(mappedToName))
+ {
+ assertEquals((ranges = map.getFromRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 2928);
+ assertEquals(ranges.get(0)[1], 3992);
+ assertEquals((ranges = map.getToRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1);
+ assertEquals(ranges.get(0)[1], 354);
+ }
+ else if ("UNIPROT|P0CE18".equals(mappedToName))
+ {
+ assertEquals((ranges = map.getFromRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 4054);
+ assertEquals(ranges.get(0)[1], 4848);
+ assertEquals((ranges = map.getToRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1);
+ assertEquals(ranges.get(0)[1], 264);
+ }
+ else if ("UNIPROT|P0CE19".equals(mappedToName))
+ {
+ // join(7022..7502,1..437)
+ assertEquals((ranges = map.getFromRanges()).size(), 2);
+ assertEquals(ranges.get(0)[0], 7022);
+ assertEquals(ranges.get(0)[1], 7502);
+ assertEquals(ranges.get(1)[0], 1);
+ assertEquals(ranges.get(1)[1], 437);
+ assertEquals((ranges = map.getToRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1);
+ assertEquals(ranges.get(0)[1], 305);
+ }
+ else if ("UNIPROT|P0CE20".equals(mappedToName))
+ {
+ // complement(488..1480)
+ assertEquals((ranges = map.getFromRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1480);
+ assertEquals(ranges.get(0)[1], 488);
+ assertEquals((ranges = map.getToRanges()).size(), 1);
+ assertEquals(ranges.get(0)[0], 1);
+ assertEquals(ranges.get(0)[1], 330);
+ }
+ else if (!"UNIPROT|P0CE23".equals(mappedToName)
+ && !"UNIPROT|P10559".equals(mappedToName)
+ && !"UNIPROT|P10560".equals(mappedToName))
+ {
+ fail("Unexpected UNIPROT dbref to " + mappedToName);
+ }
+ }
+ }
+ assertEquals(uniprotCount, 8);
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_codonStartNot1()
+ {
+ // TODO verify CDS-to-protein mapping for CDS with /codon_start=2
+ // example: https://www.ebi.ac.uk/ena/browser/api/embl/EU498516
+ }
+
+ /**
+ * Test for the case that the EMBL CDS has no UNIPROT xref. In this case
+ * Jalview should synthesize an xref to EMBLCDSPROTEIN in the hope this will
+ * allow Get Cross-References.
+ *
+ * @throws IOException
+ */
+ @Test(groups = "Functional")
+ public void testParse_noUniprotXref() throws IOException
+ {
+ // MN908947 cut down to 40BP, one CDS, length 5 peptide for test purposes
+ // plus an additional (invented) test case:
+ // - multi-line /product qualifier including escaped quotes
+ String data = "ID MN908947; SV 3; linear; genomic RNA; STD; VRL; 20 BP.\n"
+ + "DE Severe acute respiratory syndrome coronavirus 2 isolate Wuhan-Hu-1,\n"
+ + "FT CDS 3..17\n"
+ + "FT /protein_id=\"QHD43415.1\"\n"
+ + "FT /product=\"orf1ab polyprotein\n"
+ + "FT \"\"foobar\"\" \"\n"
+ + "FT /translation=\"MRKLD\n"
+ + "SQ Sequence 7496 BP; 2450 A; 1290 C; 1434 G; 2322 T; 0 other;\n"
+ + " ggatGcgtaa gttagacgaa attttgtctt tgcgcacaga 40\n";
+ FileParse fp = new FileParse(data, DataSourceType.PASTE);
+ EmblFlatFile parser = new EmblFlatFile(fp, "EmblTest");
+ parser.parse();
+ List<SequenceI> seqs = parser.getSeqs();
+ assertEquals(seqs.size(), 1);
+ SequenceI seq = seqs.get(0);
+ List<DBRefEntry> dbrefs = Arrays.asList(seq.getDBRefs());
+
+ /*
+ * dna should have dbref to itself, and to inferred EMBLCDSPROTEIN:QHD43415.1
+ */
+ assertEquals(dbrefs.size(), 2);
+
+ // dbref to self
+ DBRefEntry dbref = dbrefs.get(0);
+ assertEquals(dbref.getSource(), "EMBLTEST");
+ assertEquals(dbref.getAccessionId(), "MN908947");
+ Mapping mapping = dbref.getMap();
+ assertNull(mapping.getTo());
+ MapList map = mapping.getMap();
+ assertEquals(map.getFromLowest(), 1);
+ assertEquals(map.getFromHighest(), 40);
+ assertEquals(map.getToLowest(), 1);
+ assertEquals(map.getToHighest(), 40);
+ assertEquals(map.getFromRatio(), 1);
+ assertEquals(map.getToRatio(), 1);
+
+ // dbref to inferred EMBLCDSPROTEIN:
+ dbref = dbrefs.get(1);
+ assertEquals(dbref.getSource(), "EMBLCDSPROTEIN");
+ assertEquals(dbref.getAccessionId(), "QHD43415.1");
+ mapping = dbref.getMap();
+ SequenceI mapTo = mapping.getTo();
+ assertEquals(mapTo.getName(), "QHD43415.1");
+ // the /product qualifier transfers to protein product description
+ assertEquals(mapTo.getDescription(), "orf1ab polyprotein \"foobar\"");
+ assertEquals(mapTo.getSequenceAsString(), "MRKLD");
+ map = mapping.getMap();
+ assertEquals(map.getFromLowest(), 3);
+ assertEquals(map.getFromHighest(), 17);
+ assertEquals(map.getToLowest(), 1);
+ assertEquals(map.getToHighest(), 5);
+ assertEquals(map.getFromRatio(), 3);
+ assertEquals(map.getToRatio(), 1);
+ }
+
+ @Test(groups = "Functional")
+ public void testAdjustForProteinLength()
+ {
+ int[] exons = new int[] { 11, 15, 21, 25, 31, 38 }; // 18 bp
+
+ // exact length match:
+ assertSame(exons, EmblFlatFile.adjustForProteinLength(6, exons));
+
+ // match if we assume exons include stop codon not in protein:
+ assertSame(exons, EmblFlatFile.adjustForProteinLength(5, exons));
+
+ // truncate last exon by 6bp
+ int[] truncated = EmblFlatFile.adjustForProteinLength(4, exons);
+ assertEquals("[11, 15, 21, 25, 31, 32]", Arrays.toString(truncated));
+
+ // remove last exon and truncate preceding by 1bp (so 3bp in total)
+ truncated = EmblFlatFile.adjustForProteinLength(3, exons);
+ assertEquals("[11, 15, 21, 24]", Arrays.toString(truncated));
+
+ // exact removal of exon case:
+ exons = new int[] { 11, 15, 21, 27, 33, 38 }; // 18 bp
+ truncated = EmblFlatFile.adjustForProteinLength(4, exons);
+ assertEquals("[11, 15, 21, 27]", Arrays.toString(truncated));
+
+ // what if exons are too short for protein?
+ truncated = EmblFlatFile.adjustForProteinLength(7, exons);
+ assertSame(exons, truncated);
+ }
+
+ @Test(groups = "Functional")
+ public void testRemoveQuotes()
+ {
+ assertNull(EmblFlatFile.removeQuotes(null));
+ assertEquals(EmblFlatFile.removeQuotes("No quotes here"), "No quotes here");
+ assertEquals(EmblFlatFile.removeQuotes("\"Enclosing quotes\""), "Enclosing quotes");
+ assertEquals(EmblFlatFile.removeQuotes("\"Escaped \"\"quotes\"\" example\""), "Escaped \"quotes\" example");
+ }
+}
--- /dev/null
+ID J03321; SV 1; circular; genomic DNA; STD; PRO; 7502 BP.
+XX
+AC J03321;
+XX
+DT 27-JUL-1990 (Rel. 24, Created)
+DT 10-APR-2020 (Rel. 144, Last updated, Version 9)
+XX
+DE Chlamydia trachomatis plasmid pCHL1, complete sequence.
+XX
+KW .
+XX
+OS Chlamydia trachomatis
+OC Bacteria; Chlamydiae; Chlamydiales; Chlamydiaceae;
+OC Chlamydia/Chlamydophila group; Chlamydia.
+OG Plasmid pCHL1
+XX
+RN [1]
+RP 1-7502
+RX DOI; 10.1016/0147-619X(90)90034-A.
+RX PUBMED; 2194229.
+RA Comanducci M., Ricci S., Cevenini R., Ratti G.;
+RT "Diversity of the Chlamydia trachomatis common plasmid in biovars with
+RT different pathogenicity";
+RL Plasmid 23(2):149-154(1990).
+XX
+RN [2]
+RP 1-7502
+RA Comanducci M., Ricci S., Cevenini R., Ratti G.;
+RT ;
+RL Submitted (23-JUN-2010) to the INSDC.
+RL Sclavo Research Centre, Siena, Italy
+XX
+DR MD5; d4c4942a634e3df4995fd5ac75c26a61.
+DR BioSample; SAMN14225621.
+DR EuropePMC; PMC4450983; 26031715.
+DR EuropePMC; PMC87941; 11283058.
+XX
+CC Draft entry and computer-readable sequence kindly submitted by
+CC G.Ratti, 28-MAR-1990.
+XX
+FH Key Location/Qualifiers
+FH
+FT source 1..7502
+FT /organism="Chlamydia trachomatis"
+FT /plasmid="pCHL1"
+FT /isolate="G0/86"
+FT /serotype="D"
+FT /mol_type="genomic DNA"
+FT /isolation_source="trachoma"
+FT /db_xref="taxon:813"
+FT CDS join(7022..7502,1..437)
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP7-D"
+FT /db_xref="GOA:P0CE19"
+FT /db_xref="InterPro:IPR002104"
+FT /db_xref="InterPro:IPR011010"
+FT /db_xref="InterPro:IPR013762"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE19"
+FT /protein_id="AAA91567.1"
+FT /translation="MGSMAFHKSRLFLTFGDASEIWLSTLSYLTRKNYASGINFLVSLE
+FT ILDLSETLIKAISLDHSESLFKIKSLDVFNGKVVSEASKQARAACYISFTKFLYRLTKG
+FT YIKPAIPLKDFGNTTFFKIRDKIKTESISKQEWTVFFEALRIVNYRDYLIGKLIVQGIR
+FT KLDEILSLRTDDLFFASNQISFRIKKRQNKETKILITFPISLMEELQKYTCGRNGRVFV
+FT SKIGIPVTTSQVAHNFRLAEFHSAMKIKITPRVLRASALIHLKQIGLKDEEIMRISCLS
+FT SRQSVCSYCSGEEVIPLVQTPTIL"
+FT CDS complement(488..1480)
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP8-D"
+FT /db_xref="GOA:P0CE20"
+FT /db_xref="InterPro:IPR002104"
+FT /db_xref="InterPro:IPR011010"
+FT /db_xref="InterPro:IPR013762"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE20"
+FT /protein_id="AAA91568.1"
+FT /translation="MGKGILSLQQEMSLEYSEKSYQEVLKIRQESYWKRMKSFSLFEVI
+FT MHWTASLNKHTCRSYRGSFLSLEKIGLLSLDMNLQEFSLLNHNLILDAIKKVSSAKTSW
+FT TEGTKQVRAASYISLTRFLNRMTQGIVAIAQPSKQENSRTFFKTREIVKTDAMNSLQTA
+FT SFLKELKKINARDWLIAQTMLQGGKRSSEVLSLEISQICFQQATISFSQLKNRQTEKRI
+FT IITYPQKFMHFLQEYIGQRRGFVFVTRSGKMVGLRQIARTFSQAGLQAAIPFKITPHVL
+FT RATAVTEYKRLGCSDSDIMKVTGHATAKMIFAYDKSSREDNASKKMALI"
+FT CDS 1579..2934
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP1-D"
+FT /db_xref="GOA:P0CE16"
+FT /db_xref="InterPro:IPR003593"
+FT /db_xref="InterPro:IPR007693"
+FT /db_xref="InterPro:IPR007694"
+FT /db_xref="InterPro:IPR027417"
+FT /db_xref="InterPro:IPR036185"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE16"
+FT /protein_id="AAA91569.1"
+FT /translation="MKTRSEIENRMQDIEYALLGKALIFEDSTEYILRQLANYEFKCSH
+FT HKNIFIVFKHLKDNGLPITVDSAWEELLRRRIKDMDKSYLGLMLHDALSNDKLRSVSHT
+FT VFLDDLSVCSAEENLSNFIFRSFNEYNENPLRRSPFLLLERIKGRLDSAIAKTFSIRSA
+FT RGRSIYDIFSQSEIGVLARIKKRRVAFSENQNSFFDGFPTGYKDIDDKGVILAKGNFVI
+FT IAARPSIGKTALAIDMAINLAVTQQRRVGFLSLEMSAGQIVERIIANLTGISGEKLQRG
+FT DLSKEELFRVEEAGETVRESHFYICSDSQYKLNLIANQIRLLRKEDRVDVIFIDYLQLI
+FT NSSVGENRQNEIADISRTLRGLASELNIPIVCLSQLSRKVEDRANKVPMLSDLRDSGQI
+FT EQDADVILFINRKESSSNCEITVGKNRHGSVFSSVLHFDPKISKFSAIKKVW"
+FT CDS 2928..3992
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP2-D"
+FT /db_xref="InterPro:IPR040719"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE17"
+FT /protein_id="AAA91570.1"
+FT /translation="MVNYSNCHFIKSPIHLENQKFGRRPGQSIKISPKLAQNGMVEVIG
+FT LDFLSSHYHALAAIQRLLTATNYKGNTKGVVLSRESNSFQFEGWIPRIRFTKTEFLEAY
+FT GVKRYKTSRNKYEFSGKEAETALEALYHLGHQPFLIVATRTRWTNGTQIVDRYQTLSPI
+FT IRIYEGWEGLTDEENIDIDLTPFNSPPTRKHKGFVVEPCPILVDQIESYFVIKPANVYQ
+FT EIKMRFPNASKYAYTFIDWVITAAAKKRRKLTKDNSWPENLLLNVNVKSLAYILRMNRY
+FT ICTRNWKKIELAIDKCIEIAIQLGWLSRRKRIEFLDSSKLSKKEILYLNKERFEEITKK
+FT SKEQMEQLEQESIN"
+FT CDS 4054..4848
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP3-D"
+FT /db_xref="InterPro:IPR008444"
+FT /db_xref="InterPro:IPR033758"
+FT /db_xref="InterPro:IPR038264"
+FT /db_xref="PDB:6GJT"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE18"
+FT /protein_id="AAA91571.1"
+FT /translation="MGNSGFYLYNTENCVFADNIKVGQMTEPLKDQQIILGTTSTPVAA
+FT KMTASDGISLTVSNNSSTNASITIGLDAEKAYQLILEKLGDQILDGIADTIVDSTVQDI
+FT LDKIKTDPSLGLLKAFNNFPITNKIQCNGLFTPSNIETLLGGTEIGKFTVTPKSSGSMF
+FT LVSADIIASRMEGGVVLALVREGDSKPCAISYGYSSGIPNLCSLRTSITNTGLTPTTYS
+FT LRVGGLESGVVWVNALSNGNDILGITNTSNVSFLEVIPQTNA"
+FT CDS 4918..5226
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP4-D"
+FT /db_xref="UniProtKB/Swiss-Prot:P0CE23"
+FT /protein_id="AAA91572.1"
+FT /translation="MQNKRKVRDDFIKIVKDVKKDFPELDLKIRVNKEKVTFLNSPLEL
+FT YHKSVSLILGLLQQIENSLGLFPDSPVLEKLEDNSLKLKKALIMLILSRKDMFSKAE"
+FT CDS 5317..6048
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP5-D (gtg start codon)"
+FT /db_xref="GOA:P10559"
+FT /db_xref="InterPro:IPR025669"
+FT /db_xref="InterPro:IPR027417"
+FT /db_xref="UniProtKB/Swiss-Prot:P10559"
+FT /protein_id="AAA91573.1"
+FT /translation="MGCNLAQFLGKKVLLADLDPQSNLSSGLGASVRSDQKGLHDIVYT
+FT SNDLKSIICETKKDSVDLIPASFSSEQFRELDIHRGPSNNLKLFLNEYCAPFYDICIID
+FT TPPSLGGLTKEAFVAGDKLIACLTPEPFSILGLQKIREFLSSVGKPEEEHILGIALSFW
+FT DDRNSTNQMYIDIIESIYKNKLFSTKIRRDISLSRSLLKEDSVANVYPNSRAAEDILKL
+FT THEIANILHIEYERDYSQRTT"
+FT CDS 6045..6788
+FT /codon_start=1
+FT /transl_table=11
+FT /product="hypothetical protein"
+FT /note="pGP6-D (gtg start codon)"
+FT /db_xref="InterPro:IPR005350"
+FT /db_xref="UniProtKB/Swiss-Prot:P10560"
+FT /protein_id="AAA91574.1"
+FT /translation="MNKLKKEADVFFKKNQTAASLDFKKTLPSIELFSATLNSEESQSL
+FT DRLFLSESQNYSDEEFYQEDILAVKLLTGQIKSIQKQHVLLLGEKIYNARKILSKDHFS
+FT STTFSSWIELVFRTKSSAYNALAYYELFINLPNQTLQKEFQSIPYKSAYILAARKGDLK
+FT TKVDVIGKVCGMSNSSAIRVLDQFLPSSRNKDVRETIDKSDSEKNRQLSDFLIEILRIM
+FT CSGVSLSSYNENLLQQLFELFKQKS"
+FT repeat_region 6857..6945
+FT /note="four tandem 22bp repeats"
+XX
+SQ Sequence 7502 BP; 2460 A; 1285 C; 1433 G; 2324 T; 0 other;
+ ggatccgtaa gttagacgaa attttgtctt tgcgcacaga cgatctattt tttgcatcca 60
+ atcagatttc ctttcgcatt aaaaaaagac agaataaaga aaccaaaatt ctaatcacat 120
+ ttcctatcag cttaatggaa gagttgcaaa aatacacttg tgggagaaat gggagagtat 180
+ ttgtttctaa aatagggatt cctgtaacaa caagtcaggt tgcgcataat tttaggcttg 240
+ cagagttcca tagtgctatg aaaataaaaa ttactcccag agtacttcgt gcaagcgctt 300
+ tgattcattt aaagcaaata ggattaaaag atgaggaaat catgcgtatt tcctgtcttt 360
+ catcgagaca aagtgtgtgt tcttattgtt ctggggaaga ggtaattcct ctagtacaaa 420
+ cacccacaat attgtgatat aattaaaatt atattcatat tctgttgcca gaaaaaacac 480
+ ctttaggcta tattagagcc atcttctttg aagcgttgtc ttctcgagaa gatttatcgt 540
+ acgcaaatat catctttgcg gttgcgtgtc ctgtgacctt cattatgtcg gagtctgagc 600
+ accctaggcg tttgtactcc gtcacagcgg ttgctcgaag cacgtgcggg gttattttaa 660
+ aagggattgc agcttgtagt cctgcttgag agaacgtgcg ggcgatttgc cttaacccca 720
+ ccatttttcc ggagcgagtt acgaagacaa aacctcttcg ttgaccgatg tactcttgta 780
+ gaaagtgcat aaacttctga ggataagtta taataatcct cttttctgtc tgacggttct 840
+ taagctggga gaaagaaatg gtagcttgtt ggaaacaaat ctgactaatc tccaagctta 900
+ agacttcaga ggagcgttta cctccttgga gcattgtctg ggcgatcaac caatcccggg 960
+ cattgatttt ttttagctct tttaggaagg atgctgtttg caaactgttc atcgcatccg 1020
+ tttttactat ttccctggtt ttaaaaaatg ttcgactatt ttcttgttta gaaggttgcg 1080
+ ctatagcgac tattccttga gtcatcctgt ttaggaatct tgttaaggaa atatagcttg 1140
+ ctgctcgaac ttgtttagta ccttcggtcc aagaagtctt ggcagaggaa acttttttaa 1200
+ tcgcatctag gattagatta tgatttaaaa gggaaaactc ttgcagattc atatccaagg 1260
+ acaatagacc aatcttttct aaagacaaaa aagatcctcg atatgatcta caagtatgtt 1320
+ tgttgagtga tgcggtccaa tgcataataa cttcgaataa ggagaagctt ttcatgcgtt 1380
+ tccaatagga ttcttggcga atttttaaaa cttcctgata agacttttca ctatattcta 1440
+ acgacatttc ttgctgcaaa gataaaatcc ctttacccat gaaatccctc gtgatataac 1500
+ ctatccgtaa aatgtcctga ttagtgaaat aatcaggttg ttaacaggat agcacgctcg 1560
+ gtattttttt atataaacat gaaaactcgt tccgaaatag aaaatcgcat gcaagatatc 1620
+ gagtatgcgt tgttaggtaa agctctgata tttgaagact ctactgagta tattctgagg 1680
+ cagcttgcta attatgagtt taagtgttct catcataaaa acatattcat agtatttaaa 1740
+ cacttaaaag acaatggatt acctataact gtagactcgg cttgggaaga gcttttgcgg 1800
+ cgtcgtatca aagatatgga caaatcgtat ctcgggttaa tgttgcatga tgctttatca 1860
+ aatgacaagc ttagatccgt ttctcatacg gttttcctcg atgatttgag cgtgtgtagc 1920
+ gctgaagaaa atttgagtaa tttcattttc cgctcgttta atgagtacaa tgaaaatcca 1980
+ ttgcgtagat ctccgtttct attgcttgag cgtataaagg gaaggcttga tagtgctata 2040
+ gcaaagactt tttctattcg cagcgctaga ggccggtcta tttatgatat attctcacag 2100
+ tcagaaattg gagtgctggc tcgtataaaa aaaagacgag tagcgttctc tgagaatcaa 2160
+ aattctttct ttgatggctt cccaacagga tacaaggata ttgatgataa aggagttatc 2220
+ ttagctaaag gtaatttcgt gattatagca gctagaccat ctatagggaa aacagcttta 2280
+ gctatagaca tggcgataaa tcttgcggtt actcaacagc gtagagttgg tttcctatct 2340
+ ctagaaatga gcgcaggtca aattgttgag cggattattg ctaatttaac aggaatatct 2400
+ ggtgaaaaat tacaaagagg ggatctctct aaagaagaat tattccgagt agaagaagct 2460
+ ggagaaacgg ttagagaatc acatttttat atctgcagtg atagtcagta taagcttaac 2520
+ ttaatcgcga atcagatccg gttgctgaga aaagaagatc gagtagacgt aatatttatc 2580
+ gattacttgc agttgatcaa ctcatcggtt ggagaaaatc gtcaaaatga aatagcagat 2640
+ atatctagaa ccttaagagg tttagcctca gagctaaaca ttcctatagt ttgtttatcc 2700
+ caactatcta gaaaagttga ggatagagca aataaagttc ccatgctttc agatttgcga 2760
+ gacagcggtc aaatagagca agacgcagat gtgattttgt ttatcaatag gaaggaatcg 2820
+ tcttctaatt gtgagataac tgttgggaaa aatagacatg gatcggtttt ctcttcggta 2880
+ ttacatttcg atccaaaaat tagtaaattc tccgctatta aaaaagtatg gtaaattata 2940
+ gtaactgcca cttcatcaaa agtcctatcc accttgaaaa tcagaagttt ggaagaagac 3000
+ ctggtcaatc tattaagata tctcccaaat tggctcaaaa tgggatggta gaagttatag 3060
+ gtcttgattt tctttcatct cattaccatg cattagcagc tatccaaaga ttactgaccg 3120
+ caacgaatta caaggggaac acaaaagggg ttgttttatc cagagaatca aatagttttc 3180
+ aatttgaagg atggatacca agaatccgtt ttacaaaaac tgaattctta gaggcttatg 3240
+ gagttaagcg gtataaaaca tccagaaata agtatgagtt tagtggaaaa gaagctgaaa 3300
+ ctgctttaga agccttatac catttaggac atcaaccgtt tttaatagtg gcaactagaa 3360
+ ctcgatggac taatggaaca caaatagtag accgttacca aactctttct ccgatcatta 3420
+ ggatttacga aggatgggaa ggtttaactg acgaagaaaa tatagatata gacttaacac 3480
+ cttttaattc accacctaca cggaaacata aagggttcgt tgtagagcca tgtcctatct 3540
+ tggtagatca aatagaatcc tactttgtaa tcaagcctgc aaatgtatac caagaaataa 3600
+ aaatgcgttt cccaaatgca tcaaagtatg cttacacatt tatcgactgg gtgattacag 3660
+ cagctgcgaa aaagagacga aaattaacta aggataattc ttggccagaa aacttgttat 3720
+ taaacgttaa cgttaaaagt cttgcatata ttttaaggat gaatcggtac atctgtacaa 3780
+ ggaactggaa aaaaatcgag ttagctatcg ataaatgtat agaaatcgcc attcagcttg 3840
+ gctggttatc tagaagaaaa cgcattgaat ttctggattc ttctaaactc tctaaaaaag 3900
+ aaattctata tctaaataaa gagcgctttg aagaaataac taagaaatct aaagaacaaa 3960
+ tggaacaatt agaacaagaa tctattaatt aatagcaagc ttgaaactaa aaacctaatt 4020
+ tatttaaagc tcaaaataaa aaagagtttt aaaatgggaa attctggttt ttatttgtat 4080
+ aacactgaaa actgcgtctt tgctgataat atcaaagttg ggcaaatgac agagccgctc 4140
+ aaggaccagc aaataatcct tgggacaaca tcaacacctg tcgcagccaa aatgacagct 4200
+ tctgatggaa tatctttaac agtctccaat aattcatcaa ccaatgcttc tattacaatt 4260
+ ggtttggatg cggaaaaagc ttaccagctt attctagaaa agttgggaga tcaaattctt 4320
+ gatggaattg ctgatactat tgttgatagt acagtccaag atattttaga caaaatcaaa 4380
+ acagaccctt ctctaggttt gttgaaagct tttaacaact ttccaatcac taataaaatt 4440
+ caatgcaacg ggttattcac tcccagtaac attgaaactt tattaggagg aactgaaata 4500
+ ggaaaattca cagtcacacc caaaagctct gggagcatgt tcttagtctc agcagatatt 4560
+ attgcatcaa gaatggaagg cggcgttgtt ctagctttgg tacgagaagg tgattctaag 4620
+ ccctgcgcga ttagttatgg atactcatca ggcattccta atttatgtag tctaagaacc 4680
+ agtattacta atacaggatt gactccgaca acgtattcat tacgtgtagg cggtttagaa 4740
+ agcggtgtgg tatgggttaa tgccctttct aatggcaatg atattttagg aataacaaat 4800
+ acttctaatg tatctttttt agaggtaata cctcaaacaa acgcttaaac aatttttatt 4860
+ ggatttttct tataggtttt atatttagag aaaacagttc gaattacggg gtttgttatg 4920
+ caaaataaaa gaaaagtgag ggacgatttt attaaaattg ttaaagatgt gaaaaaagat 4980
+ ttccccgaat tagacctaaa aatacgagta aacaaggaaa aagtaacttt cttaaattct 5040
+ cccttagaac tctaccataa aagtgtctca ctaattctag gactgcttca acaaatagaa 5100
+ aactctttag gattattccc agactctcct gttcttgaaa aattagagga taacagttta 5160
+ aagctaaaaa aggctttgat tatgcttatc ttgtctagaa aagacatgtt ttccaaggct 5220
+ gaatagacaa cttactctaa cgttggagtt gatttgcaca ccttagtttt ttgctctttt 5280
+ aagggaggaa ctggaaaaac aacactttct ctaaacgtgg gatgcaactt ggcccaattt 5340
+ ttagggaaaa aagtgttact tgctgaccta gacccgcaat ccaatttatc ttctggattg 5400
+ ggggctagtg tcagaagtga ccaaaaaggc ttgcacgaca tagtatacac atcaaacgat 5460
+ ttaaaatcaa tcatttgcga aacaaaaaaa gatagtgtgg acctaattcc tgcatcattt 5520
+ tcatccgaac agtttagaga attggatatt catagaggac ctagtaacaa cttaaagtta 5580
+ tttctgaatg agtactgcgc tcctttttat gacatctgca taatagacac tccacctagc 5640
+ ctaggagggt taacgaaaga agcttttgtt gcaggagaca aattaattgc ttgtttaact 5700
+ ccagaacctt tttctattct agggttacaa aagatacgtg aattcttaag ttcggtcgga 5760
+ aaacctgaag aagaacacat tcttggaata gctttgtctt tttgggatga tcgtaactcg 5820
+ actaaccaaa tgtatataga cattatcgag tctatttaca aaaacaagct tttttcaaca 5880
+ aaaattcgtc gagatatttc tctcagccgt tctcttctta aagaagattc tgtagctaat 5940
+ gtctatccaa attctagggc cgcagaagat attctgaagt taacgcatga aatagcaaat 6000
+ attttgcata tcgaatatga acgagattac tctcagagga caacgtgaac aaactaaaaa 6060
+ aagaagcgga tgtctttttt aaaaaaaatc aaactgccgc ttctctagat tttaagaaga 6120
+ cgcttccctc cattgaacta ttctcagcaa ctttgaattc tgaggaaagt cagagtttgg 6180
+ atcgattatt tttatcagag tcccaaaact attcggatga agaattttat caagaagaca 6240
+ tcctagcggt aaaactgctt actggtcaga taaaatccat acagaagcaa cacgtacttc 6300
+ ttttaggaga aaaaatctat aatgctagaa aaatcctgag taaggatcac ttctcctcaa 6360
+ caactttttc atcttggata gagttagttt ttagaactaa gtcttctgct tacaatgctc 6420
+ ttgcatatta cgagcttttt ataaacctcc ccaaccaaac tctacaaaaa gagtttcaat 6480
+ cgatccccta taaatccgca tatattttgg ccgctagaaa aggcgattta aaaaccaagg 6540
+ tcgatgtgat agggaaagta tgtggaatgt cgaactcatc ggcgataagg gtgttggatc 6600
+ aatttcttcc ttcatctaga aacaaagacg ttagagaaac gatagataag tctgattcag 6660
+ agaagaatcg ccaattatct gatttcttaa tagagatact tcgcatcatg tgttccggag 6720
+ tttctttgtc ctcctataac gaaaatcttc tacaacagct ttttgaactt tttaagcaaa 6780
+ agagctgatc ctccgtcagc tcatatatat atatctatta tatatatata tttagggatt 6840
+ tgatttcacg agagagattt gcaactcttg gtggtagact ttgcaactct tggtggtaga 6900
+ ctttgcaact cttggtggta gactttgcaa ctcttggtgg tagacttggt cataatggac 6960
+ ttttgttaaa aaatttatta aaatcttaga gctccgattt tgaatagctt tggttaagaa 7020
+ aatgggctcg atggctttcc ataaaagtag attgttttta acttttgggg acgcgtcgga 7080
+ aatttggtta tctactttat cttatctaac tagaaaaaat tatgcgtctg ggattaactt 7140
+ tcttgtttct ttagagattc tggatttatc ggaaaccttg ataaaggcta tttctcttga 7200
+ ccacagcgaa tctttgttta aaatcaagtc tctagatgtt tttaatggaa aagttgtttc 7260
+ agaggcatct aaacaggcta gagcggcatg ctacatatct ttcacaaagt ttttgtatag 7320
+ attgaccaag ggatatatta aacccgctat tccattgaaa gattttggaa acactacatt 7380
+ ttttaaaatc cgagacaaaa tcaaaacaga atcgatttct aagcaggaat ggacagtttt 7440
+ ttttgaagcg ctccggatag tgaattatag agactattta atcggtaaat tgattgtaca 7500
+ ag 7502
+//
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
import jalview.api.AlignViewportI;
import jalview.commands.EditCommand;
assertEquals(1, ranges.size());
assertEquals(9, ranges.get(0)[1]);
}
+
+ @Test(groups = "Functional")
+ public void testListToArray()
+ {
+ List<int[]> ranges = new ArrayList<>();
+
+ int[] result = MappingUtils.listToArray(ranges);
+ assertEquals(result.length, 0);
+ ranges.add(new int[] {24, 12});
+ result = MappingUtils.listToArray(ranges);
+ assertEquals(result.length, 2);
+ assertEquals(result[0], 24);
+ assertEquals(result[1], 12);
+ ranges.add(new int[] {-7, 30});
+ result = MappingUtils.listToArray(ranges);
+ assertEquals(result.length, 4);
+ assertEquals(result[0], 24);
+ assertEquals(result[1], 12);
+ assertEquals(result[2], -7);
+ assertEquals(result[3], 30);
+ try
+ {
+ MappingUtils.listToArray(null);
+ fail("Expected exception");
+ } catch (NullPointerException e)
+ {
+ // expected
+ }
+ }
}
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.SequenceI;
import java.util.Arrays;
import java.util.List;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-public class EmblSourceTest
+public class EmblXmlSourceTest
{
// adapted from http://www.ebi.ac.uk/ena/data/view/X07547&display=xml
+ "ACCCCCAATATTGTGATATAATTAAAAACATAGCAT"
+ "</sequence></entry></ROOT>";
+ private EmblXmlSource testee;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ testee = new EmblXmlSource()
+ {
+
+ @Override
+ public String getDbSource()
+ {
+ return null;
+ }
+
+ @Override
+ public String getDbName()
+ {
+ return null;
+ }
+
+ @Override
+ public String getTestQuery()
+ {
+ return null;
+ }
+
+ @Override
+ public AlignmentI getSequenceRecords(String queries) throws Exception
+ {
+ return null;
+ }
+ };
+ }
+
@Test(groups = "Functional")
public void testGetCdsRanges()
{
- EmblSource testee = new EmblSource();
-
/*
* Make a (CDS) Feature with 5 locations
*/
Feature cds = new Feature();
- cds.setLocation("join(10..20,complement(30..40),50..60,70..80,complement(110..120))");
+ cds.setLocation(
+ "join(10..20,complement(30..40),50..60,70..80,complement(110..120))");
int[] exons = testee.getCdsRanges("EMBL", cds);
assertEquals("[10, 20, 40, 30, 50, 60, 70, 80, 120, 110]",
{
// not the whole sequence but enough for this test...
List<SequenceI> peptides = new ArrayList<>();
- List<EntryType> entries = EmblSourceTest.getEmblEntries();
+ List<EntryType> entries = getEmblEntries();
assertEquals(1, entries.size());
EntryType entry = entries.get(0);
- EmblSource testee = new EmblSource();
String sourceDb = "EMBL";
SequenceI dna = testee.getSequence(sourceDb, entry, peptides);
3, 1);
MapList cds2Map = new MapList(new int[] { 4, 15 }, new int[] { 1, 4 },
3, 1);
- MapList cds3Map = new MapList(new int[] { 4, 6, 10, 15 }, new int[] {
- 1, 3 }, 3, 1);
+ MapList cds3Map = new MapList(new int[] { 4, 6, 10, 15 },
+ new int[]
+ { 1, 3 }, 3, 1);
DBRefEntry[] dbrefs = dna.getDBRefs();
assertEquals(7, dbrefs.length);
* - to EMBLCDS (with 1:3 mapping)
* - direct (no mapping) to other protein accessions
*/
- MapList proteinToCdsMap1 = new MapList(new int[] { 1, 4 }, new int[] {
- 1, 12 }, 1, 3);
- MapList proteinToCdsMap2 = new MapList(new int[] { 1, 3 }, new int[] {
- 1, 9 }, 1, 3);
+ MapList proteinToCdsMap1 = new MapList(new int[] { 1, 4 },
+ new int[]
+ { 1, 12 }, 1, 3);
+ MapList proteinToCdsMap2 = new MapList(new int[] { 1, 3 },
+ new int[]
+ { 1, 9 }, 1, 3);
// dbrefs for first CDS EMBL product CAA30420.1
dbrefs = peptides.get(0).getDBRefs();
@Test(groups = { "Functional" })
public void testGetEmblEntries()
{
- List<EntryType> entries = EmblSourceTest.getEmblEntries();
+ List<EntryType> entries = getEmblEntries();
assertEquals(1, entries.size());
EntryType entry = entries.get(0);
-
+
assertEquals("X07547", entry.getAccession());
assertEquals("C. trachomatis plasmid", entry.getDescription());
assertEquals("STD", entry.getDataClass());
assertEquals(2, entry.getKeyword().size());
assertEquals("plasmid", entry.getKeyword().get(0));
assertEquals("unidentified reading frame", entry.getKeyword().get(1));
-
+
/*
* dbrefs
*/
assertEquals("MD5", dbref.getDb());
assertEquals("ac73317", dbref.getId());
assertNull(dbref.getSecondaryId());
-
+
/*
* three sequence features for CDS
*/
q = ef.getQualifier().get(2);
assertEquals("translation", q.getName());
assertEquals("MLCF", q.getValue());
-
+
/*
* second CDS
*/
q = ef.getQualifier().get(1);
assertEquals("translation", q.getName());
assertEquals("MSSS", q.getValue());
-
+
/*
* third CDS
*/
q = ef.getQualifier().get(1);
assertEquals("translation", q.getName());
assertEquals("MSS", q.getValue());
-
+
/*
* Sequence - raw data before removal of newlines
*/
String seq = entry.getSequence();
- assertEquals(
- "GGTATGTCCTCTAGTACAAAC\n"
- + "ACCCCCAATATTGTGATATAATTAAAAACATAGCAT",
- seq);
-
+ assertEquals("GGTATGTCCTCTAGTACAAAC\n"
+ + "ACCCCCAATATTGTGATATAATTAAAAACATAGCAT", seq);
+
/*
* getSequence() converts empty DBRefEntry.version to "0"
*/
assertNull(entry.getFeature().get(0).getXref().get(1).getSecondaryId());
}
- static List<EntryType> getEmblEntries()
+ List<EntryType> getEmblEntries()
{
- return new EmblSource()
+ return testee
.getEmblEntries(new ByteArrayInputStream(TESTDATA.getBytes()));
}
}
@Test(groups = "Functional")
public void testGetURL()
{
- String path = "pfam.xfam.org/family/ABC/alignment/full";
+ String path = "pfam.xfam.org/family/ABC/alignment/full/gzipped";
// with default value for domain
String url = new PfamFull().getURL(" abc ");
@Test(groups = "Functional")
public void testGetURL()
{
- String path = "pfam.xfam.org/family/ABC/alignment/seed";
+ String path = "pfam.xfam.org/family/ABC/alignment/seed/gzipped";
// with default value for domain
String url = new PfamSeed().getURL(" abc ");
@Test(groups = "Functional")
public void testGetURL()
{
- String path = "rfam.xfam.org/family/ABC/alignment/full";
+ String path = "rfam.xfam.org/family/ABC/alignment/full?gzip=1&download=1";
// with default value for domain
String url = new RfamFull().getURL(" abc ");
@Test(groups = "Functional")
public void testGetURL()
{
- String path = "rfam.xfam.org/family/ABC/alignment/stockholm";
+ String path = "rfam.xfam.org/family/ABC/alignment/stockholm?gzip=1&download=1";
// with default value for domain
String url = new RfamSeed().getURL(" abc ");
/*
* EMBL
*/
- assertEquals("https://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/browser/api/embl/x53838?download=true&gzip=true",
EBIFetchClient.buildUrl("X53838", "EMBL", "display=xml"));
/*
* EMBLCDS
*/
- assertEquals("https://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/browser/api/embl/caa37824?download=true&gzip=true",
EBIFetchClient.buildUrl("CAA37824", "EMBL", "display=xml"));
/*
--- /dev/null
+#!/usr/bin/env bash
+
+CMD=$(basename $0)
+CMD=${CMD%-nox.sh}
+
+echo "Running '$CMD' headlessly"
+
+xvfb-run -s "-screen 0 1280x800x16" -e /dev/stdout -a $CMD ${@}
--- /dev/null
+cmd-nox.sh
\ No newline at end of file