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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
package org.apache.commons.configuration;
20
import java.util.Iterator;
22
import org.apache.commons.collections.Transformer;
23
import org.apache.commons.collections.iterators.TransformIterator;
24
import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
27
* <p>A subset of another configuration. The new Configuration object contains
28
* every key from the parent Configuration that starts with prefix. The prefix
29
* is removed from the keys in the subset.</p>
30
* <p>It is usually not necessary to use this class directly. Instead the
31
* <code>{@link Configuration#subset(String)}</code> method should be used,
32
* which will return a correctly initialized instance.</p>
34
* @author Emmanuel Bourg
35
* @version $Revision: 930693 $, $Date: 2010-04-04 16:02:59 +0200 (So, 04. Apr 2010) $
37
public class SubsetConfiguration extends AbstractConfiguration
39
/** The parent configuration. */
40
protected Configuration parent;
42
/** The prefix used to select the properties. */
43
protected String prefix;
45
/** The prefix delimiter */
46
protected String delimiter;
49
* Create a subset of the specified configuration
51
* @param parent The parent configuration
52
* @param prefix The prefix used to select the properties
54
public SubsetConfiguration(Configuration parent, String prefix)
61
* Create a subset of the specified configuration
63
* @param parent The parent configuration
64
* @param prefix The prefix used to select the properties
65
* @param delimiter The prefix delimiter
67
public SubsetConfiguration(Configuration parent, String prefix, String delimiter)
71
this.delimiter = delimiter;
75
* Return the key in the parent configuration associated to the specified
78
* @param key The key in the subset.
79
* @return the key as to be used by the parent
81
protected String getParentKey(String key)
83
if ("".equals(key) || key == null)
89
return delimiter == null ? prefix + key : prefix + delimiter + key;
94
* Return the key in the subset configuration associated to the specified
95
* key in the parent configuration.
97
* @param key The key in the parent configuration.
98
* @return the key in the context of this subset configuration
100
protected String getChildKey(String key)
102
if (!key.startsWith(prefix))
104
throw new IllegalArgumentException("The parent key '" + key + "' is not in the subset.");
108
String modifiedKey = null;
109
if (key.length() == prefix.length())
115
int i = prefix.length() + (delimiter != null ? delimiter.length() : 0);
116
modifiedKey = key.substring(i);
124
* Return the parent configuration for this subset.
126
* @return the parent configuration
128
public Configuration getParent()
134
* Return the prefix used to select the properties in the parent configuration.
136
* @return the prefix used by this subset
138
public String getPrefix()
144
* Set the prefix used to select the properties in the parent configuration.
146
* @param prefix the prefix
148
public void setPrefix(String prefix)
150
this.prefix = prefix;
153
public Configuration subset(String prefix)
155
return parent.subset(getParentKey(prefix));
158
public boolean isEmpty()
160
return !getKeys().hasNext();
163
public boolean containsKey(String key)
165
return parent.containsKey(getParentKey(key));
168
public void addPropertyDirect(String key, Object value)
170
parent.addProperty(getParentKey(key), value);
173
protected void clearPropertyDirect(String key)
175
parent.clearProperty(getParentKey(key));
178
public Object getProperty(String key)
180
return parent.getProperty(getParentKey(key));
183
public Iterator getKeys(String prefix)
185
return new TransformIterator(parent.getKeys(getParentKey(prefix)), new Transformer()
187
public Object transform(Object obj)
189
return getChildKey((String) obj);
194
public Iterator getKeys()
196
return new TransformIterator(parent.getKeys(prefix), new Transformer()
198
public Object transform(Object obj)
200
return getChildKey((String) obj);
205
protected Object interpolate(Object base)
207
if (delimiter == null && "".equals(prefix))
209
return super.interpolate(base);
213
SubsetConfiguration config = new SubsetConfiguration(parent, "");
214
ConfigurationInterpolator interpolator = config.getInterpolator();
215
getInterpolator().registerLocalLookups(interpolator);
216
if (parent instanceof AbstractConfiguration)
218
interpolator.setParentInterpolator(((AbstractConfiguration) parent).getInterpolator());
220
return config.interpolate(base);
224
protected String interpolate(String base)
226
return super.interpolate(base);
232
* Change the behaviour of the parent configuration if it supports this feature.
234
public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing)
236
if (parent instanceof AbstractConfiguration)
238
((AbstractConfiguration) parent).setThrowExceptionOnMissing(throwExceptionOnMissing);
242
super.setThrowExceptionOnMissing(throwExceptionOnMissing);
249
* The subset inherits this feature from its parent if it supports this feature.
251
public boolean isThrowExceptionOnMissing()
253
if (parent instanceof AbstractConfiguration)
255
return ((AbstractConfiguration) parent).isThrowExceptionOnMissing();
259
return super.isThrowExceptionOnMissing();
264
* Returns the list delimiter. This property will be fetched from the parent
265
* configuration if supported.
267
* @return the list delimiter
270
public char getListDelimiter()
272
return (parent instanceof AbstractConfiguration) ? ((AbstractConfiguration) parent)
274
: super.getListDelimiter();
278
* Sets the list delimiter. If the parent configuration supports this
279
* feature, the delimiter will be set at the parent.
281
* @param delim the new list delimiter
284
public void setListDelimiter(char delim)
286
if (parent instanceof AbstractConfiguration)
288
((AbstractConfiguration) parent).setListDelimiter(delim);
292
super.setListDelimiter(delim);
297
* Returns a flag whether string properties should be checked for list
298
* delimiter characters. This implementation ensures that this flag is kept
299
* in sync with the parent configuration if this object supports this
302
* @return the delimiter parsing disabled flag
305
public boolean isDelimiterParsingDisabled()
307
return (parent instanceof AbstractConfiguration) ? ((AbstractConfiguration) parent)
308
.isDelimiterParsingDisabled()
309
: super.isDelimiterParsingDisabled();
313
* Sets a flag whether list parsing is disabled. This implementation will
314
* also set the flag at the parent configuration if this object supports
317
* @param delimiterParsingDisabled the delimiter parsing disabled flag
320
public void setDelimiterParsingDisabled(boolean delimiterParsingDisabled)
322
if (parent instanceof AbstractConfiguration)
324
((AbstractConfiguration) parent)
325
.setDelimiterParsingDisabled(delimiterParsingDisabled);
329
super.setDelimiterParsingDisabled(delimiterParsingDisabled);