All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nfigrity-core_2.9.0-1.0.10.2.source-code.Configuration.scala Maven / Gradle / Ivy

The newest version!
/*
 Copyright (C) 2011-2012, Paradigmatic 

 This file is part of Configrity.
 
 Configrity is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 Configrity 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 Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with Configrity.  If not, see .
*/

package org.streum.configrity

import converter.ValueConverter
import io._
import scala.io.Source
import scalashim._

/**
 * A Configuration class stores and allow access to configuration data. Although
 * immutable, several methods allow to easily change configuration data, returning
 * a new Configuration instance.
 */
case class Configuration( data: Map[String,String] ) {

  /**
   * Returns true if some value is associated with the
   * given key, else false.
   */
  def contains( key: String ) = data contains key

  /**
   * Retrieve and convert configuration data in the wanted type. Throws
   * an NoSuchElementException if the data is not defined. The conversion
   * is done by a ValueConverter instance which should be provided or
   * implicitly defined elsewhere.
   */
  def apply[A]( key: String )( implicit converter: ValueConverter[A] ) =
    converter( data get key ) getOrElse ( throw new NoSuchElementException( key ) )

  /**
   * Retrieve and convert configuration data in the wanted type. Returns None
   * if the data is not defined and Some(x) else. The conversion is done by
   * a ValueConverter instance which should be provided or implicitly defined
   * elsewhere.
   */
  def get[A]( key: String )( implicit converter: ValueConverter[A] ) =
    converter( data get key )

  /**
   * Retrieve and convert configuration data in the wanted type. The user
   * must supply a default value, returned is the key is not found.
   */
  def apply[A]( key: String, default: A )( implicit converter: ValueConverter[A] ) =
    converter( data get key ) getOrElse default

  /**
   * Sets a new configuration value. If the key already exists, previous value
   * is replaced.
   */
  def set[A]( key: String, a: A ) =
    Configuration( data + ( key -> a.toString ) )

  /**
   * Sets a new configuration list value. If the key already exists,
   * previous value is replaced.
   */
  def set[A]( key: String, as: List[A] ) = {
    val str = io.Utils.sanitize(as).mkString( "[", ",", "]" )
    Configuration( data + ( key -> str ) )
  }

  /**
   * Removes a configuration value. No effect if the value was not previously
   * defined.
   */
  def clear[A]( key: String ) = 
    if( data contains key ) 
      Configuration( data - key )
    else
      this

  /**
   * Convert the map in a string using a provided export format.
   * By default, FlatFormat is used.
   */
  def format( fmt: ExportFormat = Configuration.defaultFormat ) = 
    fmt.toText( this )

  /** Saves the configuration to a file */
  def save( 
    file: java.io.File, 
    fmt: ExportFormat = Configuration.defaultFormat
  ) {
    val out = new java.io.PrintWriter( file )
    out.println( format(fmt) )
    out.close
  }

  /** Saves the configuration to a file */
  def save( filename: String, fmt: ExportFormat ): Unit =
    save( new java.io.File( filename ), fmt )

  /** Saves the configuration to a file */
  def save( filename: String ): Unit =
    save( new java.io.File( filename ) )

  /** Attach a configuration as a sub block. Existing entries with
   *  same keys will be replaced. Prefix should not end with a 'dot'.
   */
  def attach( prefix: String, block: Configuration ) = {
    require( 
      prefix.substring( prefix.length-1) != ".", 
      "Prefix should not end with a dot"
    )
    var nextData = Map[String,String]()
    for( (k,v) <- block.data ) {
      val nextKey = prefix + "." + k
      nextData += nextKey -> v
    }
    Configuration( data ++ nextData )
  }

  /** Detach all values whose keys have the given prefix as a new configuration.
   *  The initial configuration is not modified. The prefix is removed in the
   *  resulting configuration. An important property:
   *
   *  
val c2 = c1.attach(prefix, c1.detach( prefix )
* * The resulting configuration c2 should be equal to c1. */ def detach( prefix: String ) = { require( prefix.substring( prefix.length-1) != ".", "Prefix should not end with a dot" ) val regexp = (prefix + """\.(.+)""" ).r var nextData = Map[String,String]() for( (k,v) <- data ) k match { case regexp( subkey ) => nextData += subkey -> v case _ => {} } Configuration( nextData ) } /** * Adds another configuration values providing entries * which are not present in the present one. Useful * for defaulting to another Configuration */ def include( config: Configuration ) = Configuration( config.data ++ data ) /** * Adds another configuration. The configuration passed in argument * will override values. */ def ++( config: Configuration ) = config include this } /** Configuration companion object */ object Configuration { /** By default, all conversions are done with BlockFormat */ val defaultFormat = BlockFormat /** Creates a configuration from tuples of key,value */ def apply( entries:(String,Any)* ):Configuration = Configuration( entries.map { case (k,v) => v match { case l: List[_] => (k, io.Utils.sanitize(l).mkString("[",",","]") ) case _ => (k,v.toString) } }.toMap ) /** Returns the environement variables as a Configuration */ def environment = Configuration( sys.env ) /** Returns the system properties as a Configuration */ def systemProperties = Configuration( sys.props.toMap ) /** Instanciates a configuration file from a string using * eventually a specified format. By default, the FlatFormat * will be used. */ def parse( s: String, fmt: ImportFormat = defaultFormat ) = fmt.fromText( s ) /** * Load a configuration from a scala.io.Source. An optional * format can be passed. */ def load( source: Source, fmt: ImportFormat = defaultFormat ): Configuration = fmt.fromText( source.mkString ) /** * Load a configuration from a file specified by a filename. */ def load( fileName: String ) (implicit codec: scala.io.Codec): Configuration = load( Source.fromFile( fileName ) ) /** * Load a configuration from a file specified by a filename and * using a given format. */ def load( fileName: String, fmt: ImportFormat ) (implicit codec: scala.io.Codec): Configuration = load( Source.fromFile( fileName ), fmt ) /** * Load a configuration as a resource from the classpath. An optional * format can be passed. */ def loadResource( fileName: String, fmt: ImportFormat = defaultFormat ) = { val inputStream = getClass.getResourceAsStream( fileName ) if (inputStream == null) { throw new java.io.FileNotFoundException(fileName) } val src = Source.fromInputStream(inputStream) load( src, fmt ) } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy