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