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 }