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

org.refcodes.configuration.ext.runtime.RuntimePropertiesImpl Maven / Gradle / Ivy

Go to download

Artefact for providing predefined configuration compositions common for everyday application setups.

There is a newer version: 2.0.5
Show newest version
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
// under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////

package org.refcodes.configuration.ext.runtime;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.refcodes.component.OpenException;
import org.refcodes.configuration.AbstractPropertiesDecorator;
import org.refcodes.configuration.EnvironmentProperties;
import org.refcodes.configuration.PolyglotPropertiesBuilder.PolyglotPropertiesBuilderFactory;
import org.refcodes.configuration.ProfilePropertiesProjection;
import org.refcodes.configuration.Properties;
import org.refcodes.configuration.PropertiesBuilderImpl;
import org.refcodes.configuration.PropertiesPrecedence.PropertiesPrecedenceBuilder;
import org.refcodes.configuration.PropertiesPrecedenceBuilderComposite;
import org.refcodes.configuration.PropertiesPrecedenceComposite;
import org.refcodes.configuration.ReloadMode;
import org.refcodes.configuration.ResourceProperties;
import org.refcodes.configuration.SystemProperties;
import org.refcodes.configuration.ext.console.ArgsParserProperties;
import org.refcodes.configuration.ext.console.ArgsParserPropertiesImpl;
import org.refcodes.configuration.ext.obfuscation.ObfuscationProperties;
import org.refcodes.configuration.ext.obfuscation.ObfuscationProperties.ObfuscationPropertiesBuilder;
import org.refcodes.configuration.ext.obfuscation.ObfuscationPropertiesDecorator;
import org.refcodes.configuration.ext.obfuscation.ObfuscationResourceProperties.ObfuscationResourcePropertiesBuilder;
import org.refcodes.configuration.ext.obfuscation.ObfuscationResourcePropertiesBuilderDecorator;
import org.refcodes.console.AmbiguousArgsException;
import org.refcodes.console.Condition;
import org.refcodes.console.Operand;
import org.refcodes.console.ParseArgsException;
import org.refcodes.console.SuperfluousArgsException;
import org.refcodes.console.SyntaxNotation;
import org.refcodes.console.UnknownArgsException;
import org.refcodes.exception.BugException;
import org.refcodes.runtime.ConfigLocator;
import org.refcodes.runtime.SystemContext;
import org.refcodes.security.DecryptionException;
import org.refcodes.security.EncryptionException;
import org.refcodes.security.alt.chaos.ChaosKeyImpl;
import org.refcodes.security.alt.chaos.ChaosTextDecrypterImpl;
import org.refcodes.security.alt.chaos.ChaosTextEncrypterImpl;
import org.refcodes.textual.Font;

/**
 * The {@link RuntimePropertiesImpl} composite represent command line
 * properties, system properties as well as environment variables (in that
 * order) and resource properties.
 * 
 * The {@link RuntimePropertiesImpl} are actually constructed from
 * {@link ArgsParserProperties}, {@link SystemProperties},
 * {@link EnvironmentProperties} and {@link ResourceProperties} instances (in
 * that precedence).
 * 
 * Add the {@link ResourceProperties} via the following methods
 * {@link #withFile(File)}, {@link #withFilePath(String)}, {@link #withUrl(URL)}
 * or {@link #withInputStream(InputStream)}.
 * 
 * Obfuscation may be applied to the properties as of the
 * {@link ObfuscationProperties} and {@link ObfuscationPropertiesBuilder} types.
 */
public class RuntimePropertiesImpl extends AbstractPropertiesDecorator implements RuntimeProperties {

	// /////////////////////////////////////////////////////////////////////////
	// STATICS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// CONSTANTS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private SystemProperties _systemProperties = new SystemProperties();
	private EnvironmentProperties _environmentProperties = new EnvironmentProperties();
	private ArgsParserProperties _argsParserProperties = null;
	private List _resourceProperties = new ArrayList<>();
	private PropertiesPrecedenceBuilder _propertiesPrecedence = new PropertiesPrecedenceBuilderComposite();
	private String _secret = toEncrypted( SystemContext.HOST.toContextSequence() );
	private boolean _isPostConstructed = false;
	private PolyglotPropertiesBuilderFactory _factory;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments. As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments when invoking
	 * {@link #withEvalArgs(String[])}.
	 */
	public RuntimePropertiesImpl() {
		this( new PolyglotPropertiesBuilderFactory() );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments.
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 */
	public RuntimePropertiesImpl( String[] aArgs ) {
		this( new PolyglotPropertiesBuilderFactory(), aArgs );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 */
	public RuntimePropertiesImpl( Condition aRootCondition ) {
		this( new PolyglotPropertiesBuilderFactory(), aRootCondition );
	}

	/**
	 * Constructs the {@link RuntimeProperties} with the given obfuscation mode
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( SystemContext aObfuscationMode ) {
		this( new PolyglotPropertiesBuilderFactory(), aObfuscationMode );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments. Also constructs the
	 * {@link RuntimeProperties} with the given obfuscation mode
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( String[] aArgs, SystemContext aObfuscationMode ) {
		this( new PolyglotPropertiesBuilderFactory(), aArgs, aObfuscationMode );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments. Also constructs
	 * the {@link RuntimeProperties} with the given obfuscation mode.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( Condition aRootCondition, SystemContext aObfuscationMode ) {
		this( new PolyglotPropertiesBuilderFactory(), aRootCondition, aObfuscationMode );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with a custom secret for
	 * obfuscation.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( String aSecret ) {
		this( new PolyglotPropertiesBuilderFactory(), aSecret );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments. Also constructs a
	 * {@link RuntimeProperties} instance with a custom secret for obfuscation.
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( String[] aArgs, String aSecret ) {
		this( new PolyglotPropertiesBuilderFactory(), aArgs, aSecret );
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments. Also constructs a
	 * {@link RuntimeProperties} instance with a custom secret for obfuscation.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( Condition aRootCondition, String aSecret ) {
		this( new PolyglotPropertiesBuilderFactory(), aRootCondition, aSecret );
	}

	// -------------------------------------------------------------------------

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments. As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments when invoking
	 * {@link #withEvalArgs(String[])}.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory ) {
		_argsParserProperties = new ArgsParserPropertiesImpl();
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, String[] aArgs ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aArgs );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, Condition aRootCondition ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aRootCondition );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs the {@link RuntimeProperties} with the given obfuscation mode
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, SystemContext aObfuscationMode ) {
		_argsParserProperties = new ArgsParserPropertiesImpl();
		_secret = toEncrypted( aObfuscationMode.toContextSequence() );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments. Also constructs the
	 * {@link RuntimeProperties} with the given obfuscation mode
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, String[] aArgs, SystemContext aObfuscationMode ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aArgs );
		_secret = toEncrypted( aObfuscationMode.toContextSequence() );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments. Also constructs
	 * the {@link RuntimeProperties} with the given obfuscation mode.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 * 
	 * @param aObfuscationMode The {@link SystemContext} specifies which level
	 *        of obfuscation is to be used when encountering upon obfuscated
	 *        properties: E.g. obfuscation may be bound to the host, the
	 *        "secret" used for obfuscation being the same for all applications
	 *        on the same host or obfuscation may be bound to the application,
	 *        being different for different applications on the same host.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, Condition aRootCondition, SystemContext aObfuscationMode ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aRootCondition );
		_secret = toEncrypted( aObfuscationMode.toContextSequence() );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with a custom secret for
	 * obfuscation.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, String aSecret ) {
		_argsParserProperties = new ArgsParserPropertiesImpl();
		_secret = toEncrypted( aSecret );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with no {@link Condition}
	 * for parsing command line arguments: As no syntax notation is required by
	 * the constructor (no root {@link Condition}), no syntax validation is
	 * done. Therefore the properties are heuristically determined from the
	 * provided command line arguments. Also constructs a
	 * {@link RuntimeProperties} instance with a custom secret for obfuscation.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aArgs The command line arguments to be evaluated.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, String[] aArgs, String aSecret ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aArgs );
		_secret = toEncrypted( aSecret );
		_factory = aPropertiesBuilderFactory;
	}

	/**
	 * Constructs a {@link RuntimeProperties} instance with the given
	 * {@link Condition} used to parse command line arguments. Also constructs a
	 * {@link RuntimeProperties} instance with a custom secret for obfuscation.
	 *
	 * @param aPropertiesBuilderFactory The factory to use when constructing
	 *        {@link ResourceProperties} instances.
	 * 
	 * @param aRootCondition The root condition being the node from which
	 *        parsing the command line arguments starts. Parse the command line
	 *        arguments via {@link #evalArgs(String[])}.
	 * 
	 * @param aSecret The secret to be used when encountering upon obfuscated
	 *        properties.
	 */
	public RuntimePropertiesImpl( PolyglotPropertiesBuilderFactory aPropertiesBuilderFactory, Condition aRootCondition, String aSecret ) {
		_argsParserProperties = new ArgsParserPropertiesImpl( aRootCondition );
		_secret = toEncrypted( aSecret );
		_factory = aPropertiesBuilderFactory;
	}

	// -------------------------------------------------------------------------

	/**
	 * After constructor execution do a post construct.
	 */
	private void postConstruct() {
		if ( !_isPostConstructed ) {
			synchronized ( this ) {
				if ( !_isPostConstructed ) {
					_propertiesPrecedence.prependProperties( toObfuscationProperties( _environmentProperties ) );
					_propertiesPrecedence.prependProperties( toObfuscationProperties( _systemProperties ) );
					_propertiesPrecedence.prependProperties( toObfuscationProperties( _argsParserProperties ) );
					for ( ResourceProperties eProperties : _resourceProperties ) {
						if ( !_propertiesPrecedence.containsProperties( eProperties ) ) {
							_propertiesPrecedence.appendProperties( new ObfuscationPropertiesDecorator( eProperties, toDecrypted( _secret ) ) );
						}
					}
					setProperties( new ProfilePropertiesProjection( _propertiesPrecedence ) );
					_isPostConstructed = true;
				}
			}
		}
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getCopyrightNote() {
		return _argsParserProperties.getCopyrightNote();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getDescription() {
		return _argsParserProperties.getDescription();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getLicenseNote() {
		return _argsParserProperties.getLicenseNote();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setRootCondition( Condition aRootCondition ) {
		if ( _isPostConstructed ) {
			throw new IllegalStateException( "The runtime properties have already been post-constructed as the properties have already been accessed, you must call this method before first accessing any property!" );
		}
		_argsParserProperties = new ArgsParserPropertiesImpl( aRootCondition );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSecret( String aSecret ) {
		if ( _isPostConstructed ) {
			throw new IllegalStateException( "The runtime properties have already been post-constructed as the properties have already been accessed, you must call this method before first accessing any property!" );
		}
		_secret = toEncrypted( aSecret );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setObfuscationMode( SystemContext aObfuscationMode ) {
		if ( _isPostConstructed ) {
			throw new IllegalStateException( "The runtime properties have already been post-constructed as the properties have already been accessed, you must call this method before first accessing any property!" );
		}
		_secret = toEncrypted( aObfuscationMode.toContextSequence() );
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withProperties( Properties aProperties ) {
		addProperties( aProperties );
		return this;
	}

	protected void addProperties( Properties aProperties ) {
		if ( aProperties instanceof ResourcePropertiesBuilder ) {
			try {
				ObfuscationResourcePropertiesBuilder theObfuscation = new ObfuscationResourcePropertiesBuilderDecorator( (ResourcePropertiesBuilder) aProperties, toDecrypted( _secret ) );
				_resourceProperties.add( theObfuscation );
				_propertiesPrecedence.appendProperties( theObfuscation );
			}
			catch ( OpenException e ) {
				_resourceProperties.add( (ResourceProperties) aProperties );
				_propertiesPrecedence.appendProperties( aProperties );
			}
		}
		else if ( aProperties instanceof ResourceProperties ) {
			ObfuscationProperties theObfuscation = new ObfuscationPropertiesDecorator( (ResourceProperties) aProperties, toDecrypted( _secret ) );
			_resourceProperties.add( (ResourceProperties) aProperties );
			_propertiesPrecedence.appendProperties( theObfuscation );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withFile( File aFile, ConfigLocator aConfigLocator, char... aDelimiters ) throws IOException, ParseException {
		addProperties( aFile, aConfigLocator, aDelimiters );
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withInputStream( InputStream aInputStream, char... aDelimiters ) throws IOException, ParseException {
		addProperties( aInputStream, aDelimiters );
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withFilePath( Class aResourceClass, String aFilePath, ConfigLocator aConfigLocator, char... aDelimiters ) throws IOException, ParseException {
		addProperties( aResourceClass, aFilePath, aConfigLocator, aDelimiters );
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withUrl( URL aUrl, char... aDelimiters ) throws IOException, ParseException {
		addProperties( aUrl, aDelimiters );
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public RuntimeProperties withParseArgs( String[] aArgs ) throws UnknownArgsException, AmbiguousArgsException, SuperfluousArgsException, ParseArgsException {
		evalArgs( aArgs );
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void errorLn( String aLine ) {
		_argsParserProperties.errorLn( aLine );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List> evalArgs( List aArgs ) throws UnknownArgsException, AmbiguousArgsException, SuperfluousArgsException, ParseArgsException {
		return _argsParserProperties.evalArgs( aArgs );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List> evalArgs( String aToPath, List aArgs ) throws UnknownArgsException, AmbiguousArgsException, SuperfluousArgsException, ParseArgsException {
		return _argsParserProperties.evalArgs( aToPath, aArgs );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List> evalArgs( String aToPath, String[] aArgs ) throws UnknownArgsException, AmbiguousArgsException, SuperfluousArgsException, ParseArgsException {
		return _argsParserProperties.evalArgs( aToPath, aArgs );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List> evalArgs( String[] aArgs ) throws UnknownArgsException, AmbiguousArgsException, SuperfluousArgsException, ParseArgsException {
		return _argsParserProperties.evalArgs( aArgs );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Condition getRootCondition() {
		return _argsParserProperties.getRootCondition();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printBanner() {
		_argsParserProperties.printBanner();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printCopyrightNote() {
		_argsParserProperties.printCopyrightNote();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printDescription() {
		_argsParserProperties.printDescription();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printHelp() {
		_argsParserProperties.printHelp();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printLicenseNote() {
		_argsParserProperties.printLicenseNote();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printLn() {
		_argsParserProperties.printLn();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printLn( String aLine ) {
		_argsParserProperties.printLn( aLine );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printOptions() {
		_argsParserProperties.printOptions();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printSeparatorLn() {
		_argsParserProperties.printSeparatorLn();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void printUsage() {
		_argsParserProperties.printUsage();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void reset() {
		_argsParserProperties.reset();

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setBannerFont( Font aBannerFont ) {
		_argsParserProperties.setBannerFont( aBannerFont );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setBannerFontPalette( char[] aColorPalette ) {
		_argsParserProperties.setBannerFontPalette( aColorPalette );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setConsoleWidth( int aConsoleWidth ) {
		_argsParserProperties.setConsoleWidth( aConsoleWidth );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setCopyrightNote( String aCopyrightNote ) {
		_argsParserProperties.setCopyrightNote( aCopyrightNote );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setDescription( String aDescription ) {
		_argsParserProperties.setDescription( aDescription );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setErrorOut( PrintStream aErrorOut ) {
		_argsParserProperties.setErrorOut( aErrorOut );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setLicenseNote( String aLicenseNote ) {
		_argsParserProperties.setLicenseNote( aLicenseNote );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setLineBreak( String aLineBreak ) {
		_argsParserProperties.setLineBreak( aLineBreak );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setMaxConsoleWidth( int aMaxConsoleWidth ) {
		_argsParserProperties.setMaxConsoleWidth( aMaxConsoleWidth );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setName( String aName ) {
		_argsParserProperties.setName( aName );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSeparatorChar( char aSeparatorChar ) {
		_argsParserProperties.setSeparatorChar( aSeparatorChar );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setStandardOut( PrintStream aStandardOut ) {
		_argsParserProperties.setStandardOut( aStandardOut );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSyntaxNotation( SyntaxNotation aSyntaxNotation ) {
		_argsParserProperties.setSyntaxNotation( aSyntaxNotation );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setTitle( String aTitle ) {
		_argsParserProperties.setTitle( aTitle );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setUsageLabel( String aUsageLabel ) {
		_argsParserProperties.setUsageLabel( aUsageLabel );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Properties reload() throws IOException, IllegalStateException, ParseException {
		PropertiesBuilder theProperties = new PropertiesBuilderImpl();
		for ( int i = _resourceProperties.size() - 1; i >= 0; i-- ) {
			theProperties.insert( _resourceProperties.get( i ).reload() );
		}
		return theProperties;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Properties reload( ReloadMode aReloadMode ) throws IOException, IllegalStateException, ParseException {
		PropertiesBuilder theProperties = new PropertiesBuilderImpl();
		for ( int i = _resourceProperties.size() - 1; i >= 0; i-- ) {
			theProperties.insert( _resourceProperties.get( i ).reload( aReloadMode ) );
		}
		return theProperties;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public char getDelimiter() {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.getDelimiter();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int size() {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.size();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean containsKey( Object aKey ) {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.containsKey( aKey );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isEmpty() {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.isEmpty();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String get( Object aKey ) {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.get( aKey );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Set keySet() {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.keySet();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Collection values() {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.values();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Properties retrieveFrom( String aFromPath ) {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.retrieveFrom( aFromPath );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Properties retrieveTo( String aToPath ) {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.retrieveTo( aToPath );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Object toDataStructure( String aFromPath ) {
		if ( getProperties() == null ) {
			throw new IllegalStateException( "You must properly construct and then initialize your instance via #postConstruct() !" );
		}
		return super.toDataStructure( aFromPath );
	}

	/**
	 * Returns the serialized format as of the {@link ResourcePropertiesBuilder}
	 * instance being produced upon invocation of the
	 * {@link PolyglotPropertiesBuilderFactory#toProperties(Properties)} method.
	 * 
	 * {@inheritDoc}
	 */
	@Override
	public String toSerialized() {
		return _factory.toProperties( this ).toSerialized();
	}

	/**
	 * Returns the serialized format as of the {@link ResourcePropertiesBuilder}
	 * instance being produced upon invocation of the
	 * {@link PolyglotPropertiesBuilderFactory#toProperties(Properties)} method.
	 * 
	 * {@inheritDoc}
	 */
	@Override
	public String toSerialized( char aDelimiter ) {
		return _factory.toProperties( this ).toSerialized( aDelimiter );
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Properties toRuntimeProfile( String... aProfiles ) {
		Properties theSysProperties = (toObfuscationProperties( _systemProperties ));
		Properties theEnvProperties = (toObfuscationProperties( _environmentProperties ));
		Properties theArgsProperties = (toObfuscationProperties( _argsParserProperties ));
		return new PropertiesPrecedenceComposite( theSysProperties, theEnvProperties, theArgsProperties, RuntimeProperties.super.toRuntimeProfile( aProfiles ) );
	}

	// /////////////////////////////////////////////////////////////////////////
	// HOOKS:
	// /////////////////////////////////////////////////////////////////////////

	@Override
	protected Properties getProperties() {
		if ( !_isPostConstructed ) {
			postConstruct();
		}
		return super.getProperties();
	}

	// /////////////////////////////////////////////////////////////////////////
	// HELPER:
	// /////////////////////////////////////////////////////////////////////////

	private ObfuscationPropertiesDecorator toObfuscationProperties( Properties aProperties ) {
		return new ObfuscationPropertiesDecorator( aProperties, toDecrypted( _secret ) );
	}

	private String toEncrypted( String aValue ) {
		try {
			return new ChaosTextEncrypterImpl( new ChaosKeyImpl( SystemContext.HOST_USER_APPLICATION_SESSION.toContextSequence() ) ).toEncrypted( aValue );
		}
		catch ( EncryptionException e ) {
			throw new BugException( e.getMessage(), e );
		}
	}

	private String toDecrypted( String aValue ) {
		try {
			return new ChaosTextDecrypterImpl( new ChaosKeyImpl( SystemContext.HOST_USER_APPLICATION_SESSION.toContextSequence() ) ).toDecrypted( aValue );
		}
		catch ( DecryptionException e ) {
			throw new BugException( e.getMessage(), e );
		}
	}

	/**
	 * Reads the {@link ResourcePropertiesBuilder} from the given data sink.
	 * 
	 * @param aFile The data sink from which to read the
	 *        {@link ResourcePropertiesBuilder}.
	 * 
	 * @param aConfigLocator The {@link ConfigLocator} specifying where to seek
	 *        for properties.
	 * 
	 * @param aDelimiters The delimiters in the properties file to identity a
	 *        path delimiter.
	 * 
	 * @throws IOException Thrown in case there were problems reading the data
	 *         sink.
	 * 
	 * @throws ParseException Thrown in case there were problems parsing the
	 *         data from the data sink.
	 */
	protected void addProperties( File aFile, ConfigLocator aConfigLocator, char... aDelimiters ) throws IOException, ParseException {
		ResourcePropertiesBuilder theProperties = _factory.toProperties( aFile, aConfigLocator, aDelimiters );
		try {
			theProperties = new ObfuscationResourcePropertiesBuilderDecorator( theProperties, toDecrypted( _secret ) );
		}
		catch ( OpenException ignore ) {}
		_resourceProperties.add( theProperties );
		_propertiesPrecedence.appendProperties( new ObfuscationPropertiesDecorator( theProperties, toDecrypted( _secret ) ) );
	}

	/**
	 * Reads the {@link ResourceProperties} from the given data sink.
	 * 
	 * @param aInputStream The data sink from which to read the
	 *        {@link ResourceProperties}.
	 * 
	 * @param aDelimiters The delimiters in the properties file to identity a
	 *        path delimiter.
	 * 
	 * @throws IOException Thrown in case there were problems reading the data
	 *         sink.
	 * 
	 * @throws ParseException Thrown in case there were problems parsing the
	 *         data from the data sink.
	 */
	protected void addProperties( InputStream aInputStream, char[] aDelimiters ) throws IOException, ParseException {
		ResourceProperties theProperties = _factory.toProperties( aInputStream, aDelimiters );
		_resourceProperties.add( theProperties );
		_propertiesPrecedence.appendProperties( new ObfuscationPropertiesDecorator( theProperties, toDecrypted( _secret ) ) );
	}

	/**
	 * Reads the {@link ResourcePropertiesBuilder} from the given data sink.
	 * 
	 * @param aResourceClass The class which's class loader is to take care of
	 *        loading the properties (from inside a JAR).
	 * 
	 * @param aFilePath The data sink from which to read the
	 *        {@link ResourcePropertiesBuilder}.
	 * 
	 * @param aConfigLocator The {@link ConfigLocator} specifying where to seek
	 *        for properties.
	 * 
	 * @param aDelimiters The delimiters in the properties file to identity a
	 *        path delimiter.
	 * 
	 * @throws IOException Thrown in case there were problems reading the data
	 *         sink.
	 * 
	 * @throws ParseException Thrown in case there were problems parsing the
	 *         data from the data sink.
	 */
	protected void addProperties( Class aResourceClass, String aFilePath, ConfigLocator aConfigLocator, char... aDelimiters ) throws IOException, ParseException {
		ResourcePropertiesBuilder theProperties = _factory.toProperties( aResourceClass, aFilePath, aConfigLocator, aDelimiters );
		try {
			theProperties = new ObfuscationResourcePropertiesBuilderDecorator( theProperties, toDecrypted( _secret ) );
		}
		catch ( OpenException ignore ) {}
		_resourceProperties.add( theProperties );
		_propertiesPrecedence.appendProperties( new ObfuscationPropertiesDecorator( theProperties, toDecrypted( _secret ) ) );
	}

	/**
	 * Reads the {@link ResourceProperties} from the given data sink.
	 * 
	 * @param aUrl The data sink from which to read the
	 *        {@link ResourceProperties}.
	 * 
	 * @param aDelimiters The delimiters in the properties file to identity a
	 *        path delimiter.
	 * 
	 * @throws IOException Thrown in case there were problems reading the data
	 *         sink.
	 * 
	 * @throws ParseException Thrown in case there were problems parsing the
	 *         data from the data sink.
	 */
	protected void addProperties( URL aUrl, char... aDelimiters ) throws IOException, ParseException {
		ResourceProperties theProperties = _factory.toProperties( aUrl, aDelimiters );
		_resourceProperties.add( theProperties );
		_propertiesPrecedence.appendProperties( new ObfuscationPropertiesDecorator( theProperties, toDecrypted( _secret ) ) );
	}

	// /////////////////////////////////////////////////////////////////////////
	// INNER CLASSES:
	// /////////////////////////////////////////////////////////////////////////

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy