Utilib -- A Scala Library of Programming Utilities
This is a Scala library of programming utilities. It is not intended to comprise a systematic collection but contains some tools that happen to be useful for myself and may be of interest for others.
Current highlights are a number of probability distributions, a command-line interface, a configuration package, an RSS utility, a class to handle temporary directories, control structures, a logger trait and a timer.
A real-world use case of the RSS package is documented by the article Server Monitoring by RSS with Utilib.
Some of them are documented below.
Table of Contents
U1 Command-Line Interface
U1-1 Package
de.h2b.scala.lib.util.cli
U1-2 Preparation
Define the parameters of your command line as instances of
-
FlagParameter
: no specific value, just signals that it is there, -
HelpParameter
: signals that the user needs some help (if given as a command-line argument, other parameters are not computed and no parse exceptions are thrown), -
ValueParameter[V]
: has exactly one value of typeV
, -
ListParameter[V]
: has a number of values of typeV
and -
MainParameter
: has a number ofString
values.
All parameters except for MainParameter
have a set of names: they act as kind of reserved words in the command line, e.g., Set("-a", "--all")
. Note, that it is not necessary (but a convention on Unix-like systems) to prefix these names by -
or --
.
All parameters except for HelpParameter
have a description string that only is used for the usage message.
ValueParameter[V]
, ListParameter[V]
and MainParameter
have a required
attribute which is false
by default. If it is true
, it's an error and will throw an exception if that parameter is not part of the actual command line. Also, these parameter types have a default
or defaults
attribute which will be used as parameter value if not given in the command line. It is undefined what happens, if such a parameter is required, has a default, but is not present in the command line, so better don't combine these attributes for a given parameter in such a way.
ValueParameter[V]
and ListParameter[V]
need a converter to convert a string to the value type V
. You might want to import the object Converter
that provides converters for standard data types implicitly by:
import de.h2b.scala.lib.util.cli.Converter._
ListParameter[V]
and MainParameter
have an arity
attribute that specifies the number of values following its parameter name as follows:
- positive number: exactly this number of values must follow the parameter name;
-
negative number: at least
abs
(this number) of values must follow the parameter name (variable arity); - zero: no values must follow the parameter name.
Values following the parameter name will be consumed up to the next parameter name.
A MainParameter
is different from a list parameter by the absence of a name in the command line. There is, however, an internal name (MainParameter.internalName
) that can be used in the command line to avoid ambiguities.
Main-parameter values can be given at the beginning or at the end of the arguments sequence (or both mixed up, but that may be confusing). Beware, that values at the end might be consumed by a variable-arity parameter in a position right before.
Note, that the particular order of arguments in the command line is not defined apart from the considerations regarding to the main parameter above.
U1-3 Application
Create a new instance of CommandLine
with a set of parameters. The resulting object then can parse a string sequence or an array of strings for parameters and their values. If something goes wrong, either a ParameterException
(some argument does not obey to the format specified by its parameter) or a CommandLineException
(something is wrong with the arguments as a whole) is thrown.
Then query the original parameter instances:
-
FlagParameter
:value
isSome(true)
if present, elseNone
-
HelpParameter
:value
isSome(true)
if present, elseNone
-
ValueParameter[V]
:value
isSome(x)
ifx
is given,Some(y)
if not given butSome(y)
is default, elseNone
-
ListParameter[V]
:values
isSome(Seq(x1,x2,...))
ifx
is given,Some(Seq(y1,y2,...))
if not given butSome(Seq(y1,,y2,...))
is default, elseNone
-
MainParameter
:values
isSome(Seq(x1,x2,...))
ifx
is given,Some(Seq(y1,y2,...))
if not given butSome(Seq(y1,,y2,...))
is default, elseNone
The usage
method constructs a string suitable for a usage message.
U1-4 API
See Scaladoc.
U1-5 Example
import de.h2b.scala.lib.util.cli._
import de.h2b.scala.lib.util.cli.Converter._
val overwrite = FlagParameter(Set("-o", "--overwrite"), "overwrite target")
val mode = ValueParameter(Set("-m"), "mode", default=Some(0))
val main = MainParameter("source target", arity=2)
CommandLine(Set(overwrite, mode, main)).parse("-o -m 1 from to".split(' '))
println(overwrite.value) //> Some(true)
println(mode.value) //> Some(1)
println(main.values) //> Some(WrappedArray(from, to))
U2 Configuration Package
U2-1 Package
de.h2b.scala.lib.util.config
U2-2 Summary
This package provides various configuration sources under a common trait Config
, which is basically an immutable map. The following implementations are available:
-
ArgsConfig
loads key/value pairs from an array of strings: array elements that contain a separator char (defined byArgsConfig.SeparatorChar
) are considered as key/value pairs, while elements not consumed by this rule can be retrieved by theremaining
array (makes it suitable to scan a command line for such key/value pairs and parsing the rest with tools like described in U1 Command-Line Interface. -
FileConfig
loads key/value pairs from a specified resource file which must conform to thejava.util.Properties#load(InputStream)
method; there is also a factory method where the resource is looked up under the modified package name of a specified class. -
BundleConfig
loads key/value pairs from a resource bundle (according to thejava.util.ResourceBundle
class) of a specified base name using a locale option; there is also a factory method where the resource bundle is looked up under the modified package name of a specified class. -
SystemPropertiesConfig
is aConfig
object that represents the system properties of the JVM. -
SystemEnvironmentConfig
is aConfig
object that represents the system environment; note that the system may not support environment variables -- in this case, this object is empty.
Multiple Config
s can be combined using the standard map ++
operators, yielding an overall Config
.
U2-3 API
See Scaladoc.
U2-4 Example
import de.h2b.scala.lib.util.config._
val argsConfig = ArgsConfig("-x key1=val1 /y key2=val2 abc".split(' '))
val sysConfig = SystemPropertiesConfig
val otherConfig = Config("one"→1, "two"→2, "three"→3)
val config = argsConfig ++ sysConfig ++ otherConfig
println(config.get("key1")) //> Some(val1)
println(config.get("java.version")) //> Some(1.8.0_121)
println(config.get("two")) //> Some(2)
println(argsConfig.remaining.mkString(" ")) //> -x /y abc
A Appendix
API
See Scaladoc.
Maven Coordinates
See The Central Repository. Choose the version you want (of course, the latest one is recommended) and look under "Dependency Information".
Licence
Utilib - A Scala Library of Programming Utilities
Copyright 2015-2018 Hans-Hermann Bode
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.