org.apache.jsieve.ConfigurationManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.jsieve.ConfigurationManager.java

Source

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you 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.apache.jsieve;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;

/**
 * <p>
 * <code>ConfigurationManager</code> parses the XML statements
 * in the Sieve configuration file and translates them to Java objects.
 * </p>
 * <p>
 * The Sieve configuration is read from 3 properties files
 * </p>
 * <ul>
 * <li><code>org/apache/jsieve/commandsmap.properties</code></li>
 * <li><code>org/apache/jsieve/testsmap.properties</code></li>
 * <li><code>org/apache/jsieve/comparatorsmap.properties</code></li>
 * </ul>
 * <p>They are located by searching the classpath of the current ClassLoader.
 * </p>
 * <h4>Thread Safety</h4>
 * <p>
 * Each configuration manager instance may be safely accessed by concurrent threads.
 * </p>
 * <p>
 * The managers constructed by 
 * </p>
 * <ul>
 * <li>{@link #getCommandManager()}</li> 
 * <li>{@link #getComparatorManager()}</li>
 * <li>{@link #getTestManager()}</li>
 * </ul>
 * <p>
 * and the {@link SieveFactory} built by
 * </p>
 * <ul>
 * <li>{@link #build()}</li>
 * </ul>
 * <p>
 * may be safely shared by multiple threads.
 * </p>
 */
public class ConfigurationManager {

    private static final int DEFAULT_INITIAL_CONCURRENCY_LEVEL = 8;

    private static final String COMMANDSMAP_PROPERTIES = "org/apache/jsieve/commandsmap.properties";

    private static final String TESTSMAP_PROPERTIES = "org/apache/jsieve/testsmap.properties";

    private static final String COMPARATORSMAP_PROPERTIES = "org/apache/jsieve/comparatorsmap.properties";

    /**
     * A Map of the Command names and their associated class names.
     */
    private ConcurrentMap<String, String> fieldCommandMap;

    /**
     * A Map of the Test names and their associated class names.
     */
    private ConcurrentMap<String, String> fieldTestMap;

    /**
     * A Map of the Comparator names and their associated class names.
     */
    private ConcurrentMap<String, String> fieldComparatorMap;

    /**
     * The initial size for the {@link ConcurrentHashMap} concurrency level.
     */
    private int initialConcurrencyLevel = DEFAULT_INITIAL_CONCURRENCY_LEVEL;

    private static final Log LOG = LogFactory.getLog("org.apache.jsieve");

    private Log log = LOG;

    /**
     * Constructor for ConfigurationManager.
     * 
     * @throws SieveConfigurationException
     */
    public ConfigurationManager() throws SieveConfigurationException {
        super();
        try {
            parse();
        } catch (SAXException e) {
            if (log.isErrorEnabled())
                log.error("Exception processing Configuration: ", e);
            throw new SieveConfigurationException(e);
        } catch (IOException e) {
            if (log.isErrorEnabled())
                log.error("Exception processing Configuration: ", e);
            throw new SieveConfigurationException(e);
        }
    }

    /**
     * Gets the current initial size for the {@link ConcurrentHashMap} concurrency level.
     * @return number of concurrent threads estimated for initial sizing
     */
    public int getInitialConcurrencyLevel() {
        return initialConcurrencyLevel;
    }

    /**
     * Sets the current initial size for the {@link ConcurrentHashMap} concurrency level.
     * @param initialConcurrencyLevel number of concurrent threads estimated for initial sizing
     */
    public void setInitialConcurrencyLevel(int initialConcurrencyLevel) {
        this.initialConcurrencyLevel = initialConcurrencyLevel;
    }

    /**
     * <p>
     * Method getConfigStream answers an InputStream over the Sieve
     * configuration file. It is located by searching the classpath of the
     * current ClassLoader.
     * </p>
     * <p>
     * The context classloader is searched first. If a suitably named resource
     * is found then this is returned. Otherwise, the classloader used to load
     * this class is searched for the resource.
     * </p>
     * 
     * @return InputStream
     * @throws IOException
     */
    private InputStream getConfigStream(String configName) throws IOException {
        InputStream stream = null;
        // Context classloader is usually right in a JEE evironment
        final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        if (contextClassLoader != null) {
            stream = contextClassLoader.getResourceAsStream(configName);
        }

        // Sometimes context classloader will not be set conventionally
        // So, try class classloader
        if (null == stream) {
            stream = ConfigurationManager.class.getClassLoader().getResourceAsStream(configName);
        }

        if (null == stream)
            throw new IOException("Resource \"" + configName + "\" not found");
        return stream;
    }

    /**
     * Method getCommandMap answers a Map of Command names and their associated
     * class names, lazily initialized if required.
     * 
     * @return Map not null
     */
    public ConcurrentMap<String, String> getCommandMap() {
        if (null == fieldCommandMap) {
            fieldCommandMap = new ConcurrentHashMap<String, String>();
        }
        return fieldCommandMap;
    }

    /**
     * Method getTestMap answers a Map of Test names and their associated class
     * names, lazily initialized if required.
     * 
     * @return Map not null
     */
    public ConcurrentMap<String, String> getTestMap() {
        if (null == fieldTestMap) {
            fieldTestMap = new ConcurrentHashMap<String, String>();
        }
        return fieldTestMap;
    }

    /**
     * Method getComparatorMap answers a Map of Comparator names and their
     * associated class names, lazily initialized if required.
     * 
     * @return Map not null
     */
    public ConcurrentMap<String, String> getComparatorMap() {
        if (null == fieldComparatorMap) {
            fieldComparatorMap = new ConcurrentHashMap<String, String>();
        }
        return fieldComparatorMap;
    }

    /**
     * Method parse uses the Digester to parse the XML statements in the Sieve
     * configuration file into Java objects.
     * 
     * @throws SAXException
     * @throws IOException
     */
    private void parse() throws SAXException, IOException {
        setCommandMap(loadConfiguration(COMMANDSMAP_PROPERTIES));
        setTestMap(loadConfiguration(TESTSMAP_PROPERTIES));
        setComparatorMap(loadConfiguration(COMPARATORSMAP_PROPERTIES));
    }

    private ConcurrentMap<String, String> loadConfiguration(final String name) throws IOException {
        final Properties properties = loadProperties(name);
        final ConcurrentMap<String, String> result = new ConcurrentHashMap<String, String>(properties.size(), 1.0f,
                initialConcurrencyLevel);
        for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
            result.put(entry.getKey().toString(), entry.getValue().toString());
        }
        return result;
    }

    private Properties loadProperties(final String name) throws IOException {
        final InputStream is = getConfigStream(name);
        final Properties p = new Properties();
        p.load(is);
        return p;
    }

    /**
     * Sets the commandMap.
     * 
     * @param commandMap
     *            The commandMap to set
     */
    private void setCommandMap(ConcurrentMap<String, String> commandMap) {
        fieldCommandMap = commandMap;
    }

    /**
     * Sets the testMap.
     * 
     * @param testMap
     *            The testMap to set
     */
    private void setTestMap(ConcurrentMap<String, String> testMap) {
        fieldTestMap = testMap;
    }

    /**
     * Sets the comparatorMap.
     * 
     * @param comparatorMap
     *            The comparatorMap to set
     */
    private void setComparatorMap(ConcurrentMap<String, String> comparatorMap) {
        fieldComparatorMap = comparatorMap;
    }

    public ComparatorManager getComparatorManager() {
        return new ComparatorManagerImpl(fieldComparatorMap);
    }

    public CommandManager getCommandManager() {
        return new CommandManagerImpl(fieldCommandMap);
    }

    public TestManager getTestManager() {
        return new TestManagerImpl(fieldTestMap);
    }

    public Log getLog() {
        return log;
    }

    public void setLog(Log log) {
        this.log = log;
    }

    public SieveFactory build() {
        return new SieveFactory(getCommandManager(), getComparatorManager(), getTestManager(), getLog());
    }
}