001: /*
002: * Copyright 2001-2007 Steven Grimm <koreth[remove] at midwinter dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: DbConnection.java 3442 2006-08-10 09:26:43Z gbevin $
007: */
008: package com.uwyn.rife.tools;
009:
010: import com.uwyn.rife.ioc.HierarchicalProperties;
011: import com.uwyn.rife.ioc.exceptions.MandatoryPropertyMissingException;
012: import java.util.HashMap;
013: import java.util.Map;
014:
015: /**
016: * Maintains a map of singletons of various classes, instantiating new
017: * ones as needed.
018: * @author Steven Grimm (koreth[remove] at midwinter dot com)
019: * @version $Revision: $
020: * @since 1.6
021: */
022: public class SingletonFactory<T> {
023: private Class<T> mClass;
024: private Map<String, T> mSingletons = new HashMap<String, T>();
025:
026: public SingletonFactory(Class<T> klass) {
027: mClass = klass;
028: }
029:
030: /**
031: * Returns a singleton with a particular identifier, or creates one with
032: * a particular class if none exists.
033:
034: * @param className the name of the class a singleton has to be obtained
035: * for
036: * @param identifier an identifier to differentiate several singletons for
037: * the same class
038: * @return the requested singleton instance
039: * @since 1.6
040: */
041: public synchronized T getInstance(String className,
042: String identifier) throws ClassNotFoundException,
043: InstantiationException, IllegalAccessException {
044: if (mSingletons.containsKey(identifier)) {
045: return mSingletons.get(identifier);
046: }
047:
048: Class<T> klass = (Class) Class.forName(className);
049: if (!mClass.isAssignableFrom(klass)) {
050: throw new ClassCastException("Can't cast " + className
051: + " to " + mClass.getName());
052: }
053:
054: T obj = klass.newInstance();
055: mSingletons.put(identifier, obj);
056: return obj;
057: }
058:
059: /**
060: * Returns a singleton instance of a class.
061: *
062: * @param className the name of the class a singleton has to be obtained
063: * for
064: * @return the requested singleton instance
065: * @since 1.6
066: */
067: public T getInstance(String className)
068: throws ClassNotFoundException, InstantiationException,
069: IllegalAccessException {
070: return getInstance(className, className);
071: }
072:
073: /**
074: * Returns an instance of a class based on a required property name from a
075: * properties collection.
076: *
077: * @param properties The properties where the class name has to be obtained from
078: * @param propertyName Which property contains the class name
079: * @param relativeTo Class whose package should be used if no package is
080: * specified in the property
081: * @return the requested singleton instance
082: * @since 1.6
083: */
084: public T getInstance(HierarchicalProperties properties,
085: String propertyName, Class relativeTo)
086: throws MandatoryPropertyMissingException,
087: ClassNotFoundException, InstantiationException,
088: IllegalAccessException {
089: String className = properties.getValueString(propertyName);
090: if (null == className) {
091: throw new MandatoryPropertyMissingException(propertyName);
092: }
093:
094: if (className.indexOf(".") < 0) {
095: className = relativeTo.getPackage().getName() + "."
096: + className;
097: }
098:
099: return getInstance(className);
100: }
101: }
|