package com.telefonica.claudia.configmanager; import java.io.File; import java.io.FileInputStream; import java.io.InvalidClassException; import java.util.Properties; import org.apache.log4j.Logger; import com.telefonica.claudia.configmanager.lb.LoadBalancerConfigurator; import com.telefonica.claudia.configmanager.lb.impl.LoadBalancerConfiguratorRESTImpl; /** * This class constructs and returns different {@link Configurator} * implementations depending on configuration and service container * implementations. * * The default constructor loads a properties file called configurators.prop * from the classpath. If metioned file is not present, default properties are * automatically loaded. See {@link ConfiguratorFactory#loadDefaultProperties()} * * This class is a singleton. For getting an instance, * {@link ConfiguratorFactory#getInstance()} should be invoked. * * @author amartin * */ public class ConfiguratorFactory { private static ConfiguratorFactory instance; private Properties prop; private Logger log; /** * Private constructor */ private ConfiguratorFactory() { this.log = Logger.getLogger(this.getClass()); ClassLoader loader = ClassLoader.getSystemClassLoader(); this.prop = new Properties(); try{ this.prop.load(new FileInputStream(new File("configurators.properties"))); } catch(Exception e){ log.info("Unable to load properties from file configurators.properties", e); this.prop = null; } if (this.prop == null) { this.log.info("Trying to load properties from classpath"); try { this.prop.load(loader.getResourceAsStream("configurators.properties")); } catch (Throwable e) { this.log.warn("Unable to load properties from classpath. Using defaults", e); this.loadDefaultProperties(); } } } /** * Loads default properties */ private void loadDefaultProperties() { this.prop = new Properties(); this.prop.setProperty( LoadBalancerConfigurator.class.getCanonicalName(), LoadBalancerConfiguratorRESTImpl.class.getCanonicalName()); this.prop.setProperty("OVFEnvironmentFilePath", "/home/amartin/ovfTemplate.xml"); this.prop.setProperty("outputVJSCConfigFilePath", "/home/amartin/output.xml"); this.prop.setProperty("DatabaseIP", "org.apache.jackrabbit.core.fs.db.DbFileSystem.IPdatabase"); this.prop.setProperty("DatabaseUser", "org.apache.jackrabbit.core.fs.db.DbFileSystem.user"); this.prop.setProperty("DatabaseURL", "org.apache.jackrabbit.core.fs.db.DbFileSystem.url"); this.prop.setProperty("DatabasePassword", "org.apache.jackrabbit.core.fs.db.DbFileSystem.password"); this.prop.setProperty("DatabaseType", "org.apache.jackrabbit.core.fs.db.DbFileSystem.schema"); } /** * Creates an instance (if not created already) and returns it. * * @return unique instance */ public static ConfiguratorFactory getInstance() { if (instance == null) { instance = new ConfiguratorFactory(); } return instance; } /** * Constructs the propper instance of a given class or interface extending * {@link Configurator}. Correct properties must be loaded in order to * construct objects correctly. * * In the mentioned properties, there has to be a property which key must be * named exactly as the canonical name of the class passed as an argument. * The value of this property must be the canonical name of a class * implementing the property's key. * * @param <T> * Class implementing {@link Configurator} * @param c * Indicates which interface must implement or class must extend * the constructed object * @return Object implementing given class * @throws InvalidClassException * when it is impossible to guess from properties which class to * instantiate from given class/interface. */ public <T extends Configurator> T createConfigManager(Class<T> c) throws InvalidClassException { String className = this.prop.getProperty(c.getCanonicalName()); try { Configurator cfg = (Configurator) Class.forName(className).newInstance(); cfg.setProperties(this.prop); return (T) cfg; } catch (Exception e) { String msg = "Unable to instantiate " + className + " corresponding to " + c.getCanonicalName(); this.log.fatal(msg, e); throw new InvalidClassException(msg, e.getLocalizedMessage()); } } }