Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
SubnodeConfiguration |
|
| 1.6666666666666667;1,667 |
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 | package org.apache.commons.configuration; | |
18 | ||
19 | import org.apache.commons.configuration.tree.ConfigurationNode; | |
20 | ||
21 | /** | |
22 | * <p> | |
23 | * A specialized hierarchical configuration class that wraps a single node of | |
24 | * its parent configuration. | |
25 | * </p> | |
26 | * <p> | |
27 | * Configurations of this type are initialized with a parent configuration and a | |
28 | * configuration node of this configuration. This node becomes the root node of | |
29 | * the subnode configuration. All property accessor methods are evaluated | |
30 | * relative to this root node. A good use case for a | |
31 | * <code>SubnodeConfiguration</code> is when multiple properties from a | |
32 | * specific sub tree of the whole configuration need to be accessed. Then a | |
33 | * <code>SubnodeConfiguration</code> can be created with the parent node of | |
34 | * the affected sub tree as root node. This allows for simpler property keys and | |
35 | * is also more efficient. | |
36 | * </p> | |
37 | * <p> | |
38 | * A subnode configuration and its parent configuration operate on the same | |
39 | * hierarchy of configuration nodes. So if modifications are performed at the | |
40 | * subnode configuration, these changes are immideately visible in the parent | |
41 | * configuration. Analogously will updates of the parent configuration affect | |
42 | * the subnode configuration if the sub tree spanned by the subnode | |
43 | * configuration's root node is involved. | |
44 | * </p> | |
45 | * <p> | |
46 | * When a subnode configuration is created, it inherits the settings of its | |
47 | * parent configuration, e.g. some flags like the | |
48 | * <code>throwExceptionOnMissing</code> flag or the settings for handling list | |
49 | * delimiters) or the expression engine. If these settings are changed later in | |
50 | * either the subnode or the parent configuration, the changes are not visible | |
51 | * for each other. So you could create a subnode configuration, change its | |
52 | * expression engine without affecting the parent configuration. | |
53 | * </p> | |
54 | * <p> | |
55 | * From its purpose this class is quite similar to | |
56 | * <code>{@link SubsetConfiguration}</code>. The difference is that a subset | |
57 | * configuration of a hierarchical configuration may combine multiple | |
58 | * configuration nodes from different sub trees of the configuration, while all | |
59 | * nodes in a subnode configuration belong to the same sub tree. If an | |
60 | * application can live with this limitation, it is recommended to use this | |
61 | * class instead of <code>SubsetConfiguration</code> because creating a subset | |
62 | * configuration is more expensive than creating a subnode configuration. | |
63 | * </p> | |
64 | * | |
65 | * @since 1.3 | |
66 | * @author Oliver Heger | |
67 | * @version $Id: SubnodeConfiguration.java 439648 2006-09-02 20:42:10Z oheger $ | |
68 | */ | |
69 | public class SubnodeConfiguration extends HierarchicalConfiguration | |
70 | { | |
71 | /** | |
72 | * The serial version UID. | |
73 | */ | |
74 | private static final long serialVersionUID = 3105734147019386480L; | |
75 | ||
76 | /** Stores the parent configuration. */ | |
77 | private HierarchicalConfiguration parent; | |
78 | ||
79 | /** | |
80 | * Creates a new instance of <code>SubnodeConfiguration</code> and | |
81 | * initializes it with the parent configuration and the new root node. | |
82 | * | |
83 | * @param parent the parent configuration | |
84 | * @param root the root node of this subnode configuration | |
85 | */ | |
86 | public SubnodeConfiguration(HierarchicalConfiguration parent, ConfigurationNode root) | |
87 | 190 | { |
88 | 190 | if (parent == null) |
89 | { | |
90 | 1 | throw new IllegalArgumentException( |
91 | "Parent configuration must not be null!"); | |
92 | } | |
93 | 189 | if (root == null) |
94 | { | |
95 | 1 | throw new IllegalArgumentException("Root node must not be null!"); |
96 | } | |
97 | ||
98 | 188 | setRootNode(root); |
99 | 188 | this.parent = parent; |
100 | 188 | initFromParent(parent); |
101 | 188 | } |
102 | ||
103 | /** | |
104 | * Returns the parent configuration of this subnode configuration. | |
105 | * | |
106 | * @return the parent configuration | |
107 | */ | |
108 | public HierarchicalConfiguration getParent() | |
109 | { | |
110 | 411 | return parent; |
111 | } | |
112 | ||
113 | /** | |
114 | * Returns a hierarchical configuration object for the given sub node. | |
115 | * This implementation will ensure that the returned | |
116 | * <code>SubnodeConfiguration</code> object will have the same parent than | |
117 | * this object. | |
118 | * | |
119 | * @param node the sub node, for which the configuration is to be created | |
120 | * @return a hierarchical configuration for this sub node | |
121 | */ | |
122 | protected SubnodeConfiguration createSubnodeConfiguration(ConfigurationNode node) | |
123 | { | |
124 | 75 | return new SubnodeConfiguration(getParent(), node); |
125 | } | |
126 | ||
127 | /** | |
128 | * Creates a new node. This task is delegated to the parent. | |
129 | * | |
130 | * @param name the node's name | |
131 | * @return the new node | |
132 | */ | |
133 | protected Node createNode(String name) | |
134 | { | |
135 | 4 | return getParent().createNode(name); |
136 | } | |
137 | ||
138 | /** | |
139 | * Initializes this subnode configuration from the given parent | |
140 | * configuration. This method is called by the constructor. It will copy | |
141 | * many settings from the parent. | |
142 | * | |
143 | * @param parentConfig the parent configuration | |
144 | */ | |
145 | protected void initFromParent(HierarchicalConfiguration parentConfig) | |
146 | { | |
147 | 188 | setExpressionEngine(parentConfig.getExpressionEngine()); |
148 | 188 | setListDelimiter(parentConfig.getListDelimiter()); |
149 | 188 | setDelimiterParsingDisabled(parentConfig.isDelimiterParsingDisabled()); |
150 | 188 | setThrowExceptionOnMissing(parentConfig.isThrowExceptionOnMissing()); |
151 | 188 | } |
152 | ||
153 | /** | |
154 | * Performs interpolation. This implementation will ask the parent | |
155 | * configuration to perform the interpolation so that variables can be | |
156 | * evaluated in the global context. | |
157 | * | |
158 | * @param value the value to be interpolated | |
159 | */ | |
160 | protected Object interpolate(Object value) | |
161 | { | |
162 | 288 | return getParent().interpolate(value); |
163 | } | |
164 | } |