/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.oxm.xmlroot.complex.inheritance;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import junit.textui.TestRunner;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.mappings.XMLMappingTestCases;
import org.eclipse.persistence.testing.oxm.xmlroot.Person;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

public class NonNullDefaultRootPersonTestCases extends XMLMappingTestCases {
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/oxm/xmlroot/complex/inheritance/personNonNullRoot.xml";
    /**
      <?xml version="1.0" encoding="UTF-8"?>
      <oxm:pRoot xsi:type="oxm:person" xmlns:oxm="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <name>Joe Smith</name>
      </oxm:pRoot>
     */
    protected final static String CONTROL_PERSON_NAME = "Joe Smith";
    protected final static int CONTROL_ID = 15;
    protected final static String CONTROL_ELEMENT_NAME = "oxm:blah";
    protected final static String CONTROL_NAMESPACE_URI = "test";

    public NonNullDefaultRootPersonTestCases(String name) throws Exception {
        super(name);
        setControlDocument(getXMLResource());
        setProject(getTopLinkProject());
    }

    public Project getTopLinkProject() {
        Project p= new XMLRootComplexInheritanceProject();
        ((XMLDescriptor)p.getDescriptor(Person.class)).setDefaultRootElement("oxm:pRoot");
        ((XMLDescriptor)p.getDescriptor(Employee.class)).setDefaultRootElement("oxm:pRoot");
        return p;
    }

     public String getXMLResource() {
        return XML_RESOURCE;
    }

    @Override
    protected Object getControlObject() {
        Person p = new Person();
        p.setName(CONTROL_PERSON_NAME);
        return p;
    }

     public static void main(String[] args) {
        String[] arguments = { "-c", "org.eclipse.persistence.testing.oxm.xmlroot.complex.inheritance.NonNullDefaultRootPersonTestCases" };

        TestRunner.main(arguments);
    }
    /*
    public void testObjectToXMLStringWriter() throws Exception {
      super.testObjectToXMLStringWriter();
    }

      public void testObjectToXMLStringWriter() throws Exception {
        StringWriter writer = new StringWriter();
        xmlMarshaller.marshal(getWriteControlObject(), writer);
       // System.out.println("#################");
        System.out.println(writer.toString());

        StringReader reader = new StringReader(writer.toString());


       // System.out.println("#################");
        InputSource inputSource = new InputSource(reader);


        Document testDocument = parser.parse(inputSource);
        writer.close();
        reader.close();

        objectToXMLDocumentTest(testDocument);
    }

     // Unmarshal tests
    public void testXMLToObjectFromInputStream() throws Exception {
        InputStream instream = ClassLoader.getSystemResourceAsStream(getXMLResource());
        Object testObject = xmlUnmarshaller.unmarshal(instream, Employee.class);
        instream.close();
        xmlToObjectTest(testObject);
    }

    public void testXMLToObjectFromDocument() throws Exception {
        Object testObject = xmlUnmarshaller.unmarshal(getControlDocument(), Employee.class);
        xmlToObjectTest(testObject);
    }

    public void testXMLToObjectFromURL() throws Exception {
        java.net.URL url = ClassLoader.getSystemResource(getXMLResource());
        Object testObject = xmlUnmarshaller.unmarshal(url, Employee.class);
        xmlToObjectTest(testObject);
    }

    public void xmlToObjectTest(Object testObject) throws Exception {
        log("\n**testXMLDocumentToObject**");
        log("Expected:");
        log(getReadControlObject().toString());
        log("Actual:");
        log(testObject.toString());

        if (getReadControlObject() instanceof XMLRoot) {
            XMLRoot controlObj = (XMLRoot)getReadControlObject();
            XMLRoot testObj = (XMLRoot)testObject;

            this.assertEquals(controlObj.getRootElementLocalName(), testObj.getRootElementLocalName());
            this.assertEquals(controlObj.getRootElementPrefix(), testObj.getRootElementPrefix());
            this.assertEquals(controlObj.getRootElementURI(), testObj.getRootElementURI());
            this.assertEquals(controlObj.getObject(), testObj.getObject());
        } else {
            this.assertEquals(getReadControlObject(), testObject);
        }
    }

      // DOES NOT APPLY
    public void testUnmarshallerHandler() throws Exception {
    }

    public void testMyTest() throws Exception {
        Person person= new Person();
        person.setName(CONTROL_PERSON_NAME);

        Employee emp = new Employee();
        emp.setName(CONTROL_PERSON_NAME);
        emp.setEmpId(CONTROL_ID);

        XMLRoot pxmlRoot = new XMLRoot();
        pxmlRoot.setRootElementName("blah");
        //pxmlRoot.setRootElementURI(CONTROL_NAMESPACE_URI);
        pxmlRoot.setObject(person);

        XMLRoot exmlRoot = new XMLRoot();
        exmlRoot.setRootElementName("blah");
        //exmlRoot.setRootElementURI(CONTROL_NAMESPACE_URI);
        exmlRoot.setObject(emp);
        //pxmlRoot.setRootElementName("oxm:pRoot");
        //pxmlRoot.setRootElementURI("test");
        //exmlRoot.setRootElementName("oxm:pRoot");
        //exmlRoot.setRootElementURI("test");
        Object objectToWrite = exmlRoot;
        //Object objectToWrite = person;

         StringWriter writer = new StringWriter();
        xmlMarshaller.marshal(objectToWrite, writer);
        System.out.println("#################Marshal");
        System.out.println(writer.toString());
        System.out.println("#################Marshal");

    }
     public void testMyTest2() throws Exception {
     System.out.println("################# UNMARSHAL");
     String resource = "org/eclipse/persistence/testing/oxm/xmlroot/complex/inheritance/employee.xml";
     InputStream instream = ClassLoader.getSystemResourceAsStream(resource);
        Object testObject = xmlUnmarshaller.unmarshal(instream);
        instream.close();

     System.out.println("################# UNMARSHAL");
     }*/
}
