View Javadoc
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    *     https://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.configuration2;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.NoSuchElementException;
27  import java.util.Set;
28  
29  import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
30  import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
31  import org.apache.commons.configuration2.ex.ConfigurationException;
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * A test class which tests functionality related to immutable configurations.
36   */
37  public class TestImmutableConfiguration {
38  
39      /** Constant for the name of a test properties file. */
40      private static final String TEST_FILE = "test.properties";
41  
42      /**
43       * Creates a test configuration object filled with properties.
44       *
45       * @return the test configuration
46       * @throws ConfigurationException if an error occurs
47       */
48      private static PropertiesConfiguration createTestConfig() throws ConfigurationException {
49          return new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class)
50              .configure(new FileBasedBuilderParametersImpl().setFile(ConfigurationAssert.getTestFile(TEST_FILE))).getConfiguration();
51      }
52  
53      /**
54       * Obtains all keys from the given iteration.
55       *
56       * @param it the iterator
57       * @return a set with all keys
58       */
59      private static Set<String> fetchKeys(final Iterator<String> it) {
60          final Set<String> keys = new HashSet<>();
61          while (it.hasNext()) {
62              keys.add(it.next());
63          }
64          return keys;
65      }
66  
67      /**
68       * Tests that exceptions thrown by the wrapped configuration are handled correctly.
69       */
70      @Test
71      void testExceptionHandling() {
72          final PropertiesConfiguration config = new PropertiesConfiguration();
73          final String property = "nonExistingProperty";
74          config.setThrowExceptionOnMissing(true);
75          final ImmutableConfiguration ic = ConfigurationUtils.unmodifiableConfiguration(config);
76          final NoSuchElementException e = assertThrows(NoSuchElementException.class, () -> ic.getString(property));
77          assertTrue(e.getMessage().contains(property));
78      }
79  
80      /**
81       * Tests whether an immutable subset can be queried.
82       */
83      @Test
84      void testImmutableSubset() throws ConfigurationException {
85          final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(createTestConfig());
86          final ImmutableConfiguration subset = conf.immutableSubset("test");
87          assertFalse(subset.isEmpty());
88          assertEquals(1000000, subset.getLong("long"));
89      }
90  
91      /**
92       * Tests whether data can be accessed from an unmodifiable configuration.
93       */
94      @Test
95      void testUnmodifiableConfigurationAccess() throws ConfigurationException {
96          final Configuration confOrg = createTestConfig();
97          final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(confOrg);
98          assertFalse(conf.isEmpty());
99          for (final Iterator<String> it = confOrg.getKeys(); it.hasNext();) {
100             final String key = it.next();
101             assertTrue(conf.containsKey(key), "Key not contained: " + key);
102             assertEquals(confOrg.getProperty(key), conf.getProperty(key), "Wrong value for " + key);
103         }
104     }
105 
106     /**
107      * Tests that a cast to a mutable configuration is not possible.
108      */
109     @Test
110     void testUnmodifiableConfigurationCast() throws ConfigurationException {
111         final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(createTestConfig());
112         assertThrows(ClassCastException.class, () -> ((Configuration) conf).clear());
113     }
114 
115     /**
116      * Tests an iteration over the keys of the immutable configuration.
117      */
118     @Test
119     void testUnmodifiableConfigurationIterate() throws ConfigurationException {
120         final Configuration confOrg = createTestConfig();
121         final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(confOrg);
122         assertEquals(fetchKeys(confOrg.getKeys()), fetchKeys(conf.getKeys()));
123     }
124 
125     /**
126      * Tests that it is not possible to remove keys using the iterator.
127      */
128     @Test
129     void testUnmodifiableConfigurationIteratorRemove() throws ConfigurationException {
130         final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(createTestConfig());
131         final Iterator<String> it = conf.getKeys();
132         it.next();
133         assertThrows(UnsupportedOperationException.class, it::remove);
134     }
135 
136     /**
137      * Tests whether an update of the original configuration is visible for the immutable view.
138      */
139     @Test
140     void testUnmodifiableConfigurationLiveUpdate() throws ConfigurationException {
141         final Configuration confOrg = createTestConfig();
142         final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(confOrg);
143         final String key = "new.property";
144         final String value = "new value";
145         confOrg.addProperty(key, value);
146         assertEquals(value, conf.getString(key));
147     }
148 
149     /**
150      * Tries to create an immutable configuration from a null object.
151      */
152     @Test
153     void testUnmodifiableConfigurationNull() {
154         assertThrows(NullPointerException.class, () -> ConfigurationUtils.unmodifiableConfiguration(null));
155     }
156 
157     /**
158      * Tests different access methods for properties.
159      */
160     @Test
161     void testUnmodifiableConfigurationOtherTypes() throws ConfigurationException {
162         final ImmutableConfiguration conf = ConfigurationUtils.unmodifiableConfiguration(createTestConfig());
163         assertEquals((byte) 10, conf.getByte("test.byte"));
164         assertTrue(conf.getBoolean("test.boolean"));
165         assertEquals(10.25, conf.getDouble("test.double"), .05);
166         assertEquals(20.25f, conf.getFloat("test.float"), .05);
167         assertEquals(10, conf.getInt("test.integer"));
168         assertEquals(1000000L, conf.getLong("test.long"));
169         assertEquals((short) 1, conf.getShort("test.short"));
170     }
171 
172     /**
173      * Tests whether an unmodifiable hierarchical configuration can be created.
174      */
175     @Test
176     void testUnmodifiableHierarchicalConfiguration() {
177         final HierarchicalConfiguration<?> conf = new BaseHierarchicalConfiguration();
178         final String key = "test";
179         conf.addProperty(key, Boolean.TRUE);
180         final ImmutableHierarchicalConfiguration ihc = ConfigurationUtils.unmodifiableConfiguration(conf);
181         assertTrue(ihc.getBoolean(key));
182         assertEquals(0, ihc.getMaxIndex(key));
183     }
184 }