You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ddlutils-dev@db.apache.org by to...@apache.org on 2005/10/30 01:16:35 UTC

svn commit: r329491 - in /db/ddlutils/trunk: ./ lib/ src/doc/src/documentation/content/xdocs/ src/java/org/apache/ddlutils/dynabean/ src/java/org/apache/ddlutils/io/ src/java/org/apache/ddlutils/io/converters/ src/java/org/apache/ddlutils/task/

Author: tomdz
Date: Sat Oct 29 16:14:54 2005
New Revision: 329491

URL: http://svn.apache.org/viewcvs?rev=329491&view=rev
Log:
Rewrote DataWriter to use StAX for generating the data XML file (fix for DDLUTILS-30)
Added commands for writing data from the database to a file to both Ant tasks
Added ability to specify converters for the data writer
The writeDataToFile command now uses the tableHints variant of Platform#query which makes it work with PostgreSQL and others (which do not return enough metadata info to determine tables from the result set)
Updated documentation of the ant tasks
Updated documentation of the Api usage to reflect the changes made to the platform concerning reading the model from the database

Added:
    db/ddlutils/trunk/lib/stax-1.1.2-dev.jar   (with props)
    db/ddlutils/trunk/lib/stax-api-1.0.jar   (with props)
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/ConverterConfiguration.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriterException.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/ConversionException.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java
Removed:
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToSpecifiedDatabaseCommand.java
Modified:
    db/ddlutils/trunk/.classpath
    db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/ant-tasks.xml
    db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/api-usage.xml
    db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/site.xml
    db/ddlutils/trunk/src/java/org/apache/ddlutils/dynabean/DynaSqlIterator.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/DateConverter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/NumberConverter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/SqlTypeConverter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimeConverter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimestampConverter.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseTaskBase.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseToDdlTask.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DdlToDatabaseTask.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java
    db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java

Modified: db/ddlutils/trunk/.classpath
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/.classpath?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/.classpath (original)
+++ db/ddlutils/trunk/.classpath Sat Oct 29 16:14:54 2005
@@ -13,5 +13,6 @@
 	<classpathentry kind="lib" path="lib/commons-betwixt-0.7.jar"/>
 	<classpathentry kind="lib" path="lib/ant-1.6.5.jar"/>
 	<classpathentry kind="lib" path="lib/commons-beanutils-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/stax-api-1.0.jar"/>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>

Added: db/ddlutils/trunk/lib/stax-1.1.2-dev.jar
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/lib/stax-1.1.2-dev.jar?rev=329491&view=auto
==============================================================================
Binary file - no diff available.

Propchange: db/ddlutils/trunk/lib/stax-1.1.2-dev.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: db/ddlutils/trunk/lib/stax-api-1.0.jar
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/lib/stax-api-1.0.jar?rev=329491&view=auto
==============================================================================
Binary file - no diff available.

Propchange: db/ddlutils/trunk/lib/stax-api-1.0.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/ant-tasks.xml
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/ant-tasks.xml?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/ant-tasks.xml (original)
+++ db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/ant-tasks.xml Sat Oct 29 16:14:54 2005
@@ -98,11 +98,13 @@
               password=""/>
 
     <writeSchemaToFile outputFile="db-schema.xml"/>
+    <writeDataToFile outputFile="data.xml"/>
   </databaseToDdl>
 </target>]]></source>
       <p>
         Here, the database schema is retrieved via the specified JDBC driver and written
-        to the file <code>db-schema.xml</code>.
+        to the file <code>db-schema.xml</code>. Likewise, the data in the database is written
+        to the file <code>data.xml</code>.
       </p>
     </section>
     <section>
@@ -149,6 +151,21 @@
             to the user mailing list so that DdlUtils can be enhanced to support this combo.
           </td>
         </tr>
+        <tr>
+          <td>useDelimitedSqlIdentifiers</td>
+          <td>no</td>
+          <td>true,false</td>
+          <td>true</td>
+          <td>
+            Whether DdlUtils shall use delimited (quoted) identifiers (table names, column names etc.)
+            In most databases, undelimited identifiers will be converted to uppercase by the database,
+            and the case of the identifier is ignored when performing any SQL command. Undelimited
+            identifiers can contain only alphanumerical characters and the underscore. Also, no reserved
+            words can be used as such identifiers.<br/>
+            The limitations do not exist for delimited identifiers. However case of the identifier will be
+            important in every SQL command executed against the database.
+          </td>
+        </tr>
       </table>
       <section>
         <title>Subelement: fileset</title>
@@ -197,21 +214,6 @@
             <td>true</td>
             <td>Specifies whether the execution shall stop if an error has occurred while the task runs.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>
-              Whether DdlUtils shall use delimited (quoted) identifiers (table names, column names etc.)
-              In most databases, undelimited identifiers will be converted to uppercase by the database,
-              and the case of the identifier is ignored when performing any SQL command. Undelimited
-              identifiers can contain only alphanumerical characters and the underscore. Also, no reserved
-              words can be used as such identifiers.<br/>
-              The limitations do not exist for delimited identifiers. However case of the identifier will be
-              important in every SQL command executed against the database.
-            </td>
-          </tr>
         </table>
         <section>
           <title>Subelement: parameter</title>
@@ -280,13 +282,6 @@
             <td>true</td>
             <td>See above.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>See above.</td>
-          </tr>
         </table>
       </section>
       <section>
@@ -318,13 +313,6 @@
             <td></td>
             <td>The name of the file to write the DTD to.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>See above.</td>
-          </tr>
         </table>
       </section>
       <section>
@@ -369,13 +357,6 @@
             <td>true</td>
             <td>See above.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>See above.</td>
-          </tr>
         </table>
       </section>
       <section>
@@ -422,13 +403,6 @@
             <td></td>
             <td>The name of the file to write the SQL commands to.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>See above.</td>
-          </tr>
         </table>
       </section>
       <section>
@@ -469,20 +443,111 @@
             <td></td>
             <td>The name of the single XML file that contains the data to insert into the database.</td>
           </tr>
+        </table>
+        <section>
+          <title>Subelement: fileset</title>
+          <p>
+            Specifies the XML files that contain the data to insert. DdlUtils processes them in the
+            order that they appear in the fileset(s). For details on the <code>FileSet</code> element
+            see the <a href="ext:ant/manual/coretypes/fileset">section in the Ant manual</a>.
+          </p>
+        </section>
+        <section>
+          <title>Subelement: converter</title>
+          <p>
+            Defines a class that is able to convert between the Java type corresponding to a SQL type
+            (e.g. <code>java.sql.Date</code>, <code>java.lang.String</code>) and strings to be used
+            in XML files.
+          </p>
+          <table>
+            <tr>
+              <th>Attribute</th>
+              <th>Required ?</th>
+              <th>Possible values</th>
+              <th>Default value</th>
+              <th>Meaning</th>
+            </tr>
+            <tr>
+              <td>className</td>
+              <td>yes</td>
+              <td></td>
+              <td></td>
+              <td>
+                Specifies the fully qualified class name of the parameter. Note that the class is
+                required to implement
+                <a href="ext:ddlutils/javadoc/converter">org.apache.ddlutils.io.converters.SqlTypeConverter</a>.
+              </td>
+            </tr>
+            <tr>
+              <td>column</td>
+              <td>either this together with <code>table</code> or <code>jdbcType</code></td>
+              <td></td>
+              <td></td>
+              <td>
+                Specifies the column for which this converter shall be used.
+              </td>
+            </tr>
+            <tr>
+              <td>jdbcType</td>
+              <td>either this or <code>table</code> + <code>column</code></td>
+              <td></td>
+              <td></td>
+              <td>
+                Specifies the JDBC type for which this converter shall be used. Note that converters
+                specified for a specific column override converters defined for types.
+              </td>
+            </tr>
+            <tr>
+              <td>table</td>
+              <td>either this together with <code>column</code> or <code>jdbcType</code></td>
+              <td></td>
+              <td></td>
+              <td>
+                Specifies the table for which this converter shall be used.
+              </td>
+            </tr>
+          </table>
+        </section>
+      </section>
+      <section>
+        <title>Subtask: writeDataToFile</title>
+        <p>
+          Generates an XML file containing the data currently stored in the database.
+        </p>
+        <table>
+          <tr>
+            <th>Attribute</th>
+            <th>Required ?</th>
+            <th>Possible values</th>
+            <th>Default value</th>
+            <th>Meaning</th>
+          </tr>
           <tr>
-            <td>useDelimitedSqlIdentifiers</td>
+            <td>encoding</td>
+            <td>no</td>
+            <td></td>
+            <td>UTF-8</td>
+            <td>The encoding of the XML file.</td>
+          </tr>
+          <tr>
+            <td>failOnError</td>
             <td>no</td>
             <td>true,false</td>
             <td>true</td>
             <td>See above.</td>
           </tr>
+          <tr>
+            <td>outputFile</td>
+            <td>yes</td>
+            <td></td>
+            <td></td>
+            <td>Specifies the XML file to write the data to.</td>
+          </tr>
         </table>
         <section>
-          <title>Subelement: fileset</title>
+          <title>Subelement: converter</title>
           <p>
-            Specifies the XML files that contain the data to insert. DdlUtils processes them in the
-            order that they appear in the fileset(s). For details on the <code>FileSet</code> element
-            see the <a href="ext:ant/manual/coretypes/fileset">section in the Ant manual</a>.
+            Same as for writeDataToDatabase, only that the reverse direction is used (sql data -> XML string).
           </p>
         </section>
       </section>
@@ -555,6 +620,21 @@
             Per default, only tables of type <code>TABLE</code>, eg. user tables, are processed.
           </td>
         </tr>
+        <tr>
+          <td>useDelimitedSqlIdentifiers</td>
+          <td>no</td>
+          <td>true,false</td>
+          <td>true</td>
+          <td>
+            Whether DdlUtils shall use delimited (quoted) identifiers (table names, column names etc.)
+            In most databases, undelimited identifiers will be converted to uppercase by the database,
+            and the case of the identifier is ignored when performing any SQL command. Undelimited
+            identifiers can contain only alphanumerical characters and the underscore. Also, no reserved
+            words can be used as such identifiers.<br/>
+            The limitations do not exist for delimited identifiers. However case of the identifier will be
+            important in every SQL command executed against the database.
+          </td>
+        </tr>
       </table>
       <section>
         <title>Subelement: dataSource</title>
@@ -643,17 +723,16 @@
             <td></td>
             <td>The name of the file to write the SQL commands to.</td>
           </tr>
-          <tr>
-            <td>useDelimitedSqlIdentifiers</td>
-            <td>no</td>
-            <td>true,false</td>
-            <td>true</td>
-            <td>See above.</td>
-          </tr>
         </table>
       </section>
       <section>
         <title>Subtask: writeDataToDatabase</title>
+        <p>
+          Same as for the <code>DdlToDatabaseTask</code> task.
+        </p>
+      </section>
+      <section>
+        <title>Subtask: writeDataToFile</title>
         <p>
           Same as for the <code>DdlToDatabaseTask</code> task.
         </p>

Modified: db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/api-usage.xml
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/api-usage.xml?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/api-usage.xml (original)
+++ db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/api-usage.xml Sat Oct 29 16:14:54 2005
@@ -72,31 +72,25 @@
 }]]></source>
     </section>
     <section>
-      <title>Reading from a database</title>
+      <title>Reading the model from a live database</title>
       <p>
         Reading the database model from a live database is only slightly more involved
-        because we first need to establish a connection to it:
+        because we first need to create a platform instance via the data source pointing
+        to the database:
       </p>
       <source><![CDATA[
-import java.sql.SQLException;
-import org.apache.ddlutils.io.JdbcModelReader;
+import javax.sql.DataSource;
+import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.PlatformFactory;
 import org.apache.ddlutils.model.Database;
-import org.apache.ddlutils.util.DataSourceWrapper;
 
-public Database readDatabase(String driverClassName,
-                             String databaseUrl,
-                             String username,
-                             String password) throws ClassNotFoundException,
-                                                     SQLException
-{
-    // you could also use a datasource provided by your jdbc driver or from commons-dbcp
-
-    DataSourceWrapper dataSource = new DataSourceWrapper(driverClassName, databaseUrl, username, password);
-    JdbcModelReader   reader     = new JdbcModelReader(dataSource.getConnection());
+...
 
-    // set catalog and schema at the reader if the database requires it
+public Database readDatabase(DataSource dataSource)
+{
+    Platform platform = PlatformFactory.createNewPlatformInstance(dataSource);
 
-    return reader.getDatabase();
+    return platform.readModelFromDatabase();
 }]]></source>
     </section>
     <section>

Modified: db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/site.xml?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/site.xml (original)
+++ db/ddlutils/trunk/src/doc/src/documentation/content/xdocs/site.xml Sat Oct 29 16:14:54 2005
@@ -64,6 +64,7 @@
       <jira href="http://issues.apache.org/jira/secure/BrowseProject.jspa?id=10731"/>
       <javadoc href="api/index.html">
         <model href="?org/apache/ddlutils/model/package-summary.html"/>
+        <converter href="org/apache/ddlutils/io/converters/SqlTypeConverter.html"/>
       </javadoc>
       <svn-view href="http://svn.apache.org/viewcvs.cgi/db/ddlutils/trunk/"/>
       <user-list>

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/dynabean/DynaSqlIterator.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/dynabean/DynaSqlIterator.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/dynabean/DynaSqlIterator.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/dynabean/DynaSqlIterator.java Sat Oct 29 16:14:54 2005
@@ -187,7 +187,7 @@
             {
                 String columnName = queryHints[tableIdx].getColumn(columnIdx).getName();
 
-                if (caseSensitive)
+                if (!caseSensitive)
                 {
                     columnName = columnName.toLowerCase();
                 }

Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/ConverterConfiguration.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/ConverterConfiguration.java?rev=329491&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/ConverterConfiguration.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/ConverterConfiguration.java Sat Oct 29 16:14:54 2005
@@ -0,0 +1,107 @@
+package org.apache.ddlutils.io;
+
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+import java.sql.Types;
+import java.util.HashMap;
+
+import org.apache.ddlutils.io.converters.DateConverter;
+import org.apache.ddlutils.io.converters.NumberConverter;
+import org.apache.ddlutils.io.converters.SqlTypeConverter;
+import org.apache.ddlutils.io.converters.TimeConverter;
+import org.apache.ddlutils.io.converters.TimestampConverter;
+import org.apache.ddlutils.model.Column;
+import org.apache.ddlutils.model.Table;
+
+/**
+ * Contains the configuration for converters, which convert between the Java data types
+ * corresponding to SQL data, and string representations.
+ * 
+ * @author Thomas Dudziak
+ * @version $Revision: 289996 $
+ */
+public class ConverterConfiguration
+{
+    /** The converters per type. */
+    private HashMap  _convertersPerType = new HashMap();
+    /** The converters per table-column path. */
+    private HashMap  _convertersPerPath = new HashMap();
+
+    /**
+     * Creates a new configuration object with the default converters.
+     */
+    public ConverterConfiguration()
+    {
+
+        NumberConverter numberConverter = new NumberConverter();
+
+        registerConverter(Types.DATE,      new DateConverter());
+        registerConverter(Types.TIME,      new TimeConverter());
+        registerConverter(Types.TIMESTAMP, new TimestampConverter());
+        registerConverter(Types.BIGINT,    numberConverter);
+        registerConverter(Types.BIT,       numberConverter);
+        registerConverter(Types.DECIMAL,   numberConverter);
+        registerConverter(Types.DOUBLE,    numberConverter);
+        registerConverter(Types.FLOAT,     numberConverter);
+        registerConverter(Types.INTEGER,   numberConverter);
+        registerConverter(Types.NUMERIC,   numberConverter);
+        registerConverter(Types.REAL,      numberConverter);
+        registerConverter(Types.SMALLINT,  numberConverter);
+        registerConverter(Types.TINYINT,   numberConverter);
+    }
+
+    /**
+     * Registers the given type converter for an sql type.
+     * 
+     * @param sqlTypeCode The type code, one of the {@link java.sql.Types} constants
+     * @param converter   The converter
+     */
+    public void registerConverter(int sqlTypeCode, SqlTypeConverter converter)
+    {
+        _convertersPerType.put(new Integer(sqlTypeCode), converter);
+    }
+
+    /**
+     * Registers the given type converter for the specified column.
+     * 
+     * @param tableName  The name of the table
+     * @param columnName The name of the column
+     * @param converter  The converter
+     */
+    public void registerConverter(String tableName, String columnName, SqlTypeConverter converter)
+    {
+        _convertersPerPath.put(tableName +"/" + columnName, converter);
+    }
+
+    /**
+     * Returns the converter registered for the specified column.
+     * 
+     * @param table  The table
+     * @param column The column
+     * @return The converter
+     */
+    public SqlTypeConverter getRegisteredConverter(Table table, Column column)
+    {
+        SqlTypeConverter result = (SqlTypeConverter)_convertersPerPath.get(table.getName() + "/" + column.getName());
+
+        if (result == null)
+        {
+            result = (SqlTypeConverter)_convertersPerType.get(new Integer(column.getTypeCode()));
+        }
+        return result;
+    }
+}

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java Sat Oct 29 16:14:54 2005
@@ -16,15 +16,8 @@
  * limitations under the License.
  */
 
-import java.sql.Types;
-import java.util.HashMap;
-
 import org.apache.commons.digester.Digester;
-import org.apache.ddlutils.io.converters.DateConverter;
-import org.apache.ddlutils.io.converters.NumberConverter;
 import org.apache.ddlutils.io.converters.SqlTypeConverter;
-import org.apache.ddlutils.io.converters.TimeConverter;
-import org.apache.ddlutils.io.converters.TimestampConverter;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.Table;
@@ -44,76 +37,19 @@
     private DataSink _sink;
     /** Specifies whether the (lazy) configuration of the digester still needs to be performed. */
     private boolean  _needsConfiguration = true;
-    /** The converters per type. */
-    private HashMap  _convertersPerType = new HashMap();
-    /** The converters per table-column path. */
-    private HashMap  _convertersPerPath = new HashMap();
+    /** The converters. */
+    private ConverterConfiguration _converterConf = new ConverterConfiguration();
     /** Whether to be case sensitive or not. */
     private boolean _caseSensitive = false;
 
     /**
-     * Creates a new data reader instance.
-     */
-    public DataReader()
-    {
-        super();
-
-        NumberConverter numberConverter = new NumberConverter();
-
-        registerConverter(Types.DATE,      new DateConverter());
-        registerConverter(Types.TIME,      new TimeConverter());
-        registerConverter(Types.TIMESTAMP, new TimestampConverter());
-        registerConverter(Types.BIGINT,    numberConverter);
-        registerConverter(Types.BIT,       numberConverter);
-        registerConverter(Types.DECIMAL,   numberConverter);
-        registerConverter(Types.DOUBLE,    numberConverter);
-        registerConverter(Types.FLOAT,     numberConverter);
-        registerConverter(Types.INTEGER,   numberConverter);
-        registerConverter(Types.NUMERIC,   numberConverter);
-        registerConverter(Types.REAL,      numberConverter);
-        registerConverter(Types.SMALLINT,  numberConverter);
-        registerConverter(Types.TINYINT,   numberConverter);
-    }
-
-    /**
-     * Registers the given type converter for an sql type.
-     * 
-     * @param sqlTypeCode The type code, one of the {@link java.sql.Types} constants
-     * @param converter   The converter
-     */
-    public void registerConverter(int sqlTypeCode, SqlTypeConverter converter)
-    {
-        _convertersPerType.put(new Integer(sqlTypeCode), converter);
-    }
-
-    /**
-     * Registers the given type converter for the specified column.
+     * Returns the converter configuration of this data reader.
      * 
-     * @param tableName  The name of the table
-     * @param columnName The name of the column
-     * @param converter  The converter
+     * @return The converter configuration
      */
-    public void registerConverter(String tableName, String columnName, SqlTypeConverter converter)
+    public ConverterConfiguration getConverterConfiguration()
     {
-        _convertersPerPath.put(tableName +"/" + columnName, converter);
-    }
-
-    /**
-     * Returns the converter registered for the specified column.
-     * 
-     * @param table  The table
-     * @param column The column
-     * @return The converter
-     */
-    public SqlTypeConverter getRegisteredConverter(Table table, Column column)
-    {
-        SqlTypeConverter result = (SqlTypeConverter)_convertersPerPath.get(table.getName() + "/" + column.getName());
-
-        if (result == null)
-        {
-            result = (SqlTypeConverter)_convertersPerType.get(new Integer(column.getTypeCode()));
-        }
-        return result;
+        return _converterConf;
     }
 
     /**
@@ -209,7 +145,7 @@
                 for (int columnIdx = 0; columnIdx < table.getColumnCount(); columnIdx++)
                 {
                     Column           column    = (Column)table.getColumn(columnIdx);
-                    SqlTypeConverter converter = getRegisteredConverter(table, column);
+                    SqlTypeConverter converter = _converterConf.getRegisteredConverter(table, column);
     
                     addRule(path, new SetColumnPropertyRule(column, converter, isCaseSensitive()));
                     addRule(path + "/" + column.getName(), new SetColumnPropertyFromSubElementRule(column, converter));

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriter.java Sat Oct 29 16:14:54 2005
@@ -17,68 +17,162 @@
  */
 
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.commons.beanutils.DynaBean;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.ddlutils.dynabean.SqlDynaBean;
 import org.apache.ddlutils.dynabean.SqlDynaClass;
+import org.apache.ddlutils.io.converters.ConversionException;
+import org.apache.ddlutils.io.converters.SqlTypeConverter;
 import org.apache.ddlutils.model.Column;
-import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.Table;
 
 /**
  * Writes dyna beans matching a specified database model into an XML file.
  * 
  * TODO: Make names (tables, columns) XML-compliant
- * TODO: Use converters
  * 
  * @author Thomas Dudziak
  * @version $Revision: 289996 $
  */
 public class DataWriter
 {
-    /** The database model. */
-    private Database    _model;
-    /** The target. */
+    /** String values with a size not bigger than this value will be written to attributes;
+        if their size is longer, then a sub element is generated instead. */ 
+    private static final int MAX_ATTRIBUTE_LENGTH = 255;
+    /** The indentation string. */
+    private static final String INDENT_STRING = "  ";
+
+    /** Our log. */
+    private final Log _log = LogFactory.getLog(DataWriter.class);
+
+    /** The converters. */
+    private ConverterConfiguration _converterConf = new ConverterConfiguration();
+    /** The output stream. */
     private PrintWriter _output;
+    /** The xml writer. */
+    private XMLStreamWriter _writer;
     /** The output encoding. */
-    private String      _encoding;
+    private String _encoding;
+    /** Whether we're pretty-printing. */
+    private boolean _prettyPrinting = true;
 
     /**
-     * Creates a data writer instance for the specified model.
+     * Creates a data writer instance using UTF-8 encoding.
      * 
-     * @param model  The database model
      * @param output The target to write the data XML to
      */
-    public DataWriter(Database model, OutputStream output)
+    public DataWriter(OutputStream output) throws DataWriterException
     {
-        _model    = model;
-        _encoding = "UTF-8";
-        _output   = new PrintWriter(new OutputStreamWriter(output));
+        this(output, null);
     }
 
     /**
-     * Creates a data writer instance for the specified model.
+     * Creates a data writer instance.
      * 
-     * @param model    The database model
      * @param output   The target to write the data XML to
      * @param encoding The encoding of the XML file
      */
-    public DataWriter(Database model, OutputStream output, String encoding) throws UnsupportedEncodingException
+    public DataWriter(OutputStream output, String encoding) throws DataWriterException
     {
-        _model = model;
-        if (encoding == null)
+        _output = new PrintWriter(output);
+        if ((encoding == null) || (encoding.length() == 0))
         {
             _encoding = "UTF-8";
-            _output   = new PrintWriter(new OutputStreamWriter(output));
         }
         else
         {
             _encoding = encoding;
-            _output   = new PrintWriter(new OutputStreamWriter(output, encoding));
+        }
+
+        try
+        {
+            XMLOutputFactory factory = XMLOutputFactory.newInstance();
+
+            _writer  = factory.createXMLStreamWriter(output, _encoding);
+        }
+        catch (XMLStreamException ex)
+        {
+            throw new DataWriterException(ex);
+        }
+    }
+
+    /**
+     * Determines whether the output shall be pretty-printed.
+     *
+     * @return <code>true</code> if the output is pretty-printed
+     */
+    public boolean isPrettyPrinting()
+    {
+        return _prettyPrinting;
+    }
+
+    /**
+     * Specifies whether the output shall be pretty-printed.
+     *
+     * @param prettyPrinting <code>true</code> if the output is pretty-printed
+     */
+    public void setPrettyPrinting(boolean prettyPrinting)
+    {
+        _prettyPrinting = prettyPrinting;
+    }
+
+    /**
+     * Returns the converter configuration of this data reader.
+     * 
+     * @return The converter configuration
+     */
+    public ConverterConfiguration getConverterConfiguration()
+    {
+        return _converterConf;
+    }
+
+    /**
+     * Prints a newline if we're pretty-printing.
+     */
+    private void printlnIfPrettyPrinting() throws DataWriterException
+    {
+        if (_prettyPrinting)
+        {
+            try
+            {
+                _writer.writeCharacters("\n");
+            }
+            catch (XMLStreamException ex)
+            {
+                throw new DataWriterException(ex);
+            }
+        }
+    }
+
+    /**
+     * Prints the indentation if we're pretty-printing.
+     */
+    private void indentIfPrettyPrinting(int level) throws DataWriterException
+    {
+        if (_prettyPrinting)
+        {
+            try
+            {
+                for (int idx = 0; idx < level; idx++)
+                {
+                    _writer.writeCharacters(INDENT_STRING);
+                }
+            }
+            catch (XMLStreamException ex)
+            {
+                throw new DataWriterException(ex);
+            }
         }
     }
 
@@ -86,18 +180,39 @@
      * Writes the start of the XML document, i.e. the "<?xml?>" section and the start of the
      * root node.
      */
-    public void writeDocumentStart()
+    public void writeDocumentStart() throws DataWriterException
     {
-        _output.println("<?xml version=\"1.0\" encoding=\"" + _encoding + "\"?>");
-        _output.println("<data>");
+        try
+        {
+            _writer.writeStartDocument(_encoding, "1.0");
+            printlnIfPrettyPrinting();
+            _writer.writeStartElement("data");
+            printlnIfPrettyPrinting();
+        }
+        catch (XMLStreamException ex)
+        {
+            throw new DataWriterException(ex);
+        }
     }
 
     /**
      * Writes the end of the XML document, i.e. end of the root node.
      */
-    public void writeDocumentEnd()
+    public void writeDocumentEnd() throws DataWriterException
     {
-        _output.println("</data>");
+        try
+        {
+            _writer.writeEndElement();
+            printlnIfPrettyPrinting();
+            _writer.writeEndDocument();
+            _writer.flush();
+            _writer.close();
+            _output.close();
+        }
+        catch (XMLStreamException ex)
+        {
+            throw new DataWriterException(ex);
+        }
     }
 
     /**
@@ -105,24 +220,73 @@
      * 
      * @param bean The bean to write
      */
-    public void write(SqlDynaBean bean)
+    public void write(SqlDynaBean bean) throws DataWriterException
     {
-        SqlDynaClass dynaClass = (SqlDynaClass)bean.getDynaClass();
-        Table        table     = dynaClass.getTable();
+        SqlDynaClass dynaClass   = (SqlDynaClass)bean.getDynaClass();
+        Table        table       = dynaClass.getTable();
+        HashMap      subElements = new HashMap();
 
-        _output.println("  <" + table.getName());
-        for (int idx = 0; idx < table.getColumnCount(); idx++)
+        try
         {
-            Column column = table.getColumn(idx);
-            Object value  = bean.get(column.getName());
-
-            if (value != null)
+            indentIfPrettyPrinting(1);
+            _writer.writeStartElement(table.getName());
+            for (int idx = 0; idx < table.getColumnCount(); idx++)
+            {
+                Column           column      = table.getColumn(idx);
+                Object           value       = bean.get(column.getName());
+                SqlTypeConverter converter   = _converterConf.getRegisteredConverter(table, column);
+                String           valueAsText = null;
+
+                if (converter == null)
+                {
+                    if (value != null)
+                    {
+                        valueAsText = value.toString();
+                    }
+                }
+                else
+                {
+                    valueAsText = converter.convertToString(value, column.getTypeCode());
+                }
+                if (valueAsText != null)
+                {
+                    if (valueAsText.length() > MAX_ATTRIBUTE_LENGTH)
+                    {
+                        // we defer writing the sub elements
+                        subElements.put(column.getName(), valueAsText);
+                    }
+                    else
+                    {
+                        _writer.writeAttribute(column.getName(), valueAsText);
+                    }
+                }
+            }
+            if (!subElements.isEmpty())
             {
-                // TODO: Add the concept of encoders for the data types
-                _output.println("    " + column.getName() + "=\"" + value.toString() + "\"");
+                for (Iterator it = subElements.entrySet().iterator(); it.hasNext();)
+                {
+                    Map.Entry entry = (Map.Entry)it.next();
+        
+                    printlnIfPrettyPrinting();
+                    indentIfPrettyPrinting(2);
+                    _writer.writeStartElement(entry.getKey().toString());
+                    _writer.writeCData(entry.getValue().toString());
+                    _writer.writeEndElement();
+                }
+                printlnIfPrettyPrinting();
+                indentIfPrettyPrinting(1);
             }
+            _writer.writeEndElement();
+            printlnIfPrettyPrinting();
+        }
+        catch (XMLStreamException ex)
+        {
+            throw new DataWriterException(ex);
+        }
+        catch (ConversionException ex)
+        {
+            throw new DataWriterException(ex);
         }
-        _output.println("  >");
     }
 
     /**
@@ -130,11 +294,20 @@
      * 
      * @param beans The beans iterator
      */
-    public void write(Iterator beans)
+    public void write(Iterator beans) throws DataWriterException
     {
         while (beans.hasNext())
         {
-            write((SqlDynaBean)beans.next());
+            DynaBean bean = (DynaBean)beans.next();
+
+            if (bean instanceof SqlDynaBean)
+            {
+                write((SqlDynaBean)bean);
+            }
+            else
+            {
+                _log.warn("Cannot write normal dyna beans (type: "+bean.getDynaClass().getName()+")");
+            }
         }
     }
 
@@ -143,7 +316,7 @@
      * 
      * @param beans The beans
      */
-    public void write(Collection beans)
+    public void write(Collection beans) throws DataWriterException
     {
         write(beans.iterator());
     }

Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriterException.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriterException.java?rev=329491&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriterException.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataWriterException.java Sat Oct 29 16:14:54 2005
@@ -0,0 +1,70 @@
+package org.apache.ddlutils.io;
+
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+import org.apache.commons.lang.exception.NestableRuntimeException;
+
+/**
+ * Exception generated by the {@link org.apache.ddlutils.io.DataWriter}.
+ * 
+ * @author Thomas Dudziak
+ * @version $Revision: 289996 $
+ */
+public class DataWriterException extends NestableRuntimeException
+{
+    /** Unique id for serialization purposes. */
+    private static final long serialVersionUID = 6254759931565130848L;
+
+    /**
+     * Creates a new exception object.
+     */
+    public DataWriterException()
+    {
+        super();
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param message The exception message
+     */
+    public DataWriterException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param baseEx The base exception
+     */
+    public DataWriterException(Throwable baseEx)
+    {
+        super(baseEx);
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param message The exception message
+     * @param baseEx  The base exception
+     */
+    public DataWriterException(String message, Throwable baseEx)
+    {
+        super(message, baseEx);
+    }
+}

Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/ConversionException.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/ConversionException.java?rev=329491&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/ConversionException.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/ConversionException.java Sat Oct 29 16:14:54 2005
@@ -0,0 +1,70 @@
+package org.apache.ddlutils.io.converters;
+
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+import org.apache.commons.lang.exception.NestableRuntimeException;
+
+/**
+ * Exception generated by {@link org.apache.ddlutils.io.converters.SqlTypeConverter} implementations.
+ * 
+ * @author Thomas Dudziak
+ * @version $Revision: 289996 $
+ */
+public class ConversionException extends NestableRuntimeException
+{
+    /** Unique id for serialization purposes. */
+    private static final long serialVersionUID = -1582788733576384843L;
+
+    /**
+     * Creates a new exception object.
+     */
+    public ConversionException()
+    {
+        super();
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param message The exception message
+     */
+    public ConversionException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param baseEx The base exception
+     */
+    public ConversionException(Throwable baseEx)
+    {
+        super(baseEx);
+    }
+
+    /**
+     * Creates a new exception object.
+     * 
+     * @param message The exception message
+     * @param baseEx  The base exception
+     */
+    public ConversionException(String message, Throwable baseEx)
+    {
+        super(message, baseEx);
+    }
+}

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/DateConverter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/DateConverter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/DateConverter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/DateConverter.java Sat Oct 29 16:14:54 2005
@@ -31,7 +31,7 @@
     /**
      * {@inheritDoc}
      */
-    public Object convertFromString(String textRep, int sqlTypeCode) throws Exception
+    public Object convertFromString(String textRep, int sqlTypeCode) throws ConversionException
     {
         if (sqlTypeCode != Types.DATE)
         {
@@ -48,27 +48,37 @@
             int    day        = 1;
             int    slashPos   = dateAsText.indexOf('-');
 
-            if (slashPos < 0)
+            try
             {
-                year = Integer.parseInt(dateAsText);
-            }
-            else
-            {
-                year       = Integer.parseInt(dateAsText.substring(0, slashPos));
-                dateAsText = dateAsText.substring(slashPos + 1);
-                slashPos   = dateAsText.indexOf('-');
                 if (slashPos < 0)
                 {
-                    month = Integer.parseInt(dateAsText);
+                    year = Integer.parseInt(dateAsText);
                 }
                 else
                 {
-                    month = Integer.parseInt(dateAsText.substring(0, slashPos));
-                    day   = Integer.parseInt(dateAsText.substring(slashPos + 1));
+                    year       = Integer.parseInt(dateAsText.substring(0, slashPos));
+                    dateAsText = dateAsText.substring(slashPos + 1);
+                    slashPos   = dateAsText.indexOf('-');
+                    if (slashPos < 0)
+                    {
+                        month = Integer.parseInt(dateAsText);
+                    }
+                    else
+                    {
+                        month = Integer.parseInt(dateAsText.substring(0, slashPos));
+                        day   = Integer.parseInt(dateAsText.substring(slashPos + 1));
+                    }
                 }
+                return new Date(year - 1900, month - 1, day);
+            }
+            catch (NumberFormatException ex)
+            {
+                throw new ConversionException(ex);
+            }
+            catch (IllegalArgumentException ex)
+            {
+                throw new ConversionException(ex);
             }
-            return new Date(year - 1900, month - 1, day);
-            
         }
         else
         {
@@ -79,8 +89,8 @@
     /**
      * {@inheritDoc}
      */
-    public String convertToString(Object obj, int sqlTypeCode)
+    public String convertToString(Object obj, int sqlTypeCode) throws ConversionException
     {
-        return (obj == null ? null : obj.toString());
+        return obj == null ? null : obj.toString();
     }
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/NumberConverter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/NumberConverter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/NumberConverter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/NumberConverter.java Sat Oct 29 16:14:54 2005
@@ -33,7 +33,7 @@
     /**
      * {@inheritDoc}
      */
-    public Object convertFromString(String textRep, int sqlTypeCode) throws Exception
+    public Object convertFromString(String textRep, int sqlTypeCode) throws ConversionException
     {
         if (textRep == null)
         {
@@ -84,7 +84,7 @@
     /**
      * {@inheritDoc}
      */
-    public String convertToString(Object obj, int sqlTypeCode) throws Exception
+    public String convertToString(Object obj, int sqlTypeCode) throws ConversionException
     {
         if (obj == null)
         {

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/SqlTypeConverter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/SqlTypeConverter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/SqlTypeConverter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/SqlTypeConverter.java Sat Oct 29 16:14:54 2005
@@ -31,7 +31,7 @@
      * @param sqlTypeCode The target sql type code, one of the constants in {@link java.sql.Types}
      * @return The corresponding object
      */
-    public Object convertFromString(String textRep, int sqlTypeCode) throws Exception;
+    public Object convertFromString(String textRep, int sqlTypeCode) throws ConversionException;
 
     /**
      * Converts the given object to a string representation.
@@ -40,5 +40,5 @@
      * @param sqlTypeCode The corresponding source type code
      * @return The textual representation
      */
-    public String convertToString(Object obj, int sqlTypeCode) throws Exception;
+    public String convertToString(Object obj, int sqlTypeCode) throws ConversionException;
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimeConverter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimeConverter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimeConverter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimeConverter.java Sat Oct 29 16:14:54 2005
@@ -31,7 +31,7 @@
     /**
      * {@inheritDoc}
      */
-    public Object convertFromString(String textRep, int sqlTypeCode) throws Exception
+    public Object convertFromString(String textRep, int sqlTypeCode) throws ConversionException
     {
         if (sqlTypeCode != Types.TIME)
         {
@@ -48,27 +48,37 @@
             int    seconds    = 0;
             int    slashPos   = timeAsText.indexOf(':');
 
-            if (slashPos < 0)
+            try
             {
-                hours = Integer.parseInt(timeAsText);
-            }
-            else
-            {
-                hours      = Integer.parseInt(timeAsText.substring(0, slashPos));
-                timeAsText = timeAsText.substring(slashPos + 1);
-                slashPos   = timeAsText.indexOf(':');
                 if (slashPos < 0)
                 {
-                    minutes = Integer.parseInt(timeAsText);
+                    hours = Integer.parseInt(timeAsText);
                 }
                 else
                 {
-                    minutes = Integer.parseInt(timeAsText.substring(0, slashPos));
-                    seconds = Integer.parseInt(timeAsText.substring(slashPos + 1));
+                    hours      = Integer.parseInt(timeAsText.substring(0, slashPos));
+                    timeAsText = timeAsText.substring(slashPos + 1);
+                    slashPos   = timeAsText.indexOf(':');
+                    if (slashPos < 0)
+                    {
+                        minutes = Integer.parseInt(timeAsText);
+                    }
+                    else
+                    {
+                        minutes = Integer.parseInt(timeAsText.substring(0, slashPos));
+                        seconds = Integer.parseInt(timeAsText.substring(slashPos + 1));
+                    }
                 }
+                return new Time(hours, minutes, seconds);
+            }
+            catch (NumberFormatException ex)
+            {
+                throw new ConversionException(ex);
+            }
+            catch (IllegalArgumentException ex)
+            {
+                throw new ConversionException(ex);
             }
-            return new Time(hours, minutes, seconds);
-            
         }
         else
         {
@@ -79,7 +89,7 @@
     /**
      * {@inheritDoc}
      */
-    public String convertToString(Object obj, int sqlTypeCode)
+    public String convertToString(Object obj, int sqlTypeCode) throws ConversionException
     {
         return obj == null ? null : obj.toString();
     }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimestampConverter.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimestampConverter.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimestampConverter.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/converters/TimestampConverter.java Sat Oct 29 16:14:54 2005
@@ -31,7 +31,7 @@
     /**
      * {@inheritDoc}
      */
-    public Object convertFromString(String textRep, int sqlTypeCode) throws Exception
+    public Object convertFromString(String textRep, int sqlTypeCode) throws ConversionException
     {
         return sqlTypeCode == Types.TIMESTAMP ? Timestamp.valueOf(textRep) : (Object)textRep;
     }
@@ -39,8 +39,8 @@
     /**
      * {@inheritDoc}
      */
-    public String convertToString(Object obj, int sqlTypeCode)
+    public String convertToString(Object obj, int sqlTypeCode) throws ConversionException
     {
-        return ((Timestamp)obj).toString();
+        return (obj == null ? null : ((Timestamp)obj).toString());
     }
 }

Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java?rev=329491&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java Sat Oct 29 16:14:54 2005
@@ -0,0 +1,59 @@
+package org.apache.ddlutils.task;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.ddlutils.io.ConverterConfiguration;
+import org.apache.ddlutils.io.DataConverterRegistration;
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Base type for database commands that use converters.
+ * 
+ * @author Thomas Dudziak
+ * @version $Revision: 289996 $
+ */
+public abstract class ConvertingDatabaseCommand extends DatabaseCommand
+{
+    /** The converters. */
+    private ArrayList _converters = new ArrayList();
+
+    /**
+     * Registers a converter.
+     * 
+     * @param converterRegistration The registration info
+     */
+    public void addConfiguredConverter(DataConverterRegistration converterRegistration)
+    {
+        _converters.add(converterRegistration);
+    }
+
+    /**
+     * Registers the converters at the given configuration.
+     * 
+     * @param converterConf The converter configuration
+     */
+    protected void registerConverters(ConverterConfiguration converterConf) throws BuildException
+    {
+        for (Iterator it = _converters.iterator(); it.hasNext();)
+        {
+            DataConverterRegistration registrationInfo = (DataConverterRegistration)it.next();
+
+            if (registrationInfo.getTypeCode() != Integer.MIN_VALUE)
+            {
+                converterConf.registerConverter(registrationInfo.getTypeCode(),
+                                                registrationInfo.getConverter());
+            }
+            else
+            {
+                if ((registrationInfo.getTable() == null) || (registrationInfo.getColumn() == null)) 
+                {
+                    throw new BuildException("Please specify either the jdbc type or a table/column pair for which the converter shall be defined");
+                }
+                converterConf.registerConverter(registrationInfo.getTable(),
+                                                registrationInfo.getColumn(),
+                                                registrationInfo.getConverter());
+            }
+        }
+    }
+}

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseTaskBase.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseTaskBase.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseTaskBase.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseTaskBase.java Sat Oct 29 16:14:54 2005
@@ -22,6 +22,9 @@
 import org.apache.commons.dbcp.BasicDataSource;
 import org.apache.ddlutils.Platform;
 import org.apache.ddlutils.model.Database;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 
 /**
@@ -126,7 +129,14 @@
     {
         return _platformConf.getPlatform();
     }
-    
+
+    /**
+     * Reads the database model on which the commands will work.
+     * 
+     * @return The database model
+     */
+    protected abstract Database readModel();
+
     /**
      * Executes the commands.
      * 
@@ -143,6 +153,42 @@
                 ((DatabaseCommand)cmd).setPlatformConfiguration(_platformConf);
             }
             cmd.execute(this, model);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute() throws BuildException
+    {
+        if (!hasCommands())
+        {
+            log("No sub tasks specified, so there is nothing to do.", Project.MSG_INFO);
+            return;
+        }
+
+        ClassLoader    sysClassLoader = Thread.currentThread().getContextClassLoader();
+        AntClassLoader newClassLoader = new AntClassLoader(getClass().getClassLoader(), true);
+
+        // we're changing the thread classloader so that we can access resources
+        // from the classpath used to load this task's class
+        Thread.currentThread().setContextClassLoader(newClassLoader);
+        
+        try
+        {
+            Database model = readModel();
+    
+            if (model == null)
+            {
+                log("No schemas read, so there is nothing to do.", Project.MSG_INFO);
+                return;
+            }
+            executeCommands(model);
+        }
+        finally
+        {
+            // rollback of our classloader change
+            Thread.currentThread().setContextClassLoader(sysClassLoader);
         }
     }
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseToDdlTask.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseToDdlTask.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseToDdlTask.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DatabaseToDdlTask.java Sat Oct 29 16:14:54 2005
@@ -21,7 +21,6 @@
 
 import org.apache.ddlutils.model.Database;
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
 
 /**
  * Ant task for working with a database, e.g. retrieving the schema from a
@@ -110,6 +109,16 @@
     }
 
     /**
+     * Adds the "write data into file"-command.
+     * 
+     * @param command The command
+     */
+    public void addWriteDataToFile(WriteDataToFileCommand command)
+    {
+        addCommand(command);
+    }
+
+    /**
      * Returns the table types to recognize.
      * 
      * @return The table types
@@ -137,11 +146,9 @@
     }
 
     /**
-     * Reads the schema(s) from the specified database.
-     * 
-     * @return The database model
+     * {@inheritDoc}
      */
-    private Database readSchema()
+    protected Database readModel()
     {
         if (getDataSource() == null)
         {
@@ -156,26 +163,5 @@
         {
             throw new BuildException("Could not read the schema from the specified database: "+ex.getLocalizedMessage(), ex);
         }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void execute() throws BuildException
-    {
-        if (!hasCommands())
-        {
-            log("No sub tasks specified, so there is nothing to do.", Project.MSG_INFO);
-            return;
-        }
-
-        Database model = readSchema();
-
-        if (model == null)
-        {
-            log("No schemas read, so there is nothing to do.", Project.MSG_INFO);
-            return;
-        }
-        executeCommands(model);
     }
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DdlToDatabaseTask.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DdlToDatabaseTask.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DdlToDatabaseTask.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/DdlToDatabaseTask.java Sat Oct 29 16:14:54 2005
@@ -115,17 +115,25 @@
      * 
      * @param command The command
      */
-    public void addWriteDataToDatabase(WriteDataToSpecifiedDatabaseCommand command)
+    public void addWriteDataToDatabase(WriteDataToDatabaseCommand command)
     {
         addCommand(command);
     }
 
     /**
-     * Reads the schemas from the specified files and merges them into one database model.
+     * Adds the "write data to file"-command.
      * 
-     * @return The database model
+     * @param command The command
      */
-    private Database readSchemaFiles()
+    public void addWriteDataToFile(WriteDataToFileCommand command)
+    {
+        addCommand(command);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Database readModel()
     {
         DatabaseIO reader = new DatabaseIO();
         Database       model  = null;
@@ -204,21 +212,5 @@
             }
         }
         return model;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void execute() throws BuildException
-    {
-        if (!hasCommands())
-        {
-            log("No sub tasks specified, so there is nothing to do.", Project.MSG_INFO);
-            return;
-        }
-
-        Database model = readSchemaFiles();
-
-        executeCommands(model);
     }
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java Sat Oct 29 16:14:54 2005
@@ -21,7 +21,6 @@
 import java.util.Iterator;
 
 import org.apache.ddlutils.Platform;
-import org.apache.ddlutils.io.DataConverterRegistration;
 import org.apache.ddlutils.io.DataReader;
 import org.apache.ddlutils.io.DataToDatabaseSink;
 import org.apache.ddlutils.model.Database;
@@ -37,14 +36,12 @@
  * @author Thomas Dudziak
  * @version $Revision: 289996 $
  */
-public class WriteDataToDatabaseCommand extends DatabaseCommand
+public class WriteDataToDatabaseCommand extends ConvertingDatabaseCommand
 {
     /** A single data file to insert. */
     private File      _singleDataFile = null;
     /** The input files. */
     private ArrayList _fileSets = new ArrayList();
-    /** The converterd. */
-    private ArrayList _converters = new ArrayList();
 
     /**
      * Adds a fileset.
@@ -57,16 +54,6 @@
     }
 
     /**
-     * Registers a converter.
-     * 
-     * @param converterRegistration The registration info
-     */
-    public void addConfiguredConverter(DataConverterRegistration converterRegistration)
-    {
-        _converters.add(converterRegistration);
-    }
-
-    /**
      * Set the xml data file.
      *
      * @param dataFile The data file
@@ -89,26 +76,7 @@
 
             reader.setModel(model);
             reader.setSink(sink);
-            for (Iterator it = _converters.iterator(); it.hasNext();)
-            {
-                DataConverterRegistration registrationInfo = (DataConverterRegistration)it.next();
-
-                if (registrationInfo.getTypeCode() != Integer.MIN_VALUE)
-                {
-                    reader.registerConverter(registrationInfo.getTypeCode(),
-                                             registrationInfo.getConverter());
-                }
-                else
-                {
-                    if ((registrationInfo.getTable() == null) || (registrationInfo.getColumn() == null)) 
-                    {
-                        throw new BuildException("Please specify either the jdbc type or a table/column pair for which the converter shall be defined");
-                    }
-                    reader.registerConverter(registrationInfo.getTable(),
-                                             registrationInfo.getColumn(),
-                                             registrationInfo.getConverter());
-                }
-            }
+            registerConverters(reader.getConverterConfiguration());
             if ((_singleDataFile != null) && !_fileSets.isEmpty())
             {
                 throw new BuildException("Please use either the datafile attribute or the sub fileset element, but not both");

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java?rev=329491&r1=329490&r2=329491&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java Sat Oct 29 16:14:54 2005
@@ -32,7 +32,7 @@
  * @author Thomas Dudziak
  * @version $Revision: 289996 $
  */
-public class WriteDataToFileCommand extends DatabaseCommand
+public class WriteDataToFileCommand extends ConvertingDatabaseCommand
 {
     /** The file to output the data to. */
     private File   _outputFile;
@@ -67,16 +67,19 @@
         try
         {
             Platform   platform = getPlatform();
-            DataWriter writer   = new DataWriter(model, new FileOutputStream(_outputFile), _encoding);
+            DataWriter writer   = new DataWriter(new FileOutputStream(_outputFile), _encoding);
+            Table[]    tables   = new Table[1];
             
+            registerConverters(writer.getConverterConfiguration());
+
             // TODO: An advanced algorithm could be employed here that writes objects
             //       related by foreign keys, in the correct order
             writer.writeDocumentStart();
             for (int idx = 0; idx < model.getTableCount(); idx++)
             {
-                Table table = (Table)model.getTable(idx);
+                tables[0] = (Table)model.getTable(idx);
 
-                writer.write(platform.query(model, "select * from "+table.getName()));
+                writer.write(platform.query(model, "select * from "+tables[0].getName(), tables));
             }
             writer.writeDocumentEnd();
         }