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