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  
18  package org.apache.commons.configuration;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotNull;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertTrue;
25  
26  import java.util.Hashtable;
27  import java.util.Properties;
28  
29  import javax.naming.Context;
30  import javax.naming.InitialContext;
31  import javax.naming.NameNotFoundException;
32  import javax.naming.NamingException;
33  
34  import org.junit.After;
35  import org.junit.Before;
36  import org.junit.Test;
37  
38  /**
39   * Test to see if the JNDIConfiguration works properly.
40   *
41   * @version $Id: TestJNDIConfiguration.java 1301996 2012-03-17 20:30:39Z sebb $
42   */
43  public class TestJNDIConfiguration {
44  
45      public static final String CONTEXT_FACTORY = MockInitialContextFactory.class.getName();
46  
47      private PotentialErrorJNDIConfiguration conf;
48      private NonStringTestHolder nonStringTestHolder;
49  
50      /** A test error listener for counting internal errors.*/
51      private ConfigurationErrorListenerImpl listener;
52  
53      @Before
54      public void setUp() throws Exception {
55  
56          System.setProperty("java.naming.factory.initial", CONTEXT_FACTORY);
57  
58          Properties props = new Properties();
59          props.put("java.naming.factory.initial", CONTEXT_FACTORY);
60          Context ctx = new InitialContext(props);
61          conf = new PotentialErrorJNDIConfiguration(ctx);
62  
63          nonStringTestHolder = new NonStringTestHolder();
64          nonStringTestHolder.setConfiguration(conf);
65  
66          listener = new ConfigurationErrorListenerImpl();
67          conf.addErrorListener(listener);
68      }
69  
70      /**
71       * Clears the test environment. If an error listener is defined, checks
72       * whether no error event was received.
73       */
74      @After
75      public void tearDown() throws Exception
76      {
77          if (listener != null)
78          {
79              listener.verify();
80          }
81      }
82  
83      @Test
84      public void testBoolean() throws Exception {
85          nonStringTestHolder.testBoolean();
86      }
87  
88      @Test
89      public void testBooleanDefaultValue() throws Exception {
90          nonStringTestHolder.testBooleanDefaultValue();
91      }
92  
93      @Test
94      public void testByte() throws Exception {
95          nonStringTestHolder.testByte();
96      }
97  
98      @Test
99      public void testDouble() throws Exception {
100         nonStringTestHolder.testDouble();
101     }
102 
103     @Test
104     public void testDoubleDefaultValue() throws Exception {
105         nonStringTestHolder.testDoubleDefaultValue();
106     }
107 
108     @Test
109     public void testFloat() throws Exception {
110         nonStringTestHolder.testFloat();
111     }
112 
113     @Test
114     public void testFloatDefaultValue() throws Exception {
115         nonStringTestHolder.testFloatDefaultValue();
116     }
117 
118     @Test
119     public void testInteger() throws Exception {
120         nonStringTestHolder.testInteger();
121     }
122 
123     @Test
124     public void testIntegerDefaultValue() throws Exception {
125         nonStringTestHolder.testIntegerDefaultValue();
126     }
127 
128     @Test
129     public void testLong() throws Exception {
130         nonStringTestHolder.testLong();
131     }
132 
133     @Test
134     public void testLongDefaultValue() throws Exception {
135         nonStringTestHolder.testLongDefaultValue();
136     }
137 
138     @Test
139     public void testShort() throws Exception {
140         nonStringTestHolder.testShort();
141     }
142 
143     @Test
144     public void testShortDefaultValue() throws Exception {
145         nonStringTestHolder.testShortDefaultValue();
146     }
147 
148     @Test
149     public void testListMissing() throws Exception {
150         nonStringTestHolder.testListMissing();
151     }
152 
153     @Test
154     public void testSubset() throws Exception {
155         nonStringTestHolder.testSubset();
156     }
157 
158     @Test
159     public void testProperties() throws Exception {
160         Object o = conf.getProperty("test.boolean");
161         assertNotNull(o);
162         assertEquals("true", o.toString());
163     }
164 
165     @Test
166     public void testContainsKey()
167     {
168         String key = "test.boolean";
169         assertTrue("'" + key + "' not found", conf.containsKey(key));
170 
171         conf.clearProperty(key);
172         assertFalse("'" + key + "' still found", conf.containsKey(key));
173     }
174 
175     @Test
176     public void testChangePrefix()
177     {
178         assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));
179         assertEquals("'boolean' property", null, conf.getString("boolean"));
180 
181         // change the prefix
182         conf.setPrefix("test");
183         assertEquals("'test.boolean' property", null, conf.getString("test.boolean"));
184         assertEquals("'boolean' property", "true", conf.getString("boolean"));
185     }
186 
187     @Test
188     public void testResetRemovedProperties() throws Exception
189     {
190         assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));
191 
192         // remove the property
193         conf.clearProperty("test.boolean");
194         assertEquals("'test.boolean' property", null, conf.getString("test.boolean"));
195 
196         // change the context
197         conf.setContext(new InitialContext());
198 
199         // get the property
200         assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));
201     }
202 
203     @Test
204     public void testConstructor() throws Exception
205     {
206         // test the constructor accepting a context
207         JNDIConfiguration c = new JNDIConfiguration(new InitialContext());
208 
209         assertEquals("'test.boolean' property", "true", c.getString("test.boolean"));
210 
211         // test the constructor accepting a context and a prefix
212         c = new JNDIConfiguration(new InitialContext(), "test");
213 
214         assertEquals("'boolean' property", "true", c.getString("boolean"));
215     }
216 
217     /**
218      * Configures the test config to throw an exception.
219      */
220     private PotentialErrorJNDIConfiguration setUpErrorConfig()
221     {
222         conf.installException();
223         conf.removeErrorListener(conf.getErrorListeners().iterator().next());
224         return conf;
225     }
226 
227     /**
228      * Tests whether the expected error events have been received.
229      *
230      * @param type the expected event type
231      * @param propName the name of the property
232      * @param propValue the property value
233      */
234     private void checkErrorListener(int type, String propName, Object propValue)
235     {
236         listener.verify(type, propName, propValue);
237         assertTrue("Wrong exception class",
238                 listener.getLastEvent().getCause() instanceof NamingException);
239         listener = null;
240     }
241 
242     /**
243      * Tests whether a JNDI configuration registers an error log listener.
244      */
245     @Test
246     public void testLogListener() throws NamingException
247     {
248         JNDIConfiguration c = new JNDIConfiguration();
249         assertEquals("No error log listener registered", 1, c
250                 .getErrorListeners().size());
251     }
252 
253     /**
254      * Tests handling of errors in getKeys().
255      */
256     @Test
257     public void testGetKeysError()
258     {
259         assertFalse("Iteration not empty", setUpErrorConfig().getKeys()
260                 .hasNext());
261         checkErrorListener(AbstractConfiguration.EVENT_READ_PROPERTY, null,
262                 null);
263     }
264 
265     /**
266      * Tests handling of errors in isEmpty().
267      */
268     @Test
269     public void testIsEmptyError() throws Exception
270     {
271         assertTrue("Error config not empty", setUpErrorConfig().isEmpty());
272         checkErrorListener(AbstractConfiguration.EVENT_READ_PROPERTY, null,
273                 null);
274     }
275 
276     /**
277      * Tests handling of errors in the containsKey() method.
278      */
279     @Test
280     public void testContainsKeyError()
281     {
282         assertFalse("Key contained after error", setUpErrorConfig()
283                 .containsKey("key"));
284         checkErrorListener(AbstractConfiguration.EVENT_READ_PROPERTY, "key",
285                 null);
286     }
287 
288     /**
289      * Tests handling of errors in getProperty().
290      */
291     @Test
292     public void testGetPropertyError()
293     {
294         assertNull("Wrong property value after error", setUpErrorConfig()
295                 .getProperty("key"));
296         checkErrorListener(AbstractConfiguration.EVENT_READ_PROPERTY, "key",
297                 null);
298     }
299 
300     /**
301      * Tests the getKeys() method when there are cycles in the tree.
302      */
303     @Test
304     public void testGetKeysWithCycles() throws NamingException
305     {
306         Hashtable<Object, Object> env = new Hashtable<Object, Object>();
307         env.put(MockInitialContextFactory.PROP_CYCLES, Boolean.TRUE);
308         InitialContext initCtx = new InitialContext(env);
309         JNDIConfiguration c = new JNDIConfiguration(initCtx);
310         c.getKeys("cycle");
311     }
312 
313     /**
314      * Tests getKeys() if no data is found. This should not cause a problem and
315      * not notify the error listeners.
316      */
317     @Test
318     public void testGetKeysNoData()
319     {
320         conf.installException(new NameNotFoundException("Test exception"));
321         assertFalse("Got keys", conf.getKeys().hasNext());
322         listener.verify();
323     }
324 
325     /**
326      * A special JNDI configuration implementation that can be configured to
327      * throw an exception when accessing the base context. Used for testing the
328      * exception handling.
329      */
330     public static class PotentialErrorJNDIConfiguration extends
331             JNDIConfiguration
332     {
333         /** An exception to be thrown by getBaseContext(). */
334         private NamingException exception;
335 
336         public PotentialErrorJNDIConfiguration(Context ctx)
337                 throws NamingException
338         {
339             super(ctx);
340         }
341 
342         /**
343          * Prepares this object to throw an exception when the JNDI context is
344          * queried.
345          *
346          * @param nex the exception to be thrown
347          */
348         public void installException(NamingException nex)
349         {
350             exception = nex;
351         }
352 
353         /**
354          * Prepares this object to throw a standard exception when the JNDI
355          * context is queried.
356          */
357         public void installException()
358         {
359             installException(new NamingException("Simulated JNDI exception!"));
360         }
361 
362         /**
363          * Returns the JNDI context. Optionally throws an exception.
364          */
365         @Override
366         public Context getBaseContext() throws NamingException
367         {
368             if (exception != null)
369             {
370                 throw exception;
371             }
372             return super.getBaseContext();
373         }
374     }
375 }