/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geowebcache;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
import org.springframework.core.Constants;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
/**
* Utility class uses to process GeoWebCache configuration workflow through external environment variables.
*
* This class must be used everytime we need to resolve a configuration placeholder at runtime.
* <p>
* An instance of this class needs to be registered in spring context as follows.
*
* <pre>
* <code>
* <bean id="geoWebCacheEnvironment" class="org.geowebcache.GeoWebCacheEnvironment" depends-on="geoWebCacheExtensions"/>
* </code>
* </pre>
*
* It must be a singleton, and must not be loaded lazily. Furthermore, this bean must be loaded before any beans that use it.
*
* @author Alessio Fabiani, GeoSolutions
*
*/
public class GeoWebCacheEnvironment {
/**
* logger
*/
public static Log LOGGER = LogFactory.getLog(GeoWebCacheEnvironment.class);
private static final Constants constants = new Constants(PlaceholderConfigurerSupport.class);
/**
* Constant set via System Environment in order to instruct GeoWebCache to make use or not of the config placeholders translation.
*
* Default to FALSE
*/
public final static boolean ALLOW_ENV_PARAMETRIZATION = Boolean
.valueOf(GeoWebCacheExtensions.getProperty("ALLOW_ENV_PARAMETRIZATION"));
private static final String nullValue = "null";
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper(
constants.asString("DEFAULT_PLACEHOLDER_PREFIX"),
constants.asString("DEFAULT_PLACEHOLDER_SUFFIX"),
constants.asString("DEFAULT_VALUE_SEPARATOR"), true);
private final PlaceholderResolver resolver = new PlaceholderResolver() {
@Override
public String resolvePlaceholder(String placeholderName) {
return GeoWebCacheEnvironment.this.resolvePlaceholder(placeholderName);
}
};
private Properties props;
/**
* Internal "props" getter method.
*
* @return the props
*/
public Properties getProps() {
return props;
}
/**
* Internal "props" setter method.
*
* @param props the props to set
*/
public void setProps(Properties props) {
this.props = props;
}
protected String resolvePlaceholder(String placeholder) {
String propVal = null;
propVal = resolveSystemProperty(placeholder);
if (props != null && propVal == null) {
propVal = props.getProperty(placeholder);
}
return propVal;
}
protected String resolveSystemProperty(String key) {
try {
String value = GeoWebCacheExtensions.getProperty(key);
if (value == null) {
value = System.getenv(key);
}
return value;
} catch (Throwable ex) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Could not access system property '" + key + "': " + ex);
}
return null;
}
}
protected String resolveStringValue(String strVal) throws BeansException {
String resolved = this.helper.replacePlaceholders(strVal, this.resolver);
return (resolved.equals(nullValue) ? null : resolved);
}
/**
* Translates placeholders in the form of Spring Property placemark ${...}
* into their real values.
*
* The method first looks for System variables which take precedence on
* local ones, then into internal props injected through the applicationContext.
*
* @param value
* @return
*/
public Object resolveValue(Object value) {
if (value != null) {
if (value instanceof String) {
return resolveStringValue((String) value);
}
}
return value;
}
}