View Javadoc

1   /*
2    * Copyright 2001-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.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              // As the inMemoryConfiguration contains all manually added keys,
80              // we must make sure that it is always last. "Normal", non composed
81              // configuration add their keys at the end of the configuration and
82              // we want to mimic this behaviour.
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          // Make sure that you can't remove the inMemoryConfiguration from
100         // the CompositeConfiguration object
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         // recreate the in memory configuration
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         // add all elements from the first configuration containing the requested key
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         // add all elements from the in memory configuration
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         // interpolate the strings
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 }