/*-- $Id: NoNsXMLOutputter.java,v 1.76 2002/03/15 05:36:48 jhunter Exp $ Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package com.webct.platform.tools.systemintegrationapi.service.adapters.sct; import java.io.IOException; import java.io.Writer; import java.util.List; import org.jdom.CDATA; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.Text; import org.jdom.output.XMLOutputter; /** * @author David Beleznay * * subclass of XMLOutputter, designed to produce the same xml as before, just without a namespace */ public class NoNsXMLOutputter extends XMLOutputter { /** standard string with which to end a line */ private static final String STANDARD_LINE_SEPARATOR = "\r\n"; class Format implements Cloneable { /** The default indent is no spaces (as original document) */ String indent = null; /** Whether or not to expand empty elements to * <tagName></tagName> - default is false */ boolean expandEmptyElements = false; /** New line separator */ String lineSeparator = STANDARD_LINE_SEPARATOR; /** Should we trim whitespace only content or not */ boolean trimAllWhite = false; /** Should we trim leading/trailing whitespace or not in text nodes */ boolean textTrim = false; /** Should we preserve whitespace or not in text nodes */ boolean textNormalize = false; /** The default new line flag, set to do new lines only as in * original document */ boolean newlines = false; Format() {} protected Object clone() { Format format = null; try { format = (Format) super.clone(); } catch (CloneNotSupportedException ce) { } return format; } } Format noFormatting = new Format(); Format defaultFormat = new Format(); Format currentFormat = defaultFormat; /** *

* This will create an XMLOutputter with no additional * whitespace (indent or newlines) added; the whitespace from the * element text content is fully preserved. *

*/ public NoNsXMLOutputter() { super(); } /** *

* This will create an XMLOutputter with the given indent * added but no new lines added; all whitespace from the element text * content is included as well. *

* * @param indent the indent string, usually some number of spaces */ public NoNsXMLOutputter(String indent) { super(indent); } /** *

* This will create an XMLOutputter with the given indent * that prints newlines only if newlines is * true; all whitespace from the element text content is * included as well. *

* * @param indent the indent String, usually some number * of spaces * @param newlines true indicates new lines should be * printed, else new lines are ignored (compacted). */ public NoNsXMLOutputter(String indent, boolean newlines) { super(indent, newlines); } /** *

* This will create an XMLOutputter with * the given indent and new lines printing only if * newlines is true, and encoding format * encoding. *

* * @param indent the indent String, usually some number * of spaces * @param newlines true indicates new lines should be * printed, else new lines are ignored (compacted). * @param encoding set encoding format. Use XML-style names like * "UTF-8" or "ISO-8859-1" or "US-ASCII" */ public NoNsXMLOutputter(String indent, boolean newlines, String encoding) { super(indent, newlines, encoding); } /** *

* This will create an XMLOutputter with all the * options as set in the given XMLOutputter. Note * that XMLOutputter two = (XMLOutputter)one.clone(); * would work equally well. *

* * @param that the XMLOutputter to clone */ public NoNsXMLOutputter(XMLOutputter that) { super(that); } /** *

* This will handle printing of a {@link Element}, * it's {@link Attribute}s, and all contained (child) * elements, etc. *

* * @param element Element to output. * @param out Writer to use. * @param indent int level of indention. * @param namespaces List stack of Namespaces in scope. */ protected void printElement(Element element, Writer out, int level, NamespaceStack namespaces) throws IOException { List attributes = element.getAttributes(); List content = element.getContent(); // Check for xml:space and adjust format settings String space = null; if (attributes != null) { space = element.getAttributeValue( "space", Namespace.XML_NAMESPACE); } Format previousFormat = currentFormat; if ("default".equals( space)) currentFormat = defaultFormat; else if ("preserve".equals( space)) currentFormat = noFormatting; // Print the beginning of the tag plus attributes and any // necessary namespace declarations out.write("<"); out.write(element.getQualifiedName()); // Mark our namespace starting point int previouslyDeclaredNamespaces = namespaces.size(); // Print the element's namespace, if appropriate //printElementNamespace(element, out, namespaces); // Print out additional namespace declarations //printAdditionalNamespaces(element, out, namespaces); // Print out attributes if (attributes != null) printAttributes( attributes, element, out, namespaces); // Depending on the settings (newlines, textNormalize, etc), we may // or may not want to print all of the content, so determine the // index of the start of the content we're interested // in based on the current settings. int start = skipLeadingWhite( content, 0); if (start >= content.size()) { // Case content is empty or all insignificant whitespace if (currentFormat.expandEmptyElements) { out.write(">"); } else { out.write(" />"); } } else { out.write(">"); // For a special case where the content is only CDATA // or Text we don't want to indent after the start or // before the end tag. if (nextNonText( content, start) < content.size()) { // Case Mixed Content - normal indentation newline(out); printContentRange(content, start, content.size(), out, level + 1, namespaces); newline(out); indent(out, level); } else { // Case all CDATA or Text - no indentation printTextRange(content, start, content.size(), out); } out.write(""); } // remove declared namespaces from stack while (namespaces.size() > previouslyDeclaredNamespaces) { namespaces.pop(); } // Restore our format settings currentFormat = previousFormat; } // Returns the index of the first non-all-whitespace CDATA or Text, // index = content.size() is returned if content contains // all whitespace. // @param start index to begin search (inclusive) private int skipLeadingWhite( List content, int start) { if (start < 0) start = 0; int index = start; if (currentFormat.trimAllWhite || currentFormat.textNormalize || currentFormat.textTrim || currentFormat.newlines) { while( index < content.size()) { if ( !isAllWhitespace( content.get(index))) break; index++; } } return index; } // Return the index + 1 of the last non-all-whitespace CDATA or // Text node, index < 0 is returned // if content contains all whitespace. // @param start index to begin search (exclusive) private int skipTrialingWhite( List content, int start) { if (start > content.size()) start = content.size(); int index = start; if (currentFormat.trimAllWhite || currentFormat.textNormalize || currentFormat.textTrim || currentFormat.newlines) { while( index >= 0) { if ( !isAllWhitespace( content.get(index - 1))) break; --index; } } return index; } // Return the next non-CDATA or non-Text node, index = content.size() // is returned if there is no more non-CDATA or non-Text nodes // @param start index to begin search (inclusive) private int nextNonText( List content, int start) { if (start < 0) start = 0; int index = start; while( index < content.size()) { if ( !((content.get( index) instanceof CDATA) || (content.get( index) instanceof Text))) break; index++; } return index; } // Determine if a Object is all whitespace private boolean isAllWhitespace(Object obj) { String str = null; if (obj instanceof String) { str = (String) obj; } else if (obj instanceof CDATA) { str = ((CDATA) obj).getText(); } else if (obj instanceof Text) { str = ((Text) obj).getText(); } else { return false; } for (int i = 0; i < str.length(); i++) { if ( !isWhitespace( str.charAt( i))) return false; } return true; } // Determine if a character is a XML whitespace. // XXX should this method be in Verifier private boolean isWhitespace(char ch) { if (" \t\n\r".indexOf(ch) < 0) { return false; } return true; } }