1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.LinkedList;
22 import java.util.List;
23 import java.util.Vector;
24
25 /***
26 * This Configuration class allows you to add multiple different types of Configuration
27 * to this CompositeConfiguration. If you add Configuration1, and then Configuration2,
28 * any properties shared will mean that Configuration1 will be returned.
29 * You can add multiple different types or the same type of properties file.
30 * If Configuration1 doesn't have the property, then Configuration2 will be checked.
31 *
32 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
33 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
34 * @version $Id: CompositeConfiguration.java,v 1.19 2004/10/05 22:56:58 ebourg Exp $
35 */
36 public class CompositeConfiguration extends AbstractConfiguration
37 {
38 /*** List holding all the configuration */
39 private List configList = new LinkedList();
40
41 /***
42 * Configuration that holds in memory stuff. Inserted as first so any
43 * setProperty() override anything else added.
44 */
45 private Configuration inMemoryConfiguration;
46
47 /***
48 * Creates an empty CompositeConfiguration object which can then
49 * be added some other Configuration files
50 */
51 public CompositeConfiguration()
52 {
53 clear();
54 }
55
56 /***
57 * Creates an CompositeConfiguration object with a specified InMemory
58 * configuration. This configuration will store any changes made to
59 * the CompositeConfiguration.
60 *
61 * @param inMemoryConfiguration the in memory configuration to use
62 */
63 public CompositeConfiguration(Configuration inMemoryConfiguration)
64 {
65 configList.clear();
66 this.inMemoryConfiguration = inMemoryConfiguration;
67 configList.add(inMemoryConfiguration);
68 }
69
70 /***
71 * Add a configuration.
72 *
73 * @param config the configuration to add
74 */
75 public void addConfiguration(Configuration config)
76 {
77 if (!configList.contains(config))
78 {
79
80
81
82
83 configList.add(configList.indexOf(inMemoryConfiguration), config);
84
85 if (config instanceof AbstractConfiguration)
86 {
87 ((AbstractConfiguration) config).setThrowExceptionOnMissing(isThrowExceptionOnMissing());
88 }
89 }
90 }
91
92 /***
93 * Remove a configuration. The in memory configuration cannot be removed.
94 *
95 * @param config The configuration to remove
96 */
97 public void removeConfiguration(Configuration config)
98 {
99
100
101 if (!config.equals(inMemoryConfiguration))
102 {
103 configList.remove(config);
104 }
105 }
106
107 /***
108 * Return the number of configurations.
109 *
110 * @return the number of configuration
111 */
112 public int getNumberOfConfigurations()
113 {
114 return configList.size();
115 }
116
117 /***
118 * Remove all configuration reinitialize the in memory configuration.
119 */
120 public void clear()
121 {
122 configList.clear();
123
124 inMemoryConfiguration = new BaseConfiguration();
125 ((BaseConfiguration) inMemoryConfiguration).setThrowExceptionOnMissing(isThrowExceptionOnMissing());
126 configList.add(inMemoryConfiguration);
127 }
128
129 /***
130 * Add this property to the inmemory Configuration.
131 *
132 * @param key The Key to add the property to.
133 * @param token The Value to add.
134 */
135 protected void addPropertyDirect(String key, Object token)
136 {
137 inMemoryConfiguration.addProperty(key, token);
138 }
139
140 /***
141 * Read property from underlying composite
142 *
143 * @param key key to use for mapping
144 *
145 * @return object associated with the given configuration key.
146 */
147 protected Object getPropertyDirect(String key)
148 {
149 Configuration firstMatchingConfiguration = null;
150 for (Iterator i = configList.iterator(); i.hasNext();)
151 {
152 Configuration config = (Configuration) i.next();
153 if (config.containsKey(key))
154 {
155 firstMatchingConfiguration = config;
156 break;
157 }
158 }
159
160 if (firstMatchingConfiguration != null)
161 {
162 return firstMatchingConfiguration.getProperty(key);
163 }
164 else
165 {
166 return null;
167 }
168 }
169
170 /***
171 * {@inheritDoc}
172 */
173 public Iterator getKeys()
174 {
175 List keys = new ArrayList();
176 for (Iterator i = configList.iterator(); i.hasNext();)
177 {
178 Configuration config = (Configuration) i.next();
179
180 Iterator j = config.getKeys();
181 while (j.hasNext())
182 {
183 String key = (String) j.next();
184 if (!keys.contains(key))
185 {
186 keys.add(key);
187 }
188 }
189 }
190
191 return keys.iterator();
192 }
193
194 /***
195 * {@inheritDoc}
196 */
197 public Iterator getKeys(String key)
198 {
199 List keys = new ArrayList();
200 for (Iterator i = configList.iterator(); i.hasNext();)
201 {
202 Configuration config = (Configuration) i.next();
203
204 Iterator j = config.getKeys(key);
205 while (j.hasNext())
206 {
207 String newKey = (String) j.next();
208 if (!keys.contains(newKey))
209 {
210 keys.add(newKey);
211 }
212 }
213 }
214
215 return keys.iterator();
216 }
217
218 /***
219 * {@inheritDoc}
220 */
221 public boolean isEmpty()
222 {
223 boolean isEmpty = true;
224 for (Iterator i = configList.iterator(); i.hasNext();)
225 {
226 Configuration config = (Configuration) i.next();
227 if (!config.isEmpty())
228 {
229 return false;
230 }
231 }
232
233 return isEmpty;
234 }
235
236 /***
237 * {@inheritDoc}
238 */
239 public Object getProperty(String key)
240 {
241 return getPropertyDirect(key);
242 }
243
244 /***
245 * {@inheritDoc}
246 */
247 public void setProperty(String key, Object value)
248 {
249 clearProperty(key);
250 addProperty(key, value);
251 }
252
253 /***
254 * {@inheritDoc}
255 */
256 public void clearProperty(String key)
257 {
258 for (Iterator i = configList.iterator(); i.hasNext();)
259 {
260 Configuration config = (Configuration) i.next();
261 config.clearProperty(key);
262 }
263 }
264
265 /***
266 * {@inheritDoc}
267 */
268 public boolean containsKey(String key)
269 {
270 for (Iterator i = configList.iterator(); i.hasNext();)
271 {
272 Configuration config = (Configuration) i.next();
273 if (config.containsKey(key))
274 {
275 return true;
276 }
277 }
278 return false;
279 }
280
281 /***
282 * {@inheritDoc}
283 */
284 public List getList(String key, List defaultValue)
285 {
286 List list = new ArrayList();
287
288
289 Iterator it = configList.iterator();
290 while (it.hasNext() && list.isEmpty())
291 {
292 Configuration config = (Configuration) it.next();
293 if (config != inMemoryConfiguration && config.containsKey(key))
294 {
295 list.addAll(config.getList(key));
296 }
297 }
298
299
300 list.addAll(inMemoryConfiguration.getList(key));
301
302 if (list.isEmpty())
303 {
304 return defaultValue;
305 }
306
307 return list;
308 }
309
310 /***
311 * {@inheritDoc}
312 */
313 public Vector getVector(String key, Vector defaultValue)
314 {
315 return new Vector(getList(key, defaultValue));
316 }
317
318 /***
319 * {@inheritDoc}
320 */
321 public String[] getStringArray(String key)
322 {
323 List list = getList(key);
324
325
326 String[] tokens = new String[list.size()];
327
328 for (int i = 0; i < tokens.length; i++)
329 {
330 tokens[i] = interpolate(String.valueOf(list.get(i)));
331 }
332
333 return tokens;
334 }
335
336 /***
337 * Return the configuration at the specified index.
338 *
339 * @param index The index of the configuration to retrieve
340 */
341 public Configuration getConfiguration(int index)
342 {
343 return (Configuration) configList.get(index);
344 }
345
346 /***
347 * {@inheritDoc}
348 */
349 public Configuration getInMemoryConfiguration()
350 {
351 return inMemoryConfiguration;
352 }
353 }