/*
 * 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.tests.aggregate;

import java.util.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.framework.WriteObjectTest;
import org.eclipse.persistence.testing.models.aggregate.AddressDescription;
import org.eclipse.persistence.testing.models.aggregate.Employee;
import org.eclipse.persistence.testing.models.aggregate.Language;
import org.eclipse.persistence.testing.models.aggregate.ProjectDescription;

/**
 * <p>
 * <b>Purpose</b>: This test checks to see if TopLink handles null's while cloning aggregates
 *
 * <p>
 * <b>Motivation </b>: This test was written to fix a bug. While merging if the root of
 *                                   an aggregate object contained any null's a null pointer exception was
 *                                        raised.
 * <p>
 * <b>Design</b>: The Complex Aggregate model is used. An Employee is registered into the UOW, and then
 *                             different levels of aggregation and relationship mappings are tested by setting them to
 *                             null.
 *
 *     <p>
 * <b>Responsibilities</b>: Try to commit an object with a null part, the merge should proceed without
 *                                             a NullPointerException
 * <p>
 *     <b>Features Used</b>: Aggregate Mappings, Unit Of Work
 *
 * <p>
 * <b>Paths Covered</b>: Within the unit of work, different parts listed below were set to null:
 *                                <ul>
 *                                <li>    <i>First and Last Name</i>, Direct To Field
 *                                <li> <i>Project's Description</i>, Aggregate Objects, Direct To Field
 *                                <li>    <i>Period</i>, Third level Aggregate Object replaced
 *                                <li>    <i>Computer</i>, Aggregate Object's 1 to 1 mapped object
 *                                <li>    <i>Responsibilities</i>,Aggregate objects 1:M mapping
 *                                <li> <i>Language Modified</i>, Aggregate objects M:M mapping
 *                                <li> <i>null added to languages</i>, Aggregate objects M:M mapping
 *                                </ul>
 */
public class CheckForNullUnitOfWorkTest extends WriteObjectTest {
    public Object unitOfWorkWorkingCopy;
    public UnitOfWork unitOfWork;
    public UnitOfWork nestedUnitOfWork;

    /**
     * CheckForNullUnitOfWorkTest constructor comment.
     */
    public CheckForNullUnitOfWorkTest() {
        super();
    }

    /**
     * CheckForNullUnitOfWorkTest constructor comment.
     * @param originalObject java.lang.Object
     */
    public CheckForNullUnitOfWorkTest(Object originalObject) {
        super(originalObject);
    }

    protected void changeUnitOfWorkWorkingCopy() {
        Employee employee = (Employee)this.unitOfWorkWorkingCopy;
        AddressDescription addressDescription = employee.getAddressDescription();
        ProjectDescription projectDescription = employee.getProjectDescription();
        Language language;
        Vector languages;

        //Root object changed
        employee.setFirstName(null);
        employee.setLastName(null);
        //Third level aggregate object changed
        addressDescription.setPeriodDescription(null);
        //1 to 1 mapped object changed
        projectDescription.getComputer().setValue(null);
        //1 level aggregate's 1:M mapping
        projectDescription.getResponsibilities().setValue(null);
        languages = (Vector)projectDescription.getLanguages().getValue();
        language = (Language)languages.firstElement();
        language.setLanguage(null);

        // 1 level aggregate's M:M mapping, adding a new element
        //languages.addElement(null);
    }

    @Override
    protected void setup() {
        super.setup();

        // Acquire first unit of work
        this.unitOfWork = getSession().acquireUnitOfWork();

        this.unitOfWorkWorkingCopy = this.unitOfWork.registerObject(this.objectToBeWritten);
        changeUnitOfWorkWorkingCopy();
        // Use the original session for comparision
        if (!compareObjects(this.originalObject, this.objectToBeWritten)) {
            throw new TestErrorException("The original object was changed through changing the clone.");
        }
    }

    @Override
    protected void test() {
        this.unitOfWork.commit();
    }

    /**
     * Verify if the objects match completely through allowing the session to use the descriptors.
     * This will compare the objects and all of their privately owned parts.
     */
    @Override
    protected void verify() {
        if (!(compareObjects(this.unitOfWorkWorkingCopy, this.objectToBeWritten))) {
            throw new TestErrorException("The object in the unit of work has not been commited properly to its parent");
        }

        super.verify();
    }
}
