    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 }