/*
 * Copyright (c) 2002-2003 IST-2004-2006-511731 ModelWare - ModelBus.
 * All rights reserved.
 *
 * This software is published under the terms of the ModelBus Software License
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * A copy of ModelBus Software License is provided with this distribution in
 * doc/LICENSE.txt file.
 */

/*
 * Created on 5 juil. 2005
 *
 */
package org.eclipse.mddi.modelbus.adapter.test.unit;

import java.util.Collection;

import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPMessage;

import org.apache.log4j.Logger;
import org.eclipse.mddi.modelbus.adapter.infrastructure.LoggerConfigurator;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.DefaultMarshaler;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.SoapUtil;

import org.eclipse.mddi.modelbus.description.abstract_.*;
import org.eclipse.mddi.modelbus.description.abstract_.impl.AbstractPackageImpl;

import junit.framework.TestCase;

/**
 * Tests marshalling and unmarshalling mechanism. In each test methods, a
 * different type of parameter is marshalled. Then it is unmarshalled. The
 * results of marshalling and unmarshalling are compared. If they are correct,
 * then they must be equal.
 * 
 * @author P. Sriplakich, Andrey Sadovykh (LIP6)
 * 
 */
public class MarshallTest extends TestCase {

    private static Logger logger = Logger.getLogger(MarshallTest.class);

    private static DefaultMarshaler marshaler = new DefaultMarshaler(null);

    public static void main(String[] args) {
        LoggerConfigurator.configure();
        junit.textui.TestRunner.run(MarshallTest.class);
    }

    SOAPMessage msg;

    SOAPElement topElem;

    // a factory for creating service description
    AbstractFactory factory;

    /*
     * @see TestCase#setUp()
     */
    protected void setUp() throws Exception {
        try {
            msg = SoapUtil.messageFactory.createMessage();
            SOAPBody body = msg.getSOAPBody();
            DefaultMarshaler.setNamespaces(body);
            topElem = body.addChildElement("service1", "modelbus");
            factory = AbstractPackageImpl.init().getAbstractFactory();
        } catch (Exception e) {
            throw new Exception("TestCase can not be initialized", e);
        }
    }

    /*
     * @see TestCase#tearDown()
     */
    protected void tearDown() throws Exception {

    }

    public void testMarshall_string() throws Exception {

        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("string");
        p.setType(t);

        Object parameterValue = "test string";

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_string");
        logger.info("marshall result = \n" + topElem + "\n");
        Object unmarshalledParam;
        unmarshalledParam = marshaler.unmarshal(p, topElem);
        assertEquals(parameterValue, unmarshalledParam);

    }

    public void testMarshall_string_array() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        p.setUpper(-1);
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("string");
        p.setType(t);

        String[] parameterValue = new String[] { "string1", "string2",
                "string3" };

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_string_array");
        logger.info("marshall result = \n" + topElem + "\n");
        String[] unmarshalledParam = (String[]) marshaler.unmarshal(p, topElem);

        for (int i = 0; i < parameterValue.length; i++) {
            assertEquals(parameterValue[i], unmarshalledParam[i]);
        }

    }

    public void testMarshall_boulean_array() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        p.setUpper(-1);
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("boolean");
        p.setType(t);

        Boolean[] parameterValue = new Boolean[] { new Boolean(true),
                new Boolean(false), new Boolean(false) };

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_boolean_array");
        logger.info("marshall result = \n" + topElem + "\n");
        Boolean[] unmarshalledParam = (Boolean[]) marshaler.unmarshal(p, topElem);
         

        for (int i = 0; i < parameterValue.length; i++) {
            assertEquals(parameterValue[i], unmarshalledParam[i]);
        }

    }
    public void testMarshall_int_array() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        p.setUpper(-1);
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("integer");
        p.setType(t);

        Integer[] parameterValue = new Integer[] { new Integer(456),
                new Integer(789), new Integer(687) };

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_int_array");
        logger.info("marshall result = \n" + topElem + "\n");
        Integer[] unmarshalledParam = (Integer[]) marshaler.unmarshal(p, topElem);
         

        for (int i = 0; i < parameterValue.length; i++) {
            assertEquals(parameterValue[i], unmarshalledParam[i]);
        }

    }
    public void testMarshall_double_array() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        p.setUpper(-1);
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("double");
        p.setType(t);

        Double[] parameterValue = new Double[] { new Double(456.757),
                new Double(789.757), new Double(687.757) };

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_double_array");
        logger.info("marshall result = \n" + topElem + "\n");
        Double[] unmarshalledParam = (Double[]) marshaler.unmarshal(p, topElem);
         

        for (int i = 0; i < parameterValue.length; i++) {
            assertEquals(parameterValue[i], unmarshalledParam[i]);
        }

    }
    public void testMarshall_model_array() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        p.setUpper(-1);
        ModelType t = factory.createModelType();
        p.setType(t);

        Collection[] parameterValue = new Collection[]{Util.createUml2Model(),Util.createUml2Model(),Util.createUml2Model()};


        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_model_array");
        logger.info("marshall result = \n" + topElem + "\n");
        Collection[] unmarshalledParam = (Collection[]) marshaler.unmarshal(p, topElem);
         

        for (int i = 0; i < parameterValue.length; i++) {
            assertTrue(Util.compareModels(parameterValue[i], unmarshalledParam[i]));
        }

    }

    public void testMarshall_null() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("boolean");
        p.setType(t);

        Object parameterValue = null;

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_null");
        logger.info("marshall result = \n" + topElem + "\n");
        Object unmarshalledParam = marshaler.unmarshal(p, topElem);

        assertEquals(parameterValue, unmarshalledParam);
    }

    public void testMarshall_boolean() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("boolean");
        p.setType(t);

        Object parameterValue = new Boolean(true);

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_boolean");
        logger.info("marshall result = \n" + topElem + "\n");
        Object unmarshalledParam = marshaler.unmarshal(p, topElem);

        assertEquals(parameterValue, unmarshalledParam);
    }

    public void testMarshall_int() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("integer");
        p.setType(t);

        Object parameterValue = new Integer(456573);

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_boolean");
        logger.info("marshall result = \n" + topElem + "\n");
        Object unmarshalledParam = marshaler.unmarshal(p, topElem);

        assertEquals(parameterValue, unmarshalledParam);
    }

    public void testMarshall_double() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        PrimitiveType t = factory.createPrimitiveType();
        t.setName("double");
        p.setType(t);

        Object parameterValue = new Double(456573.646546);

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_boolean");
        logger.info("marshall result = \n" + topElem + "\n");
        Object unmarshalledParam = marshaler.unmarshal(p, topElem);

        assertEquals(parameterValue, unmarshalledParam);
    }

    public void testMarshall_model() throws Exception {
        // create parameter description
        Parameter p = factory.createParameter();
        p.setName("p1");
        ModelType t = factory.createModelType();
        p.setType(t);

        Collection parameterValue = Util.createUml2Model();
        
        logger.info("Size of model1:"+parameterValue.size());

        topElem.removeContents();
        marshaler.marshal(p, parameterValue, topElem);
        logger.info("testMarshall_model");
        //logger.info("marshall result = \n" + topElem + "\n");
        Collection unmarshalledParam = (Collection) marshaler.unmarshal(p,
                topElem);
        logger.info("Size of model2:"+unmarshalledParam.size());

        logger.info("Compare result:"+Util.compareModels(parameterValue, unmarshalledParam));
        assertTrue(Util.compareModels(parameterValue, unmarshalledParam));
    }

}
