⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 referenceentitylockservice.java

📁 uPortal是开放源码的Portal门户产品
💻 JAVA
字号:
/** * Copyright (c) 2002 The JA-SIG Collaborative.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the JA-SIG Collaborative *    (http://www.jasig.org/)." * * THIS SOFTWARE IS PROVIDED BY THE JA-SIG COLLABORATIVE "AS IS" AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JA-SIG COLLABORATIVE OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */package org.jasig.portal.concurrency.locking;import java.util.Date;import org.jasig.portal.EntityIdentifier;import org.jasig.portal.concurrency.IEntityLock;import org.jasig.portal.concurrency.IEntityLockService;import org.jasig.portal.concurrency.LockingException;import org.jasig.portal.properties.PropertiesManager;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * @author Dan Ellentuck * @version $Revision: 1.10.2.3 $ */public class ReferenceEntityLockService implements IEntityLockService{    private static final Log log = LogFactory.getLog(ReferenceEntityLockService.class);        // Singleton instance:    private static IEntityLockService singleton = null;    // Store for IEntityLocks:    private IEntityLockStore lockStore = null;    // Locking properties, initialized with default values, are settable    // via portal.properties:    // Are we running in a multi-server environment?  If so, the lock store    // will be in persistent storage.    private boolean multiServer = false;    // Lifetime of a lock in seconds, defaults to 5 minutes.    private int defaultLockPeriod = 300;    /* Fudge factor in milliseconds, extends the apparent expiration times     * of potentially conflicting locks beyond their actual expirations.     * We only use it when checking for locking conflicts and then only if     * inMemory == false.  Defaults to 5000.     */    private int lockToleranceMillis = 5000;/** * ReferenceEntityLockingService constructor comment. */public ReferenceEntityLockService() throws LockingException{    super();    initialize();}/** * Attempts to change the lock's <code>lockType</code> to <code>newType</code>. * @param lock IEntityLock * @param newType int * @exception org.jasig.portal.concurrency.LockingException */public void convert(IEntityLock lock, int newType) throws LockingException{    convert(lock, newType, defaultLockPeriod);}/** * Attempts to change the lock's <code>lockType</code> to <code>newType</code>. * @param lock IEntityLock * @param newType int * @param newDuration int * @exception org.jasig.portal.concurrency.LockingException */public void convert(IEntityLock lock, int newType, int newDuration) throws LockingException{    if ( lock.getLockType() == newType )       { throw new LockingException("Could not convert " + lock + " : old and new lock TYPEs are the same."); }    if ( ! isValidLockType(newType)  )        { throw new LockingException("Could not convert " + lock + " : lock TYPE " + newType + " is invalid."); }    if ( ! isValid(lock) )        { throw new LockingException("Could not convert " + lock + " : lock is invalid."); }    if ( newType == WRITE_LOCK && retrieveLocks(lock.getEntityType(), lock.getEntityKey(), null).length > 1 )        { throw new LockingException("Could not convert " + lock + " : another lock already exists."); }    if ( newType == READ_LOCK )        { /* Can always convert to READ */ }    Date newExpiration = getNewExpiration(newDuration);    getLockStore().update(lock, newExpiration, new Integer(newType));    ((EntityLockImpl)lock).setLockType(newType);    ((EntityLockImpl)lock).setExpirationTime(newExpiration);}/** * Answer if this <code>IEntityLock</code> exists in the store. * @param lock * @return boolean */public boolean existsInStore(IEntityLock lock) throws LockingException{    Class entityType = lock.getEntityType();    String key = lock.getEntityKey();    Integer lockType = new Integer(lock.getLockType());    Date expiration = lock.getExpirationTime();    String owner = lock.getLockOwner();    IEntityLock[] lockArray = getLockStore().find(entityType, key, lockType, expiration, owner);    return (lockArray.length > 0);}/** * @return int */private int getDefaultLockPeriod() {    return defaultLockPeriod;}/** * @return org.jasig.portal.concurrency.locking.IEntityLockStore */private IEntityLockStore getLockStore() {    return lockStore;}/** * @return int */private int getLockToleranceMillis() {    return lockToleranceMillis;}/** * @return java.util.Date */private Date getNewExpiration(int durationSecs){    return new Date(System.currentTimeMillis() + (durationSecs*1000));}/** * @exception LockingException */private void initialize() throws LockingException{    String eMsg = null;    try    {        multiServer = PropertiesManager.getPropertyAsBoolean("org.jasig.portal.concurrency.multiServer");        lockStore = ( multiServer )            ? RDBMEntityLockStore.singleton()            : MemoryEntityLockStore.singleton();    }    catch ( Exception e )    {        eMsg = "ReferenceEntityLockingService.initialize(): Failed to instantiate entity lock store. " + e;        log.error( eMsg);        throw new LockingException(eMsg);    }    try    {        int lockDuration = PropertiesManager.getPropertyAsInt            ("org.jasig.portal.concurrency.IEntityLockService.defaultLockDuration");        setDefaultLockPeriod(lockDuration);    }    catch ( Exception ex ) { /* defaults to 5 minutes. */ }    if ( multiServer ) {        try        {            int lockTolerance = PropertiesManager.getPropertyAsInt                ("org.jasig.portal.concurrency.clockTolerance");            setLockToleranceMillis(lockTolerance);        }        catch ( Exception ex ) { /* defaults to 0. */ }    }}/** * Answers if the entity represented by the entityType and entityKey already * has a lock of some type. *  * @param entityType * @param entityKey * @exception org.jasig.portal.concurrency.LockingException */private boolean isLocked(Class entityType, String entityKey) throws LockingException{    return isLocked(entityType, entityKey, null);}/** * Answers if the entity represented by entityType and entityKey has one * or more locks.  Param <code>lockType</code> can be null. * * @param entityType * @param entityKey * @param lockType (optional) * @exception org.jasig.portal.concurrency.LockingException */private boolean isLocked(Class entityType, String entityKey, Integer lockType) throws LockingException{    IEntityLock[] locks = retrieveLocks(entityType, entityKey, lockType);    return locks.length > 0;}/** * @return boolean */private boolean isMultiServer() {    return multiServer;}/** * @param lock IEntityLock * @return boolean */private boolean isUnexpired(IEntityLock lock){    return lock.getExpirationTime().getTime() > System.currentTimeMillis();}/** * Answers if this <code>IEntityLock</code> represents a lock that is still * good.  To be valid, a lock must exist in the underlying store and be * unexpired. * * @param lock IEntityLock * @exception org.jasig.portal.concurrency.LockingException */public boolean isValid(IEntityLock lock) throws LockingException{    return isUnexpired(lock) && existsInStore(lock);}/** * */private boolean isValidLockType(int lockType){    return ( (lockType == READ_LOCK) || (lockType == WRITE_LOCK) );}/** * Returns a lock for the entity, lock type and owner if no conflicting locks exist. * @param entityType * @param entityKey * @param lockType * @param owner * @return org.jasig.portal.groups.IEntityLock * @exception LockingException */public IEntityLock newLock(Class entityType, String entityKey, int lockType, String owner)throws LockingException{    return newLock(entityType, entityKey, lockType, owner, defaultLockPeriod);}/** * Returns a lock for the entity, lock type and owner if no conflicting locks exist. * @param entityType * @param entityKey * @param lockType * @param owner * @param durationSecs * @return org.jasig.portal.groups.IEntityLock * @exception LockingException *  * Retrieves potentially conflicting locks and checks them before adding * the new lock to the store.  The add of a write lock will fail if any  * other lock exists for the entity.  The add of a read lock will fail if  * a write lock exists for the entity.  After we add a write lock we  * check the store a second time and roll back if any other lock has snuck * in.  I think this is slightly safer than depending on the db isolation * level for transactional integrity.   */public IEntityLock newLock(Class entityType, String entityKey, int lockType, String owner, int durationSecs)throws LockingException{    int expirationSecs = durationSecs;     Date expires = getNewExpiration(expirationSecs);    IEntityLock newLock = new EntityLockImpl(entityType, entityKey, lockType, expires, owner, this);    // retrieve potentially conflicting locks:    IEntityLock[] locks = retrieveLocks(entityType, entityKey, null);    if ( lockType == WRITE_LOCK )     {        if ( locks.length > 0 )             { throw new LockingException("Could not create lock: entity already locked."); }                getLockStore().add(newLock);        locks = retrieveLocks(entityType, entityKey, null);        if ( locks.length > 1 )  // another lock snuck in        {             release(newLock);            throw new LockingException("Could not create lock: entity already locked.");        }    }    else // ( lockType == READ_LOCK )    {        for ( int i = 0; i<locks.length; i++ )        {            if ( locks[i].getLockType() == WRITE_LOCK )                { throw new LockingException("Could not create lock: entity already write locked."); }            else            {                if ( locks[i].equals(newLock) )                 {                     // another read lock from the same owner; bump the expiration time.                    expirationSecs++;                    expires = getNewExpiration(expirationSecs);                    newLock = new EntityLockImpl(entityType, entityKey, lockType, expires, owner, this);                }            }        }        getLockStore().add(newLock);    }    return newLock;}/** * Returns a lock for the entity, lock type and owner if no conflicting locks exist. * @return org.jasig.portal.groups.IEntityLock * @param entityID org.jasig.portal.EntityIdentifier * @param lockType int * @param owner String * @exception LockingException */public IEntityLock newLock(EntityIdentifier entityID, int lockType, String owner)throws LockingException{    return newLock(entityID.getType(), entityID.getKey(), lockType, owner, defaultLockPeriod);}/** * Returns a lock for the entity, lock type and owner if no conflicting locks exist. * @return org.jasig.portal.groups.IEntityLock * @param entityID org.jasig.portal.EntityIdentifier * @param lockType int * @param owner String * @param durationSecs int * @exception LockingException */public IEntityLock newLock(EntityIdentifier entityID, int lockType, String owner, int durationSecs)throws LockingException{    return newLock(entityID.getType(), entityID.getKey(), lockType, owner, durationSecs);}/** * Releases the <code>IEntityLock</code>. * @param lock IEntityLock * @exception LockingException */public void release(IEntityLock lock) throws LockingException{    getLockStore().delete(lock);    ((EntityLockImpl)lock).setExpirationTime(new Date(0));}/** * Extends the expiration time of the lock by some service-defined increment. * @param lock IEntityLock * @exception LockingException */public void renew(IEntityLock lock) throws LockingException{    renew(lock, defaultLockPeriod);}/** * Extends the expiration time of the lock by some service-defined increment. * @param lock IEntityLock * @exception LockingException */public void renew(IEntityLock lock, int duration) throws LockingException{    if ( isValid(lock) )    {        Date newExpiration = getNewExpiration(duration);        getLockStore().update(lock, newExpiration);        ((EntityLockImpl)lock).setExpirationTime(newExpiration);    }    else        { throw new LockingException("Could not renew " + lock + " : lock is invalid."); }}/** * Returns an IEntityLock[] containing unexpired locks for the entityType, entityKey * and lockType.  Param <code>lockType</code> can be null. * * @param entityType * @param entityKey * @param lockType (optional) * @exception LockingException */private IEntityLock[] retrieveLocks(Class entityType, String entityKey, Integer lockType) throws LockingException{    Date expiration = ( multiServer )        ? new Date(System.currentTimeMillis() - getLockToleranceMillis())        : new Date();    return getLockStore().findUnexpired(expiration, entityType, entityKey, lockType, null);}/** * @param newDefaultLockPeriod int */private void setDefaultLockPeriod(int newDefaultLockPeriod) {    defaultLockPeriod = newDefaultLockPeriod;}/** * @param newLockToleranceMillis int */private void setLockToleranceMillis(int newLockToleranceMillis) {    lockToleranceMillis = newLockToleranceMillis;}/** * @param newMultiServer boolean */private void setMultiServer(boolean newMultiServer) {    multiServer = newMultiServer;}/** * @return org.jasig.portal.concurrency.locking.ReferenceEntityLockService */public static synchronized IEntityLockService singleton() throws LockingException{    if ( singleton == null )        { singleton = new ReferenceEntityLockService(); }    return singleton;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -