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    *     http://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.builder.fluent;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
21  import static org.junit.jupiter.api.Assertions.assertNotEquals;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  import static org.mockito.ArgumentMatchers.any;
26  import static org.mockito.Mockito.doAnswer;
27  import static org.mockito.Mockito.mock;
28  import static org.mockito.Mockito.verify;
29  import static org.mockito.Mockito.verifyNoMoreInteractions;
30  
31  import java.nio.charset.StandardCharsets;
32  import java.util.ArrayList;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.apache.commons.configuration2.ConfigurationConsumer;
37  import org.apache.commons.configuration2.PropertiesConfiguration;
38  import org.apache.commons.configuration2.builder.BasicBuilderParameters;
39  import org.apache.commons.configuration2.builder.BasicBuilderProperties;
40  import org.apache.commons.configuration2.builder.BuilderParameters;
41  import org.apache.commons.configuration2.builder.DefaultParametersHandler;
42  import org.apache.commons.configuration2.builder.DefaultParametersManager;
43  import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
44  import org.apache.commons.configuration2.builder.combined.CombinedBuilderParametersImpl;
45  import org.apache.commons.configuration2.builder.combined.MultiFileBuilderParametersImpl;
46  import org.apache.commons.configuration2.convert.ListDelimiterHandler;
47  import org.apache.commons.configuration2.ex.ConfigurationException;
48  import org.apache.commons.configuration2.tree.ExpressionEngine;
49  import org.junit.jupiter.api.BeforeAll;
50  import org.junit.jupiter.api.Test;
51  
52  /**
53   * Test class for {@code Parameters}.
54   */
55  public class TestParameters {
56      /** A default encoding. */
57      private static final String DEF_ENCODING = StandardCharsets.UTF_8.name();
58  
59      /** A test list delimiter handler. */
60      private static ListDelimiterHandler listHandler;
61  
62      /**
63       * Checks whether the given parameters map contains the standard values for basic properties.
64       *
65       * @param map the map to be tested
66       */
67      private static void checkBasicProperties(final Map<String, Object> map) {
68          assertEquals(listHandler, map.get("listDelimiterHandler"));
69          assertEquals(Boolean.TRUE, map.get("throwExceptionOnMissing"));
70      }
71  
72      /**
73       * Checks whether a given parameters object implements all the specified interfaces.
74       *
75       * @param params the parameters object to check
76       * @param ifcClasses the interface classes to be implemented
77       */
78      private static void checkInheritance(final Object params, final Class<?>... ifcClasses) {
79          assertInstanceOf(BasicBuilderProperties.class, params);
80          for (final Class<?> c : ifcClasses) {
81              assertInstanceOf(c, params);
82          }
83      }
84  
85      /**
86       * Creates a mock for a defaults parameter handler.
87       *
88       * @return the mock object
89       */
90      @SuppressWarnings("unchecked")
91      private static DefaultParametersHandler<XMLBuilderParameters> createHandlerMock() {
92          return mock(DefaultParametersHandler.class);
93      }
94  
95      @BeforeAll
96      public static void setUpBeforeClass() throws Exception {
97          listHandler = mock(ListDelimiterHandler.class);
98      }
99  
100     /**
101      * Tests whether default values are set for newly created parameters objects.
102      */
103     @Test
104     public void testApplyDefaults() {
105         final DefaultParametersManager manager = mock(DefaultParametersManager.class);
106         final List<Object> initializedParams = new ArrayList<>(1);
107 
108         doAnswer(invocation -> {
109             initializedParams.add(invocation.getArgument(0));
110             return null;
111         }).when(manager).initializeParameters(any());
112 
113         final Parameters params = new Parameters(manager);
114         final XMLBuilderParameters xmlParams = params.xml();
115         assertEquals(1, initializedParams.size());
116         assertSame(xmlParams, initializedParams.get(0));
117 
118         verify(manager).initializeParameters(any());
119         verifyNoMoreInteractions(manager);
120     }
121 
122     /**
123      * Tests whether a basic parameters object can be created.
124      */
125     @Test
126     public void testBasic() {
127         final BasicBuilderParameters basic = new Parameters().basic();
128         assertNotNull(basic);
129     }
130 
131     /**
132      * Tests whether a combined parameters object can be created.
133      */
134     @Test
135     public void testCombined() {
136         final Map<String, Object> map = new Parameters().combined().setThrowExceptionOnMissing(true).setBasePath("test").setListDelimiterHandler(listHandler)
137             .getParameters();
138         final CombinedBuilderParametersImpl cparams = CombinedBuilderParametersImpl.fromParameters(map);
139         assertEquals("test", cparams.getBasePath());
140         checkBasicProperties(map);
141     }
142 
143     /**
144      * Tests whether a parameters object for a database configuration can be created.
145      */
146     @Test
147     public void testDatabase() {
148         final Map<String, Object> map = new Parameters().database().setThrowExceptionOnMissing(true).setAutoCommit(true).setTable("table")
149             .setListDelimiterHandler(listHandler).setKeyColumn("keyColumn").getParameters();
150         checkBasicProperties(map);
151         assertEquals("table", map.get("table"));
152         assertEquals("keyColumn", map.get("keyColumn"));
153         assertEquals(Boolean.TRUE, map.get("autoCommit"));
154     }
155 
156     /**
157      * Tests whether an uninitialized default parameters manager is created at construction time.
158      */
159     @Test
160     public void testDefaultParametersManager() {
161         final Parameters parameters = new Parameters();
162         assertNotNull(parameters.getDefaultParametersManager());
163     }
164 
165     /**
166      * Tests whether a file-based parameters object can be created.
167      */
168     @Test
169     public void testFileBased() {
170         final Map<String, Object> map = new Parameters().fileBased().setThrowExceptionOnMissing(true).setEncoding(DEF_ENCODING)
171             .setListDelimiterHandler(listHandler).setFileName("test.xml").getParameters();
172         final FileBasedBuilderParametersImpl fbparams = FileBasedBuilderParametersImpl.fromParameters(map);
173         assertEquals("test.xml", fbparams.getFileHandler().getFileName());
174         assertEquals(DEF_ENCODING, fbparams.getFileHandler().getEncoding());
175         checkBasicProperties(map);
176     }
177 
178     /**
179      * Tests the inheritance structure of a fileBased parameters object.
180      */
181     @Test
182     public void testFileBasedInheritance() {
183         checkInheritance(new Parameters().fileBased());
184     }
185 
186     /**
187      * Tests whether a parameters object for a hierarchical configuration can be created.
188      */
189     @Test
190     public void testHierarchical() {
191         final ExpressionEngine engine = mock(ExpressionEngine.class);
192         final Map<String, Object> map = new Parameters().hierarchical().setThrowExceptionOnMissing(true).setExpressionEngine(engine).setFileName("test.xml")
193             .setListDelimiterHandler(listHandler).getParameters();
194         checkBasicProperties(map);
195         final FileBasedBuilderParametersImpl fbp = FileBasedBuilderParametersImpl.fromParameters(map);
196         assertEquals("test.xml", fbp.getFileHandler().getFileName());
197         assertEquals(engine, map.get("expressionEngine"));
198     }
199 
200     /**
201      * Tests the inheritance structure of a hierarchical parameters object.
202      */
203     @Test
204     public void testHierarchicalInheritance() {
205         checkInheritance(new Parameters().hierarchical(), FileBasedBuilderParameters.class);
206     }
207 
208     /**
209      * Tests whether the parameters objects created by the Parameters instance have a logic inheritance hierarchy. This
210      * means that they also implement all base interfaces that make sense.
211      */
212     @Test
213     public void testInheritance() {
214         final Object params = new Parameters().xml();
215         final FileBasedBuilderParameters fbParams = assertInstanceOf(FileBasedBuilderParameters.class, params);
216         fbParams.setListDelimiterHandler(listHandler).setFileName("test.xml").setThrowExceptionOnMissing(true);
217         final ExpressionEngine engine = mock(ExpressionEngine.class);
218         ((HierarchicalBuilderParameters) params).setExpressionEngine(engine);
219         final Map<String, Object> map = fbParams.getParameters();
220         checkBasicProperties(map);
221         assertSame(engine, map.get("expressionEngine"));
222     }
223 
224     /**
225      * Tests whether a JNDI parameters object can be created.
226      */
227     @Test
228     public void testJndi() {
229         final Map<String, Object> map = new Parameters().jndi().setThrowExceptionOnMissing(true).setPrefix("test").setListDelimiterHandler(listHandler)
230             .getParameters();
231         assertEquals("test", map.get("prefix"));
232         checkBasicProperties(map);
233     }
234 
235     /**
236      * Tests whether a {@code MultiFileBuilderParameters} object can be created.
237      */
238     @Test
239     public void testMultiFile() {
240         final BuilderParameters bp = mock(BuilderParameters.class);
241         final String pattern = "a pattern";
242         final Map<String, Object> map = new Parameters().multiFile().setThrowExceptionOnMissing(true).setFilePattern(pattern)
243             .setListDelimiterHandler(listHandler).setManagedBuilderParameters(bp).getParameters();
244         checkBasicProperties(map);
245         final MultiFileBuilderParametersImpl params = MultiFileBuilderParametersImpl.fromParameters(map);
246         assertSame(bp, params.getManagedBuilderParameters());
247         assertEquals(pattern, params.getFilePattern());
248     }
249 
250     /**
251      * Tests whether a parameters object for a properties configuration can be created.
252      */
253     @Test
254     public void testProperties() {
255         final PropertiesConfiguration.IOFactory factory = mock(PropertiesConfiguration.IOFactory.class);
256         @SuppressWarnings("unchecked")
257         final ConfigurationConsumer<ConfigurationException> includeListener = mock(ConfigurationConsumer.class);
258         // @formatter:off
259         final Map<String, Object> map =
260                 new Parameters().properties()
261                         .setThrowExceptionOnMissing(true)
262                         .setFileName("test.properties")
263                         .setIncludeListener(includeListener)
264                         .setIOFactory(factory)
265                         .setListDelimiterHandler(listHandler)
266                         .setIncludesAllowed(false)
267                         .getParameters();
268         // @formatter:on
269         checkBasicProperties(map);
270         final FileBasedBuilderParametersImpl fbp = FileBasedBuilderParametersImpl.fromParameters(map);
271         assertEquals("test.properties", fbp.getFileHandler().getFileName());
272         assertEquals(Boolean.FALSE, map.get("includesAllowed"));
273         assertSame(includeListener, map.get("includeListener"));
274         assertSame(factory, map.get("IOFactory"));
275     }
276 
277     /**
278      * Tests the inheritance structure of a properties parameters object.
279      */
280     @Test
281     public void testPropertiesInheritance() {
282         checkInheritance(new Parameters().properties(), FileBasedBuilderParameters.class);
283     }
284 
285     /**
286      * Tests whether the proxy parameters object can deal with methods inherited from Object.
287      */
288     @Test
289     public void testProxyObjectMethods() {
290         final FileBasedBuilderParameters params = new Parameters().fileBased();
291         final String s = params.toString();
292         assertTrue(s.contains(FileBasedBuilderParametersImpl.class.getSimpleName()));
293         assertNotEquals(0, params.hashCode());
294     }
295 
296     /**
297      * Tests the registration of a defaults handler if no start class is provided.
298      */
299     @Test
300     public void testRegisterDefaultsHandlerNoStartClass() {
301         final DefaultParametersManager manager = mock(DefaultParametersManager.class);
302         final DefaultParametersHandler<XMLBuilderParameters> handler = createHandlerMock();
303 
304         final Parameters params = new Parameters(manager);
305         params.registerDefaultsHandler(XMLBuilderParameters.class, handler);
306 
307         verify(manager).registerDefaultsHandler(XMLBuilderParameters.class, handler);
308         verifyNoMoreInteractions(manager);
309     }
310 
311     /**
312      * Tests whether a default handler with a start class can be registered.
313      */
314     @Test
315     public void testRegisterDefaultsHandlerWithStartClass() {
316         final DefaultParametersManager manager = mock(DefaultParametersManager.class);
317         final DefaultParametersHandler<XMLBuilderParameters> handler = createHandlerMock();
318 
319         final Parameters params = new Parameters(manager);
320         params.registerDefaultsHandler(XMLBuilderParameters.class, handler, FileBasedBuilderParameters.class);
321 
322         verify(manager).registerDefaultsHandler(XMLBuilderParameters.class, handler, FileBasedBuilderParameters.class);
323         verifyNoMoreInteractions(manager);
324     }
325 
326     /**
327      * Tests whether a parameters object for an XML configuration can be created.
328      */
329     @Test
330     public void testXml() {
331         final ExpressionEngine engine = mock(ExpressionEngine.class);
332         final Map<String, Object> map = new Parameters().xml().setThrowExceptionOnMissing(true).setFileName("test.xml").setValidating(true)
333             .setExpressionEngine(engine).setListDelimiterHandler(listHandler).setSchemaValidation(true).getParameters();
334         checkBasicProperties(map);
335         final FileBasedBuilderParametersImpl fbp = FileBasedBuilderParametersImpl.fromParameters(map);
336         assertEquals("test.xml", fbp.getFileHandler().getFileName());
337         assertEquals(Boolean.TRUE, map.get("validating"));
338         assertEquals(Boolean.TRUE, map.get("schemaValidation"));
339         assertEquals(engine, map.get("expressionEngine"));
340     }
341 
342     /**
343      * Tests the inheritance structure of an XML parameters object.
344      */
345     @Test
346     public void testXmlInheritance() {
347         checkInheritance(new Parameters().xml(), HierarchicalBuilderParameters.class, FileBasedBuilderParameters.class);
348     }
349 }