/*
 * 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:
// mmacivor - March 2nd/2010 - 2.0 - Initial implementation
package org.eclipse.persistence.testing.oxm.mappings.compositeobject.self;

import java.util.Calendar;
import org.eclipse.persistence.testing.oxm.mappings.XMLMappingTestCases;

public class SelfWithOtherCompositeTestCases extends XMLMappingTestCases {
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/oxm/mappings/compositeobject/self/SelfWithOtherComposite.xml";
    private final static int CONTROL_START_YYYY = 1970;
    private final static int CONTROL_START_MM = 0;
    private final static int CONTROL_START_DD = 1;
    private final static int CONTROL_END_YYYY = 2004;
    private final static int CONTROL_END_MM = 0;
    private final static int CONTROL_END_DD = 1;
    private final static String CONTROL_STREET = "123 A St.";
    private final static String CONTROL_CITY = "Any Town";

    public SelfWithOtherCompositeTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_RESOURCE);
        setProject(new SelfWithOtherCompositeProject());
    }

    @Override
    protected Object getControlObject() {
        Calendar start = Calendar.getInstance();
        start.clear();
        start.set(CONTROL_START_YYYY, CONTROL_START_MM, CONTROL_START_DD);

        Calendar end = Calendar.getInstance();
        end.clear();
        end.set(CONTROL_END_YYYY, CONTROL_END_MM, CONTROL_END_DD);

        Employee employee = new Employee();

        Employee.Period period = employee.getStartDateAndEndDate();
        period.setStartDate(start);
        period.setEndDate(end);
        employee.setStartDateAndEndDate(period);

        Address address = new Address();
        address.street = CONTROL_STREET;
        address.city = CONTROL_CITY;
        employee.address = address;

        return employee;
    }
}

