You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by jg...@apache.org on 2008/04/15 04:33:09 UTC

svn commit: r648102 [4/34] - in /ibatis/trunk/java/tools/ibator/core: ./ build/ devlib/ doc/ htmldoc/ htmldoc/configreference/ htmldoc/generatedobjects/ htmldoc/reference/ htmldoc/usage/ src/ src/org/ src/org/apache/ src/org/apache/ibatis/ src/org/apac...

Added: ibatis/trunk/java/tools/ibator/core/htmldoc/usage/db2.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/usage/db2.html?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/usage/db2.html (added)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/usage/db2.html Mon Apr 14 19:32:53 2008
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>iBATOR DB2 Usage Notes</title>
+  <link type="text/css" rel="stylesheet" href="../ibator.css"/>
+</head>
+<body>
+<p align="right">
+  <font size="-2">
+    <a href="../index.html" target="_top">Frames</a>
+    <a href="db2.html" target="_top">No Frames</a>
+  </font>
+</p>
+<h1>iBATOR DB2 Usage Notes</h1>
+<h2>LONG VARCHAR Fields</h2>
+<p>By default iBATOR will map LONG VARCHAR fields to the <code>java.lang.String</code> data type,
+and will mark these fields as <code>jdbcType="LONGVARCHAR"</code>.  This
+mapping will cause errors when retrieving data from DB2.  DB2 LONG VARCHAR fields should be mapped
+to the <code>java.lang.String</code> data type with <code>jdbcType="VARCHAR"</code>.  To overcome
+this problem, use a <code>&lt;columnOverride&gt;</code> as follows:</p>
+<pre>
+  &lt;table schema="DB2ADMIN" tableName="ALLTYPES" &gt;
+    &lt;columnOverride column="LONG_VARCHAR_FIELD" javaType="java.lang.String" jdbcType="VARCHAR" /&gt;
+  &lt;/table&gt;
+</pre>
+</body>
+</html>

Added: ibatis/trunk/java/tools/ibator/core/htmldoc/usage/intro.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/usage/intro.html?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/usage/intro.html (added)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/usage/intro.html Mon Apr 14 19:32:53 2008
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>iBATOR Usage Notes</title>
+  <link type="text/css" rel="stylesheet" href="../ibator.css"/>
+</head>
+<body>
+<p align="right">
+  <font size="-2">
+    <a href="../index.html" target="_top">Frames</a>
+    <a href="intro.html" target="_top">No Frames</a>
+  </font>
+</p>
+<h1>iBATOR Usage Notes</h1>
+<p>This section collects usage information for different databases.</p>
+
+<ul>
+  <li><a href="db2.html">DB2</a></li>
+  <li><a href="mysql.html">MySql</a></li>
+  <li><a href="oracle.html">Oracle</a></li>
+</ul>
+<p>Please let us know about any quirks you discover for the database you are using - we will
+be happy to add the information
+to this section for future reference.</p>
+</body>
+</html>

Added: ibatis/trunk/java/tools/ibator/core/htmldoc/usage/mysql.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/usage/mysql.html?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/usage/mysql.html (added)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/usage/mysql.html Mon Apr 14 19:32:53 2008
@@ -0,0 +1,32 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>iBATOR MySql Usage Notes</title>
+  <link type="text/css" rel="stylesheet" href="../ibator.css"/>
+</head>
+<body>
+<p align="right">
+  <font size="-2">
+    <a href="../index.html" target="_top">Frames</a>
+    <a href="mysql.html" target="_top">No Frames</a>
+  </font>
+</p>
+<h1>iBATOR MySql Usage Notes</h1>
+<h2>Unsigned Fields</h2>
+<p>MySql supports both signed, and unsigned, numeric fields.  These are not JDBC types, so iBATOR
+cannot automatically account for these types of fields.  The Java data types are always signed.
+This can
+lead to a loss of precision when using unsigned fields.  The solution is to provide a
+<code>&lt;columnOverride&gt;</code> for any unsigned numeric field in MySql.  Here is an example
+of how to deal with an unsigned bigint field in MySql:</p>
+<pre>
+  &lt;table tableName="ALLTYPES" &gt;
+    &lt;columnOverride column="UNSIGNED_BIGINT_FIELD" javaType="java.lang.Object" jdbcType="LONG" /&gt;
+  &lt;/table&gt;
+</pre>
+<p>You will have to cast the returned value to the appropriate type yourself (in this case,
+<code>java.math.BigInteger</code>).</p>
+</body>
+</html>

Added: ibatis/trunk/java/tools/ibator/core/htmldoc/usage/oracle.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/usage/oracle.html?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/usage/oracle.html (added)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/usage/oracle.html Mon Apr 14 19:32:53 2008
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>iBATOR Oracle Usage Notes</title>
+  <link type="text/css" rel="stylesheet" href="../ibator.css"/>
+</head>
+<body>
+<p align="right">
+  <font size="-2">
+    <a href="../index.html" target="_top">Frames</a>
+    <a href="oracle.html" target="_top">No Frames</a>
+  </font>
+</p>
+<h1>iBATOR Oracle Usage Notes</h1>
+<h2>Public Synonyms</h2>
+<p>If you want to generate objects for a table that has a public synonym, you
+should actually generate the objects against the real table - and then change the
+table name at runtime.  iBATOR supports this automatically.</p>
+<p>For example, assume there is a public alias "FRED" that points the the
+table "HR.EMPLOYEES".  The following table configuration will generate the objects
+based on HR.EMPLOYEES, but the runtime SQL will only refer to FRED:</p>
+<pre>
+  &lt;table schema="HR" tableName="EMPLOYEES"&gt;
+    &lt;property name="ignoreQualifiersAtRuntime" value="true" /&gt;
+    &lt;property name="runtimeTableName" value="FRED" /&gt;
+  &lt;/table&gt;
+</pre>
+</body>
+</html>

Added: ibatis/trunk/java/tools/ibator/core/htmldoc/whatsNew.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/whatsNew.html?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/whatsNew.html (added)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/whatsNew.html Mon Apr 14 19:32:53 2008
@@ -0,0 +1,263 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>What's New in iBATOR</title>
+  <link type="text/css" rel="stylesheet" href="ibator.css"/>
+</head>
+<body>
+<p align="right">
+  <font size="-2">
+    <a href="index.html" target="_top">Frames</a>
+    <a href="whatsNew.html" target="_top">No Frames</a>
+  </font>
+</p>
+<h1>What's New in iBATOR</h1>
+<h2>Version 1.1.0</h2>
+<h3>Announcements</h3>
+<ul>
+  <li>The next release of Abator will require JRE 5.0 or higher.</li>
+  <li>Java2 is now the default generator set.  This will cause different code to be
+      generated if you have not specified a generator set previously.  To remedy this,
+      set the generator set to "Legacy".</li>
+</ul>
+
+<h3>New Generated Methods</h3>
+<p>Abator will generate these new methods:</p>
+<dl>
+  <dt><b>countByExample</b></dt>
+  <dd>This method will return an integer representing the number of rows in a table
+      that match the given criteria.</dd>
+  <dt><b>updateByExample</b></dt>
+  <dd>This method will update all rows in a table that match a given criteria.  This method is
+      available in the Java2 and Java5 generator sets only.  There is also a "selective" version
+      of the method that only updates certain columns of a table (the selective version of this
+      method is probably the more useful version to use in most situations).</dd>
+</dl>
+
+<h3>Bugs Fixed</h3>
+<ul>
+  <li>Fixed bug for corner case where a criteria class is created, but no criteria
+      are set.</li>
+  <li>Fixed a bug that caused the JavaModelGenerator's "trimStrings" property to fail</li>
+  <li>Fixed the XML file merger so that internal entities are preserved</li>
+  <li>Fixed the XML configuration parser so that external entities are handled properly</li>
+  <li>Fixed bug - incorrect datatype mapping for JDBC BIT datatype</li>
+  <li>Fixed bug where Abator generated incorrect properties for certain database columns
+      (for example, if the column name is I_NAME)</li>
+</ul>
+
+<h3>Miscellaneous Changes</h3>
+<ul>
+  <li>Added the ability to specify properties to ignore qualifiers and change runtime
+      table names in the generated SQL for a table.  Primary use cases for this
+      support include:
+      <ul>
+        <li>Generating objects for a table that has a public synonym or alias</li>
+        <li>Generating objects for a table that exists in many schemas, and the
+            schema will be selected at runtime</li>
+      </ul>
+    See the <a href="configreference/table.html">&lt;table&gt;</a>
+    reference page for more information, or the
+    <a href="usage/oracle.html">Oracle</a> reference page for an example.</li>
+  <li>Added support for delimiting SQL identifiers for the use cases where identifiers
+      contain spaces or SQL reserved words.
+      See the <a href="configreference/table.html">&lt;table&gt;</a>,
+      <a href="configreference/abatorContext.html">&lt;abatorContext&gt;</a>,
+      and <a href="configreference/columnOverride.html">&lt;columnOverride&gt;</a>
+      reference pages for more information.</li>
+  <li>Added SYBASE dialect for generated keys.
+      See the <a href="configreference/generatedKey.html">&lt;generatedKey&gt;</a>
+      reference page for more information.</li>
+  <li>Added DB2_MF (DB2 on Main Frames) dialect for generated keys.
+      See the <a href="configreference/generatedKey.html">&lt;generatedKey&gt;</a>
+      reference page for more information.</li>
+  <li>Abator will now automatically escape identifiers that contain the $ or # characters
+      as these characters have special meaning in iBATIS configuration files.</li>
+  <li>Added a <code>clear</code> method to the generated example classes (in the Java2 and Java5
+      generator sets only).  This allows reuse of these classes.</li>
+  <li>Added the ability to specify that result maps should use column indexes rather
+      than column names in the result mappings.  Primary use cases for this
+      support include:
+      <ul>
+        <li>When tables have columns whose name is only differentiated by
+            case (e.g. "first name" and "First Name")</li>
+        <li>When you want to make the selects as fast as possible (there is a slight
+            performance benefit when using column indexes)</li>
+      </ul>
+    See the <a href="configreference/table.html">&lt;table&gt;</a>
+    reference page for more information.</li>
+  <li>Made the generated Example and Criteria classes extendable.  Added some documentation
+      about how to extend these classes.  See the
+      <a href="generatedobjects/extendingExampleClass.html">Extending the Example Classes</a>
+      reference page for more information.</li>
+  <li>Made the legacy DAOs extendable.</li>
+  <li>Added the ability to provide a renaming rule for columns.  This is for the
+      use case where columns have a common prefix that should be removed before
+      calculating the property name.  See the
+      <a href="configreference/columnRenamingRule.html">&lt;columnRenamingRule&gt;</a>
+      reference page for more information.</li>
+  <li>Added support for persisting a configuration to XML - this to enable
+      a graphical editor in the future.</li>
+  <li>Add afterXXXGenerationHook() methods in all generators to enable adding
+      extra Java code or XML elements to any generated object.  This will make
+      it easier to create customized generators.</li>
+  <li>API change to allow generating with selected contexts rather than
+      the entire config file.</li>
+  <li>API change to allow generating with selected tables rather than
+    the entire config file.</li>
+  <li>Exposed new support for selecting tables and/or contexts to the
+      command line and the Ant task - this has added an advanced syntax to the command
+      line for Abator.  See the
+      <a href="running.html">Running Abator</a> reference page for more information.</li>
+  <li><code>rootClass</code> and <code>rootInterface</code> may now be specified for each table.
+      See the <a href="configreference/table.html">&lt;table&gt;</a>
+      reference page for more information.</li>
+  <li>If a <code>rootClass</code> is specified for any table, Abator will now check in the
+      rootClass to see if a generated property already exists in the root class.  If it does,
+      Abator will not generate the property.  The &lt;javaModelGenerator&gt; element now
+      accepts a property to specify the classpath of the <code>rootClass</code>.  See the
+      <a href="configreference/javaModelGenerator.html">&lt;javaModelGenerator&gt;</a>
+      reference page for more information.  Thanks to Ashok Madhavan for the beginnings
+      of this code.</li>
+  <li>Allowed specifying a type (pre or post) for the generated key element.  See the
+      <a href="configreference/generatedKey.html">&lt;generatedKey&gt;</a>
+      reference page for more information.</li>
+  <li>Added a comment generator interface to enable generation of custom comments.
+      See the <a href="configreference/commentGenerator.html">&lt;commentGenerator&gt;</a>
+      reference page for more information.</li>
+</ul>
+
+<h2>Version 1.0.0</h2>
+<h3>Generator Sets</h3>
+<p>A generator set is a set of
+code generators (SQL Map Generator, Java Model Generator, DAO Generator, and Java Type Resolver).
+Abator now ships three different generator sets.  The generated code from these three
+generator sets is slightly different, and the use of the generated objects is slightly
+different too.  The concepts are exactly the same.  With the newer generator sets, the
+"by example" methods have been vastly improved.  It is now possible to generate
+<b>virtually any</b> WHERE clause (including IN and BETWEEN predicates).  Lastly, the new
+generator sets generate much more concise code - the DAOs and SQL Maps are of
+normal size, and there are no extraneous methods.  The example class in the new generator
+sets encapsulates all the function needed to generate dynamic queries.</p>
+<p>The three generator sets shipped with Abator are as follows:</p>
+<dl>
+  <dt>Legacy</dt>
+  <dd>This generator set generates code that is the same as previous versions of
+      Abator.  There are some limitations with this generator set and we strongly
+      recommend that you choose one of the other sets.  However, this set remains
+      the default for now.  <b>This generator set will likely be removed in a future
+      version of Abator.</b></dd>
+  <dt>Java2</dt>
+  <dd>This generator set generates code that is compatible with iBATIS versions 2.2.0 and
+      higher.  With this generator set the "by example" methods are much more powerful
+      than in the legacy set.  It is now possible to generate
+      virtually unlimited SQL WHERE clauses with Abator generated code (including "IN"
+      and "BETWEEN" clauses).  <b>This generator set will likely become the default set in a
+      future version of Abator.</b></dd>
+  <dt>Java5</dt>
+  <dd>This generator set has the same capabilities as the Java2 generator set with the
+      added feature of generating code that is JSE 5.0 compliant using parameterized
+      types and annotations.</dd>
+</dl>
+<p><b>Important:</b> code generated with the Java2 or Java5 generator sets is not 100%
+compatible with code generated with the Legacy set - especially in the use of the
+"by example" methods.  Also note that the "by example" methods in these generator sets rely
+on iBATIS dynamic SQL support that is missing in iBATIS versions prior to version 2.2.0.</p>
+<p>A generator set is selected with the <code>generatorSet</code> attribute of the
+<code>&lt;abatorContext&gt;</code> element.  See the
+<a href="configreference/abatorContext.html">&lt;abatorContext&gt;</a> reference page for
+more information.</p>
+
+<p>Use of the example classes is different with the different generator sets.  See the
+<a href="generatedobjects/exampleClassUsage.html">Example Class Usage</a> page for more
+information.</p>
+
+<h3>Model Types</h3>
+<p>A model type is used to give you more control over the types of domain objects
+generated by Abator.  Abator now supports three different types of domain models
+as follows:</p>
+<dl>
+  <dt>conditional</dt>
+  <dd>This model is similar to the hierarchical model except that a separate
+    class will not be generated if that separate class would only contain
+    one field.  So if a table has only one primary key field, that field
+    will be merged into the base record class.  This model type is the default.
+    <b>Note that this model type may generate classes that are not 100%
+    with classes generated in previous versions of Abator.</b></dd>
+  <dt>flat</dt>
+  <dd>This model generates only one domain class for any table.  The class
+     will hold all fields in the table.</dd>
+  <dt>hierarchical</dt>
+  <dd>This model is the same as the model shipped with the initial versions
+      of Abator.  This model will generate a primary key class if the table has
+      a primary key, another class that holds any BLOB columns in the table, and
+      another class that holds the remaining fields.  There is an appropriate
+      inheritance relationship between the classes.</dd>
+</dl>
+
+<p>Model types can be specified as a default for an entire context, and you may
+override the default for each table in a context.  See the
+<a href="configreference/abatorContext.html">&lt;abatorContext&gt;</a> reference page for
+more information about setting the context default..
+See the <a href="configreference/table.html">&lt;table&gt;</a>
+reference page for more information about setting a model type for specific tables.
+</p>
+<p><b>Important:</b> the default value is conditional - this is a non-backward compatible
+change from previous versions of Abator.</p>
+
+<h3>updateByPrimaryKeySelective</h3>
+<p>This is a new mapped SQL statement, and new DAO method, that will only
+update columns whose corresponding properties in the parameter class are non-null.
+This can be used to update certain
+columns in a record without needing to update the entire record.
+</p>
+<p><b>Important:</b> any column that is mapped to a primitive type
+will always be updated.</p>
+
+<h3>Miscellaneous Changes</h3>
+<ul>
+  <li>Added the ability to specify a table alias.  This aids in reuse of generated
+    SQL map elements.  See the <a href="configreference/table.html">&lt;table&gt;</a>
+    reference page for more information.</li>
+  <li>Fixed the XML file merger so that extraneous blank lines at the end of the
+      file are removed.</li>
+  <li>Added the ability to specify a type handler for table columns.
+    See the <a href="configreference/columnOverride.html">&lt;columnOverride&gt;</a>
+    reference page for more information.</li>
+  <li>Added the ability to specify the visibility of the DAO "by example" methods.
+    This allows you to make the methods private for internal use only.
+    See the <a href="configreference/daoGenerator.html">&lt;daoGenerator&gt;</a>
+    reference page for more information.</li>
+  <li>Added the ability to override the naming convention for DAO method names.
+    See the <a href="configreference/daoGenerator.html">&lt;daoGenerator&gt;</a>
+    reference page for more information.</li>
+  <li>Added the ability to specify wildcards for schema or tableName in a table
+      configuration.  This will allow generation of many tables with a simple
+      XML configuration.
+    See the <a href="configreference/table.html">&lt;table&gt;</a>
+    reference page for more information.</li>
+  <li>Added the ability to escape wildcard characters in schema or table names
+      if required by the driver.  See the <a href="configreference/table.html">&lt;table&gt;</a>
+      reference page for more information.</li>
+  <li>Added the ability to suppress JSE 5.0 type warning messages for non-parameterized
+      types if you are using the Legacy or Java2 generator sets in a JSE 5.0 environment.
+    See the <a href="configreference/abatorContext.html">&lt;abatorContext&gt;</a>
+    reference page for more information.
+  </li>
+  <li>Added the ability to specify an external properties file for passing
+    parameters into an Abator configuration file (like the iBATIS properties
+    file).  See the <a href="configreference/properties.html">&lt;properties&gt;</a>
+    reference page for more information.
+  </li>
+  <li>The Ant task now supports a "verbose" attribute.  See the
+    <a href="running.html">Running Abator</a> page for more information.
+  </li>
+  <li>The Ant task now supports a nested property set for passing values into
+      an Abator configuration file.  See the
+     <a href="running.html">Running Abator</a> page for more information.
+  </li>
+</ul>
+</body>
+</html>
\ No newline at end of file

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/AntProgressCallback.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/AntProgressCallback.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/AntProgressCallback.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/AntProgressCallback.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,69 @@
+/*
+ *  Copyright 2006 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.
+ */
+
+package org.apache.ibatis.ibator.ant;
+
+import org.apache.ibatis.ibator.api.ProgressCallback;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * This callback logs progress messages with the Ant logger
+ * 
+ * @author Jeff Butler
+ *
+ */
+public class AntProgressCallback implements ProgressCallback {
+
+    private Task task;
+    private boolean verbose;
+    
+    /**
+     * 
+     */
+    public AntProgressCallback(Task task, boolean verbose) {
+        super();
+        this.task = task;
+        this.verbose = verbose;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.ProgressCallback#setNumberOfSubTasks(int)
+     */
+    public void setNumberOfSubTasks(int totalSubTasks) {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.ProgressCallback#startSubTask(java.lang.String)
+     */
+    public void startSubTask(String subTaskName) {
+        if (verbose) {
+            task.log(subTaskName, Project.MSG_VERBOSE);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.ProgressCallback#finished()
+     */
+    public void finished() {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.ProgressCallback#checkCancel()
+     */
+    public void checkCancel() throws InterruptedException {
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/IbatorAntTask.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/IbatorAntTask.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/IbatorAntTask.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/IbatorAntTask.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,230 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.ibatis.ibator.api.Ibator;
+import org.apache.ibatis.ibator.config.IbatorConfiguration;
+import org.apache.ibatis.ibator.config.xml.IbatorConfigurationParser;
+import org.apache.ibatis.ibator.exception.InvalidConfigurationException;
+import org.apache.ibatis.ibator.exception.XMLParserException;
+import org.apache.ibatis.ibator.internal.DefaultShellCallback;
+import org.apache.ibatis.ibator.internal.util.StringUtility;
+import org.apache.ibatis.ibator.internal.util.messages.Messages;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.PropertySet;
+
+/**
+ * This is an Ant task that will run Ibator.  The following is a sample Ant
+ * script that shows how to run Ibator from Ant:
+ * 
+ * <pre>
+ *  &lt;project default="genfiles" basedir="."&gt;
+ *    &lt;property name="generated.source.dir" value="${basedir}" /&gt;
+ *    &lt;target name="genfiles" description="Generate the files"&gt;
+ *      &lt;taskdef name="ibator"
+ *               classname="org.apache.ibatis.ibator.ant.ibatorAntTask"
+ *               classpath="ibator.jar" /&gt;
+ *      &lt;ibator overwrite="true" configfile="ibatorConfig.xml" verbose="false" &gt;
+ *        &lt;propertyset&gt;
+ *          &lt;propertyref name="generated.source.dir"/&gt;
+ *        &lt;/propertyset&gt;
+ *      &lt;/ibator&gt;
+ *    &lt;/target&gt;
+ *  &lt;/project&gt;
+ * </pre>
+ * 
+ * The task also supports these optional attributes:
+ * <ul>
+ *   <li>"contextIds" - a comma delimited list of contaxtIds to use
+ *      for this run</li>
+ *   <li>"fullyQualifiedTableNames" - a comma delimited list of 
+ *     fully qualified table names to use for this run</li>
+ * </ul>
+ * 
+ * 
+ * @author Jeff Butler
+ */
+public class IbatorAntTask extends Task {
+    
+    private String configfile;
+    private boolean overwrite;
+    private PropertySet propertyset;
+    private boolean verbose;
+    private String contextIds;
+    private String fullyQualifiedTableNames;
+
+    /**
+     * 
+     */
+    public IbatorAntTask() {
+        super();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Task#execute()
+     */
+    @Override
+    public void execute() throws BuildException {
+        if (!StringUtility.stringHasValue(configfile)) {
+            throw new BuildException(Messages.getString("RuntimeError.0")); //$NON-NLS-1$
+        }
+
+        List<String> warnings = new ArrayList<String>();
+        
+        File configurationFile = new File(configfile);
+        if (!configurationFile.exists()) {
+            throw new BuildException(Messages.getString("RuntimeError.1", configfile)); //$NON-NLS-1$
+        }
+        
+        Set<String> fullyqualifiedTables = new HashSet<String>();
+        if (StringUtility.stringHasValue(fullyQualifiedTableNames)) {
+            StringTokenizer st = new StringTokenizer(fullyQualifiedTableNames, ","); //$NON-NLS-1$
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken().trim();
+                if (s.length() > 0) {
+                    fullyqualifiedTables.add(s);
+                }
+            }
+        }
+        
+        Set<String> contexts = new HashSet<String>();
+        if (StringUtility.stringHasValue(contextIds)) {
+            StringTokenizer st = new StringTokenizer(contextIds, ","); //$NON-NLS-1$
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken().trim();
+                if (s.length() > 0) {
+                    contexts.add(s);
+                }
+            }
+        }
+        
+        try {
+            Properties p = propertyset == null ? null : propertyset.getProperties();
+            
+            IbatorConfigurationParser cp = new IbatorConfigurationParser(p,
+                warnings);
+            IbatorConfiguration config = cp.parseIbatorConfiguration(configurationFile);
+            
+            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+            
+            Ibator ibator = new Ibator(config, callback, warnings);
+            
+            ibator.generate(new AntProgressCallback(this, verbose), contexts, fullyqualifiedTables);
+            
+        } catch (XMLParserException e) {
+            Iterator<String> errors = e.getErrors().iterator();
+            while (errors.hasNext()) {
+                log(errors.next(), Project.MSG_ERR);
+            }
+            
+            throw new BuildException(e.getMessage());
+        } catch (SQLException e) {
+            throw new BuildException(e.getMessage());
+        } catch (IOException e) {
+            throw new BuildException(e.getMessage());
+        } catch (InvalidConfigurationException e) {
+            Iterator<String> errors = e.getErrors().iterator();
+            while (errors.hasNext()) {
+                log(errors.next(), Project.MSG_ERR);
+            }
+            throw new BuildException(e.getMessage());
+        } catch (InterruptedException e) {
+            // ignore (will never happen with the DefaultShellCallback)
+            ;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BuildException(e.getMessage());
+        }
+        
+        Iterator<String> iter = warnings.iterator();
+        while (iter.hasNext()) {
+            log(iter.next(), Project.MSG_WARN);
+        }
+    }
+    
+    /**
+     * @return Returns the configfile.
+     */
+    public String getConfigfile() {
+        return configfile;
+    }
+    
+    /**
+     * @param configfile The configfile to set.
+     */
+    public void setConfigfile(String configfile) {
+        this.configfile = configfile;
+    }
+    
+    /**
+     * @return Returns the overwrite.
+     */
+    public boolean isOverwrite() {
+        return overwrite;
+    }
+    
+    /**
+     * @param overwrite The overwrite to set.
+     */
+    public void setOverwrite(boolean overwrite) {
+        this.overwrite = overwrite;
+    }
+
+    public PropertySet createPropertyset() {
+        if (propertyset == null) {
+            propertyset = new PropertySet();
+        }
+        
+        return propertyset;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public String getContextIds() {
+        return contextIds;
+    }
+
+    public void setContextIds(String contextIds) {
+        this.contextIds = contextIds;
+    }
+
+    public String getFullyQualifiedTableNames() {
+        return fullyQualifiedTableNames;
+    }
+
+    public void setFullyQualifiedTableNames(String fullyQualifiedTableNames) {
+        this.fullyQualifiedTableNames = fullyQualifiedTableNames;
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/SqlScriptRunnerTask.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/SqlScriptRunnerTask.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/SqlScriptRunnerTask.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/ant/SqlScriptRunnerTask.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,172 @@
+/*
+ *  Copyright 2007 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.
+ */
+
+package org.apache.ibatis.ibator.ant;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.ibatis.ibator.internal.util.StringUtility;
+import org.apache.ibatis.ibator.internal.util.messages.Messages;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * This task executes an SQL script.  It is used during the iBATOR build
+ * because the built in Ant SQL task treats some of the columns in "awful table"
+ * as properties.
+ * 
+ * This task is very simplistic and not intended for general use.
+ * 
+ * @author Jeff Butler
+ *
+ */
+public class SqlScriptRunnerTask extends Task {
+    
+    private String driver;
+    private String url;
+    private String userid;
+    private String password;
+    private String src;
+
+    @Override
+    public void execute() throws BuildException {
+        
+        Connection connection = null;
+        
+        try {
+            Class.forName(driver);
+            connection = DriverManager.getConnection(url, userid, password);
+            
+            Statement statement = connection.createStatement();
+            
+            BufferedReader br = new BufferedReader(new FileReader(src));
+            
+            String sql;
+            
+            while ((sql = readStatement(br)) != null) {
+                statement.execute(sql);
+            }
+            
+            closeStatement(statement);
+            connection.commit();
+            br.close();
+        } catch (Exception e) {
+            throw new BuildException(e.getMessage());
+        } finally {
+            closeConnection(connection);
+        }
+    }
+    
+    public String getDriver() {
+        return driver;
+    }
+
+    public void setDriver(String driver) {
+        this.driver = driver;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getSrc() {
+        return src;
+    }
+
+    public void setSrc(String src) {
+        this.src = src;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getUserid() {
+        return userid;
+    }
+
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+
+    private void closeConnection(Connection connection) {
+        if (connection != null) {
+            try {
+                connection.close();
+            } catch (SQLException e) {
+                // ignore
+                ;
+            }
+        }
+    }
+          
+    private void closeStatement(Statement statement) {
+        if (statement != null) {
+            try {
+                statement.close();
+            } catch (SQLException e) {
+                // ignore
+                ;
+            }
+        }
+    }
+    
+    private String readStatement(BufferedReader br) throws IOException {
+        StringBuffer sb = new StringBuffer();
+        
+        String line;
+        
+        while ((line = br.readLine()) != null) {
+            if (line.startsWith("--")) { //$NON-NLS-1$
+                continue;
+            }
+            
+            if (!StringUtility.stringHasValue(line)) {
+                continue;
+            }
+            
+            if (line.endsWith(";")) { //$NON-NLS-1$
+                sb.append(line.substring(0, line.length() - 1));
+                break;
+            } else {
+                sb.append(line);
+            }
+        }
+        
+        String s = sb.toString().trim();
+
+        if (s.length() > 0) {
+            log(Messages.getString("Progress.13", s), Project.MSG_DEBUG); //$NON-NLS-1$
+        }
+        
+        return s.length() > 0 ? s : null;
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/CommentGenerator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/CommentGenerator.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/CommentGenerator.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/CommentGenerator.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,107 @@
+/*
+ *  Copyright 2008 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import java.util.Properties;
+
+import org.apache.ibatis.ibator.api.dom.java.CompilationUnit;
+import org.apache.ibatis.ibator.api.dom.java.Field;
+import org.apache.ibatis.ibator.api.dom.java.InnerClass;
+import org.apache.ibatis.ibator.api.dom.java.InnerEnum;
+import org.apache.ibatis.ibator.api.dom.java.Method;
+import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
+
+/**
+ * Implementations of this interface are used to generate comments
+ * for the various artifacts generated by iBATOR. 
+ * 
+ * @author Jeff Butler
+ */
+public interface CommentGenerator {
+
+    /**
+     * Adds properties for this instance from any properties configured
+     * in the CommentGenerator configuration.
+     * 
+     * This method will be called before any of the other methods.
+     * 
+     * @param properties
+     *            All properties from the configuration
+     */
+    void addConfigurationProperties(Properties properties);
+    
+    /**
+     * This method should add a Javadoc comment to the specified field.
+     * The field is related to the specified table and is used to
+     * hold the value of the specified column.<p>
+     * 
+     *  <b>Important:</b> This method should add a the nonstandard
+     *  JavaDoc tag "@ibatorgenerated" to the comment.  Without this
+     *  tag, the Eclipse based Java merge feature will fail.
+     * 
+     * @param field
+     * @param table
+     * @param columnName
+     */
+    public void addFieldComment(Field field, FullyQualifiedTable table, String columnName);
+
+    public void addFieldComment(Field field, FullyQualifiedTable table);
+
+    public void addClassComment(InnerClass innerClass, FullyQualifiedTable table);
+
+    public void addEnumComment(InnerEnum innerEnum, FullyQualifiedTable table);
+
+    public void addGetterComment(Method method, FullyQualifiedTable table, String columnName);
+
+    public void addSetterComment(Method method, FullyQualifiedTable table, String columnName);
+
+    public void addGeneralMethodComment(Method method, FullyQualifiedTable table);
+
+    /**
+     * This method is called to add a file level comment to a generated
+     * java file.  This method could be used to add a general file
+     * comment (such as a copyright notice).  However, note that the Java
+     * file merge function in Eclipse does not deal with this comment.
+     * If you run iBATOR repeatedly, you will only retain the comment
+     * from the initial run.<p>
+     * 
+     * The default implementation does nothing.
+     * 
+     * @param compilationUnit
+     */
+    public void addJavaFileComment(CompilationUnit compilationUnit);
+
+    /**
+     * This method should add a suitable comment as a child element of the
+     * specified xmlElement to warn users that the element was generated and
+     * is subject to regeneration.
+     */
+    public void addComment(XmlElement xmlElement);
+    
+    /**
+     * This method is called to add a comment as the first child of
+     * the root element.  This method could be used to add a general file
+     * comment (such as a copyright notice).  However, note that the XML
+     * file merge function does not deal with this comment.  If you run
+     * iBATOR repeatedly, you will only retain the comment from the
+     * initial run.<p>
+     * 
+     * The default implementation does nothing.
+     * 
+     * @param rootElement
+     */
+    public void addRootComment(XmlElement rootElement);
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOGenerator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOGenerator.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOGenerator.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOGenerator.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,113 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.ibatis.ibator.config.IbatorContext;
+
+/**
+ * The DAOGenerator interface describes the methods needed to generate DAO
+ * objects for a table.
+ * 
+ * @author Jeff Butler
+ */
+public interface DAOGenerator {
+    /**
+     * Adds properties for this instance from any properties configured
+     * in the DAOGeneratorConfiguration.
+     * 
+     * This method will be called before any of the get methods.
+     * 
+     * @param properties
+     *            All properties from the configuration
+     */
+    void addConfigurationProperties(Properties properties);
+    
+    /**
+     * Sets the instance of the IbatorContext object associated with 
+     * this instance.
+     * 
+     * This method will be called before any of the get methods.
+     * 
+     * @param ibatorContext
+     *            The current IbatorContext
+     */
+    void setIbatorContext(IbatorContext ibatorContext);
+
+	/**
+	 * iBATOR will supply a list to this method.  The implementation class may
+	 * add strings to the list that will be treated as warning messages and
+	 * displayed to the user.  The concept of a warning is that code generation
+	 * can continue, but that the results may not be what is expected.
+	 * 
+	 * @param warnings
+	 */
+	void setWarnings(List<String> warnings);
+	
+    /**
+     * Sets the target package for this instance. This value should be used to
+     * calculate the package for the DAO interface and implementation classes.
+     * 
+     * This method will be called before any of the get methods.
+     * 
+     * @param targetPackage
+     *            The target package from the configuration
+     */
+    void setTargetPackage(String targetPackage);
+
+    /**
+     * 
+     * @param targetProject
+     */
+    void setTargetProject(String targetProject);
+
+    /**
+     * Sets the instance of JavaModelGenerator associated with this instance.
+     * 
+     * This method will be called before any of the get methods.
+     * 
+     * @param javaModelGenerator
+     *            The JavaModelGenerator associated with this instance
+     */
+    void setJavaModelGenerator(JavaModelGenerator javaModelGenerator);
+
+    /**
+     * Sets the instance of SqlMapGenerator associated with this instance.
+     * 
+     * This method will be called before any of the get methods.
+     * 
+     * @param sqlMapGenerator
+     *            The SqlMapGenerator associated with this instance
+     */
+    void setSqlMapGenerator(SqlMapGenerator sqlMapGenerator);
+
+    /**
+     * This method returns a list of GenerateJavaFile objects. The list may
+     * include any, or all, of the following types of generated java classes:
+     * 
+     * <ul>
+     * <li>A DAO Interface Class</li>
+     * <li>A DAO Implementation Class</li>
+     * </ul>
+     * 
+     * @param introspectedTable
+     * @param callback
+     * @return a list of GeneratedJavaFile objects
+     */
+    List<GeneratedJavaFile> getGeneratedJavaFiles(IntrospectedTable introspectedTable, ProgressCallback callback);
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOMethodNameCalculator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOMethodNameCalculator.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOMethodNameCalculator.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/DAOMethodNameCalculator.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,136 @@
+/*
+ *  Copyright 2006 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.
+ */
+
+package org.apache.ibatis.ibator.api;
+
+/**
+ * This interface is used to supply names for DAO methods.  Users
+ * can provide different implementations if the supplied implementations
+ * aren't sufficient.
+ * 
+ * @author Jeff Butler
+ *
+ */
+public interface DAOMethodNameCalculator {
+    /**
+     * Calculates and returns a name for the insert method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getInsertMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the update by primary key without BLOBs
+     * method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByPrimaryKeyWithoutBLOBsMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the update by primary key with BLOBs
+     * method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByPrimaryKeyWithBLOBsMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the update by primary key selective
+     * method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByPrimaryKeySelectiveMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the select by primary key method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getSelectByPrimaryKeyMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the select by example method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getSelectByExampleWithoutBLOBsMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the select by example with BLOBs method.
+     * If the table contains BLOBs, then iBATOR will generate different select by
+     * example methods - one including BLOBs, one not including BLOBs.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getSelectByExampleWithBLOBsMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the delete by primary key method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getDeleteByPrimaryKeyMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the delete by example method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getDeleteByExampleMethodName(IntrospectedTable introspectedTable);
+
+    /**
+     * Calculates and returns a name for the count by example method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getCountByExampleMethodName(IntrospectedTable introspectedTable);
+    
+    /**
+     * Calculates and returns a name for the update by example selective method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByExampleSelectiveMethodName(IntrospectedTable introspectedTable);    
+
+    /**
+     * Calculates and returns a name for the update by example with BLOBs method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByExampleWithBLOBsMethodName(IntrospectedTable introspectedTable);    
+
+    /**
+     * Calculates and returns a name for the update by example without BLOBs method.
+     * 
+     * @param introspectedTable
+     * @return the calculated name
+     */
+    String getUpdateByExampleWithoutBLOBsMethodName(IntrospectedTable introspectedTable);    
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/FullyQualifiedTable.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/FullyQualifiedTable.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/FullyQualifiedTable.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/FullyQualifiedTable.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,246 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import org.apache.ibatis.ibator.config.IbatorContext;
+import org.apache.ibatis.ibator.internal.util.EqualsUtil;
+import org.apache.ibatis.ibator.internal.util.HashCodeUtil;
+import org.apache.ibatis.ibator.internal.util.JavaBeansUtil;
+import org.apache.ibatis.ibator.internal.util.StringUtility;
+
+/**
+ * @author Jeff Butler
+ */
+public class FullyQualifiedTable {
+
+	private String catalog;
+
+	private String schema;
+
+	private String tableName;
+
+    private String runtimeTableName;
+    
+	private String domainObjectName;
+    
+    private String alias;
+    
+    private boolean ignoreQualifiersAtRuntime;
+    
+    private String beginningDelimiter;
+    
+    private String endingDelimiter;
+    
+    
+    /**
+     * This object is used to hold information related to the table itself,
+     * not the columns in the table.
+     * 
+     * @param catalog the actual catalog of the table as returned from
+     *  DatabaseMetaData.  This value should only be set if the user
+     *  configured a catalog.  Otherwise the DatabaseMetaData is reporting
+     *  some database default that we don't want in the generated code.
+     *  
+     * @param schema the actual schema of the table as returned from
+     *  DatabaseMetaData.  This value should only be set if the user
+     *  configured a schema.  Otherwise the DatabaseMetaData is reporting
+     *  some database default that we don't want in the generated code.
+     *  
+     * @param tableName the actual table name as returned from DatabaseMetaData
+     * 
+     * @param domainObjectName the configred domain object name for this table.
+     *  If nothing is configured, we'll build the domain object named based
+     *  on the tableName or runtimeTableName.
+     *  
+     * @param alias a configured alias for the table. This alias will be
+     *  added to the table name in the SQL
+     * 
+     * @param ignoreQualifiersAtRuntime if true, then the catalog and schema
+     *  qualifiers will be ignored when composing fully qualified names in 
+     *  the generated SQL.  This is used, for example, when the user needs
+     *  to specify a specific schema for generating code but does not want
+     *  the schema in the generated SQL 
+     * 
+     * @param runtimeTableName this is used to "rename" the table in the 
+     *  generated SQL.  This is usefule, for example, when generating code
+     *  to run with an Oracle synonym.  The user would have to specify
+     *  the actual table name and schema for generation, but would want to 
+     *  use the synonym name in the generated SQL
+     *  
+     *  @param delimitIdentifiers if true, then the table identifiers will be
+     *   delimited at runtime.  The delimiter characters are obtained
+     *   from the IbatorContext.
+     */
+	public FullyQualifiedTable(String catalog, String schema, String tableName,
+            String domainObjectName, String alias, boolean ignoreQualifiersAtRuntime,
+            String runtimeTableName, boolean delimitIdentifiers, IbatorContext ibatorContext) {
+		super();
+        this.catalog = catalog;
+        this.schema = schema;
+        this.tableName = tableName;
+        this.domainObjectName = domainObjectName;
+        this.ignoreQualifiersAtRuntime = ignoreQualifiersAtRuntime;
+        this.runtimeTableName = runtimeTableName;
+        
+        if (alias == null) {
+            this.alias = null;
+        } else {
+            this.alias = alias.trim();
+        }
+
+        beginningDelimiter = delimitIdentifiers ? ibatorContext.getBeginningDelimiter() : ""; //$NON-NLS-1$
+        endingDelimiter = delimitIdentifiers ? ibatorContext.getEndingDelimiter() : ""; //$NON-NLS-1$
+    }
+
+	public String getCatalog() {
+		return catalog;
+	}
+
+	public String getSchema() {
+		return schema;
+	}
+
+	public String getTableName() {
+		return tableName;
+	}
+
+    public String getFullyQualifiedTableNameAtRuntime() {
+        String localCatalog;
+        String localSchema;
+        String localTableName;
+        
+        if (StringUtility.stringHasValue(catalog)  && !ignoreQualifiersAtRuntime) {
+            localCatalog = beginningDelimiter + catalog + endingDelimiter;
+        } else {
+            localCatalog = null;
+        }
+        
+        if (StringUtility.stringHasValue(schema)  && !ignoreQualifiersAtRuntime) {
+            localSchema = beginningDelimiter + schema + endingDelimiter;
+        } else {
+            localSchema = null;
+        }
+        
+        if (StringUtility.stringHasValue(runtimeTableName)) {
+            localTableName = beginningDelimiter + runtimeTableName + endingDelimiter;
+        } else {
+            localTableName = beginningDelimiter + tableName + endingDelimiter;
+        }
+        
+        return StringUtility.composeFullyQualifiedTableName(
+                localCatalog,
+                localSchema,
+                localTableName,
+                '.');
+    }
+
+    public String getAliasedFullyQualifiedTableNameAtRuntime() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(getFullyQualifiedTableNameAtRuntime());
+        
+        if(StringUtility.stringHasValue(alias)) {
+            sb.append(' ');
+            sb.append(alias);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * This method returns a string that is the fully qualified table name, with
+     * underscores as the seperator.  This String should be 
+     * @return
+     */
+    public String getSqlMapNamespace() {
+        return StringUtility.composeFullyQualifiedTableName(
+                ignoreQualifiersAtRuntime ? null : catalog,
+                ignoreQualifiersAtRuntime ? null : schema,
+                StringUtility.stringHasValue(runtimeTableName) ? runtimeTableName : tableName,
+                '_');
+	}
+	
+	public String getDomainObjectName() {
+		if (StringUtility.stringHasValue(domainObjectName)) {
+			return domainObjectName;
+        } else if (StringUtility.stringHasValue(runtimeTableName)) {
+            return JavaBeansUtil.getCamelCaseString(runtimeTableName, true);
+		} else {
+			return JavaBeansUtil.getCamelCaseString(tableName, true);
+		}
+	}
+
+	@Override
+    public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+
+		if (!(obj instanceof FullyQualifiedTable)) {
+			return false;
+		}
+
+		FullyQualifiedTable other = (FullyQualifiedTable) obj;
+		
+		return EqualsUtil.areEqual(this.tableName, other.tableName)
+		        && EqualsUtil.areEqual(this.catalog, other.catalog)
+				&& EqualsUtil.areEqual(this.schema, other.schema);
+    }
+    
+	@Override
+    public int hashCode() {
+		int result = HashCodeUtil.SEED;
+		result = HashCodeUtil.hash(result, tableName);
+		result = HashCodeUtil.hash(result, catalog);
+		result = HashCodeUtil.hash(result, schema);
+
+		return result;
+    }
+    
+	@Override
+    public String toString() {
+        return StringUtility.composeFullyQualifiedTableName(
+                catalog, schema, tableName, '.');
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    /**
+     * Calculates a Java package fragment based on the 
+     * table catalog and schema.  If qualifiers are ignored,
+     * then this method will return an empty string 
+     * 
+     * @return
+     */
+    public String getSubPackage() {
+        StringBuffer sb = new StringBuffer();
+        if (!ignoreQualifiersAtRuntime) {
+            if (StringUtility.stringHasValue(catalog)) {
+                sb.append('.');
+                sb.append(catalog.toLowerCase());
+            }
+
+            if (StringUtility.stringHasValue(schema)) {
+                sb.append('.');
+                sb.append(schema.toLowerCase());
+            }
+        }
+
+        return sb.toString();
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedFile.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedFile.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedFile.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedFile.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,75 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+/**
+ * Abstract class that holds information common to all generated files.
+ * 
+ * @author Jeff Butler
+ */
+public abstract class GeneratedFile {
+	private String targetProject;
+
+	/**
+	 *  
+	 */
+	public GeneratedFile(String targetProject) {
+		super();
+		this.targetProject = targetProject;
+	}
+
+	/**
+	 * This method returns the entire contents of the generated file.  Clients
+	 * can simply save the value returned from this method as the file contents.
+	 * Subclasses such as @see org.apache.ibatis.ibator.api.GeneratedJavaFile
+	 * offer more fine grained access to file parts, but still implement this method
+	 * in the event that the entire contents are desired.
+	 * 
+	 * @return Returns the content.
+	 */
+	public abstract String getFormattedContent();
+	
+	/**
+	 * Get the file name (without any path).  Clients should use this method to determine how to save
+	 * the results.
+	 * 
+	 * @return Returns the file name.
+	 */
+	public abstract String getFileName();
+
+	/**
+	 * Gets the target project.  Clients can call this method to determine
+	 * how to save the results.
+	 * 
+	 * @return the target project
+	 */
+	public String getTargetProject() {
+		return targetProject;
+	}
+
+	/**
+	 * Get the target package for the file.  Clients should use this method to determine how to save
+	 * the results.
+	 * 
+	 * @return Returns the target project.
+	 */
+	public abstract String getTargetPackage();
+
+	@Override
+    public String toString() {
+        return getFormattedContent();
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedJavaFile.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedJavaFile.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedJavaFile.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedJavaFile.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,84 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import java.util.Set;
+
+import org.apache.ibatis.ibator.api.dom.java.CompilationUnit;
+import org.apache.ibatis.ibator.api.dom.java.FullyQualifiedJavaType;
+
+
+/**
+ * @author Jeff Butler
+ */
+public class GeneratedJavaFile extends GeneratedFile {
+    private CompilationUnit compilationUnit;
+    
+	/**
+	 *  Default constructor
+	 */
+	public GeneratedJavaFile(CompilationUnit compilationUnit,
+            String targetProject) {
+		super(targetProject);
+        this.compilationUnit = compilationUnit;
+	}
+
+	public Set<FullyQualifiedJavaType> getImportedTypes() {
+		return compilationUnit.getImportedTypes();
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.apache.ibatis.ibator.api.GeneratedFile#getFormattedContent()
+	 */
+	@Override
+	public String getFormattedContent() {
+	    return compilationUnit.getFormattedContent();
+	}
+
+	public Set<FullyQualifiedJavaType> getSuperInterfaceTypes() {
+		return compilationUnit.getSuperInterfaceTypes();
+	}
+
+    /**
+     * @return Returns the superClass.
+     */
+    public FullyQualifiedJavaType getSuperClass() {
+        return compilationUnit.getSuperClass();
+    }
+
+    /*
+     *  (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.GeneratedFile#getFileName()
+     */
+	@Override
+    public String getFileName() {
+        return compilationUnit.getType().getShortName() + ".java"; //$NON-NLS-1$
+    }
+
+    /*
+     *  (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.GeneratedFile#getTargetPackage()
+     */
+	@Override
+    public String getTargetPackage() {
+        return compilationUnit.getType().getPackageName();
+    }
+    
+    public boolean isJavaInterface() {
+        return compilationUnit.isJavaInterface();
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,64 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import org.apache.ibatis.ibator.api.dom.xml.Document;
+
+/**
+ * @author Jeff Butler
+ */
+public class GeneratedXmlFile extends GeneratedFile {
+    private Document document;
+
+    private String fileName;
+
+    private String targetPackage;
+
+    /**
+     *  
+     */
+    public GeneratedXmlFile(Document document, String fileName, String targetPackage, String targetProject) {
+        super(targetProject);
+        this.document = document;
+        this.fileName = fileName;
+        this.targetPackage = targetPackage;
+    }
+
+    /*
+     *  (non-Javadoc)
+     * @see org.apache.ibatis.ibator.api.GeneratedFile#getFormattedContent()
+     */
+	@Override
+    public String getFormattedContent() {
+        return document.getFormattedContent();
+    }
+
+    /**
+     * @return Returns the fileName.
+     */
+	@Override
+    public String getFileName() {
+        return fileName;
+    }
+
+    /**
+     * @return Returns the targetPackage.
+     */
+	@Override
+    public String getTargetPackage() {
+        return targetPackage;
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java?rev=648102&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java Mon Apr 14 19:32:53 2008
@@ -0,0 +1,316 @@
+/*
+ *  Copyright 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.
+ */
+package org.apache.ibatis.ibator.api;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ibatis.ibator.config.IbatorConfiguration;
+import org.apache.ibatis.ibator.config.IbatorContext;
+import org.apache.ibatis.ibator.exception.InvalidConfigurationException;
+import org.apache.ibatis.ibator.exception.ShellException;
+import org.apache.ibatis.ibator.internal.DefaultShellCallback;
+import org.apache.ibatis.ibator.internal.IbatorObjectFactory;
+import org.apache.ibatis.ibator.internal.NullProgressCallback;
+import org.apache.ibatis.ibator.internal.XmlFileMergerJaxp;
+import org.apache.ibatis.ibator.internal.util.ClassloaderUtility;
+import org.apache.ibatis.ibator.internal.util.messages.Messages;
+
+/**
+ * This class is the main interface to the iBATOR for iBATIS code generator. A
+ * typical execution of the tool involves these steps:
+ * 
+ * <ol>
+ * <li>Create an IbatorConfiguration object. The IbatorConfiguration can
+ * be the result of a parsing the XML configuration file, or it can be created
+ * solely in Java.</li>
+ * <li>Create an Ibator object</li>
+ * <li>Call one of the generate() methods</li>
+ * </ol>
+ * 
+ * @see org.apache.ibatis.ibator.config.xml.IbatorConfigurationParser
+ * 
+ * @author Jeff Butler
+ */
+public class Ibator {
+
+    private IbatorConfiguration ibatorConfiguration;
+
+    private ShellCallback shellCallback;
+
+    private List<GeneratedJavaFile> generatedJavaFiles;
+
+    private List<GeneratedXmlFile> generatedXmlFiles;
+
+    private List<String> warnings;
+
+    private Set<String> projects;
+
+    /**
+     * Constructs an Ibator object.
+     * 
+     * @param ibatorConfiguration The configuration for this run of iBATOR
+     * @param shellCallback an instance of a ShellCallback interface.  You may specify
+     *    <code>null</code> in which case iBATOR will use the DefaultShellCallback.
+     * @param warnings Any warnings generated during execution will be added to this
+     *            list. Warnings do not affect the running of the tool, but they
+     *            may affect the results. A typical warning is an unsupported
+     *            data type. In that case, the column will be ignored and
+     *            generation will continue. iBATOR will only add Strings to the
+     *            list.  You may specify <code>null</code> if you do not
+     *            want warnings returned.
+     * @throws InvalidConfigurationException if the specified configuration
+     *   is invalid
+     */
+    public Ibator(IbatorConfiguration ibatorConfiguration,
+            ShellCallback shellCallback, List<String> warnings) throws InvalidConfigurationException {
+        super();
+        if (ibatorConfiguration == null) {
+            throw new IllegalArgumentException(Messages.getString("RuntimeError.2")); //$NON-NLS-1$
+        } else {
+            this.ibatorConfiguration = ibatorConfiguration;
+        }
+        
+        if (shellCallback == null) {
+            this.shellCallback = new DefaultShellCallback(false);
+        } else {
+            this.shellCallback = shellCallback;
+        }
+        
+        if (warnings == null) {
+            this.warnings = new ArrayList<String>();
+        } else {
+            this.warnings = warnings;
+        }
+        generatedJavaFiles = new ArrayList<GeneratedJavaFile>();
+        generatedXmlFiles = new ArrayList<GeneratedXmlFile>();
+        projects = new HashSet<String>();
+        
+        this.ibatorConfiguration.validate();
+    }
+
+    /**
+     * This is the main method for generating code.  This method is long running, but
+     * progress can be provided and the method can be cancelled through the ProgressCallback
+     * interface.  This version of the method runs all configured contexts.
+     * 
+     * @param callback an instance of the ProgressCallback interface, or <code>null</code>
+     *   if you do not require progress information
+     * @throws SQLException
+     * @throws IOException
+     * @throws InterruptedException if the method is cancelled through the ProgressCallback
+     */
+    public void generate(ProgressCallback callback)
+            throws SQLException, IOException, InterruptedException {
+        generate(callback, null, null);
+    }
+    
+    /**
+     * This is the main method for generating code.  This method is long running, but
+     * progress can be provided and the method can be cancelled through the ProgressCallback
+     * interface.
+     * 
+     * @param callback an instance of the ProgressCallback interface, or <code>null</code>
+     *   if you do not require progress information
+     * @param contextIds a set of Strings containing context ids to run.  Only the
+     *   contexts with an id specified in this list will be run.  If the list is
+     *   null or empty, than all contexts are run.
+     * @throws InvalidConfigurationException
+     * @throws SQLException
+     * @throws IOException
+     * @throws InterruptedException if the method is cancelled through the ProgressCallback
+     */
+    public void generate(ProgressCallback callback, Set<String> contextIds)
+            throws SQLException, IOException, InterruptedException {
+        generate(callback, contextIds, null);
+    }
+    
+    /**
+     * This is the main method for generating code.  This method is long running, but
+     * progress can be provided and the method can be cancelled through the ProgressCallback
+     * interface.
+     * 
+     * @param callback an instance of the ProgressCallback interface, or <code>null</code>
+     *   if you do not require progress information
+     * @param contextIds a set of Strings containing context ids to run.  Only the
+     *   contexts with an id specified in this list will be run.  If the list is
+     *   null or empty, than all contexts are run.
+     * @param fullyQualifiedTableNames a set of table names to generate.  The elements
+     *   of the set must be Strings that exactly match what's specified in the configuration.
+     *   For example, if table name = "foo" and schema = "bar", then the fully qualified
+     *   table name is "foo.bar".
+     *   If the Set is null or empty, then all tables in the configuration will be
+     *   used for code generation.
+     * @throws InvalidConfigurationException
+     * @throws SQLException
+     * @throws IOException
+     * @throws InterruptedException if the method is cancelled through the ProgressCallback
+     */
+    public void generate(ProgressCallback callback, Set<String> contextIds, Set<String> fullyQualifiedTableNames)
+            throws SQLException, IOException, InterruptedException {
+
+        if (callback == null) {
+            callback = new NullProgressCallback();
+        }
+
+        generatedJavaFiles.clear();
+        generatedXmlFiles.clear();
+        
+        // calculate the contexts to run
+        List<IbatorContext> contextsToRun;
+        if (contextIds == null || contextIds.size() == 0) {
+            contextsToRun = ibatorConfiguration.getIbatorContexts();
+        } else {
+            contextsToRun = new ArrayList<IbatorContext>();
+            Iterator<IbatorContext> iter = ibatorConfiguration.getIbatorContexts().iterator();
+            while (iter.hasNext()) {
+                IbatorContext ibatorContext = iter.next();
+                if (contextIds.contains(ibatorContext.getId())) {
+                    contextsToRun.add(ibatorContext);
+                }
+            }
+        }
+
+        int totalSteps = 0;
+
+        Iterator<IbatorContext> iterContext = contextsToRun.iterator();
+        while (iterContext.hasNext()) {
+            IbatorContext ibatorContext = iterContext.next();
+
+            totalSteps += ibatorContext.getTotalSteps();
+        }
+
+        callback.setNumberOfSubTasks(totalSteps);
+        
+        // setup custom classloader
+        ClassLoader classLoader = 
+            ClassloaderUtility.getCustomClassloader(ibatorConfiguration.getClassPathEntries());
+        IbatorObjectFactory.setClassLoader(classLoader);
+
+        // now run the generates...
+        iterContext = contextsToRun.iterator();
+        while (iterContext.hasNext()) {
+            IbatorContext ibatorContext = iterContext.next();
+
+            ibatorContext.generateFiles(callback, generatedJavaFiles,
+                    generatedXmlFiles, warnings, fullyQualifiedTableNames);
+        }
+        
+        Iterator<GeneratedXmlFile> iterXML = generatedXmlFiles.iterator();
+        while (iterXML.hasNext()) {
+            GeneratedXmlFile gxf = iterXML.next();
+            projects.add(gxf.getTargetProject());
+
+            File targetFile;
+            String source;
+            try {
+                File directory = shellCallback.getDirectory(gxf
+                        .getTargetProject(), gxf.getTargetPackage(), warnings);
+                targetFile = new File(directory, gxf.getFileName());
+                if (targetFile.exists()) {
+                    source = XmlFileMergerJaxp.getMergedSource(gxf, targetFile);
+                } else {
+                    source = gxf.getFormattedContent();
+                }
+            } catch (ShellException e) {
+                warnings.add(e.getMessage());
+                continue;
+            }
+
+            writeFile(targetFile, source);
+        }
+
+        Iterator<GeneratedJavaFile> iterJava = generatedJavaFiles.iterator();
+        while (iterJava.hasNext()) {
+            GeneratedJavaFile gjf = iterJava.next();
+            projects.add(gjf.getTargetProject());
+
+            File targetFile;
+            String source;
+            try {
+                File directory = shellCallback.getDirectory(gjf
+                        .getTargetProject(), gjf.getTargetPackage(), warnings);
+                targetFile = new File(directory, gjf.getFileName());
+                if (targetFile.exists()) {
+                    if (shellCallback.mergeSupported()) {
+                        source = shellCallback.mergeJavaFile(gjf,
+                            "@ibatorgenerated", warnings); //$NON-NLS-1$
+                    } else {
+                        source = gjf.getFormattedContent();
+                        targetFile = getUniqueFileName(directory, gjf);
+                        warnings.add(Messages.getString("Warning.2", targetFile.getAbsolutePath())); //$NON-NLS-1$
+                    }
+                } else {
+                    source = gjf.getFormattedContent();
+                }
+                
+                writeFile(targetFile, source);
+            } catch (ShellException e) {
+                warnings.add(e.getMessage());
+            }
+        }
+
+        Iterator<String> iterString = projects.iterator();
+        while (iterString.hasNext()) {
+            shellCallback.refreshProject(iterString.next());
+        }
+    }
+
+    /**
+     * Writes, or overwrites, the contents of the specified file
+     * 
+     * @param file
+     * @param content
+     */
+    private void writeFile(File file, String content) throws IOException {
+        BufferedWriter bw = new BufferedWriter(new FileWriter(file, false));
+        bw.write(content);
+        bw.close();
+    }
+    
+    private File getUniqueFileName(File directory, GeneratedJavaFile gjf) {
+        File answer = null;
+        
+        // try up to 10000 times to generate a unique file name
+        StringBuffer sb = new StringBuffer();
+        for (int i = 1; i < 10000; i++) {
+            sb.setLength(0);
+            sb.append(gjf.getFileName());
+            sb.append('.');
+            sb.append(i);
+            
+            File testFile = new File(directory, sb.toString());
+            if (!testFile.exists()) {
+                answer = testFile;
+                break;
+            }
+        }
+        
+        if (answer == null) {
+            throw new RuntimeException(Messages.getString("RuntimeError.3", directory.getAbsolutePath())); //$NON-NLS-1$
+        }
+        
+        return answer;
+    }
+}