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/24 01:05:23 UTC

svn commit: r651096 - in /ibatis/trunk/java/tools/ibator/core: build/ doc/ htmldoc/configreference/ src/org/apache/ibatis/ibator/api/ src/org/apache/ibatis/ibator/config/ src/org/apache/ibatis/ibator/config/xml/ src/org/apache/ibatis/ibator/internal/ s...

Author: jgbutler
Date: Wed Apr 23 16:05:17 2008
New Revision: 651096

URL: http://svn.apache.org/viewvc?rev=651096&view=rev
Log:
ibator: more on plugins, and two sample plugins too

Added:
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorPluginConfiguration.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/EqualsHashCodePlugin.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/SqlMapConfigPlugin.java
Modified:
    ibatis/trunk/java/tools/ibator/core/build/version.properties
    ibatis/trunk/java/tools/ibator/core/doc/ReleaseNotes.txt
    ibatis/trunk/java/tools/ibator/core/doc/todo.txt
    ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorConfiguration.html
    ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorContext.html
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPlugin.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPluginAdapter.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorContext.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/IbatorConfigurationParser.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/ibator-config_1_0.dtd
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/DefaultCommentGenerator.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorObjectFactory.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorPluginAggregator.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/XmlFileMergerJaxp.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/java/model/JavaModelGeneratorJava2Impl.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/SqlMapGeneratorIterateImpl.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/XmlConstants.java
    ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/util/messages/messages.properties
    ibatis/trunk/java/tools/ibator/core/testJava2/ibatortest/java2/ibatorConfig.xml
    ibatis/trunk/java/tools/ibator/core/testJava5/ibatortest/ibatorConfig.xml

Modified: ibatis/trunk/java/tools/ibator/core/build/version.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/build/version.properties?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/build/version.properties (original)
+++ ibatis/trunk/java/tools/ibator/core/build/version.properties Wed Apr 23 16:05:17 2008
@@ -1,4 +1,4 @@
 #ibator build version info
-#Tue Apr 22 17:33:38 CDT 2008
+#Wed Apr 23 17:51:25 CDT 2008
 version=1.2.0
-buildNum=455
+buildNum=492

Modified: ibatis/trunk/java/tools/ibator/core/doc/ReleaseNotes.txt
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/doc/ReleaseNotes.txt?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/doc/ReleaseNotes.txt (original)
+++ ibatis/trunk/java/tools/ibator/core/doc/ReleaseNotes.txt Wed Apr 23 16:05:17 2008
@@ -1,15 +1,33 @@
 -------------------------------------------------------------------------------
 Version 1.2.0:  Renamed to ibator
 
+Bugs:
+1. Fixed the JavaTypeResolver so that an unsupported data type can be
+   overridden by configuration.
+
+Enhancements:
+1. Ibator now includes a plugin machanism that you can use to extend or
+   modify code generated by ibator.  In most cases, you should be able
+   to write plugins to replace any custom classes that subclass one of
+   ibator's built-in generators.  Plugins are now the preferred method for
+   extending ibator and we recommend that you do not extend ibator's
+   built in generators unless absolutely necessary.
+   
+   
 Changes:
 1. JSE 5.0 or greater is required
 2. Changed and centralized classloading - moved the <classPathEntry> from
    the <jdbcConnection> element to <ibatorConfiguration>, removed the
    rootClasspath property from <javaModelGenerator>
 3. Changed API on the JavaTypeResolver interface
-4. Removed Legacy generator set
-5. Removed after generation hook methods in favor of the new ibator
+4. Changed API on the SqlMapGenerator interface.  If you have previously extended
+   one of ibator's implementations, we suggest you switch to an ibator plugin.
+5. Changed API on the DAOGenerator interface.  If you have previously extended
+   one of ibator's implementations, we suggest you switch to an ibator plugin.
+6. Removed Legacy generator set
+7. Removed after generation hook methods in favor of the new ibator
    plugin mechanism.
+8. <ibatorContext> elements now require an id
 
 -------------------------------------------------------------------------------
 Version 1.1.0:

Modified: ibatis/trunk/java/tools/ibator/core/doc/todo.txt
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/doc/todo.txt?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/doc/todo.txt (original)
+++ ibatis/trunk/java/tools/ibator/core/doc/todo.txt Wed Apr 23 16:05:17 2008
@@ -3,9 +3,10 @@
   1.2
 
     1. Write page explaining how to use the GENERIC DAOs
-    2. Make a more general method of dealing with the classpath
-    3. Take a look at the Java API - looks a little cumbersome to run
-    4. The mergers should delete the old abator stuff also
+    2. Finish JavaDoc on the IbatorPlugin interface
+    3. Document plugins - plugin lifecycle
+    4. Document example plugins - equals/hashCode generator, sqlMapConfig generator
+    5. Write example plugins - SpringValidator
        
   Future
 
@@ -13,11 +14,7 @@
        runtime, rather than requiring a connection in the 
        XML config.
 
-    2. Write a plugin mechanism for the base code - to be able to add
-       user written plugins.  Good example would be a Spring validator
-       generator plugin, or a plugin that generates SqlMapConfig fragments.
-
-    3. Refactoring: Make a class for each type of method to be generated
+    2. Refactoring: Make a class for each type of method to be generated
     
     4. Relationships?
 
@@ -25,7 +22,7 @@
 
   1.2
   
-    1. Rename to iBATOR
+    1. Rename to ibator
 
     2. Write a launch configuration for the plugin to allow better
        control of the class path.

Modified: ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorConfiguration.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorConfiguration.html?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorConfiguration.html (original)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorConfiguration.html Wed Apr 23 16:05:17 2008
@@ -19,7 +19,7 @@
 </p>
 <pre>
 &lt;!DOCTYPE ibatorConfiguration PUBLIC
-  "-//Apache Software Foundation//DTD ibator for iBATIS Configuration 1.0//EN"
+  "-//Apache Software Foundation//DTD Apache iBATIS ibator Configuration 1.0//EN"
   "http://ibatis.apache.org/dtd/ibator-config_1_0.dtd"&gt;
 </pre>
 
@@ -31,7 +31,6 @@
 
 <h2>Child Elements</h2>
 <ul>
-  <li><a href="properties.html">&lt;properties&gt;</a> (0 or 1)</li>
   <li><a href="classPathEntry.html">&lt;classPathEntry&gt;</a> (0..N)</li>
   <li><a href="ibatorContext.html">&lt;ibatorContext&gt;</a> (1..N)</li>
 </ul>

Modified: ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorContext.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorContext.html?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorContext.html (original)
+++ ibatis/trunk/java/tools/ibator/core/htmldoc/configreference/ibatorContext.html Wed Apr 23 16:05:17 2008
@@ -23,7 +23,17 @@
 databases, or with different generation parameters, in the same run of ibator.</p>
 
 <h2>Required Attributes</h2>
-<p>None</p>
+<table border="1" cellspacing="0" cellpadding="5">
+  <tr>
+    <th>Attribute</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>id</td>
+    <td>A unique identifier for this context.  This value will be used in some
+      error messages.</td>
+  </tr>
+</table>
 
 <h2>Optional Attributes</h2>
 <table border="1" cellspacing="0" cellpadding="5">
@@ -63,11 +73,6 @@
         </tr>
       </table>
     </td>
-  </tr>
-  <tr>
-    <td>id</td>
-    <td>A unique identifier for this context.  This value will be used in some
-      error messages.</td>
   </tr>
   <tr>
     <td valign="top">generatorSet</td>

Modified: 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=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/GeneratedXmlFile.java Wed Apr 23 16:05:17 2008
@@ -26,15 +26,25 @@
     private String fileName;
 
     private String targetPackage;
+    
+    private boolean isMergeable;
 
     /**
-     *  
+     * 
+     * @param document
+     * @param fileName
+     * @param targetPackage
+     * @param targetProject
+     * @param isMergeable true if the file can be merged by the built in
+     *   XML file merger.  Files are mergeable if all mergeable elements contain
+     *   id's with the "ibatorgenerated_" prefix.
      */
-    public GeneratedXmlFile(Document document, String fileName, String targetPackage, String targetProject) {
+    public GeneratedXmlFile(Document document, String fileName, String targetPackage, String targetProject, boolean isMergeable) {
         super(targetProject);
         this.document = document;
         this.fileName = fileName;
         this.targetPackage = targetPackage;
+        this.isMergeable = isMergeable;
     }
 
     /*
@@ -60,5 +70,13 @@
 	@Override
     public String getTargetPackage() {
         return targetPackage;
+    }
+
+    public Document getDocument() {
+        return document;
+    }
+
+    public boolean isMergeable() {
+        return isMergeable;
     }
 }

Modified: 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=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/Ibator.java Wed Apr 23 16:05:17 2008
@@ -219,7 +219,13 @@
                         .getTargetProject(), gxf.getTargetPackage(), warnings);
                 targetFile = new File(directory, gxf.getFileName());
                 if (targetFile.exists()) {
-                    source = XmlFileMergerJaxp.getMergedSource(gxf, targetFile);
+                    if (gxf.isMergeable()) {
+                        source = XmlFileMergerJaxp.getMergedSource(gxf, targetFile);
+                    } else {
+                        source = gxf.getFormattedContent();
+                        targetFile = getUniqueFileName(directory, gxf.getFileName());
+                        warnings.add(Messages.getString("Warning.2", targetFile.getAbsolutePath())); //$NON-NLS-1$
+                    }
                 } else {
                     source = gxf.getFormattedContent();
                 }
@@ -247,7 +253,7 @@
                                 warnings);
                     } else {
                         source = gjf.getFormattedContent();
-                        targetFile = getUniqueFileName(directory, gjf);
+                        targetFile = getUniqueFileName(directory, gjf.getFileName());
                         warnings.add(Messages.getString("Warning.2", targetFile.getAbsolutePath())); //$NON-NLS-1$
                     }
                 } else {
@@ -277,14 +283,14 @@
         bw.close();
     }
     
-    private File getUniqueFileName(File directory, GeneratedJavaFile gjf) {
+    private File getUniqueFileName(File directory, String fileName) {
         File answer = null;
         
         // try up to 1000 times to generate a unique file name
         StringBuffer sb = new StringBuffer();
         for (int i = 1; i < 1000; i++) {
             sb.setLength(0);
-            sb.append(gjf.getFileName());
+            sb.append(fileName);
             sb.append('.');
             sb.append(i);
             

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPlugin.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPlugin.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPlugin.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPlugin.java Wed Apr 23 16:05:17 2008
@@ -21,7 +21,6 @@
 import org.apache.ibatis.ibator.api.dom.java.Interface;
 import org.apache.ibatis.ibator.api.dom.java.Method;
 import org.apache.ibatis.ibator.api.dom.java.TopLevelClass;
-import org.apache.ibatis.ibator.api.dom.xml.Document;
 import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
 import org.apache.ibatis.ibator.config.IbatorContext;
 
@@ -48,6 +47,23 @@
      * @param properties
      */
     void setProperties(Properties properties);
+    
+    /**
+     * This method is called after all the setXXX methods are called, but before any
+     * other method is called.  This allows the plugin to determine whether
+     * it can run or not.  For example, if the plugin requires certain properties
+     * to be set, and the properties are not set, then the plugin is invalid
+     * and will not run.
+     * 
+     * @param warnings add strings to this list to specify warnings.  For example,
+     *   if the plugin is invalid, you should specify why.
+     * @return true if the plugin is valid.  Invalid plugins will not be
+     *   called
+     */
+    boolean validate(List<String> warnings);
+    
+    List<GeneratedJavaFile> generateAdditionalJavaFiles();
+    List<GeneratedXmlFile> generateAdditionalXmlFiles();
 
     /**
      * This method can be used by plugins to generate additional Java classes.
@@ -83,11 +99,11 @@
     void modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable);
     
     // methods related to generated XML elements
-    List<GeneratedXmlFile> generateAdditionalXMLFiles(IntrospectedTable introspectedTable);
+    List<GeneratedXmlFile> generateAdditionalXmlFiles(IntrospectedTable introspectedTable);
     
     // the following methods are only guaranteed to be called with the built in 
     // ibator SqlMap generators.
-    void sqlMapGenerated(Document document, IntrospectedTable introspectedTable);
+    void sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable);
     void sqlMapBaseResultMapGenerated(XmlElement element, IntrospectedTable introspectedTable);
     void sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable);
     void sqlMapDeleteByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable);

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPluginAdapter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPluginAdapter.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPluginAdapter.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/api/IbatorPluginAdapter.java Wed Apr 23 16:05:17 2008
@@ -21,21 +21,27 @@
 import org.apache.ibatis.ibator.api.dom.java.Interface;
 import org.apache.ibatis.ibator.api.dom.java.Method;
 import org.apache.ibatis.ibator.api.dom.java.TopLevelClass;
-import org.apache.ibatis.ibator.api.dom.xml.Document;
 import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
 import org.apache.ibatis.ibator.config.IbatorContext;
 
 /**
- * This class includes no-operation methods for every method in the
+ * This class includes no-operation methods for almost every method in the
  * IbatorPlugin interface.  Clients may extend this class to implement
- * some or all of the methods in a plugin. 
+ * some or all of the methods in a plugin.
+ * <p>
+ * This adapter does not implement the <tt>validate</tt> method -
+ * all plugins must perform validation.
  * 
  * @author Jeff Butler
  *
  */
-public class IbatorPluginAdapter implements IbatorPlugin {
+public abstract class IbatorPluginAdapter implements IbatorPlugin {
     protected IbatorContext ibatorContext;
     protected Properties properties;
+    
+    public IbatorPluginAdapter () {
+        properties = new Properties();
+    }
 
     public IbatorContext getIbatorContext() {
         return ibatorContext;
@@ -50,13 +56,13 @@
     }
 
     public void setProperties(Properties properties) {
-        this.properties = properties;
+        this.properties.putAll(properties);
     }
 
-    public void modelBaseRecordClassGenerated(TopLevelClass baseClass, IntrospectedTable introspectedTable) {
+    public void modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
     }
 
-    public void modelRecordWithBLOBsClassGenerated(TopLevelClass blobsClass, IntrospectedTable introspectedTable) {
+    public void modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
     }
 
     public void sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable table) {
@@ -68,21 +74,21 @@
     public void sqlMapDeleteByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable table) {
     }
 
-    public void modelExampleClassGenerated(TopLevelClass example, IntrospectedTable introspectedTable) {
+    public void modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
     }
 
     public List<GeneratedJavaFile> generateAdditionalModelClasses(IntrospectedTable introspectedTable) {
         return null;
     }
 
-    public List<GeneratedXmlFile> generateAdditionalXMLFiles(IntrospectedTable introspectedTable) {
+    public List<GeneratedXmlFile> generateAdditionalXmlFiles(IntrospectedTable introspectedTable) {
         return null;
     }
 
-    public void modelPrimaryKeyClassGenerated(TopLevelClass primaryKey, IntrospectedTable introspectedTable) {
+    public void modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
     }
 
-    public void sqlMapGenerated(Document document, IntrospectedTable introspectedTable) {
+    public void sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
     }
 
     public void sqlMapBaseResultMapGenerated(XmlElement element, IntrospectedTable introspectedTable) {
@@ -209,6 +215,14 @@
     }
 
     public List<GeneratedJavaFile> generateAdditionalDAOClasses(IntrospectedTable introspectedTable) {
+        return null;
+    }
+
+    public List<GeneratedJavaFile> generateAdditionalJavaFiles() {
+        return null;
+    }
+
+    public List<GeneratedXmlFile> generateAdditionalXmlFiles() {
         return null;
     }
 }

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorContext.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorContext.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorContext.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorContext.java Wed Apr 23 16:05:17 2008
@@ -78,6 +78,8 @@
     
     private IbatorPluginAggregator pluginAggregator;
     
+    private List<IbatorPluginConfiguration> pluginConfigurations;
+    
     /**
      * Constructs an IbatorContext object.
      * 
@@ -106,7 +108,7 @@
         }
         
 		tableConfigurations = new ArrayList<TableConfiguration>();
-        pluginAggregator = new IbatorPluginAggregator();
+        pluginConfigurations = new ArrayList<IbatorPluginConfiguration>();
     }
 
 	public void addTableConfiguration(TableConfiguration tc) {
@@ -132,18 +134,24 @@
 	public SqlMapGeneratorConfiguration getSqlMapGeneratorConfiguration() {
 		return sqlMapGeneratorConfiguration;
 	}
+    
+    public void addPluginConfiguration(IbatorPluginConfiguration ibatorPluginConfiguration) {
+        pluginConfigurations.add(ibatorPluginConfiguration);
+    }
 
 	/**
 	 * This method does a simple validate, it makes sure that all required
-	 * fields have been filled in and that all implementation classes exist and
-	 * are of the proper type. It does not do any more complex operations such
-	 * as: Validating that database tables exist or Validating that named
+	 * fields have been filled in. It does not do any more complex operations such
+	 * as validating that database tables exist or validating that named
 	 * columns exist
 	 */
 	public void validate(List<String> errors) {
+        if (!StringUtility.stringHasValue(id)) {
+            errors.add(Messages.getString("ValidationError.16")); //$NON-NLS-1$
+        }
+        
         if (jdbcConnectionConfiguration == null) {
             errors.add(Messages.getString("ValidationError.10")); //$NON-NLS-1$
-            return;
         } else {
             jdbcConnectionConfiguration.validate(errors);
         }
@@ -194,6 +202,10 @@
 				tc.validate(errors, i);
 			}
 		}
+        
+        for (IbatorPluginConfiguration ibatorPluginConfiguration : pluginConfigurations) {
+            ibatorPluginConfiguration.validate(errors, id);
+        }
 	}
 	
 	/**
@@ -228,22 +240,33 @@
 	        callback = new NullProgressCallback();
 	    }
 	    
-	    JavaTypeResolver javaTypeResolver = IbatorObjectFactory.createJavaTypeResolver(this, warnings);
-	    JavaModelGenerator javaModelGenerator = IbatorObjectFactory.createJavaModelGenerator(this, warnings);
-	    SqlMapGenerator sqlMapGenerator = IbatorObjectFactory.createSqlMapGenerator(this, javaModelGenerator, warnings);
-	    DAOGenerator daoGenerator = IbatorObjectFactory.createDAOGenerator(this, javaModelGenerator, sqlMapGenerator, warnings);
+        JavaTypeResolver javaTypeResolver = IbatorObjectFactory.createJavaTypeResolver(this, warnings);
+        JavaModelGenerator javaModelGenerator = IbatorObjectFactory.createJavaModelGenerator(this, warnings);
+        SqlMapGenerator sqlMapGenerator = IbatorObjectFactory.createSqlMapGenerator(this, javaModelGenerator, warnings);
+        DAOGenerator daoGenerator = IbatorObjectFactory.createDAOGenerator(this, javaModelGenerator, sqlMapGenerator, warnings);
+        pluginAggregator = new IbatorPluginAggregator();
+        for (IbatorPluginConfiguration ibatorPluginConfiguration : pluginConfigurations) {
+            IbatorPlugin plugin = IbatorObjectFactory.createIbatorPlugin(this, ibatorPluginConfiguration);
+            if (plugin.validate(warnings)) {
+                pluginAggregator.addPlugin(plugin);
+            } else {
+                warnings.add(Messages.getString("Warning.24", //$NON-NLS-1$
+                        ibatorPluginConfiguration.getConfigurationType(),
+                        id));
+            }
+        }
 
-		Connection connection = null;
+        Connection connection = null;
 		
-		try {
-			callback.startSubTask(Messages.getString("Progress.0")); //$NON-NLS-1$
-			connection = getConnection();
-            
+        try {
+            callback.startSubTask(Messages.getString("Progress.0")); //$NON-NLS-1$
+            connection = getConnection();
+
             DatabaseIntrospector databaseIntrospector =
                 new DatabaseIntrospector(this, connection.getMetaData(), javaTypeResolver, warnings);
 
             for (TableConfiguration tc : tableConfigurations) {
-				String tableName = StringUtility.composeFullyQualifiedTableName(
+                String tableName = StringUtility.composeFullyQualifiedTableName(
                         tc.getCatalog(), tc.getSchema(), tc.getTableName(), '.');
                 
                 if (fullyQualifiedTableNames != null
@@ -253,16 +276,15 @@
                     }
                 }
 				
-				if (!tc.areAnyStatementsEnabled()) {
-				    warnings.add(Messages.getString("Warning.0", tableName)); //$NON-NLS-1$
-				    continue;
-				}
-				
+                if (!tc.areAnyStatementsEnabled()) {
+                    warnings.add(Messages.getString("Warning.0", tableName)); //$NON-NLS-1$
+                    continue;
+                }
 
-				Collection<? extends IntrospectedTable> introspectedTables;
-				callback.startSubTask(Messages.getString("Progress.1", tableName)); //$NON-NLS-1$
+                Collection<? extends IntrospectedTable> introspectedTables;
+                callback.startSubTask(Messages.getString("Progress.1", tableName)); //$NON-NLS-1$
                 introspectedTables  = databaseIntrospector.introspectTables(tc);
-				callback.checkCancel();
+                callback.checkCancel();
                 
                 if (introspectedTables != null) {
                     for (IntrospectedTable introspectedTable : introspectedTables) {
@@ -277,14 +299,17 @@
                         generatedJavaFiles.addAll(pluginAggregator.generateAdditionalModelClasses(introspectedTable));
                         
                         generatedXmlFiles.addAll(sqlMapGenerator.getGeneratedXMLFiles(introspectedTable, callback));
-                        generatedXmlFiles.addAll(pluginAggregator.generateAdditionalXMLFiles(introspectedTable));
+                        generatedXmlFiles.addAll(pluginAggregator.generateAdditionalXmlFiles(introspectedTable));
                     }
                 }
-			}
-		} finally {
-			closeConnection(connection);
-			callback.finished();
-		}
+            }
+            
+            generatedJavaFiles.addAll(pluginAggregator.generateAdditionalJavaFiles());
+            generatedXmlFiles.addAll(pluginAggregator.generateAdditionalXmlFiles());
+        } finally {
+            closeConnection(connection);
+            callback.finished();
+        }
 	}
 	
 	public int getTotalSteps() {
@@ -466,5 +491,9 @@
 
     public IbatorPlugin getPluginAggregator() {
         return pluginAggregator;
+    }
+
+    public String getConfiguredGeneratorSet() {
+        return configuredGeneratorSet;
     }
 }

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorPluginConfiguration.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorPluginConfiguration.java?rev=651096&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorPluginConfiguration.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/IbatorPluginConfiguration.java Wed Apr 23 16:05:17 2008
@@ -0,0 +1,51 @@
+/*
+ *  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.config;
+
+import java.util.List;
+
+import org.apache.ibatis.ibator.api.dom.xml.Attribute;
+import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
+import org.apache.ibatis.ibator.internal.util.StringUtility;
+import org.apache.ibatis.ibator.internal.util.messages.Messages;
+
+/**
+ * 
+ * @author Jeff Butler
+ *
+ */
+public class IbatorPluginConfiguration extends TypedPropertyHolder {
+    public IbatorPluginConfiguration() {
+    }
+
+    public XmlElement toXmlElement() {
+        XmlElement answer = new XmlElement("ibatorPlugin"); //$NON-NLS-1$
+        if (getConfigurationType() != null) {
+            answer.addAttribute(new Attribute("type", getConfigurationType())); //$NON-NLS-1$
+        }
+        
+        addPropertyXmlElements(answer);
+        
+        return answer;
+    }
+    
+    public void validate(List<String> errors, String contextId) {
+        if (!StringUtility.stringHasValue(getConfigurationType())) {
+            errors.add(Messages.getString("ValidationError.17", //$NON-NLS-1$
+                    contextId));
+        }
+    }
+}

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/IbatorConfigurationParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/IbatorConfigurationParser.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/IbatorConfigurationParser.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/IbatorConfigurationParser.java Wed Apr 23 16:05:17 2008
@@ -36,6 +36,7 @@
 import org.apache.ibatis.ibator.config.CommentGeneratorConfiguration;
 import org.apache.ibatis.ibator.config.DAOGeneratorConfiguration;
 import org.apache.ibatis.ibator.config.GeneratedKey;
+import org.apache.ibatis.ibator.config.IbatorPluginConfiguration;
 import org.apache.ibatis.ibator.config.IgnoredColumn;
 import org.apache.ibatis.ibator.config.JDBCConnectionConfiguration;
 import org.apache.ibatis.ibator.config.JavaModelGeneratorConfiguration;
@@ -258,6 +259,8 @@
 
             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                 parseProperty(ibatorContext, childNode);
+            } else if ("ibatorPlugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
+                parseIbatorPlugin(ibatorContext, childNode);
             } else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                 parseCommentGenerator(ibatorContext, childNode);
             } else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
@@ -549,6 +552,30 @@
         }
     }
 
+    private void parseIbatorPlugin(IbatorContext ibatorContext, Node node) {
+        IbatorPluginConfiguration ibatorPluginConfiguration = new IbatorPluginConfiguration();
+
+        ibatorContext.addPluginConfiguration(ibatorPluginConfiguration);
+
+        Properties attributes = parseAttributes(node);
+        String type = attributes.getProperty("type"); //$NON-NLS-1$
+
+        ibatorPluginConfiguration.setConfigurationType(type);
+
+        NodeList nodeList = node.getChildNodes();
+        for (int i = 0; i < nodeList.getLength(); i++) {
+            Node childNode = nodeList.item(i);
+
+            if (childNode.getNodeType() != 1) {
+                continue;
+            }
+
+            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
+                parseProperty(ibatorPluginConfiguration, childNode);
+            }
+        }
+    }
+    
     private void parseJavaModelGenerator(IbatorContext ibatorContext, Node node) {
         JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
 

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/ibator-config_1_0.dtd
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/ibator-config_1_0.dtd?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/ibator-config_1_0.dtd (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/config/xml/ibator-config_1_0.dtd Wed Apr 23 16:05:17 2008
@@ -50,9 +50,9 @@
   The ibatorContext element is used to describe a context for generating files, and the source
   tables.
 -->
-<!ELEMENT ibatorContext (property*, commentGenerator?, jdbcConnection, javaTypeResolver?, javaModelGenerator,
-                        sqlMapGenerator, daoGenerator?, table+)>
-<!ATTLIST ibatorContext id ID #IMPLIED
+<!ELEMENT ibatorContext (property*, ibatorPlugin*, commentGenerator?, jdbcConnection, javaTypeResolver?,
+                         javaModelGenerator, sqlMapGenerator, daoGenerator?, table+)>
+<!ATTLIST ibatorContext id ID #REQUIRED
   defaultModelType CDATA #IMPLIED
   generatorSet CDATA #IMPLIED>
 
@@ -85,6 +85,13 @@
 <!ATTLIST property
   name CDATA #REQUIRED
   value CDATA #REQUIRED>
+
+<!--
+  The ibatorPlugin element is used to define an ibator plugin.
+-->
+<!ELEMENT ibatorPlugin (property*)>
+<!ATTLIST ibatorPlugin
+  type CDATA #REQUIRED>
 
 <!--
   The javaModelGenerator element is used to define properties of the Java Model Generator.

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/DefaultCommentGenerator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/DefaultCommentGenerator.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/DefaultCommentGenerator.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/DefaultCommentGenerator.java Wed Apr 23 16:05:17 2008
@@ -52,7 +52,7 @@
         StringBuffer sb = new StringBuffer();
         
         field.addJavaDocLine("/**"); //$NON-NLS-1$
-        field.addJavaDocLine(" * This field was generated by ibator for iBATIS."); //$NON-NLS-1$
+        field.addJavaDocLine(" * This field was generated by Apache iBATIS ibator."); //$NON-NLS-1$
         
         sb.append(" * This field corresponds to the database column "); //$NON-NLS-1$
         sb.append(table);
@@ -69,7 +69,7 @@
         StringBuffer sb = new StringBuffer();
         
         field.addJavaDocLine("/**"); //$NON-NLS-1$
-        field.addJavaDocLine(" * This field was generated by ibator for iBATIS."); //$NON-NLS-1$
+        field.addJavaDocLine(" * This field was generated by Apache iBATIS ibator."); //$NON-NLS-1$
         
         sb.append(" * This field corresponds to the database table "); //$NON-NLS-1$
         sb.append(table);
@@ -84,7 +84,7 @@
         StringBuffer sb = new StringBuffer();
         
         innerClass.addJavaDocLine("/**"); //$NON-NLS-1$
-        innerClass.addJavaDocLine(" * This class was generated by ibator for iBATIS."); //$NON-NLS-1$
+        innerClass.addJavaDocLine(" * This class was generated by Apache iBATIS ibator."); //$NON-NLS-1$
         
         sb.append(" * This class corresponds to the database table "); //$NON-NLS-1$
         sb.append(table);
@@ -99,7 +99,7 @@
         StringBuffer sb = new StringBuffer();
         
         innerEnum.addJavaDocLine("/**"); //$NON-NLS-1$
-        innerEnum.addJavaDocLine(" * This enum was generated by ibator for iBATIS."); //$NON-NLS-1$
+        innerEnum.addJavaDocLine(" * This enum was generated by Apache iBATIS ibator."); //$NON-NLS-1$
         
         sb.append(" * This enum corresponds to the database table "); //$NON-NLS-1$
         sb.append(table);
@@ -114,7 +114,7 @@
         StringBuffer sb = new StringBuffer();
         
         method.addJavaDocLine("/**"); //$NON-NLS-1$
-        method.addJavaDocLine(" * This method was generated by ibator for iBATIS."); //$NON-NLS-1$
+        method.addJavaDocLine(" * This method was generated by Apache iBATIS ibator."); //$NON-NLS-1$
     
         sb.append(" * This method returns the value of the database column "); //$NON-NLS-1$
         sb.append(table);
@@ -140,7 +140,7 @@
         StringBuffer sb = new StringBuffer();
         
         method.addJavaDocLine("/**"); //$NON-NLS-1$
-        method.addJavaDocLine(" * This method was generated by ibator for iBATIS."); //$NON-NLS-1$
+        method.addJavaDocLine(" * This method was generated by Apache iBATIS ibator."); //$NON-NLS-1$
     
         sb.append(" * This method sets the value of the database column "); //$NON-NLS-1$
         sb.append(table);
@@ -169,7 +169,7 @@
         StringBuffer sb = new StringBuffer();
         
         method.addJavaDocLine("/**"); //$NON-NLS-1$
-        method.addJavaDocLine(" * This method was generated by ibator for iBATIS."); //$NON-NLS-1$
+        method.addJavaDocLine(" * This method was generated by Apache iBATIS ibator."); //$NON-NLS-1$
         
         sb.append(" * This method corresponds to the database table "); //$NON-NLS-1$
         sb.append(table);
@@ -192,7 +192,7 @@
     public void addComment(XmlElement xmlElement) {
         xmlElement.addElement(new TextElement("<!--")); //$NON-NLS-1$
         xmlElement.addElement(new TextElement(
-                "  WARNING - This element is automatically generated by ibator for iBATIS, do not modify.")); //$NON-NLS-1$
+                "  WARNING - This element is automatically generated by Apache iBATIS ibator, do not modify.")); //$NON-NLS-1$
 
         String s = getDateString();
         if (s != null) {

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorObjectFactory.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorObjectFactory.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorObjectFactory.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorObjectFactory.java Wed Apr 23 16:05:17 2008
@@ -21,12 +21,14 @@
 
 import org.apache.ibatis.ibator.api.CommentGenerator;
 import org.apache.ibatis.ibator.api.DAOGenerator;
+import org.apache.ibatis.ibator.api.IbatorPlugin;
 import org.apache.ibatis.ibator.api.JavaModelGenerator;
 import org.apache.ibatis.ibator.api.JavaTypeResolver;
 import org.apache.ibatis.ibator.api.SqlMapGenerator;
 import org.apache.ibatis.ibator.config.IbatorContext;
 import org.apache.ibatis.ibator.config.CommentGeneratorConfiguration;
 import org.apache.ibatis.ibator.config.DAOGeneratorConfiguration;
+import org.apache.ibatis.ibator.config.IbatorPluginConfiguration;
 import org.apache.ibatis.ibator.config.JavaModelGeneratorConfiguration;
 import org.apache.ibatis.ibator.config.JavaTypeResolverConfiguration;
 import org.apache.ibatis.ibator.config.SqlMapGeneratorConfiguration;
@@ -117,6 +119,13 @@
 	    
 	    return answer;
 	}
+    
+    public static IbatorPlugin createIbatorPlugin(IbatorContext ibatorContext, IbatorPluginConfiguration ibatorPluginConfiguration) {
+        IbatorPlugin ibatorPlugin = (IbatorPlugin) createObject(ibatorPluginConfiguration.getConfigurationType());
+        ibatorPlugin.setIbatorContext(ibatorContext);
+        ibatorPlugin.setProperties(ibatorPluginConfiguration.getProperties());
+        return ibatorPlugin;
+    }
 	
 	public static SqlMapGenerator createSqlMapGenerator(IbatorContext context,
 	        JavaModelGenerator javaModelGenerator, List<String> warnings) {

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorPluginAggregator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorPluginAggregator.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorPluginAggregator.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/IbatorPluginAggregator.java Wed Apr 23 16:05:17 2008
@@ -26,11 +26,20 @@
 import org.apache.ibatis.ibator.api.dom.java.Interface;
 import org.apache.ibatis.ibator.api.dom.java.Method;
 import org.apache.ibatis.ibator.api.dom.java.TopLevelClass;
-import org.apache.ibatis.ibator.api.dom.xml.Document;
 import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
 import org.apache.ibatis.ibator.config.IbatorContext;
 
-public class IbatorPluginAggregator implements IbatorPlugin {
+/**
+ * THis class is for internal use only.  It contains a list of plugins
+ * for the current context and is used to aggregate plugins together.
+ * <p>
+ * This class does not follow the normal plugin lifecycle and should not be
+ * subclassed by clients.
+ * 
+ * @author Jeff
+ *
+ */
+public final class IbatorPluginAggregator implements IbatorPlugin {
     private List<IbatorPlugin> plugins;
 
     public IbatorPluginAggregator() {
@@ -41,6 +50,18 @@
         plugins.add(plugin);
     }
 
+    public void setIbatorContext(IbatorContext ibatorContext) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setProperties(Properties properties) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean validate(List<String> warnings) {
+        throw new UnsupportedOperationException();
+    }
+    
     public void modelBaseRecordClassGenerated(TopLevelClass tlc,
             IntrospectedTable introspectedTable) {
         for (IbatorPlugin plugin : plugins) {
@@ -95,11 +116,11 @@
         return answer;
     }
 
-    public List<GeneratedXmlFile> generateAdditionalXMLFiles(
+    public List<GeneratedXmlFile> generateAdditionalXmlFiles(
             IntrospectedTable introspectedTable) {
         List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>();
         for (IbatorPlugin plugin : plugins) {
-            List<GeneratedXmlFile> temp = plugin.generateAdditionalXMLFiles(introspectedTable);
+            List<GeneratedXmlFile> temp = plugin.generateAdditionalXmlFiles(introspectedTable);
             if (temp != null) {
                 answer.addAll(temp);
             }
@@ -114,11 +135,6 @@
         }
     }
 
-    public void setIbatorContext(IbatorContext ibatorContext) {
-        // ignore - not needed here
-        ;
-    }
-
     public void sqlMapBaseResultMapGenerated(XmlElement element, IntrospectedTable introspectedTable) {
         for (IbatorPlugin plugin : plugins) {
             plugin.sqlMapBaseResultMapGenerated(element, introspectedTable);
@@ -161,9 +177,9 @@
         }
     }
 
-    public void sqlMapGenerated(Document document, IntrospectedTable introspectedTable) {
+    public void sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
         for (IbatorPlugin plugin : plugins) {
-            plugin.sqlMapGenerated(document, introspectedTable);
+            plugin.sqlMapGenerated(sqlMap, introspectedTable);
         }
     }
 
@@ -203,11 +219,6 @@
         }
     }
 
-    public void setProperties(Properties properties) {
-        // ignore - not needed here
-        ;
-    }
-
     public void daoCountByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
         for (IbatorPlugin plugin : plugins) {
             plugin.daoCountByExampleMethodGenerated(method, interfaze, introspectedTable);
@@ -380,6 +391,28 @@
         List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
         for (IbatorPlugin plugin : plugins) {
             List<GeneratedJavaFile> temp = plugin.generateAdditionalDAOClasses(introspectedTable);
+            if (temp != null) {
+                answer.addAll(temp);
+            }
+        }
+        return answer;
+    }
+
+    public List<GeneratedJavaFile> generateAdditionalJavaFiles() {
+        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
+        for (IbatorPlugin plugin : plugins) {
+            List<GeneratedJavaFile> temp = plugin.generateAdditionalJavaFiles();
+            if (temp != null) {
+                answer.addAll(temp);
+            }
+        }
+        return answer;
+    }
+
+    public List<GeneratedXmlFile> generateAdditionalXmlFiles() {
+        List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>();
+        for (IbatorPlugin plugin : plugins) {
+            List<GeneratedXmlFile> temp = plugin.generateAdditionalXmlFiles();
             if (temp != null) {
                 answer.addAll(temp);
             }

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/XmlFileMergerJaxp.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/XmlFileMergerJaxp.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/XmlFileMergerJaxp.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/XmlFileMergerJaxp.java Wed Apr 23 16:05:17 2008
@@ -31,6 +31,7 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentType;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
@@ -91,10 +92,25 @@
             Element existingRootElement = existingDocument.getDocumentElement();
             Element newRootElement = newDocument.getDocumentElement();
 
-            // reconcile the namespace
-            String namespace = newRootElement.getAttribute("namespace"); //$NON-NLS-1$
-            existingRootElement.setAttribute("namespace", namespace); //$NON-NLS-1$
+            // reconcile the root element attributes -
+            // take all attributes from the new element and add to the existing element
+            
+            // remove all attributes from the existing root element
+            NamedNodeMap attributes = existingRootElement.getAttributes();
+            int attributeCount = attributes.getLength();
+            for (int i = attributeCount - 1; i >= 0; i--) {
+                Node node = attributes.item(i);
+                existingRootElement.removeAttribute(node.getNodeName());
+            }
 
+            // add attributes from the new root node to the old root node
+            attributes = newRootElement.getAttributes();
+            attributeCount = attributes.getLength();
+            for (int i = 0; i < attributeCount; i++) {
+                Node node = attributes.item(i);
+                existingRootElement.setAttribute(node.getNodeName(), node.getNodeValue());
+            }
+            
             // remove the old ibator generated elements and any
             // white space before the old ibator nodes
             List<Node> nodesToDelete = new ArrayList<Node>();

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/java/model/JavaModelGeneratorJava2Impl.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/java/model/JavaModelGeneratorJava2Impl.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/java/model/JavaModelGeneratorJava2Impl.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/java/model/JavaModelGeneratorJava2Impl.java Wed Apr 23 16:05:17 2008
@@ -1513,21 +1513,21 @@
 
                 // Is it the proper type?
                 if (!rootClassProperties[i].getPropertyType().getName().equals(propertyType)) {
-                    warnings.add(Messages.getString("Warning.21",
+                    warnings.add(Messages.getString("Warning.21", //$NON-NLS-1$
                             propertyName, rootClass, propertyType));
                     break;
                 }
                 
                 // Does it have a getter?
                 if (rootClassProperties[i].getReadMethod() == null) {
-                    warnings.add(Messages.getString("Warning.22",
+                    warnings.add(Messages.getString("Warning.22", //$NON-NLS-1$
                             propertyName, rootClass));
                     break;
                 }
                 
                 // Does it have a setter?
                 if (rootClassProperties[i].getWriteMethod() == null) {
-                    warnings.add(Messages.getString("Warning.23",
+                    warnings.add(Messages.getString("Warning.23", //$NON-NLS-1$
                             propertyName, rootClass));
                     break;
                 }

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/SqlMapGeneratorIterateImpl.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/SqlMapGeneratorIterateImpl.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/SqlMapGeneratorIterateImpl.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/SqlMapGeneratorIterateImpl.java Wed Apr 23 16:05:17 2008
@@ -151,13 +151,13 @@
                 XmlConstants.SQL_MAP_SYSTEM_ID);
         document.setRootElement(getSqlMapElement(introspectedTable));
         
-        ibatorContext.getPluginAggregator().sqlMapGenerated(document, introspectedTable);
-        
         FullyQualifiedTable table = introspectedTable.getTable();
         GeneratedXmlFile answer = new GeneratedXmlFile(document,
                 getSqlMapFileName(table), getSqlMapPackage(table),
-                targetProject);
+                targetProject, true);
 
+        ibatorContext.getPluginAggregator().sqlMapGenerated(answer, introspectedTable);
+        
         return answer;
     }
 
@@ -174,8 +174,8 @@
         answer.addAttribute(new Attribute("namespace", //$NON-NLS-1$
                 table.getSqlMapNamespace()));
 
-        ibatorContext.getCommentGenerator().addRootComment(answer);
         IbatorPlugin plugin = ibatorContext.getPluginAggregator();
+        ibatorContext.getCommentGenerator().addRootComment(answer);
         
         IbatorRules rules = introspectedTable.getRules();
         XmlElement element;
@@ -1217,8 +1217,8 @@
 
         XmlElement answer = new XmlElement("select"); //$NON-NLS-1$
 
-        answer.addAttribute(new Attribute("id",
-                XmlConstants.SELECT_BY_EXAMPLE_STATEMENT_ID)); //$NON-NLS-1$
+        answer.addAttribute(new Attribute("id", //$NON-NLS-1$
+                XmlConstants.SELECT_BY_EXAMPLE_STATEMENT_ID));
         answer
                 .addAttribute(new Attribute(
                         "resultMap", getResultMapName(table))); //$NON-NLS-1$

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/XmlConstants.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/XmlConstants.java?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/XmlConstants.java (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/sqlmap/XmlConstants.java Wed Apr 23 16:05:17 2008
@@ -101,6 +101,10 @@
 
     public static final String SQL_MAP_PUBLIC_ID = "-//ibatis.apache.org//DTD SQL Map 2.0//EN"; //$NON-NLS-1$
     
+    public static final String SQL_MAP_CONFIG_SYSTEM_ID = "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"; //$NON-NLS-1$
+
+    public static final String SQL_MAP_CONFIG_PUBLIC_ID = "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"; //$NON-NLS-1$
+    
     public static final String IBATOR_CONFIG_SYSTEM_ID = "http://ibatis.apache.org/dtd/ibator-config_1_0.dtd"; //$NON-NLS-1$
     
     public static final String IBATOR_CONFIG_PUBLIC_ID = "-//Apache Software Foundation//DTD Apache iBATIS ibator Configuration 1.0//EN"; //$NON-NLS-1$

Modified: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/util/messages/messages.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/util/messages/messages.properties?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/util/messages/messages.properties (original)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/internal/util/messages/messages.properties Wed Apr 23 16:05:17 2008
@@ -12,8 +12,10 @@
 ValidationError.11=At least one IbatorConfiguration element is required
 ValidationError.12={0} Target Package is Required for context {1}
 ValidationError.13=If "useColumnIndexes" property is set, then either both or neither query id must be set for table {0}
-ValidationError.14="searchString is required in a ColumnRenamingRule"
+ValidationError.14="searchString" is required in a ColumnRenamingRule
 ValidationError.15=Generated key type must be either "pre" or "post" if the type is specified for a generated key for table {0}
+ValidationError.16="id" is required in an IbatorContext
+ValidationError.17="type" is required in an IbatorPlugin in context {0}
 
 RuntimeError.0=configfile is a required parameter
 RuntimeError.1=configfile {0} does not exist
@@ -38,7 +40,7 @@
 
 Warning.0=There are no statements enabled for table {0}, this table will be ignored.
 Warning.1=Table {0} does not exist, this table will be ignored
-Warning.2=Existing file not overwritten, the generated Java file is saved as {0}
+Warning.2=Existing file not overwritten, the generated file is saved as {0}
 Warning.3=Column {0}, specified for override in table {1}, does not exist in the table.
 Warning.4=Column {0}, specified to be ignored in table {1}, does not exist in the table.
 Warning.5=Column {0}, specified as an identity column in table {1}, does not exist in the table.
@@ -60,7 +62,8 @@
 Warning.20=Root class {0} cannot be loaded, checking for member overrides is disabled for this class 
 Warning.21=Property {0} exists in root class {1}, but is not of type {2}.  iBATOR will generate the property. 
 Warning.22=Property {0} exists in root class {1}, but does not have a getter.  iBATOR will generate the property. 
-Warning.23=Property {0} exists in root class {1}, but does not have a setter.  iBATOR will generate the property. 
+Warning.23=Property {0} exists in root class {1}, but does not have a setter.  iBATOR will generate the property.
+Warning.24=Plugin {0} in context {1} is invalid and will be ignored. 
 
 Progress.0=Connecting to the Database
 Progress.1=Introspecting table {0}
@@ -77,22 +80,22 @@
 Progress.13=Found SQL Statement: {0}
 
 Usage.Lines=19
-Usage.0=iBATOR code generator for iBATIS.  Usage:
+Usage.0=Apache iBATIS ibator - a code generator for iBATIS.  Usage:
 Usage.1=\   java -jar ibator.jar -configfile file_name [-overwrite]
 Usage.2=\                        [-contextids ids] [-tables tableName]
 Usage.3=
 Usage.4=Where:
-Usage.5=\   -configfile: Specifies the the iBATOR XML configuration file (required)
+Usage.5=\   -configfile: Specifies the the ibator XML configuration file (required)
 Usage.6=
 Usage.7=\   -overwrite: If specified then exsting Java files will be overwritten.
-Usage.8=\               If not specified, then  iBATOR will not overwrite existing
+Usage.8=\               If not specified, then  ibator will not overwrite existing
 Usage.9=\               Java files (will save results in uniqely named files)
 Usage.10=
 Usage.11=\   -contextids: Used to specify a comma delimited list of contexts to use in
-Usage.12=\                this run of iBATOR.  If not specified, all contexts will be
+Usage.12=\                this run of ibator.  If not specified, all contexts will be
 Usage.13=\                used.
 Usage.14=
 Usage.15=\   -tables: Used to specify a comma delimited list of tables to use in this
-Usage.16=\            run of iBATOR.  If not specified, all tables will be used.  Table
+Usage.16=\            run of ibator.  If not specified, all tables will be used.  Table
 Usage.17=\            names must be fully qualified (e.g. schema.tablename).  Table names
 Usage.18=\            must exactly match the case specified in the configuration file.

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/EqualsHashCodePlugin.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/EqualsHashCodePlugin.java?rev=651096&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/EqualsHashCodePlugin.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/EqualsHashCodePlugin.java Wed Apr 23 16:05:17 2008
@@ -0,0 +1,291 @@
+/*
+ *  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.plugins;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.ibatis.ibator.api.IbatorPluginAdapter;
+import org.apache.ibatis.ibator.api.IntrospectedTable;
+import org.apache.ibatis.ibator.api.dom.OutputUtilities;
+import org.apache.ibatis.ibator.api.dom.java.FullyQualifiedJavaType;
+import org.apache.ibatis.ibator.api.dom.java.JavaVisibility;
+import org.apache.ibatis.ibator.api.dom.java.Method;
+import org.apache.ibatis.ibator.api.dom.java.Parameter;
+import org.apache.ibatis.ibator.api.dom.java.TopLevelClass;
+import org.apache.ibatis.ibator.config.IbatorContext;
+import org.apache.ibatis.ibator.internal.db.ColumnDefinition;
+import org.apache.ibatis.ibator.internal.util.JavaBeansUtil;
+
+/**
+ * This plugin adds equals() and hashCode() methods to the generated model
+ * classes. It demonstrates the process of adding methods to generated classes
+ * <p>
+ * The <tt>equals</tt> method generated by this class is correct in most
+ * cases, but will probably NOT be correct if you have specified a rootClass -
+ * because our equals method only checks the fields it knows about.
+ * <p>
+ * The <tt>hashCode</tt> method generated by this class is a very simplistic
+ * implementation.  A better implementation would rely on the HashCodeUtil
+ * from www.javapractices.com - but we do not want to introduce another
+ * dependancy in this simple plugin.
+ * 
+ * @author Jeff Butler
+ * 
+ */
+public class EqualsHashCodePlugin extends IbatorPluginAdapter {
+
+    private boolean usingJava5;
+
+    public EqualsHashCodePlugin() {
+    }
+
+    /**
+     * This plugin is always valid - no properties are required
+     */
+    public boolean validate(List<String> warnings) {
+        return true;
+    }
+    
+    @Override
+    public void setIbatorContext(IbatorContext ibatorContext) {
+        super.setIbatorContext(ibatorContext);
+        usingJava5 = "Java5".equalsIgnoreCase(ibatorContext //$NON-NLS-1$
+                .getConfiguredGeneratorSet());
+    }
+
+    @Override
+    public void modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
+            IntrospectedTable introspectedTable) {
+        List<ColumnDefinition> columns;
+        if (introspectedTable.getRules().generateRecordWithBLOBsClass()) {
+            columns = introspectedTable.getNonBLOBColumns();
+        } else {
+            columns = introspectedTable.getAllColumns();
+        }
+
+        generateEquals(topLevelClass, columns, introspectedTable);
+        generateHashCode(topLevelClass, columns, introspectedTable);
+    }
+
+    @Override
+    public void modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,
+            IntrospectedTable introspectedTable) {
+        generateEquals(topLevelClass, introspectedTable.getPrimaryKeyColumns(),
+                introspectedTable);
+        generateHashCode(topLevelClass, introspectedTable.getPrimaryKeyColumns(),
+                introspectedTable);
+    }
+
+    @Override
+    public void modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass,
+            IntrospectedTable introspectedTable) {
+        generateEquals(topLevelClass, introspectedTable.getAllColumns(),
+                introspectedTable);
+        generateHashCode(topLevelClass, introspectedTable.getAllColumns(),
+                introspectedTable);
+    }
+
+    /**
+     * Generates an <tt>equals</tt> method that does a comparison of
+     * all fields.
+     * <p>
+     * The generated <tt>equals</tt> method will be correct unless:
+     * <ul>
+     *   <li>Other fields have been added to the ibator generated classes</li>
+     *   <li>A <tt>rootClass</tt> is specified that holds state</li>
+     * </ul>
+     * 
+     * @param topLevelClass the class to which the method will be added
+     * @param columnDefinitions column definitions of this class and 
+     *   any superclass of this class
+     * @param introspectedTable the table corresponding to this class 
+     */
+    protected void generateEquals(TopLevelClass topLevelClass,
+            List<ColumnDefinition> columnDefinitions,
+            IntrospectedTable introspectedTable) {
+        Method method = new Method();
+        method.setVisibility(JavaVisibility.PUBLIC);
+        method.setReturnType(FullyQualifiedJavaType
+                .getBooleanPrimitiveInstance());
+        method.setName("equals"); //$NON-NLS-1$
+        method.addParameter(new Parameter(FullyQualifiedJavaType
+                .getObjectInstance(), "that")); //$NON-NLS-1$
+        if (usingJava5) {
+            method.addAnnotation("@Override"); //$NON-NLS-1$
+        }
+
+        ibatorContext.getCommentGenerator().addGeneralMethodComment(method,
+                introspectedTable.getTable());
+
+        method.addBodyLine("if (this == that) {"); //$NON-NLS-1$
+        method.addBodyLine("return true;"); //$NON-NLS-1$
+        method.addBodyLine("}"); //$NON-NLS-1$
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("if (!(that instanceof "); //$NON-NLS-1$
+        sb.append(topLevelClass.getType().getShortName());
+        sb.append(")) {"); //$NON-NLS-1$
+        method.addBodyLine(sb.toString());
+        method.addBodyLine("return false;"); //$NON-NLS-1$
+        method.addBodyLine("}"); //$NON-NLS-1$
+
+        sb.setLength(0);
+        sb.append(topLevelClass.getType().getShortName());
+        sb.append(" other = ("); //$NON-NLS-1$
+        sb.append(topLevelClass.getType().getShortName());
+        sb.append(") that;"); //$NON-NLS-1$
+        method.addBodyLine(sb.toString());
+
+        boolean first = true;
+        Iterator<ColumnDefinition> iter = columnDefinitions.iterator();
+        while (iter.hasNext()) {
+            ColumnDefinition columnDefinition = iter.next();
+
+            sb.setLength(0);
+
+            if (first) {
+                sb.append("return "); //$NON-NLS-1$
+                first = false;
+            } else {
+                OutputUtilities.javaIndent(sb, 1);
+                sb.append("&& "); //$NON-NLS-1$
+            }
+
+            String getterMethod = JavaBeansUtil.getGetterMethodName(
+                    columnDefinition.getJavaProperty(), columnDefinition
+                            .getResolvedJavaType().getFullyQualifiedJavaType());
+
+            if (columnDefinition.getResolvedJavaType()
+                    .getFullyQualifiedJavaType().isPrimitive()) {
+                sb.append("this."); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("() == "); //$NON-NLS-1$
+                sb.append("other."); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("()"); //$NON-NLS-1$
+            } else {
+                sb.append("this."); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("() == null ? other == null : this."); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("().equals(other."); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("())"); //$NON-NLS-1$
+                if (!iter.hasNext()) {
+                    sb.append(';');
+                }
+            }
+
+            method.addBodyLine(sb.toString());
+        }
+
+        topLevelClass.addMethod(method);
+    }
+
+    /**
+     * Generates a <tt>hashCode</tt> method that multiplies the hashCodes of
+     * all fields.
+     * <p>
+     * Note that this is a very simplistic implementation of hashCode.
+     * 
+     * @param topLevelClass the class to which the method will be added
+     * @param columnDefinitions column definitions of this class and 
+     *   any superclass of this class
+     * @param introspectedTable the table corresponding to this class 
+     */
+    protected void generateHashCode(TopLevelClass topLevelClass,
+            List<ColumnDefinition> columnDefinitions,
+            IntrospectedTable introspectedTable) {
+        Method method = new Method();
+        method.setVisibility(JavaVisibility.PUBLIC);
+        method.setReturnType(FullyQualifiedJavaType
+                .getIntInstance());
+        method.setName("hashCode"); //$NON-NLS-1$
+        if (usingJava5) {
+            method.addAnnotation("@Override"); //$NON-NLS-1$
+        }
+
+        ibatorContext.getCommentGenerator().addGeneralMethodComment(method,
+                introspectedTable.getTable());
+
+        method.addBodyLine("int hash = 23;"); //$NON-NLS-1$
+
+        StringBuffer sb = new StringBuffer();
+        boolean valueDeclared = false;
+
+        Iterator<ColumnDefinition> iter = columnDefinitions.iterator();
+        while (iter.hasNext()) {
+            ColumnDefinition columnDefinition = iter.next();
+
+
+            FullyQualifiedJavaType fqjt = columnDefinition.getResolvedJavaType()
+                .getFullyQualifiedJavaType();
+
+            String getterMethod = JavaBeansUtil.getGetterMethodName(
+                    columnDefinition.getJavaProperty(), fqjt);
+            
+            if (fqjt.isPrimitive()) {
+                boolean cast = false;
+                if ("boolean".equals(fqjt.getFullyQualifiedName())) { //$NON-NLS-1$
+                    // no adding the booleans to the hashCode computation
+                    continue;
+                } else if ("long".equals(fqjt.getFullyQualifiedName())) { //$NON-NLS-1$
+                    cast = true;
+                } else if ("double".equals(fqjt.getFullyQualifiedName())) { //$NON-NLS-1$
+                    cast = true;
+                } else if ("float".equals(fqjt.getFullyQualifiedName())) { //$NON-NLS-1$
+                    cast = true;
+                }
+                
+                sb.setLength(0);
+                if (!valueDeclared) {
+                    sb.append("int "); //$NON-NLS-1$
+                    valueDeclared = true;
+                }
+                sb.append("value = "); //$NON-NLS-1$
+                if (cast) {
+                    sb.append("(int) "); //$NON-NLS-1$
+                }
+                sb.append(getterMethod);
+                sb.append("();"); //$NON-NLS-1$
+                method.addBodyLine(sb.toString());
+                
+                method.addBodyLine("if (value != 0) {"); //$NON-NLS-1$
+                method.addBodyLine("hash *= value;"); //$NON-NLS-1$
+                method.addBodyLine("}"); //$NON-NLS-1$
+            } else {
+                sb.setLength(0);
+                sb.append("if ("); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("() != null) {"); //$NON-NLS-1$
+                method.addBodyLine(sb.toString());
+                
+                sb.setLength(0);
+                sb.append("hash *= "); //$NON-NLS-1$
+                sb.append(getterMethod);
+                sb.append("().hashCode();"); //$NON-NLS-1$
+                method.addBodyLine(sb.toString());
+
+                method.addBodyLine("}"); //$NON-NLS-1$
+            }
+        }
+
+        method.addBodyLine("return hash;"); //$NON-NLS-1$
+        
+        topLevelClass.addMethod(method);
+    }
+}

Added: ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/SqlMapConfigPlugin.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/SqlMapConfigPlugin.java?rev=651096&view=auto
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/SqlMapConfigPlugin.java (added)
+++ ibatis/trunk/java/tools/ibator/core/src/org/apache/ibatis/ibator/plugins/SqlMapConfigPlugin.java Wed Apr 23 16:05:17 2008
@@ -0,0 +1,140 @@
+/*
+ *  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.plugins;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.ibatis.ibator.api.GeneratedXmlFile;
+import org.apache.ibatis.ibator.api.IbatorPluginAdapter;
+import org.apache.ibatis.ibator.api.IntrospectedTable;
+import org.apache.ibatis.ibator.api.dom.xml.Attribute;
+import org.apache.ibatis.ibator.api.dom.xml.Document;
+import org.apache.ibatis.ibator.api.dom.xml.TextElement;
+import org.apache.ibatis.ibator.api.dom.xml.XmlElement;
+import org.apache.ibatis.ibator.internal.sqlmap.XmlConstants;
+import org.apache.ibatis.ibator.internal.util.StringUtility;
+
+/**
+ * This plugin generates an SqlMapConfig file containing sqlMap entries for
+ * SQL maps generated by ibator.  This demonstrates hooking into the ibator
+ * code generation lifecycle and generating additional XML files.
+ * <p>
+ * This plugin accepts three properties:
+ * <ul>
+ *   <li><tt>fileName</tt> (optional) the name of the generated file.
+ *       this defaults to "SqlMapConfig.xml" if not specified.</li>
+ *   <li><tt>targetPackage</tt> (required) the name of the package where the 
+ *      file should be placed.  Specified like "com.mycompany.sql".</li>
+ *   <li><tt>targetProject</tt> (required) the name of the project where the 
+ *      file should be placed.</li>
+ * </ul>
+ * 
+ * Note: targetPackage and targetProject follow the same rules as the
+ * targetPackage and targetProject values on the sqlMapGenerator
+ * configuration element.
+ * 
+ * @author Jeff Butler
+ *
+ */
+public class SqlMapConfigPlugin extends IbatorPluginAdapter {
+    
+    private List<String> sqlMapFiles;
+
+    public SqlMapConfigPlugin() {
+        sqlMapFiles = new ArrayList<String>();
+    }
+
+    public boolean validate(List<String> warnings) {
+        boolean valid = true;
+        
+        if (!StringUtility.stringHasValue(properties.getProperty("targetProject"))) { //$NON-NLS-1$
+            warnings.add("The SqlMapConfig plugin requires the targetProject property");
+            valid = false;
+        }
+        
+        if (!StringUtility.stringHasValue(properties.getProperty("targetPackage"))) { //$NON-NLS-1$
+            warnings.add("The SqlMapConfig plugin requires the targetPackage property");
+            valid = false;
+        }
+        
+        return valid;
+    }
+    
+    @Override
+    public List<GeneratedXmlFile> generateAdditionalXmlFiles() {
+        Document document = new Document(XmlConstants.SQL_MAP_CONFIG_PUBLIC_ID,
+                XmlConstants.SQL_MAP_CONFIG_SYSTEM_ID);
+        
+        XmlElement root = new XmlElement("sqlMapConfig"); //$NON-NLS-1$
+        document.setRootElement(root);
+        
+        root.addElement(new TextElement("<--"));
+        root.addElement(new TextElement(
+            "  This file is generated by Apache iBATIS ibator.")); //$NON-NLS-1$
+        root.addElement(new TextElement(
+            "  This file is the shell of an SqlMapConfig file - in many cases you will need to add")); //$NON-NLS-1$
+        root.addElement(new TextElement(
+            "    to this file before it is usable by iBATIS.")); //$NON-NLS-1$
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("  This file was generated on "); //$NON-NLS-1$
+        sb.append(new Date());
+        sb.append('.');
+        root.addElement(new TextElement(sb.toString()));
+
+        root.addElement(new TextElement("-->")); //$NON-NLS-1$
+        
+        XmlElement settings = new XmlElement("settings"); //$NON-NLS-1$
+        settings.addAttribute(new Attribute("useStatementNamespaces", "true")); //$NON-NLS-1$ //$NON-NLS-2$
+        root.addElement(settings);
+        
+        XmlElement sqlMap;
+        for (String sqlMapFile : sqlMapFiles) {
+            sqlMap = new XmlElement("sqlMap"); //$NON-NLS-1$
+            sqlMap.addAttribute(new Attribute("resource", sqlMapFile)); //$NON-NLS-1$
+            root.addElement(sqlMap);
+        }
+        
+        GeneratedXmlFile gxf = new GeneratedXmlFile(document,
+                properties.getProperty("fileName", "SqlMapConfig.xml"), //$NON-NLS-1$ //$NON-NLS-2$
+                properties.getProperty("targetPackage"), //$NON-NLS-1$
+                properties.getProperty("targetProject"), //$NON-NLS-1$
+                false);
+        
+        List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>(1);
+        answer.add(gxf);
+        
+        return answer;
+    }
+
+    /*
+     * This method collects the name of every SqlMap file generated
+     * by ibator in this context.
+     */
+    @Override
+    public void sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(sqlMap.getTargetPackage());
+        sb.append('.');
+        String temp = sb.toString();
+        sb.setLength(0);
+        sb.append(temp.replace('.', '/'));
+        sb.append(sqlMap.getFileName());
+        sqlMapFiles.add(sb.toString());
+    }
+}

Modified: ibatis/trunk/java/tools/ibator/core/testJava2/ibatortest/java2/ibatorConfig.xml
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/testJava2/ibatortest/java2/ibatorConfig.xml?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/testJava2/ibatortest/java2/ibatorConfig.xml (original)
+++ ibatis/trunk/java/tools/ibator/core/testJava2/ibatortest/java2/ibatorConfig.xml Wed Apr 23 16:05:17 2008
@@ -5,7 +5,13 @@
 
 <ibatorConfiguration>
   
-  <ibatorContext generatorSet="Java2" defaultModelType="flat">
+  <ibatorContext id="FlatJava2" generatorSet="Java2" defaultModelType="flat">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.SqlMapConfigPlugin" >
+      <property name="targetPackage" value="ibatortest.java2.generated.flat" />
+      <property name="targetProject" value="${generated.source.dir.java2}" />
+    </ibatorPlugin>
+    
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -42,7 +48,9 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java2" defaultModelType="hierarchical">
+  <ibatorContext id="HierarchicalJava2" generatorSet="Java2" defaultModelType="hierarchical">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -79,7 +87,9 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java2" defaultModelType="conditional">
+  <ibatorContext id="ConditionalJava2" generatorSet="Java2" defaultModelType="conditional">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -117,6 +127,8 @@
   </ibatorContext>
 
   <ibatorContext id="miscellaneousTests" generatorSet="Java2">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />

Modified: ibatis/trunk/java/tools/ibator/core/testJava5/ibatortest/ibatorConfig.xml
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/tools/ibator/core/testJava5/ibatortest/ibatorConfig.xml?rev=651096&r1=651095&r2=651096&view=diff
==============================================================================
--- ibatis/trunk/java/tools/ibator/core/testJava5/ibatortest/ibatorConfig.xml (original)
+++ ibatis/trunk/java/tools/ibator/core/testJava5/ibatortest/ibatorConfig.xml Wed Apr 23 16:05:17 2008
@@ -6,9 +6,15 @@
 <ibatorConfiguration>
   <classPathEntry location="${generated.bin.dir.java5}"/>
   
-  <ibatorContext generatorSet="Java5" defaultModelType="flat">
+  <ibatorContext id="FlatJava5" generatorSet="Java5" defaultModelType="flat">
     <property name="suppressTypeWarnings" value="true" /> <!-- should be ignored -->
     
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.SqlMapConfigPlugin" >
+      <property name="targetPackage" value="ibatortest.generated.flat" />
+      <property name="targetProject" value="${generated.source.dir.java5}" />
+    </ibatorPlugin>
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -45,9 +51,11 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java2" defaultModelType="flat">
+  <ibatorContext id="FlatJava2" generatorSet="Java2" defaultModelType="flat">
     <property name="suppressTypeWarnings" value="true" />
     
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -84,7 +92,9 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java5" defaultModelType="hierarchical">
+  <ibatorContext id="HierarchicalJava5" generatorSet="Java5" defaultModelType="hierarchical">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -121,9 +131,11 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java2" defaultModelType="hierarchical">
+  <ibatorContext id="HierarchicalJava2" generatorSet="Java2" defaultModelType="hierarchical">
     <property name="suppressTypeWarnings" value="true" />
     
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -160,7 +172,9 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java5" defaultModelType="conditional">
+  <ibatorContext id="ConditionalJava5" generatorSet="Java5" defaultModelType="conditional">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -197,9 +211,11 @@
     </table>
   </ibatorContext>
 
-  <ibatorContext generatorSet="Java2" defaultModelType="conditional">
+  <ibatorContext id="ConditionalJava2" generatorSet="Java2" defaultModelType="conditional">
     <property name="suppressTypeWarnings" value="true" />
     
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <jdbcConnection driverClass="org.hsqldb.jdbcDriver"
         connectionURL="jdbc:hsqldb:mem:aname"
         userId="sa" />
@@ -237,6 +253,8 @@
   </ibatorContext>
 
   <ibatorContext id="miscellaneousTests" generatorSet="Java5">
+    <ibatorPlugin type="org.apache.ibatis.ibator.plugins.EqualsHashCodePlugin" />
+
     <commentGenerator>
       <property name="suppressDate" value="true"/>
     </commentGenerator>