View Javadoc

    1   /*
    2    * Copyright 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.io.File;
    20  import java.io.InputStream;
    21  import java.io.OutputStream;
    22  import java.io.Reader;
    23  import java.io.Writer;
    24  import java.net.URL;
    25  import javax.xml.parsers.DocumentBuilder;
    26  import javax.xml.parsers.DocumentBuilderFactory;
    27
    28  import org.w3c.dom.Attr;
    29  import org.w3c.dom.Document;
    30  import org.w3c.dom.Element;
    31  import org.w3c.dom.NamedNodeMap;
    32  import org.w3c.dom.NodeList;
    33  import org.w3c.dom.Text;
    34  import org.xml.sax.InputSource;
    35
    36  /***
    37   * A specialized hierarchical configuration class that is able to parse
    38   * XML documents.
    39   *
    40   * <p>The parsed document will be stored keeping its structure. The
    41   * contained properties can be accessed using all methods supported by
    42   * the base class <code>HierarchicalConfiguration</code>.
    43   *
    44   * @since commons-configuration 1.0
    45   *
    46   * @author J&ouml;rg Schaible
    47   * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
    48   * @version $Revision: 1.3 $, $Date: 2004/09/22 17:17:30 $
    49   */
    50  public class HierarchicalXMLConfiguration extends HierarchicalConfiguration implements FileConfiguration
    51  {
    52      private FileConfiguration delegate = new FileConfigurationDelegate();
    53
    54      /***
    55       * Initializes this configuration from an XML document.
    56       *
    57       * @param document the document to be parsed
    58       */
    59      public void initProperties(Document document)
    60      {
    61          constructHierarchy(getRoot(), document.getDocumentElement());
    62      }
    63
    64      /***
    65       * Helper method for building the internal storage hierarchy. The XML
    66       * elements are transformed into node objects.
    67       *
    68       * @param node the actual node
    69       * @param element the actual XML element
    70       */
    71      private void constructHierarchy(Node node, Element element)
    72      {
    73          StringBuffer buffer = new StringBuffer();
    74          NodeList list = element.getChildNodes();
    75          for (int i = 0; i < list.getLength(); i++)
    76          {
    77              org.w3c.dom.Node w3cNode = list.item(i);
    78              if (w3cNode instanceof Element)
    79              {
    80                  Element child = (Element) w3cNode;
    81                  Node childNode = new Node(child.getTagName());
    82                  constructHierarchy(childNode, child);
    83                  node.addChild(childNode);
    84                  processAttributes(childNode, child);
    85              }
    86              else if (w3cNode instanceof Text)
    87              {
    88                  Text data = (Text) w3cNode;
    89                  buffer.append(data.getData());
    90              }
    91          }
    92          String text = buffer.toString().trim();
    93          if (text.length() > 0)
    94          {
    95              node.setValue(text);
    96          }
    97      }
    98
    99      /***
    100      * Helper method for constructing node objects for the attributes of the
    101      * given XML element.
    102      *
    103      * @param node the actual node
    104      * @param element the actual XML element
    105      */
    106     private void processAttributes(Node node, Element element)
    107     {
    108         NamedNodeMap attributes = element.getAttributes();
    109         for (int i = 0; i < attributes.getLength(); ++i)
    110         {
    111             org.w3c.dom.Node w3cNode = attributes.item(i);
    112             if (w3cNode instanceof Attr)
    113             {
    114                 Attr attr = (Attr) w3cNode;
    115                 Node child =
    116                     new Node(
    117                         ConfigurationKey.constructAttributeKey(attr.getName()));
    118                 child.setValue(attr.getValue());
    119                 node.addChild(child);
    120             }
    121         }
    122     }
    123
    124     public void load() throws ConfigurationException
    125     {
    126         delegate.load();
    127     }
    128
    129     public void load(String fileName) throws ConfigurationException
    130     {
    131         delegate.load(fileName);
    132     }
    133
    134     public void load(File file) throws ConfigurationException
    135     {
    136         delegate.load(file);
    137     }
    138
    139     public void load(URL url) throws ConfigurationException
    140     {
    141         delegate.load(url);
    142     }
    143
    144     public void load(InputStream in) throws ConfigurationException
    145     {
    146         delegate.load(in);
    147     }
    148
    149     public void load(InputStream in, String encoding) throws ConfigurationException
    150     {
    151         delegate.load(in, encoding);
    152     }
    153
    154     public void load(Reader in) throws ConfigurationException
    155     {
    156         try
    157         {
    158             DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    159             initProperties(builder.parse(new InputSource(in)));
    160         }
    161         catch (Exception e)
    162         {
    163             throw new ConfigurationException(e.getMessage(), e);
    164         }
    165     }
    166
    167     public void save() throws ConfigurationException
    168     {
    169         delegate.save();
    170     }
    171
    172     public void save(String fileName) throws ConfigurationException
    173     {
    174         delegate.save(fileName);
    175     }
    176
    177     public void save(File file) throws ConfigurationException
    178     {
    179         delegate.save(file);
    180     }
    181
    182     public void save(URL url) throws ConfigurationException
    183     {
    184         delegate.save(url);
    185     }
    186
    187     public void save(OutputStream out) throws ConfigurationException
    188     {
    189         delegate.save(out);
    190     }
    191
    192     public void save(OutputStream out, String encoding) throws ConfigurationException
    193     {
    194         delegate.save(out, encoding);
    195     }
    196
    197     public void save(Writer out) throws ConfigurationException
    198     {
    199         throw new UnsupportedOperationException("Can't save HierarchicalXMLConfigurations");
    200     }
    201
    202     public String getFileName()
    203     {
    204         return delegate.getFileName();
    205     }
    206
    207     public void setFileName(String fileName)
    208     {
    209         delegate.setFileName(fileName);
    210     }
    211
    212     public String getBasePath()
    213     {
    214         return delegate.getBasePath();
    215     }
    216
    217     public void setBasePath(String basePath)
    218     {
    219         delegate.setBasePath(basePath);
    220     }
    221
    222     public File getFile()
    223     {
    224         return delegate.getFile();
    225     }
    226
    227     public void setFile(File file)
    228     {
    229         delegate.setFile(file);
    230     }
    231
    232     public URL getURL()
    233     {
    234         return delegate.getURL();
    235     }
    236
    237     public void setURL(URL url)
    238     {
    239         delegate.setURL(url);
    240     }
    241
    242     private class FileConfigurationDelegate extends AbstractFileConfiguration {
    243
    244         public void load(Reader in) throws ConfigurationException
    245         {
    246             HierarchicalXMLConfiguration.this.load(in);
    247         }
    248
    249         public void save(Writer out) throws ConfigurationException
    250         {
    251             HierarchicalXMLConfiguration.this.save(out);
    252         }
    253
    254     }
    255 }