##### Coverage Report - org.apache.commons.configuration.HierarchicalConfigurationXMLReader

Classes in this File | Line Coverage | Branch Coverage | Complexity

HierarchicalConfigurationXMLReader

100% | 11/11

N/A | N/A

1.4166666666666667;1,417

HierarchicalConfigurationXMLReader$SAXVisitor

100% | 19/19

100% | 7/7

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

     }