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;
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.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertSame;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.mockito.Mockito.mock;
25  
26  import java.nio.charset.StandardCharsets;
27  import java.util.Map;
28  
29  import org.apache.commons.configuration2.builder.fluent.FileBasedBuilderParameters;
30  import org.apache.commons.configuration2.builder.fluent.Parameters;
31  import org.apache.commons.configuration2.builder.fluent.PropertiesBuilderParameters;
32  import org.apache.commons.configuration2.builder.fluent.XMLBuilderParameters;
33  import org.apache.commons.configuration2.convert.ListDelimiterHandler;
34  import org.apache.commons.configuration2.tree.ExpressionEngine;
35  import org.junit.jupiter.api.BeforeAll;
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * Test class for {@code DefaultParametersManager}.
41   */
42  public class TestDefaultParametersManager {
43      /**
44       * A test defaults handler implementation for testing the initialization of parameters objects with default values. This
45       * class sets some hard-coded default values.
46       */
47      private static final class FileBasedDefaultsHandler implements DefaultParametersHandler<FileBasedBuilderParameters> {
48          @Override
49          public void initializeDefaults(final FileBasedBuilderParameters parameters) {
50              parameters.setThrowExceptionOnMissing(true).setEncoding(DEF_ENCODING).setListDelimiterHandler(listHandler);
51          }
52      }
53  
54      /** Constant for the default encoding. */
55      private static final String DEF_ENCODING = StandardCharsets.UTF_8.name();
56  
57      /** A test list delimiter handler. */
58      private static ListDelimiterHandler listHandler;
59  
60      /**
61       * Checks whether the expected default values have been set on a parameters object.
62       *
63       * @param map the map with parameters
64       */
65      private static void checkDefaultValues(final Map<String, Object> map) {
66          assertEquals(listHandler, map.get("listDelimiterHandler"));
67          assertEquals(Boolean.TRUE, map.get("throwExceptionOnMissing"));
68          final FileBasedBuilderParametersImpl fbparams = FileBasedBuilderParametersImpl.fromParameters(map);
69          assertEquals(DEF_ENCODING, fbparams.getFileHandler().getEncoding());
70      }
71  
72      /**
73       * Checks that no default values have been set on a parameters object.
74       *
75       * @param map the map with parameters
76       */
77      private static void checkNoDefaultValues(final Map<String, Object> map) {
78          assertFalse(map.containsKey("throwExceptionOnMissing"));
79          final FileBasedBuilderParametersImpl fbParams = FileBasedBuilderParametersImpl.fromParameters(map, true);
80          assertNull(fbParams.getFileHandler().getEncoding());
81      }
82  
83      @BeforeAll
84      public static void setUpBeforeClass() throws Exception {
85          listHandler = mock(ListDelimiterHandler.class);
86      }
87  
88      /** An object for creating new parameters objects. */
89      private Parameters parameters;
90  
91      /** The manager to be tested. */
92      private DefaultParametersManager manager;
93  
94      @BeforeEach
95      public void setUp() throws Exception {
96          parameters = new Parameters();
97          manager = new DefaultParametersManager();
98      }
99  
100     /**
101      * Tests whether default values are set for newly created parameters objects.
102      */
103     @Test
104     public void testApplyDefaults() {
105         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, new FileBasedDefaultsHandler());
106         final FileBasedBuilderParameters params = parameters.fileBased();
107         manager.initializeParameters(params);
108         final Map<String, Object> map = params.getParameters();
109         checkDefaultValues(map);
110     }
111 
112     /**
113      * Tests whether multiple handlers can be registered for the same classes and whether they are called in the correct
114      * order.
115      */
116     @Test
117     public void testApplyDefaultsMultipleHandlers() {
118         final ExpressionEngine engine = mock(ExpressionEngine.class);
119         manager.registerDefaultsHandler(XMLBuilderParameters.class, parameters -> parameters.setThrowExceptionOnMissing(false)
120             .setListDelimiterHandler(mock(ListDelimiterHandler.class)).setExpressionEngine(engine));
121         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, new FileBasedDefaultsHandler());
122         final XMLBuilderParameters params = parameters.xml();
123         manager.initializeParameters(params);
124         final Map<String, Object> map = params.getParameters();
125         checkDefaultValues(map);
126         assertSame(engine, map.get("expressionEngine"));
127     }
128 
129     /**
130      * Tests whether default values are also applied when a sub parameters class is created.
131      */
132     @Test
133     public void testApplyDefaultsOnSubClass() {
134         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, new FileBasedDefaultsHandler());
135         final XMLBuilderParameters params = parameters.xml();
136         manager.initializeParameters(params);
137         final Map<String, Object> map = params.getParameters();
138         checkDefaultValues(map);
139     }
140 
141     /**
142      * Tests that default values are only applied if the start class provided at registration time matches.
143      */
144     @Test
145     public void testApplyDefaultsStartClass() {
146         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, new FileBasedDefaultsHandler(), XMLBuilderParameters.class);
147         final XMLBuilderParameters paramsXml = parameters.xml();
148         manager.initializeParameters(paramsXml);
149         Map<String, Object> map = paramsXml.getParameters();
150         checkDefaultValues(map);
151         final PropertiesBuilderParameters paramsProps = parameters.properties();
152         manager.initializeParameters(paramsProps);
153         map = paramsProps.getParameters();
154         checkNoDefaultValues(map);
155     }
156 
157     /**
158      * Tests whether initializeParameters() ignores null input. (We can only test that no exception is thrown.)
159      */
160     @Test
161     public void testInitializeParametersNull() {
162         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, new FileBasedDefaultsHandler());
163         manager.initializeParameters(null);
164     }
165 
166     /**
167      * Tries to register a default handler without a class.
168      */
169     @Test
170     public void testRegisterDefaultsHandlerNoClass() {
171         final FileBasedDefaultsHandler handler = new FileBasedDefaultsHandler();
172         assertThrows(IllegalArgumentException.class, () -> manager.registerDefaultsHandler(null, handler));
173     }
174 
175     /**
176      * Tries to register a null default handler.
177      */
178     @Test
179     public void testRegisterDefaultsHandlerNoHandler() {
180         assertThrows(IllegalArgumentException.class, () -> manager.registerDefaultsHandler(BasicBuilderProperties.class, null));
181     }
182 
183     /**
184      * Tests whether all occurrences of a given defaults handler can be removed.
185      */
186     @Test
187     public void testUnregisterDefaultsHandlerAll() {
188         final FileBasedDefaultsHandler handler = new FileBasedDefaultsHandler();
189         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, handler, XMLBuilderParameters.class);
190         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, handler, PropertiesBuilderParameters.class);
191         manager.unregisterDefaultsHandler(handler);
192 
193         final XMLBuilderParameters paramsXml = parameters.xml();
194         manager.initializeParameters(paramsXml);
195         checkNoDefaultValues(paramsXml.getParameters());
196         final PropertiesBuilderParameters paramsProps = parameters.properties();
197         manager.initializeParameters(paramsProps);
198         checkNoDefaultValues(paramsProps.getParameters());
199     }
200 
201     /**
202      * Tests whether a specific occurrence of a defaults handler can be removed.
203      */
204     @Test
205     public void testUnregisterDefaultsHandlerSpecific() {
206         final FileBasedDefaultsHandler handler = new FileBasedDefaultsHandler();
207         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, handler, XMLBuilderParameters.class);
208         manager.registerDefaultsHandler(FileBasedBuilderParameters.class, handler, PropertiesBuilderParameters.class);
209         manager.unregisterDefaultsHandler(handler, PropertiesBuilderParameters.class);
210         final XMLBuilderParameters paramsXml = parameters.xml();
211         manager.initializeParameters(paramsXml);
212         checkDefaultValues(paramsXml.getParameters());
213         final PropertiesBuilderParameters paramsProps = parameters.properties();
214         manager.initializeParameters(paramsProps);
215         checkNoDefaultValues(paramsProps.getParameters());
216     }
217 }