package org.apache.commons.betwixt.strategy;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import junit.framework.TestCase;

import org.apache.commons.betwixt.XMLIntrospector;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.strategy.CapitalizeNameMapper;
import org.apache.commons.betwixt.strategy.DecapitalizeNameMapper;
import org.apache.commons.betwixt.strategy.DefaultNameMapper;
import org.apache.commons.betwixt.strategy.HyphenatedNameMapper;
import org.apache.commons.betwixt.strategy.NameMapper;


/** 
 * Tests streaming/destreaming of an <code>Elements</code> bean, 
 * a container for <code>Element</code> instances, using various name mappers
 * The objective of this is to verify that containers whose names
 * are plurals of their contents can be written and read back successfully.
 * 
 * @author <a href="mailto:tima@intalio.com">Tim Anderson</a>
 */
public class TestElementsIO extends TestCase {

    public TestElementsIO(String name) {
        super(name);
    }

    public void testCapitalizeNameMapper() throws Exception {
        doTest(new CapitalizeNameMapper());
    }

    public void testDecapitalizeNameMapper() throws Exception {
        doTest(new DecapitalizeNameMapper());
    }

    public void testDefaultElementMapper() throws Exception {
        doTest(new DefaultNameMapper());
    }

    public void testHyphenatedNameMapper() throws Exception {
        doTest(new HyphenatedNameMapper());
    }

    private void doTest(NameMapper mapper) throws Exception {
        Elements elements = new Elements();
        elements.addElement(new Element("a"));
        elements.addElement(new Element("b"));
        elements.addElement(new Element("c"));

        StringWriter out = new StringWriter();
        BeanWriter writer = newBeanWriter(out, mapper);
        writer.write(elements);
        writer.flush();

        StringReader in = new StringReader(out.toString());
        BeanReader reader = new BeanReader();
        reader.setXMLIntrospector(newXMLIntrospector(mapper));
        reader.registerBeanClass(Elements.class);
        Elements result = (Elements) reader.parse(in);

        assertNotNull(result.getElement("a"));
        assertNotNull(result.getElement("b"));
        assertNotNull(result.getElement("c"));
    }

    private BeanWriter newBeanWriter(Writer writer, NameMapper mapper) {
        BeanWriter result = new BeanWriter(writer);
        result.setXMLIntrospector(newXMLIntrospector(mapper));
        result.enablePrettyPrint();
        result.setWriteIDs(false);
        return result;
    }

    private XMLIntrospector newXMLIntrospector(NameMapper mapper) {
        XMLIntrospector introspector = new XMLIntrospector();
        introspector.setAttributesForPrimitives(true);
        introspector.setWrapCollectionsInElement(false);
        introspector.setElementNameMapper(mapper);
        return introspector;
    }
}

