/******************************************************************************* * Copyright (c) 2010-2014 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation *******************************************************************************/ package org.eclipse.skalli.services; import java.io.InputStream; import java.net.URL; import java.text.MessageFormat; import java.util.Iterator; import java.util.Properties; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Utility class to access system properties and properties defined in * <tt>"skalli.properties"</tt> files in installed bundles. */ public class BundleProperties { /** Name of the property files to search for: <tt>{@value}</tt> */ public static final String PROPERTIES_RESOURCE = "skalli.properties";//$NON-NLS-1$ /** Name of the property specifying the active storage service: <tt>{@value}</tt> */ public static final String PROPERTY_STORAGE_SERVICE = "skalli.storageService"; //$NON-NLS-1$ /** Name of the property specifying the workig directory for file storage: <tt>{@value}</tt> */ public static final String PROPERTY_WORKDIR = "workdir"; //$NON-NLS-1$ private static final Logger LOG = LoggerFactory.getLogger(BundleProperties.class); private static Properties propertyCache = getBundleProperties(); /** * Returns the value of the specified property. This method is a shortcut for * {@link #getProperty(String, String) getProperty(propertyName, null)}. * * @param propertyName the name of the property. * @return the value of ths property, or <code>null</code> if the specified property does not exist. */ public static String getProperty(String propertyName) { return getProperty(propertyName, null); } /** * Returns the value of the specified property or a default value if the property does not exist. * <br> * This method returns the value of a system property with the given name, if it exists. * Otherwise, the property is searched in all installed bundles, i.e. in property files with * name <tt>"skalli.properties"</tt>, which must reside in the root directories of their * respective bundles. The first encounter of the property wins in case the property is * defined in several property files. Since the search order is in general unpredictable this * situation should be avoided. * <br> * Note: Properties from installed bundles are cached during startup, since scanning all installed * bundles for certain files is a time consuming operation. Installing additional bundles at * a later time or uninstalling bundles will not update the property cache. * * @param propertyName the name of the property. * @param defaultValue the value to return in case the property does not exist. * @return the value of the property, or the given default value if the property does not exist. */ public static String getProperty(String propertyName, String defaultValue) { String propertyValue = System.getProperty(propertyName); if (propertyValue == null) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format("system property ''{0}'' is undefined", propertyName)); //$NON-NLS-1$ } propertyValue = propertyCache.getProperty(propertyName); if (propertyValue == null && StringUtils.isNotBlank(defaultValue)) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( "using default value ''{0}'' for property ''{1}''", //$NON-NLS-1$ defaultValue, propertyName)); } propertyValue = defaultValue; } } if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format("found property ''{0}'' with value ''{1}''", //$NON-NLS-1$ propertyName, propertyValue)); } return propertyValue; } private static Properties getBundleProperties() { Properties bundleProperties = new Properties(); Iterator<URL> resources = Services.findResources("/", PROPERTIES_RESOURCE, false, FilterMode.ALL, //$NON-NLS-1$ new BundleFilter.AcceptAll()).iterator(); while (resources.hasNext()) { addBundleProperties(resources.next(), bundleProperties); } return bundleProperties; } private static void addBundleProperties(URL resource, Properties bundleProperties) { InputStream in = null; try { in = resource.openStream(); if (in != null) { Properties properties = new Properties(); properties.load(in); bundleProperties.putAll(properties); } } catch (Exception e) { LOG.info(MessageFormat.format("Failed to retrieve properties from resource ''{0}''", //$NON-NLS-1$ resource)); } finally { IOUtils.closeQuietly(in); } } }