/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ package at.knowcenter.wag.egov.egiz.cfg; import static org.junit.Assert.fail; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Properties; import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.junit.Test; /** * Tests dealing with include-capable properties. * * @author Datentechnik Innovation GmbH */ public class NestedPropertiesTest { @Test public void testNoIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("config_noincludes.properties").getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = new FileInputStream(configFile)); } finally { IOUtils.closeQuietly(in); } NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test public void testSingleIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("config_single_includes.properties") .getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = getClass().getResourceAsStream("config_noincludes.properties")); } finally { IOUtils.closeQuietly(in); } NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test public void testSingleIncludesWithDefaultConfig() throws IOException { // add some properties to a default configuration object Properties defaultConfiguration = new Properties(); defaultConfiguration.put("key1", "defaultValue1"); defaultConfiguration.put("key2", "defaultValue2"); // set a property which will be locally overridden by config_single_includes.properties defaultConfiguration.put("correct_document_on_verify_if_necessary", "false"); defaultConfiguration.put("sig_obj.types.INVISIBLE", "off"); File configFile = new File(NestedPropertiesTest.class.getResource("config_single_includes.properties") .getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = getClass().getResourceAsStream("config_noincludes.properties")); expectedProperties.put("key1", "defaultValue1"); expectedProperties.put("key2", "defaultValue2"); } finally { IOUtils.closeQuietly(in); } // load include aware properties considering default configuration NestedProperties nestedProperties = new NestedProperties(defaultConfiguration); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test public void testWildcardIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("config_wildcard_includes.properties") .getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = getClass().getResourceAsStream("config_noincludes.properties")); } finally { IOUtils.closeQuietly(in); } NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test public void testNestedIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("config_nested_includes.properties") .getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = getClass().getResourceAsStream("config_noincludes.properties")); } finally { IOUtils.closeQuietly(in); } NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test public void testSubdirIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("config_subdir_includes.properties") .getFile()); Properties expectedProperties = new Properties(); InputStream in = null; try { expectedProperties.load(in = getClass().getResourceAsStream("config_noincludes.properties")); } finally { IOUtils.closeQuietly(in); } NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); assertEquals(expectedProperties, nestedProperties); } @Test(timeout = 2500, expected = CircularIncludeException.class) public void testCircularIncludes() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("circular/profile.1.properties").getFile()); NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); fail("Circular references should have been detected."); } @Test /** * Tests include priority: Included properties should override locally set properties. */ public void testLocalVsIncludedProperties() throws IOException { File configFile = new File(NestedPropertiesTest.class.getResource("local_vs_included_properties.properties") .getFile()); NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); Properties expectedProperties = new Properties(); expectedProperties.put("key1", "included value 1"); expectedProperties.put("key2", "local value 2"); expectedProperties.put("key3", "local value 3"); expectedProperties.put("key4", "local value 4"); assertEquals(expectedProperties, nestedProperties); } @Test public void testIncludeOrder() throws CircularIncludeException, IOException { File configFile = new File(NestedPropertiesTest.class.getResource("include_order.properties").getFile()); NestedProperties nestedProperties = new NestedProperties(); nestedProperties.load(configFile); Properties expectedProperties = new Properties(); expectedProperties.put("key1", "include_xyz"); expectedProperties.put("key2", "include_abc"); expectedProperties.put("key3", "include_3"); expectedProperties.put("key4", "include_2"); expectedProperties.put("key5", "include_1"); expectedProperties.put("key6", "include"); assertEquals(expectedProperties, nestedProperties); } /** * Java default {@link Properties} does not provide equals and hashcode methods therefore default properties are not * taken into consideration when comparing two Properties (using {@link Hashtable#equals(Object)}. This method * compares two Properties considering defaults. Note that this method considers two Properties equal if the * respective union of keys and default keys equals. * * @param expected * The expected set of Properties. * @param actual * Properties to be compared with. */ private static void assertEquals(Properties expected, Properties actual) { if (expected == actual) { // same object return; } if (expected == null || actual == null) { fail("expected: <" + expected + "> but was <" + actual + ">"); } // fetch all keys (including defaults) from actual properties @SuppressWarnings("unchecked") Enumeration actualPropertyNames = (Enumeration) actual.propertyNames(); Set actualKeys = new HashSet(); while (actualPropertyNames.hasMoreElements()) { actualKeys.add(actualPropertyNames.nextElement()); } @SuppressWarnings("unchecked") Enumeration expectedPropertyNames = (Enumeration) expected.propertyNames(); while (expectedPropertyNames.hasMoreElements()) { String key = expectedPropertyNames.nextElement(); String expectedValue = expected.getProperty(key); if (!actualKeys.contains(key)) { fail("missing entry for key '" + key + "'"); } String actualValue = actual.getProperty(key); if (!StringUtils.equals(expectedValue, actualValue)) { fail("key '" + key + "' value expected: <" + expectedValue + "> but was <" + actualValue + ">"); } actualKeys.remove(key); } if (!actualKeys.isEmpty()) { fail("more entries found than expected: " + StringUtils.join(actualKeys, ", ")); } } }