Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 348   Methods: 11
NCLOC: 219   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Xml2HtmlWriter.java 0% 0% 0% 0%
coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: Xml2HtmlWriter.java 705952 2008-10-19 02:37:42Z natalia $
 18    */
 19   
 20    package org.apache.xindice.xml;
 21   
 22   
 23    import org.w3c.dom.Node;
 24    import org.w3c.dom.DOMException;
 25    import org.w3c.dom.Element;
 26    import org.w3c.dom.NamedNodeMap;
 27    import org.w3c.dom.Attr;
 28    import org.w3c.dom.ProcessingInstruction;
 29    import org.w3c.dom.NodeList;
 30    import org.apache.commons.logging.LogFactory;
 31    import org.apache.commons.logging.Log;
 32    import org.apache.xindice.util.StringUtilities;
 33    import org.apache.xindice.util.XMLUtilities;
 34   
 35    import java.io.BufferedWriter;
 36    import java.io.IOException;
 37    import java.io.OutputStream;
 38    import java.io.OutputStreamWriter;
 39    import java.io.StringWriter;
 40    import java.io.UnsupportedEncodingException;
 41    import java.io.Writer;
 42   
 43    /**
 44    * Xml2HtmlWriter takes a Document, DocumentFragment, or Element and
 45    * streams it as html to an output source (or a String).
 46    * <p/>
 47    * a css stylesheet should define these classes:
 48    * xml-misc, xml-element-name, xml-attribute-name, xml-attribute-content,
 49    * xml-element-content, xml-comment, xml-processing, xml-cdata
 50    *
 51    * @author <a href="mailto:jmetzner@apache.org">Jan Metzner</a>
 52    * @version $Id: Xml2HtmlWriter.java 705952 2008-10-19 02:37:42Z natalia $
 53    */
 54    public class Xml2HtmlWriter {
 55   
 56    private static final String indent = "&nbsp;&nbsp;";
 57    private Node node = null;
 58    private static final Log log = LogFactory.getLog(Xml2HtmlWriter.class);
 59   
 60  0 public Xml2HtmlWriter(Node node) throws DOMException {
 61  0 this.node = node;
 62    }
 63   
 64    /**
 65    * write writes the node to the writer as text.
 66    *
 67    * @param writer The Writer to write to
 68    */
 69  0 public void write(Writer writer) throws IOException {
 70  0 write(node, writer);
 71    }
 72   
 73    /**
 74    * write writes the node to the OutputStream as text.
 75    *
 76    * @param output The OutputStream to write to
 77    */
 78  0 public void write(OutputStream output) throws IOException {
 79  0 write(node, output);
 80    }
 81   
 82    /**
 83    * toString returns the node as a String.
 84    *
 85    * @return The String value
 86    */
 87  0 public String toString() {
 88  0 return toString(node);
 89    }
 90   
 91    /**
 92    * writes the Node to the writer.
 93    *
 94    * @param writer The Writer to write to.
 95    * @param node The Node to write.
 96    * @param currentIndent the current indent.
 97    * @throws IOException while writing to the writer.
 98    */
 99  0 private static void writeNode(Writer writer, Node node, int currentIndent) throws IOException {
 100  0 short type = node.getNodeType();
 101   
 102  0 switch (type) {
 103  0 case Node.DOCUMENT_NODE: {
 104  0 writeIndent(writer, currentIndent);
 105  0 writer.write("<span class=\"xml-processing\">&lt;?xml ");
 106  0 writer.write(" version=\"1.0\"?&gt;</span><br />\n");
 107  0 currentIndent--;
 108  0 writeChildren(writer, node, currentIndent);
 109  0 break;
 110    }
 111   
 112  0 case Node.DOCUMENT_FRAGMENT_NODE: {
 113  0 writeChildren(writer, node, currentIndent);
 114  0 break;
 115    }
 116   
 117  0 case Node.DOCUMENT_TYPE_NODE: {
 118  0 break;
 119    }
 120   
 121  0 case Node.ELEMENT_NODE: {
 122  0 Element e = (Element) node;
 123  0 String n = e.getTagName();
 124   
 125  0 writeIndent(writer, currentIndent);
 126  0 writer.write("<span class=\"xml-misc\">&lt;</span>");
 127  0 writer.write("<span class=\"xml-element-name\">");
 128  0 writer.write(n);
 129  0 writer.write("</span>");
 130   
 131  0 NamedNodeMap a = e.getAttributes();
 132  0 int size = a.getLength();
 133  0 for (int i = 0; i < size; i++) {
 134  0 Attr att = (Attr) a.item(i);
 135  0 writer.write(' ');
 136  0 writeNode(writer, att, currentIndent);
 137    }
 138   
 139  0 if (e.hasChildNodes()) {
 140  0 writer.write("<span class=\"xml-misc\">&gt;</span><br />\n");
 141  0 writeChildren(writer, node, currentIndent);
 142  0 writeIndent(writer, currentIndent);
 143  0 writer.write("<span class=\"xml-misc\">&lt;/</span>");
 144  0 writer.write("<span class=\"xml-element-name\">");
 145  0 writer.write(n);
 146  0 writer.write("</span><span class=\"xml-misc\">&gt;</span><br />\n");
 147    } else {
 148  0 writer.write("<span class=\"xml-misc\"> /&gt;</span><br />\n");
 149    }
 150  0 break;
 151    }
 152   
 153  0 case Node.ATTRIBUTE_NODE: {
 154  0 Attr a = (Attr) node;
 155  0 writer.write("<span class=\"xml-attribute-name\">");
 156  0 writer.write(a.getName());
 157  0 writer.write("</span><span class=\"xml-misc\">=\"</span>");
 158  0 writer.write("<span class=\"xml-attribute-content\">");
 159  0 writeEscapedText(writer, XMLUtilities.escape(a.getValue()), currentIndent);
 160  0 writer.write("</span><span class=\"xml-misc\">\"</span>");
 161  0 break;
 162    }
 163   
 164  0 case Node.ENTITY_REFERENCE_NODE: {
 165  0 break;
 166    }
 167   
 168  0 case Node.ENTITY_NODE: {
 169  0 break;
 170    }
 171   
 172  0 case Node.NOTATION_NODE: {
 173  0 break;
 174    }
 175   
 176  0 case Node.PROCESSING_INSTRUCTION_NODE: {
 177  0 ProcessingInstruction pi = (ProcessingInstruction) node;
 178  0 writeIndent(writer, currentIndent);
 179  0 writer.write("<span class=\"xml-processing\">&lt;?");
 180  0 writer.write(pi.getTarget());
 181  0 writer.write(" ");
 182  0 writer.write(pi.getData());
 183  0 writer.write("?&gt;</span><br />\n");
 184  0 break;
 185    }
 186   
 187  0 case Node.TEXT_NODE: {
 188  0 if (!StringUtilities.isBlank(node.getNodeValue())) {
 189  0 writeIndent(writer, currentIndent);
 190  0 writer.write("<span class=\"xml-element-content\">");
 191  0 writeEscapedText(writer, XMLUtilities.escape(node.getNodeValue().trim()), currentIndent);
 192  0 writer.write("</span><br />");
 193    }
 194  0 break;
 195    }
 196   
 197  0 case Node.CDATA_SECTION_NODE: {
 198  0 writeIndent(writer, currentIndent);
 199  0 writer.write("<span class=\"xml-cdata\">&lt;![CDATA[");
 200  0 writeEscapedText(writer, node.getNodeValue(), currentIndent);
 201  0 writer.write("]]&gt;</span><br />");
 202  0 break;
 203    }
 204   
 205  0 case Node.COMMENT_NODE: {
 206  0 writeIndent(writer, currentIndent);
 207  0 writer.write("<span class=\"xml-comment\">&lt;!--");
 208  0 writeEscapedText(writer, node.getNodeValue(), currentIndent);
 209  0 writer.write("--&gt;</span><br />");
 210  0 break;
 211    }
 212    }
 213    }
 214   
 215    /**
 216    * writes the children nodes for the given node.
 217    *
 218    * @param writer The Writer to write to.
 219    * @param node The Parent Node.
 220    * @param currentIndent The current Indent.
 221    * @throws IOException while writing to the writer.
 222    */
 223  0 private static void writeChildren(Writer writer, Node node, int currentIndent) throws IOException {
 224  0 NodeList l = node.getChildNodes();
 225  0 int size = l.getLength();
 226  0 currentIndent++;
 227  0 for (int i = 0; i < size; i++) {
 228  0 writeNode(writer, l.item(i), currentIndent);
 229    }
 230    }
 231   
 232    /**
 233    * writes the text as escaped html.
 234    *
 235    * @param writer The Writer to write to.
 236    * @param text The text to write.
 237    * @param currentIndent The current Indent.
 238    * @throws IOException
 239    */
 240  0 private static void writeEscapedText(Writer writer, String text, int currentIndent) throws IOException {
 241  0 char[] value = text.toCharArray();
 242  0 String outval = null;
 243  0 int start = 0;
 244  0 int len = 0;
 245  0 for (int i = 0; i < value.length; i++) {
 246  0 switch (value[i]) {
 247  0 case '&':
 248  0 outval = "&amp;";
 249  0 break;
 250  0 case '\'':
 251  0 outval = "&apos;";
 252  0 break;
 253  0 case '\"':
 254  0 outval = "&quot;";
 255  0 break;
 256  0 case '<':
 257  0 outval = "&lt;";
 258  0 break;
 259  0 case '>' :
 260  0 outval = "&gt;";
 261  0 break;
 262  0 case '\n':
 263    //writer.write("<br />");
 264    //writeIndent(writer, currentIndent);
 265  0 outval = "<br />";
 266  0 for (int i1 = 0; i1 < currentIndent; i1++) {
 267  0 outval += indent;
 268    }
 269  0 break;
 270  0 default:
 271  0 len++;
 272  0 break;
 273    }
 274   
 275  0 if (outval != null) {
 276  0 if (len > 0) {
 277  0 writer.write(value, start, len);
 278    }
 279  0 writer.write(outval);
 280  0 start = i + 1;
 281  0 len = 0;
 282  0 outval = null;
 283    }
 284    }
 285  0 if (len > 0) {
 286  0 writer.write(value, start, len);
 287    }
 288    }
 289   
 290    /**
 291    * writes the indent to the writer.
 292    *
 293    * @param writer The Writer to write to.
 294    * @param currentIndent The current Indent.
 295    * @throws IOException
 296    */
 297  0 private static void writeIndent(Writer writer, int currentIndent)
 298    throws IOException {
 299  0 for (int i = 0; i < currentIndent; i++) {
 300  0 writer.write(indent);
 301    }
 302    }
 303   
 304    /**
 305    * write writes the specified node to the writer as text.
 306    *
 307    * @param node The Node to write.
 308    * @param writer The Writer to write to.
 309    */
 310  0 public static void write(Node node, Writer writer) throws IOException {
 311  0 BufferedWriter buf = new BufferedWriter(writer, 4096);
 312  0 writeNode(buf, node, 0);
 313  0 buf.flush();
 314    }
 315   
 316    /**
 317    * write writes the specified node to the OutputStream as text.
 318    *
 319    * @param node The Node to write.
 320    * @param output The OutputStream to write to.
 321    */
 322  0 public static void write(Node node, OutputStream output) throws IOException {
 323  0 try {
 324  0 OutputStreamWriter o = new OutputStreamWriter(output, "utf-8");
 325  0 write(node, o);
 326    } catch (UnsupportedEncodingException e) {
 327  0 log.error(e); //won't happen
 328    }
 329    }
 330   
 331    /**
 332    * toString returns the node as a String.
 333    *
 334    * @param node The Node to convert
 335    * @return The String value
 336    */
 337  0 public static String toString(Node node) {
 338  0 StringWriter sw = new StringWriter();
 339  0 try {
 340  0 write(node, sw);
 341  0 return sw.toString();
 342    } catch (IOException e) {
 343  0 log.error(e);
 344  0 return null;
 345    }
 346    }
 347   
 348    }