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 2007/03/08 00:01:43 UTC

svn commit: r515831 - in /ibatis/trunk/java/mapper/mapper2/tools/abator/core: build/ doc/ htmldoc/ src/org/apache/ibatis/abator/ant/ src/org/apache/ibatis/abator/api/ src/org/apache/ibatis/abator/config/ src/org/apache/ibatis/abator/config/xml/ src/org...

Author: jgbutler
Date: Wed Mar  7 15:01:42 2007
New Revision: 515831

URL: http://svn.apache.org/viewvc?view=rev&rev=515831
Log:
Abator: Fix some issues with the XML merge function, and enhance the API for running only selected contexts

Added:
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/DomWriter.java
Modified:
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/ant/SqlScriptRunnerTask.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/api/Abator.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorConfiguration.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorContext.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/ColumnOverride.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/IgnoredColumn.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/AbatorConfigurationParser.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/abator-config_1_0.dtd
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/XmlFileMergerJaxp.java
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties Wed Mar  7 15:01:42 2007
@@ -1,4 +1,4 @@
 #Abator build version info
-#Fri Feb 23 17:15:14 CST 2007
+#Wed Mar 07 13:22:36 CST 2007
 version=1.0.1
-buildNum=343
+buildNum=345

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/doc/ReleaseNotes.txt Wed Mar  7 15:01:42 2007
@@ -4,6 +4,7 @@
 1. corner case where the new "by example" methods fail if a criteria
    class has been added to the list, but there are no criteria set
 2. trimStrings on JavaModelGenerator not working
+3. Fix the XML file merger so that entities are preserved
 
 Enhancements - 
 1. IBATIS-348 - escape column names with $ or #, and ignore special characters
@@ -23,6 +24,8 @@
    where column names differ only in case.  This may also improve performance.
 8. Added the ability to work with delimited names in database tables or
    columns.
+9. API change to allow generating with selected contexts rather than
+   the entire config file.
 
 -------------------------------------------------------------------------------
 Version 1.0.0:

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html Wed Mar  7 15:01:42 2007
@@ -13,6 +13,7 @@
 <h3>Miscellaneous Changes</h3>
 <ul>
   <li>Fixed a bug that caused the "trimStrings" property to fail</li>
+  <li>Fixed the XML file merger so that internal entities are preserved</li>
   <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:

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/ant/SqlScriptRunnerTask.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/ant/SqlScriptRunnerTask.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/ant/SqlScriptRunnerTask.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/ant/SqlScriptRunnerTask.java Wed Mar  7 15:01:42 2007
@@ -25,6 +25,7 @@
 import java.sql.Statement;
 
 import org.apache.ibatis.abator.internal.util.StringUtility;
+import org.apache.ibatis.abator.internal.util.messages.Messages;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
@@ -143,7 +144,7 @@
         String line;
         
         while ((line = br.readLine()) != null) {
-            if (line.startsWith("--")) {
+            if (line.startsWith("--")) { //$NON-NLS-1$
                 continue;
             }
             
@@ -151,7 +152,7 @@
                 continue;
             }
             
-            if (line.endsWith(";")) {
+            if (line.endsWith(";")) { //$NON-NLS-1$
                 sb.append(line.substring(0, line.length() - 1));
                 break;
             } else {
@@ -162,7 +163,7 @@
         String s = sb.toString().trim();
 
         if (s.length() > 0) {
-            log("Found Statement: " + s, Project.MSG_DEBUG);
+            log(Messages.getString("Progress.13", s), Project.MSG_DEBUG); //$NON-NLS-1$
         }
         
         return s.length() > 0 ? s : null;

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/api/Abator.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/api/Abator.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/api/Abator.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/api/Abator.java Wed Mar  7 15:01:42 2007
@@ -78,9 +78,11 @@
      *            generation will continue. Abator 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 Abator(AbatorConfiguration abatorConfiguration,
-            ShellCallback shellCallback, List warnings) {
+            ShellCallback shellCallback, List warnings) throws InvalidConfigurationException {
         super();
         if (abatorConfiguration == null) {
             throw new IllegalArgumentException(Messages.getString("RuntimeError.2")); //$NON-NLS-1$
@@ -102,23 +104,43 @@
         generatedJavaFiles = new ArrayList();
         generatedXmlFiles = new ArrayList();
         projects = new HashSet();
+        
+        this.abatorConfiguration.validate();
     }
 
     /**
      * This is the main method for generating code.  This method is long running, but
-     * progress can be provided and the method can be calncelled through the ProgressCallbac
+     * 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);
+    }
+    
+    /**
+     * 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 list 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)
-            throws InvalidConfigurationException, SQLException, IOException,
-            InterruptedException {
+    public void generate(ProgressCallback callback, List contextIds)
+            throws SQLException, IOException, InterruptedException {
 
         if (callback == null) {
             callback = new NullProgressCallback();
@@ -126,11 +148,25 @@
 
         generatedJavaFiles.clear();
         generatedXmlFiles.clear();
+        
+        // calculate the contexts to run
+        List contextsToRun;
+        if (contextIds == null || contextIds.size() == 0) {
+            contextsToRun = abatorConfiguration.getAbatorContexts();
+        } else {
+            contextsToRun = new ArrayList();
+            Iterator iter = contextIds.iterator();
+            while (iter.hasNext()) {
+                AbatorContext abatorContext = abatorConfiguration.getAbatorContext((String) iter.next());
+                if (abatorContext != null) {
+                    contextsToRun.add(abatorContext);
+                }
+            }
+        }
 
         int totalSteps = 0;
-        totalSteps++; // validation
 
-        Iterator iter = abatorConfiguration.getAbatorContexts().iterator();
+        Iterator iter = contextsToRun.iterator();
         while (iter.hasNext()) {
             AbatorContext abatorContext = (AbatorContext) iter.next();
 
@@ -139,10 +175,7 @@
 
         callback.setNumberOfSubTasks(totalSteps);
 
-        callback.startSubTask(Messages.getString("Progress.2")); //$NON-NLS-1$
-        abatorConfiguration.validate();
-
-        iter = abatorConfiguration.getAbatorContexts().iterator();
+        iter = contextsToRun.iterator();
         while (iter.hasNext()) {
             AbatorContext abatorContext = (AbatorContext) iter.next();
 

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorConfiguration.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorConfiguration.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorConfiguration.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorConfiguration.java Wed Mar  7 15:01:42 2007
@@ -71,6 +71,18 @@
         abatorContexts.add(abatorContext);
     }
     
+    public AbatorContext getAbatorContext(String id) {
+        Iterator iter = abatorContexts.iterator();
+        while (iter.hasNext()) {
+            AbatorContext abatorContext = (AbatorContext) iter.next();
+            if (id.equals(abatorContext.getId())) {
+                return abatorContext;
+            }
+        }
+        
+        return null;
+    }
+    
     /**
      * Builds an XML representation of this configuration.  This
      * can be used to persist a programtically generated

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorContext.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorContext.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorContext.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/AbatorContext.java Wed Mar  7 15:01:42 2007
@@ -30,7 +30,6 @@
 import org.apache.ibatis.abator.api.SqlMapGenerator;
 import org.apache.ibatis.abator.api.dom.xml.Attribute;
 import org.apache.ibatis.abator.api.dom.xml.XmlElement;
-import org.apache.ibatis.abator.exception.InvalidConfigurationException;
 import org.apache.ibatis.abator.internal.AbatorObjectFactory;
 import org.apache.ibatis.abator.internal.NullProgressCallback;
 import org.apache.ibatis.abator.internal.db.ConnectionFactory;
@@ -245,15 +244,13 @@
 	 * @param warnings any warning generated from this method will be added to the List.  Warnings
 	 *                   are always Strings.
 	 * 
-	 * @throws InvalidConfigurationException if some configuration error prevents
-	 *                                       continuation
 	 * @throws SQLException if some error arrises while introspecting the specified
 	 *                      database tables.
 	 * 
 	 * @throws InterruptedException if the progress callback reports a cancel
 	 */
-	public void generateFiles(ProgressCallback callback, List generatedJavaFiles, List generatedXmlFiles, List warnings) throws InvalidConfigurationException,
-			SQLException, InterruptedException {
+	public void generateFiles(ProgressCallback callback, List generatedJavaFiles, List generatedXmlFiles, List warnings)
+            throws SQLException, InterruptedException {
 	    
 	    if (callback == null) {
 	        callback = new NullProgressCallback();
@@ -314,8 +311,20 @@
 	    int steps = 0;
 	    
 	    steps++;  // connect to database
+        
+        // for each table:
+        //
+        // 1. Introspect
+        // 2. Generate Example
+        // 3. Generate Primary Key
+        // 4. Generate Record
+        // 5. Generate Record with BLOBs
+        // 6. Generate SQL Map
+        // 7. Generate DAO Interface
+        // 8. Generate DAO Implementation
+
 	    steps += tableConfigurations.size() * 8;
-	    
+        
 	    return steps;
 	}
 

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/ColumnOverride.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/ColumnOverride.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/ColumnOverride.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/ColumnOverride.java Wed Mar  7 15:01:42 2007
@@ -105,7 +105,7 @@
         }
         
         if (StringUtility.stringHasValue(configuredDelimitedColumnName)) {
-            xmlElement.addAttribute(new Attribute("delimitedColumnName", configuredDelimitedColumnName));
+            xmlElement.addAttribute(new Attribute("delimitedColumnName", configuredDelimitedColumnName)); //$NON-NLS-1$
         }
         
         return xmlElement;
@@ -118,6 +118,6 @@
     public void setColumnNameDelimited(boolean isColumnNameDelimited) {
         this.isColumnNameDelimited = isColumnNameDelimited;
         
-        configuredDelimitedColumnName = isColumnNameDelimited ? "true" : "false";
+        configuredDelimitedColumnName = isColumnNameDelimited ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
     }
 }

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/IgnoredColumn.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/IgnoredColumn.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/IgnoredColumn.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/IgnoredColumn.java Wed Mar  7 15:01:42 2007
@@ -51,7 +51,7 @@
 
     public void setColumnNameDelimited(boolean isColumnNameDelimited) {
         this.isColumnNameDelimited = isColumnNameDelimited;
-        configuredDelimitedColumnName = isColumnNameDelimited ? "true" : "false";
+        configuredDelimitedColumnName = isColumnNameDelimited ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     public boolean equals(Object obj) {
@@ -71,7 +71,7 @@
         xmlElement.addAttribute(new Attribute("column", columnName)); //$NON-NLS-1$
         
         if (StringUtility.stringHasValue(configuredDelimitedColumnName)) {
-            xmlElement.addAttribute(new Attribute("delimitedColumnName", configuredDelimitedColumnName));
+            xmlElement.addAttribute(new Attribute("delimitedColumnName", configuredDelimitedColumnName)); //$NON-NLS-1$
         }
         
         return xmlElement;

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/AbatorConfigurationParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/AbatorConfigurationParser.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/AbatorConfigurationParser.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/AbatorConfigurationParser.java Wed Mar  7 15:01:42 2007
@@ -453,7 +453,7 @@
         }
 
         if (StringUtility.stringHasValue(delimitedColumnName)) {
-            co.setColumnNameDelimited("true".equalsIgnoreCase(delimitedColumnName));
+            co.setColumnNameDelimited("true".equalsIgnoreCase(delimitedColumnName)); //$NON-NLS-1$
         }
         
         tc.addColumnOverride(co);
@@ -479,7 +479,7 @@
         IgnoredColumn ic = new IgnoredColumn(column);
         
         if (StringUtility.stringHasValue(delimitedColumnName)) {
-            ic.setColumnNameDelimited("true".equalsIgnoreCase(delimitedColumnName));
+            ic.setColumnNameDelimited("true".equalsIgnoreCase(delimitedColumnName)); //$NON-NLS-1$
         }
 
         tc.addIgnoredColumn(ic);

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/abator-config_1_0.dtd
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/abator-config_1_0.dtd?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/abator-config_1_0.dtd (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/config/xml/abator-config_1_0.dtd Wed Mar  7 15:01:42 2007
@@ -52,7 +52,7 @@
 -->
 <!ELEMENT abatorContext (property*, jdbcConnection, javaTypeResolver?, javaModelGenerator,
                         sqlMapGenerator, daoGenerator?, table+)>
-<!ATTLIST abatorContext id CDATA #IMPLIED
+<!ATTLIST abatorContext id ID #IMPLIED
   defaultModelType CDATA #IMPLIED
   generatorSet CDATA #IMPLIED>
 

Added: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/DomWriter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/DomWriter.java?view=auto&rev=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/DomWriter.java (added)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/DomWriter.java Wed Mar  7 15:01:42 2007
@@ -0,0 +1,339 @@
+/*
+ *  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.abator.internal;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+
+import org.apache.ibatis.abator.exception.ShellException;
+import org.apache.ibatis.abator.internal.util.messages.Messages;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+/**
+ * This class is used to generate a String representation of an XML document. It
+ * is very much based on the class dom.Writer from the Apache Xerces examples,
+ * but I've simplified and updated it for use with Abator.
+ * 
+ * @author Andy Clark, IBM (Original work)
+ * @author Jeff Butler (derivation)
+ */
+public class DomWriter {
+    protected PrintWriter printWriter;
+
+    protected boolean isXML11;
+
+    public DomWriter() {
+        super();
+    }
+    
+    public synchronized String toString(Document document) throws ShellException {
+        StringWriter sw = new StringWriter();
+        printWriter = new PrintWriter(sw);
+        write(document);
+        String s = sw.toString();
+        return s;
+    }
+
+    /** Returns a sorted list of attributes. */
+    protected Attr[] sortAttributes(NamedNodeMap attrs) {
+
+        int len = (attrs != null) ? attrs.getLength() : 0;
+        Attr array[] = new Attr[len];
+        for (int i = 0; i < len; i++) {
+            array[i] = (Attr) attrs.item(i);
+        }
+        for (int i = 0; i < len - 1; i++) {
+            String name = array[i].getNodeName();
+            int index = i;
+            for (int j = i + 1; j < len; j++) {
+                String curName = array[j].getNodeName();
+                if (curName.compareTo(name) < 0) {
+                    name = curName;
+                    index = j;
+                }
+            }
+            if (index != i) {
+                Attr temp = array[i];
+                array[i] = array[index];
+                array[index] = temp;
+            }
+        }
+
+        return array;
+
+    }
+
+    /** Normalizes and prints the given string. */
+    protected void normalizeAndPrint(String s, boolean isAttValue) {
+
+        int len = (s != null) ? s.length() : 0;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            normalizeAndPrint(c, isAttValue);
+        }
+
+    }
+
+    /** Normalizes and print the given character. */
+    protected void normalizeAndPrint(char c, boolean isAttValue) {
+
+        switch (c) {
+        case '<': {
+            printWriter.print("&lt;"); //$NON-NLS-1$
+            break;
+        }
+        case '>': {
+            printWriter.print("&gt;"); //$NON-NLS-1$
+            break;
+        }
+        case '&': {
+            printWriter.print("&amp;"); //$NON-NLS-1$
+            break;
+        }
+        case '"': {
+            // A '"' that appears in character data
+            // does not need to be escaped.
+            if (isAttValue) {
+                printWriter.print("&quot;"); //$NON-NLS-1$
+            } else {
+                printWriter.print('"');
+            }
+            break;
+        }
+        case '\r': {
+            // If CR is part of the document's content, it
+            // must not be printed as a literal otherwise
+            // it would be normalized to LF when the document
+            // is reparsed.
+            printWriter.print("&#xD;"); //$NON-NLS-1$
+            break;
+        }
+        default: {
+            // In XML 1.1, control chars in the ranges [#x1-#x1F, #x7F-#x9F]
+            // must be escaped.
+            //
+            // Escape space characters that would be normalized to #x20 in
+            // attribute values
+            // when the document is reparsed.
+            //
+            // Escape NEL (0x85) and LSEP (0x2028) that appear in content
+            // if the document is XML 1.1, since they would be normalized to LF
+            // when the document is reparsed.
+            if (isXML11
+                    && ((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A)
+                            || (c >= 0x7F && c <= 0x9F) || c == 0x2028)
+                    || isAttValue && (c == 0x09 || c == 0x0A)) {
+                printWriter.print("&#x"); //$NON-NLS-1$
+                printWriter.print(Integer.toHexString(c).toUpperCase());
+                printWriter.print(';');
+            } else {
+                printWriter.print(c);
+            }
+        }
+        }
+    }
+
+    /** Extracts the XML version from the Document. */
+    protected String getVersion(Document document) {
+        if (document == null) {
+            return null;
+        }
+        String version = null;
+        Method getXMLVersion = null;
+        try {
+            getXMLVersion = document.getClass().getMethod("getXmlVersion", //$NON-NLS-1$
+                    new Class[] {});
+            // If Document class implements DOM L3, this method will exist.
+            if (getXMLVersion != null) {
+                version = (String) getXMLVersion.invoke(document,
+                        (Object[]) null);
+            }
+        } catch (Exception e) {
+            // Either this locator object doesn't have
+            // this method, or we're on an old JDK.
+        }
+        return version;
+    }
+
+    protected void writeAnyNode(Node node) throws ShellException {
+        // is there anything to do?
+        if (node == null) {
+            return;
+        }
+
+        short type = node.getNodeType();
+        switch (type) {
+        case Node.DOCUMENT_NODE:
+            write((Document) node);
+            break;
+
+        case Node.DOCUMENT_TYPE_NODE:
+            write((DocumentType) node);
+            break;
+
+        case Node.ELEMENT_NODE:
+            write((Element) node);
+            break;
+
+        case Node.ENTITY_REFERENCE_NODE:
+            write((EntityReference) node);
+            break;
+
+        case Node.CDATA_SECTION_NODE:
+            write((CDATASection) node);
+            break;
+
+        case Node.TEXT_NODE:
+            write((Text) node);
+            break;
+
+        case Node.PROCESSING_INSTRUCTION_NODE:
+            write((ProcessingInstruction) node);
+            break;
+
+        case Node.COMMENT_NODE:
+            write((Comment) node);
+            break;
+            
+        default:
+            throw new ShellException(Messages.getString("RuntimeError.18", Short.toString(type))); //$NON-NLS-1$
+        }
+    }
+    
+    protected void write(Document node) throws ShellException {
+        isXML11 = "1.1".equals(getVersion(node)); //$NON-NLS-1$
+        if (isXML11) {
+            printWriter.println("<?xml version=\"1.1\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+        } else {
+            printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+        }
+        printWriter.flush();
+        write(node.getDoctype());
+        write(node.getDocumentElement());
+    }
+
+    protected void write(DocumentType node) throws ShellException {
+        printWriter.print("<!DOCTYPE "); //$NON-NLS-1$
+        printWriter.print(node.getName());
+        String publicId = node.getPublicId();
+        String systemId = node.getSystemId();
+        if (publicId != null) {
+            printWriter.print(" PUBLIC \""); //$NON-NLS-1$
+            printWriter.print(publicId);
+            printWriter.print("\" \""); //$NON-NLS-1$
+            printWriter.print(systemId);
+            printWriter.print('\"');
+        } else if (systemId != null) {
+            printWriter.print(" SYSTEM \""); //$NON-NLS-1$
+            printWriter.print(systemId);
+            printWriter.print('"');
+        }
+        
+        String internalSubset = node.getInternalSubset();
+        if (internalSubset != null) {
+            printWriter.println(" ["); //$NON-NLS-1$
+            printWriter.print(internalSubset);
+            printWriter.print(']');
+        }
+        printWriter.println('>');
+    }
+
+    protected void write(Element node) throws ShellException {
+        printWriter.print('<');
+        printWriter.print(node.getNodeName());
+        Attr attrs[] = sortAttributes(node.getAttributes());
+        for (int i = 0; i < attrs.length; i++) {
+            Attr attr = attrs[i];
+            printWriter.print(' ');
+            printWriter.print(attr.getNodeName());
+            printWriter.print("=\""); //$NON-NLS-1$
+            normalizeAndPrint(attr.getNodeValue(), true);
+            printWriter.print('"');
+        }
+        
+        if (node.getChildNodes().getLength() == 0) {
+            printWriter.print(" />"); //$NON-NLS-1$
+            printWriter.flush();
+        } else {
+            printWriter.print('>');
+            printWriter.flush();
+
+            Node child = node.getFirstChild();
+            while (child != null) {
+                writeAnyNode(child);
+                child = child.getNextSibling();
+            }
+
+            printWriter.print("</"); //$NON-NLS-1$
+            printWriter.print(node.getNodeName());
+            printWriter.print('>');
+            printWriter.flush();
+        }
+    }
+
+    protected void write(EntityReference node) {
+        printWriter.print('&');
+        printWriter.print(node.getNodeName());
+        printWriter.print(';');
+        printWriter.flush();
+    }
+
+    protected void write(CDATASection node) {
+        printWriter.print("<![CDATA["); //$NON-NLS-1$
+        printWriter.print(node.getNodeValue());
+        printWriter.print("]]>"); //$NON-NLS-1$
+        printWriter.flush();
+    }
+
+    protected void write(Text node) {
+        normalizeAndPrint(node.getNodeValue(), false);
+        printWriter.flush();
+    }
+
+    protected void write(ProcessingInstruction node) {
+        printWriter.print("<?"); //$NON-NLS-1$
+        printWriter.print(node.getNodeName());
+        String data = node.getNodeValue();
+        if (data != null && data.length() > 0) {
+            printWriter.print(' ');
+            printWriter.print(data);
+        }
+        printWriter.print("?>"); //$NON-NLS-1$
+        printWriter.flush();
+    }
+
+    protected void write(Comment node) {
+        printWriter.print("<!--"); //$NON-NLS-1$
+        String comment = node.getNodeValue();
+        if (comment != null && comment.length() > 0) {
+            printWriter.print(comment);
+        }
+        printWriter.print("-->"); //$NON-NLS-1$
+        printWriter.flush();
+    }
+}

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/XmlFileMergerJaxp.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/XmlFileMergerJaxp.java?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/XmlFileMergerJaxp.java (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/XmlFileMergerJaxp.java Wed Mar  7 15:01:42 2007
@@ -15,7 +15,6 @@
  */
 package org.apache.ibatis.abator.internal;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
@@ -25,16 +24,9 @@
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 
 import org.apache.ibatis.abator.api.GeneratedXmlFile;
 import org.apache.ibatis.abator.exception.ShellException;
-import org.apache.ibatis.abator.internal.sqlmap.XmlConstants;
 import org.apache.ibatis.abator.internal.util.messages.Messages;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentType;
@@ -68,7 +60,7 @@
     }
 
     /**
-     * Utility class - no instances allowed  
+     * Utility class - no instances allowed
      */
     private XmlFileMergerJaxp() {
         super();
@@ -79,11 +71,13 @@
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory
                     .newInstance();
+            factory.setExpandEntityReferences(false);
             DocumentBuilder builder = factory.newDocumentBuilder();
             builder.setEntityResolver(new NullEntityResolver());
 
             Document existingDocument = builder.parse(existingFile);
-            StringReader sr = new StringReader(generatedXmlFile.getFormattedContent());
+            StringReader sr = new StringReader(generatedXmlFile
+                    .getFormattedContent());
             Document newDocument = builder.parse(new InputSource(sr));
 
             DocumentType newDocType = newDocument.getDoctype();
@@ -110,31 +104,11 @@
                 Node node = children.item(i);
                 if (isAnAbatorNode(node)) {
                     nodesToDelete.add(node);
-                }
-                
-                short nodeType = node.getNodeType();
-                if (nodeType == Element.TEXT_NODE) {
-                    // remove any nodes that are only white space
-                    // if the next node is an Abator node, or if this
-                    // is the last node.
-                    // this ensures that we don't end up with
-                    // lots of blank lines at the end of a merged file
-                    Text tn = (Text) node;
-                    String text = tn.getData();
-                    
-                    if (text.trim().length() == 0) {
-                        // node is just whitespace. if next node is an Abator
-                        //node, then remove the node.  Or if this is the last node
-                        // then delete the node
-                        if (i == length - 1) {
-                            nodesToDelete.add(tn);
-                        } else if (isAnAbatorNode(children.item(i + 1))) {
-                            nodesToDelete.add(tn);
-                        }
-                    }
+                } else if (isWhiteSpace(node) && isAnAbatorNode(children.item(i + 1))) {
+                    nodesToDelete.add(node);
                 }
             }
-            
+
             Iterator iter = nodesToDelete.iterator();
             while (iter.hasNext()) {
                 existingRootElement.removeChild((Node) iter.next());
@@ -148,15 +122,11 @@
                 Node node = children.item(i);
                 // don't add the last node if it is only white space
                 if (i == length - 1) {
-                    // last node - only add if it isn't whitespace
-                    if (node.getNodeType() == Node.TEXT_NODE) {
-                        Text tn = (Text) node;
-                        if (tn.getData().trim().length() == 0) {
-                            break;
-                        }
+                    if (isWhiteSpace(node)) {
+                        break;
                     }
                 }
-                
+
                 Node newNode = existingDocument.importNode(node, true);
                 if (firstChild == null) {
                     existingRootElement.appendChild(newNode);
@@ -169,39 +139,40 @@
             return prettyPrint(existingDocument);
         } catch (Exception e) {
             throw new ShellException(Messages.getString("Warning.13", //$NON-NLS-1$
-                existingFile.getName()), e);
+                    existingFile.getName()), e);
         }
     }
 
-    private static String prettyPrint(Document document) throws TransformerException {
-        TransformerFactory factory = TransformerFactory.newInstance();
-
-        Transformer transformer = factory.newTransformer();
-        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); //$NON-NLS-1$
-        transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
-        transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
-        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
-        transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, XmlConstants.SQL_MAP_PUBLIC_ID);
-        transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, XmlConstants.SQL_MAP_SYSTEM_ID);
-
-        ByteArrayOutputStream bas = new ByteArrayOutputStream();
-
-        transformer.transform(new DOMSource(document), new StreamResult(bas));
-
-        return bas.toString();
+    private static String prettyPrint(Document document) throws ShellException {
+         DomWriter dw = new DomWriter();
+         String s = dw.toString(document);
+         return s;
     }
-    
+
     private static boolean isAnAbatorNode(Node node) {
         boolean rc = false;
-        
-        if (node.getNodeType() == Node.ELEMENT_NODE) {
+
+        if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
             Element element = (Element) node;
             String id = element.getAttribute("id"); //$NON-NLS-1$
             if (id != null && id.startsWith("abatorgenerated_")) { //$NON-NLS-1$
                 rc = true;
             }
         }
-        
+
+        return rc;
+    }
+
+    private static boolean isWhiteSpace(Node node) {
+        boolean rc = false;
+
+        if (node != null && node.getNodeType() == Node.TEXT_NODE) {
+            Text tn = (Text) node;
+            if (tn.getData().trim().length() == 0) {
+                rc = true;
+            }
+        }
+
         return rc;
     }
 }

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties?view=diff&rev=515831&r1=515830&r2=515831
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties (original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/util/messages/messages.properties Wed Mar  7 15:01:42 2007
@@ -30,6 +30,7 @@
 RuntimeError.15=<properties> resource {0} does not exist
 RuntimeError.16=Cannot load properties from <properties> resource {0}
 RuntimeError.17=Cannot load properties from <properties> url {0}
+RuntimeError.18=Unsupported XML Node Type {0} in XML File Merger
 
 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
@@ -55,7 +56,6 @@
 
 Progress.0=Connecting to the Database
 Progress.1=Introspecting table {0}
-Progress.2=Validating Configuration
 Progress.3=XML Parser Errors occured:
 Progress.4=Abator finshed successfully.
 Progress.5=Abator finshed successfully, there were warninigs.
@@ -66,6 +66,7 @@
 Progress.10=Generating DAO Implementation for table {0}
 Progress.11=Generating DAO Interface for table {0}
 Progress.12=Generating SQL Map for table {0}
+Progress.13=Found SQL Statement: {0}
 
 Usage.0=Abator code generator for iBATIS.  Usage:
 Usage.1=\   java -jar abator.jar configfile overwrite