it.cnr.icar.eric.common.AbstractProperties.java Source code

Java tutorial

Introduction

Here is the source code for it.cnr.icar.eric.common.AbstractProperties.java

Source

/*
 * ====================================================================
 * This file is part of the ebXML Registry by Icar Cnr v3.2 
 * ("eRICv32" in the following disclaimer).
 *
 * "eRICv32" is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * "eRICv32" is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License Version 3
 * along with "eRICv32".  If not, see <http://www.gnu.org/licenses/>.
 *
 * eRICv32 is a forked, derivative work, based on:
 *    - freebXML Registry, a royalty-free, open source implementation of the ebXML Registry standard,
 *      which was published under the "freebxml License, Version 1.1";
 *   - ebXML OMAR v3.2 Edition, published under the GNU GPL v3 by S. Krushe & P. Arwanitis.
 * 
 * All derivative software changes and additions are made under
 *
 * Copyright (C) 2013 Ing. Antonio Messina <messina@pa.icar.cnr.it>
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the freebxml Software Foundation.  For more
 * information on the freebxml Software Foundation, please see
 * "http://www.freebxml.org/".
 *
 * This product includes software developed by the Apache Software
 * Foundation (http://www.apache.org/).
 *
 * ====================================================================
 */
package it.cnr.icar.eric.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.TreeSet;
import javax.xml.registry.JAXRException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * An abstract class for configuration properties. Contains common methods
 * refactored from other properties classes, i.e. RegistryProperties,
 * ProviderProperties.
 *
 * @author  Diego Ballve / Republica Corp
 */
public abstract class AbstractProperties {
    private static final Log log = LogFactory.getLog(AbstractProperties.class);

    //Do not do following as it causes cyclic dependency related problem.
    //protected static CommonResourceBundle resourceBundle = CommonResourceBundle.getInstance();

    /** Default home dir, relative to user home. */
    protected static final String DEFAULT_ERIC_HOME = "eric";
    /** Property containing full path to eric home directory. */
    protected static final String ERIC_HOME_KEY = "eric.home";

    protected Properties props = new Properties();

    protected AbstractProperties() {
    }

    /**
     * Checks if a directory for the given name exists. If not, try to create it.
     *
     * @param homeDir A File descriptor for the directory to be checked.
     * @return Full path to the directory.
     * @throw JAXRException if it fails to find and create the directory.
     */
    protected static String initHomeDir(String propName, File homeDir) {
        try {
            if (!homeDir.exists()) {
                if (!homeDir.mkdirs()) {
                    throw new RuntimeException(CommonResourceBundle.getInstance()
                            .getString("message.createDirectory", new String[] { propName, homeDir.getPath() }));
                }
            } else {
                if (!homeDir.isDirectory()) {
                    throw new RuntimeException(CommonResourceBundle.getInstance()
                            .getString("message.accessDirectory", new String[] { propName, homeDir.getPath() }));
                }
            }
            String homeDirStr = homeDir.getCanonicalPath();
            return homeDirStr;
        } catch (SecurityException se) {
            throw new RuntimeException(CommonResourceBundle.getInstance().getString("message.permissionDenied",
                    new String[] { propName, homeDir.getPath(), se.toString() }));
        } catch (IOException io) {
            throw new RuntimeException(CommonResourceBundle.getInstance().getString("message.createAccessDirectory",
                    new String[] { propName, homeDir.getPath(), io.toString() }));
        }
    }

    protected static void initEricHomeDir(Properties properties) {
        //String ericHome = getEricHome(properties);
        String ericHome = getEricHome();
        File ericHomeFile = new File(ericHome);
        initHomeDir(ERIC_HOME_KEY, ericHomeFile);
        properties.put(ERIC_HOME_KEY, ericHome);
    }

    /**
     * Replace pre-defined variables in property values with the variable value from the
     * corresponding property.
     *
     * @param properties the Properties object to be changed
     * @param oldKeyPrefix String to be replaced from properties' keys
     * @param newKeyPrefix replacement String
     *
     */
    protected static void substituteVariables(Properties properties, String oldKeySubstring,
            String newKeySubstring) {
        //Iterate and replace the variable
        int oldKeySubstringSize = oldKeySubstring.length();
        for (Enumeration<?> keys = properties.propertyNames(); keys.hasMoreElements();) {
            String key = (String) keys.nextElement();
            String value = properties.getProperty(key);
            //System.err.println("key = " + key + " value = " + value);
            if (key.startsWith("eric.")) {
                int index = -1;
                boolean modified = false;
                while (true) {
                    index = value.indexOf(oldKeySubstring);
                    if (index == -1) {
                        break;
                    }
                    value = value.substring(0, index) + newKeySubstring
                            + value.substring(index + oldKeySubstringSize);
                    modified = true;
                }
                if (modified) {
                    properties.put(key, value);
                }
            }
        }
    }

    protected static String substituteVariable(String value, String oldKeySubstring, String newKeySubstring) {
        if (value == null) {
            return null;
        }
        int oldKeySubstringSize = oldKeySubstring.length();
        while (true) {
            int index = value.indexOf(oldKeySubstring);
            if (index == -1) {
                break;
            }
            value = value.substring(0, index) + newKeySubstring + value.substring(index + oldKeySubstringSize);
        }
        return value;
    }

    /**
     * Getter for property 'propertyName'. Returns null if property is not defined.
     *
     * @param propertyName the property key (name).
     *
     * @return the value in this property list with the specified key value.
     */
    public String getProperty(String propertyName) {
        return props.getProperty(propertyName);
    }

    /**
     * Getter for property 'propertyName', with 'def' being returned if property
     * not defined.
     *
     * @param propertyName the property key (name).
     * @param def a default value
     *
     * @return the value in this property list with the specified key value.
     */
    public String getProperty(String propertyName, String def) {
        return props.getProperty(propertyName, def);
    }

    /** Convenience method. */
    public Iterator<String> getPropertyNamesStartingWith(String prefix) {
        List<String> lst = new LinkedList<String>();
        Enumeration<?> e = props.propertyNames();

        while (e.hasMoreElements()) {
            String propertyName = (String) e.nextElement();

            if (propertyName.startsWith(prefix)) {
                lst.add(propertyName);
            }
        }

        return lst.iterator();
    }

    /**
     * Initializes the properties performing the full loading sequence.
     */
    protected abstract void initProperties();

    /**
     * Load property settings, with the source for properties being
     * provided by each implementation.
     *
     * @param properties a default list of properties
     *
     * @return a Properties object loaded from a predefined resource
     */
    protected abstract Properties loadProperties(Properties defaultProps);

    /**
     * This method is used to reload properties into memory.
     */
    public void reloadProperties() {
        initProperties();
    }

    /**
     * Load default property settings.
     *
     * @return a Properties object loaded from a predefined resource
     */
    protected abstract void loadDefaultProperties(Properties properties);

    /**
     * Loads properties from resourceName (from classpath) to 'properties'.
     *
     * @param classLoader the ClassLoader to use when getting resource
     * @param properties existing properties (might get overwritten)
     * @param resourceName the resource name, to be loaded from classpath
     * @return True if load ok. False otherwise.
     */
    protected static boolean loadResourceProperties(ClassLoader classLoader, Properties properties,
            String resourceName) {
        log.trace(CommonResourceBundle.getInstance().getString("message.LoadPropsFromClasspath",
                new Object[] { resourceName }));
        try {
            InputStream is = classLoader.getResourceAsStream(resourceName);
            if (is == null) {
                throw new JAXRException(CommonResourceBundle.getInstance().getString("message.resourceNotFound",
                        new String[] { resourceName }));
            }
            properties.load(is);
            is.close();
            return true;
        } catch (Exception e) {
            log.debug(CommonResourceBundle.getInstance().getString("message.IgnoringDueToException",
                    new Object[] { resourceName, e.toString() }));
            return false;
        }
    }

    /**
     * Loads properties from file to 'properties'.
     *
     * @param properties existing properties (might get overwritten)
     * @param file the file, to be loaded from file system
     * @return True if load ok. False otherwise.
     */
    protected static boolean loadFileProperties(Properties properties, File file) {
        log.trace(CommonResourceBundle.getInstance().getString("message.LoadPropsFromFile",
                new Object[] { file.getPath() }));
        try {
            InputStream is = new FileInputStream(file);
            properties.load(is);
            is.close();
            return true;
        } catch (Exception e) {
            // silently ignore missing client properties
            log.debug(CommonResourceBundle.getInstance().getString("message.IgnoringDueToException",
                    new Object[] { file.getPath(), e.toString() }));
            return false;
        }
    }

    /**
     * Loads system properties to 'properties'.
     *
     * @param properties existing properties (might get overwriten)
     * @return True if load ok. False otherwise.
     */
    protected static boolean loadSystemProperties(Properties properties) {
        log.trace(CommonResourceBundle.getInstance().getString("message.LoadPropsFromSystemProps"));
        try {
            AccessController.doPrivileged(new ReadSystemPropsPrivilegedAction(properties));
            return true;
        } catch (Exception e) {
            // silently ignore missing System properties
            log.debug(CommonResourceBundle.getInstance().getString("message.IgnoringSystemPropsDueToException",
                    new Object[] { e.toString() }));
            return false;
        }
    }

    /**
     * Logs all properties as name=value pairs. Requires debug level.
     *
     * @param propsName name for the properties set.
     * @param props Properties to be logged.
     */
    protected static void logProperties(String propsName, Properties props) {
        if (log.isDebugEnabled()) {
            log.debug("==================================================");
            log.debug(propsName + ":");
            Iterator<Object> names = (new TreeSet<Object>(props.keySet())).iterator();
            while (names.hasNext()) {
                String name = (String) names.next();
                String value = props.getProperty(name);
                log.debug(name + "=" + value);
            }
            log.debug("==================================================");
        }
    }

    public Properties cloneProperties() {
        Properties clone = new Properties();
        clone.putAll(props);
        return clone;
    }

    /**
     * Getter for ericHome. If null, sets default value and return.
     *
     * @return String value for registryHome property.
     */
    protected static String getEricHome(Properties properties) {
        String ericHome = properties.getProperty(ERIC_HOME_KEY);
        //TODO: needs doPrivileged?!
        ericHome = System.getProperty(ERIC_HOME_KEY, ericHome);
        ericHome = substituteVariable(ericHome, "$user.home", getUserHome());
        if (ericHome == null) {
            throw new RuntimeException(CommonResourceBundle.getInstance().getString("message.propertyNotDefined",
                    new String[] { ERIC_HOME_KEY }));
        }
        return ericHome;
    }

    protected static String getEricHome() {
        String ericHome = System.getenv("ERIC_HOME");
        if (ericHome == null) {
            throw new RuntimeException("ERIC_HOME is not set");
        }
        return ericHome;
    }

    protected static String getUserHome() {
        return System.getProperty("user.home");
    }

    /**
     * @see java.util.Properties#put(Object,Object)
     */
    public void put(Object key, Object value) {
        //todo: consider removing
        this.props.put(key, value);
    }

    /**
     * @see java.util.Properties#remove(Object)
     */
    public void remove(Object key) {
        this.props.remove(key);
    }

    /**
     * Inner class to load System properties.
     */
    private static class ReadSystemPropsPrivilegedAction implements PrivilegedAction<Object> {
        private Properties props;

        public ReadSystemPropsPrivilegedAction(Properties props) {
            this.props = props;
        }

        public Object run() {
            props.putAll(System.getProperties());
            return null;
        }
    }
}