package au.com.observant.device.metadata.xstream;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

import junit.framework.TestCase;

public class XStreamAttributeHelperTest extends TestCase
{
    XStream xs = null;
    protected void setUp() throws Exception
    {
        xs = new XStream();;
        xs.addImplicitCollection(C.class, "as", A.class);
        xs.addImplicitCollection(A.class, "bs", B.class);
    }
    
    public void testWithXPathAbsolute()
    {
        xs.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
        checkObjectGraph();
    }

    public void testWithXPathRelative()
    {
        xs.setMode(XStream.XPATH_RELATIVE_REFERENCES);
        checkObjectGraph();
    }

    public void testWithIDs()
    {
        xs.setMode(XStream.ID_REFERENCES);
        checkObjectGraph();
    }

    private void checkObjectGraph()
    {
        C c = new C();
        A a1 = new A("a1");
        A a2 = new A("a2");
        B b1 = new B("b1", a2);
        B b2 = new B("b2", a1);
        c.as.add(a1);
        c.as.add(a2);
        a1.bs.add(b1);
        a2.bs.add(b2);
        C c_prime = (C) xs.fromXML(xs.toXML(c));
        assertEquals(a1, ((B)((A)c_prime.as.get(1)).bs.get(0)).a);
        assertEquals(a2, ((B)((A)c_prime.as.get(0)).bs.get(0)).a);
    }

    static class A
    {
        String name;
        List bs = new ArrayList();

        A(String name)
        {
            this.name = name;
        }
        public String toString()
        {
            return this.name;
        }

        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            final A other = (A) obj;
            if (name == null)
            {
                if (other.name != null)
                    return false;
            }
            else if (!name.equals(other.name))
                return false;
            return true;
        }
        
    }
    
    static class B
    {
        String name;
        A a;
        B(String name, A a)
        {
            this.name = name;
            this.a = a;
        }
        public String toString()
        {
            return name;
        }

        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            final B other = (B) obj;
            if (name == null)
            {
                if (other.name != null)
                    return false;
            }
            else if (!name.equals(other.name))
                return false;
            return true;
        }

    }
    
    static class C
    {
        List as = new ArrayList();
    }
}
