/*
 * Copyright (c) 2011, 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:
//     Blaise Doughan - 2.2 - initial implementation
package org.eclipse.persistence.testing.jaxb.xmlmarshaller;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.URL;

import jakarta.xml.bind.JAXBContext;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBUnmarshaller;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class UnmarshallerNullTestCases extends OXTestCase {

    static String DOUBLE_ERROR_XML = "org/eclipse/persistence/testing/jaxb/xmlmarshaller/Employee_TwoError.xml";

    private JAXBUnmarshaller unmarshaller;

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

    @Override
    protected void setUp() throws Exception {
        Class<?>[] classes = {Employee.class};
        JAXBContext jc = JAXBContextFactory.createContext(classes, null);
        unmarshaller = (JAXBUnmarshaller) jc.createUnmarshaller();
    }

    public void testFailNullFile() throws Exception {
        try {
            unmarshaller.unmarshal((File) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullInputSource() throws Exception {
        try {
            unmarshaller.unmarshal((InputSource) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullNode() throws Exception {
        try {
            unmarshaller.unmarshal((Node) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullNodeWithClass() throws Exception {
        try {
            unmarshaller.unmarshal((Node) null, Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNodeWithNullClass() throws Exception {
        try {
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
            XMLParser xmlParser = xmlPlatform.newXMLParser();
            xmlParser.setNamespaceAware(true);
            Node node = xmlParser.parse(stream);
            unmarshaller.unmarshal(node, null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullReader() throws Exception {
        try {
            unmarshaller.unmarshal((Reader) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullSource() throws Exception {
        try {
            unmarshaller.unmarshal((Source) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullSourceWithClass() throws Exception {
        try {
            unmarshaller.unmarshal((Source) null, Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailSourceWithNullClass() throws Exception {
        try {
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            Source source = new StreamSource(stream);
            unmarshaller.unmarshal(source, (Class) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullSourceWithType() throws Exception {
        try {
            unmarshaller.unmarshal((Source) null, (Type) Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailSourceWithNullType() throws Exception {
        try {
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            Source source = new StreamSource(stream);
            unmarshaller.unmarshal(source, (Type) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullURL() throws Exception {
        try {
            unmarshaller.unmarshal((URL) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLEventReader() throws Exception {
        try {
            unmarshaller.unmarshal((XMLEventReader) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLEventReaderWithClass() throws Exception {
        try {
            unmarshaller.unmarshal((XMLEventReader) null, Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailXMLEventReaderWithNullClass() throws Exception {
        try {
            if(null == XML_INPUT_FACTORY) {
                return;
            }
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            XMLEventReader xmlEventReader = XML_INPUT_FACTORY.createXMLEventReader(stream);
            unmarshaller.unmarshal(xmlEventReader, (Class) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLEventReaderWithType() throws Exception {
        try {
            unmarshaller.unmarshal((XMLEventReader) null, (Type) Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailXMLEventReaderWithNullType() throws Exception {
        try {
            if(null == XML_INPUT_FACTORY) {
                return;
            }
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            XMLEventReader xmlEventReader = XML_INPUT_FACTORY.createXMLEventReader(stream);
            unmarshaller.unmarshal(xmlEventReader, (Type) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLStreamReader() throws Exception {
        try {
            unmarshaller.unmarshal((XMLStreamReader) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLStreamReaderWithClass() throws Exception {
        try {
            unmarshaller.unmarshal((XMLStreamReader) null, Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailXMLStreamReaderWithNullClass() throws Exception {
        try {
            if(null == XML_INPUT_FACTORY) {
                return;
            }
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            XMLStreamReader xmlStreamReader = XML_INPUT_FACTORY.createXMLStreamReader(stream);
            unmarshaller.unmarshal(xmlStreamReader, (Class) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullXMLStreamReaderWithType() throws Exception {
        try {
            unmarshaller.unmarshal((XMLStreamReader) null, (Type) Employee.class);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailXMLStreamReaderWithNullType() throws Exception {
        try {
            if(null == XML_INPUT_FACTORY) {
                return;
            }
            InputStream stream = ClassLoader.getSystemResourceAsStream(DOUBLE_ERROR_XML);
            XMLStreamReader xmlStreamReader = XML_INPUT_FACTORY.createXMLStreamReader(stream);
            unmarshaller.unmarshal(xmlStreamReader, (Type) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

    public void testFailNullInputStream() throws Exception {
        try {
            unmarshaller.unmarshal((InputStream) null);
        } catch(IllegalArgumentException e) {
            return;
        }
        fail("IllegalArgumentException not thrown.");
    }

}
