001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.configuration;
019    
020    import static org.junit.Assert.assertEquals;
021    import static org.junit.Assert.assertFalse;
022    import static org.junit.Assert.assertNull;
023    import static org.junit.Assert.assertTrue;
024    import static org.junit.Assert.fail;
025    
026    import java.io.File;
027    import java.util.ArrayList;
028    import java.util.HashSet;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.NoSuchElementException;
032    import java.util.Set;
033    
034    import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
035    import org.apache.commons.lang.text.StrLookup;
036    import org.junit.Test;
037    
038    /**
039     * Test case for the {@link SubsetConfiguration} class.
040     *
041     * @author Emmanuel Bourg
042     * @version $Id: TestSubsetConfiguration.java 1225019 2011-12-27 21:18:54Z oheger $
043     */
044    public class TestSubsetConfiguration
045    {
046        static final String TEST_DIR = ConfigurationAssert.TEST_DIR_NAME;
047        static final String TEST_FILE = "testDigesterConfiguration2.xml";
048    
049        @Test
050        public void testGetProperty()
051        {
052            Configuration conf = new BaseConfiguration();
053            conf.setProperty("test.key1", "value1");
054            conf.setProperty("testing.key2", "value1");
055    
056            Configuration subset = new SubsetConfiguration(conf, "test", ".");
057            assertFalse("the subset is empty", subset.isEmpty());
058            assertTrue("'key1' not found in the subset", subset.containsKey("key1"));
059            assertFalse("'ng.key2' found in the subset", subset.containsKey("ng.key2"));
060        }
061    
062        @Test
063        public void testSetProperty()
064        {
065            Configuration conf = new BaseConfiguration();
066            Configuration subset = new SubsetConfiguration(conf, "test", ".");
067    
068            // set a property in the subset and check the parent
069            subset.setProperty("key1", "value1");
070            assertEquals("key1 in the subset configuration", "value1", subset.getProperty("key1"));
071            assertEquals("test.key1 in the parent configuration", "value1", conf.getProperty("test.key1"));
072    
073            // set a property in the parent and check in the subset
074            conf.setProperty("test.key2", "value2");
075            assertEquals("test.key2 in the parent configuration", "value2", conf.getProperty("test.key2"));
076            assertEquals("key2 in the subset configuration", "value2", subset.getProperty("key2"));
077        }
078    
079        @Test
080        public void testGetParentKey()
081        {
082            // subset with delimiter
083            SubsetConfiguration subset = new SubsetConfiguration(null, "prefix", ".");
084            assertEquals("parent key for \"key\"", "prefix.key", subset.getParentKey("key"));
085            assertEquals("parent key for \"\"", "prefix", subset.getParentKey(""));
086    
087            // subset without delimiter
088            subset = new SubsetConfiguration(null, "prefix", null);
089            assertEquals("parent key for \"key\"", "prefixkey", subset.getParentKey("key"));
090            assertEquals("parent key for \"\"", "prefix", subset.getParentKey(""));
091        }
092    
093        @Test
094        public void testGetChildKey()
095        {
096            // subset with delimiter
097            SubsetConfiguration subset = new SubsetConfiguration(null, "prefix", ".");
098            assertEquals("parent key for \"prefixkey\"", "key", subset.getChildKey("prefix.key"));
099            assertEquals("parent key for \"prefix\"", "", subset.getChildKey("prefix"));
100    
101            // subset without delimiter
102            subset = new SubsetConfiguration(null, "prefix", null);
103            assertEquals("parent key for \"prefixkey\"", "key", subset.getChildKey("prefixkey"));
104            assertEquals("parent key for \"prefix\"", "", subset.getChildKey("prefix"));
105        }
106    
107        @Test
108        public void testGetKeys()
109        {
110            Configuration conf = new BaseConfiguration();
111            conf.setProperty("test", "value0");
112            conf.setProperty("test.key1", "value1");
113            conf.setProperty("testing.key2", "value1");
114    
115            Configuration subset = new SubsetConfiguration(conf, "test", ".");
116    
117            Iterator<String> it = subset.getKeys();
118            assertEquals("1st key", "", it.next());
119            assertEquals("2nd key", "key1", it.next());
120            assertFalse("too many elements", it.hasNext());
121        }
122    
123        @Test
124        public void testGetKeysWithPrefix()
125        {
126            Configuration conf = new BaseConfiguration();
127            conf.setProperty("test.abc", "value0");
128            conf.setProperty("test.abc.key1", "value1");
129            conf.setProperty("test.abcdef.key2", "value1");
130    
131            Configuration subset = new SubsetConfiguration(conf, "test", ".");
132    
133            Iterator<String> it = subset.getKeys("abc");
134            assertEquals("1st key", "abc", it.next());
135            assertEquals("2nd key", "abc.key1", it.next());
136            assertFalse("too many elements", it.hasNext());
137        }
138    
139        @Test
140        public void testGetList()
141        {
142            Configuration conf = new BaseConfiguration();
143            conf.setProperty("test.abc", "value0,value1");
144            conf.addProperty("test.abc", "value3");
145    
146            Configuration subset = new SubsetConfiguration(conf, "test", ".");
147            List<Object> list = subset.getList("abc", new ArrayList<Object>());
148            assertEquals(3, list.size());
149        }
150    
151        @Test
152        public void testGetParent()
153        {
154            Configuration conf = new BaseConfiguration();
155            SubsetConfiguration subset = new SubsetConfiguration(conf, "prefix", ".");
156    
157            assertEquals("parent", conf, subset.getParent());
158        }
159    
160        @Test
161        public void testGetPrefix()
162        {
163            Configuration conf = new BaseConfiguration();
164            SubsetConfiguration subset = new SubsetConfiguration(conf, "prefix", ".");
165    
166            assertEquals("prefix", "prefix", subset.getPrefix());
167        }
168    
169        @Test
170        public void testSetPrefix()
171        {
172            Configuration conf = new BaseConfiguration();
173            SubsetConfiguration subset = new SubsetConfiguration(conf, null, ".");
174            subset.setPrefix("prefix");
175    
176            assertEquals("prefix", "prefix", subset.getPrefix());
177        }
178    
179        @Test
180        public void testThrowExceptionOnMissing()
181        {
182            BaseConfiguration config = new BaseConfiguration();
183            config.setThrowExceptionOnMissing(true);
184    
185            SubsetConfiguration subset = new SubsetConfiguration(config, "prefix");
186    
187            try
188            {
189                subset.getString("foo");
190                fail("NoSuchElementException expected");
191            }
192            catch (NoSuchElementException e)
193            {
194                // expected
195            }
196    
197            config.setThrowExceptionOnMissing(false);
198            assertNull(subset.getString("foo"));
199    
200    
201            subset.setThrowExceptionOnMissing(true);
202            try
203            {
204                config.getString("foo");
205                fail("NoSuchElementException expected");
206            }
207            catch (NoSuchElementException e)
208            {
209                // expected
210            }
211        }
212    
213        @SuppressWarnings("deprecation")
214        @Test
215        public void testNested() throws Exception
216        {
217            ConfigurationFactory factory = new ConfigurationFactory();
218            File src = new File(new File(TEST_DIR), TEST_FILE);
219            factory.setConfigurationURL(src.toURL());
220            Configuration config = factory.getConfiguration();
221            Configuration subConf = config.subset("tables.table(0)");
222            assertTrue(subConf.getKeys().hasNext());
223            Configuration subSubConf = subConf.subset("fields.field(1)");
224            Iterator<String> itKeys = subSubConf.getKeys();
225            Set<String> keys = new HashSet<String>();
226            keys.add("name");
227            keys.add("type");
228            while(itKeys.hasNext())
229            {
230                String k = itKeys.next();
231                assertTrue(keys.contains(k));
232                keys.remove(k);
233            }
234            assertTrue(keys.isEmpty());
235        }
236    
237        @Test
238        public void testClear()
239        {
240            Configuration config = new BaseConfiguration();
241            config.setProperty("test.key1", "value1");
242            config.setProperty("testing.key2", "value1");
243    
244            Configuration subset = config.subset("test");
245            subset.clear();
246    
247            assertTrue("the subset is not empty", subset.isEmpty());
248            assertFalse("the parent configuration is empty", config.isEmpty());
249        }
250    
251        @Test
252        public void testSetListDelimiter()
253        {
254            BaseConfiguration config = new BaseConfiguration();
255            Configuration subset = config.subset("prefix");
256            config.setListDelimiter('/');
257            subset.addProperty("list", "a/b/c");
258            assertEquals("Wrong size of list", 3, config.getList("prefix.list")
259                    .size());
260    
261            ((AbstractConfiguration) subset).setListDelimiter(';');
262            subset.addProperty("list2", "a;b;c");
263            assertEquals("Wrong size of list2", 3, config.getList("prefix.list2")
264                    .size());
265        }
266    
267        @Test
268        public void testGetListDelimiter()
269        {
270            BaseConfiguration config = new BaseConfiguration();
271            AbstractConfiguration subset = (AbstractConfiguration) config
272                    .subset("prefix");
273            config.setListDelimiter('/');
274            assertEquals("Wrong list delimiter in subset", '/', subset
275                    .getListDelimiter());
276            subset.setListDelimiter(';');
277            assertEquals("Wrong list delimiter in parent", ';', config
278                    .getListDelimiter());
279        }
280    
281        @Test
282        public void testSetDelimiterParsingDisabled()
283        {
284            BaseConfiguration config = new BaseConfiguration();
285            Configuration subset = config.subset("prefix");
286            config.setDelimiterParsingDisabled(true);
287            subset.addProperty("list", "a,b,c");
288            assertEquals("Wrong value of property", "a,b,c", config
289                    .getString("prefix.list"));
290    
291            ((AbstractConfiguration) subset).setDelimiterParsingDisabled(false);
292            subset.addProperty("list2", "a,b,c");
293            assertEquals("Wrong size of list2", 3, config.getList("prefix.list2")
294                    .size());
295        }
296    
297        @Test
298        public void testIsDelimiterParsingDisabled()
299        {
300            BaseConfiguration config = new BaseConfiguration();
301            AbstractConfiguration subset = (AbstractConfiguration) config
302                    .subset("prefix");
303            config.setDelimiterParsingDisabled(true);
304            assertTrue("Wrong value of list parsing flag in subset", subset
305                    .isDelimiterParsingDisabled());
306            subset.setDelimiterParsingDisabled(false);
307            assertFalse("Wrong value of list parsing flag in parent", config
308                    .isDelimiterParsingDisabled());
309        }
310    
311        /**
312         * Tests manipulating the interpolator.
313         */
314        @Test
315        public void testInterpolator()
316        {
317            BaseConfiguration config = new BaseConfiguration();
318            AbstractConfiguration subset = (AbstractConfiguration) config
319                    .subset("prefix");
320            InterpolationTestHelper.testGetInterpolator(subset);
321        }
322    
323        @Test
324        public void testLocalLookupsInInterpolatorAreInherited() {
325            BaseConfiguration config = new BaseConfiguration();
326            ConfigurationInterpolator interpolator = config.getInterpolator();
327            interpolator.registerLookup("brackets", new StrLookup(){
328    
329                @Override
330                public String lookup(String key) {
331                    return "(" + key +")";
332                }
333    
334            });
335            config.setProperty("prefix.var", "${brackets:x}");
336            AbstractConfiguration subset = (AbstractConfiguration) config
337                    .subset("prefix");
338            assertEquals("Local lookup was not inherited", "(x)", subset
339                    .getString("var", ""));
340        }
341    
342        @Test
343        public void testInterpolationForKeysOfTheParent() {
344            BaseConfiguration config = new BaseConfiguration();
345            config.setProperty("test", "junit");
346            config.setProperty("prefix.key", "${test}");
347            AbstractConfiguration subset = (AbstractConfiguration) config
348                    .subset("prefix");
349            assertEquals("Interpolation does not resolve parent keys", "junit",
350                    subset.getString("key", ""));
351        }
352    }