0N/A/*
0N/A * reserved comment block
0N/A * DO NOT REMOVE OR ALTER!
0N/A */
0N/A/*
0N/A * Copyright 1999-2004 The Apache Software Foundation.
0N/A *
0N/A * Licensed under the Apache License, Version 2.0 (the "License");
0N/A * you may not use this file except in compliance with the License.
0N/A * You may obtain a copy of the License at
0N/A *
0N/A * http://www.apache.org/licenses/LICENSE-2.0
0N/A *
0N/A * Unless required by applicable law or agreed to in writing, software
0N/A * distributed under the License is distributed on an "AS IS" BASIS,
0N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0N/A * See the License for the specific language governing permissions and
0N/A * limitations under the License.
0N/A *
0N/A */
0N/Apackage com.sun.org.apache.xml.internal.security.signature;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.io.StringWriter;
0N/Aimport java.io.Writer;
0N/Aimport java.util.Arrays;
0N/Aimport java.util.Set;
0N/A
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.XMLUtils;
0N/Aimport org.w3c.dom.Attr;
0N/Aimport org.w3c.dom.Comment;
0N/Aimport org.w3c.dom.Document;
0N/Aimport org.w3c.dom.Element;
0N/Aimport org.w3c.dom.NamedNodeMap;
0N/Aimport org.w3c.dom.Node;
0N/Aimport org.w3c.dom.ProcessingInstruction;
0N/A
0N/A/**
0N/A * Class XMLSignatureInputDebugger
0N/A *
661N/A * @author $Author: mullan $
661N/A * @version $Revision: 1.3 $
0N/A */
0N/Apublic class XMLSignatureInputDebugger {
0N/A
0N/A
0N/A
0N/A /** Field _xmlSignatureInput */
0N/A private Set _xpathNodeSet;
0N/A
0N/A private Set _inclusiveNamespaces;
0N/A
0N/A /** Field _doc */
0N/A private Document _doc = null;
0N/A
0N/A /** Field _writer */
0N/A private Writer _writer = null;
0N/A
0N/A // J-
0N/A // public static final String HTMLPrefix = "<!DOCTYPE HTML PUBLIC
0N/A // \"-//W3C//DTD HTML 4.01 Transitional//EN\"><html><head><style
0N/A // type=\"text/css\"><!-- .INCLUDED { color: #000000; background-color:
0N/A // #FFFFFF; font-weight: bold; } .EXCLUDED { color: #666666;
0N/A // background-color: #999999; } .INCLUDEDINCLUSIVENAMESPACE { color:
0N/A // #0000FF; background-color: #FFFFFF; font-weight: bold; font-style:
0N/A // italic; } .EXCLUDEDINCLUSIVENAMESPACE { color: #0000FF; background-color:
0N/A // #999999; font-style: italic; } --> </style> </head><body
0N/A // bgcolor=\"#999999\"><pre>";
0N/A /** The HTML Prefix* */
0N/A static final String HTMLPrefix = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
0N/A + "<html>\n"
0N/A + "<head>\n"
0N/A + "<title>Caninical XML node set</title>\n"
0N/A + "<style type=\"text/css\">\n"
0N/A + "<!-- \n"
0N/A + ".INCLUDED { \n"
0N/A + " color: #000000; \n"
0N/A + " background-color: \n"
0N/A + " #FFFFFF; \n"
0N/A + " font-weight: bold; } \n"
0N/A + ".EXCLUDED { \n"
0N/A + " color: #666666; \n"
0N/A + " background-color: \n"
0N/A + " #999999; } \n"
0N/A + ".INCLUDEDINCLUSIVENAMESPACE { \n"
0N/A + " color: #0000FF; \n"
0N/A + " background-color: #FFFFFF; \n"
0N/A + " font-weight: bold; \n"
0N/A + " font-style: italic; } \n"
0N/A + ".EXCLUDEDINCLUSIVENAMESPACE { \n"
0N/A + " color: #0000FF; \n"
0N/A + " background-color: #999999; \n"
0N/A + " font-style: italic; } \n"
0N/A + "--> \n"
0N/A + "</style> \n"
0N/A + "</head>\n"
0N/A + "<body bgcolor=\"#999999\">\n"
0N/A + "<h1>Explanation of the output</h1>\n"
0N/A + "<p>The following text contains the nodeset of the given Reference before it is canonicalized. There exist four different styles to indicate how a given node is treated.</p>\n"
0N/A + "<ul>\n"
0N/A + "<li class=\"INCLUDED\">A node which is in the node set is labeled using the INCLUDED style.</li>\n"
0N/A + "<li class=\"EXCLUDED\">A node which is <em>NOT</em> in the node set is labeled EXCLUDED style.</li>\n"
0N/A + "<li class=\"INCLUDEDINCLUSIVENAMESPACE\">A namespace which is in the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n"
0N/A + "<li class=\"EXCLUDEDINCLUSIVENAMESPACE\">A namespace which is in NOT the node set AND in the InclusiveNamespaces PrefixList is labeled using the INCLUDEDINCLUSIVENAMESPACE style.</li>\n"
0N/A + "</ul>\n" + "<h1>Output</h1>\n" + "<pre>\n";
0N/A
0N/A /** HTML Suffix * */
0N/A static final String HTMLSuffix = "</pre></body></html>";
0N/A
0N/A static final String HTMLExcludePrefix = "<span class=\"EXCLUDED\">";
0N/A
0N/A static final String HTMLExcludeSuffix = "</span>";
0N/A
0N/A static final String HTMLIncludePrefix = "<span class=\"INCLUDED\">";
0N/A
0N/A static final String HTMLIncludeSuffix = "</span>";
0N/A
0N/A static final String HTMLIncludedInclusiveNamespacePrefix = "<span class=\"INCLUDEDINCLUSIVENAMESPACE\">";
0N/A
0N/A static final String HTMLIncludedInclusiveNamespaceSuffix = "</span>";
0N/A
0N/A static final String HTMLExcludedInclusiveNamespacePrefix = "<span class=\"EXCLUDEDINCLUSIVENAMESPACE\">";
0N/A
0N/A static final String HTMLExcludedInclusiveNamespaceSuffix = "</span>";
0N/A
0N/A private static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
0N/A
0N/A private static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
0N/A
0N/A private static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
0N/A
0N/A static final AttrCompare ATTR_COMPARE = new AttrCompare();
0N/A
0N/A // J+
0N/A private XMLSignatureInputDebugger() {
0N/A // do nothing
0N/A }
0N/A
0N/A /**
0N/A * Constructor XMLSignatureInputDebugger
0N/A *
0N/A * @param xmlSignatureInput the signatur to pretty print
0N/A */
0N/A public XMLSignatureInputDebugger(
0N/A XMLSignatureInput xmlSignatureInput) {
0N/A
0N/A if (!xmlSignatureInput.isNodeSet()) {
0N/A this._xpathNodeSet = null;
0N/A } else {
0N/A this._xpathNodeSet = xmlSignatureInput._inputNodeSet;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Constructor XMLSignatureInputDebugger
0N/A *
0N/A * @param xmlSignatureInput the signatur to pretty print
0N/A * @param inclusiveNamespace
0N/A */
0N/A public XMLSignatureInputDebugger(
0N/A XMLSignatureInput xmlSignatureInput, Set inclusiveNamespace) {
0N/A
0N/A this(xmlSignatureInput);
0N/A
0N/A this._inclusiveNamespaces = inclusiveNamespace;
0N/A }
0N/A
0N/A /**
0N/A * Method getHTMLRepresentation
0N/A *
0N/A * @return The HTML Representation.
0N/A * @throws XMLSignatureException
0N/A */
0N/A public String getHTMLRepresentation() throws XMLSignatureException {
0N/A
0N/A if ((this._xpathNodeSet == null) || (this._xpathNodeSet.size() == 0)) {
0N/A return HTMLPrefix + "<blink>no node set, sorry</blink>"
0N/A + HTMLSuffix;
0N/A }
0N/A
0N/A {
0N/A
0N/A // get only a single node as anchor to fetch the owner document
0N/A Node n = (Node) this._xpathNodeSet.iterator().next();
0N/A
0N/A this._doc = XMLUtils.getOwnerDocument(n);
0N/A }
0N/A
0N/A try {
0N/A this._writer = new StringWriter();
0N/A
0N/A this.canonicalizeXPathNodeSet(this._doc);
0N/A this._writer.close();
0N/A
0N/A return this._writer.toString();
0N/A } catch (IOException ex) {
0N/A throw new XMLSignatureException("empty", ex);
0N/A } finally {
0N/A this._xpathNodeSet = null;
0N/A this._doc = null;
0N/A this._writer = null;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Method canonicalizeXPathNodeSet
0N/A *
0N/A * @param currentNode
0N/A * @throws XMLSignatureException
0N/A * @throws IOException
0N/A */
0N/A private void canonicalizeXPathNodeSet(Node currentNode)
0N/A throws XMLSignatureException, IOException {
0N/A
0N/A int currentNodeType = currentNode.getNodeType();
0N/A switch (currentNodeType) {
0N/A
0N/A case Node.DOCUMENT_TYPE_NODE:
0N/A default:
0N/A break;
0N/A
0N/A case Node.ENTITY_NODE:
0N/A case Node.NOTATION_NODE:
0N/A case Node.DOCUMENT_FRAGMENT_NODE:
0N/A case Node.ATTRIBUTE_NODE:
0N/A throw new XMLSignatureException("empty");
0N/A case Node.DOCUMENT_NODE:
0N/A this._writer.write(HTMLPrefix);
0N/A
0N/A for (Node currentChild = currentNode.getFirstChild(); currentChild != null; currentChild = currentChild
0N/A .getNextSibling()) {
0N/A this.canonicalizeXPathNodeSet(currentChild);
0N/A }
0N/A
0N/A this._writer.write(HTMLSuffix);
0N/A break;
0N/A
0N/A case Node.COMMENT_NODE:
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A int position = getPositionRelativeToDocumentElement(currentNode);
0N/A
0N/A if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
0N/A this._writer.write("\n");
0N/A }
0N/A
0N/A this.outputCommentToWriter((Comment) currentNode);
0N/A
0N/A if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
0N/A this._writer.write("\n");
0N/A }
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A break;
0N/A
0N/A case Node.PROCESSING_INSTRUCTION_NODE:
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A position = getPositionRelativeToDocumentElement(currentNode);
0N/A
0N/A if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
0N/A this._writer.write("\n");
0N/A }
0N/A
0N/A this.outputPItoWriter((ProcessingInstruction) currentNode);
0N/A
0N/A if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
0N/A this._writer.write("\n");
0N/A }
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A break;
0N/A
0N/A case Node.TEXT_NODE:
0N/A case Node.CDATA_SECTION_NODE:
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A outputTextToWriter(currentNode.getNodeValue());
0N/A
0N/A for (Node nextSibling = currentNode.getNextSibling(); (nextSibling != null)
0N/A && ((nextSibling.getNodeType() == Node.TEXT_NODE) || (nextSibling
0N/A .getNodeType() == Node.CDATA_SECTION_NODE)); nextSibling = nextSibling
0N/A .getNextSibling()) {
0N/A
0N/A /*
0N/A * The XPath data model allows to select only the first of a
0N/A * sequence of mixed text and CDATA nodes. But we must output
0N/A * them all, so we must search:
0N/A *
0N/A * @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329
0N/A */
0N/A this.outputTextToWriter(nextSibling.getNodeValue());
0N/A }
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A break;
0N/A
0N/A case Node.ELEMENT_NODE:
0N/A Element currentElement = (Element) currentNode;
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A this._writer.write("&lt;");
0N/A this._writer.write(currentElement.getTagName());
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A
0N/A // we output all Attrs which are available
0N/A NamedNodeMap attrs = currentElement.getAttributes();
0N/A int attrsLength = attrs.getLength();
0N/A Object attrs2[] = new Object[attrsLength];
0N/A
0N/A for (int i = 0; i < attrsLength; i++) {
0N/A attrs2[i] = attrs.item(i);
0N/A }
0N/A
0N/A Arrays.sort(attrs2, ATTR_COMPARE);
0N/A Object attrs3[] = attrs2;
0N/A
0N/A for (int i = 0; i < attrsLength; i++) {
0N/A Attr a = (Attr) attrs3[i];
0N/A boolean included = this._xpathNodeSet.contains(a);
0N/A boolean inclusive = this._inclusiveNamespaces.contains(a
0N/A .getName());
0N/A
0N/A if (included) {
0N/A if (inclusive) {
0N/A
0N/A // included and inclusive
0N/A this._writer
0N/A .write(HTMLIncludedInclusiveNamespacePrefix);
0N/A } else {
0N/A
0N/A // included and not inclusive
0N/A this._writer.write(HTMLIncludePrefix);
0N/A }
0N/A } else {
0N/A if (inclusive) {
0N/A
0N/A // excluded and inclusive
0N/A this._writer
0N/A .write(HTMLExcludedInclusiveNamespacePrefix);
0N/A } else {
0N/A
0N/A // excluded and not inclusive
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A }
0N/A
0N/A this.outputAttrToWriter(a.getNodeName(), a.getNodeValue());
0N/A
0N/A if (included) {
0N/A if (inclusive) {
0N/A
0N/A // included and inclusive
0N/A this._writer
0N/A .write(HTMLIncludedInclusiveNamespaceSuffix);
0N/A } else {
0N/A
0N/A // included and not inclusive
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A }
0N/A } else {
0N/A if (inclusive) {
0N/A
0N/A // excluded and inclusive
0N/A this._writer
0N/A .write(HTMLExcludedInclusiveNamespaceSuffix);
0N/A } else {
0N/A
0N/A // excluded and not inclusive
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A this._writer.write("&gt;");
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A
0N/A // traversal
0N/A for (Node currentChild = currentNode.getFirstChild(); currentChild != null; currentChild = currentChild
0N/A .getNextSibling()) {
0N/A this.canonicalizeXPathNodeSet(currentChild);
0N/A }
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludePrefix);
0N/A } else {
0N/A this._writer.write(HTMLExcludePrefix);
0N/A }
0N/A
0N/A this._writer.write("&lt;/");
0N/A this._writer.write(currentElement.getTagName());
0N/A this._writer.write("&gt;");
0N/A
0N/A if (this._xpathNodeSet.contains(currentNode)) {
0N/A this._writer.write(HTMLIncludeSuffix);
0N/A } else {
0N/A this._writer.write(HTMLExcludeSuffix);
0N/A }
0N/A break;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Checks whether a Comment or ProcessingInstruction is before or after the
0N/A * document element. This is needed for prepending or appending "\n"s.
0N/A *
0N/A * @param currentNode
0N/A * comment or pi to check
0N/A * @return NODE_BEFORE_DOCUMENT_ELEMENT,
0N/A * NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or
0N/A * NODE_AFTER_DOCUMENT_ELEMENT
0N/A * @see #NODE_BEFORE_DOCUMENT_ELEMENT
0N/A * @see #NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
0N/A * @see #NODE_AFTER_DOCUMENT_ELEMENT
0N/A */
0N/A private int getPositionRelativeToDocumentElement(Node currentNode) {
0N/A
0N/A if (currentNode == null) {
0N/A return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
0N/A }
0N/A
0N/A Document doc = currentNode.getOwnerDocument();
0N/A
0N/A if (currentNode.getParentNode() != doc) {
0N/A return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
0N/A }
0N/A
0N/A Element documentElement = doc.getDocumentElement();
0N/A
0N/A if (documentElement == null) {
0N/A return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
0N/A }
0N/A
0N/A if (documentElement == currentNode) {
0N/A return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
0N/A }
0N/A
0N/A for (Node x = currentNode; x != null; x = x.getNextSibling()) {
0N/A if (x == documentElement) {
0N/A return NODE_BEFORE_DOCUMENT_ELEMENT;
0N/A }
0N/A }
0N/A
0N/A return NODE_AFTER_DOCUMENT_ELEMENT;
0N/A }
0N/A
0N/A /**
0N/A * Normalizes an {@link Attr}ibute value
0N/A *
0N/A * The string value of the node is modified by replacing
0N/A * <UL>
0N/A * <LI>all ampersands (&) with <CODE>&amp;amp;</CODE></LI>
0N/A * <LI>all open angle brackets (<) with <CODE>&amp;lt;</CODE></LI>
0N/A * <LI>all quotation mark characters with <CODE>&amp;quot;</CODE></LI>
0N/A * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD,
0N/A * with character references. The character references are written in
0N/A * uppercase hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE>
0N/A * is represented by the character reference <CODE>&amp;#xD;</CODE>)</LI>
0N/A * </UL>
0N/A *
0N/A * @param name
0N/A * @param value
0N/A * @throws IOException
0N/A */
0N/A private void outputAttrToWriter(String name, String value)
0N/A throws IOException {
0N/A
0N/A this._writer.write(" ");
0N/A this._writer.write(name);
0N/A this._writer.write("=\"");
0N/A
0N/A int length = value.length();
0N/A
0N/A for (int i = 0; i < length; i++) {
0N/A char c = value.charAt(i);
0N/A
0N/A switch (c) {
0N/A
0N/A case '&':
0N/A this._writer.write("&amp;amp;");
0N/A break;
0N/A
0N/A case '<':
0N/A this._writer.write("&amp;lt;");
0N/A break;
0N/A
0N/A case '"':
0N/A this._writer.write("&amp;quot;");
0N/A break;
0N/A
0N/A case 0x09: // '\t'
0N/A this._writer.write("&amp;#x9;");
0N/A break;
0N/A
0N/A case 0x0A: // '\n'
0N/A this._writer.write("&amp;#xA;");
0N/A break;
0N/A
0N/A case 0x0D: // '\r'
0N/A this._writer.write("&amp;#xD;");
0N/A break;
0N/A
0N/A default:
0N/A this._writer.write(c);
0N/A break;
0N/A }
0N/A }
0N/A
0N/A this._writer.write("\"");
0N/A }
0N/A
0N/A /**
0N/A * Normalizes a {@link org.w3c.dom.Comment} value
0N/A *
0N/A * @param currentPI
0N/A * @throws IOException
0N/A */
0N/A private void outputPItoWriter(ProcessingInstruction currentPI)
0N/A throws IOException {
0N/A
0N/A if (currentPI == null) {
0N/A return;
0N/A }
0N/A
0N/A this._writer.write("&lt;?");
0N/A
0N/A String target = currentPI.getTarget();
0N/A int length = target.length();
0N/A
0N/A for (int i = 0; i < length; i++) {
0N/A char c = target.charAt(i);
0N/A
0N/A switch (c) {
0N/A
0N/A case 0x0D:
0N/A this._writer.write("&amp;#xD;");
0N/A break;
0N/A
0N/A case ' ':
0N/A this._writer.write("&middot;");
0N/A break;
0N/A
0N/A case '\n':
0N/A this._writer.write("&para;\n");
0N/A break;
0N/A
0N/A default:
0N/A this._writer.write(c);
0N/A break;
0N/A }
0N/A }
0N/A
0N/A String data = currentPI.getData();
0N/A
0N/A length = data.length();
0N/A
661N/A if (length > 0) {
661N/A this._writer.write(" ");
0N/A
661N/A for (int i = 0; i < length; i++) {
661N/A char c = data.charAt(i);
0N/A
661N/A switch (c) {
0N/A
661N/A case 0x0D:
661N/A this._writer.write("&amp;#xD;");
661N/A break;
0N/A
661N/A default:
661N/A this._writer.write(c);
661N/A break;
0N/A }
661N/A }
0N/A }
0N/A
0N/A this._writer.write("?&gt;");
0N/A }
0N/A
0N/A /**
0N/A * Method outputCommentToWriter
0N/A *
0N/A * @param currentComment
0N/A * @throws IOException
0N/A */
0N/A private void outputCommentToWriter(Comment currentComment)
0N/A throws IOException {
0N/A
0N/A if (currentComment == null) {
0N/A return;
0N/A }
0N/A
0N/A this._writer.write("&lt;!--");
0N/A
0N/A String data = currentComment.getData();
0N/A int length = data.length();
0N/A
0N/A for (int i = 0; i < length; i++) {
0N/A char c = data.charAt(i);
0N/A
0N/A switch (c) {
0N/A
0N/A case 0x0D:
0N/A this._writer.write("&amp;#xD;");
0N/A break;
0N/A
0N/A case ' ':
0N/A this._writer.write("&middot;");
0N/A break;
0N/A
0N/A case '\n':
0N/A this._writer.write("&para;\n");
0N/A break;
0N/A
0N/A default:
0N/A this._writer.write(c);
0N/A break;
0N/A }
0N/A }
0N/A
0N/A this._writer.write("--&gt;");
0N/A }
0N/A
0N/A /**
0N/A * Method outputTextToWriter
0N/A *
0N/A * @param text
0N/A * @throws IOException
0N/A */
0N/A private void outputTextToWriter(String text) throws IOException {
0N/A
0N/A if (text == null) {
0N/A return;
0N/A }
0N/A
0N/A int length = text.length();
0N/A
0N/A for (int i = 0; i < length; i++) {
0N/A char c = text.charAt(i);
0N/A
0N/A switch (c) {
0N/A
0N/A case '&':
0N/A this._writer.write("&amp;amp;");
0N/A break;
0N/A
0N/A case '<':
0N/A this._writer.write("&amp;lt;");
0N/A break;
0N/A
0N/A case '>':
0N/A this._writer.write("&amp;gt;");
0N/A break;
0N/A
0N/A case 0xD:
0N/A this._writer.write("&amp;#xD;");
0N/A break;
0N/A
0N/A case ' ':
0N/A this._writer.write("&middot;");
0N/A break;
0N/A
0N/A case '\n':
0N/A this._writer.write("&para;\n");
0N/A break;
0N/A
0N/A default:
0N/A this._writer.write(c);
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A}