Utilib -- README

Submitted by h2b on

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 type V,
  • ListParameter[V]: has a number of values of type V and
  • MainParameter: has a number of String 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 is Some(true) if present, else None
  • HelpParameter: value is Some(true) if present, else None
  • ValueParameter[V]: value is Some(x) if x is given, Some(y) if not given but Some(y) is default, else None
  • ListParameter[V]: values is Some(Seq(x1,x2,...)) if x is given, Some(Seq(y1,y2,...)) if not given but Some(Seq(y1,,y2,...)) is default, else None
  • MainParameter: values is Some(Seq(x1,x2,...)) if x is given, Some(Seq(y1,y2,...)) if not given but Some(Seq(y1,,y2,...)) is default, else None

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 by ArgsConfig.SeparatorChar) are considered as key/value pairs, while elements not consumed by this rule can be retrieved by the remaining 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 the java.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 the java.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 a Config object that represents the system properties of the JVM.

  • SystemEnvironmentConfig is a Config object that represents the system environment; note that the system may not support environment variables -- in this case, this object is empty.

Multiple Configs 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.

Bereich
Tags