You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2005/08/12 17:23:08 UTC

svn commit: r232310 [89/92] - in /beehive/trunk/controls/test: common/ infra/gtlf/ infra/gtlf/xsl/ infra/mantis/ infra/tch/ infra/tch/messages/ infra/tch/runtime/ infra/tch/schema/ perf/ perf/bin/ perf/cases/ perf/ctlsrc/org/apache/beehive/controls/per...

Modified: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/PrintWriterXMLWriter.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/PrintWriterXMLWriter.java?rev=232310&r1=232309&r2=232310&view=diff
==============================================================================
--- beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/PrintWriterXMLWriter.java (original)
+++ beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/PrintWriterXMLWriter.java Fri Aug 12 08:12:28 2005
@@ -1,486 +1,486 @@
-package org.apache.beehive.test.tools.tch.util.xml;
-
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.apache.beehive.test.tools.tch.util.Stack;
-
-/**
- * XMLWriter takes care of writing well-formatted 
- * xml. 
- * 
- * The most important methods are:
- * 
- * addElement(String name)
- * addAttribue(String name, String value)
- * closeElement()
- * 
- * setPrintWriter(PrintWriter in)
- * 
- * @version 1.0, April 27, 2002
- * 
- * Revised on June 21, 2003.
- *
- */
-public class PrintWriterXMLWriter implements XMLWriter
-{
-  protected final static String sep = System.getProperty("line.separator");
-  private final static int DEFAULT_INDENT = 2;
-  private final static int DEFAULT_MAX_ATTRS_ON_SAME_LINE = 2;
-  
-  // if enabled, escapes text in text/cadata sections
-  private boolean escapeText = true;
-
-  private boolean hasElements = false;
-  private boolean incompleteOpenTag = false;
-  private boolean hasAttributes = false;
-  private boolean closeElementOnNewLine = false;
-  private Stack elementStack = new Stack();
-  private PrintWriterHolder pw = new PrintWriterHolder(System.out);
-  private int indent = DEFAULT_INDENT;
-  private int maxAttrsOnSameLine = DEFAULT_MAX_ATTRS_ON_SAME_LINE;
-
-  public PrintWriterXMLWriter()
-  {
-    this(DEFAULT_INDENT);
-  }
-
-  public PrintWriterXMLWriter(int inIndent)
-  {
-    this(inIndent, DEFAULT_MAX_ATTRS_ON_SAME_LINE);
-  }
-
-  public PrintWriterXMLWriter(int inIndent, int inMaxAttrsOnSameLine)
-  {
-    indent = inIndent;
-    maxAttrsOnSameLine = inMaxAttrsOnSameLine;
-  }
-  
-  public void setEscape(boolean in)
-  {
-    escapeText = in;
-  }
-
-  /**
-   * Set PrintWriter to write to. By default, writes to 
-   * System.out
-   */
-  public void setPrintWriter(PrintWriter in)
-  {
-    pw.setPrintWriter(in);
-  }
-
-  /**
-   * Writes DOCTYPE, publicID, privateID. Can only be called before adding 
-   * any elements.
-   * @param publicID
-   * @param privateID
-   */
-  public void startDocument(
-    String doctypeName,
-    String publicID,
-    String systemID)
-  {
-    if (hasElements)
-      throw new MalformedXMLRuntimeException("Cannot init document after elements have been added");
-
-    StringBuffer dtdString = new StringBuffer();
-    dtdString.append("<!DOCTYPE ").append(doctypeName);
-    if (publicID != null)
-      dtdString.append(" PUBLIC \"").append(publicID).append("\"");
-
-    if (systemID != null)
-      dtdString.append(" \"").append(systemID).append("\"");
-    dtdString.append(">" + sep);
-
-    writeGeneric(dtdString.toString());
-  }
-
-  /**
-   * Adds comment 
-   * 
-   * @param comment
-   */
-  public void addComment(String comment)
-  {
-    finishIncompleteTag();
-    writeGeneric(sep + getIndent() + "<!--" + comment + "-->");
-  }
-
-  /**
-   * Adds attribute (name and value) to current XML element.
-   * 
-   * @param name
-   * @param value
-   */
-  public void addAttribute(String name, String value)
-  {
-    if (!incompleteOpenTag)
-    {
-      throw new MalformedXMLRuntimeException("Illegal call to addAttribute");
-    }
-    hasAttributes = true;
-    if (closeElementOnNewLine)
-      pw.print(sep + getIndent());
-    else
-      pw.print(" ");
-    pw.print(name + "=\"" + XMLUtil.escape(value) + "\"");
-    pw.flush();
-  }
-
-  /**
-   * Adds attributes to current XML element, represented as Map.
-   * Uses the keys as atttribute names and corresponding
-   * elements as attribute values.
-   * Calls String.valueOf(...) on keys and values.
-   * 
-   * @param attributes
-   */
-  public void addAttribute(Map attributes)
-  {
-    String[] attributesArray = new String[attributes.size() * 2];
-    int index = 0;
-    for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();)
-    {
-      Map.Entry entry = (Map.Entry)iter.next();
-      attributesArray[index] = (String)entry.getKey();
-      attributesArray[index + 1] = (String)entry.getValue();
-      index += 2;
-    }
-    addAttribute(attributesArray);
-  }
-
-  public void addAttribute(String[] attributes)
-  {
-    // if no attributes yet for this element, we can decided 
-    // on the formatting (all attributes on same line or not)
-    if (!hasAttributes && (attributes.length / 2) > maxAttrsOnSameLine)
-      closeElementOnNewLine = true;
-
-    for (int i = 0; i < attributes.length; i += 2)
-    {
-      String key = attributes[i];
-      String value = attributes[i + 1];
-      addAttribute(key, value);
-    }
-  }
-
-  /**
-   * Convenience method for adding more than one nested elements.
-   * 
-   * @param elementNames
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addNestedElements(String[] elementNames)
-  {
-    for (int i = 0; i < elementNames.length; i++)
-    {
-      addElement(elementNames[i]);
-    }
-    return this;
-  }
-
-  /**
-   * Convenience method for adding more than one empty element.
-   * Useful for writing HTML.
-   * 
-   * @param elementNames
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addEmptyElements(String[] elementNames)
-  {
-    for (int i = 0; i < elementNames.length; i++)
-    {
-      addEmptyElement(elementNames[i]);
-    }
-    return this;
-  }
-
-  /**
-   * Convenience method for adding an empty element (no attributes, no children). 
-   * Useful for writing HTML. Equivalent to calling:
-   * 
-   * addElement(elementName)
-   * closeElement()
-   * 
-   * @param elementName
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addEmptyElement(String elementName)
-  {
-    addElement(elementName);
-    closeElement();
-    return this;
-  }
-
-  /**
-   * Writes a new XML element to PrintWriter. If another
-   * XML element has been written and not closed, writes this
-   * element as a child. 
-   * 
-   * @param elementName
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addElement(String elementName)
-  {
-    hasElements = true;
-    finishIncompleteTag();
-    pw.print(sep + getIndent() + "<" + elementName);
-    pw.flush();
-    elementStack.push(elementName);
-    incompleteOpenTag = true;
-    hasAttributes = false;
-    closeElementOnNewLine = false;
-    return this;
-  }
-
-  /**
-   * Writes a new XML element to PrintWriter. If another
-   * XML element has been written and not closed, writes this
-   * element as a child. Also adds passed attributes.
-   * 
-   * @param elementName attributes
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addElement(
-    String elementName,
-    String[] attributes)
-  {
-    addElement(elementName);
-    addAttribute(attributes);
-    return this;
-  }
-
-  /**
-   * Closes the last XML element that has been written.
-   * 
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter closeElement()
-  {
-    if (elementStack.isEmpty())
-    {
-      throw new MalformedXMLRuntimeException("Illegal call to closeElement");
-    }
-    String element = (String)elementStack.pop();
-    if (incompleteOpenTag)
-    {
-      if (closeElementOnNewLine)
-        pw.print(sep + getIndent() + "/>");
-      else
-        pw.print("/>");
-
-      incompleteOpenTag = false;
-    } else
-    {
-      pw.print(sep + getIndent() + "</" + element + ">");
-    }
-    pw.flush();
-    hasAttributes = false;
-    return this;
-  }
-
-  /**
-   * Writes Text as child element to the current element.
-   * 
-   * @param in
-   * @return XMLWriter
-   */
-  public PrintWriterXMLWriter addText(String in)
-  {
-    if (in.trim().length() == 0)
-      return this;
-    finishIncompleteTag();
-    pw.print(sep);
-    pw.print(getIndent());
-    if (escapeText)
-      pw.print(XMLUtil.escape(in).trim());
-    else
-      pw.print(in.trim());
-    pw.flush();
-    return this;
-  }
-
-  public PrintWriterXMLWriter addCDATA(String in)
-  {
-	if (in.trim().length() == 0)
-      return this;
-    finishIncompleteTag();
-    StringBuffer sb = new StringBuffer(500);
-    sb.append(sep).append(getIndent()).append("<![CDATA[");
-    
-    String data = in.trim();
-    if (escapeText)
-    {
-      // why escape if being in CDATA?
-      data = XMLUtil.escape(in);
-    }
-
-    // why do we need this?
-    for (StringTokenizer st = new StringTokenizer(data, sep);
-      st.hasMoreTokens();
-      )
-      sb.append(sep).append(getIndent()).append(getIndentUnit()).append(
-        st.nextToken().trim());
-
-    sb.append(sep).append(getIndent()).append("]]>").append(sep);
-    writeGeneric(sb.toString());
-    return this;
-  }
-
-  /**
-   * Closes all XML elements that have been added, and not yet closed.
-   */
-  public void closeAll()
-  {
-    while (!elementStack.isEmpty())
-      closeElement();
-  }
-
-  private void finishIncompleteTag()
-  {
-    if (incompleteOpenTag)
-    {
-      if (closeElementOnNewLine)
-        pw.print(sep + getIndent(getStackSize() - 1) + ">");
-      else
-        pw.print(">");
-
-      incompleteOpenTag = false;
-    }
-  }
-
-  private PrintWriterXMLWriter writeGeneric(String in)
-  {
-    pw.print(in);
-    pw.flush();
-    return this;
-  }
-
-  private String getIndent()
-  {
-    return getIndent(getStackSize());
-  }
-
-  private String getIndent(int numUnits)
-  {
-    StringBuffer indentString = new StringBuffer();
-    int max = numUnits * indent;
-    for (int i = 0; i < max; i++)
-    {
-      indentString.append(" ");
-    }
-    return indentString.toString();
-  }
-
-  private String getIndentUnit()
-  {
-    StringBuffer indentString = new StringBuffer();
-    for (int i = 0; i < indent; i++)
-    {
-      indentString.append(" ");
-    }
-    return indentString.toString();
-  }
-
-  private int getStackSize()
-  {
-    return elementStack.size();
-  }
-
-  /**
-   * Using this class to swallow the first 'sep'
-   * it receives
-   */
-  private class PrintWriterHolder
-  {
-    private PrintWriter pw = null;
-    private boolean gotFirstSep = false;
-    private boolean swallowFirstSep = true;
-    public PrintWriterHolder(OutputStream out)
-    {
-      pw = new PrintWriter(out);
-    }
-
-    public void setPrintWriter(PrintWriter in)
-    {
-      pw = in;
-    }
-
-    public PrintWriterHolder print(String in)
-    {
-      if (swallowFirstSep && !gotFirstSep)
-      {
-        if (in.startsWith(sep))
-        {
-          gotFirstSep = true;
-          in = in.substring(sep.length());
-        }
-      }
-      pw.print(in);
-      return this;
-    }
-    public void flush()
-    {
-      pw.flush();
-    }
-  }
-
-  /**
-   * Exception thrown only by XMLWriter
-   */
-  private class MalformedXMLRuntimeException extends RuntimeException
-  {
-    public MalformedXMLRuntimeException(String message)
-    {
-      super(message);
-    }
-  }
-
-  public static void main(String args[])
-  {
-    System.out.println(sep);
-
-    PrintWriterXMLWriter foo = new PrintWriterXMLWriter(2, 3);
-    //foo.startDocument("foo-name", "some-url", "some-other-url");
-    foo.addElement("project");
-    foo.addAttribute("name", "foo-project");
-    foo.addAttribute("default", "default-target");
-    foo.addAttribute("a3", "v3");
-    foo.addAttribute("a4", "v4");
-    foo.addComment("A comment between project and target");
-    foo.addElement(
-      "target",
-      new String[] { "a1", "v1", "a2", "v2", "a3", "v3" });
-    foo.addAttribute("name", "default-target");
-    foo.addAttribute("a5", "v5");
-    foo.addElement("test-suite");
-    foo.addAttribute("testunit", "foo-testunit");
-    foo.addElement("test");
-    foo.addAttribute("name", "foo-test");
-    foo.addElement("javatest");
-    foo.addAttribute("testclass", "org.apache.beehive.test.tools.tch.test.foo");
-    foo.addCDATA("Some CDATA nested inside the second \"javatest\" element");
-    foo.closeElement();
-    foo.addElement(
-      "javatest",
-      new String[] { "a1", "v1", "a2", "v2", "a3", "v3", "a4", "v4" });
-    foo.addText("Some text nested inside the second \"javatest\" element");
-    foo.closeElement();
-    foo
-      .addElement(
-        "javatest",
-        new String[] { "a1", "v1", "a2", "v2", "a3", "v3" })
-      .closeElement();
-    foo.addComment("Some nested elements");
-    foo.addNestedElements(new String[] { "e1", "e2", "e3", "e4" });
-    foo.closeAll();
-
-    System.out.println(sep);
-
-  }
-
-}
+package org.apache.beehive.test.tools.tch.util.xml;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.beehive.test.tools.tch.util.Stack;
+
+/**
+ * XMLWriter takes care of writing well-formatted 
+ * xml. 
+ * 
+ * The most important methods are:
+ * 
+ * addElement(String name)
+ * addAttribue(String name, String value)
+ * closeElement()
+ * 
+ * setPrintWriter(PrintWriter in)
+ * 
+ * @version 1.0, April 27, 2002
+ * 
+ * Revised on June 21, 2003.
+ *
+ */
+public class PrintWriterXMLWriter implements XMLWriter
+{
+  protected final static String sep = System.getProperty("line.separator");
+  private final static int DEFAULT_INDENT = 2;
+  private final static int DEFAULT_MAX_ATTRS_ON_SAME_LINE = 2;
+  
+  // if enabled, escapes text in text/cadata sections
+  private boolean escapeText = true;
+
+  private boolean hasElements = false;
+  private boolean incompleteOpenTag = false;
+  private boolean hasAttributes = false;
+  private boolean closeElementOnNewLine = false;
+  private Stack elementStack = new Stack();
+  private PrintWriterHolder pw = new PrintWriterHolder(System.out);
+  private int indent = DEFAULT_INDENT;
+  private int maxAttrsOnSameLine = DEFAULT_MAX_ATTRS_ON_SAME_LINE;
+
+  public PrintWriterXMLWriter()
+  {
+    this(DEFAULT_INDENT);
+  }
+
+  public PrintWriterXMLWriter(int inIndent)
+  {
+    this(inIndent, DEFAULT_MAX_ATTRS_ON_SAME_LINE);
+  }
+
+  public PrintWriterXMLWriter(int inIndent, int inMaxAttrsOnSameLine)
+  {
+    indent = inIndent;
+    maxAttrsOnSameLine = inMaxAttrsOnSameLine;
+  }
+  
+  public void setEscape(boolean in)
+  {
+    escapeText = in;
+  }
+
+  /**
+   * Set PrintWriter to write to. By default, writes to 
+   * System.out
+   */
+  public void setPrintWriter(PrintWriter in)
+  {
+    pw.setPrintWriter(in);
+  }
+
+  /**
+   * Writes DOCTYPE, publicID, privateID. Can only be called before adding 
+   * any elements.
+   * @param publicID
+   * @param privateID
+   */
+  public void startDocument(
+    String doctypeName,
+    String publicID,
+    String systemID)
+  {
+    if (hasElements)
+      throw new MalformedXMLRuntimeException("Cannot init document after elements have been added");
+
+    StringBuffer dtdString = new StringBuffer();
+    dtdString.append("<!DOCTYPE ").append(doctypeName);
+    if (publicID != null)
+      dtdString.append(" PUBLIC \"").append(publicID).append("\"");
+
+    if (systemID != null)
+      dtdString.append(" \"").append(systemID).append("\"");
+    dtdString.append(">" + sep);
+
+    writeGeneric(dtdString.toString());
+  }
+
+  /**
+   * Adds comment 
+   * 
+   * @param comment
+   */
+  public void addComment(String comment)
+  {
+    finishIncompleteTag();
+    writeGeneric(sep + getIndent() + "<!--" + comment + "-->");
+  }
+
+  /**
+   * Adds attribute (name and value) to current XML element.
+   * 
+   * @param name
+   * @param value
+   */
+  public void addAttribute(String name, String value)
+  {
+    if (!incompleteOpenTag)
+    {
+      throw new MalformedXMLRuntimeException("Illegal call to addAttribute");
+    }
+    hasAttributes = true;
+    if (closeElementOnNewLine)
+      pw.print(sep + getIndent());
+    else
+      pw.print(" ");
+    pw.print(name + "=\"" + XMLUtil.escape(value) + "\"");
+    pw.flush();
+  }
+
+  /**
+   * Adds attributes to current XML element, represented as Map.
+   * Uses the keys as atttribute names and corresponding
+   * elements as attribute values.
+   * Calls String.valueOf(...) on keys and values.
+   * 
+   * @param attributes
+   */
+  public void addAttribute(Map attributes)
+  {
+    String[] attributesArray = new String[attributes.size() * 2];
+    int index = 0;
+    for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();)
+    {
+      Map.Entry entry = (Map.Entry)iter.next();
+      attributesArray[index] = (String)entry.getKey();
+      attributesArray[index + 1] = (String)entry.getValue();
+      index += 2;
+    }
+    addAttribute(attributesArray);
+  }
+
+  public void addAttribute(String[] attributes)
+  {
+    // if no attributes yet for this element, we can decided 
+    // on the formatting (all attributes on same line or not)
+    if (!hasAttributes && (attributes.length / 2) > maxAttrsOnSameLine)
+      closeElementOnNewLine = true;
+
+    for (int i = 0; i < attributes.length; i += 2)
+    {
+      String key = attributes[i];
+      String value = attributes[i + 1];
+      addAttribute(key, value);
+    }
+  }
+
+  /**
+   * Convenience method for adding more than one nested elements.
+   * 
+   * @param elementNames
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addNestedElements(String[] elementNames)
+  {
+    for (int i = 0; i < elementNames.length; i++)
+    {
+      addElement(elementNames[i]);
+    }
+    return this;
+  }
+
+  /**
+   * Convenience method for adding more than one empty element.
+   * Useful for writing HTML.
+   * 
+   * @param elementNames
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addEmptyElements(String[] elementNames)
+  {
+    for (int i = 0; i < elementNames.length; i++)
+    {
+      addEmptyElement(elementNames[i]);
+    }
+    return this;
+  }
+
+  /**
+   * Convenience method for adding an empty element (no attributes, no children). 
+   * Useful for writing HTML. Equivalent to calling:
+   * 
+   * addElement(elementName)
+   * closeElement()
+   * 
+   * @param elementName
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addEmptyElement(String elementName)
+  {
+    addElement(elementName);
+    closeElement();
+    return this;
+  }
+
+  /**
+   * Writes a new XML element to PrintWriter. If another
+   * XML element has been written and not closed, writes this
+   * element as a child. 
+   * 
+   * @param elementName
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addElement(String elementName)
+  {
+    hasElements = true;
+    finishIncompleteTag();
+    pw.print(sep + getIndent() + "<" + elementName);
+    pw.flush();
+    elementStack.push(elementName);
+    incompleteOpenTag = true;
+    hasAttributes = false;
+    closeElementOnNewLine = false;
+    return this;
+  }
+
+  /**
+   * Writes a new XML element to PrintWriter. If another
+   * XML element has been written and not closed, writes this
+   * element as a child. Also adds passed attributes.
+   * 
+   * @param elementName attributes
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addElement(
+    String elementName,
+    String[] attributes)
+  {
+    addElement(elementName);
+    addAttribute(attributes);
+    return this;
+  }
+
+  /**
+   * Closes the last XML element that has been written.
+   * 
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter closeElement()
+  {
+    if (elementStack.isEmpty())
+    {
+      throw new MalformedXMLRuntimeException("Illegal call to closeElement");
+    }
+    String element = (String)elementStack.pop();
+    if (incompleteOpenTag)
+    {
+      if (closeElementOnNewLine)
+        pw.print(sep + getIndent() + "/>");
+      else
+        pw.print("/>");
+
+      incompleteOpenTag = false;
+    } else
+    {
+      pw.print(sep + getIndent() + "</" + element + ">");
+    }
+    pw.flush();
+    hasAttributes = false;
+    return this;
+  }
+
+  /**
+   * Writes Text as child element to the current element.
+   * 
+   * @param in
+   * @return XMLWriter
+   */
+  public PrintWriterXMLWriter addText(String in)
+  {
+    if (in.trim().length() == 0)
+      return this;
+    finishIncompleteTag();
+    pw.print(sep);
+    pw.print(getIndent());
+    if (escapeText)
+      pw.print(XMLUtil.escape(in).trim());
+    else
+      pw.print(in.trim());
+    pw.flush();
+    return this;
+  }
+
+  public PrintWriterXMLWriter addCDATA(String in)
+  {
+	if (in.trim().length() == 0)
+      return this;
+    finishIncompleteTag();
+    StringBuffer sb = new StringBuffer(500);
+    sb.append(sep).append(getIndent()).append("<![CDATA[");
+    
+    String data = in.trim();
+    if (escapeText)
+    {
+      // why escape if being in CDATA?
+      data = XMLUtil.escape(in);
+    }
+
+    // why do we need this?
+    for (StringTokenizer st = new StringTokenizer(data, sep);
+      st.hasMoreTokens();
+      )
+      sb.append(sep).append(getIndent()).append(getIndentUnit()).append(
+        st.nextToken().trim());
+
+    sb.append(sep).append(getIndent()).append("]]>").append(sep);
+    writeGeneric(sb.toString());
+    return this;
+  }
+
+  /**
+   * Closes all XML elements that have been added, and not yet closed.
+   */
+  public void closeAll()
+  {
+    while (!elementStack.isEmpty())
+      closeElement();
+  }
+
+  private void finishIncompleteTag()
+  {
+    if (incompleteOpenTag)
+    {
+      if (closeElementOnNewLine)
+        pw.print(sep + getIndent(getStackSize() - 1) + ">");
+      else
+        pw.print(">");
+
+      incompleteOpenTag = false;
+    }
+  }
+
+  private PrintWriterXMLWriter writeGeneric(String in)
+  {
+    pw.print(in);
+    pw.flush();
+    return this;
+  }
+
+  private String getIndent()
+  {
+    return getIndent(getStackSize());
+  }
+
+  private String getIndent(int numUnits)
+  {
+    StringBuffer indentString = new StringBuffer();
+    int max = numUnits * indent;
+    for (int i = 0; i < max; i++)
+    {
+      indentString.append(" ");
+    }
+    return indentString.toString();
+  }
+
+  private String getIndentUnit()
+  {
+    StringBuffer indentString = new StringBuffer();
+    for (int i = 0; i < indent; i++)
+    {
+      indentString.append(" ");
+    }
+    return indentString.toString();
+  }
+
+  private int getStackSize()
+  {
+    return elementStack.size();
+  }
+
+  /**
+   * Using this class to swallow the first 'sep'
+   * it receives
+   */
+  private class PrintWriterHolder
+  {
+    private PrintWriter pw = null;
+    private boolean gotFirstSep = false;
+    private boolean swallowFirstSep = true;
+    public PrintWriterHolder(OutputStream out)
+    {
+      pw = new PrintWriter(out);
+    }
+
+    public void setPrintWriter(PrintWriter in)
+    {
+      pw = in;
+    }
+
+    public PrintWriterHolder print(String in)
+    {
+      if (swallowFirstSep && !gotFirstSep)
+      {
+        if (in.startsWith(sep))
+        {
+          gotFirstSep = true;
+          in = in.substring(sep.length());
+        }
+      }
+      pw.print(in);
+      return this;
+    }
+    public void flush()
+    {
+      pw.flush();
+    }
+  }
+
+  /**
+   * Exception thrown only by XMLWriter
+   */
+  private class MalformedXMLRuntimeException extends RuntimeException
+  {
+    public MalformedXMLRuntimeException(String message)
+    {
+      super(message);
+    }
+  }
+
+  public static void main(String args[])
+  {
+    System.out.println(sep);
+
+    PrintWriterXMLWriter foo = new PrintWriterXMLWriter(2, 3);
+    //foo.startDocument("foo-name", "some-url", "some-other-url");
+    foo.addElement("project");
+    foo.addAttribute("name", "foo-project");
+    foo.addAttribute("default", "default-target");
+    foo.addAttribute("a3", "v3");
+    foo.addAttribute("a4", "v4");
+    foo.addComment("A comment between project and target");
+    foo.addElement(
+      "target",
+      new String[] { "a1", "v1", "a2", "v2", "a3", "v3" });
+    foo.addAttribute("name", "default-target");
+    foo.addAttribute("a5", "v5");
+    foo.addElement("test-suite");
+    foo.addAttribute("testunit", "foo-testunit");
+    foo.addElement("test");
+    foo.addAttribute("name", "foo-test");
+    foo.addElement("javatest");
+    foo.addAttribute("testclass", "org.apache.beehive.test.tools.tch.test.foo");
+    foo.addCDATA("Some CDATA nested inside the second \"javatest\" element");
+    foo.closeElement();
+    foo.addElement(
+      "javatest",
+      new String[] { "a1", "v1", "a2", "v2", "a3", "v3", "a4", "v4" });
+    foo.addText("Some text nested inside the second \"javatest\" element");
+    foo.closeElement();
+    foo
+      .addElement(
+        "javatest",
+        new String[] { "a1", "v1", "a2", "v2", "a3", "v3" })
+      .closeElement();
+    foo.addComment("Some nested elements");
+    foo.addNestedElements(new String[] { "e1", "e2", "e3", "e4" });
+    foo.closeAll();
+
+    System.out.println(sep);
+
+  }
+
+}

Propchange: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/PrintWriterXMLWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLDocument.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLDocument.java?rev=232310&r1=232309&r2=232310&view=diff
==============================================================================
--- beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLDocument.java (original)
+++ beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLDocument.java Fri Aug 12 08:12:28 2005
@@ -1,782 +1,782 @@
-package org.apache.beehive.test.tools.tch.util.xml;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.TreeMap;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/*
- * This class provides helper methods for creating an DOM tree from scratch.
- * ...a similar class must have been written a million times already.... 
- *   great....magic classes.
- *
- * @version 1.0, December 1st, 2002
- *
- */
-public class XMLDocument
-{
-  //=========================================================================
-  // Variables
-
-  private Document root = null; // dom
-  private String documentName = "unnamed";
-  private Stack elementStack = new Stack();
-
-  // for printing
-  private int maxAttributesOnOneLine = 2;
-
-  //=========================================================================
-  // Constructors
-
-  /**
-   * Creates empty Document, with named root element. 
-   */
-  public XMLDocument(String rootNodeName)
-  {
-    this(rootNodeName, new String[] {
-    });
-  }
-
-  /**
-  	* Creates empty Document, with named root element and attributes.
-  	*/
-  public XMLDocument(String rootNodeName, Map attributes)
-  {
-    this(rootNodeName, mapToStringArray(attributes));
-  }
-
-  /**
-   * Creates empty Document, with named root element and attributes.
-   */
-  public XMLDocument(String rootNodeName, String[] attributes)
-  {
-    try
-    {
-      root = DomUtils.instantiateDom();
-    }
-    catch (ParserConfigurationException ex)
-    {
-      throw new NestedXMLProcessingRuntimeException(ex);
-    }
-
-    Element firstElement = createElement(rootNodeName, attributes);
-    root.appendChild(firstElement);
-    elementStack.push(firstElement);
-  }
-
-  /**
-   * Initializes from File.
-   * Assumes File is a valid XML document.
-   */
-  public XMLDocument(File f) throws NestedXMLProcessingException
-  {
-    root = DomUtils.instantiateDom(f, false);
-    setName(f.getName());
-  }
-
-  //=========================================================================
-  // Public Methods
-
-  public String getName()
-  {
-    return documentName;
-  }
-
-  public Node getElement(String elementName)
-  {
-    NodeList elements = root.getElementsByTagName(elementName);
-    if (elements != null && elements.getLength() != 0)
-    {
-      return elements.item(0);
-    }
-    return null;
-  }
-
-  public Node[] getElementsExluding(Collection excludedElementNames)
-  {
-    ArrayList ret = new ArrayList();
-    NodeList children = getDocument().getChildNodes();
-    if (children != null)
-    {
-      int childrenLength = children.getLength();
-      for (int i = 0; i < childrenLength; i++)
-      {
-        Node child = children.item(i);
-        if (!excludedElementNames.contains(child.getNodeName()))
-        {
-          ret.add(child);
-        }
-      }
-    }
-    return (Node[])ret.toArray(new Node[] { null });
-  }
-
-  public Element appendElementToRoot(String name)
-  {
-    return appendElementToRoot(name, new String[] {
-    });
-  }
-
-  public Element appendElementToRoot(String name, Map attributes)
-  {
-    return appendElementToRoot(name, mapToStringArray(attributes));
-  }
-
-  public Element appendElementToRoot(String name, String[] attributes)
-  {
-    Element element = createElement(name, attributes);
-    appendElementToRoot(element);
-    return element;
-  }
-
-  public void appendElementToRoot(Node element)
-  {
-    elementStack.removeAllElements();
-    elementStack.push(element);
-    getDocument().getDocumentElement().appendChild(element);
-  }
-
-  public Element appendElementToMostRecent(String name)
-  {
-    return appendElementToMostRecent(name, new String[] {
-    });
-  }
-
-  public Element appendElementToMostRecent(String name, Map attributes)
-  {
-    return appendElementToMostRecent(name, mapToStringArray(attributes));
-  }
-
-  public Element appendElementToMostRecent(String name, String[] attributes)
-  {
-    Element element = createElement(name, attributes);
-    appendElementToMostRecent(element);
-    return element;
-  }
-
-  public void appendElementToMostRecent(Node element)
-  {
-    Element mostRecent = (Element)elementStack.peek();
-    mostRecent.appendChild(element);
-    elementStack.push(element);
-  }
-
-  public Element appendElement(Element parent, String name)
-  {
-    return appendElement(parent, name, new String[] {
-    });
-  }
-
-  public Element appendElement(Element parent, String name, Map attrs)
-  {
-    return appendElement(parent, name, mapToStringArray(attrs));
-  }
-
-  public Element appendElement(Element parent, String name, String[] attrs)
-  {
-    Element e = createElement(name, attrs);
-    return appendElement(parent, e);
-  }
-
-  public Element appendElement(Element parent, Element child)
-  {
-    elementStack.push(child);
-    parent.appendChild(child);
-    return child;
-  }
-
-  public Element insertElementAtBeginning(
-    Element parent,
-    String name,
-    Map attrs)
-  {
-    return insertElementAtBeginning(parent, name, mapToStringArray(attrs));
-  }
-
-  public Element insertElementAtBeginning(
-    Element parent,
-    String name,
-    String[] attrs)
-  {
-    Element e = createElement(name, attrs);
-    return insertElementAtBeginning(parent, e);
-  }
-
-  public Element insertElementAtBeginning(Element parent, Element child)
-  {
-    elementStack.push(child);
-    Node firstChild = parent.getFirstChild();
-    if (firstChild == null)
-    {
-      parent.appendChild(child);
-    }
-    else
-    {
-      parent.insertBefore(child, firstChild);
-    }
-    return child;
-  }
-
-  public Element insertElementBefore(
-    Element parent,
-    Element beforeThis,
-    String name,
-    Map attrs)
-  {
-    return insertElementBefore(
-      parent,
-      beforeThis,
-      name,
-      mapToStringArray(attrs));
-  }
-
-  public Element insertElementBefore(
-    Element parent,
-    Element beforeThis,
-    String name,
-    String[] attrs)
-  {
-    Element e = createElement(name, attrs);
-    return insertElementBefore(parent, beforeThis, e);
-  }
-
-  public Element insertElementBefore(
-    Element parent,
-    Element beforeThis,
-    Element child)
-  {
-    elementStack.push(child);
-    parent.insertBefore(child, beforeThis);
-    return child;
-  }
-
-  public void appendText(Element parent, String text)
-  {
-    parent.appendChild(getDocument().createTextNode(text));
-  }
-
-  public void appendComment(Element parent, String comment)
-  {
-    parent.appendChild(getDocument().createComment(comment));
-  }
-
-  public Comment insertCommentBefore(
-    Element parent,
-    Element beforeThis,
-    String commentString)
-  {
-    Comment comment = getDocument().createComment(commentString);
-    parent.insertBefore(comment, beforeThis);
-    return comment;
-  }
-
-  public void insertCommentBannerBefore(
-    Element parent,
-    Element beforeThis,
-    String commentString)
-  {
-    insertCommentBannerBefore(parent, beforeThis, commentString, 1, 1, 1);
-  }
-
-  public void insertCommentBannerBefore(
-    Element parent,
-    Element beforeThis,
-    String inComment,
-    int numEmptyHeaderComments,
-    int numEmptyFooterComments,
-    int numPadSpaces)
-  {
-    StringBuffer comment =
-      new StringBuffer(inComment.length() + (numPadSpaces * 2));
-    comment.append(inComment);
-    for (int i = 0; i < numPadSpaces; i++)
-    {
-      comment.insert(0, " ");
-      comment.append(" ");
-    }
-
-    for (int i = 0; i < numEmptyFooterComments; i++)
-      insertCommentBefore(parent, beforeThis, "");
-
-    insertCommentBefore(parent, beforeThis, comment.toString());
-
-    for (int i = 0; i < numEmptyHeaderComments; i++)
-      insertCommentBefore(parent, beforeThis, "");
-  }
-
-  public void closeMostRecent()
-  {
-    if (!elementStack.isEmpty())
-    {
-      elementStack.pop();
-    }
-  }
-
-  public Node importNode(Node inNode)
-  {
-    return getDocument().importNode(inNode, true);
-  }
-
-  public void addAttribute(Node n, String attName, String attValue)
-  {
-    NamedNodeMap attributes = n.getAttributes();
-    Node attribute = attributes.getNamedItem(attName);
-    if (attribute == null)
-    {
-      attribute = getDocument().createAttribute(attName);
-      attributes.setNamedItem(attribute);
-    }
-    attribute.setNodeValue(attValue);
-  }
-
-  public void toFile(File destination) throws NestedXMLProcessingException
-  {
-    DomUtils.writeDom(getDocument(), destination, maxAttributesOnOneLine);
-  }
-
-  public void setMaxAttributesOnLine(int i)
-  {
-    maxAttributesOnOneLine = i;
-  }
-
-  public String toString()
-  {
-    StringBuffer sb = new StringBuffer();
-    DomUtils.writeDom(getDocument(), sb, maxAttributesOnOneLine);
-    return sb.toString();
-  }
-
-  public Document getDocument()
-  {
-    return root;
-  }
-
-  public void moveElements(
-    String elementName,
-    Element newParent,
-    String sortAttrName)
-  {
-    moveElements(elementName, newParent, null, null, sortAttrName);
-  }
-
-  /**
-   * This finds all elements with "elementName", and if there's more than one 
-   * (with all attrs matching) for which parent is not "newParent", makes 
-   * them children of "newParent", and removes them from their current location.
-   * 
-   * If requiredAttrName is not null, only touches Elements that have that attribute.
-   * 
-   * If "sortAttrName" not null, sorts the elements by the value of that attribute
-   * as they are being added to "newParent".
-   */
-  public void moveElements(
-    String elementName,
-    Element newParent,
-    Node insertBefore,
-    String requiredAttrName,
-    String sortAttrName)
-  {
-    boolean insert = (insertBefore != null);
-
-    // maps String we want to sort onto Element 
-    Map moveElements = new TreeMap();
-
-    Collection removeElements = new HashSet();
-    NodeList allMatchingElements =
-      getDocument().getElementsByTagName(elementName);
-    for (int i = allMatchingElements.getLength() - 1; i >= 0; i--)
-    {
-      Element baseElement = (Element)allMatchingElements.item(i);
-
-      if (requiredAttrName != null
-        && !baseElement.hasAttribute(requiredAttrName))
-      {
-        continue;
-      }
-
-      if (baseElement.getParentNode() == newParent)
-      {
-        continue;
-      }
-
-      if (removeElements.contains(baseElement))
-      {
-        continue;
-      }
-
-      String sortAttrValue = null;
-      if (sortAttrName != null)
-      {
-        sortAttrValue = baseElement.getAttribute(sortAttrName);
-      }
-      // now compare to all other ones we have, and see if there's one or 
-      // more identical ones
-      // if we already have the same element with newParent, remove also
-      for (int j = allMatchingElements.getLength() - 1; j >= 0; j--)
-      {
-        if (j == i)
-          continue;
-        Element e = (Element)allMatchingElements.item(j);
-
-        if (requiredAttrName != null && !e.hasAttribute(requiredAttrName))
-        {
-          continue;
-        }
-        if (DomUtils.hasSameAttributes(baseElement, e))
-        {
-          // if parent is newParent, and we have the same element there already,
-          // remove base element also
-          if (e.getParentNode() == newParent)
-          {
-            removeElements.add(baseElement);
-          }
-          else
-          {
-            removeElements.add(e);
-          }
-          //ok to add multiple times since 
-          // moveElements is a HashSet
-          if (sortAttrValue != null)
-          {
-            moveElements.put(sortAttrValue, baseElement);
-          }
-          else
-          {
-            // don't know what to sort by
-            moveElements.put(
-              String.valueOf(baseElement.hashCode()),
-              baseElement);
-          }
-        }
-      }
-    }
-
-    // remove
-    for (Iterator iter = removeElements.iterator(); iter.hasNext();)
-    {
-      Element e = (Element)iter.next();
-      e.getParentNode().removeChild(e);
-    }
-
-    // now add to new parent
-    for (Iterator iter = moveElements.entrySet().iterator(); iter.hasNext();)
-    {
-      Element e = (Element) ((Map.Entry)iter.next()).getValue();
-      if (insert && insertBefore != null)
-      {
-        newParent.insertBefore(e, insertBefore);
-      }
-      else
-      {
-        newParent.appendChild(e);
-      }
-    }
-  }
-
-  /**
-   * Removes all duplicate elements with name "elementName" that have the same parent element
-   * and the same value for "comparisonAttrName"
-   * @param elementName
-   * @param comparisonAttrName
-   */
-  public void removeElementsWithSameAttribute(
-    String elementName,
-    String comparisonAttrName)
-  {
-    Collection elementsToRemove = new HashSet();
-
-    // Element (parent) -> Collection of Strings (values we have encountered)
-    Map parentToAttrValueMapping = new HashMap();
-    NodeList allElements = getDocument().getElementsByTagName(elementName);
-    int length = allElements.getLength();
-    for (int i = 0; i < length; i++)
-    {
-      Element e = (Element)allElements.item(i);
-      Node parent = e.getParentNode();
-      String attrValue = DomUtils.getAttributeValue(e, comparisonAttrName);
-      if (attrValue == null)
-      {
-        continue;
-      }
-      // check if we already have an element with the same parent and the same attr value
-      Collection attrValues = (Collection)parentToAttrValueMapping.get(parent);
-      if (attrValues == null)
-      {
-        // first time
-        attrValues = new HashSet();
-        parentToAttrValueMapping.put(parent, attrValues);
-      }
-      if (attrValues.contains(attrValue))
-        elementsToRemove.add(e);
-
-      else
-        attrValues.add(attrValue);
-    }
-
-    for (Iterator iter = elementsToRemove.iterator(); iter.hasNext();)
-    {
-      Element e = (Element)iter.next();
-      //System.out.println("GOING TO REMOVE ");
-      //DomUtils.writeDom(e);
-      //System.out.println("PARENT IS: ");
-      //System.out.println(e.getParentNode().getNodeName());
-      e.getParentNode().removeChild(e);
-    }
-  }
-
-  /**
-   * Loops over all elements with "elementName". For each element e:
-   * If e has an attr with name "attrName" and if there's a mapping v1->v2 
-   * in "valueMappings" such that the value of "attrName" (va) == v1, replaces 
-   * va with v2.
-   *
-   * @param elementName
-   * @param attrName
-   * @param valueMappings
-   */
-  public void replaceAttrValue(
-    String elementName,
-    String attrName,
-    Map valueMappings)
-  {
-    if (valueMappings.isEmpty())
-      return;
-    NodeList allElements = getDocument().getElementsByTagName(elementName);
-    int length = allElements.getLength();
-    for (int i = 0; i < length; i++)
-    {
-      Element e = (Element)allElements.item(i);
-      Attr attr = e.getAttributeNode(attrName);
-      if (attr != null)
-      {
-        String attrValue = attr.getValue();
-        if (valueMappings.containsKey(attrValue))
-          attr.setValue((String)valueMappings.get(attrValue));
-      }
-    }
-  }
-
-  public void sortElements(String inElementName, Node inParent)
-  {
-    sortElements(inElementName, inParent, null);
-  }
-
-  public void sortElements(
-    String inElementName,
-    Node inParent,
-    Node insertBeforeThisNode)
-  {
-    sortElements(
-      inElementName,
-      inParent,
-      insertBeforeThisNode,
-      new NameComparator());
-  }
-
-  /**
-   * Looks for all elements that have "elementName" and parent "inParent", and 
-   * sorts these elements using the passed "inComparator".
-   * If "insertBeforeThisNode" not null, inserts all sorted elements before
-   * "insertbeforeThisNode". 
-   * 
-   * @param inElementName
-   * @param inParent
-   * @param insertBeforeThisNode
-   * @param inComparator
-   */
-  public void sortElements(
-    String inElementName,
-    Node inParent,
-    Node insertBeforeThisNode,
-    Comparator inComparator)
-  {
-    List elementsToSort = new ArrayList();
-    NodeList elements = inParent.getChildNodes();
-    for (int i = 0; i < elements.getLength(); i++)
-    {
-      Node n = (Node)elements.item(i);
-      if (n.getNodeName().equals(inElementName))
-        elementsToSort.add(n);
-    }
-    if (elementsToSort.isEmpty())
-      return;
-
-    Collections.sort(elementsToSort, inComparator);
-
-    //System.out.println("FOO: " + DomUtils.NodeCollectionToString(elementsToSort));
-
-    // could be null
-    Node lastElementInserted = insertBeforeThisNode;
-
-    int size = elementsToSort.size() - 1;
-    for (int i = size; i >= 0; i--)
-    {
-      Element e = (Element)elementsToSort.get(i);
-      inParent.removeChild(e);
-      if (lastElementInserted == null)
-      {
-        lastElementInserted = e;
-        inParent.appendChild(e);
-      }
-      else
-      {
-        inParent.insertBefore(e, lastElementInserted);
-        lastElementInserted = e;
-      }
-    }
-  }
-
-  //=========================================================================
-  // Private Methods
-
-  private void setName(String inName)
-  {
-    documentName = inName;
-  }
-
-  private boolean containsElementWithSameAttributes(
-    Collection elements,
-    Element e)
-  {
-    for (Iterator iter = elements.iterator(); iter.hasNext();)
-    {
-      Element moved = (Element)iter.next();
-      if (DomUtils.hasSameAttributes(e, moved))
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private Element createElement(String name, String[] attributes)
-  {
-    Element newElement = root.createElement(name);
-    if (attributes != null)
-    {
-      for (int i = 0; i < attributes.length; i += 2)
-      {
-        newElement.setAttribute(attributes[i], attributes[i + 1]);
-      }
-    }
-    return newElement;
-  }
-
-  private static String[] mapToStringArray(Map m)
-  {
-    String[] ret = null;
-    if (m != null && m.size() > 0)
-    {
-      ret = new String[m.size() * 2];
-      int counter = 0;
-      for (Iterator iter = m.entrySet().iterator(); iter.hasNext();)
-      {
-        Map.Entry entry = (Map.Entry)iter.next();
-        ret[counter] = (String)entry.getKey();
-        ret[counter + 1] = (String)entry.getValue();
-        counter += 2;
-      }
-    }
-    return ret;
-  }
-
-  /**
-   * Imposes an absolute ordering an elements that have a "name" attribute.
-   * To determine the ordering uses standard String.compareTo on the 
-   * value of "name".
-   * 
-   * Note: this comparator imposes orderings that are inconsistent with equals.
-   * 
-   *
-   */
-  private class NameComparator implements Comparator
-  {
-    public int compare(Object o1, Object o2)
-    {
-      if (!(o1 instanceof Element) || !(o2 instanceof Element))
-        throw new XMLProcessingRuntimeException("Can only compare Elements");
-
-      Element e1 = (Element)o1;
-      Element e2 = (Element)o2;
-
-      String name1 = DomUtils.getNameAttributeValue(e1);
-      String name2 = DomUtils.getNameAttributeValue(e2);
-
-      if (name1 == null || name2 == null)
-        return 0;
-      else
-        return name1.compareTo(name2);
-    }
-  }
-
-  //=========================================================================
-  //testing
-
-  public static void main(String[] args) throws Exception
-  {
-    Map attributes = new HashMap();
-    attributes.put("name", "name-1");
-    attributes.put("value", "value-1");
-    Map attributes2 = new HashMap();
-    attributes2.put("name", "name-2");
-    attributes2.put("value", "value-2");
-
-    Map attributes4 = new HashMap();
-    attributes4.put("name", "x");
-    attributes4.put("value", "ab");
-
-    XMLDocument doc = new XMLDocument("root");
-    doc.appendElementToRoot(
-      "property",
-      new String[] { "name", "z", "value", "1" });
-    doc.appendElementToRoot(
-      "property",
-      new String[] { "name", "aa", "value", "1" });
-
-    Element e1 = doc.appendElementToRoot("e1");
-    doc.appendElement(e1, "property", attributes);
-    doc.appendElement(e1, "property", attributes4);
-
-    Element e2 = doc.appendElementToRoot("e2");
-    doc.appendElement(e2, "property", attributes2);
-
-    Element e3 = doc.appendElementToRoot("e3");
-    doc.appendElement(e3, "property", attributes2);
-
-    Element e4 = doc.appendElementToRoot("e4");
-    doc.appendElement(e4, "property", attributes4);
-
-    System.out.println("Before:");
-    DomUtils.writeDom(doc.getDocument());
-    doc.moveElements(
-      "property",
-      doc.getDocument().getDocumentElement(),
-      doc.getDocument().getDocumentElement().getFirstChild(),
-      "name",
-      "name");
-    System.out.println("\nAfter moving elements with same 'name' attr to top:");
-    DomUtils.writeDom(doc.getDocument());
-    System.out.println("\nAfter sorting props on top by name attr");
-    doc.sortElements("property", doc.getDocument().getDocumentElement(), e1);
-    DomUtils.writeDom(doc.getDocument());
-    System.out.println("");
-  }
-}
+package org.apache.beehive.test.tools.tch.util.xml;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.TreeMap;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/*
+ * This class provides helper methods for creating an DOM tree from scratch.
+ * ...a similar class must have been written a million times already.... 
+ *   great....magic classes.
+ *
+ * @version 1.0, December 1st, 2002
+ *
+ */
+public class XMLDocument
+{
+  //=========================================================================
+  // Variables
+
+  private Document root = null; // dom
+  private String documentName = "unnamed";
+  private Stack elementStack = new Stack();
+
+  // for printing
+  private int maxAttributesOnOneLine = 2;
+
+  //=========================================================================
+  // Constructors
+
+  /**
+   * Creates empty Document, with named root element. 
+   */
+  public XMLDocument(String rootNodeName)
+  {
+    this(rootNodeName, new String[] {
+    });
+  }
+
+  /**
+  	* Creates empty Document, with named root element and attributes.
+  	*/
+  public XMLDocument(String rootNodeName, Map attributes)
+  {
+    this(rootNodeName, mapToStringArray(attributes));
+  }
+
+  /**
+   * Creates empty Document, with named root element and attributes.
+   */
+  public XMLDocument(String rootNodeName, String[] attributes)
+  {
+    try
+    {
+      root = DomUtils.instantiateDom();
+    }
+    catch (ParserConfigurationException ex)
+    {
+      throw new NestedXMLProcessingRuntimeException(ex);
+    }
+
+    Element firstElement = createElement(rootNodeName, attributes);
+    root.appendChild(firstElement);
+    elementStack.push(firstElement);
+  }
+
+  /**
+   * Initializes from File.
+   * Assumes File is a valid XML document.
+   */
+  public XMLDocument(File f) throws NestedXMLProcessingException
+  {
+    root = DomUtils.instantiateDom(f, false);
+    setName(f.getName());
+  }
+
+  //=========================================================================
+  // Public Methods
+
+  public String getName()
+  {
+    return documentName;
+  }
+
+  public Node getElement(String elementName)
+  {
+    NodeList elements = root.getElementsByTagName(elementName);
+    if (elements != null && elements.getLength() != 0)
+    {
+      return elements.item(0);
+    }
+    return null;
+  }
+
+  public Node[] getElementsExluding(Collection excludedElementNames)
+  {
+    ArrayList ret = new ArrayList();
+    NodeList children = getDocument().getChildNodes();
+    if (children != null)
+    {
+      int childrenLength = children.getLength();
+      for (int i = 0; i < childrenLength; i++)
+      {
+        Node child = children.item(i);
+        if (!excludedElementNames.contains(child.getNodeName()))
+        {
+          ret.add(child);
+        }
+      }
+    }
+    return (Node[])ret.toArray(new Node[] { null });
+  }
+
+  public Element appendElementToRoot(String name)
+  {
+    return appendElementToRoot(name, new String[] {
+    });
+  }
+
+  public Element appendElementToRoot(String name, Map attributes)
+  {
+    return appendElementToRoot(name, mapToStringArray(attributes));
+  }
+
+  public Element appendElementToRoot(String name, String[] attributes)
+  {
+    Element element = createElement(name, attributes);
+    appendElementToRoot(element);
+    return element;
+  }
+
+  public void appendElementToRoot(Node element)
+  {
+    elementStack.removeAllElements();
+    elementStack.push(element);
+    getDocument().getDocumentElement().appendChild(element);
+  }
+
+  public Element appendElementToMostRecent(String name)
+  {
+    return appendElementToMostRecent(name, new String[] {
+    });
+  }
+
+  public Element appendElementToMostRecent(String name, Map attributes)
+  {
+    return appendElementToMostRecent(name, mapToStringArray(attributes));
+  }
+
+  public Element appendElementToMostRecent(String name, String[] attributes)
+  {
+    Element element = createElement(name, attributes);
+    appendElementToMostRecent(element);
+    return element;
+  }
+
+  public void appendElementToMostRecent(Node element)
+  {
+    Element mostRecent = (Element)elementStack.peek();
+    mostRecent.appendChild(element);
+    elementStack.push(element);
+  }
+
+  public Element appendElement(Element parent, String name)
+  {
+    return appendElement(parent, name, new String[] {
+    });
+  }
+
+  public Element appendElement(Element parent, String name, Map attrs)
+  {
+    return appendElement(parent, name, mapToStringArray(attrs));
+  }
+
+  public Element appendElement(Element parent, String name, String[] attrs)
+  {
+    Element e = createElement(name, attrs);
+    return appendElement(parent, e);
+  }
+
+  public Element appendElement(Element parent, Element child)
+  {
+    elementStack.push(child);
+    parent.appendChild(child);
+    return child;
+  }
+
+  public Element insertElementAtBeginning(
+    Element parent,
+    String name,
+    Map attrs)
+  {
+    return insertElementAtBeginning(parent, name, mapToStringArray(attrs));
+  }
+
+  public Element insertElementAtBeginning(
+    Element parent,
+    String name,
+    String[] attrs)
+  {
+    Element e = createElement(name, attrs);
+    return insertElementAtBeginning(parent, e);
+  }
+
+  public Element insertElementAtBeginning(Element parent, Element child)
+  {
+    elementStack.push(child);
+    Node firstChild = parent.getFirstChild();
+    if (firstChild == null)
+    {
+      parent.appendChild(child);
+    }
+    else
+    {
+      parent.insertBefore(child, firstChild);
+    }
+    return child;
+  }
+
+  public Element insertElementBefore(
+    Element parent,
+    Element beforeThis,
+    String name,
+    Map attrs)
+  {
+    return insertElementBefore(
+      parent,
+      beforeThis,
+      name,
+      mapToStringArray(attrs));
+  }
+
+  public Element insertElementBefore(
+    Element parent,
+    Element beforeThis,
+    String name,
+    String[] attrs)
+  {
+    Element e = createElement(name, attrs);
+    return insertElementBefore(parent, beforeThis, e);
+  }
+
+  public Element insertElementBefore(
+    Element parent,
+    Element beforeThis,
+    Element child)
+  {
+    elementStack.push(child);
+    parent.insertBefore(child, beforeThis);
+    return child;
+  }
+
+  public void appendText(Element parent, String text)
+  {
+    parent.appendChild(getDocument().createTextNode(text));
+  }
+
+  public void appendComment(Element parent, String comment)
+  {
+    parent.appendChild(getDocument().createComment(comment));
+  }
+
+  public Comment insertCommentBefore(
+    Element parent,
+    Element beforeThis,
+    String commentString)
+  {
+    Comment comment = getDocument().createComment(commentString);
+    parent.insertBefore(comment, beforeThis);
+    return comment;
+  }
+
+  public void insertCommentBannerBefore(
+    Element parent,
+    Element beforeThis,
+    String commentString)
+  {
+    insertCommentBannerBefore(parent, beforeThis, commentString, 1, 1, 1);
+  }
+
+  public void insertCommentBannerBefore(
+    Element parent,
+    Element beforeThis,
+    String inComment,
+    int numEmptyHeaderComments,
+    int numEmptyFooterComments,
+    int numPadSpaces)
+  {
+    StringBuffer comment =
+      new StringBuffer(inComment.length() + (numPadSpaces * 2));
+    comment.append(inComment);
+    for (int i = 0; i < numPadSpaces; i++)
+    {
+      comment.insert(0, " ");
+      comment.append(" ");
+    }
+
+    for (int i = 0; i < numEmptyFooterComments; i++)
+      insertCommentBefore(parent, beforeThis, "");
+
+    insertCommentBefore(parent, beforeThis, comment.toString());
+
+    for (int i = 0; i < numEmptyHeaderComments; i++)
+      insertCommentBefore(parent, beforeThis, "");
+  }
+
+  public void closeMostRecent()
+  {
+    if (!elementStack.isEmpty())
+    {
+      elementStack.pop();
+    }
+  }
+
+  public Node importNode(Node inNode)
+  {
+    return getDocument().importNode(inNode, true);
+  }
+
+  public void addAttribute(Node n, String attName, String attValue)
+  {
+    NamedNodeMap attributes = n.getAttributes();
+    Node attribute = attributes.getNamedItem(attName);
+    if (attribute == null)
+    {
+      attribute = getDocument().createAttribute(attName);
+      attributes.setNamedItem(attribute);
+    }
+    attribute.setNodeValue(attValue);
+  }
+
+  public void toFile(File destination) throws NestedXMLProcessingException
+  {
+    DomUtils.writeDom(getDocument(), destination, maxAttributesOnOneLine);
+  }
+
+  public void setMaxAttributesOnLine(int i)
+  {
+    maxAttributesOnOneLine = i;
+  }
+
+  public String toString()
+  {
+    StringBuffer sb = new StringBuffer();
+    DomUtils.writeDom(getDocument(), sb, maxAttributesOnOneLine);
+    return sb.toString();
+  }
+
+  public Document getDocument()
+  {
+    return root;
+  }
+
+  public void moveElements(
+    String elementName,
+    Element newParent,
+    String sortAttrName)
+  {
+    moveElements(elementName, newParent, null, null, sortAttrName);
+  }
+
+  /**
+   * This finds all elements with "elementName", and if there's more than one 
+   * (with all attrs matching) for which parent is not "newParent", makes 
+   * them children of "newParent", and removes them from their current location.
+   * 
+   * If requiredAttrName is not null, only touches Elements that have that attribute.
+   * 
+   * If "sortAttrName" not null, sorts the elements by the value of that attribute
+   * as they are being added to "newParent".
+   */
+  public void moveElements(
+    String elementName,
+    Element newParent,
+    Node insertBefore,
+    String requiredAttrName,
+    String sortAttrName)
+  {
+    boolean insert = (insertBefore != null);
+
+    // maps String we want to sort onto Element 
+    Map moveElements = new TreeMap();
+
+    Collection removeElements = new HashSet();
+    NodeList allMatchingElements =
+      getDocument().getElementsByTagName(elementName);
+    for (int i = allMatchingElements.getLength() - 1; i >= 0; i--)
+    {
+      Element baseElement = (Element)allMatchingElements.item(i);
+
+      if (requiredAttrName != null
+        && !baseElement.hasAttribute(requiredAttrName))
+      {
+        continue;
+      }
+
+      if (baseElement.getParentNode() == newParent)
+      {
+        continue;
+      }
+
+      if (removeElements.contains(baseElement))
+      {
+        continue;
+      }
+
+      String sortAttrValue = null;
+      if (sortAttrName != null)
+      {
+        sortAttrValue = baseElement.getAttribute(sortAttrName);
+      }
+      // now compare to all other ones we have, and see if there's one or 
+      // more identical ones
+      // if we already have the same element with newParent, remove also
+      for (int j = allMatchingElements.getLength() - 1; j >= 0; j--)
+      {
+        if (j == i)
+          continue;
+        Element e = (Element)allMatchingElements.item(j);
+
+        if (requiredAttrName != null && !e.hasAttribute(requiredAttrName))
+        {
+          continue;
+        }
+        if (DomUtils.hasSameAttributes(baseElement, e))
+        {
+          // if parent is newParent, and we have the same element there already,
+          // remove base element also
+          if (e.getParentNode() == newParent)
+          {
+            removeElements.add(baseElement);
+          }
+          else
+          {
+            removeElements.add(e);
+          }
+          //ok to add multiple times since 
+          // moveElements is a HashSet
+          if (sortAttrValue != null)
+          {
+            moveElements.put(sortAttrValue, baseElement);
+          }
+          else
+          {
+            // don't know what to sort by
+            moveElements.put(
+              String.valueOf(baseElement.hashCode()),
+              baseElement);
+          }
+        }
+      }
+    }
+
+    // remove
+    for (Iterator iter = removeElements.iterator(); iter.hasNext();)
+    {
+      Element e = (Element)iter.next();
+      e.getParentNode().removeChild(e);
+    }
+
+    // now add to new parent
+    for (Iterator iter = moveElements.entrySet().iterator(); iter.hasNext();)
+    {
+      Element e = (Element) ((Map.Entry)iter.next()).getValue();
+      if (insert && insertBefore != null)
+      {
+        newParent.insertBefore(e, insertBefore);
+      }
+      else
+      {
+        newParent.appendChild(e);
+      }
+    }
+  }
+
+  /**
+   * Removes all duplicate elements with name "elementName" that have the same parent element
+   * and the same value for "comparisonAttrName"
+   * @param elementName
+   * @param comparisonAttrName
+   */
+  public void removeElementsWithSameAttribute(
+    String elementName,
+    String comparisonAttrName)
+  {
+    Collection elementsToRemove = new HashSet();
+
+    // Element (parent) -> Collection of Strings (values we have encountered)
+    Map parentToAttrValueMapping = new HashMap();
+    NodeList allElements = getDocument().getElementsByTagName(elementName);
+    int length = allElements.getLength();
+    for (int i = 0; i < length; i++)
+    {
+      Element e = (Element)allElements.item(i);
+      Node parent = e.getParentNode();
+      String attrValue = DomUtils.getAttributeValue(e, comparisonAttrName);
+      if (attrValue == null)
+      {
+        continue;
+      }
+      // check if we already have an element with the same parent and the same attr value
+      Collection attrValues = (Collection)parentToAttrValueMapping.get(parent);
+      if (attrValues == null)
+      {
+        // first time
+        attrValues = new HashSet();
+        parentToAttrValueMapping.put(parent, attrValues);
+      }
+      if (attrValues.contains(attrValue))
+        elementsToRemove.add(e);
+
+      else
+        attrValues.add(attrValue);
+    }
+
+    for (Iterator iter = elementsToRemove.iterator(); iter.hasNext();)
+    {
+      Element e = (Element)iter.next();
+      //System.out.println("GOING TO REMOVE ");
+      //DomUtils.writeDom(e);
+      //System.out.println("PARENT IS: ");
+      //System.out.println(e.getParentNode().getNodeName());
+      e.getParentNode().removeChild(e);
+    }
+  }
+
+  /**
+   * Loops over all elements with "elementName". For each element e:
+   * If e has an attr with name "attrName" and if there's a mapping v1->v2 
+   * in "valueMappings" such that the value of "attrName" (va) == v1, replaces 
+   * va with v2.
+   *
+   * @param elementName
+   * @param attrName
+   * @param valueMappings
+   */
+  public void replaceAttrValue(
+    String elementName,
+    String attrName,
+    Map valueMappings)
+  {
+    if (valueMappings.isEmpty())
+      return;
+    NodeList allElements = getDocument().getElementsByTagName(elementName);
+    int length = allElements.getLength();
+    for (int i = 0; i < length; i++)
+    {
+      Element e = (Element)allElements.item(i);
+      Attr attr = e.getAttributeNode(attrName);
+      if (attr != null)
+      {
+        String attrValue = attr.getValue();
+        if (valueMappings.containsKey(attrValue))
+          attr.setValue((String)valueMappings.get(attrValue));
+      }
+    }
+  }
+
+  public void sortElements(String inElementName, Node inParent)
+  {
+    sortElements(inElementName, inParent, null);
+  }
+
+  public void sortElements(
+    String inElementName,
+    Node inParent,
+    Node insertBeforeThisNode)
+  {
+    sortElements(
+      inElementName,
+      inParent,
+      insertBeforeThisNode,
+      new NameComparator());
+  }
+
+  /**
+   * Looks for all elements that have "elementName" and parent "inParent", and 
+   * sorts these elements using the passed "inComparator".
+   * If "insertBeforeThisNode" not null, inserts all sorted elements before
+   * "insertbeforeThisNode". 
+   * 
+   * @param inElementName
+   * @param inParent
+   * @param insertBeforeThisNode
+   * @param inComparator
+   */
+  public void sortElements(
+    String inElementName,
+    Node inParent,
+    Node insertBeforeThisNode,
+    Comparator inComparator)
+  {
+    List elementsToSort = new ArrayList();
+    NodeList elements = inParent.getChildNodes();
+    for (int i = 0; i < elements.getLength(); i++)
+    {
+      Node n = (Node)elements.item(i);
+      if (n.getNodeName().equals(inElementName))
+        elementsToSort.add(n);
+    }
+    if (elementsToSort.isEmpty())
+      return;
+
+    Collections.sort(elementsToSort, inComparator);
+
+    //System.out.println("FOO: " + DomUtils.NodeCollectionToString(elementsToSort));
+
+    // could be null
+    Node lastElementInserted = insertBeforeThisNode;
+
+    int size = elementsToSort.size() - 1;
+    for (int i = size; i >= 0; i--)
+    {
+      Element e = (Element)elementsToSort.get(i);
+      inParent.removeChild(e);
+      if (lastElementInserted == null)
+      {
+        lastElementInserted = e;
+        inParent.appendChild(e);
+      }
+      else
+      {
+        inParent.insertBefore(e, lastElementInserted);
+        lastElementInserted = e;
+      }
+    }
+  }
+
+  //=========================================================================
+  // Private Methods
+
+  private void setName(String inName)
+  {
+    documentName = inName;
+  }
+
+  private boolean containsElementWithSameAttributes(
+    Collection elements,
+    Element e)
+  {
+    for (Iterator iter = elements.iterator(); iter.hasNext();)
+    {
+      Element moved = (Element)iter.next();
+      if (DomUtils.hasSameAttributes(e, moved))
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Element createElement(String name, String[] attributes)
+  {
+    Element newElement = root.createElement(name);
+    if (attributes != null)
+    {
+      for (int i = 0; i < attributes.length; i += 2)
+      {
+        newElement.setAttribute(attributes[i], attributes[i + 1]);
+      }
+    }
+    return newElement;
+  }
+
+  private static String[] mapToStringArray(Map m)
+  {
+    String[] ret = null;
+    if (m != null && m.size() > 0)
+    {
+      ret = new String[m.size() * 2];
+      int counter = 0;
+      for (Iterator iter = m.entrySet().iterator(); iter.hasNext();)
+      {
+        Map.Entry entry = (Map.Entry)iter.next();
+        ret[counter] = (String)entry.getKey();
+        ret[counter + 1] = (String)entry.getValue();
+        counter += 2;
+      }
+    }
+    return ret;
+  }
+
+  /**
+   * Imposes an absolute ordering an elements that have a "name" attribute.
+   * To determine the ordering uses standard String.compareTo on the 
+   * value of "name".
+   * 
+   * Note: this comparator imposes orderings that are inconsistent with equals.
+   * 
+   *
+   */
+  private class NameComparator implements Comparator
+  {
+    public int compare(Object o1, Object o2)
+    {
+      if (!(o1 instanceof Element) || !(o2 instanceof Element))
+        throw new XMLProcessingRuntimeException("Can only compare Elements");
+
+      Element e1 = (Element)o1;
+      Element e2 = (Element)o2;
+
+      String name1 = DomUtils.getNameAttributeValue(e1);
+      String name2 = DomUtils.getNameAttributeValue(e2);
+
+      if (name1 == null || name2 == null)
+        return 0;
+      else
+        return name1.compareTo(name2);
+    }
+  }
+
+  //=========================================================================
+  //testing
+
+  public static void main(String[] args) throws Exception
+  {
+    Map attributes = new HashMap();
+    attributes.put("name", "name-1");
+    attributes.put("value", "value-1");
+    Map attributes2 = new HashMap();
+    attributes2.put("name", "name-2");
+    attributes2.put("value", "value-2");
+
+    Map attributes4 = new HashMap();
+    attributes4.put("name", "x");
+    attributes4.put("value", "ab");
+
+    XMLDocument doc = new XMLDocument("root");
+    doc.appendElementToRoot(
+      "property",
+      new String[] { "name", "z", "value", "1" });
+    doc.appendElementToRoot(
+      "property",
+      new String[] { "name", "aa", "value", "1" });
+
+    Element e1 = doc.appendElementToRoot("e1");
+    doc.appendElement(e1, "property", attributes);
+    doc.appendElement(e1, "property", attributes4);
+
+    Element e2 = doc.appendElementToRoot("e2");
+    doc.appendElement(e2, "property", attributes2);
+
+    Element e3 = doc.appendElementToRoot("e3");
+    doc.appendElement(e3, "property", attributes2);
+
+    Element e4 = doc.appendElementToRoot("e4");
+    doc.appendElement(e4, "property", attributes4);
+
+    System.out.println("Before:");
+    DomUtils.writeDom(doc.getDocument());
+    doc.moveElements(
+      "property",
+      doc.getDocument().getDocumentElement(),
+      doc.getDocument().getDocumentElement().getFirstChild(),
+      "name",
+      "name");
+    System.out.println("\nAfter moving elements with same 'name' attr to top:");
+    DomUtils.writeDom(doc.getDocument());
+    System.out.println("\nAfter sorting props on top by name attr");
+    doc.sortElements("property", doc.getDocument().getDocumentElement(), e1);
+    DomUtils.writeDom(doc.getDocument());
+    System.out.println("");
+  }
+}

Propchange: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLProcessingRuntimeException.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLProcessingRuntimeException.java?rev=232310&r1=232309&r2=232310&view=diff
==============================================================================
--- beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLProcessingRuntimeException.java (original)
+++ beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLProcessingRuntimeException.java Fri Aug 12 08:12:28 2005
@@ -1,18 +1,18 @@
-package org.apache.beehive.test.tools.tch.util.xml;
-
-import org.apache.beehive.test.tools.tch.util.NestedRuntimeException;
-
-/**
- */
-public class XMLProcessingRuntimeException extends NestedRuntimeException
-{
-  public XMLProcessingRuntimeException(String inMessage)
-  {
-    super(inMessage);
-  }
-
-  public XMLProcessingRuntimeException(Throwable th)
-  {
-    super(th);
-  }
-}
+package org.apache.beehive.test.tools.tch.util.xml;
+
+import org.apache.beehive.test.tools.tch.util.NestedRuntimeException;
+
+/**
+ */
+public class XMLProcessingRuntimeException extends NestedRuntimeException
+{
+  public XMLProcessingRuntimeException(String inMessage)
+  {
+    super(inMessage);
+  }
+
+  public XMLProcessingRuntimeException(Throwable th)
+  {
+    super(th);
+  }
+}

Propchange: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/util/xml/XMLProcessingRuntimeException.java
------------------------------------------------------------------------------
    svn:eol-style = native