From 9f928d930f635d66262c2c214b4fb49710a5a60c Mon Sep 17 00:00:00 2001 From: j2blake Date: Wed, 16 Oct 2013 17:21:41 -0400 Subject: [PATCH] VIVO-364 Include build.properties in ConfigurationProperties The language-setup smoke tests assumed that we had access to build.properties. --- .../config/ConfigurationPropertiesImpl.java | 23 ++-- .../config/ConfigurationPropertiesSetup.java | 102 ++++++++++-------- .../ConfigurationPropertiesSmokeTests.java | 6 +- 3 files changed, 69 insertions(+), 62 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesImpl.java index f4e4a13ab..9389ea6d3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesImpl.java @@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.config; import java.io.IOException; import java.io.InputStream; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -18,7 +17,8 @@ import org.apache.commons.logging.LogFactory; * The basic implementation of ConfigurationProperties. It loads the * configuration properties from a properties file and stores them in a map. It * also permits the caller to supply a map of "preemptive" properties that will - * be included and will override any matching properties from the file. + * be included and will override any matching properties from the file, and a + * map of "build" properties that may be overridden by the file. * * Leading and trailing white space are trimmed from the property values. * @@ -31,9 +31,14 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties { private final Map propertyMap; public ConfigurationPropertiesImpl(InputStream stream, - Map preemptiveProperties) throws IOException { + Map preemptiveProperties, + Map buildProperties) throws IOException { + Map map = new HashMap<>(buildProperties); + Properties props = loadFromPropertiesFile(stream); - Map map = copyPropertiesToMap(props); + for (String key: props.stringPropertyNames()) { + map.put(key, props.getProperty(key)); + } if (preemptiveProperties != null) { map.putAll(preemptiveProperties); @@ -52,16 +57,6 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties { return props; } - private Map copyPropertiesToMap(Properties props) { - Map map = new HashMap(); - for (Enumeration keys = props.keys(); keys.hasMoreElements();) { - String key = (String) keys.nextElement(); - String value = props.getProperty(key); - map.put(key, value); - } - return map; - } - private void trimWhiteSpaceFromValues(Map map) { for (String key : map.keySet()) { map.put(key, map.get(key).trim()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java index abc704697..55b00be17 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java @@ -29,20 +29,20 @@ import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; * This must be invoked before any listener that requires configuration * properties. * - * The properties file must be called 'runtime.properties' in the Vitro home - * directory. The path to the Vitro home directory can be specifed by an JNDI - * value, or by a System property, or by a property in - * WEB-INF/resources/build.properties, in that order. If the Vitro home - * directory is specified in more than one way, a warning is issued and the - * first value is used. + * The properties are determined from a file called 'build.properties' in the + * resources directory of the webapp, and a file called 'runtime.properties' in + * the Vitro home directory. In case of conflict, runtime.properties wins. * - * If the Vitro home directory cannot be located, or if it does not contain a - * file called 'runtime.properties', or if the file cannot be loaded, a fatal - * error is registered to abort the startup. + * The path to the Vitro home directory can be specifed by an JNDI value, or by + * a System property, or by a property in build.properties, in that order. If + * the Vitro home directory is specified in more than one way, a warning is + * issued and the first value is used. * - * The ConfigurationProperties bean is created from the key/value pairs found in - * 'runtime.properties', and is stored in the servlet context. The value that - * was determined for 'vitro.home' is also included in the bean. + * The value that was determined for 'vitro.home' is also included in the + * ConfigurationProperties bean. + * + * If build.properties or runtime.properties cannot be located or loaded, a + * fatal error is registered to abort the startup. */ public class ConfigurationPropertiesSetup implements ServletContextListener { private static final Log log = LogFactory @@ -63,6 +63,9 @@ public class ConfigurationPropertiesSetup implements ServletContextListener { /** Name of the file that contains runtime properties. */ private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties"; + /** Path to the file of build properties baked into the webapp. */ + private static final String PATH_BUILD_PROPERTIES = "/WEB-INF/resources/build.properties"; + @Override public void contextInitialized(ServletContextEvent sce) { ServletContext ctx = sce.getServletContext(); @@ -79,8 +82,9 @@ public class ConfigurationPropertiesSetup implements ServletContextListener { Map preempts = createPreemptiveProperties( VHD_CONFIGURATION_PROPERTY, vitroHomeDir); + ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl( - stream, preempts); + stream, preempts, getBuildProperties(ctx)); ConfigurationProperties.setBean(ctx, bean); ss.info(this, "Loaded " + bean.getPropertyMap().size() @@ -94,8 +98,6 @@ public class ConfigurationPropertiesSetup implements ServletContextListener { } } } - } catch (IllegalStateException e) { - ss.fatal(this, e.getMessage(), e); } catch (Exception e) { ss.fatal(this, e.getMessage(), e); } @@ -196,42 +198,44 @@ public class ConfigurationPropertiesSetup implements ServletContextListener { private void getVhdFromBuildProperties(ServletContext ctx, Map whereWasIt) { - String resourcePath = "/WEB-INF/resources/build.properties"; + Map buildProps = getBuildProperties(ctx); + String vhdPath = buildProps.get(VHD_BUILD_PROPERTY); + if (vhdPath == null) { + log.debug("'" + PATH_BUILD_PROPERTIES + + "' didn't contain a value for '" + VHD_BUILD_PROPERTY + + "'."); + return; + } - InputStream stream = null; - try { - stream = ctx.getResourceAsStream(resourcePath); + log.debug("'" + VHD_BUILD_PROPERTY + + "' as specified by build.properties: " + vhdPath); + String message = String.format( + "In resource '%s', '%s' was set to '%s'.", + PATH_BUILD_PROPERTIES, VHD_BUILD_PROPERTY, vhdPath); + whereWasIt.put(message, vhdPath); + } + + private Map getBuildProperties(ServletContext ctx) { + Map map = new HashMap<>(); + + try (InputStream stream = ctx + .getResourceAsStream(PATH_BUILD_PROPERTIES)) { if (stream == null) { - log.debug("Didn't find a resource at '" + resourcePath + "'."); - return; - } + log.debug("Didn't find a resource at '" + PATH_BUILD_PROPERTIES + + "'."); + } else { - Properties props = new Properties(); - props.load(stream); - String vhdPath = props.getProperty(VHD_BUILD_PROPERTY); - if (vhdPath == null) { - log.debug("'" + resourcePath + "' didn't contain a value for '" - + VHD_BUILD_PROPERTY + "'."); - return; - } - - log.debug("'" + VHD_BUILD_PROPERTY - + "' as specified by build.properties: " + vhdPath); - String message = String.format( - "In resource '%s', '%s' was set to '%s'.", resourcePath, - VHD_BUILD_PROPERTY, vhdPath); - whereWasIt.put(message, vhdPath); - } catch (IOException e) { - log.warn("Failed to load from '" + resourcePath + "'.", e); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (IOException e) { - e.printStackTrace(); + Properties props = new Properties(); + props.load(stream); + for (String key : props.stringPropertyNames()) { + map.put(key, props.getProperty(key)); } } + } catch (IOException e) { + throw new SetupException("Failed to load from '" + + PATH_BUILD_PROPERTIES + "'.", e); } + return map; } private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) { @@ -266,4 +270,12 @@ public class ConfigurationPropertiesSetup implements ServletContextListener { ConfigurationProperties.removeBean(sce.getServletContext()); } + /** + * Indicates a problem setting up. Abandon ship. + */ + private static class SetupException extends RuntimeException { + public SetupException(String message, Throwable cause) { + super(message, cause); + } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSmokeTests.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSmokeTests.java index 3f0419cfa..e3b534737 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSmokeTests.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSmokeTests.java @@ -298,13 +298,13 @@ public class ConfigurationPropertiesSmokeTests implements */ private void checkLanguages(ConfigurationProperties props, StartupStatus ss) { String buildString = props.getProperty(PROPERTY_LANGUAGE_BUILD); - boolean buildWithLanguages = StringUtils.isNotEmpty(buildString); + boolean buildWithLanguages = StringUtils.isNotBlank(buildString); String selectString = props.getProperty(PROPERTY_LANGUAGE_SELECTABLE); - boolean selectableLanguages = StringUtils.isNotEmpty(selectString); + boolean selectableLanguages = StringUtils.isNotBlank(selectString); String forceString = props.getProperty(PROPERTY_LANGUAGE_FORCE); - boolean forceLanguage = StringUtils.isNotEmpty(forceString); + boolean forceLanguage = StringUtils.isNotBlank(forceString); String filterString = props.getProperty(PROPERTY_LANGUAGE_FILTER, "true");