001: package org.apache.ojb.broker.util.factory;
002:
003: /* Copyright 2002-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import org.apache.commons.lang.SystemUtils;
019: import org.apache.ojb.broker.PersistenceBrokerException;
020: import org.apache.ojb.broker.util.ClassHelper;
021: import org.apache.ojb.broker.util.configuration.Configurable;
022: import org.apache.ojb.broker.util.configuration.Configuration;
023: import org.apache.ojb.broker.util.configuration.ConfigurationException;
024: import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
025: import org.apache.ojb.broker.util.interceptor.InterceptorFactory;
026: import org.apache.ojb.broker.util.logging.Logger;
027: import org.apache.ojb.broker.util.logging.LoggerFactory;
028:
029: /**
030: * ConfigurableFactory is an abstract baseclass for OJB factory classes.
031: * It provides all infrastructure for configuration through OJB.properties.
032: * A derived class must implement the getConfigurationKey() method.
033: * The returned configuration key is used to lookup the class to be instantiated
034: * by the derived factory.
035: * The lookup is performed in the configure() method and uses the OJB.properties
036: * information.
037: *
038: * @author Thomas Mahler
039: */
040: public abstract class ConfigurableFactory implements Configurable {
041: private Logger log = LoggerFactory.getLogger(this .getClass());
042:
043: /**
044: * the class to be served
045: */
046: private Class classToServe = null;
047:
048: /**
049: * the public constructor calls configure() to perform configuration
050: * of the factory instance.
051: */
052: public ConfigurableFactory() {
053: OjbConfigurator.getInstance().configure(this );
054: }
055:
056: /**
057: * must be implemented in the concrete factory classes.
058: * the configuration key is used to lookup the Class to serve
059: * from the OjbConfiguration in configure().
060: */
061: protected abstract String getConfigurationKey();
062:
063: /**
064: * @see org.apache.ojb.broker.util.configuration.Configurable#configure(Configuration)
065: * looks up the the key getConfigurationKey() in the OjbConfiguration
066: * to determine the Class to be served.
067: */
068: public void configure(Configuration pConfig)
069: throws ConfigurationException {
070: if (getConfigurationKey() == null) {
071: getLogger().error(
072: "ConfigurableFactory configuration key is 'null'");
073: throw new PersistenceBrokerException(
074: "ConfigurableFactory configuration key is 'null'");
075: }
076: Class clazz = pConfig.getClass(getConfigurationKey(), null);
077: if (clazz == null) {
078: getLogger().error(
079: "ConfigurableFactory configuration key class for key'"
080: + getConfigurationKey()
081: + "' does not exist.");
082: throw new PersistenceBrokerException(
083: "ConfigurableFactory configuration key class for key'"
084: + getConfigurationKey()
085: + "' does not exist.");
086: }
087: this .setClassToServe(clazz);
088: }
089:
090: /**
091: * factory method for creating new instances
092: * the Class to be instantiated is defined by getClassToServe().
093: * @return Object the created instance
094: */
095: public Object createNewInstance(Class[] types, Object[] args) {
096: try {
097: Object result;
098: // create an instance of the target class
099: if (types != null) {
100: result = ClassHelper.newInstance(getClassToServe(),
101: types, args, true);
102: } else {
103: result = ClassHelper.newInstance(getClassToServe(),
104: true);
105: }
106: // if defined in OJB.properties all instances are wrapped by an interceptor
107: result = InterceptorFactory.getInstance()
108: .createInterceptorFor(result);
109: return result;
110:
111: } catch (InstantiationException e) {
112: getLogger().error(
113: "ConfigurableFactory can't instantiate class "
114: + getClassToServe()
115: + buildArgumentString(types, args), e);
116: throw new PersistenceBrokerException(e);
117: } catch (IllegalAccessException e) {
118: getLogger().error(
119: "ConfigurableFactory can't access constructor for class "
120: + getClassToServe()
121: + buildArgumentString(types, args), e);
122: throw new PersistenceBrokerException(e);
123: } catch (Exception e) {
124: getLogger().error(
125: "ConfigurableFactory instantiation failed for class "
126: + getClassToServe()
127: + buildArgumentString(types, args), e);
128: throw new PersistenceBrokerException(e);
129: }
130: }
131:
132: protected String buildArgumentString(Class[] types, Object[] args) {
133: StringBuffer buf = new StringBuffer();
134: String eol = SystemUtils.LINE_SEPARATOR;
135: buf.append(eol + "* Factory types: ");
136: if (types != null) {
137: for (int i = 0; i < types.length; i++) {
138: Class type = types[i];
139: buf.append(eol + (i + 1) + " - Type: "
140: + (type != null ? type.getName() : null));
141: }
142: } else
143: buf.append(eol + "none");
144:
145: buf.append(eol + "* Factory arguments: ");
146: if (args != null) {
147: for (int i = 0; i < args.length; i++) {
148: Object obj = args[i];
149: buf.append(eol + (i + 1) + " - Argument: " + obj);
150: }
151: } else
152: buf.append(eol + "none");
153: return buf.toString();
154: }
155:
156: /**
157: * factory method for creating new instances
158: * the Class to be instantiated is defined by getClassToServe().
159: * @return Object the created instance
160: */
161: public Object createNewInstance() {
162: return createNewInstance((Class) null, (Object) null);
163: }
164:
165: /**
166: * factory method for creating new instances
167: * the Class to be instantiated is defined by getClassToServe().
168: * @return Object the created instance
169: */
170: public Object createNewInstance(Class type, Object arg) {
171: if (type != null)
172: return createNewInstance(new Class[] { type },
173: new Object[] { arg });
174: else
175: return createNewInstance((Class[]) null, (Object[]) null);
176: }
177:
178: /**
179: * Returns the classToServe.
180: * @return Class
181: */
182: public Class getClassToServe() {
183: return classToServe;
184: }
185:
186: /**
187: * Sets the classToServe.
188: * <br/>
189: * Normally this is done by the factory using
190: * {@link #getConfigurationKey}.
191: * <br/>
192: * <b>Note:</b> For internal use only!
193: * @param classToServe The classToServe to set
194: */
195: public void setClassToServe(Class classToServe) {
196: this .classToServe = classToServe;
197: }
198:
199: /**
200: * the logger for the ConfigurableFactory
201: */
202: protected Logger getLogger() {
203: return log;
204: }
205: }
|