/*
 * Tigase XMPP Client Library
 * Copyright (C) 2006-2012 "Bartosz Małkowski" <bartosz.malkowski@tigase.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. Look for COPYING file in the top folder.
 * If not, see http://www.gnu.org/licenses/.
 */
package tigase.jaxmpp.core.client.factory;

import java.util.HashMap;

/**
 * Provides methods to inject alternative implementation of object in several
 * points in this library.
 * 
 * @author bmalkow
 * 
 */
public class UniversalFactory {

	/**
	 * Interface for object factory.
	 * 
	 * @param <T>
	 *            type of created objects.
	 */
	public static interface FactorySpi<T> {

		/**
		 * Creates new instance of class.
		 * 
		 * @return
		 */
		T create();
	}

	private static UniversalFactory instance;

	/**
	 * Creates instance of object with given name.
	 * 
	 * @param key
	 *            name of object.
	 * @return instance of object or <code>null</code> if no factory is
	 *         registered for that name.
	 */
	public static <T> T createInstance(String key) {
		FactorySpi<T> spi = (FactorySpi<T>) instance().factories.get(key);
		if (spi == null)
			return null;
		return spi.create();
	}

	static UniversalFactory instance() {
		if (instance == null)
			instance = new UniversalFactory();
		return instance;
	}

	/**
	 * Registers object factory with name.
	 * 
	 * @param key
	 *            name of object factory.
	 * @param spi
	 *            implementation of factory.
	 */
	public static void setSpi(String key, FactorySpi<?> spi) {
		instance().factories.put(key, spi);
	}

	private final HashMap<String, FactorySpi<?>> factories = new HashMap<String, FactorySpi<?>>();

	private UniversalFactory() {
	}

}
@@ -1856,24 +1856,83 @@
 y with name.
+ Previously registered factory will%0A%09 * not be overwritten.
 %0A%09 * %0A%09 * @p
@@ -2101,16 +2101,487 @@
  spi) %7B%0A
+%09%09setSpi(key, spi, false);%0A%09%7D%0A%0A%09/**%0A%09 * Registers object factory with name.%0A%09 * %0A%09 * @param key%0A%09 *            name of object factory.%0A%09 * @param spi%0A%09 *            implementation of factory.%0A%09 * @param overwrite%0A%09 *            %3Ccode%3Etrue%3C/code%3E if previously registered factory should be%0A%09 *            overwritten.%0A%09 */%0A%09public static void setSpi(String key, FactorySpi%3C?%3E spi, boolean overwrite) %7B%0A%09%09if (!overwrite && instance().factories.containsKey(key))%0A%09%09%09return;%0A
 %09%09instan

add "overwrite" parameter to factory register method