org.apache.torque.generator.configuration.ReadConfigurationTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.torque.generator.configuration.ReadConfigurationTest.java

Source

package org.apache.torque.generator.configuration;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.torque.generator.BaseTest;
import org.apache.torque.generator.configuration.controller.Loglevel;
import org.apache.torque.generator.configuration.controller.OutletReference;
import org.apache.torque.generator.configuration.controller.Output;
import org.apache.torque.generator.configuration.mergepoint.MergepointMapping;
import org.apache.torque.generator.configuration.option.MapOptionsConfiguration;
import org.apache.torque.generator.configuration.option.OptionsConfiguration;
import org.apache.torque.generator.configuration.outlet.OutletConfiguration;
import org.apache.torque.generator.configuration.paths.CustomProjectPaths;
import org.apache.torque.generator.configuration.paths.DefaultTorqueGeneratorPaths;
import org.apache.torque.generator.configuration.paths.Maven2DirectoryProjectPaths;
import org.apache.torque.generator.configuration.paths.ProjectPaths;
import org.apache.torque.generator.configuration.source.EntityReferences;
import org.apache.torque.generator.control.ControllerState;
import org.apache.torque.generator.control.action.ApplyAction;
import org.apache.torque.generator.control.action.MergepointAction;
import org.apache.torque.generator.control.action.TraverseAllAction;
import org.apache.torque.generator.file.Fileset;
import org.apache.torque.generator.java.JavaOutlet;
import org.apache.torque.generator.option.Option;
import org.apache.torque.generator.option.OptionImpl;
import org.apache.torque.generator.option.Options;
import org.apache.torque.generator.outlet.Outlet;
import org.apache.torque.generator.qname.QualifiedName;
import org.apache.torque.generator.source.SourceProcessConfiguration;
import org.apache.torque.generator.source.SourceTransformerDefinition;
import org.apache.torque.generator.source.jdbc.JdbcMetadataSourceProvider;
import org.apache.torque.generator.source.stream.FileSourceProvider;
import org.apache.torque.generator.source.stream.PropertiesSourceFormat;
import org.apache.torque.generator.source.stream.XmlSourceFormat;
import org.apache.torque.generator.template.velocity.VelocityOutlet;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests whether the configuration is read correctly.
 */
public class ReadConfigurationTest extends BaseTest {
    private ControllerState controllerState;

    @Before
    public void setUp() {
        controllerState = new ControllerState();
        UnitConfiguration unitConfiguration = new UnitConfiguration();
        controllerState.setUnitConfiguration(unitConfiguration);
        Options options = new Options();
        unitConfiguration.setOptions(options);
    }

    @Test
    public void testReadConfiguration() throws Exception {
        ProjectPaths projectPaths = new Maven2DirectoryProjectPaths(new File("src/test/configuration"));
        UnitDescriptor unitDescriptor = new UnitDescriptor(UnitDescriptor.Packaging.DIRECTORY, projectPaths,
                new DefaultTorqueGeneratorPaths());
        UnitConfigurationReader configurationReader = new UnitConfigurationReader();
        ConfigurationHandlers configurationHandlers = new ConfigurationHandlers();
        UnitConfiguration unitConfiguration = configurationReader.read(unitDescriptor, configurationHandlers);
        {
            File defaultTargetDirectory = unitConfiguration.getOutputDirectory(null);
            File expected = new File("src/test/configuration/target/generated-sources");
            assertEquals(expected, defaultTargetDirectory);
        }
        {
            File modifiableTargetDirectory = unitConfiguration.getOutputDirectory("modifiable");
            File expected = new File("src/test/configuration/src/main/generated-java");
            assertEquals(expected, modifiableTargetDirectory);
        }
        try {
            unitConfiguration.getOutputDirectory("notExistingKey");
            fail("Exception expected");
        } catch (IllegalStateException e) {
            // expected
        }

        assertEquals(Loglevel.DEBUG, unitConfiguration.getLoglevel());

        {
            Options expectedOptions = new Options();
            Set<Option> expectedOptionSet = new HashSet<Option>();
            expectedOptionSet
                    .add(new OptionImpl(new QualifiedName("org.apache.torque.generator.optionWithNamespace"),
                            "optionWithNamespaceValue"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("org.apache.optionWithNamespace"),
                    "org.apache.optionWithNamespaceValue"));
            expectedOptionSet.add(
                    new OptionImpl(new QualifiedName("optionWithoutNamespace", ""), "optionWithoutNamespaceValue"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("optionPrecedenceLastFile"), "value from xml"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("jdbcUrl"), "jdbc.url.option.value"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("jdbcDriver"), "jdbc.driver.option.value"));
            expectedOptions.addGlobalOptions(expectedOptionSet);
            assertOptionsEquals(expectedOptions, unitConfiguration.getOptions());
        }

        {
            EntityReferences entityReferences = unitConfiguration.getEntityReferences();
            Map<String, byte[]> actual = entityReferences.getEntityReferences();
            assertEquals(2, actual.size());
            assertArrayEquals(
                    FileUtils.readFileToByteArray(
                            new File("src/test/configuration/src/main/torque-gen/resources/override.xsd")),
                    actual.get("http://db.apache.org/torque/some.xsd"));
            assertArrayEquals(
                    FileUtils.readFileToByteArray(
                            new File("src/test/configuration/src/main/torque-gen/resources/new.xsd")),
                    actual.get("http://db.apache.org/torque/new.xsd"));
        }

        {
            List<Output> outputFiles = unitConfiguration.getOutputList();
            assertEquals(3, outputFiles.size());

            {
                Output output = outputFiles.get(0);
                assertEquals(new QualifiedName("org.apache.torque.generator.firstOutput"), output.getName());
                assertEquals("skip", output.getExistingTargetStrategy());
                assertEquals(null, output.getOutputDirKey());
                assertNull(output.getFilename());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(new QualifiedName("org.apache.torque.generator.test.readConfiguration.javaOutlet"),
                            outletConfiguration.getName());
                }

                {
                    JavaOutlet filenameOutlet = (JavaOutlet) output.getFilenameOutlet();
                    assertEquals("Foo", filenameOutlet.getFoo());
                    assertEquals("Bar", filenameOutlet.getBar());
                    assertEquals(new QualifiedName("org.apache.torque.generator.configuration.filenameOutlet"),
                            filenameOutlet.getName());
                }

                {
                    Fileset sourceFileset = new Fileset(projectPaths.getDefaultSourcePath(), new HashSet<String>(),
                            new HashSet<String>());
                    FileSourceProvider sourceProvider = new FileSourceProvider(new XmlSourceFormat(), sourceFileset,
                            null);
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertFileSourceProviderEquals(sourceProvider, (FileSourceProvider) output.getSourceProvider());
                }
                assertSourceProcessConfigurationEquals(new SourceProcessConfiguration(),
                        output.getSourceProcessConfiguration());
            }

            {
                Output output = outputFiles.get(1);
                assertEquals(new QualifiedName("secondOutput"), output.getName());
                assertEquals("replace", output.getExistingTargetStrategy());
                assertEquals("secondOutputDirKey", output.getOutputDirKey());
                assertNull(output.getFilename());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(
                            new QualifiedName("org.apache.torque.generator.test.readConfiguration.anotherOutlet"),
                            outletConfiguration.getName());
                }

                {
                    VelocityOutlet filenameOutlet = (VelocityOutlet) output.getFilenameOutlet();
                    String templateContent = filenameOutlet.getContent(controllerState);
                    // remove License from template by comparing only
                    // the last line
                    String templateContentLicenseRemoved = StringUtils.substringAfterLast(templateContent, "\r\n");
                    assertEquals("test template output", templateContentLicenseRemoved);
                    assertEquals(new QualifiedName("org.apache.torque.generator.configuration.filenameOutlet"),
                            filenameOutlet.getName());
                    assertTrue(filenameOutlet.isOptionsInContext());
                    assertTrue(filenameOutlet.isSourceAttributesInContext());
                    assertTrue(filenameOutlet.isVariablesInContext());
                }

                {
                    Fileset sourceFileset = new Fileset(projectPaths.getDefaultSourcePath(),
                            createSetFrom("second.source.path.properties"),
                            createSetFrom("second.excluded.properties"));
                    FileSourceProvider sourceProvider = new FileSourceProvider(new PropertiesSourceFormat(),
                            sourceFileset, true);
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertFileSourceProviderEquals(sourceProvider, (FileSourceProvider) output.getSourceProvider());
                }
                {
                    SourceProcessConfiguration sourceProcessConfiguration = new SourceProcessConfiguration();
                    sourceProcessConfiguration.setStartElementsPath("properties/entry");
                    List<SourceTransformerDefinition> transformerDefinitions = new ArrayList<SourceTransformerDefinition>();

                    transformerDefinitions
                            .add(new SourceTransformerDefinition(new ConfigurationTestTransformer(), null));
                    transformerDefinitions.add(
                            new SourceTransformerDefinition(new OtherConfigurationTestTransformer(), "database"));
                    sourceProcessConfiguration.setSourceTransformerDefinitions(transformerDefinitions);
                    sourceProcessConfiguration.setSkipDecider(
                            "org.apache.torque.generator.configuration.ConfigurationTestSkipDecider");
                    assertSourceProcessConfigurationEquals(sourceProcessConfiguration,
                            output.getSourceProcessConfiguration());
                }
            }
            {
                Output output = outputFiles.get(2);
                assertEquals(new QualifiedName("thirdOutput"), output.getName());
                assertEquals("append", output.getExistingTargetStrategy());
                assertEquals("thirdOutputDirKey", output.getOutputDirKey());
                assertEquals("outputFileName", output.getFilename());
                assertNull(output.getFilenameOutlet());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(
                            new QualifiedName("org.apache.torque.generator.test.readConfiguration.thirdOutlet"),
                            outletConfiguration.getName());
                }

                {
                    JdbcMetadataSourceProvider sourceProvider = new JdbcMetadataSourceProvider("jdbcUrl",
                            "jdbcDriver", "jdbcUsername", "jdbcPassword", "jdbcSchema");
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertJdbcMetadataSourceProviderEquals(sourceProvider,
                            (JdbcMetadataSourceProvider) output.getSourceProvider());
                }
                assertSourceProcessConfigurationEquals(new SourceProcessConfiguration(),
                        output.getSourceProcessConfiguration());
            }
        }

        {
            OutletConfiguration outletConfiguration = unitConfiguration.getOutletConfiguration();
            Map<QualifiedName, Outlet> outletMap = outletConfiguration.getOutlets();
            assertEquals(2, outletMap.size());
            {
                JavaOutlet outlet = (JavaOutlet) outletMap
                        .get(new QualifiedName("org.apache.torque.generator.test.readConfiguration.javaOutlet"));
                assertEquals("Foo2", outlet.getFoo());
                assertEquals("Bar2", outlet.getBar());
                Map<String, MergepointMapping> mergepointMappings = outlet.getMergepointMappings();
                assertEquals(3, mergepointMappings.size());
                {
                    MergepointMapping mergepointMapping = mergepointMappings.get("properties");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new TraverseAllAction("entry", "org.apache.torque.generator.velocity.propertyCopy",
                            true), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
                {
                    // mergepoint from the separate mapping
                    MergepointMapping mergepointMapping = mergepointMappings.get("mergepointName");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new ApplyAction(null, "someOutletAction", false), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
                {
                    // other mergepoint from the separate mapping
                    MergepointMapping mergepointMapping = mergepointMappings.get("mergepointFromParent");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new ApplyAction(null, "newOutletAction", true), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
            }

            {
                VelocityOutlet outlet = (VelocityOutlet) outletMap
                        .get(new QualifiedName("org.apache.torque.generator.test.readConfiguration.anotherOutlet"));
                String templateContent = outlet.getContent(controllerState);
                // remove License from template by comparing only
                // the last line
                String templateContentLicenseRemoved = StringUtils.substringAfterLast(templateContent, "\r\n");
                assertEquals("test template output", templateContentLicenseRemoved);
                assertEquals(0, outlet.getMergepointMappings().size());
                assertNull(outlet.getInputElementName());
                assertFalse(outlet.isOptionsInContext());
                assertFalse(outlet.isSourceAttributesInContext());
                assertFalse(outlet.isVariablesInContext());
            }
        }
    }

    @Test
    public void testReadConfigFromClasspath() throws Exception {
        Map<String, File> outputDirMap = new HashMap<String, File>();
        outputDirMap.put(null, new File("generated-sources"));
        ProjectPaths projectPaths = new CustomProjectPaths(null,
                "org.apache.torque.generator.test.readfromclasspath", new File("src"), outputDirMap,
                new File("work"));
        UnitDescriptor unitDescriptor = new UnitDescriptor(UnitDescriptor.Packaging.CLASSPATH, projectPaths,
                new DefaultTorqueGeneratorPaths());
        ConfigurationHandlers configurationHandlers = new ConfigurationHandlers();
        UnitConfigurationReader configurationReader = new UnitConfigurationReader();
        UnitConfiguration unitConfiguration = configurationReader.read(unitDescriptor, configurationHandlers);

        // check that we have read the correct configuration
        {
            Options options = unitConfiguration.getOptions();
            Option option = options.getInHierarchy(new QualifiedName("configuration"));
            assertNotNull("option configuration should be set", option);
            assertEquals("fromClasspath", option.getValue());
        }

        // check that the outlets are read
        {
            OutletConfiguration outletConfiguration = unitConfiguration.getOutletConfiguration();
            Map<QualifiedName, Outlet> outletMap = outletConfiguration.getOutlets();
            assertEquals(2, outletMap.size());
        }
    }

    @Test
    public void testOverrideOptions() throws Exception {
        ProjectPaths projectPaths = new Maven2DirectoryProjectPaths(new File("src/test/configuration"));
        Map<String, String> overrideOptions = new HashMap<String, String>();
        overrideOptions.put("optionWithoutNamespace", "overriddenValue");
        overrideOptions.put("newOption", "newValue");
        OptionsConfiguration optionConfiguration = new MapOptionsConfiguration(overrideOptions);

        UnitDescriptor unitDescriptor = new UnitDescriptor(UnitDescriptor.Packaging.DIRECTORY, projectPaths,
                new DefaultTorqueGeneratorPaths());
        unitDescriptor.setOverrideOptions(optionConfiguration);
        ConfigurationHandlers configurationHandlers = new ConfigurationHandlers();
        UnitConfigurationReader configurationReader = new UnitConfigurationReader();
        UnitConfiguration unitConfiguration = configurationReader.read(unitDescriptor, configurationHandlers);
        Options options = unitConfiguration.getOptions();
        {
            Option option = options.getInHierarchy(new QualifiedName("optionWithoutNamespace"));
            assertEquals("overriddenValue", option.getValue());
        }
        {
            Option option = options.getInHierarchy(new QualifiedName("newOption"));
            assertEquals("newValue", option.getValue());
        }
    }

    @Test
    public void testInheritance() throws Exception {
        CustomProjectPaths projectPaths;
        UnitConfiguration unitConfiguration;
        ConfigurationHandlers configurationHandlers = new ConfigurationHandlers();
        {
            CustomProjectPaths parentProjectPaths = new CustomProjectPaths(
                    new Maven2DirectoryProjectPaths(new File("src/test/configuration")));
            parentProjectPaths.setConfigurationDir(new File("src/test/configuration/src/main/torque-gen-parent"));
            parentProjectPaths.setOutputDirectory(null, new File("src/test/configuration/target/parentCustom"));
            parentProjectPaths.setOutputDirectory("modifiable",
                    new File("src/test/configuration/src/main/parentCustom"));
            UnitDescriptor parentUnitDescriptor = new UnitDescriptor(UnitDescriptor.Packaging.DIRECTORY,
                    parentProjectPaths, new DefaultTorqueGeneratorPaths());

            projectPaths = new CustomProjectPaths(
                    new Maven2DirectoryProjectPaths(new File("src/test/configuration")));
            projectPaths.setOutputDirectory(null, new File("src/test/configuration/target/custom"));
            projectPaths.setOutputDirectory("modifiable", new File("src/test/configuration/src/main/custom"));
            UnitDescriptor unitDescriptor = new UnitDescriptor(UnitDescriptor.Packaging.DIRECTORY, projectPaths,
                    new DefaultTorqueGeneratorPaths());
            unitDescriptor.setInheritsFrom(parentUnitDescriptor);
            UnitConfigurationReader configurationReader = new UnitConfigurationReader();
            unitConfiguration = configurationReader.read(unitDescriptor, configurationHandlers);
        }

        assertEquals(Loglevel.DEBUG, unitConfiguration.getLoglevel());

        {
            File newFileTargetDirectory = unitConfiguration.getOutputDirectory(null);
            File expected = new File("src/test/configuration/target/custom");
            assertEquals(expected, newFileTargetDirectory);
        }
        {
            File modifiableFileTargetDirectory = unitConfiguration.getOutputDirectory("modifiable");
            File expected = new File("src/test/configuration/src/main/custom");
            assertEquals(expected, modifiableFileTargetDirectory);
        }

        {
            Options expectedOptions = new Options();
            Set<Option> expectedOptionSet = new HashSet<Option>();
            expectedOptionSet
                    .add(new OptionImpl(new QualifiedName("org.apache.torque.generator.optionWithNamespace"),
                            "optionWithNamespaceValue"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("org.apache.optionWithNamespace"),
                    "org.apache.optionWithNamespaceValue"));
            expectedOptionSet.add(
                    new OptionImpl(new QualifiedName("optionWithoutNamespace", ""), "optionWithoutNamespaceValue"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("optionPrecedenceLastFile"), "value from xml"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("jdbcUrl"), "jdbc.url.option.value"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("jdbcDriver"), "jdbc.driver.option.value"));
            expectedOptionSet.add(new OptionImpl(new QualifiedName("parentOptionWithoutNamespace", ""),
                    "parentOptionWithoutNamespaceParentValue"));
            expectedOptionSet
                    .add(new OptionImpl(new QualifiedName("org.apache.torque.generator.parentOptionWithNamespace"),
                            "parentOptionWithNamespaceParentValue"));
            expectedOptions.addGlobalOptions(expectedOptionSet);
            assertOptionsEquals(expectedOptions, unitConfiguration.getOptions());
        }

        {
            EntityReferences entityReferences = unitConfiguration.getEntityReferences();
            Map<String, byte[]> actual = entityReferences.getEntityReferences();
            assertEquals(3, actual.size());
            assertArrayEquals(
                    FileUtils.readFileToByteArray(
                            new File("src/test/configuration/src/main/torque-gen-parent/resources/parent.xsd")),
                    actual.get("http://db.apache.org/torque/parent.xsd"));
            assertArrayEquals(
                    FileUtils.readFileToByteArray(
                            new File("src/test/configuration/src/main/torque-gen/resources/override.xsd")),
                    actual.get("http://db.apache.org/torque/some.xsd"));
            assertArrayEquals(
                    FileUtils.readFileToByteArray(
                            new File("src/test/configuration/src/main/torque-gen/resources/new.xsd")),
                    actual.get("http://db.apache.org/torque/new.xsd"));
        }

        {
            List<Output> outputList = unitConfiguration.getOutputList();
            assertEquals(4, outputList.size());

            {
                Output output = outputList.get(0);
                assertEquals(new QualifiedName("parentOutput"), output.getName());
                assertEquals("replace", output.getExistingTargetStrategy());
                assertEquals("parentOutputDirKeyFromParent", output.getOutputDirKey());
                assertNull(output.getFilename());
                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(
                            new QualifiedName(
                                    "org.apache.torque.generator.test.readConfiguration.testParentOutlet"),
                            outletConfiguration.getName());
                }
                {
                    JavaOutlet filenameOutlet = (JavaOutlet) output.getFilenameOutlet();
                    assertEquals("ParentFoo", filenameOutlet.getFoo());
                    assertEquals("ParentBar", filenameOutlet.getBar());
                    assertEquals(new QualifiedName("org.apache.torque.generator.configuration.filenameOutlet"),
                            filenameOutlet.getName());
                }

                {
                    Fileset sourceFileset = new Fileset(projectPaths.getDefaultSourcePath(),
                            createSetFrom("parentSource"), new HashSet<String>());
                    FileSourceProvider sourceProvider = new FileSourceProvider(new XmlSourceFormat(), sourceFileset,
                            false);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    sourceProvider.init(configurationHandlers, controllerState);
                    assertFileSourceProviderEquals(sourceProvider, (FileSourceProvider) output.getSourceProvider());
                }
                {
                    SourceProcessConfiguration sourceProcessConfiguration = new SourceProcessConfiguration();
                    sourceProcessConfiguration.setStartElementsPath("parentSourceElement");
                    List<SourceTransformerDefinition> transformerDefinitions = new ArrayList<SourceTransformerDefinition>();

                    transformerDefinitions.add(new SourceTransformerDefinition(
                            new OtherConfigurationTestTransformer(), "parent/database"));
                    sourceProcessConfiguration.setSourceTransformerDefinitions(transformerDefinitions);
                    sourceProcessConfiguration.setSkipDecider(
                            "org.apache.torque.generator.configuration.OtherConfigurationTestSkipDecider");
                    assertSourceProcessConfigurationEquals(sourceProcessConfiguration,
                            output.getSourceProcessConfiguration());
                }
            }
            {
                Output output = outputList.get(1);
                assertEquals(new QualifiedName("org.apache.torque.generator.firstOutput"), output.getName());
                assertEquals("skip", output.getExistingTargetStrategy());
                assertEquals(null, output.getOutputDirKey());
                assertNull(output.getFilename());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(new QualifiedName("org.apache.torque.generator.test.readConfiguration.javaOutlet"),
                            outletConfiguration.getName());
                }
                {
                    JavaOutlet filenameOutlet = (JavaOutlet) output.getFilenameOutlet();
                    assertEquals("Foo", filenameOutlet.getFoo());
                    assertEquals("Bar", filenameOutlet.getBar());
                    assertEquals(new QualifiedName("org.apache.torque.generator.configuration.filenameOutlet"),
                            filenameOutlet.getName());
                }

                {
                    Fileset sourceFileset = new Fileset(projectPaths.getDefaultSourcePath(), new HashSet<String>(),
                            new HashSet<String>());
                    FileSourceProvider sourceProvider = new FileSourceProvider(new XmlSourceFormat(), sourceFileset,
                            null);
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertFileSourceProviderEquals(sourceProvider, (FileSourceProvider) output.getSourceProvider());
                }
                assertSourceProcessConfigurationEquals(new SourceProcessConfiguration(),
                        output.getSourceProcessConfiguration());
            }

            {
                Output output = outputList.get(2);
                assertEquals(new QualifiedName("secondOutput"), output.getName());
                assertEquals("replace", output.getExistingTargetStrategy());
                assertEquals(output.getOutputDirKey(), "secondOutputDirKey");
                assertNull(output.getFilename());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(
                            new QualifiedName("org.apache.torque.generator.test.readConfiguration.anotherOutlet"),
                            outletConfiguration.getName());
                }
                {
                    VelocityOutlet filenameOutlet = (VelocityOutlet) output.getFilenameOutlet();
                    String templateContent = filenameOutlet.getContent(controllerState);
                    // remove License from template by comparing only
                    // the last line
                    String templateContentLicenseRemoved = StringUtils.substringAfterLast(templateContent, "\r\n");
                    assertEquals("test template output", templateContentLicenseRemoved);
                    assertEquals(new QualifiedName("org.apache.torque.generator.configuration.filenameOutlet"),
                            filenameOutlet.getName());
                }

                {
                    Fileset sourceFileset = new Fileset(projectPaths.getDefaultSourcePath(),
                            createSetFrom("second.source.path.properties"),
                            createSetFrom("second.excluded.properties"));
                    FileSourceProvider sourceProvider = new FileSourceProvider(new PropertiesSourceFormat(),
                            sourceFileset, true);
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertFileSourceProviderEquals(sourceProvider, (FileSourceProvider) output.getSourceProvider());
                }
                {
                    SourceProcessConfiguration sourceProcessConfiguration = new SourceProcessConfiguration();
                    sourceProcessConfiguration.setStartElementsPath("properties/entry");
                    List<SourceTransformerDefinition> transformerDefinitions = new ArrayList<SourceTransformerDefinition>();
                    transformerDefinitions
                            .add(new SourceTransformerDefinition(new ConfigurationTestTransformer(), null));
                    transformerDefinitions.add(
                            new SourceTransformerDefinition(new OtherConfigurationTestTransformer(), "database"));
                    sourceProcessConfiguration.setSourceTransformerDefinitions(transformerDefinitions);
                    sourceProcessConfiguration.setSkipDecider(
                            "org.apache.torque.generator.configuration.ConfigurationTestSkipDecider");
                    assertSourceProcessConfigurationEquals(sourceProcessConfiguration,
                            output.getSourceProcessConfiguration());
                }
            }
            {
                Output output = outputList.get(3);
                assertEquals(new QualifiedName("thirdOutput"), output.getName());
                assertEquals("append", output.getExistingTargetStrategy());
                assertEquals("thirdOutputDirKey", output.getOutputDirKey());
                assertEquals("outputFileName", output.getFilename());
                assertNull(output.getFilenameOutlet());

                {
                    OutletReference outletConfiguration = output.getContentOutlet();
                    assertEquals(
                            new QualifiedName("org.apache.torque.generator.test.readConfiguration.thirdOutlet"),
                            outletConfiguration.getName());
                }

                {
                    JdbcMetadataSourceProvider sourceProvider = new JdbcMetadataSourceProvider("jdbcUrl",
                            "jdbcDriver", "jdbcUsername", "jdbcPassword", "jdbcSchema");
                    sourceProvider.init(configurationHandlers, controllerState);
                    output.getSourceProvider().init(configurationHandlers, controllerState);
                    assertJdbcMetadataSourceProviderEquals(sourceProvider,
                            (JdbcMetadataSourceProvider) output.getSourceProvider());
                }
                assertSourceProcessConfigurationEquals(new SourceProcessConfiguration(),
                        output.getSourceProcessConfiguration());
            }
        }

        {
            OutletConfiguration outletConfiguration = unitConfiguration.getOutletConfiguration();
            Map<QualifiedName, Outlet> outletMap = outletConfiguration.getOutlets();
            assertEquals(3, outletMap.size());
            {
                JavaOutlet outlet = (JavaOutlet) outletMap
                        .get(new QualifiedName("org.apache.torque.generator.test.readConfiguration.javaOutlet"));
                assertEquals("Foo2", outlet.getFoo());
                assertEquals("Bar2", outlet.getBar());
                Map<String, MergepointMapping> mergepointMappings = outlet.getMergepointMappings();
                assertEquals(3, mergepointMappings.size());
                {
                    MergepointMapping mergepointMapping = mergepointMappings.get("properties");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new TraverseAllAction("entry", "org.apache.torque.generator.velocity.propertyCopy",
                            true), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
                {
                    // mergepoint from the separate mapping in child
                    MergepointMapping mergepointMapping = mergepointMappings.get("mergepointName");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new ApplyAction(null, "someOutletAction", false), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
                {
                    // other mergepoint from the separate mapping in child
                    MergepointMapping mergepointMapping = mergepointMappings.get("mergepointFromParent");
                    assertEquals(1, mergepointMapping.getActions().size());
                    MergepointAction action = mergepointMapping.getActions().get(0);
                    assertEquals(new ApplyAction(null, "newOutletAction", true), action);
                    assertEquals("inputElement", outlet.getInputElementName());
                }
            }

            {
                VelocityOutlet outlet = (VelocityOutlet) outletMap
                        .get(new QualifiedName("org.apache.torque.generator.test.readConfiguration.anotherOutlet"));
                String templateContent = outlet.getContent(controllerState);
                // remove License from template by comparing only
                // the last line
                String templateContentLicenseRemoved = StringUtils.substringAfterLast(templateContent, "\r\n");
                assertEquals("test template output", templateContentLicenseRemoved);
                assertEquals(0, outlet.getMergepointMappings().size());
            }
            {
                VelocityOutlet outlet = (VelocityOutlet) outletMap
                        .get(new QualifiedName("org.apache.torque.generator.test.readConfiguration.parentOutlet"));
                String templateContent = outlet.getContent(controllerState);
                // remove License from template by comparing only
                // the last line
                String templateContentLicenseRemoved = StringUtils.substringAfterLast(templateContent, "\r\n");
                assertEquals("parent test template output", templateContentLicenseRemoved);
                assertEquals(0, outlet.getMergepointMappings().size());
            }
        }
    }

    private static void assertFileSourceProviderEquals(FileSourceProvider expected, FileSourceProvider actual) {
        assertEquals(expected.getSourceFormat(), actual.getSourceFormat());
        assertEquals(expected.getSourceFileset().getIncludes(), actual.getSourceFileset().getIncludes());
        assertEquals(expected.getSourceFileset().getExcludes(), actual.getSourceFileset().getExcludes());
        assertEquals(expected.getSourceFileset().getBasedir(), actual.getSourceFileset().getBasedir());
        assertEquals(expected.getPaths(), actual.getPaths());
        assertEquals(expected.getCombineFiles(), actual.getCombineFiles());
    }

    private static void assertJdbcMetadataSourceProviderEquals(JdbcMetadataSourceProvider expected,
            JdbcMetadataSourceProvider actual) {
        assertEquals(expected.getDriverOption(), actual.getDriverOption());
        assertEquals(expected.getPasswordOption(), actual.getPasswordOption());
        assertEquals(expected.getSchemaOption(), actual.getSchemaOption());
        assertEquals(expected.getUrlOption(), actual.getUrlOption());
        assertEquals(expected.getUsernameOption(), actual.getUsernameOption());
        assertEquals(expected.getDriver(), actual.getDriver());
        assertEquals(expected.getPassword(), actual.getPassword());
        assertEquals(expected.getSchema(), actual.getSchema());
        assertEquals(expected.getUrl(), actual.getUrl());
        assertEquals(expected.getUsername(), actual.getUsername());
    }

    private static void assertOptionsEquals(Options expected, Options actual) {
        Map<QualifiedName, Option> expectedMap = expected.getGlobalScope();
        Map<QualifiedName, Option> actualMap = actual.getGlobalScope();
        assertEquals(expectedMap.size(), actualMap.size());

        for (QualifiedName expectedKey : expectedMap.keySet()) {
            assertTrue(expectedMap.containsKey(expectedKey));
            Object expectedValue = expectedMap.get(expectedKey).getValue();
            Object actualValue = actualMap.get(expectedKey).getValue();
            assertEquals(expectedValue, actualValue);
        }
    }

    private void assertSourceProcessConfigurationEquals(SourceProcessConfiguration expected,
            SourceProcessConfiguration actual) {
        if (expected.getSkipDecider() != null) {
            assertEquals(expected.getSkipDecider().getClass(), actual.getSkipDecider().getClass());
        } else {
            assertNull(actual.getSkipDecider());
        }
        assertEquals(expected.getStartElementsPath(), actual.getStartElementsPath());
        assertEquals(expected.getTransformerDefinitions(), actual.getTransformerDefinitions());
    }

    /**
     * Creates as set containing the Strings in content.
     *
     * @param content The Strings which should be in the set.
     *
     * @return the Set containing all the strings.
     */
    private static Set<String> createSetFrom(String... content) {
        Set<String> result = new HashSet<String>();
        for (String part : content) {
            result.add(part);
        }
        return result;
    }
}