Index: C:/Java/castor-1/codegen/src/main/java/org/exolab/castor/builder/SourceGenerator.java
===================================================================
--- C:/Java/castor-1/codegen/src/main/java/org/exolab/castor/builder/SourceGenerator.java (revision 7076)
+++ C:/Java/castor-1/codegen/src/main/java/org/exolab/castor/builder/SourceGenerator.java (working copy)
@@ -61,6 +61,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.castor.core.exceptions.CastorRuntimeException;
import org.exolab.castor.builder.binding.BindingException;
import org.exolab.castor.builder.binding.BindingLoader;
import org.exolab.castor.builder.binding.ExtendedBinding;
@@ -76,7 +77,6 @@
import org.exolab.castor.builder.factory.FieldInfoFactory;
import org.exolab.castor.builder.factory.SourceFactory;
import org.exolab.castor.builder.info.ClassInfo;
-import org.exolab.castor.core.exceptions.CastorRuntimeException;
import org.exolab.castor.mapping.xml.MappingRoot;
import org.exolab.castor.util.Configuration;
import org.exolab.castor.util.LocalConfiguration;
Index: C:/Java/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java
===================================================================
--- C:/Java/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java (revision 0)
+++ C:/Java/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java (revision 0)
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2007 Ralf Joachim
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: Configuration.java 6907 2007-03-28 21:24:52Z rjoachim $
+ */
+package org.castor.cpa;
+
+import org.castor.core.CoreConfiguration;
+import org.castor.core.util.CastorConfiguration;
+import org.castor.core.util.Configuration;
+import org.castor.xml.XMLConfiguration;
+
+/**
+ * Castor configuration of CPA modul.
+ *
+ * @version $Id: Configuration.java,v 1.8 2006/03/08 17:25:52 jens Exp $
+ * @author Ralf Joachim
+ * @since 1.1.3
+ */
+public final class CPAConfiguration extends Configuration {
+ //--------------------------------------------------------------------------
+
+ /** Path to Castor configuration of core modul. */
+ private static final String FILEPATH = "/org/castor/cpa/";
+
+ /** Name of Castor configuration of core modul. */
+ private static final String FILENAME = "castor.cpa.properties";
+
+ /** A static configuration instance to be used during migration to a none static one. */
+ // TODO Remove property after support for static configuration has been terminated.
+ private static Configuration _instance = null;
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the one and only static CPA configuration.
+ *
+ * @return One and only configuration instance for Castor CPA modul.
+ * @deprecated Don't limit your applications flexibility by using a static configuration. Use
+ * your own configuration instance created with one of the newInstance() methods
+ * instead.
+ */
+ // TODO Remove method after support for static configuration has been terminated.
+ public static synchronized Configuration getInstance() {
+ if (_instance == null) { _instance = newInstance(); }
+ return _instance;
+ }
+
+ /**
+ * Factory method for a default CPA configuration instance. Application and domain class
+ * loaders will be initialized to the one used to load the Configuration class. The
+ * configuration instance returned will be a CastorConfiguration with a CPAConfiguration, a
+ * XMLConfiguration and a CoreConfiguration instance as parents. The CastorConfiguration
+ * holding user specific properties is the only one that can be modified by put() and remove()
+ * methods. CPAConfiguration, XMLConfiguration and CoreConfiguration are responsble to deliver
+ * Castor's default values if they have not been overwritten by the user.
+ *
+ * @return Configuration instance for Castor CPA modul.
+ */
+ public static Configuration newInstance() {
+ Configuration core = new CoreConfiguration();
+ Configuration cpa = new CPAConfiguration(core);
+ Configuration xml = new XMLConfiguration(cpa);
+ Configuration castor = new CastorConfiguration(xml);
+ return castor;
+ }
+
+ /**
+ * Factory method for a CPA configuration instance that uses the specified class loaders. The
+ * configuration instance returned will be a CastorConfiguration with a CPAConfiguration, a
+ * XMLConfiguration and a CoreConfiguration instance as parents. The CastorConfiguration
+ * holding user specific properties is the only one that can be modified by put() and remove()
+ * methods. CPAConfiguration, XMLConfiguration and CoreConfiguration are responsble to deliver
+ * Castor's default values if they have not been overwritten by the user.
+ *
+ * @param app Classloader to be used for all classes of Castor and its required libraries.
+ * @param domain Classloader to be used for all domain objects.
+ * @return Configuration instance for Castor CPA modul.
+ */
+ public static Configuration newInstance(final ClassLoader app, final ClassLoader domain) {
+ Configuration core = new CoreConfiguration(app, domain);
+ Configuration cpa = new CPAConfiguration(core);
+ Configuration xml = new XMLConfiguration(cpa);
+ Configuration castor = new CastorConfiguration(xml);
+ return castor;
+ }
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a configuration with given parent. Application and domain class loaders will be
+ * initialized to the ones of the parent.
+ *
+ * Note: This constructor is not intended for public use. Use one of the newInstance() methods
+ * instead.
+ *
+ * @param parent Parent configuration.
+ */
+ public CPAConfiguration(final Configuration parent) {
+ super(parent);
+ loadDefaultProperties(FILEPATH, FILENAME);
+ }
+
+ //--------------------------------------------------------------------------
+
+ // Specify public keys of xml configuration properties here.
+
+ /** Property listing all available {@link org.castor.cache.Cache} implementations
+ * (org.castor.cache.Factories). */
+ public static final String CACHE_FACTORIES =
+ "org.castor.cache.Factories";
+
+ /** Property listing all the available
+ * {@link org.castor.transactionmanager.TransactionManagerFactory}
+ * implementations (org.castor.transaction.TransactionManagerFactories). */
+ public static final String TRANSACTION_MANAGER_FACTORIES =
+ "org.castor.transactionmanager.Factories";
+
+ /** Property telling if TransactionManager should be initialized at registration. */
+ public static final String TRANSACTION_MANAGER_INIT =
+ "org.castor.transactionmanager.InitializeAtRegistration";
+
+ /** Property telling if database should be initialized when loading. */
+ public static final String INITIALIZE_AT_LOAD =
+ "org.exolab.castor.jdo.DatabaseInitializeAtLoad";
+
+ /** Property name of default timezone in castor.properties. */
+ public static final String DEFAULT_TIMEZONE =
+ "org.exolab.castor.jdo.defaultTimeZone";
+
+ /** Property listing all the available key genence
+ * factories. (org.exolab.castor.jdo.keyGeneratorFactories). */
+ public static final String KEYGENERATOR_FACTORIES =
+ "org.exolab.castor.jdo.keyGeneratorFactories";
+
+ /** Property name of LOB buffer size in castor.properties. */
+ public static final String LOB_BUFFER_SIZE =
+ "org.exolab.castor.jdo.lobBufferSize";
+
+ /** Property listing all the available persistence
+ * factories. (org.exolab.castor.jdo.engines). */
+ public static final String PERSISTENCE_FACTORIES =
+ "org.exolab.castor.jdo.engines";
+
+ /** Property listing all the available
+ * {@link org.exolab.castor.persist.TxSynchronizable}
+ * implementations (org.exolab.castor.persit.TxSynchronizable). */
+ public static final String TX_SYNCHRONIZABLE =
+ "org.exolab.castor.persist.TxSynchronizable";
+
+ /** Property specifying whether JDBC 3.0-specific features should be used,
+ * such as e.g. the use of Statement.getGeneratedKeys()
+ *
org.castor.jdo.use.jdbc30. */ + public static final String USE_JDBC30 = + "org.castor.jdo.use.jdbc30"; + + /** Property specifying whether JDBC proxy classes should be used + *
org.exolab.castor.persist.useProxies. */ + public static final String USE_JDBC_PROXIES = + "org.exolab.castor.persist.useProxies"; + + //-------------------------------------------------------------------------- +} Index: C:/Java/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties =================================================================== --- C:/Java/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties (revision 0) +++ C:/Java/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties (revision 0) @@ -0,0 +1,104 @@ +# Castor CPA properties file +# +# This file specifies default values of Castor's CPA modul which may be +# overwritten by the user through castor.properties file. +# +# $Id: castor.properties 7076 2007-07-24 22:03:25Z rjoachim $ + + +# List of persistence factories for the supported database servers: +# +org.exolab.castor.jdo.engines=\ + org.exolab.castor.jdo.drivers.OracleFactory,\ + org.exolab.castor.jdo.drivers.PostgreSQLFactory,\ + org.exolab.castor.jdo.drivers.SybaseFactory,\ + org.exolab.castor.jdo.drivers.SQLServerFactory,\ + org.exolab.castor.jdo.drivers.DB2Factory,\ + org.exolab.castor.jdo.drivers.InformixFactory,\ + org.exolab.castor.jdo.drivers.HsqlFactory,\ + org.exolab.castor.jdo.drivers.InstantDBFactory,\ + org.exolab.castor.jdo.drivers.InterbaseFactory,\ + org.exolab.castor.jdo.drivers.MySQLFactory,\ + org.exolab.castor.jdo.drivers.SapDbFactory,\ + org.exolab.castor.jdo.drivers.GenericFactory,\ + org.exolab.castor.jdo.drivers.DerbyFactory,\ + org.castor.jdo.drivers.PointbaseFactory,\ + org.castor.jdo.drivers.ProgressFactory + +# List of key generator factories: +# +org.exolab.castor.jdo.keyGeneratorFactories=\ + org.exolab.castor.jdo.keygen.MaxKeyGeneratorFactory,\ + org.exolab.castor.jdo.keygen.HighLowKeyGeneratorFactory,\ + org.exolab.castor.jdo.keygen.IdentityKeyGeneratorFactory,\ + org.exolab.castor.jdo.keygen.SequenceKeyGeneratorFactory,\ + org.exolab.castor.jdo.keygen.UUIDKeyGeneratorFactory + +# Configures the default time zone to apply to dates/times fetched from database +# fields (if not already part of the data). Specify same format as in +# java.util.TimeZone.getTimeZone (e.g GMT-8:00), or the empty string to use the +# computer's local time zone. Please see http://de.wikipedia.org/wiki/Zeitzone for +# detailed information about time zones. +# +org.exolab.castor.jdo.defaultTimeZone= + +# List of TxSynchronizeable implementations: +# +#org.exolab.castor.persist.TxSynchronizable= + +# Sets the buffer size in bytes for fetching LOBs (this is dependent upon +# the JDBC driver implementation). The value below == 5k. +# +org.exolab.castor.jdo.lobBufferSize=5120 + +# True if database configuration should be initalized dircetly after loading it. +# When set to false the database instances are lazy initialized at first use. +# Defaults to true. +# +org.exolab.castor.jdo.DatabaseInitializeAtLoad=true + +# True if proxy classes should be used for JDBC connections and prepared statements. +# Defaults to true. +# +org.exolab.castor.persist.useProxies=false + +# Cache implementations: +# +org.castor.cache.Factories=\ + org.castor.cache.simple.NoCacheFactory,\ + org.castor.cache.simple.TimeLimitedFactory,\ + org.castor.cache.simple.CountLimitedFactory,\ + org.castor.cache.simple.UnlimitedFactory,\ + org.castor.cache.distributed.FKCacheFactory,\ + org.castor.cache.distributed.JcsCacheFactory,\ + org.castor.cache.distributed.JCacheFactory,\ + org.castor.cache.distributed.CoherenceCacheFactory,\ + org.castor.cache.distributed.OsCacheFactory,\ + org.castor.cache.hashbelt.FIFOHashbeltFactory,\ + org.castor.cache.hashbelt.LRUHashbeltFactory,\ + org.castor.cache.distributed.EHCacheFactory,\ + org.castor.cache.distributed.GigaspacesCacheFactory + +# TransactionManagerFactory implementations: +# +org.castor.transactionmanager.Factories=\ + org.castor.transactionmanager.WebSphereTransactionManagerFactory,\ + org.castor.transactionmanager.WebSphere5TransactionManagerFactory,\ + org.castor.transactionmanager.WebSphere51TransactionManagerFactory,\ + org.castor.transactionmanager.LocalTransactionManagerFactory,\ + org.castor.transactionmanager.JNDIENCTransactionManagerFactory,\ + org.castor.transactionmanager.JOTMTransactionManagerFactory + +# Selects whether the TransactionManager should be initialized at registration, +# or lazily when requested for the first time. Defaults to false. +# +org.castor.transactionmanager.InitializeAtRegistration=false + +# Instructs Castor JDO to use the JDBC 3.0-specific features to obtain the +# generated value of an identity column. Defaults to false. +# +org.castor.jdo.use.jdbc30=false + +# Specifies whether to use ANSI-compliant SQL for MS SQL Server. Defaults to false. +# +org.exolab.castor.jdo.sqlserver.ansi-compliant=false Index: C:/Java/castor-1/src/doc/release-notes.xml =================================================================== --- C:/Java/castor-1/src/doc/release-notes.xml (revision 7076) +++ C:/Java/castor-1/src/doc/release-notes.xml (working copy) @@ -69,8 +69,39 @@
Be aware that no proxy interfaces are defined by default as the interface search slightly decreases marshalling performance.
+We have added a new class hierarchy to handle independed configurations + for every modul of Castor. At the moment the old configuration classes + are still used but everything is in place to use the new one. Having said + that this should not change anything for the user of Castor as he still + specifies his properties in a single castor.properties file for all + moduls.
+null if the cause is nonexistent or unknown. */
+ private Throwable _cause = null;
- /** The cause for this exception. */
- private Throwable _cause;
+ /** Has the cause of this exception been initialized? */
+ private boolean _initCause = false;
+ /**
+ * Constructs a new Castor runtime exception without a message. The cause is not initialized
+ * but may subsequently be initialized by a call to initCause(Throwable).
+ */
public CastorRuntimeException() {
super();
}
@@ -14,26 +46,59 @@
super();
}
+ /**
+ * Constructs a new Castor runtime exception with the specified detail message. The cause is
+ * not initialized but may subsequently be initialized by a call to initCause(Throwable).
+ *
+ * @param message The detail message.
+ */
+ public CastorRuntimeException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new Castor runtime exception with the specified cause and the detail message
+ * of the cause. This constructor is useful for exceptions that are wrappers for others.
+ *
+ * @param cause The cause.
+ */
public CastorRuntimeException(final Throwable cause) {
- super();
+ super((cause == null) ? null : cause.getMessage());
_cause = cause;
+ _initCause = true;
}
- public CastorRuntimeException(final String message) {
+ /**
+ * Constructs a new Castor runtime exception with the specified detail message and cause.
+ *
+ * @param message The detail message.
+ * @param cause The cause.
+ */
+ public CastorRuntimeException(final String message, final Throwable cause) {
super(message);
+ _cause = cause;
+ _initCause = true;
}
-
- public CastorRuntimeException(final String message, final Throwable cause) {
- super(message);
+
+ /**
+ * The method emulates the JDK 1.4 Throwable version of initCause() for JDKs before 1.4.
+ * true if properties could be loaded, false otherwise.
+ */
+ private boolean loadFromClassPath(final Properties properties, final String filename) {
+ InputStream classPathStream = null;
+ try {
+ URL url = getClass().getResource(filename);
+ if (url != null) {
+ classPathStream = url.openStream();
+ properties.load(classPathStream);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Configuration loaded from classpath: " + filename);
+ }
+
+ return true;
+ }
+ return false;
+ } catch (Exception ex) {
+ LOG.warn("Failed to load configuration from classpath: " + filename, ex);
+ return false;
+ } finally {
+ if (classPathStream != null) {
+ try {
+ classPathStream.close();
+ } catch (IOException e) {
+ LOG.warn("Failed to close configuration from classpath: " + filename);
+ }
+ }
+ }
+ }
+
+ /**
+ * Load properties with given filename from Java library directory and merge them into
+ * the given properties.
+ *
+ * @param properties Properties to merge the loaded ones into.
+ * @param filename Name of the properties file to load from Java library directory.
+ * @return true if properties could be loaded, false otherwise.
+ */
+ private boolean loadFromJavaHome(final Properties properties, final String filename) {
+ try {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome == null) { return false; }
+ return loadFromFile(properties, new File(new File(javaHome, "lib"), filename));
+ } catch (SecurityException ex) {
+ LOG.warn("Security policy prevented access to system property 'java.home'.", ex);
+ return false;
+ }
+ }
+
+ /**
+ * Load properties with given filename from local working directory and merge them into
+ * the given properties.
+ *
+ * @param properties Properties to merge the loaded ones into.
+ * @param filename Name of the properties file to load from local working directory.
+ * @return true if properties could be loaded, false otherwise.
+ */
+ private boolean loadFromWorkingDirectory(final Properties properties, final String filename) {
+ return loadFromFile(properties, new File(filename));
+ }
+
+ /**
+ * Load properties with given file and merge them into the given properties.
+ *
+ * @param properties Properties to merge the loaded ones into.
+ * @param file Properties file to load.
+ * @return true if properties could be loaded, false otherwise.
+ */
+ private boolean loadFromFile(final Properties properties, final File file) {
+ InputStream fileStream = null;
+ try {
+ if (file.exists() && file.canRead()) {
+ fileStream = new FileInputStream(file);
+ properties.load(fileStream);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Configuration file loaded: " + file);
+ }
+
+ return true;
+ }
+ return false;
+ } catch (SecurityException ex) {
+ LOG.warn("Security policy prevented access to configuration file: " + file, ex);
+ return false;
+ } catch (Exception ex) {
+ LOG.warn("Failed to load configuration file: " + file, ex);
+ return false;
+ } finally {
+ if (fileStream != null) {
+ try {
+ fileStream.close();
+ } catch (IOException e) {
+ LOG.warn("Failed to close configuration file: " + file);
+ }
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Put given value associated with given key into the properties map of this configuration. If
+ * the configuration previously associated the key to another value the previous value will be
+ * returned. If a mapping for the key previously exist in the parent configuration only, the
+ * method returns null and not the value of the parent. This allows to distingush
+ * if the mapping existed in this configuration or one of its parents.
+ * NullPointerException will be thrown if the given value is
+ * null.
+ *
+ * @param key Key of the property to put into configuration.
+ * @param value Value to put into configuration associated with the given key..
+ * @return Object in this configuration that previously has been associated with the given key.
+ */
+ public final synchronized Object put(final String key, final Object value) {
+ if (value == null) { throw new NullPointerException(); }
+ return _map.put(key, value);
+ }
+
+ /**
+ * Remove any value previously associated with the given key from this configuration. The value
+ * previously associated with the key int this configuration will be returned. If a mapping
+ * for the key existed in the parent configuration only, the method returns null
+ * and not the value of the parent. This allows to distingush if the mapping existed in this
+ * configuration or one of its parents.
+ * null as one of the parents may still contain a mapping for the key that
+ * was hidden by the mapping in this configuration.
+ *
+ * @param key Key of the property to remove from configuration.
+ * @return Object in this configuration that previously has been associated with the given key.
+ */
+ public final synchronized Object remove(final String key) {
+ return _map.remove(key);
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned.
+ *
+ * @param key Key of the property to get from configuration.
+ * @return Object in this property map with the specified key value.
+ */
+ protected synchronized Object get(final String key) {
+ Object value = _map.get(key);
+ if ((value == null) && (_parent != null)) {
+ value = _parent.get(key);
+ }
+ return value;
+ }
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other types and
+ * string values a ConfigurationException will be thrown. This behaviour is intended for those
+ * usecases that need distinguish between values that are missconfigured or not specified at
+ * all.
+ *
+ * @param key Property key.
+ * @return Boolean value in this property map with the specified key value.
+ */
+ public final Boolean getBoolean(final String key) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof Boolean) {
+ return (Boolean) objectValue;
+ } else if (objectValue instanceof String) {
+ String stringValue = (String) objectValue;
+ if ("true".equalsIgnoreCase(stringValue)) {
+ return Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(stringValue)) {
+ return Boolean.FALSE;
+ }
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value can not be converted to boolean: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other types and
+ * string values a ConfigurationException will be thrown. This behaviour is intended for those
+ * usecases that need distinguish between values that are missconfigured or not specified at
+ * all.
+ *
+ * @param key Property key.
+ * @return Integer value in this property map with the specified key value.
+ */
+ public final Integer getInteger(final String key) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof Integer) {
+ return (Integer) objectValue;
+ } else if (objectValue instanceof String) {
+ try {
+ return Integer.valueOf((String) objectValue);
+ } catch (NumberFormatException ex) {
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value can not be converted to int: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ }
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value can not be converted to int: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other types a ConfigurationException will be
+ * thrown.
+ *
+ * @param key Property key.
+ * @return String value in this property map with the specified key value.
+ */
+ public final String getString(final String key) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof String) {
+ return (String) objectValue;
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value is not a string: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other
+ * types a ConfigurationException will be thrown.
+ *
+ * @param key Property key.
+ * @return String array in this property map with the specified key value.
+ */
+ public final String[] getStringArray(final String key) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof String[]) {
+ return (String[]) objectValue;
+ } else if (objectValue instanceof String) {
+ return ((String) objectValue).split(",");
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value is not a String[]: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other types and if loading of the
+ * class fails a ConfigurationException will be thrown.
+ *
+ * @param key Property key.
+ * @param loader Class loader to load classes with.
+ * @return Class in this property map with the specified key value.
+ */
+ public final Class getClass(final String key, final ClassLoader loader) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof Class) {
+ return (Class) objectValue;
+ } else if (objectValue instanceof String) {
+ String classname = (String) objectValue;
+ try {
+ return loader.loadClass(classname);
+ } catch (ClassNotFoundException ex) {
+ Object[] args = new Object[] {key, classname};
+ String msg = "Could not find class of configuration value: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ }
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value is not a Class: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other
+ * types and if loading of one of the classes fails a ConfigurationException will be thrown.
+ *
+ * @param key Property key.
+ * @param loader Class loader to load classes with.
+ * @return Class array in this property map with the specified key value.
+ */
+ public final Class[] getClassArray(final String key, final ClassLoader loader) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof Class[]) {
+ return (Class[]) objectValue;
+ } else if (objectValue instanceof String) {
+ String[] classnames = ((String) objectValue).split(",");
+ Class[] classes = new Class[classnames.length];
+ for (int i = 0; i < classnames.length; i++) {
+ try {
+ classes[i] = loader.loadClass(classnames[i]);
+ } catch (ClassNotFoundException ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not find class of configuration value: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ }
+ }
+ return classes;
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value is not a Class[]: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned.
+ *
+ * @param key Property key.
+ * @return Object in this property map with the specified key value.
+ */
+ public final Object getObject(final String key) {
+ return get(key);
+ }
+
+ /**
+ * Searches for the property with the specified key in this property map. If the key is not
+ * found in this property map, the parent property map, and its parents, recursively, are then
+ * checked.
+ * null will be returned. For all other types and if loading or instantiation of
+ * one of the classes fails a ConfigurationException will be thrown.
+ *
+ * @param key Property key.
+ * @param loader Class loader to load classes with.
+ * @return Class array in this property map with the specified key value.
+ */
+ public final Object[] getObjectArray(final String key, final ClassLoader loader) {
+ Object objectValue = get(key);
+
+ if (objectValue == null) {
+ return null;
+ } else if (objectValue instanceof Object[]) {
+ return (Object[]) objectValue;
+ } else if (objectValue instanceof String) {
+ String[] classnames = ((String) objectValue).split(",");
+ Object[] objects = new Class[classnames.length];
+ for (int i = 0; i < classnames.length; i++) {
+ try {
+ objects[i] = loader.loadClass(classnames[i]).newInstance();
+ } catch (ClassNotFoundException ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not find configured class: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ } catch (IllegalAccessException ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not instantiate configured class: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ } catch (InstantiationException ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not instantiate configured class: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ } catch (ExceptionInInitializerError ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not instantiate configured class: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ } catch (SecurityException ex) {
+ Object[] args = new Object[] {key, new Integer(i), classnames[i]};
+ String msg = "Could not instantiate configured class: {0}[{1}]={2}";
+ throw new ConfigurationException(MessageFormat.format(msg, args), ex);
+ }
+ }
+ return objects;
+ }
+
+ Object[] args = new Object[] {key, objectValue};
+ String msg = "Configuration value is not an Object[]: {0}={1}";
+ throw new ConfigurationException(MessageFormat.format(msg, args));
+ }
+
+ //--------------------------------------------------------------------------
+}
Index: C:/Java/castor-1/src/main/java/org/castor/core/util/ConfigurationException.java
===================================================================
--- C:/Java/castor-1/src/main/java/org/castor/core/util/ConfigurationException.java (revision 0)
+++ C:/Java/castor-1/src/main/java/org/castor/core/util/ConfigurationException.java (revision 0)
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2007 Ralf Joachim
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: Configuration.java 6907 2007-03-28 21:24:52Z rjoachim $
+ */
+package org.castor.core.util;
+
+import org.castor.core.exceptions.CastorRuntimeException;
+
+/**
+ * ConfigurationException is an unchecked exception thrown when Configuration can not be loaded
+ * or if configuration property can't be converted to the requested type.
+ *
+ * @version $Id: Configuration.java,v 1.8 2006/03/08 17:25:52 jens Exp $
+ * @author Ralf Joachim
+ * @since 1.1.3
+ */
+public final class ConfigurationException extends CastorRuntimeException {
+ /** SerialVersionUID */
+ private static final long serialVersionUID = 4446761026170253291L;
+
+ /**
+ * Constructs a new ConfigurationException without a message. The cause is not initialized
+ * but may subsequently be initialized by a call to initCause(Throwable).
+ */
+ public ConfigurationException() {
+ super();
+ }
+
+ /**
+ * Constructs a new ConfigurationException with the specified detail message. The cause is
+ * not initialized but may subsequently be initialized by a call to initCause(Throwable).
+ *
+ * @param message The detail message.
+ */
+ public ConfigurationException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new ConfigurationException with the specified cause and the detail message
+ * of the cause. This constructor is useful for exceptions that are wrappers for others.
+ *
+ * @param cause The cause.
+ */
+ public ConfigurationException(final Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new ConfigurationException with the specified detail message and cause.
+ *
+ * @param message The detail message.
+ * @param cause The cause.
+ */
+ public ConfigurationException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
Index: C:/Java/castor-1/src/main/java/org/castor/util/Configuration.java
===================================================================
--- C:/Java/castor-1/src/main/java/org/castor/util/Configuration.java (revision 7076)
+++ C:/Java/castor-1/src/main/java/org/castor/util/Configuration.java (working copy)
@@ -30,7 +30,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.exolab.castor.core.exceptions.CastorRuntimeException;
+import org.castor.core.exceptions.CastorRuntimeException;
/**
* Class to hold Castor configuration properties.
Index: C:/Java/castor-1/src/main/java/org/castor/xml/XMLConfiguration.java
===================================================================
--- C:/Java/castor-1/src/main/java/org/castor/xml/XMLConfiguration.java (revision 0)
+++ C:/Java/castor-1/src/main/java/org/castor/xml/XMLConfiguration.java (revision 0)
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Ralf Joachim
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: Configuration.java 6907 2007-03-28 21:24:52Z rjoachim $
+ */
+package org.castor.xml;
+
+import org.castor.core.CoreConfiguration;
+import org.castor.core.util.CastorConfiguration;
+import org.castor.core.util.Configuration;
+
+/**
+ * Castor configuration of XML modul.
+ *
+ * @version $Id: Configuration.java,v 1.8 2006/03/08 17:25:52 jens Exp $
+ * @author Ralf Joachim
+ * @since 1.1.3
+ */
+public final class XMLConfiguration extends Configuration {
+ //--------------------------------------------------------------------------
+
+ /** Path to Castor configuration of core modul. */
+ private static final String FILEPATH = "/org/castor/xml/";
+
+ /** Name of Castor configuration of core modul. */
+ private static final String FILENAME = "castor.xml.properties";
+
+ /** A static configuration instance to be used during migration to a none static one. */
+ // TODO Remove property after support for static configuration has been terminated.
+ private static Configuration _instance = null;
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the one and only static XML configuration.
+ *
+ * @return One and only configuration instance for Castor XML modul.
+ * @deprecated Don't limit your applications flexibility by using a static configuration. Use
+ * your own configuration instance created with one of the newInstance() methods
+ * instead.
+ */
+ // TODO Remove method after support for static configuration has been terminated.
+ public static synchronized Configuration getInstance() {
+ if (_instance == null) { _instance = newInstance(); }
+ return _instance;
+ }
+
+ /**
+ * Factory method for a default XML configuration instance. Application and domain class
+ * loaders will be initialized to the one used to load the Configuration class. The
+ * configuration instance returned will be a CastorConfiguration with a XMLConfiguration and
+ * a CoreConfiguration instance as parents. The CastorConfiguration holding user specific
+ * properties is the only one that can be modified by put() and remove() methods.
+ * XMLConfiguration and CoreConfiguration are responsble to deliver Castor's default values
+ * if they have not been overwritten by the user.
+ *
+ * @return Configuration instance for Castor XML modul.
+ */
+ public static Configuration newInstance() {
+ Configuration core = new CoreConfiguration();
+ Configuration xml = new XMLConfiguration(core);
+ Configuration castor = new CastorConfiguration(xml);
+ return castor;
+ }
+
+ /**
+ * Factory method for a XML configuration instance that uses the specified class loaders. The
+ * configuration instance returned will be a CastorConfiguration with a XMLConfiguration and
+ * a CoreConfiguration instance as parents. The CastorConfiguration holding user specific
+ * properties is the only one that can be modified by put() and remove() methods.
+ * XMLConfiguration and CoreConfiguration are responsble to deliver Castor's default values
+ * if they have not been overwritten by the user.
+ *
+ * @param app Classloader to be used for all classes of Castor and its required libraries.
+ * @param domain Classloader to be used for all domain objects.
+ * @return Configuration instance for Castor XML modul.
+ */
+ public static Configuration newInstance(final ClassLoader app, final ClassLoader domain) {
+ Configuration core = new CoreConfiguration(app, domain);
+ Configuration xml = new XMLConfiguration(core);
+ Configuration castor = new CastorConfiguration(xml);
+ return castor;
+ }
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a configuration with given parent. Application and domain class loaders will be
+ * initialized to the ones of the parent.
+ *