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

com.thetransactioncompany.util.PropertyRetriever Maven / Gradle / Ivy

Go to download

This package provides a Java utility for typed retrieval of java.util.Properties as boolean, integer, floating point, string, URL, URI and enum values.

There is a newer version: 2.0
Show newest version
package com.thetransactioncompany.util;


import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;


/**
 * Provides typed retrieval of {@link java.util.Properties} as {@code boolean}, 
 * {@code int}, {@code long}, {@code float}, {@code double}, 
 * {@link java.lang.String}, {@link java.net.URL}, {@link java.net.URI} or
 * {@code enum} values.
 *
 * @author Vladimir Dzhuvinov
 */
public class PropertyRetriever {

	
	/** 
	 * The properties to parse.
	 */
	private final Properties props;


	/**
	 * {@code true} if system property override has been enabled,
	 * {@code false} if it's disabled.
	 */
	private final boolean enableSysPropOverride;


	/**
	 * Creates a new retriever for the specified properties. System
	 * property override is disabled.
	 *
	 * @param props The properties. Must not be {@code null}.
	 */
	public PropertyRetriever(final Properties props) {
	
		this(props, false);
	}


	/**
	 * Creates a new retriever for the specified properties.
	 *
	 * @param props                 The properties. Must not be
	 *                              {@code null}.
	 * @param enableSysPropOverride If {@code true} if system properties
	 *                              with the same names are present they
	 *                              will override the specified properties,
	 *                              {@code false} to disable this
	 *                              behaviour.
	 */
	public PropertyRetriever(final Properties props, final boolean enableSysPropOverride) {

		this.props = new Properties();
		this.props.putAll(props);

		this.enableSysPropOverride = enableSysPropOverride;
		if (enableSysPropOverride) {
			// Overwrite
			this.props.putAll(System.getProperties());
		}
	}


	/**
	 * Gets the system property override setting.
	 *
	 * @return {@code true} if system property override has been enabled,
	 *         {@code false} if it's disabled.
	 */
	public boolean systemPropertyOverrideIsEnabled() {

		return enableSysPropOverride;
	}
	
	
	/**
	 * Retrieves a boolean value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a boolean value.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public boolean getBoolean(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		if (value.equalsIgnoreCase("true"))
			return true;
		
		else if (value.equalsIgnoreCase("false"))
			return false;
		
		else
			throw new PropertyParseException("Invalid boolean property", key, value);
	}
	
	
	/**
	 * Retrieves an optional boolean value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a boolean.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public boolean getOptBoolean(final String key, final boolean def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		if (value.equalsIgnoreCase("true"))
			return true;
		
		if (value.equalsIgnoreCase("false"))
			return false;
		
		throw new PropertyParseException("Invalid boolean property", key, value);
	}
	
	
	/**
	 * Retrieves an integer value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as an integer.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public int getInt(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return Integer.parseInt(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid int property", key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional integer value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as an integer.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public int getOptInt(final String key, final int def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return Integer.parseInt(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid int property", key);
		}
	}
	
	
	/**
	 * Retrieves a long value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a long.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public long getLong(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return Long.parseLong(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid long property", key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional long value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a long.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public long getOptLong(final String key, final long def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return Long.parseLong(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid long property", key, value);
		}
	}
	
	
	/**
	 * Retrieves a float value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a float.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public float getFloat(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return Float.parseFloat(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid float property", key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional float value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a float.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public float getOptFloat(final String key, final float def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return Float.parseFloat(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid float property", key, value);
		}
	}
	
	
	/**
	 * Retrieves a double value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a double.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public double getDouble(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return Double.parseDouble(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid double property", key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional double value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a double.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public double getOptDouble(final String key, final double def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return Double.parseDouble(value);
		
		} catch (NumberFormatException e) {

			throw new PropertyParseException("Invalid double property", key, value);
		}
	}
	
	
	/**
	 * Retrieves a string value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a string.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public String getString(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		return value;
	}
	
	
	/**
	 * Retrieves an optional string value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a string.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public String getOptString(final String key, final String def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		return value;
	}
	
	
	/**
	 * Retrieves an enumerated string value. String case is ignored during
	 * comparison.
	 *
	 * @param key   The property name.
	 * @param enums A string array defining the acceptable values.
	 *
	 * @return The property as a string.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public String getEnumString(final String key, final String[] enums)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		for (String en: enums) {
			
			if (en.equalsIgnoreCase(value))
				return value;
		}
			
		throw new PropertyParseException("Invalid enum string property", key, value);
	}
	
	
	/**
	 * Retrieves an enumerated string value. String case is ignored during
	 * comparison.
	 *
	 * @param key   The property name.
	 * @param enums A string array defining the acceptable values.
	 * @param def   The default value if the property value is undefined or
	 *              empty.
	 *
	 * @return The property as a string.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public String getOptEnumString(final String key, final String[] enums, final String def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		for (String en: enums) {
			
			if (en.equalsIgnoreCase(value))
				return value;
		}
			
		throw new PropertyParseException("Invalid enum string property", key, value);
	}
	
	
	/**
	 * Retrieves an enumerated constant. String case is ignored during
	 * comparison.
	 *
	 * @param key       The property name.
	 * @param enumClass The enumeration class specifying the acceptable
	 *                  values.
	 *
	 * @return The matching enumerated constant.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public > T getEnum(final String key, final Class enumClass)
		throws PropertyParseException {
		
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
			
		for (T en: enumClass.getEnumConstants()) {
		
			if (en.toString().equalsIgnoreCase(value))
				return en;
		}
		
		// No match? -> raise exception
		throw new PropertyParseException("Invalid enum property", key, value);
	}
	
	
	/**
	 * Retrieves an optional enumerated constant. String case is ignored
	 * during comparison.
	 *
	 * @param key       The property name.
	 * @param enumClass The enumeration class specifying the acceptable
	 *                  values.
	 * @param def       The default value if the property value is 
	 *                  undefined or empty.
	 *
	 * @return The matching enumerated constant.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public > T getOptEnum(final String key, final Class enumClass, final T def)
		throws PropertyParseException {
		
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
			
		for (T en: enumClass.getEnumConstants()) {
		
			if (en.toString().equalsIgnoreCase(value))
				return en;
		}
		
		// No match? -> raise exception
		throw new PropertyParseException("Invalid enum property", key, value);
	}
	
	
	/**
	 * Retrieves a string list consisting of one or more comma / space
	 * separated items.
	 *
	 * @param key The property name.
	 *
	 * @return The string list with at least one item.
	 *
	 * @throws PropertyParseException On a missing or empty property.
	 */
	public List getStringList(final String key)
		throws PropertyParseException {
		
		String s = getString(key);
		
		StringTokenizer st = new StringTokenizer(s, ", ");
		List out = new LinkedList<>();
		while (st.hasMoreElements()) {
			out.add(st.nextToken());
		}
		
		if (out.isEmpty()) {
			throw new PropertyParseException("Empty string list", key, s);
		}
		
		return out;
	}
	
	
	/**
	 * Retrieves an optional string list consisting of zero or more comma /
	 * space separated items.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The string list with zero or more items.
	 *
	 * @throws PropertyParseException On a invalid property.
	 */
	public List getOptStringList(final String key, final List def)
		throws PropertyParseException {
		
		String s = getOptString(key, null);
		
		if (s == null) {
			return def;
		}
		
		StringTokenizer st = new StringTokenizer(s, ", ");
		List out = new LinkedList<>();
		while (st.hasMoreElements()) {
			out.add(st.nextToken());
		}
		
		if (out.isEmpty()) {
			return def;
		}
		
		return out;
	}
	
	
	/**
	 * Retrieves a string list consisting of one or more comma / space
	 * separated items from a enumeration.
	 *
	 * @param key   The property name.
	 * @param enums A string array defining the acceptable values.
	 *
	 * @return The string list with at least one item.
	 *
	 * @throws PropertyParseException On a missing or empty property.
	 */
	public List getEnumStringList(final String key, final String[] enums)
		throws PropertyParseException {
		
		return getEnumStringList(key, Arrays.asList(enums));
	}
	
	
	/**
	 * Retrieves an optional string list consisting of zero or more comma /
	 * space separated items from a enumeration.
	 *
	 * @param key   The property name.
	 * @param enums A string array defining the acceptable values.
	 * @param def   The default value if the property value is undefined or
	 *              empty.
	 *
	 * @return The string list with zero or more items.
	 *
	 * @throws PropertyParseException On a invalid property.
	 */
	public List getOptEnumStringList(final String key, final String[] enums, final List def)
		throws PropertyParseException {
		
		return getOptEnumStringList(key, Arrays.asList(enums), def);
	}
	
	
	/**
	 * Retrieves a string list consisting of one or more comma / space
	 * separated items from a enumeration.
	 *
	 * @param key   The property name.
	 * @param enums A string list defining the acceptable values.
	 *
	 * @return The string list with at least one item.
	 *
	 * @throws PropertyParseException On a missing or empty property.
	 */
	public List getEnumStringList(final String key, final List enums)
		throws PropertyParseException {
		
		List out = getStringList(key);
		
		for (String v: out) {
			if (! enums.contains(v)) {
				throw new PropertyParseException("Invalid enum string list property: " + v, key, props.getProperty(key));
			}
		}
		
		return out;
	}
	
	
	/**
	 * Retrieves an optional string list consisting of zero or more comma /
	 * space separated items from a enumeration.
	 *
	 * @param key   The property name.
	 * @param enums A string list defining the acceptable values.
	 * @param def   The default value if the property value is undefined or
	 *              empty.
	 *
	 * @return The string list with zero or more items.
	 *
	 * @throws PropertyParseException On a invalid property.
	 */
	public List getOptEnumStringList(final String key, final List enums, final List def)
		throws PropertyParseException {
		
		List out = getOptStringList(key, def);
		
		for (String v: out) {
			if (! enums.contains(v)) {
				throw new PropertyParseException("Invalid enum string list property: " + v, key, props.getProperty(key));
			}
		}
		
		return out;
	}
	
	
	/**
	 * Retrieves a string list from multiple properties sharing a common
	 * prefix.
	 *
	 * @param commonPrefix The common property name prefix.
	 *
	 * @return The string list with at least one item.
	 *
	 * @throws PropertyParseException On a missing or empty property.
	 */
	public List getStringListMulti(final String commonPrefix)
		throws PropertyParseException {
		
		List stringList = getOptStringListMulti(commonPrefix, null);
		
		if (stringList == null) {
			throw new PropertyParseException("Missing properties", commonPrefix + "*");
		}
		
		return stringList;
	}
	
	
	/**
	 * Retrieves an optional string list from multiple properties sharing a
	 * common prefix.
	 *
	 * @param commonPrefix The common property name prefix.
	 * @param def          The default value if no non-blank properties
	 *                     are found.
	 *
	 * @return The string list with at least one item or the default value.
	 */
	public List getOptStringListMulti(final String commonPrefix, final List def) {
		
		Properties filteredProps = PropertyFilter.filterWithPrefix(commonPrefix, props);
		List stringList = new LinkedList<>();
		for (String name: filteredProps.stringPropertyNames()) {
			String value = filteredProps.getProperty(name);
			if (value == null || value.trim().isEmpty()) {
				continue;
			}
			stringList.add(value);
		}
		
		if (stringList.isEmpty()) {
			return def;
		} else {
			return Collections.unmodifiableList(stringList);
		}
	}
	
	
	/**
	 * Retrieves a URI value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a URI.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public URI getURI(final String key)
		throws PropertyParseException {
		
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return new URI(value);
			
		} catch (URISyntaxException e) {
			
			throw new PropertyParseException("Invalid URI property: " + e.getMessage(), key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional URI value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a URL.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public URI getOptURI(final String key, final URI def)
		throws PropertyParseException {
		
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return new URI(value);
			
		} catch (URISyntaxException e) {
			
			throw new PropertyParseException("Invalid URI property: " + e.getMessage(), key, value);
		}
	}


	/**
	 * Retrieves a URL value.
	 *
	 * @param key The property name.
	 *
	 * @return The property as a URL.
	 *
	 * @throws PropertyParseException On a missing or invalid property.
	 */
	public URL getURL(final String key)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null)
			throw new PropertyParseException("Missing property", key);
		
		try {
			return new URL(value);

		} catch (MalformedURLException e) {

			throw new PropertyParseException("Invalid URL property: " + e.getMessage(), key, value);
		}
	}
	
	
	/**
	 * Retrieves an optional URL value.
	 *
	 * @param key The property name.
	 * @param def The default value if the property value is undefined or
	 *            empty.
	 *
	 * @return The property as a URL.
	 *
	 * @throws PropertyParseException On an invalid property.
	 */
	public URL getOptURL(final String key, final URL def)
		throws PropertyParseException {
	
		String value = props.getProperty(key);
		
		if (value == null || value.trim().isEmpty())
			return def;
		
		try {
			return new URL(value);

		} catch (MalformedURLException e) {

			throw new PropertyParseException("Invalid URL property: " + e.getMessage(), key, value);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy