/*
 * Copyright (c) 1998, 2019 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.descriptors;

import java.util.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;

/**
 * <p><b>Purpose</b>: An implementation of the OptimisticLockingPolicy interface.
 * This policy compares only the changed fields in the WHERE clause
 * when doing an update.  If any field has been changed, an optimistic
 * locking exception will be thrown.  A delete will only compare
 * the primary key.  <p>
 * NOTE: This policy can only be used inside a unit of work.
 *
 * @since TopLink 2.1
 * @author Peter Krogh
 */
public class ChangedFieldsLockingPolicy extends FieldsLockingPolicy {

    /**
     * PUBLIC:
     * Create a new changed fields locking policy.
     * This locking policy is based on locking on all changed fields by comparing with
     * their previous values to detect field-level collisions.
     *
     * Note: the unit of work must be used for all updates when using field locking. Without
     * a unit of work, there is no way for  to know what the original values were
     * without the back up clone in the unit of work.
     */
    public ChangedFieldsLockingPolicy() {
        super();
    }

    /**
     * INTERNAL:
     * Values to be included in the locking mechanism are added to the translation row.
     * For changed fields the normal build row is ok as only changed fields matter.
     */
    @Override
    public void addLockValuesToTranslationRow(ObjectLevelModifyQuery query) {
        verifyUsage(query.getSession());
        Object object;
        if (query.isDeleteObjectQuery()) {
            return;
        }
        object = query.getBackupClone();

        // EL bug 319759
        if (query.isUpdateObjectQuery()) {
            query.setShouldValidateUpdateCallCacheUse(true);
        }

        for (Enumeration enumtr = query.getModifyRow().keys(); enumtr.hasMoreElements();) {
            DatabaseField field = (DatabaseField)enumtr.nextElement();
            DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForField(field);
            mapping.writeFromObjectIntoRow(object, query.getTranslationRow(), query.getSession(), WriteType.UNDEFINED);
        }
    }

    /**
     * INTERNAL:
     * When given an expression, this method will return a new expression with the optimistic
     * locking values included.  The values are taken from the passed in database row.
     * This expression will be used in a delete call.
     * No new criteria will be added for changed fields.
     */
    @Override
    public Expression buildDeleteExpression(DatabaseTable table, Expression mainExpression, AbstractRecord row) {
        return mainExpression;
    }

    /**
     * INTERNAL:
     * Returns the fields that should be compared in the where clause.
     * In this case, it is only the fields that were changed.
     */
    @Override
    protected List<DatabaseField> getFieldsToCompare(DatabaseTable table, AbstractRecord transRow, AbstractRecord modifyRow) {
        List<DatabaseField> fields = getAllNonPrimaryKeyFields(table);
        List<DatabaseField> returnedFields = new ArrayList<>();
        for (DatabaseField field : fields) {
            if (modifyRow.containsKey(field)) {
                returnedFields.add(field);
            }
        }
        return returnedFields;
    }
}
