/* * Copyright 2011-2014 Eric F. Savage, code@efsavage.com * * 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. */ package com.ajah.util.config; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import lombok.extern.java.Log; import com.ajah.util.StringUtils; import com.ajah.util.data.format.EmailAddress; /** * Config object. Works kind of like a stripped-down version of commons config, * but without all the bells and whistles (or dependencies). Uses enum style * singleton pattern. * * @author Eric F. Savage <code@efsavage.com> */ @Log public enum Config { /** * Singleton instance of Config. */ i; /** * Returns the logger. * * @return The logger. */ private static Logger getLog() { return log; } private final Properties properties = new Properties(); private Config() { final String config = StringUtils.isBlank(System.getProperty("config")) ? "/ajah.properties" : System.getProperty("config"); try (final InputStream stream = getClass().getResourceAsStream(config)) { if (stream != null) { try { this.properties.load(stream); Logger.getLogger(Config.class.getName()).log(Level.CONFIG, "Loaded properties from " + config); } catch (final IOException e) { Logger.getLogger(Config.class.getName()).log(Level.CONFIG, e.getMessage(), e); } } else { Logger.getLogger(Config.class.getName()).log(Level.CONFIG, "No resource " + config + " found."); } } catch (final IOException e) { getLog().log(Level.WARNING, e.getMessage(), e); } for (final Object propKey : this.properties.keySet()) { final String sysProp = System.getProperty((String) propKey); if (!StringUtils.isBlank(sysProp)) { Logger.getLogger(Config.class.getName()).log(Level.CONFIG, "Overriding property " + (String) propKey + " with System property value of " + sysProp); this.properties.setProperty((String) propKey, sysProp); } } } /** * Returns the value for the specified key, or the default value specified. * Invokes {@link #get(String, String)} with the values from * {@link PropertyKey}. * * @param key * The key of the property sought. * @return Returns the value for the specified key, or defaultValue */ public String get(final PropertyKey key) { if (key.getFallback() != null) { return get(key.getName(), get(key.getFallback())); } return get(key.getName(), key.getDefaultValue()); } /** * Calls {@link #get(String, String)} with a default value of null. * * @param key * The key to fetch. * @return The value of the key, or null. */ public String get(final String key) { return get(key, null); } /** * Returns the value for the specified key, or the default value specified. * * @param key * The key of the property sought. * @param defaultValue * The value to return if no value is found. * @return Returns the value for the specified key, or defaultValue */ public String get(final String key, final String defaultValue) { final String retVal = (String) this.properties.get(key); if (StringUtils.isBlank(retVal)) { return defaultValue; } return retVal; } /** * Returns The value as a boolean. * * @param key * The property to return * @return Returns true if the value is "true", case-insensitive. */ public boolean getBoolean(final PropertyKey key) { return "true".equalsIgnoreCase(get(key)); } /** * Returns The value as a boolean. * * @param key * The property to return * @param defaultValue * The value to return if the property is not found. * @return Returns true if the value is "true", case-insensitive. */ public boolean getBoolean(final String key, final boolean defaultValue) { return "true".equalsIgnoreCase(get(key, String.valueOf(defaultValue))); } /** * Returns the value as an EmailAddress. * * @see EmailAddress#EmailAddress(String) * @param key * The key of the property sought. * @return Email address, if valid. * @throws IllegalArgumentException * If the value is not a valid address. */ public EmailAddress getEmailAddress(final PropertyKey key) { return new EmailAddress(get(key.getName(), key.getDefaultValue())); } /** * Returns The value as a int. * * @param key * The property to return * @param defaultValue * The value to return if the property is not found. * @return Returns true if the value is "true", case-insensitive. */ public int getInt(final String key, final int defaultValue) { final String retVal = (String) this.properties.get(key); if (StringUtils.isBlank(retVal)) { return defaultValue; } return Integer.parseInt(retVal); } /** * Returns The value as a long. * * @param key * The property to return * @param defaultValue * The value to return if the property is not found. * @return Returns true if the value is "true", case-insensitive. */ public long getLong(final String key, final long defaultValue) { final String retVal = (String) this.properties.get(key); if (StringUtils.isBlank(retVal)) { return defaultValue; } return Long.parseLong(retVal); } /** * Returns the value, split on commas. Whitespace around the commas is * permitted and removed. * * @param key * The property to return. * @return The values as delimited by commas in the property value. */ public String[] getStrings(final PropertyKey key) { return get(key).split("\\s*,\\s*"); } /** * Sets the value for the specified key in the local map. <strong>These * changes will not be persisted!</strong> * * @param key * The key of the property to set. * @param value * The value of the property to set. */ public void set(final String key, final String value) { log.fine("Property " + key + " set to " + value); this.properties.put(key, value); } }