Package org.castor.xmlctf

Source Code of org.castor.xmlctf.TestSourceGenerator

/*
* Copyright 2006 Edward Kuns
*
* Licensed 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.
*
* $Id: TestSourceGenerator.java 0000 2006-10-25 00:00:00Z ekuns $
*/
package org.castor.xmlctf;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.castor.xmlctf.compiler.CompilationException;
import org.castor.xmlctf.compiler.Compiler;
import org.castor.xmlctf.compiler.SunJavaCompiler;
import org.castor.xmlctf.util.FileServices;
import org.exolab.castor.builder.SourceGenerator;
import org.exolab.castor.builder.factory.FieldInfoFactory;
import org.exolab.castor.tests.framework.testDescriptor.OnlySourceGenerationTest;
import org.exolab.castor.tests.framework.testDescriptor.SourceGeneratorTest;
import org.exolab.castor.tests.framework.testDescriptor.UnitTestCase;
import org.exolab.castor.tests.framework.testDescriptor.types.FailureStepType;
import org.xml.sax.InputSource;

/**
* This class encapsulate all the logic needed to run the source generator by
* itself and then compile the file that have been generated. This class does
* not do anything additional. It only runs the source generator and ensures
* that the generated source will compile without error.
*
* @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
* @version $Revision: 0000 $ $Date: $
*/
public class TestSourceGenerator extends XMLTestCase {
   
    /** Name of the property file to use, null if none. */
    private final String   _propertyFileName;
    /** Name of the collection to use by default, null if we rely on the default behavior. */
    private final String   _fieldInfoFactoryName;
    /** Name of the binding file. */
    private final String   _bindingFileName;
    /** Array of schemas we'll process. */
    private final String[] _schemas;
    /** Package name for generated source. */
    private final String   _package;
    /** Should we generate source from imported schemas? */
    private final boolean  _genFromImported;
    /** Expected source files.*/
    private List _expectedSources;

    public TestSourceGenerator(final CastorTestCase test, final UnitTestCase unit, final OnlySourceGenerationTest sourceGen) {
        super(test, unit);
        _propertyFileName     = sourceGen.getProperty_File();
        _fieldInfoFactoryName = sourceGen.getCollection().toString();
        _bindingFileName      = sourceGen.getBindingFile();
        _schemas              = sourceGen.getSchema();
        _package              = sourceGen.getPackage();
        _genFromImported      = unit.hasGenerateImported() && unit.getGenerateImported();
    }

    public TestSourceGenerator(final CastorTestCase test, final UnitTestCase unit, final SourceGeneratorTest sourceGen) {
        super(test, unit);
        _propertyFileName     = sourceGen.getProperty_File();
        _fieldInfoFactoryName = sourceGen.getCollection().toString();
        _bindingFileName      = sourceGen.getBindingFile();
        _schemas              = sourceGen.getSchema();
        _package              = sourceGen.getPackage();
        _genFromImported      = unit.hasGenerateImported() && unit.getGenerateImported();
    }

    /**
     * Sets up this test suite.
     * @throws java.lang.Exception if anything goes wrong
     */
    protected void setUp() throws java.lang.Exception {
        try {
            FileServices.copySupportFiles(_test.getTestFile(), _outputRootFile);
        } catch (IOException e) {
            fail("IOException copying support files " + e);
        }
    }

    /**
     * Cleans up after this unit test.
     * @throws java.lang.Exception if anything goes wrong
     */
    protected void tearDown() throws java.lang.Exception {
        // Nothing to do
    }

    /**
     * Runs our source generation test. Creates, configures, and executes the
     * source generator on each schema we have to test. Compiles the generated
     * code. Loads classes via the appropriate class loader.
     */
    public void runTest() {
        if (_skip) {
            verbose("--> Skipping the test");
            return;
        }

        // 1. Run the source generator
        verbose("--> Running the source generator");

        try {
            final SourceGenerator sourceGen = createSourceGenerator();

            for (int i=0; i<_schemas.length; i++) {
                String schemaName = _schemas[i];
                File   schemaFile = new File(_outputRootFile, schemaName);

                if (!schemaFile.exists()) {
                    assertNotNull("Unable to find the schema: ", schemaName);
                }

                InputSource source = new InputSource(new FileReader(schemaFile));
                source.setSystemId(schemaFile.getAbsolutePath());
                sourceGen.generateSource(source, _package);
            }
        } catch (Exception e) {
            if (!checkExceptionWasExpected(e, FailureStepType.SOURCE_GENERATION)) {
                fail("Source Generator threw an Exception: " + e.getMessage());
            }
            return;
        }

        if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
            _failure.getFailureStep().equals(FailureStepType.SOURCE_GENERATION)) {
            fail("Source Generator was expected to fail, but succeeded");
            return;
        }
       
        // 1a. Check that all expected files had been generated
        checkExpectedSources();
       
        // 2. Compile the files generated by the source generator
        verbose("--> Compiling the files in " + _outputRootFile);
        try {
            Compiler compiler = new SunJavaCompiler(_outputRootFile);
            if (_unitTest.hasJavaSourceVersion()) {
                compiler.setJavaSourceVersion(_unitTest.getJavaSourceVersion());
            }
            compiler.compileDirectory();
        } catch (CompilationException e) {
            if (!checkExceptionWasExpected(e, FailureStepType.SOURCE_COMPILATION)) {
                fail("Compiling generated source failed: " + e.getMessage());
            }
            return;
        }

        if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
            _failure.getFailureStep().equals(FailureStepType.SOURCE_COMPILATION)) {
            fail("Compilation was expected to fail, but succeeded");
            return;
        }

        // 3. Nest the class loader to look into the tmp dir (don't forget previous path)
        verbose("--> Set up the class loader");
        try {
            URL[] urlList = {_test.getTestFile().toURI().toURL(), _outputRootFile.toURI().toURL()};
            ClassLoader loader =  new URLClassLoader(urlList, _test.getClass().getClassLoader());
            _test.setClassLoader(loader);
            getXMLContext().getInternalContext().setClassLoader(loader);
        } catch (Exception e) {
            if (!checkExceptionWasExpected(e, FailureStepType.LOAD_GENERATED_CLASSES)) {
                fail("Unable to process the test case:" + e);
            }
            return;
        }

        if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
            _failure.getFailureStep().equals(FailureStepType.LOAD_GENERATED_CLASSES)) {
            fail("Loading the generated classes was expected to fail, but succeeded");
        }
    }

    private void checkExpectedSources() {
        verbose("--> Checking for the existence of all expected files in " + _outputRootFile);
        String location = _outputRootFile.getAbsolutePath();
       
        boolean allFilesExist = true;
        if (_expectedSources != null && !_expectedSources.isEmpty()) {
            Iterator iter = _expectedSources.iterator();
            while (iter.hasNext()) {
                String fileName = (String) iter.next();
                String normalizedFileName = normalizeClassName(fileName);
                if (!new File(location + "/" + normalizedFileName + ".java").exists()) {
                    allFilesExist = false;
                }
            }
        }
       
        if (!allFilesExist) {
          fail("Source code generation didn't generate all expected files.");
        }
    }

    /**
     * Converts a qualified class name to a file name.
     * @param className Qualified class name
     * @return File name.
     */
    private String normalizeClassName(final String className) {
        return className.replace('.', '/');
    }

    /**
     * Creates and provides initial configuration for our Source Generator.
     *
     * @return a new SourceGenerator configured for out test
     * @throws IOException
     *             if any IOException occurs preparing the source generator.
     */
    private SourceGenerator createSourceGenerator() throws IOException {
        // Create our source generator
        final SourceGenerator sourceGen;
        if (_fieldInfoFactoryName != null) {
            FieldInfoFactory factory = new FieldInfoFactory(_fieldInfoFactoryName);
            sourceGen = new SourceGenerator(factory);
        } else {
            sourceGen = new SourceGenerator();
        }

        // Do we have a castorbuilder.properties file?
        if (_propertyFileName != null) {
            if (!(new File(_test.getTestFile(), _propertyFileName)).exists()) {
                fail("Test properties file '" + _propertyFileName + "' does not exist; check TestDescriptor.xml");
            }
            Properties prop = new Properties();
            prop.load(_test.getClassLoader().getResourceAsStream(_propertyFileName));
            sourceGen.setDefaultProperties(prop);
        } else {
            //don't forget to reset the properties
            sourceGen.setDefaultProperties(null);
        }

        // Do we have a binding file?
        if (_bindingFileName != null && _bindingFileName.length() >0) {
            File bindingFile = new File(_outputRootFile, _bindingFileName);

            if ( !bindingFile.exists()) {
                fail("Unable to find the specified binding file: " + _bindingFileName);
            }

            verbose("using binding file: " + bindingFile.getAbsolutePath());
            InputSource source = new InputSource(new FileReader(bindingFile));
            source.setSystemId(bindingFile.getAbsolutePath());
            sourceGen.setBinding(source);
        }

        // Final configuration of our source generator
        sourceGen.setEqualsMethod(true);
        sourceGen.setTestable(true);
        sourceGen.setSuppressNonFatalWarnings(true);
        sourceGen.setFailOnFirstError(true);
        sourceGen.setGenerateImportedSchemas(_genFromImported);
        sourceGen.setDestDir(_outputRootFile.getAbsolutePath());
        return sourceGen;
    }

    /**
     * Sets a collection of expected source files.
     * @param expectedSources A collection of expected source files.
     */
    public void setExpectedSources(final List expectedSources) {
        _expectedSources = expectedSources;
    }

}
TOP

Related Classes of org.castor.xmlctf.TestSourceGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.