001/*
002 * GWTEventService
003 * Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr?nkt)
004 *
005 * This is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU Lesser General Public License as
007 * published by the Free Software Foundation; either version 3 of
008 * the License, or (at your option) any later version.
009 * Other licensing for GWTEventService may also be possible on request.
010 * Please view the license.txt of the project for more information.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022package de.novanic.eventservice.client.config;
023
024import com.google.gwt.core.client.GWT;
025import de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector;
026import de.novanic.eventservice.client.connection.strategy.connector.DefaultClientConnector;
027import de.novanic.eventservice.client.connection.strategy.connector.streaming.GWTStreamingClientConnector;
028
029/**
030 * The {@link de.novanic.eventservice.client.config.ConfigurationTransferableDependentFactory} can create instances from a transferable configuration
031 * ({@link de.novanic.eventservice.client.config.EventServiceConfigurationTransferable}) which can be configured with a class name.
032 * The created instances are hold as a singleton.
033 *
034 * @author sstrohschein
035 *         <br>Date: 16.04.2010
036 *         <br>Time: 23:59:58
037 */
038public final class ConfigurationTransferableDependentFactory
039{
040    private static EventServiceConfigurationTransferable myConfiguration;
041
042    private ConnectionStrategyClientConnector myConnectionStrategyClientConnector;
043
044    /**
045     * That constructor is only called one time, because the factory is created as a singleton.
046     */
047    private ConfigurationTransferableDependentFactory() {}
048
049    /**
050     * Factory-Holder class to ensure thread-safe lazy-loading with IODH.
051     */
052    private static class ConfigTransferableDependentFactoryHolder {
053        private static ConfigurationTransferableDependentFactory INSTANCE = new ConfigurationTransferableDependentFactory();
054    }
055
056    /**
057     * This method should be used to create an instance of {@link ConfigurationTransferableDependentFactory}.
058     * {@link ConfigurationTransferableDependentFactory} is a singleton, so this method returns always the same instance of
059     * {@link ConfigurationTransferableDependentFactory}. This method initializes the factory with a configuration and should be
060     * called before {@link ConfigurationTransferableDependentFactory#getInstance()} is used, because it has to be initialized with
061     * with a configuration at first.
062     * @return {@link ConfigurationTransferableDependentFactory} (singleton)
063     */
064    public static ConfigurationTransferableDependentFactory getInstance(EventServiceConfigurationTransferable aConfiguration) {
065        if(aConfiguration == null) {
066            throw new ConfigurationException(ConfigurationTransferableDependentFactory.class.getName() + " has to be initialized with a configuration!");
067        }
068        final boolean isReInit;
069        if(myConfiguration == null) {
070            myConfiguration = aConfiguration;
071            isReInit = true;
072        } else {
073            isReInit = false;
074        }
075        ConfigurationTransferableDependentFactory theInstance = ConfigTransferableDependentFactoryHolder.INSTANCE;
076        if(isReInit) {
077            theInstance.init();
078        }
079        return theInstance;
080    }
081
082    /**
083     * This method returns the {@link ConfigurationTransferableDependentFactory} as a singleton. It has to be initialized
084     * with a configuration at first. Therefore the method {@link ConfigurationTransferableDependentFactory#getInstance(EventServiceConfigurationTransferable)} should
085     * be used at first.
086     * @return {@link ConfigurationTransferableDependentFactory} (singleton)
087     */
088    public static ConfigurationTransferableDependentFactory getInstance() {
089        if(myConfiguration == null) {
090            throw new ConfigurationException(ConfigurationTransferableDependentFactory.class.getName() + " has to be initialized with a configuration before!");
091        }
092        return ConfigTransferableDependentFactoryHolder.INSTANCE;
093    }
094
095    /**
096     * Creates the configured instances from the configuration.
097     */
098    private void init() {
099        if(myConfiguration != null) {
100            myConnectionStrategyClientConnector = createObject(myConfiguration.getConnectionStrategyClientConnector());
101        } else {
102            myConnectionStrategyClientConnector = null;
103        }
104    }
105
106    /**
107     * Returns the configured {@link de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector}.
108     * @return configured {@link de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector}
109     */
110    public ConnectionStrategyClientConnector getConnectionStrategyClientConnector() {
111        return myConnectionStrategyClientConnector;
112    }
113
114    /**
115     * Creates and initializes an object of a specific type.
116     */
117    @SuppressWarnings("unchecked")
118    private static <T> T createObject(String aClassName) {
119        //GWT doesn't support instance creation from a String (via reflection)
120        if(aClassName.equals(DefaultClientConnector.class.getName())) {
121            return (T)new DefaultClientConnector();
122        } else if(aClassName.equals(GWTStreamingClientConnector.class.getName())) {
123            return (T)GWT.create(GWTStreamingClientConnector.class);
124        } else {
125            throw new ConfigurationException("The configured class \"" + aClassName + "\" is unknown!");
126        }
127    }
128
129    /**
130     * Returns the configuration which was specified with the initialization of the {@link ConfigurationTransferableDependentFactory}.
131     * @see {@link ConfigurationTransferableDependentFactory#getInstance(EventServiceConfigurationTransferable)}
132     * @return configuration which was specified with the initialization of the {@link ConfigurationTransferableDependentFactory}
133     */
134    public static EventServiceConfigurationTransferable getConfiguration() {
135        return myConfiguration;
136    }
137
138    /**
139     * Resets the {@link ConfigurationTransferableDependentFactory}.
140     * It has to be re-initialized with {@link #getInstance(EventServiceConfigurationTransferable)}.
141     */
142    public static void reset() {
143        final ConfigurationTransferableDependentFactory theSingleton = ConfigTransferableDependentFactoryHolder.INSTANCE;
144        myConfiguration = null;
145        theSingleton.init();
146    }
147}