/*
 * Copyright 2008 Le Duc Bao
 * 
 * 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.
 */
package org.castor.xml.schema.writer;

import org.exolab.castor.xml.schema.ComplexType;
import org.exolab.castor.xml.schema.ElementDecl;
import org.exolab.castor.xml.schema.Group;
import org.exolab.castor.xml.schema.Order;
import org.exolab.castor.xml.schema.SchemaNames;

/**
 * This test covers complex type generation.
 * 
 * @author <a href="mailto:leducbao AT gmail DOT com">Le Duc Bao</a>
 */
public class ComplexTypeTest extends AbstractSchemaTest {

    /**
     * @param testcase
     */
    public ComplexTypeTest(String testcase) {
        super(testcase);
    }

    /**
     * Create simple type
     * 
     * @throws Exception
     */
    public void testSingleAttribute() throws Exception {
        // create targeted schema
        _schema.addNamespace("pre", "my.namespace.org");
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);

        Group group = new Group();
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        // compare
        TestResult result = doTest("complextype_singleattribute.xsd");
        assertEquals("single attribute test failed", TestResult.IDENTICAL,
                result);
    }

    /**
     * sequence multiple attributes
     * 
     * @throws Exception
     */
    public void testSequenceAttribute() throws Exception {
        // create targeted schema
        _schema.addNamespace("pre", "my.namespace.org");
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);

        Group group = new Group();
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        ElementDecl e2 = new ElementDecl(_schema);
        e2.setName("myAttr2");
        group.addElementDecl(e2);

        ElementDecl e3 = new ElementDecl(_schema);
        e3.setName("myAttr3");
        group.addElementDecl(e3);

        // compare
        TestResult result = doTest("complextype_sequenceattribute.xsd");
        assertEquals("sequence multiple attributes test failed",
                TestResult.IDENTICAL, result);
    }

    /**
     * un-order attributes
     * 
     * @throws Exception
     */
    public void testAllOrderAttribute() throws Exception {

        // TODO it seems the XMLDiff does not detect order of attributes
        // create targeted schema
        _schema.addNamespace("pre", "my.namespace.org");
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);

        Group group = new Group();
        group.setOrder(Order.all);
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        ElementDecl e2 = new ElementDecl(_schema);
        e2.setName("myAttr2");
        group.addElementDecl(e2);

        ElementDecl e3 = new ElementDecl(_schema);
        e3.setName("myAttr3");
        group.addElementDecl(e3);

        // compare
        TestResult result = doTest("complextype_allorder.xsd");
        assertEquals("all order attributes test failed", TestResult.IDENTICAL,
                result);
    }

    /**
     * choice group attributes
     * 
     * @throws Exception
     */
    public void testChoiceAttribute() throws Exception {

        // TODO it seems the XMLDiff does not detect order of attributes
        // create targeted schema
        _schema.addNamespace("pre", "my.namespace.org");
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);

        Group group = new Group();
        group.setOrder(Order.choice);
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        ElementDecl e2 = new ElementDecl(_schema);
        e2.setName("myAttr2");
        group.addElementDecl(e2);

        ElementDecl e3 = new ElementDecl(_schema);
        e3.setName("myAttr3");
        group.addElementDecl(e3);

        // compare
        TestResult result = doTest("complextype_choiceattribute.xsd");
        assertEquals("choice group attributes test failed",
                TestResult.IDENTICAL, result);
    }

    /**
     * extension generation test
     * 
     * @throws Exception
     */
    public void testExtension() throws Exception {
        // create targeted schema
        // create base type
        ComplexType cBaseType = _schema.createComplexType("baseType");
        _schema.addComplexType(cBaseType);

        Group gBase = new Group();
        cBaseType.addGroup(gBase);

        ElementDecl ebase = new ElementDecl(_schema);
        ebase.setName("baseAttr");
        gBase.addElementDecl(ebase);

        // create dependency
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);
        cType.setBaseType(cBaseType);
        cType.setDerivationMethod(SchemaNames.EXTENSION);

        Group group = new Group();
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        ElementDecl e2 = new ElementDecl(_schema);
        e2.setName("myAttr2");
        group.addElementDecl(e2);

        // compare
        TestResult result = doTest("complextype_attributeorder.xsd");
        assertEquals("create extension test failed", TestResult.IDENTICAL,
                result);
    }

    /**
     * extension generation test
     * 
     * @throws Exception
     */
    public void testCreateElementForComplexType() throws Exception {

        // create targeted schema
        _schema.addNamespace("pre", "my.namespace.org");

        // create dependency
        ComplexType cType = _schema.createComplexType("myType");
        _schema.addComplexType(cType);

        Group group = new Group();
        cType.addGroup(group);

        ElementDecl e = new ElementDecl(_schema);
        e.setName("myAttr");
        group.addElementDecl(e);

        ElementDecl element = new ElementDecl(_schema);
        element.setName("myElement");
        element.setTypeReference("myType");
        _schema.addElementDecl(element);

        // compare
        TestResult result = doTest("complextype_elementforcomplextype.xsd");
        assertEquals("test create element for complexType test failed",
                TestResult.IDENTICAL, result);
    }
}
