/*
 * 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:
//     bdoughan - August 11/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.testing.oxm.xmlmarshaller.stax;

import java.io.InputStream;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderInputSource;
import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.testing.oxm.OXTestCase;

public class UnmarshalLevelTestCases extends OXTestCase {

    private XMLInputFactory xmlInputFactory;

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

    @Override
    public void setUp() {
        try {
            xmlInputFactory = XMLInputFactory.newInstance();
        } catch(FactoryConfigurationError e) {
            xmlInputFactory = null;
        }
    }

    public void testUnmarshalLevelDocument() throws Exception {
        if(null == xmlInputFactory) {
            return;
        }

        InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/oxm/xmlmarshaller/stax/address.xml");
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(instream);

        XMLStreamReaderReader staxReader = new XMLStreamReaderReader();
        XMLContext xmlContext = new XMLContext(new AddressProject());
        XMLUnmarshaller xmlUnmarshaller = xmlContext.createUnmarshaller();
        staxReader.setErrorHandler(xmlUnmarshaller.getErrorHandler());
        XMLStreamReaderInputSource inputSource = new XMLStreamReaderInputSource(xmlStreamReader);
        xmlUnmarshaller.unmarshal(staxReader, inputSource);

        if(xmlStreamReader.getEventType() != XMLStreamReader.END_DOCUMENT) {
            fail("The last event type should have the been end document");
        }

        instream.close();
    }

    public void testUnmarshalLevelElement() throws Exception {
        if(null == xmlInputFactory) {
            return;
        }

        InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/oxm/xmlmarshaller/stax/address.xml");
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(instream);
        xmlStreamReader.next();  // Advance event to start element
        xmlStreamReader.next();  // Advance event to start element

        XMLStreamReaderReader staxReader = new XMLStreamReaderReader();
        XMLContext xmlContext = new XMLContext(new AddressProject());
        XMLUnmarshaller xmlUnmarshaller = xmlContext.createUnmarshaller();
        staxReader.setErrorHandler(xmlUnmarshaller.getErrorHandler());
        XMLStreamReaderInputSource inputSource = new XMLStreamReaderInputSource(xmlStreamReader);
        xmlUnmarshaller.unmarshal(staxReader, inputSource);

        if(xmlStreamReader.getEventType() != XMLStreamReader.END_DOCUMENT) {
            fail("The last event type should have the been end document");
        }

        instream.close();
    }

    public void testUnmarshalLevelElementWithClass() throws Exception{
           if(null == xmlInputFactory) {
               return;
           }

           InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/oxm/xmlmarshaller/stax/address.xml");
           XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(instream);
           xmlStreamReader.next();  // Advance event to start element
           xmlStreamReader.next();  // Advance event to start element

           XMLStreamReaderReader staxReader = new XMLStreamReaderReader();
           XMLContext xmlContext = new XMLContext(new AddressProject());
           XMLUnmarshaller xmlUnmarshaller = xmlContext.createUnmarshaller();
           staxReader.setErrorHandler(xmlUnmarshaller.getErrorHandler());
           XMLStreamReaderInputSource inputSource = new XMLStreamReaderInputSource(xmlStreamReader);
           xmlUnmarshaller.unmarshal(staxReader, inputSource, Address.class);

           if(xmlStreamReader.getEventType() != XMLStreamReader.END_DOCUMENT) {
               fail("The last event type should have the been end document");
           }

           instream.close();
    }

}
