PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/protocols/smpp/src/main/java/org/mobicents/protocols/smpp/util/APIConfigFactory.java

http://mobicents.googlecode.com/
Java | 188 lines | 86 code | 12 blank | 90 comment | 15 complexity | fbff876d3eddec7cb15c761967599b79 MD5 | raw file
  1/*
  2 * JBoss, Home of Professional Open Source
  3 * Copyright 2011, Red Hat, Inc. and individual contributors
  4 * by the @authors tag. See the copyright.txt in the distribution for a
  5 * full listing of individual contributors.
  6 *
  7 * This is free software; you can redistribute it and/or modify it
  8 * under the terms of the GNU Lesser General Public License as
  9 * published by the Free Software Foundation; either version 2.1 of
 10 * the License, or (at your option) any later version.
 11 *
 12 * This software is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15 * Lesser General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU Lesser General Public
 18 * License along with this software; if not, write to the Free
 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21 */
 22
 23package org.mobicents.protocols.smpp.util;
 24
 25/**
 26 * Factory class for obtaining the API configuration. Alternative API
 27 * configurations can be specified by setting the
 28 * <tt>org.mobicents.smpp.configClass</tt> system property to the fully qualified
 29 * class name of a class that implements the {@link APIConfig} interface.
 30 * The default is {@link PropertiesAPIConfig}.
 31 * 
 32 * <p>
 33 * Normally, the {@link #getConfig()} method will cache the loaded
 34 * configuration object on first call and return the cached config
 35 * on subsequent calls. If you want to override this behaviour and
 36 * never cache the loaded configuration object, set the
 37 * <tt>org.mobicents.smpp.cacheConfig</tt> system property to <tt>false</tt>.
 38 * </p>
 39 * 
 40 * <p>
 41 * For example, to run your application with a configuration implementation
 42 * called <tt>app.MyAPIConfig</tt> and with singleton caching turned off,
 43 * execute:<br />
 44 * <tt>java -Dorg.mobicents.smpp.configClass=app.MyAPIConfig
 45 * -Dorg.mobicents.smpp.cacheConfig=false app.MainClass</tt>
 46 * </p>
 47 * @version $Id: APIConfigFactory.java 452 2009-01-15 16:56:36Z orank $
 48 */
 49public final class APIConfigFactory {
 50    /**
 51     * The system property to set to control whether a loaded
 52     * configuration instance is cached as a singleton or not.
 53     */
 54    public static final String CONFIG_CLASS_PROP = "org.mobicents.smpp.configClass";
 55    
 56    /**
 57     * The system property specifying the concrete implementation of
 58     * {@link APIConfig} to read configuration properties from.
 59     */
 60    public static final String CACHE_CONFIG_PROP = "org.mobicents.smpp.cacheConfig";
 61    
 62    private static APIConfig cachedConfig;
 63    
 64    private APIConfigFactory() {
 65    }
 66    
 67    /**
 68     * Get the API configuration. Returns a cached {@link APIConfig}
 69     * instance if the configuration has previously been loaded and
 70     * caching is enabled. If no configuration object has been cached,
 71     * return the result of calling {@link #loadConfig()} (and cache
 72     * that result if caching is enabled).
 73     * <p>
 74     * The system property to enable and disable caching is read at every
 75     * call to this method, so the cache strategy can be affected by
 76     * Java code modifying this value.
 77     * </p>
 78     * @return The API configuration implementation.
 79     * @throws InvalidConfigurationException for the same reasons that
 80     * <tt>loadConfig</tt> throws this exception.
 81     */
 82    public static final APIConfig getConfig() {
 83        boolean cacheConfig = readCacheConfig();
 84        if (cachedConfig != null) {
 85            return cachedConfig;
 86        } else {
 87            APIConfig config = loadConfig();
 88            if (cacheConfig) {
 89                cachedConfig = config;
 90            }
 91            return config;
 92        }
 93    }
 94    
 95    /**
 96     * Load and initialise an {@link APIConfig} instance. The type of
 97     * implementation to instantiate is read from the system property as
 98     * described in the {@link APIConfigFactory class description}.
 99     * @return An initialised <tt>APIConfig</tt> instance.
100     * @throws InvalidConfigurationException If the configuration class
101     * cannot be found, it does not implement {@link APIConfig} or its
102     * constructor is not visible or throws an exception.
103     */
104    public static final APIConfig loadConfig() {
105        String className = null;
106        try {
107            ClassLoader loader = getClassLoader();
108            className = getConfigClassName();
109            Class<?> clazz = loader.loadClass(className);
110            if (!APIConfig.class.isAssignableFrom(clazz)) {
111                throw new InvalidConfigurationException(
112                        "Class "
113                        + className
114                        + " does not implement "
115                        + APIConfig.class.getName());
116            }
117            APIConfig config = (APIConfig) clazz.newInstance();
118            config.initialise();
119            return config;
120        } catch (ClassNotFoundException x) {
121            throw new InvalidConfigurationException(
122                    "Cannot find class " + className);
123        } catch (InstantiationException x) {
124            throw new InvalidConfigurationException(
125                    "Constructor in class "
126                    + className
127                    + " threw an exception", x);
128        } catch (IllegalAccessException x) {
129            throw new InvalidConfigurationException(
130                    "Constructor in class "
131                    + className
132                    + " is not visible");
133        }
134    }
135    
136    /**
137     * Set the cached {@link APIConfig} instance that will be returned
138     * from calls to {@link #getConfig()}. This method allows
139     * applications to set their own <tt>APIConfig</tt> implementation,
140     * bypassing the {@link #loadConfig()} logic.
141     * @param apiConfig The <tt>APIConfig</tt> instance to cache and 
142     * return from subsequent calls to <tt>getConfig()</tt>.
143     */
144    public static final void setCachedConfig(APIConfig apiConfig) {
145        cachedConfig = apiConfig;
146    }
147
148    /**
149     * Reset this <tt>APIConfigFactory</tt>. This clears the
150     * cached configuration object so that the next call to
151     * {@link #getConfig()} will reload the API configuration.
152     */
153    public static final void reset() {
154        cachedConfig = null;
155    }
156    
157    private static boolean readCacheConfig() {
158        boolean cacheConfig = true;
159        String value = System.getProperty(CACHE_CONFIG_PROP);
160        if (value != null) {
161            value = value.trim().toLowerCase();
162            if ("false".equals(value)
163                    || "no".equals(value)
164                    || "off".equals(value)) {
165                cacheConfig = false;
166            }
167        }
168        return cacheConfig;
169    }
170    
171    private static ClassLoader getClassLoader() {
172        Thread currentThread = Thread.currentThread();
173        ClassLoader loader = currentThread.getContextClassLoader();
174        if (loader == null) {
175            loader = APIConfigFactory.class.getClassLoader();
176        }
177        return loader;
178    }
179    
180    private static String getConfigClassName() {
181        String value = System.getProperty(CONFIG_CLASS_PROP);
182        if (value != null) {
183            return value;
184        } else {
185            return PropertiesAPIConfig.class.getName();
186        }
187    }
188}