Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
HierarchicalConfigurationXMLReader |
|
| 1.4166666666666667;1,417 | ||||
HierarchicalConfigurationXMLReader$SAXVisitor |
|
| 1.4166666666666667;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 | } |