org.wisdom.configuration.ConfigurationImpl Maven / Gradle / Ivy
The newest version!
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* 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.
* #L%
*/
package org.wisdom.configuration;
import com.google.common.collect.ImmutableList;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigException;
import com.typesafe.config.ConfigResolveOptions;
import org.wisdom.api.configuration.Configuration;
import org.wisdom.api.content.ParameterFactories;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* An implementation of the configuration object based on Apache Commons Configuration.
* Unlike the main application configuration, this implementation does not used a logger.
*/
public class ConfigurationImpl implements Configuration {
private static final String ERROR_KEYNOTFOUND = "Key %s does not exist. Please include it in your application.conf. " +
"Otherwise this application will not work";
protected static final String ERROR_NOSUCHKEY = "No such key \"";
/**
* The parameter converter service, must be a proxy.
*/
protected ParameterFactories converters;
private Config configuration;
/**
* Creates an instance of {@link org.wisdom.configuration.ConfigurationImpl}.
*
* @param configuration the underlying configuration
*/
public ConfigurationImpl(ParameterFactories converters, Config configuration) {
this(converters);
this.configuration = configuration;
}
protected ConfigurationImpl(ParameterFactories converters) {
this.converters = converters;
// This constructor requires an invocation of setConfiguration.
}
protected void setConfiguration(Config configuration) {
this.configuration = configuration;
}
protected Config getConfiguration() {
return configuration;
}
/**
* Get a String property or null if it is not there...
*
* @param key the key
* @return the property of null if not there
*/
@Override
public String get(final String key) {
return retrieve(new Callable() {
@Override
public String call() throws Exception {
return configuration.getString(key);
}
}, null);
}
/**
* Checks whether the configuration object define a value at the given name / path.
* @param key the key / path
* @return {@code true} if the configuration has a non-null value, {@code false} otherwise
*/
public boolean has(String key) {
return configuration.hasPath(key);
}
private T retrieve(Callable callable, T defaultValue) {
try {
T v = callable.call();
return v != null ? v : defaultValue;
} catch (ConfigException.Missing e) {
return defaultValue;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Get a String property or a default value when property cannot be found in
* any configuration file.
*
* @param key the key used in the configuration file.
* @param defaultValue Default value returned, when value cannot be found in
* configuration.
* @return the value of the key or the default value.
*/
@Override
public String getWithDefault(final String key, String defaultValue) {
return retrieve(new Callable() {
@Override
public String call() throws Exception {
return configuration.getString(key);
}
}, defaultValue);
}
/**
* Get a property as Integer or null if not there / or property no integer.
*
* @param key the key
* @return the property or {@literal null} if not there or property no integer
*/
@Override
public Integer getInteger(final String key) {
return retrieve(new Callable() {
@Override
public Integer call() throws Exception {
return configuration.getInt(key);
}
}, null);
}
/**
* Get a Integer property or a default value when property cannot be found
* in any configuration file.
*
* @param key the key used in the configuration file.
* @param defaultValue Default value returned, when value cannot be found in
* configuration.
* @return the value of the key or the default value.
*/
@Override
public Integer getIntegerWithDefault(final String key, Integer defaultValue) {
return retrieve(new Callable() {
@Override
public Integer call() throws Exception {
return configuration.getInt(key);
}
}, defaultValue);
}
/**
* Get a property as Double or {@literal null} if not there / or if the property is not an integer.
*
* @param key the key used in the configuration file.
* @return the property or {@literal null} if not there or property no integer
*/
@Override
public Double getDouble(final String key) {
return retrieve(new Callable() {
@Override
public Double call() throws Exception {
return configuration.getDouble(key);
}
}, null);
}
/**
* Get a Double property or a default value when property cannot be found
* in any configuration file.
*
* @param key the key used in the configuration file.
* @param defaultValue Default value returned, when value cannot be found in
* configuration.
* @return the value of the key or the default value.
*/
@Override
public Double getDoubleWithDefault(final String key, Double defaultValue) {
return retrieve(new Callable() {
@Override
public Double call() throws Exception {
return configuration.getDouble(key);
}
}, defaultValue);
}
/**
* @param key the key
* @return the property or null if not there or property no boolean
*/
@Override
public Boolean getBoolean(final String key) {
return retrieve(new Callable() {
@Override
public Boolean call() throws Exception {
return configuration.getBoolean(key);
}
}, null);
}
/**
* Get a Boolean property or a default value when property cannot be found
* in any configuration file.
*
* @param key the key used in the configuration file.
* @param defaultValue Default value returned, when value cannot be found in
* configuration.
* @return the value of the key or the default value.
*/
@Override
public Boolean getBooleanWithDefault(final String key, Boolean defaultValue) {
return retrieve(new Callable() {
@Override
public Boolean call() throws Exception {
return configuration.getBoolean(key);
}
}, defaultValue);
}
@Override
public Long getLong(final String key) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getLong(key);
}
}, null);
}
@Override
public Long getLongWithDefault(final String key, Long defaultValue) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getLong(key);
}
}, defaultValue);
}
@Override
public Long getLongOrDie(String key) {
Long value = Long.getLong(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}
/**
* The "die" method forces this key to be set. Otherwise a runtime exception
* will be thrown.
*
* @param key the key
* @return the boolean or a IllegalArgumentException will be thrown.
*/
@Override
public Boolean getBooleanOrDie(String key) {
Boolean value = getBoolean(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}
/**
* The "die" method forces this key to be set. Otherwise a runtime exception
* will be thrown.
*
* @param key the key
* @return the Integer or a IllegalArgumentException will be thrown.
*/
@Override
public Integer getIntegerOrDie(String key) {
Integer value = getInteger(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}
/**
* The "die" method forces this key to be set. Otherwise a runtime exception
* will be thrown.
*
* @param key the key used in the configuration file.
* @return the Double or a RuntimeException will be thrown.
*/
@Override
public Double getDoubleOrDie(String key) {
Double value = getDouble(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}
/**
* The "die" method forces this key to be set. Otherwise a runtime exception
* will be thrown.
*
* @param key the key
* @return the String or a IllegalArgumentException will be thrown.
*/
@Override
public String getOrDie(String key) {
String value = get(key);
if (value == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
} else {
return value;
}
}
/**
* {@inheritDoc}
*/
public Long getDuration(final String key, final TimeUnit unit) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getDuration(key, unit);
}
}, null);
}
/**
* {@inheritDoc}
*/
@Override
public Long getDuration(final String key, final TimeUnit unit, long defaultValue) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getDuration(key, unit);
}
}, defaultValue);
}
/**
* {@inheritDoc}
*/
public Long getBytes(final String key) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getBytes(key);
}
}, null);
}
/**
* {@inheritDoc}
*/
public Long getBytes(final String key, long defaultValue) {
return retrieve(new Callable() {
@Override
public Long call() throws Exception {
return configuration.getBytes(key);
}
}, defaultValue);
}
/**
* Retrieves the values as a array of String, the format is: key=[myval1,myval2].
*
* @return an array containing the values of that key or empty if not found.
*/
@Override
public String[] getStringArray(final String key) {
List list = getList(key);
return list.toArray(new String[list.size()]);
}
//TODO List of other type.
/**
* Retrieves the values as a list of String, the format is: key=[myval1,myval2].
*
* @param key the key the key used in the configuration file.
* @return an list containing the values of that key or empty if not found.
*/
@Override
public List getList(final String key) {
return retrieve(new Callable>() {
@Override
public List call() throws Exception {
try {
return configuration.getStringList(key);
} catch (ConfigException.WrongType e) {
// Not a list.
String s = get(key);
if (s != null) {
return ImmutableList.of(s);
} else {
throw new IllegalArgumentException("Cannot create a list for the key '" + key + "'", e);
}
}
}
}, Collections.emptyList());
}
/**
* @return All properties that are currently loaded from internal and
* external files
*/
@Override
public Properties asProperties() {
Properties properties = new Properties();
properties.putAll(asMap());
return properties;
}
/**
* @return All properties that are currently loaded from internal and
* external files
*/
@Override
public Map asMap() {
return configuration
.resolve(ConfigResolveOptions.defaults().setUseSystemEnvironment(true).setAllowUnresolved(true))
.root()
.unwrapped();
}
/**
* Gets a configuration object with all the properties starting with the given prefix.
*
* @param prefix the prefix (without the ending `.`)
* @return a configuration object with all properties with a name starting with `prefix.`,
* or {@literal null} if no properties start with the given prefix.
*/
@Override
public Configuration getConfiguration(String prefix) {
try {
Config value = configuration.getConfig(prefix);
return new ConfigurationImpl(converters, value);
} catch (ConfigException.Missing e) {
// Ignore the exception.
return null;
}
}
@Override
public T get(String key, Class clazz) {
String value = get(key);
if (value == null) {
return null;
}
return converters.convertValue(value, clazz, clazz, null);
}
/**
* Get a custom type property. The object is created using the
* {@link org.wisdom.api.content.ParameterFactories} strategy. This "die" method forces this key to be set.
* Otherwise a runtime exception will be thrown.
*
* @param key the key the key used in the configuration file.
* @param clazz the class of the object to create
* @return the created object. The object cannot be created (because the property is missing,
* or because the conversion failed) a {@link RuntimeException} is thrown.
*/
@Override
public T getOrDie(String key, Class clazz) {
T val = get(key, clazz);
if (val == null) {
throw new IllegalArgumentException(String.format(ERROR_KEYNOTFOUND, key));
}
return val;
}
@Override
public T get(String key, Class clazz, T defaultValue) {
String value = get(key);
if (value == null) {
return defaultValue;
}
return converters.convertValue(value, clazz, clazz, null);
}
@Override
public T get(String key, Class clazz, String defaultValueAsString) {
String value = get(key);
return converters.convertValue(value, clazz, clazz, defaultValueAsString);
}
}