/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.kernel;


/**
 * {@link LockManager} implementation that provides support
 * for version checking and version updating when locks are acquired.
 * This lock manager may be used standalone or extended for additional locking.
 *
 * @author Marc Prud'hommeaux
 */
public class VersionLockManager
    extends AbstractLockManager {

    private boolean _versionCheckOnReadLock = true;
    private boolean _versionUpdateOnWriteLock = true;
    private boolean _refreshing = false;

    /**
     * Returns the given instance's lock level, assuming that the state's
     * lock object is a number. If the given instance is embedded, traverses
     * to its owner. Override if lock is not stored as a number.
     */
    @Override
    public int getLockLevel(OpenJPAStateManager sm) {
        while (sm.getOwner() != null)
            sm = sm.getOwner();
        Number level = (Number) sm.getLock();
        return (level == null) ? LOCK_NONE : level.intValue();
    }

    /**
     * Sets the given instance's lock level to the given number. Override
     * to store something else as the lock.
     */
    protected void setLockLevel(OpenJPAStateManager sm, int level) {
        sm.setLock(level);
    }

    /**
     * Nulls given instance's lock object.
     */
    @Override
    public void release(OpenJPAStateManager sm) {
        sm.setLock(null);
    }

    /**
     * Delegates to {@link #lockInternal} after traversing to owning
     * instance (if embedded) and assuring that the instance is persistent,
     * is not new, and is not already locked at a higher level. After
     * locking, calls {@link #setLockLevel} with the given level.
     */
    @Override
    public void lock(OpenJPAStateManager sm, int level, int timeout,
        Object sdata) {
        commonLock(sm, level, timeout, sdata, !_refreshing);
    }

    @Override
    public void refreshLock(OpenJPAStateManager sm, int level, int timeout,
            Object sdata) {
    	try {
        	_refreshing = true;
    		commonLock(sm, level, timeout, sdata, false);
    	} finally {
        	_refreshing = false;
    	}
    }

    private void commonLock(OpenJPAStateManager sm, int level, int timeout,
            Object sdata, boolean postLockVersionCheck) {
        if (level == LOCK_NONE)
            return;
        while (sm.getOwner() != null)
            sm = sm.getOwner();
        int oldLevel = getLockLevel(sm);
        if (!sm.isPersistent() || sm.isNew() || level <= oldLevel)
            return;

        try {
            lockInternal(sm, level, timeout, sdata, postLockVersionCheck);
        } catch (RuntimeException re) {
            // revert lock
            setLockLevel(sm, oldLevel);
            throw re;
        }
    }

    /**
     * Marks the instance's transactional status in accordance with
     * the settings of {@link #getVersionCheckOnReadLock}
     * and {@link #getVersionUpdateOnWriteLock}. Override to perform
     * additional locking.
     *
     * @see StoreContext#transactional
     */
    protected void lockInternal(OpenJPAStateManager sm, int level, int timeout,
        Object sdata, boolean postLockVersionCheck) {
        optimisticLockInternal(sm, level, timeout, sdata, postLockVersionCheck);
    }

    protected void optimisticLockInternal(OpenJPAStateManager sm, int level,
        int timeout, Object sdata, boolean postLockVersionCheck) {
        // Set lock level first to prevent infinite recursion with
        // transactional(..) call
        setLockLevel(sm, level);
        if (level >= LockLevels.LOCK_WRITE && _versionUpdateOnWriteLock)
            getContext().transactional(sm.getManagedInstance(), true, null);
        else if (level >= LockLevels.LOCK_READ && _versionCheckOnReadLock)
            getContext().transactional(sm.getManagedInstance(), false, null);
    }

    /**
     * Whether or not we should force a version check at commit
     * time when a read lock is requested in order to verify read
     * consistency. Defaults to true.
     */
    public void setVersionCheckOnReadLock(boolean versionCheckOnReadLock) {
        _versionCheckOnReadLock = versionCheckOnReadLock;
    }

    /**
     * Whether or not we should force a version check at commit
     * time when a read lock is requested in order to verify read
     * consistency. Defaults to true.
     */
    public boolean getVersionCheckOnReadLock() {
        return _versionCheckOnReadLock;
    }

    /**
     * Whether or not we should force an update to the version at commit
     * time when a write lock is requested. Defaults to true.
     */
    public void setVersionUpdateOnWriteLock(boolean versionUpdateOnWriteLock) {
        _versionUpdateOnWriteLock = versionUpdateOnWriteLock;
    }

    /**
     * Whether or not we should force an update to the version at commit
     * time when a write lock is requested. Defaults to true.
     */
    public boolean getVersionUpdateOnWriteLock() {
        return _versionUpdateOnWriteLock;
    }
}
