Coverage Report - org.apache.commons.configuration.HierarchicalConfigurationXMLReader
 
Classes in this File Line Coverage Branch Coverage Complexity
HierarchicalConfigurationXMLReader
100%
11/11
N/A
1,417
HierarchicalConfigurationXMLReader$SAXVisitor
100%
19/19
100%
7/7
1,417
 
 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  
 
 18  
 package org.apache.commons.configuration;
 19  
 
 20  
 import java.util.Iterator;
 21  
 
 22  
 import org.apache.commons.configuration.HierarchicalConfiguration.Node;
 23  
 import org.xml.sax.Attributes;
 24  
 import org.xml.sax.helpers.AttributesImpl;
 25  
 
 26  
 /**
 27  
  * <p>A specialized SAX2 XML parser that "parses" hierarchical
 28  
  * configuration objects.</p>
 29  
  * <p>This class mimics to be a SAX conform XML parser. Instead of parsing
 30  
  * XML documents it processes a <code>Configuration</code> object and
 31  
  * generates SAX events for the single properties defined there. This enables
 32  
  * the whole world of XML processing for configuration objects.</p>
 33  
  * <p>The <code>HierarchicalConfiguration</code> object to be parsed can be
 34  
  * specified using a constructor or the <code>setConfiguration()</code> method.
 35  
  * This object will be processed by the <code>parse()</code> methods. Note
 36  
  * that these methods ignore their argument.</p>
 37  
  *
 38  
  * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
 39  
  * @version $Id: HierarchicalConfigurationXMLReader.java 439648 2006-09-02 20:42:10Z oheger $
 40  
  */
 41  
 public class HierarchicalConfigurationXMLReader extends ConfigurationXMLReader
 42  
 {
 43  
     /** Stores the configuration object to be parsed.*/
 44  
     private HierarchicalConfiguration configuration;
 45  
 
 46  
     /**
 47  
      * Creates a new instance of
 48  
      * <code>HierarchicalConfigurationXMLReader</code>.
 49  
      */
 50  
     public HierarchicalConfigurationXMLReader()
 51  
     {
 52  1
         super();
 53  1
     }
 54  
 
 55  
     /**
 56  
      * Creates a new instance of
 57  
      * <code>HierarchicalConfigurationXMLReader</code> and sets the
 58  
      * configuration to be parsed.
 59  
      *
 60  
      * @param config the configuration object
 61  
      */
 62  
     public HierarchicalConfigurationXMLReader(HierarchicalConfiguration config)
 63  
     {
 64  1
         this();
 65  1
         setConfiguration(config);
 66  1
     }
 67  
 
 68  
     /**
 69  
      * Returns the configuration object to be parsed.
 70  
      *
 71  
      * @return the configuration object to be parsed
 72  
      */
 73  
     public HierarchicalConfiguration getConfiguration()
 74  
     {
 75  2
         return configuration;
 76  
     }
 77  
 
 78  
     /**
 79  
      * Sets the configuration object to be parsed.
 80  
      *
 81  
      * @param config the configuration object to be parsed
 82  
      */
 83  
     public void setConfiguration(HierarchicalConfiguration config)
 84  
     {
 85  1
         configuration = config;
 86  1
     }
 87  
 
 88  
     /**
 89  
      * Returns the configuration object to be processed.
 90  
      *
 91  
      * @return the actual configuration object
 92  
      */
 93  
     public Configuration getParsedConfiguration()
 94  
     {
 95  1
         return getConfiguration();
 96  
     }
 97  
 
 98  
     /**
 99  
      * Processes the actual configuration object to generate SAX parsing events.
 100  
      */
 101  
     protected void processKeys()
 102  
     {
 103  1
         getConfiguration().getRoot().visit(new SAXVisitor(), null);
 104  1
     }
 105  
 
 106  
     /**
 107  
      * A specialized visitor class for generating SAX events for a
 108  
      * hierarchical node structure.
 109  
      *
 110  
      */
 111  1
     class SAXVisitor extends HierarchicalConfiguration.NodeVisitor
 112  
     {
 113  
         /** Constant for the attribute type.*/
 114  
         private static final String ATTR_TYPE = "CDATA";
 115  
 
 116  
         /**
 117  
          * Visits the specified node after its children have been processed.
 118  
          *
 119  
          * @param node the actual node
 120  
          * @param key the key of this node
 121  
          */
 122  
         public void visitAfterChildren(Node node, ConfigurationKey key)
 123  
         {
 124  40
             if (!isAttributeNode(node))
 125  
             {
 126  38
                 fireElementEnd(nodeName(node));
 127  
             }
 128  40
         }
 129  
 
 130  
         /**
 131  
          * Visits the specified node.
 132  
          *
 133  
          * @param node the actual node
 134  
          * @param key the key of this node
 135  
          */
 136  
         public void visitBeforeChildren(Node node, ConfigurationKey key)
 137  
         {
 138  40
             if (!isAttributeNode(node))
 139  
             {
 140  38
                 fireElementStart(nodeName(node), fetchAttributes(node));
 141  
 
 142  38
                 if (node.getValue() != null)
 143  
                 {
 144  22
                     fireCharacters(node.getValue().toString());
 145  
                 }
 146  
             }
 147  40
         }
 148  
 
 149  
         /**
 150  
          * Checks if iteration should be terminated. This implementation stops
 151  
          * iteration after an exception has occurred.
 152  
          *
 153  
          * @return a flag if iteration should be stopped
 154  
          */
 155  
         public boolean terminate()
 156  
         {
 157  39
             return getException() != null;
 158  
         }
 159  
 
 160  
         /**
 161  
          * Returns an object with all attributes for the specified node.
 162  
          *
 163  
          * @param node the actual node
 164  
          * @return an object with all attributes of this node
 165  
          */
 166  
         protected Attributes fetchAttributes(Node node)
 167  
         {
 168  38
             AttributesImpl attrs = new AttributesImpl();
 169  
 
 170  78
             for (Iterator it = node.getAttributes().iterator(); it.hasNext();)
 171  
             {
 172  2
                 Node child = (Node) it.next();
 173  2
                 if (child.getValue() != null)
 174  
                 {
 175  2
                     String attr = child.getName();
 176  2
                     attrs.addAttribute(NS_URI, attr, attr, ATTR_TYPE, child.getValue().toString());
 177  
                 }
 178  
             }
 179  
 
 180  38
             return attrs;
 181  
         }
 182  
 
 183  
         /**
 184  
          * Helper method for determining the name of a node. If a node has no
 185  
          * name (which is true for the root node), the specified default name
 186  
          * will be used.
 187  
          *
 188  
          * @param node the node to be checked
 189  
          * @return the name for this node
 190  
          */
 191  
         private String nodeName(Node node)
 192  
         {
 193  76
             return (node.getName() == null) ? getRootName() : node.getName();
 194  
         }
 195  
 
 196  
         /**
 197  
          * Checks if the specified node is an attribute node. In the node
 198  
          * hierarchy attributes are stored as normal child nodes, but with
 199  
          * special names.
 200  
          *
 201  
          * @param node the node to be checked
 202  
          * @return a flag if this is an attribute node
 203  
          */
 204  
         private boolean isAttributeNode(Node node)
 205  
         {
 206  80
             return node.isAttribute();
 207  
         }
 208  
     }
 209  
 }