Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 252   Methods: 7
NCLOC: 129   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
DOMUtil.java 25% 38.8% 14.3% 33.3%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant.taskdefs.optional.junit;
 55   
 
 56   
 import java.util.Vector;
 57   
 import org.w3c.dom.Attr;
 58   
 import org.w3c.dom.CDATASection;
 59   
 import org.w3c.dom.Comment;
 60   
 import org.w3c.dom.DOMException;
 61   
 import org.w3c.dom.Document;
 62   
 import org.w3c.dom.Element;
 63   
 import org.w3c.dom.NamedNodeMap;
 64   
 import org.w3c.dom.Node;
 65   
 import org.w3c.dom.NodeList;
 66   
 import org.w3c.dom.ProcessingInstruction;
 67   
 import org.w3c.dom.Text;
 68   
 
 69   
 /**
 70   
  * Some utilities that might be useful when manipulating DOM trees.
 71   
  *
 72   
  * @author <a href="bailliez@noos.fr">Stephane Bailliez</a>
 73   
  */
 74   
 public final class DOMUtil {
 75   
 
 76   
     /** unused constructor */
 77  0
     private DOMUtil(){
 78   
     }
 79   
 
 80   
     /**
 81   
      * Filter interface to be applied when iterating over a DOM tree.
 82   
      * Just think of it like a <tt>FileFilter</tt> clone.
 83   
      */
 84   
     public interface NodeFilter {
 85   
         /**
 86   
          * @param       node    the node to check for acceptance.
 87   
          * @return      <tt>true</tt> if the node is accepted by this filter,
 88   
          *                      otherwise <tt>false</tt>
 89   
          */
 90   
         boolean accept(Node node);
 91   
     }
 92   
 
 93   
     /**
 94   
      * list a set of node that match a specific filter. The list can be made
 95   
      * recursively or not.
 96   
      * @param   parent  the parent node to search from
 97   
      * @param   filter  the filter that children should match.
 98   
      * @param   recurse <tt>true</tt> if you want the list to be made recursively
 99   
      *                  otherwise <tt>false</tt>.
 100   
      */
 101  0
     public static NodeList listChildNodes(Node parent, NodeFilter filter, boolean recurse){
 102  0
         NodeListImpl matches = new NodeListImpl();
 103  0
         NodeList children = parent.getChildNodes();
 104  0
         if (children != null) {
 105  0
             final int len = children.getLength();
 106  0
             for (int i = 0; i < len; i++) {
 107  0
                 Node child = children.item(i);
 108  0
                 if (filter.accept(child)) {
 109  0
                     matches.addElement(child);
 110   
                 }
 111  0
                 if (recurse) {
 112  0
                     NodeList recmatches = listChildNodes(child, filter, recurse);
 113  0
                     final int reclength = matches.getLength();
 114  0
                     for (int j = 0; j < reclength; j++) {
 115  0
                         matches.addElement(recmatches.item(i));
 116   
                     }
 117   
                 }
 118   
             }
 119   
         }
 120  0
         return matches;
 121   
     }
 122   
 
 123   
     /** custom implementation of a nodelist */
 124   
     public static class NodeListImpl extends Vector implements NodeList {
 125  0
         public int getLength(){
 126  0
             return size();
 127   
         }
 128  0
         public Node item(int i){
 129  0
             try {
 130  0
                 return (Node) elementAt(i);
 131   
             } catch (ArrayIndexOutOfBoundsException e){
 132  0
                 return null; // conforming to NodeList interface
 133   
             }
 134   
         }
 135   
     }
 136   
 
 137   
     /**
 138   
      * return the attribute value of an element.
 139   
      * @param node the node to get the attribute from.
 140   
      * @param name the name of the attribute we are looking for the value.
 141   
      * @return the value of the requested attribute or <tt>null</tt> if the
 142   
      *         attribute was not found or if <tt>node</tt> is not an <tt>Element</tt>.
 143   
      */
 144  0
     public static String getNodeAttribute(Node node, String name) {
 145  0
         if (node instanceof Element) {
 146  0
             Element element = (Element) node;
 147  0
             return element.getAttribute(name);
 148   
         }
 149  0
         return null;
 150   
     }
 151   
 
 152   
 
 153   
     /**
 154   
      * Iterate over the children of a given node and return the first node
 155   
      * that has a specific name.
 156   
      * @param   parent  the node to search child from. Can be <tt>null</tt>.
 157   
      * @param   tagname the child name we are looking for. Cannot be <tt>null</tt>.
 158   
      * @return  the first child that matches the given name or <tt>null</tt> if
 159   
      *                  the parent is <tt>null</tt> or if a child does not match the
 160   
      *                  given name.
 161   
      */
 162  0
     public static Element getChildByTagName (Node parent, String tagname) {
 163  0
         if (parent == null){
 164  0
             return null;
 165   
         }
 166  0
         NodeList childList = parent.getChildNodes();
 167  0
         final int len = childList.getLength();
 168  0
         for (int i = 0; i < len; i++) {
 169  0
             Node child = childList.item(i);
 170  0
             if (child != null && child.getNodeType() == Node.ELEMENT_NODE &&
 171   
                  child.getNodeName().equals(tagname)) {
 172  0
                 return (Element) child;
 173   
             }
 174   
         }
 175  0
         return null;
 176   
     }
 177   
 
 178   
     /**
 179   
      * Simple tree walker that will clone recursively a node. This is to
 180   
      * avoid using parser-specific API such as Sun's <tt>changeNodeOwner</tt>
 181   
      * when we are dealing with DOM L1 implementations since <tt>cloneNode(boolean)</tt>
 182   
      * will not change the owner document.
 183   
      * <tt>changeNodeOwner</tt> is much faster and avoid the costly cloning process.
 184   
      * <tt>importNode</tt> is in the DOM L2 interface.
 185   
      * @param   parent  the node parent to which we should do the import to.
 186   
      * @param   child   the node to clone recursively. Its clone will be
 187   
      *              appended to <tt>parent</tt>.
 188   
      * @return  the cloned node that is appended to <tt>parent</tt>
 189   
      */
 190  296
     public static final Node importNode(Node parent, Node child){
 191  296
         Node copy = null;
 192  296
         final Document doc = parent.getOwnerDocument();
 193   
 
 194  296
         switch (child.getNodeType()) {
 195   
         case Node.CDATA_SECTION_NODE:
 196  2
             copy = doc.createCDATASection(((CDATASection) child).getData());
 197  2
             break;
 198   
         case Node.COMMENT_NODE:
 199  0
             copy = doc.createComment(((Comment) child).getData());
 200  0
             break;
 201   
         case Node.DOCUMENT_FRAGMENT_NODE:
 202  0
             copy = doc.createDocumentFragment();
 203  0
             break;
 204   
         case Node.ELEMENT_NODE:
 205  144
             final Element elem = doc.createElement(((Element) child).getTagName());
 206  144
             copy = elem;
 207  144
             final NamedNodeMap attributes = child.getAttributes();
 208  144
             if (attributes != null) {
 209  144
                 final int size = attributes.getLength();
 210  144
                 for (int i = 0; i < size; i++) {
 211  282
                     final Attr attr = (Attr) attributes.item(i);
 212  282
                     elem.setAttribute(attr.getName(), attr.getValue());
 213   
                 }
 214   
             }
 215  144
             break;
 216   
         case Node.ENTITY_REFERENCE_NODE:
 217  0
             copy = doc.createEntityReference(child.getNodeName());
 218  0
             break;
 219   
         case Node.PROCESSING_INSTRUCTION_NODE:
 220  0
             final ProcessingInstruction pi = (ProcessingInstruction) child;
 221  0
             copy = doc.createProcessingInstruction(pi.getTarget(), pi.getData());
 222  0
             break;
 223   
         case Node.TEXT_NODE:
 224  150
             copy = doc.createTextNode(((Text) child).getData());
 225  150
             break;
 226   
         default:
 227   
             // this should never happen
 228  0
             throw new IllegalStateException("Invalid node type: " + child.getNodeType());
 229   
         }
 230   
 
 231   
         // okay we have a copy of the child, now the child becomes the parent
 232   
         // and we are iterating recursively over its children.
 233  296
         try {
 234  296
             final NodeList children = child.getChildNodes();
 235  296
             if (children != null) {
 236  296
                 final int size = children.getLength();
 237  296
                 for (int i = 0; i < size; i++) {
 238  294
                     final Node newChild = children.item(i);
 239  294
                     if (newChild != null) {
 240  294
                         importNode(copy, newChild);
 241   
                     }
 242   
                 }
 243   
             }
 244   
         } catch (DOMException ignored) {
 245   
         }
 246   
 
 247   
         // bingo append it. (this should normally not be done here)
 248  296
         parent.appendChild(copy);
 249  296
         return copy;
 250   
     }
 251   
 }
 252