View Javadoc

    1   /*
    2    * Copyright 2001-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License")
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package org.apache.commons.configuration;
    18
    19  import java.util.List;
    20
    21  import org.apache.commons.configuration.HierarchicalConfiguration.Node;
    22  import org.xml.sax.Attributes;
    23  import org.xml.sax.helpers.AttributesImpl;
    24
    25  /***
    26   * <p>A specialized SAX2 XML parser that "parses" hierarchical
    27   * configuration objects.</p>
    28   * <p>This class mimics to be a SAX conform XML parser. Instead of parsing
    29   * XML documents it processes a <code>Configuration</code> object and
    30   * generates SAX events for the single properties defined there. This enables
    31   * the whole world of XML processing for configuration objects.</p>
    32   * <p>The <code>HierarchicalConfiguration</code> object to be parsed can be
    33   * specified using a constructor or the <code>setConfiguration()</code> method.
    34   * This object will be processed by the <code>parse()</code> methods. Note
    35   * that these methods ignore their argument.</p>
    36   *
    37   * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
    38   * @version $Id: HierarchicalConfigurationXMLReader.java,v 1.5 2004/07/05 09:54:17 ebourg Exp $
    39   */
    40  public class HierarchicalConfigurationXMLReader extends ConfigurationXMLReader
    41  {
    42      /*** Stores the configuration object to be parsed.*/
    43      private HierarchicalConfiguration configuration;
    44
    45      /***
    46       * Creates a new instance of
    47       * <code>HierarchicalConfigurationXMLReader</code>.
    48       */
    49      public HierarchicalConfigurationXMLReader()
    50      {
    51          super();
    52      }
    53
    54      /***
    55       * Creates a new instance of
    56       * <code>HierarchicalConfigurationXMLReader</code> and sets the
    57       * configuration to be parsed.
    58       *
    59       * @param config the configuration object
    60       */
    61      public HierarchicalConfigurationXMLReader(HierarchicalConfiguration config)
    62      {
    63          this();
    64          setConfiguration(config);
    65      }
    66
    67      /***
    68       * Returns the configuration object to be parsed.
    69       *
    70       * @return the configuration object to be parsed
    71       */
    72      public HierarchicalConfiguration getConfiguration()
    73      {
    74          return configuration;
    75      }
    76
    77      /***
    78       * Sets the configuration object to be parsed.
    79       *
    80       * @param config the configuration object to be parsed
    81       */
    82      public void setConfiguration(HierarchicalConfiguration config)
    83      {
    84          configuration = config;
    85      }
    86
    87      /***
    88       * Returns the configuration object to be processed.
    89       *
    90       * @return the actual configuration object
    91       */
    92      public Configuration getParsedConfiguration()
    93      {
    94          return getConfiguration();
    95      }
    96
    97      /***
    98       * Processes the actual configuration object to generate SAX parsing events.
    99       */
    100     protected void processKeys()
    101     {
    102         getConfiguration().getRoot().visit(new SAXVisitor(), null);
    103     }
    104
    105     /***
    106      * A specialized visitor class for generating SAX events for a
    107      * hierarchical node structure.
    108      *
    109      */
    110     class SAXVisitor extends HierarchicalConfiguration.NodeVisitor
    111     {
    112         /*** Constant for the attribute type.*/
    113         private static final String ATTR_TYPE = "CDATA";
    114
    115         /***
    116          * Visits the specified node after its children have been processed.
    117          *
    118          * @param node the actual node
    119          * @param key the key of this node
    120          */
    121         public void visitAfterChildren(Node node, ConfigurationKey key)
    122         {
    123             if (!isAttributeNode(node))
    124             {
    125                 fireElementEnd(nodeName(node));
    126             }
    127         }
    128
    129         /***
    130          * Visits the specified node.
    131          *
    132          * @param node the actual node
    133          * @param key the key of this node
    134          */
    135         public void visitBeforeChildren(Node node, ConfigurationKey key)
    136         {
    137             if (!isAttributeNode(node))
    138             {
    139                 fireElementStart(nodeName(node), fetchAttributes(node));
    140
    141                 if (node.getValue() != null)
    142                 {
    143                     fireCharacters(node.getValue().toString());
    144                 }
    145             }
    146         }
    147
    148         /***
    149          * Checks if iteration should be terminated. This implementation stops
    150          * iteration after an exception has occurred.
    151          *
    152          * @return a flag if iteration should be stopped
    153          */
    154         public boolean terminate()
    155         {
    156             return getException() != null;
    157         }
    158
    159         /***
    160          * Returns an object with all attributes for the specified node.
    161          *
    162          * @param node the actual node
    163          * @return an object with all attributes of this node
    164          */
    165         protected Attributes fetchAttributes(Node node)
    166         {
    167             AttributesImpl attrs = new AttributesImpl();
    168             List children = node.getChildren();
    169
    170             for (int i = 0; i < children.size(); i++)
    171             {
    172                 Node child = (Node) children.get(i);
    173                 if (isAttributeNode(child) && child.getValue() != null)
    174                 {
    175                     String attr = ConfigurationKey.attributeName(child.getName());
    176                     attrs.addAttribute(NS_URI, attr, attr, ATTR_TYPE, child.getValue().toString());
    177                 }
    178             }
    179
    180             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             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             return ConfigurationKey.isAttributeKey(node.getName());
    207         }
    208     }
    209 }