Clover coverage report - JFCUnit Test Coverage
Coverage timestamp: Mon Dec 20 2004 23:38:10 MST
file stats: LOC: 575   Methods: 19
NCLOC: 270   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XMLWriter.java 62% 45.3% 57.9% 49.8%
coverage coverage
 1   
 /*
 2   
  * This XML writer was adapted from the Apache sample software, and
 3   
  * has undergone the following corrections:
 4   
  * 1. XML comments are now preserved.
 5   
  * 2. main method has been removed.
 6   
  * 3. the package has been changed.
 7   
  */
 8   
 /*
 9   
  * The Apache Software License, Version 1.1
 10   
  *
 11   
  *
 12   
  * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 13   
  * reserved.
 14   
  *
 15   
  * Redistribution and use in source and binary forms, with or without
 16   
  * modification, are permitted provided that the following conditions
 17   
  * are met:
 18   
  *
 19   
  * 1. Redistributions of source code must retain the above copyright
 20   
  *    notice, this list of conditions and the following disclaimer.
 21   
  *
 22   
  * 2. Redistributions in binary form must reproduce the above copyright
 23   
  *    notice, this list of conditions and the following disclaimer in
 24   
  *    the documentation and/or other materials provided with the
 25   
  *    distribution.
 26   
  *
 27   
  * 3. The end-user documentation included with the redistribution,
 28   
  *    if any, must include the following acknowledgment:
 29   
  *       "This product includes software developed by the
 30   
  *        Apache Software Foundation (http://www.apache.org/)."
 31   
  *    Alternately, this acknowledgment may appear in the software itself,
 32   
  *    if and wherever such third-party acknowledgments normally appear.
 33   
  *
 34   
  * 4. The names "Xerces" and "Apache Software Foundation" must
 35   
  *    not be used to endorse or promote products derived from this
 36   
  *    software without prior written permission. For written
 37   
  *    permission, please contact apache@apache.org.
 38   
  *
 39   
  * 5. Products derived from this software may not be called "Apache",
 40   
  *    nor may "Apache" appear in their name, without prior written
 41   
  *    permission of the Apache Software Foundation.
 42   
  *
 43   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 44   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 45   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 46   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 47   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 48   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 49   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 50   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 51   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 52   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 53   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 54   
  * SUCH DAMAGE.
 55   
  * ====================================================================
 56   
  *
 57   
  * This software consists of voluntary contributions made by many
 58   
  * individuals on behalf of the Apache Software Foundation and was
 59   
  * originally based on software copyright (c) 1999, International
 60   
  * Business Machines, Inc., http://www.apache.org.  For more
 61   
  * information on the Apache Software Foundation, please see
 62   
  * <http://www.apache.org/>.
 63   
  */
 64   
 package junit.extensions.xml;
 65   
 
 66   
 import org.w3c.dom.Attr;
 67   
 import org.w3c.dom.Document;
 68   
 import org.w3c.dom.DocumentType;
 69   
 import org.w3c.dom.NamedNodeMap;
 70   
 import org.w3c.dom.Node;
 71   
 import org.w3c.dom.NodeList;
 72   
 
 73   
 import java.io.OutputStream;
 74   
 import java.io.OutputStreamWriter;
 75   
 import java.io.PrintWriter;
 76   
 import java.io.UnsupportedEncodingException;
 77   
 import java.io.Writer;
 78   
 
 79   
 
 80   
 /**
 81   
  * A sample DOM writer. This sample program illustrates how to
 82   
  * traverse a DOM tree in order to print a document that is parsed.
 83   
  *
 84   
  * @author Andy Clark, IBM
 85   
  *
 86   
  * @version $Id: XMLWriter.java,v 1.3 2004/12/20 20:33:19 kwilson227 Exp $
 87   
  */
 88   
 public class XMLWriter {
 89   
     //
 90   
     // Constants
 91   
     //
 92   
     // feature ids
 93   
 
 94   
     /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
 95   
     protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
 96   
 
 97   
     /**
 98   
      * Validation feature id
 99   
      * (http://xml.org/sax/features/validation).
 100   
      */
 101   
     protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
 102   
 
 103   
     /**
 104   
      * Schema validation feature id
 105   
      * (http://apache.org/xml/features/validation/schema).
 106   
      */
 107   
     protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
 108   
 
 109   
     /**
 110   
      * Schema full checking feature id
 111   
      * (http://apache.org/xml/features/validation/schema-full-checking).
 112   
      */
 113   
     protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
 114   
 
 115   
     /**
 116   
      * Lexical handler property id
 117   
      * (http://xml.org/sax/properties/lexical-handler).
 118   
      */
 119   
     protected static final String LEXICAL_HANDLER_PROPERTY_ID = "http://xml.org/sax/properties/lexical-handler";
 120   
 
 121   
     /** Default parser name. */
 122   
     protected static final String DEFAULT_PARSER_NAME = "dom.wrappers.Xerces";
 123   
 
 124   
     /** Default namespaces support (true). */
 125   
     protected static final boolean DEFAULT_NAMESPACES = true;
 126   
 
 127   
     /** Default validation support (false). */
 128   
     protected static final boolean DEFAULT_VALIDATION = false;
 129   
 
 130   
     /** Default Schema validation support (false). */
 131   
     protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
 132   
 
 133   
     /** Default Schema full checking support (false). */
 134   
     protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
 135   
 
 136   
     /** Default canonical output (false). */
 137   
     protected static final boolean DEFAULT_CANONICAL = false;
 138   
 
 139   
     //
 140   
     // Data
 141   
     //
 142   
 
 143   
     /** Print writer. */
 144   
     private PrintWriter m_fOut;
 145   
 
 146   
     /** Canonical output. */
 147   
     private boolean m_fCanonical;
 148   
 
 149   
     //
 150   
     // Constructors
 151   
     //
 152   
 
 153   
     /** Default constructor. */
 154  2
     public XMLWriter() {
 155   
     }
 156   
 
 157   
     // <init>()
 158   
 
 159   
     /**
 160   
      * Write the XML file in cannonical form.
 161   
      * @param canonical true if the file is to be written in cannonical form
 162   
      */
 163  12
     public XMLWriter(final boolean canonical) {
 164  12
         m_fCanonical = canonical;
 165   
     }
 166   
 
 167   
     /**
 168   
      * set canonical form of writting.
 169   
      * @param canonical true if canonical.
 170   
      */
 171  1
     public void setCanonical(final boolean canonical) {
 172  1
         m_fCanonical = canonical;
 173   
     }
 174   
 
 175   
     /**
 176   
      * Get the canonical state of the writer.
 177   
      * @return true if the canonical state is set.
 178   
      */
 179  0
     public boolean getCanonical() {
 180  0
         return m_fCanonical;
 181   
     }
 182   
 
 183   
     /**
 184   
      * Sets the output writer.
 185   
      * @param writer The writer to be used.
 186   
      **/
 187  14
     public void setOutput(final Writer writer) {
 188  14
         if (writer instanceof PrintWriter) {
 189  2
             m_fOut = (PrintWriter) writer;
 190   
         } else {
 191  12
             m_fOut = new PrintWriter(writer);
 192   
         }
 193   
     }
 194   
 
 195   
     // setOutput(java.io.Writer)
 196   
 
 197   
     /**
 198   
      * Sets the output stream for printing.
 199   
      * @param stream The output stream the XML will be written to.
 200   
      * @param encoding The encoding to be used for the output stream.
 201   
      * @throws UnsupportedEncodingException if the encoding passed is
 202   
      * not supported.
 203   
      **/
 204  12
     public void setOutput(final OutputStream stream, final String encoding)
 205   
         throws UnsupportedEncodingException {
 206  12
         String enc = encoding;
 207   
 
 208  12
         if (enc == null) {
 209  3
             enc = "UTF8";
 210   
         }
 211   
 
 212  12
         java.io.Writer writer = new OutputStreamWriter(stream, enc);
 213  12
         setOutput(writer);
 214   
     }
 215   
 
 216   
     // setOutput(OutputStream,String)
 217   
 
 218   
     /**
 219   
      * Writes the specified node, recursively.
 220   
      * @param node Node to be written.
 221   
      **/
 222  55
     public void write(final Node node) {
 223   
         // is there anything to do?
 224  55
         if (node == null) {
 225  11
             return;
 226   
         }
 227   
 
 228  44
         short type = node.getNodeType();
 229   
 
 230  44
         switch (type) {
 231  12
         case Node.DOCUMENT_NODE:
 232  12
             processDocument(node);
 233   
 
 234  12
             break;
 235   
 
 236  0
         case Node.DOCUMENT_TYPE_NODE:
 237  0
             processDocumentType(node);
 238   
 
 239  0
             break;
 240   
 
 241  32
         case Node.ELEMENT_NODE:
 242  32
             processElement(type, node);
 243   
 
 244  32
             break;
 245   
 
 246  0
         case Node.ENTITY_REFERENCE_NODE:
 247  0
             processEntityRef(node);
 248   
 
 249  0
             break;
 250   
 
 251  0
         case Node.CDATA_SECTION_NODE:
 252  0
             processCData(node);
 253   
 
 254  0
             break;
 255   
 
 256  0
         case Node.TEXT_NODE:
 257  0
             processText(node);
 258   
 
 259  0
             break;
 260   
 
 261  0
         case Node.COMMENT_NODE:
 262  0
             processComment(node);
 263   
 
 264  0
             break;
 265   
 
 266  0
         case Node.PROCESSING_INSTRUCTION_NODE:
 267  0
             processInstructions(node);
 268   
 
 269  0
             break;
 270   
 
 271  0
         default:
 272  0
             processOther(node);
 273   
 
 274  0
             break;
 275   
         }
 276   
     }
 277   
 
 278   
     /**
 279   
      * Write the string after normalization.
 280   
      * @param s String to be normalized and printed.
 281   
      */
 282  34
     protected void normalizeAndPrint(final String s) {
 283  34
         int len = 0;
 284   
 
 285  34
         if (s != null) {
 286  34
             len = s.length();
 287   
         }
 288   
 
 289  34
         for (int i = 0; i < len; i++) {
 290  498
             char c = s.charAt(i);
 291  498
             normalizeAndPrint(c);
 292   
         }
 293   
     }
 294   
 
 295   
     // normalizeAndPrint(String)
 296   
 
 297   
     /**
 298   
      * Normalizes and print the given character.
 299   
      * Normalizing converts the special HTML characters to
 300   
      * there &..; mapping.
 301   
      *
 302   
      * @param c The character to be printed.
 303   
      **/
 304  498
     protected void normalizeAndPrint(final char c) {
 305  498
         switch (c) {
 306  0
         case '<':
 307  0
             m_fOut.print("&lt;");
 308   
 
 309  0
             break;
 310   
 
 311  0
         case '>':
 312  0
             m_fOut.print("&gt;");
 313   
 
 314  0
             break;
 315   
 
 316  0
         case '&':
 317  0
             m_fOut.print("&amp;");
 318   
 
 319  0
             break;
 320   
 
 321  0
         case '"':
 322  0
             m_fOut.print("&quot;");
 323   
 
 324  0
             break;
 325   
 
 326  0
         case '\r':
 327  0
         case '\n':
 328   
 
 329  0
             if (m_fCanonical) {
 330  0
                 m_fOut.print("&#");
 331  0
                 m_fOut.print(Integer.toString(c));
 332  0
                 m_fOut.print(';');
 333   
 
 334  0
                 break;
 335   
             }
 336   
 
 337  498
         default:
 338  498
             m_fOut.print(c);
 339   
         }
 340   
     }
 341   
 
 342   
     // normalizeAndPrint(char)
 343   
 
 344   
     /**
 345   
      * Returns a sorted list of attributes.
 346   
      * @param attrs The array of attributes to be sorted.
 347   
      * @return Attr[] The attrs in sorted order.
 348   
      **/
 349  33
     protected Attr[] sortAttributes(final NamedNodeMap attrs) {
 350  33
         int len = 0;
 351   
 
 352  33
         if (attrs != null) {
 353  33
             len = attrs.getLength();
 354   
         }
 355   
 
 356  33
         Attr[] array = new Attr[len];
 357   
 
 358  33
         for (int i = 0; i < len; i++) {
 359  38
             array[i] = (Attr) attrs.item(i);
 360   
         }
 361   
 
 362  33
         for (int i = 0; i < (len - 1); i++) {
 363  5
             String name  = array[i].getNodeName();
 364  5
             int    index = i;
 365   
 
 366  5
             for (int j = i + 1; j < len; j++) {
 367  6
                 String curName = array[j].getNodeName();
 368   
 
 369  6
                 if (curName.compareTo(name) < 0) {
 370  0
                     name      = curName;
 371  0
                     index     = j;
 372   
                 }
 373   
             }
 374   
 
 375  5
             if (index != i) {
 376  0
                 Attr temp = array[i];
 377  0
                 array[i]         = array[index];
 378  0
                 array[index]     = temp;
 379   
             }
 380   
         }
 381   
 
 382  33
         return array;
 383   
     }
 384   
 
 385   
     // sortAttributes(NamedNodeMap):Attr[]
 386   
 
 387   
     /**
 388   
      * Process CDATA nodes.
 389   
      * @param node Node to be processed.
 390   
      */
 391  0
     private void processCData(final Node node) {
 392  0
         if (m_fCanonical) {
 393  0
             normalizeAndPrint(node.getNodeValue());
 394   
         } else {
 395  0
             m_fOut.print("<![CDATA[");
 396  0
             m_fOut.print(node.getNodeValue());
 397  0
             m_fOut.print("]]>");
 398   
         }
 399   
 
 400  0
         m_fOut.flush();
 401   
     }
 402   
 
 403   
     /**
 404   
      * Process Comment Nodes.
 405   
      * @param node Node to be processed.
 406   
      */
 407  0
     private void processComment(final Node node) {
 408  0
         m_fOut.print("<!-- ");
 409  0
         m_fOut.print(node.getNodeValue());
 410  0
         m_fOut.print(" -->");
 411   
     }
 412   
 
 413   
     /**
 414   
      * Process Document Nodes.
 415   
      * @param node Node to be processed.
 416   
      */
 417  12
     private void processDocument(final Node node) {
 418  12
         Document document = (Document) node;
 419   
 
 420  12
         if (!m_fCanonical) {
 421  11
             m_fOut.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
 422  11
             m_fOut.flush();
 423  11
             write(document.getDoctype());
 424   
         }
 425   
 
 426  12
         NodeList list = document.getChildNodes();
 427   
 
 428  12
         for (int i = 0; i < list.getLength(); i++) {
 429  12
             write(list.item(i));
 430   
         }
 431   
     }
 432   
 
 433   
     /**
 434   
      * Process Document Type nodes.
 435   
      * @param node Node to be processed.
 436   
      */
 437  0
     private void processDocumentType(final Node node) {
 438  0
         DocumentType doctype = (DocumentType) node;
 439  0
         m_fOut.print("<!DOCTYPE ");
 440  0
         m_fOut.print(doctype.getName());
 441   
 
 442  0
         String publicId = doctype.getPublicId();
 443  0
         String systemId = doctype.getSystemId();
 444   
 
 445  0
         if (publicId != null) {
 446  0
             m_fOut.print(" PUBLIC '");
 447  0
             m_fOut.print(publicId);
 448  0
             m_fOut.print("' '");
 449  0
             m_fOut.print(systemId);
 450  0
             m_fOut.print('\'');
 451   
         } else {
 452  0
             m_fOut.print(" SYSTEM '");
 453  0
             m_fOut.print(systemId);
 454  0
             m_fOut.print('\'');
 455   
         }
 456   
 
 457  0
         String internalSubset = doctype.getInternalSubset();
 458   
 
 459  0
         if (internalSubset != null) {
 460  0
             m_fOut.println(" [");
 461  0
             m_fOut.print(internalSubset);
 462  0
             m_fOut.print(']');
 463   
         }
 464   
 
 465  0
         m_fOut.println('>');
 466   
     }
 467   
 
 468   
     /**
 469   
      * Process Element node.
 470   
      * @param type Type of the node.
 471   
      * @param node Node to be processed.
 472   
      */
 473  32
     private void processElement(final short type, final Node node) {
 474  32
         m_fOut.print('<');
 475  32
         m_fOut.print(node.getNodeName());
 476   
 
 477  32
         Attr[] attrs = sortAttributes(node.getAttributes());
 478   
 
 479  32
         for (int i = 0; i < attrs.length; i++) {
 480  35
             Attr   attr = attrs[i];
 481  35
             String name = attr.getNodeName();
 482   
 
 483  35
             if (!XMLConstants.JFCFILELOC.equals(name)) {
 484  34
                 m_fOut.print(' ');
 485  34
                 m_fOut.print(attr.getNodeName());
 486  34
                 m_fOut.print("=\"");
 487  34
                 normalizeAndPrint(attr.getNodeValue());
 488  34
                 m_fOut.print('"');
 489   
             }
 490   
         }
 491   
 
 492  32
         NodeList children = node.getChildNodes();
 493   
 
 494  32
         if (children.getLength() == 0) {
 495  17
             m_fOut.print("/>");
 496  17
             m_fOut.flush();
 497   
         } else {
 498  15
             m_fOut.print('>');
 499  15
             m_fOut.flush();
 500   
 
 501  15
             Node child = node.getFirstChild();
 502   
 
 503  15
             while (child != null) {
 504  18
                 write(child);
 505  18
                 child = child.getNextSibling();
 506   
             }
 507   
 
 508  15
             if (type == Node.ELEMENT_NODE) {
 509  15
                 m_fOut.print("</");
 510  15
                 m_fOut.print(node.getNodeName());
 511  15
                 m_fOut.print('>');
 512  15
                 m_fOut.flush();
 513   
             }
 514   
         }
 515   
     }
 516   
 
 517   
     /**
 518   
      * Process EntityRef nodes.
 519   
      * @param node Node to be processed.
 520   
      */
 521  0
     private void processEntityRef(final Node node) {
 522  0
         if (m_fCanonical) {
 523  0
             Node child = node.getFirstChild();
 524   
 
 525  0
             while (child != null) {
 526  0
                 write(child);
 527  0
                 child = child.getNextSibling();
 528   
             }
 529   
         } else {
 530  0
             m_fOut.print('&');
 531  0
             m_fOut.print(node.getNodeName());
 532  0
             m_fOut.print(';');
 533  0
             m_fOut.flush();
 534   
         }
 535   
     }
 536   
 
 537   
     /**
 538   
      * Process Instruction nodes.
 539   
      * @param node Node to be processed
 540   
      */
 541  0
     private void processInstructions(final Node node) {
 542  0
         m_fOut.print("<?");
 543  0
         m_fOut.print(node.getNodeName());
 544   
 
 545  0
         String data = node.getNodeValue();
 546   
 
 547  0
         if ((data != null) && (data.length() > 0)) {
 548  0
             m_fOut.print(' ');
 549  0
             m_fOut.print(data);
 550   
         }
 551   
 
 552  0
         m_fOut.println("?>");
 553  0
         m_fOut.flush();
 554   
     }
 555   
 
 556   
     /**
 557   
      * Process nodes which are not handled any other way.
 558   
      * @param node Node to be processed.
 559   
      */
 560  0
     private void processOther(final Node node) {
 561   
     }
 562   
 
 563   
     /**
 564   
      * Process Text nodes.
 565   
      * @param node Node to be processed.
 566   
      */
 567  0
     private void processText(final Node node) {
 568  0
         normalizeAndPrint(node.getNodeValue());
 569  0
         m_fOut.flush();
 570   
     }
 571   
 }
 572   
 
 573   
 
 574   
 // class Writer
 575