From 4b7c3af763f94a0d412e7ab9bd93d8bae5ca9cfc Mon Sep 17 00:00:00 2001 From: kshakir Date: Mon, 11 Apr 2011 20:22:44 +0000 Subject: [PATCH] When /etc/mailname is unreadable fall back to the hostname. Implicit conversions for String to/from File. Small updates to the example QScripts. git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@5614 348d0f76-0448-11de-a6fe-93d51630548a --- .../examples/ExampleUnifiedGenotyper.scala | 6 +- scala/qscript/examples/HelloWorld.scala | 2 +- .../broadinstitute/sting/queue/QScript.scala | 25 +---- .../queue/util/StringFileConversions.scala | 105 ++++++++++++++++++ .../sting/queue/util/SystemUtils.scala | 10 +- .../util/StringFileConversionsUnitTest.scala | 102 +++++++++++++++++ 6 files changed, 224 insertions(+), 26 deletions(-) create mode 100644 scala/src/org/broadinstitute/sting/queue/util/StringFileConversions.scala create mode 100644 scala/test/org/broadinstitute/sting/queue/util/StringFileConversionsUnitTest.scala diff --git a/scala/qscript/examples/ExampleUnifiedGenotyper.scala b/scala/qscript/examples/ExampleUnifiedGenotyper.scala index b630df96f..2f6940d64 100644 --- a/scala/qscript/examples/ExampleUnifiedGenotyper.scala +++ b/scala/qscript/examples/ExampleUnifiedGenotyper.scala @@ -36,14 +36,12 @@ class ExampleUnifiedGenotyper extends QScript { // and then reuse this trait on each CommandLineGATK function below. trait UnifiedGenotyperArguments extends CommandLineGATK { this.reference_sequence = qscript.referenceFile - this.intervals = List(qscript.intervals) - // is how you set the value for an scala Option. + this.intervals = if (qscript.intervals == null) Nil else List(qscript.intervals) // Set the memory limit to 2 gigabytes on each command. this.memoryLimit = 2 } - - def script = { + def script() { // Create the four function that we can run. val genotyper = new UnifiedGenotyper with UnifiedGenotyperArguments val variantFilter = new VariantFiltration with UnifiedGenotyperArguments diff --git a/scala/qscript/examples/HelloWorld.scala b/scala/qscript/examples/HelloWorld.scala index fd3c3b71e..64e0c161c 100644 --- a/scala/qscript/examples/HelloWorld.scala +++ b/scala/qscript/examples/HelloWorld.scala @@ -1,7 +1,7 @@ import org.broadinstitute.sting.queue.QScript class HelloWorld extends QScript { - def script = { + def script() { add(new CommandLineFunction { def commandLine = "echo hello world" }) diff --git a/scala/src/org/broadinstitute/sting/queue/QScript.scala b/scala/src/org/broadinstitute/sting/queue/QScript.scala index 2b509d765..5cb8d1d29 100755 --- a/scala/src/org/broadinstitute/sting/queue/QScript.scala +++ b/scala/src/org/broadinstitute/sting/queue/QScript.scala @@ -24,15 +24,15 @@ package org.broadinstitute.sting.queue -import util.{PrimitiveOptionConversions, Logging} import org.broadinstitute.sting.queue.function.QFunction -import org.broadinstitute.sting.utils.text.XReadLines import annotation.target.field +import io.Source +import util.{StringFileConversions, PrimitiveOptionConversions, Logging} /** * Defines a Queue pipeline as a collection of CommandLineFunctions. */ -trait QScript extends Logging with PrimitiveOptionConversions { +trait QScript extends Logging with PrimitiveOptionConversions with StringFileConversions { // Type aliases so users don't have to import type File = java.io.File @@ -55,7 +55,7 @@ trait QScript extends Logging with PrimitiveOptionConversions { /** * Builds the CommandLineFunctions that will be used to run this script and adds them to this.functions directly or using the add() utility method. */ - def script: Unit + def script() /** * The command line functions that will be executed for this QScript. @@ -72,17 +72,6 @@ trait QScript extends Logging with PrimitiveOptionConversions { protected def swapExt(file: File, oldExtension: String, newExtension: String) = new File(file.getName.stripSuffix(oldExtension) + newExtension) - /** - * Exchanges the extension on a file. - * @param dir New directory for the file. - * @param file File to look for the extension. - * @param oldExtension Old extension to strip off, if present. - * @param newExtension New extension to append. - * @return new File with the new extension in dir. - */ - protected def swapExt(dir: String, file: File, oldExtension: String, newExtension: String) = - new File(dir, file.getName.stripSuffix(oldExtension) + newExtension) - /** * Exchanges the extension on a file. * @param dir New directory for the file. @@ -103,13 +92,11 @@ trait QScript extends Logging with PrimitiveOptionConversions { this.functions ++= functions } - def addAll(functions: List[QFunction] ) = { + def addAll(functions: List[QFunction]) { functions.foreach( f => add(f) ) } - def extractFileEntries(in: File): List[File] = { - return collection.JavaConversions.asScalaIterator((new XReadLines(in))).toList.map( new File(_) ) - } + def extractFileEntries(in: File): List[File] = Source.fromFile(in).getLines().toList } object QScript { diff --git a/scala/src/org/broadinstitute/sting/queue/util/StringFileConversions.scala b/scala/src/org/broadinstitute/sting/queue/util/StringFileConversions.scala new file mode 100644 index 000000000..b4c123bbe --- /dev/null +++ b/scala/src/org/broadinstitute/sting/queue/util/StringFileConversions.scala @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011, The Broad Institute + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.queue.util + +import java.io.{Serializable, File} + +/** + * Converts String to/from File + * The method signatures are based on the compiler errors reported by StringFileConversionsUnitTest. + * The implementations are based on the runtime errors reported by StringFileConversionsUnitTest. + */ +object StringFileConversions { + implicit def stringAsFile(x: String): File = { + if (x == null) null else new File(x) + } + + implicit def fileAsString(x: File): String = { + if (x == null) null else x.getPath + } + + // Possible to get the invariants, covariants, contravariants, upper type bounds, lower type bounds + // and mixins all correct so this doesn't have to be duplicated with concrete implementations? + // http://programming-scala.labs.oreilly.com/ch12.html is your friend. + + implicit def stringsAsFiles(x: List[Comparable[_ >: String with File <: Comparable[_ >: String with File <: Serializable] with Serializable] with Serializable]) = { + x.map(_ match { + case string: String => stringAsFile(string) + case file: File => file + }) + } + + implicit def filesAsStrings(x: List[Comparable[_ >: File with String <: Comparable[_ >: File with String <: Serializable] with Serializable] with Serializable]) = { + x.map(_ match { + case file: File => fileAsString(file) + case string: String => string + }) + } + + implicit def stringsAsFiles(x: Set[Comparable[_ >: File with String <: Comparable[_ >: File with String <: Comparable[_ >: File with String <: Serializable] with Serializable] with Serializable] with Serializable]) = { + x.map(_ match { + case string: String => stringAsFile(string) + case file: File => file + }) + } + + implicit def filesAsStrings(x: Set[Comparable[_ >: String with File <: Comparable[_ >: String with File <: Comparable[_ >: String with File <: Serializable] with Serializable] with Serializable] with Serializable]) = { + x.map(_ match { + case file: File => fileAsString(file) + case string: String => string + }) + } +} + +/** + * Converts String to/from File + * The method signatures are based on the compiler errors reported by StringFileConversionsUnitTest. + * The implementations are based on the runtime errors reported by StringFileConversionsUnitTest. + */ +trait StringFileConversions { + implicit def stringAsFile(x: String): File = { + StringFileConversions.stringAsFile(x) + } + + implicit def fileAsString(x: File): String = { + StringFileConversions.fileAsString(x) + } + + implicit def stringsAsFiles(x: List[Comparable[_ >: String with File <: Comparable[_ >: String with File <: Serializable] with Serializable] with Serializable]) = { + StringFileConversions.stringsAsFiles(x) + } + + implicit def filesAsStrings(x: List[Comparable[_ >: File with String <: Comparable[_ >: File with String <: Serializable] with Serializable] with Serializable]) = { + StringFileConversions.filesAsStrings(x) + } + + implicit def stringsAsFiles(x: Set[Comparable[_ >: File with String <: Comparable[_ >: File with String <: Comparable[_ >: File with String <: Serializable] with Serializable] with Serializable] with Serializable]) = { + StringFileConversions.stringsAsFiles(x) + } + + implicit def filesAsStrings(x: Set[Comparable[_ >: String with File <: Comparable[_ >: String with File <: Comparable[_ >: String with File <: Serializable] with Serializable] with Serializable] with Serializable]) = { + StringFileConversions.filesAsStrings(x) + } +} diff --git a/scala/src/org/broadinstitute/sting/queue/util/SystemUtils.scala b/scala/src/org/broadinstitute/sting/queue/util/SystemUtils.scala index f2f5f3fa0..9002def78 100644 --- a/scala/src/org/broadinstitute/sting/queue/util/SystemUtils.scala +++ b/scala/src/org/broadinstitute/sting/queue/util/SystemUtils.scala @@ -32,7 +32,7 @@ import io.Source /** * A collection of various system utilities. */ -object SystemUtils { +object SystemUtils extends Logging { val inetAddress = InetAddress.getLocalHost.getHostAddress val canonicalHostName = InetAddress.getLocalHost.getCanonicalHostName @@ -46,7 +46,13 @@ object SystemUtils { val mailName = { val mailnameFile = new File("/etc/mailname") if (mailnameFile.exists) - Source.fromFile(mailnameFile).mkString.trim + try { + Source.fromFile(mailnameFile).mkString.trim + } catch { + case e: Exception => + logger.error("Unabled to read mail domain. Using hostname.", e) + hostName.split('.').takeRight(2).mkString(".") + } else hostName.split('.').takeRight(2).mkString(".") } diff --git a/scala/test/org/broadinstitute/sting/queue/util/StringFileConversionsUnitTest.scala b/scala/test/org/broadinstitute/sting/queue/util/StringFileConversionsUnitTest.scala new file mode 100644 index 000000000..4ddcbc486 --- /dev/null +++ b/scala/test/org/broadinstitute/sting/queue/util/StringFileConversionsUnitTest.scala @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011, The Broad Institute + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.queue.util + +import org.testng.annotations.Test +import java.io.File +import org.testng.Assert +import StringFileConversions._ + +class StringFileConversionsUnitTest { + @Test + def testStringToFile() { + val file = new File("foo") + val string: String = file + Assert.assertEquals(string, "foo") + } + + @Test + def testFileToString() { + val string = "foo" + val file: File = string + Assert.assertEquals(file, new File("foo")) + } + + @Test + def testStringToFileList() { + var files = List(new File("foo")) + files :+= "bar" + Assert.assertEquals(files, List(new File("foo"), new File("bar"))) + } + + @Test + def testFileToStringList() { + var strings = List("foo") + strings :+= new File("bar") + Assert.assertEquals(strings, List("foo", "bar")) + } + + @Test + def testStringToFileSet() { + var files = Set(new File("foo")) + files += "bar" + Assert.assertEquals(files, Set(new File("foo"), new File("bar"))) + } + + @Test + def testFileToStringSet() { + var strings = Set("foo") + strings += new File("bar") + Assert.assertEquals(strings, Set("foo", "bar")) + } + + @Test + def testStringListToFileList() { + var files = List(new File("foo")) + files ++= List("bar") + Assert.assertEquals(files, List(new File("foo"), new File("bar"))) + } + + @Test + def testFileListToStringList() { + var strings = List("foo") + strings ++= List(new File("bar")) + Assert.assertEquals(strings, List("foo", "bar")) + } + + @Test + def testStringSetToFileSet() { + var files = Set(new File("foo")) + files ++= Set("bar") + Assert.assertEquals(files, Set(new File("foo"), new File("bar"))) + } + + @Test + def testFileSetToStringSet() { + var strings = Set("foo") + strings ++= Set(new File("bar")) + Assert.assertEquals(strings, Set("foo", "bar")) + } +}