    1   package org.apache.commons.configuration;
    2
    3   /*
    4    * Licensed to the Apache Software Foundation (ASF) under one or more
    5    * contributor license agreements.  See the NOTICE file distributed with
    6    * this work for additional information regarding copyright ownership.
    7    * The ASF licenses this file to You under the Apache License, Version 2.0
    8    * (the "License"); you may not use this file except in compliance with
    9    * the License.  You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19
    20  import junit.framework.TestCase;
    21
    22  import java.io.File;
    23  import java.util.Collection;
    24  import java.util.Iterator;
    25
    26  /***
    27   * Test class for XMLConfiguration. In addition to TestXMLConfiguration this
    28   * class especially tests the hierarchical nature of this class and structured
    29   * data access.
    30   *
    31   * @author Emmanuel Bourg
    32   * @author Mark Woodman
    33   * @author Oliver Heger
    34   * @version $Id: TestHierarchicalXMLConfiguration.java 439648 2006-09-02 20:42:10Z oheger $
    35   */
    36  public class TestHierarchicalXMLConfiguration extends TestCase
    37  {
    38      /*** Test resources directory. */
    39      private static final String TEST_DIR = "conf";
    40
    41      /*** Test file #1 **/
    42      private static final String TEST_FILENAME = "testHierarchicalXMLConfiguration.xml";
    43
    44      /*** Test file #2 **/
    45      private static final String TEST_FILENAME2 = "testHierarchicalXMLConfiguration2.xml";
    46
    47      /*** Test file path #1 **/
    48      private static final String TEST_FILE = TEST_DIR + File.separator + TEST_FILENAME;
    49
    50      /*** Test file path #2 **/
    51      private static final String TEST_FILE2 = TEST_DIR + File.separator + TEST_FILENAME2;
    52
    53      /*** Test file path #3.*/
    54      private static final String TEST_FILE3 = TEST_DIR + File.separator + "test.xml";
    55
    56      /*** File name for saving.*/
    57      private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
    58
    59      /*** File path for saving.*/
    60      private static final String TEST_SAVE = "target" + File.separator + TEST_SAVENAME;
    61
    62      /*** Instance config used for tests. */
    63      private XMLConfiguration config;
    64
    65      /*** Fixture setup. */
    66      protected void setUp() throws Exception
    67      {
    68          config = new XMLConfiguration();
    69      }
    70
    71      private void configTest(XMLConfiguration config)
    72      {
    73          assertEquals(1, config.getMaxIndex("tables.table"));
    74          assertEquals("system", config.getProperty("tables.table(0)[@tableType]"));
    75          assertEquals("application", config.getProperty("tables.table(1)[@tableType]"));
    76
    77          assertEquals("users", config.getProperty("tables.table(0).name"));
    78          assertEquals("documents", config.getProperty("tables.table(1).name"));
    79
    80          Object prop = config.getProperty("tables.table.fields.field.name");
    81          assertTrue(prop instanceof Collection);
    82          assertEquals(10, ((Collection) prop).size());
    83
    84          prop = config.getProperty("tables.table(0).fields.field.type");
    85          assertTrue(prop instanceof Collection);
    86          assertEquals(5, ((Collection) prop).size());
    87
    88          prop = config.getProperty("tables.table(1).fields.field.type");
    89          assertTrue(prop instanceof Collection);
    90          assertEquals(5, ((Collection) prop).size());
    91      }
    92
    93      public void testGetProperty() throws Exception
    94      {
    95          config.setFileName(TEST_FILE);
    96          config.load();
    97
    98          configTest(config);
    99      }
    100
    101     public void testLoadURL() throws Exception
    102     {
    103         config.load(new File(TEST_FILE).getAbsoluteFile().toURL());
    104         configTest(config);
    105     }
    106
    107     public void testLoadBasePath1() throws Exception
    108     {
    109         config.setBasePath(TEST_DIR);
    110         config.setFileName(TEST_FILENAME);
    111         config.load();
    112         configTest(config);
    113     }
    114
    115     public void testLoadBasePath2() throws Exception
    116     {
    117         config.setBasePath(new File(TEST_FILE).getAbsoluteFile().toURL().toString());
    118         config.setFileName(TEST_FILENAME);
    119         config.load();
    120         configTest(config);
    121     }
    122
    123     /***
    124      * Ensure various node types are correctly processed in config.
    125      * @throws Exception
    126      */
    127     public void testXmlNodeTypes() throws Exception
    128     {
    129         // Number of keys expected from test configuration file
    130         final int KEY_COUNT = 5;
    131
    132         // Load the configuration file
    133         config.load(new File(TEST_FILE2).getAbsoluteFile().toURL());
    134
    135         // Validate comment in element ignored
    136         assertEquals("Comment in element must not change element value.", "Case1Text", config
    137                 .getString("case1"));
    138
    139         // Validate sibling comment ignored
    140         assertEquals("Comment as sibling must not change element value.", "Case2Text", config
    141                 .getString("case2.child"));
    142
    143         // Validate comment ignored, CDATA processed
    144         assertEquals("Comment and use of CDATA must not change element value.", "Case3Text", config
    145                 .getString("case3"));
    146
    147         // Validate comment and processing instruction ignored
    148         assertEquals("Comment and use of PI must not change element value.", "Case4Text", config
    149                 .getString("case4"));
    150
    151         // Validate comment ignored in parent attribute
    152         assertEquals("Comment must not change attribute node value.", "Case5Text", config
    153                 .getString("case5[@attr]"));
    154
    155         // Validate non-text nodes haven't snuck in as keys
    156         Iterator iter = config.getKeys();
    157         int count = 0;
    158         while (iter.hasNext())
    159         {
    160             iter.next();
    161             count++;
    162         }
    163         assertEquals("Config must contain only " + KEY_COUNT + " keys.", KEY_COUNT, count);
    164     }
    165
    166     public void testSave() throws Exception
    167     {
    168         removeTestSaveFile();
    169         try
    170         {
    171             config.setFileName(TEST_FILE3);
    172             config.load();
    173             File saveFile = new File(TEST_SAVE);
    174             config.save(saveFile);
    175
    176             config = new XMLConfiguration();
    177             config.load(saveFile.toURL());
    178             assertEquals("value", config.getProperty("element"));
    179             assertEquals("I'm complex!", config.getProperty("element2.subelement.subsubelement"));
    180             assertEquals(8, config.getInt("test.short"));
    181             assertEquals("one", config.getString("list(0).item(0)[@name]"));
    182             assertEquals("two", config.getString("list(0).item(1)"));
    183             assertEquals("six", config.getString("list(1).sublist.item(1)"));
    184
    185         }
    186         finally
    187         {
    188             removeTestSaveFile();
    189         }
    190     }
    191
    192     /***
    193      * Tests to save a newly created configuration.
    194      *
    195      */
    196     public void testSaveNew() throws Exception
    197     {
    198         config.addProperty("connection.url", "jdbc://mydb:1234");
    199         config.addProperty("connection.user", "scott");
    200         config.addProperty("connection.passwd", "tiger");
    201         config.addProperty("connection[@type]", "system");
    202         config.addProperty("tables.table.name", "tests");
    203         config.addProperty("tables.table(0).fields.field.name", "test_id");
    204         config.addProperty("tables.table(0).fields.field(-1).name", "test_name");
    205         config.addProperty("tables.table(-1).name", "results");
    206         config.addProperty("tables.table(1).fields.field.name", "res_id");
    207         config.addProperty("tables.table(1).fields.field(0).type", "int");
    208         config.addProperty("tables.table(1).fields.field(-1).name", "value");
    209         config.addProperty("tables.table(1).fields.field(1).type", "string");
    210         config.addProperty("tables.table(1).fields.field(1)[@null]", "true");
    211
    212         removeTestSaveFile();
    213         try
    214         {
    215             File saveFile = new File(TEST_SAVE);
    216             config.setFile(saveFile);
    217             config.setRootElementName("myconfig");
    218             config.save();
    219
    220             config = new XMLConfiguration();
    221             config.load(saveFile);
    222             assertEquals(1, config.getMaxIndex("tables.table.name"));
    223             assertEquals("tests", config.getString("tables.table(0).name"));
    224             assertEquals("test_name", config.getString("tables.table(0).fields.field(1).name"));
    225             assertEquals("int", config.getString("tables.table(1).fields.field(0).type"));
    226             assertTrue(config.getBoolean("tables.table(1).fields.field(1)[@null]"));
    227             assertEquals("tiger", config.getString("connection.passwd"));
    228             assertEquals("system", config.getProperty("connection[@type]"));
    229             assertEquals("myconfig", config.getRootElementName());
    230         }
    231         finally
    232         {
    233             removeTestSaveFile();
    234         }
    235     }
    236
    237     /***
    238      * Tests to save a modified configuration.
    239      *
    240      */
    241     public void testSaveModified() throws Exception
    242     {
    243         config.setFile(new File(TEST_FILE3));
    244         config.load();
    245
    246         assertTrue(config.getString("mean").startsWith("This is\n A long story..."));
    247         assertTrue(config.getString("mean").indexOf("And even longer") > 0);
    248         config.clearProperty("test.entity[@name]");
    249         config.setProperty("element", "new value");
    250         config.setProperty("test(0)", "A <new> value");
    251         config.addProperty("test(1).int", new Integer(9));
    252         config.addProperty("list(1).sublist.item", "seven");
    253         config.setProperty("clear", "yes");
    254         config.setProperty("mean", "now it's simple");
    255         config.addProperty("[@topattr]", "available");
    256         config.addProperty("[@topattr]", "successfull");
    257
    258         removeTestSaveFile();
    259         try
    260         {
    261             config.save(new File(TEST_SAVE));
    262             config = new XMLConfiguration();
    263             config.load(TEST_SAVE);
    264             assertFalse(config.containsKey("test.entity[@name]"));
    265             assertEquals("1<2", config.getProperty("test.entity"));
    266             assertEquals("new value", config.getString("element"));
    267             assertEquals("A <new> value", config.getProperty("test(0)"));
    268             assertEquals((short) 8, config.getShort("test(1).short"));
    269             assertEquals(9, config.getInt("test(1).int"));
    270             assertEquals("six", config.getProperty("list(1).sublist.item(1)"));
    271             assertEquals("seven", config.getProperty("list(1).sublist.item(2)"));
    272             assertEquals("yes", config.getProperty("clear"));
    273             assertEquals("now it's simple", config.getString("mean"));
    274             assertEquals("available", config.getString("[@topattr](0)"));
    275             assertEquals("successfull", config.getString("[@topattr](1)"));
    276         }
    277         finally
    278         {
    279             removeTestSaveFile();
    280         }
    281     }
    282
    283     /***
    284      * Tests manipulation of the root element's name.
    285      *
    286      */
    287     public void testRootElement() throws Exception
    288     {
    289         assertEquals("configuration", config.getRootElementName());
    290         config.setRootElementName("newRootName");
    291         assertEquals("newRootName", config.getRootElementName());
    292
    293         config.setFile(new File(TEST_FILE3));
    294         config.load();
    295         assertEquals("testconfig", config.getRootElementName());
    296         try
    297         {
    298             config.setRootElementName("anotherRootElement");
    299             fail("Setting root element name when loaded from file!");
    300         }
    301         catch(UnsupportedOperationException uex)
    302         {
    303             //fine
    304         }
    305     }
    306
    307     /***
    308      * Helper method that ensures that the test save file has been removed.
    309      *
    310      */
    311     private void removeTestSaveFile()
    312     {
    313         File saveFile = new File(TEST_SAVE);
    314         if (saveFile.exists())
    315         {
    316             assertTrue(saveFile.delete());
    317         }
    318     }
    319 }