/*
 * 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:
//  - rbarkhouse - 27 February - 2.3.3 - Initial implementation
package org.eclipse.persistence.testing.jaxb.sun.idresolver;

import org.eclipse.persistence.testing.jaxb.JAXBTestCases;

public class NonELIDResolverTestCases extends JAXBTestCases {

    private static final String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/idresolver/fruit2.xml";

    private NonELIDResolver idResolver = new NonELIDResolver();

    public NonELIDResolverTestCases(String name) throws Exception {
        super(name);
        setClasses(new Class[] { Melon.class, MelonRef.class, Box.class, FruitOrder.class });
        setControlDocument(XML_RESOURCE);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        getJAXBUnmarshaller().setProperty("org.glassfish.jaxb.IDResolver", idResolver);
    }

    public void testHitMethods() throws Exception {
        getJAXBUnmarshaller().unmarshal(getControlDocument());

        assertTrue("IDResolver.startDocument() was not called.", idResolver.hitStartDocument);
        assertTrue("IDResolver.endDocument() was not called.", idResolver.hitEndDocument);
        assertTrue("IDResolver.bind(Object) was not called.", idResolver.hitBind);
        assertTrue("IDResolver.resolve(Object) was not called.", idResolver.hitResolve);
        assertTrue("ValidationEventHandler was not set.", idResolver.eventHandlerNotNull);
    }

    @Override
    public Object getControlObject() {
        Melon m1 = new Melon();
        m1.id = "M1";
        m1.type = "Watermelon";
        m1.processed = true;
        MelonRef m1Ref = new MelonRef();
        m1Ref.ref = m1;
        Melon m2 = new Melon();
        m2.id = "M2";
        m2.type = "Cantaloupe";
        m2.processed = true;
        MelonRef m2Ref = new MelonRef();
        m2Ref.ref = m2;
        Melon m3 = new Melon();
        m3.id = "M3";
        m3.type = "Honeydew";
        m3.processed = true;
        MelonRef m3Ref = new MelonRef();
        m3Ref.ref = m3;


        Box box1 = new Box();
        box1.fruits.add(m1Ref);
        box1.fruits.add(m2Ref);
        box1.fruits.add(m1);
        box1.fruits.add(m2);
        Box box2 = new Box();
        box2.fruits.add(m3Ref);
        box2.fruits.add(m3);

        FruitOrder o = new FruitOrder();
        o.boxes.add(box1);
        o.boxes.add(box2);

        return o;
    }

}
