/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/jdomobjects/XObjectNode_0_x_Test.java,v 1.1 2004/03/25 16:18:14 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:14 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.apache.slide.store.tamino.jdomobjects;

import java.io.IOException;
import java.util.Enumeration;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.apache.slide.store.tamino.Configuration;
import org.apache.slide.store.tamino.common.XUriCache;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.JDom;
import org.jdom.Element;
import org.jdom.JDOMException;

public class XObjectNode_0_x_Test extends TestCase {
    private final String STORE_URI = "/" + Configuration.get().taminoCollection;
    private final String PARENT_URI = STORE_URI + "/dir";
    private final String MY_URI = PARENT_URI + "/foo";

    private XUriCache uriCache;
    
    public XObjectNode_0_x_Test(String name) {
        super( name );
    }

    public void setUp() throws Exception {
        super.setUp();
        
        uriCache = new XUriCache();
    }
    public void testKindSubject() throws JDOMException {
        checkKind("subject", SubjectNode.class);
    }

    public void testKindUnkown() throws JDOMException {
        try {
            checkKind("noSuchKind", null);
            fail();
        } catch (IllegalStateException e) {
            // ok
        }
    }


    public void testNewChildren() throws JDOMException {
        ObjectNode slide;
        Enumeration en;

        slide = checkNormal();
        en = slide.enumerateBindings();
        checkBinding("first", uriCache.get(STORE_URI + "/a/first"), en.nextElement());
        checkBinding("second", uriCache.get(STORE_URI + "/a/second"), en.nextElement());
        assertFalse(en.hasMoreElements());
    }

    public void testExistingChildren() throws JDOMException {
        String uuri;
        ObjectNode slide;
        Enumeration en;

        uuri = uriCache.getOrCreate(true, STORE_URI + "/a/first");
        uriCache.put(STORE_URI + "/a/second", uuri);
        slide = checkNormal();
        en = slide.enumerateBindings();
        checkBinding("first", uuri, en.nextElement());
        checkBinding("second", uuri, en.nextElement());
        assertFalse(en.hasMoreElements());
    }

    public void testNewParent() throws JDOMException {
        ObjectNode slide;
        Enumeration en;

        slide = checkNormal();
        en = slide.enumerateParentBindings();
        checkParentBinding("foo", uriCache.get(PARENT_URI), en.nextElement());
        assertFalse(en.hasMoreElements());
    }

    public void testExistingParent() throws JDOMException {
        String uuri;
        ObjectNode slide;
        Enumeration en;

        uuri = uriCache.getOrCreate(true, PARENT_URI);
        slide = checkNormal();
        en = slide.enumerateParentBindings();
        checkParentBinding("foo", uuri, en.nextElement());
        assertFalse(en.hasMoreElements());
    }

    //--

    private ObjectNode checkNormal() throws JDOMException {
        return check("<objectNode kind='subject'>\n" +
            "  <children>\n" +
            "    <childNode uriRef='" + STORE_URI + "/a/first'/>\n" +
            "    <childNode uriRef='" + STORE_URI + "/a/second'/>\n" +
            "  </children>\n" +
            "  <links/>\n" +
            "</objectNode>"
        );
    }
    private void checkKind(String kindStr, Class kindClass) throws JDOMException {
        ObjectNode slide;

        slide = check(
            "<objectNode kind='" + kindStr + "'>\n" +
                "  <children/>\n" +
                "  <links/>\n" +
                "</objectNode>"
        );
        assertTrue(kindClass.isInstance(slide));
    }

    private void checkBinding(String name, String uriRef, Object obj) {
        ObjectNode.Binding binding;

        assertTrue(obj instanceof ObjectNode.Binding);
        binding = (ObjectNode.Binding) obj;
        assertEquals(name, binding.getName());
        assertEquals(uriRef, binding.getUuri());
    }

    private void checkParentBinding(String name, String uriRef, Object obj) {
        ObjectNode.ParentBinding binding;

        assertTrue(obj instanceof ObjectNode.ParentBinding);
        binding = (ObjectNode.ParentBinding) obj;
        assertEquals(name, binding.getName());
        assertEquals(uriRef, binding.getUuri());
    }

    private ObjectNode check(String str) throws JDOMException {
        final String UURI = XUuri.create(true, MY_URI);
        Element xml;
        ObjectNode slide;

        try {
            xml = JDom.forString(str).getRootElement();
        } catch (IOException e) {
            fail(e.getMessage());
            return null; // dummy
        }
        // do toSlide/getElement roundtrip to test getElement as well
        slide = XObjectNode.toSlideFrom_0_x(true, xml, MY_URI, UURI, uriCache);
        xml = XObjectNode.toXml(slide);
        return XObjectNode.toSlide(xml, MY_URI);
    }

    /**
     ** Start precisely this test suite with the commandline interface.
     **
     ** @param args   commandline options (not used)
     **/
    public static void main( String[] args ) {
        TestRunner.run( suite() );
    }


    public static Test suite() {
        return new TestSuite(XObjectNode_0_x_Test.class);
    }
}
