001: /*
002: * Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
003: *
004: * This library is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2.1 of the License, or
007: * (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details
013: * (http://www.gnu.org/copyleft/lesser.html).
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package jcckit.util;
020:
021: import java.lang.reflect.*;
022:
023: /**
024: * General purpose factory method based on {@link ConfigParameters}
025: * and Java's Reflection API.
026: *
027: * @author Franz-Josef Elmer
028: */
029: public class Factory {
030: /** The constant defining the key <tt>className</tt>. */
031: public static final String CLASS_NAME_KEY = "className";
032:
033: /** No public constructor necessary. */
034: private Factory() {
035: }
036:
037: /**
038: * Creates an instance of the specified class.
039: * @param className Fully-qualified name of a class with a default
040: * constructor.
041: * @return a new instance.
042: * @throws IllegalArgumentException if the instance could be created.
043: */
044: public static Object create(String className) {
045: try {
046: return Class.forName(className).newInstance();
047: } catch (Throwable t) {
048: throw new IllegalArgumentException(
049: "Could not create an instance of " + className
050: + " because of " + t);
051: }
052: }
053:
054: /**
055: * Creates an object based on the specified configuration
056: * parameters. The class of the object is determined by the
057: * parameter with the key {@link #CLASS_NAME_KEY}.
058: * The constructor with a single argument of the type
059: * <tt>ConfigParameter</tt> is invoked with the argument
060: * <tt>configParameters</tt>. If such a constructor
061: * does not exists the default constructor is invoked. If
062: * neither of these constructors exist a {@link FactoryException}
063: * is thrown.
064: * @param configParameters Configuration parameters.
065: * @return the newly created object.
066: * @throws IllegalArgumentException if key <tt>className</tt> is missing.
067: * @throws FactoryException wrapping any kind of exception or error occured.
068: */
069: public static Object create(ConfigParameters configParameters) {
070: String className = configParameters.get(CLASS_NAME_KEY);
071: return createObject(configParameters, className);
072: }
073:
074: /**
075: * Creates an object based on the specified configuration
076: * parameters and default class name. If the
077: * parameter with the key {@link #CLASS_NAME_KEY} is missed in
078: * <tt>configParameters</tt> <tt>defaultClassName</tt> is used.
079: * Otherwise it works as {@link #create(jcckit.util.ConfigParameters)}.
080: * @param configParameters Configuration parameters.
081: * @param defaultClassName Default class name.
082: * @return the newly created object.
083: * @throws FactoryException wrapping any kind of exception or error occured.
084: */
085: public static Object create(ConfigParameters configParameters,
086: String defaultClassName) {
087: String className = configParameters.get(CLASS_NAME_KEY,
088: defaultClassName);
089: return createObject(configParameters, className);
090: }
091:
092: /**
093: * Creates an object based on the specified configuration
094: * parameters or returns the default object. This method behaves
095: * as {@link #create(jcckit.util.ConfigParameters)}, except that is does
096: * not throw an <tt>IllegalArgumentException</tt> if key <tt>className</tt>
097: * is missing. Instead <tt>defaultObject</tt> is returned.
098: */
099: public static Object createOrGet(ConfigParameters configParameters,
100: Object defaultObject) {
101: String className = configParameters.get(CLASS_NAME_KEY, null);
102: return className == null ? defaultObject : createObject(
103: configParameters, className);
104: }
105:
106: private static Object createObject(
107: ConfigParameters configParameters, String className) {
108: try {
109: Class c = Class.forName(className);
110: Object result = null;
111: Constructor constructor = null;
112: try {
113: constructor = c
114: .getConstructor(new Class[] { ConfigParameters.class });
115: result = constructor
116: .newInstance(new Object[] { configParameters });
117: } catch (NoSuchMethodException e) {
118: result = c.newInstance();
119: }
120: return result;
121: } catch (Throwable t) {
122: throw new FactoryException(configParameters,
123: CLASS_NAME_KEY, t);
124: }
125: }
126: }
|