/** * Copyright 2013 Tommi S.E. Laukkanen * * 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 org.bubblecloud.ilves.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * Properties loading utility which supports [category]-ext.properties for * extending properties defined in [category].properties. * * @author Tommi S.E. Laukkanen */ public final class PropertiesUtil { /** The loaded properties. */ private static final Map<String, Properties> PROPERTIES_MAP = new HashMap<String, Properties>(); /** The loaded extension properties. */ private static final Map<String, Properties> EXTENDED_PROPERTIES_MAP = new HashMap<String, Properties>(); /** Map of property overrides */ private static final Map<String, Properties> OVERRIDE_PROPERTIES_MAP = new HashMap<String, Properties>(); /** The category redirection map. */ private static Map<String, String> categoryRedirection = new HashMap<String, String>(); /** * Private default constructor to disable construction of utility class. */ private PropertiesUtil() { } /** * Redirect extended property loading from source to target directory. * This enables loading for example site kit built in properties * from application specific property file. * * @param sourceCategory the source category * @param targetCategory the target category */ public static void setCategoryRedirection(final String sourceCategory, final String targetCategory){ categoryRedirection.put(sourceCategory, targetCategory); } /** * Sets explicit override value for a property. * @param category the category * @param propertyKey the property key * @param propertyValue the property value */ public static synchronized void setProperty(final String category, final String propertyKey, final String propertyValue) { if (!OVERRIDE_PROPERTIES_MAP.containsKey(category)) { OVERRIDE_PROPERTIES_MAP.put(category, new Properties()); } OVERRIDE_PROPERTIES_MAP.get(category).put(propertyKey, propertyValue); } /** * Gets property value String or throws exception if no value is defined. * @param categoryKey Category defines the property file prefix. * @param propertyKey Property key defines the key in property file. * @return property value String or null. */ public static synchronized String getProperty(final String categoryKey, final String propertyKey) { return getProperty(categoryKey, propertyKey, true); } /** * Checks if property value is defined. * @param categoryKey Category defines the property file prefix. * @param propertyKey Property key defines the key in property file. * @return property value String or null. */ public static synchronized boolean hasProperty(final String categoryKey, final String propertyKey) { return getProperty(categoryKey, propertyKey, false) != null; } /** * Gets property value String. * @param categoryKey Category defines the property file prefix. * @param propertyKey Property key defines the key in property file. * @param required if required then non existing property causes exception. * @return property value String or null. */ public static synchronized String getProperty(final String categoryKey, final String propertyKey, final boolean required) { final String baseCategoryKey; final String extendedCategoryKey; if (categoryRedirection.containsKey(categoryKey)) { baseCategoryKey = categoryRedirection.get(categoryKey); extendedCategoryKey = categoryRedirection.get(categoryKey) + "-ext"; } else { baseCategoryKey = categoryKey; extendedCategoryKey = categoryKey + "-ext"; } if (!PROPERTIES_MAP.containsKey(baseCategoryKey)) { PROPERTIES_MAP.put(baseCategoryKey, getProperties(baseCategoryKey)); } if (!EXTENDED_PROPERTIES_MAP.containsKey(extendedCategoryKey)) { EXTENDED_PROPERTIES_MAP.put(extendedCategoryKey, getProperties(extendedCategoryKey)); } if (OVERRIDE_PROPERTIES_MAP.containsKey(baseCategoryKey)) { final String valueString = (String) OVERRIDE_PROPERTIES_MAP.get(baseCategoryKey).get(propertyKey); if (valueString != null) { return valueString; } } if (EXTENDED_PROPERTIES_MAP.get(extendedCategoryKey) != null) { final String valueString = (String) EXTENDED_PROPERTIES_MAP.get(extendedCategoryKey).get(propertyKey); if (valueString != null) { return valueString; } } if (PROPERTIES_MAP.get(baseCategoryKey) != null) { final String valueString = (String) PROPERTIES_MAP.get(baseCategoryKey).get(propertyKey); if (valueString != null) { return valueString; } } if (required) { throw new RuntimeException("Property not found: " + baseCategoryKey + " / " + propertyKey); } else { return null; } } /** * Loads properties with given category key. * @param categoryKey The category key. * @return Properties or null. */ private static synchronized Properties getProperties(final String categoryKey) { final String propertiesFileName = categoryKey + ".properties"; final Properties properties = new Properties(); InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(propertiesFileName); if (inputStream == null) { try { if (!new File(propertiesFileName).exists()) { return null; } inputStream = new FileInputStream(propertiesFileName); } catch (final IOException e) { e.printStackTrace(); return null; } if (inputStream == null) { return null; } } try { properties.load(inputStream); inputStream.close(); } catch (final IOException e) { e.printStackTrace(); return null; } return properties; } }