Coverage Report - org.apache.ojb.broker.locking.LockManagerCommonsImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
LockManagerCommonsImpl
N/A
N/A
1.429
LockManagerCommonsImpl$LoggerFacadeImpl
N/A
N/A
1.429
LockManagerCommonsImpl$OJBLockManager
N/A
N/A
1.429
 
 1  
 package org.apache.ojb.broker.locking;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import org.apache.commons.lang.SystemUtils;
 19  
 import org.apache.commons.transaction.locking.GenericLock;
 20  
 import org.apache.commons.transaction.locking.GenericLockManager;
 21  
 import org.apache.commons.transaction.locking.LockException;
 22  
 import org.apache.commons.transaction.util.LoggerFacade;
 23  
 import org.apache.ojb.broker.util.logging.Logger;
 24  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 25  
 
 26  
 /**
 27  
  * A {@link LockManager} implementation based on apache's commons-transaction
 28  
  * locking part.
 29  
  * <p/>
 30  
  * The timeout of locks is currently (OJB 1.0.2) not supported, maybe
 31  
  * in further versions.
 32  
  *
 33  
  * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
 34  
  * @version $Id: LockManagerCommonsImpl.java,v 1.1 2007-08-24 22:17:41 ewestfal Exp $
 35  
  */
 36  
 public class LockManagerCommonsImpl implements LockManager
 37  
 {
 38  
     private Logger log = LoggerFactory.getLogger(LockManagerCommonsImpl.class);
 39  
 
 40  
     /**
 41  
      * Timeout of the obtained lock.
 42  
      */
 43  
     private long lockTimeout;
 44  
     /**
 45  
      * Time to wait when lock call is blocked.
 46  
      */
 47  
     private long blockTimeout;
 48  
     private LoggerFacade logFacade;
 49  
     private OJBLockManager lm;
 50  
 
 51  
     public LockManagerCommonsImpl()
 52  
     {
 53  
         logFacade = new LoggerFacadeImpl();
 54  
         // default lock timeout
 55  
         this.lockTimeout = DEFAULT_LOCK_TIMEOUT;
 56  
         // default time to wait for a lock
 57  
         this.blockTimeout = DEFAULT_BLOCK_TIMEOUT;
 58  
         lm = new OJBLockManager(logFacade, blockTimeout, GenericLockManager.DEFAULT_CHECK_THRESHHOLD);
 59  
     }
 60  
 
 61  
     private boolean ignore(int isolationLevel)
 62  
     {
 63  
         return isolationLevel == IsolationLevels.IL_OPTIMISTIC || isolationLevel == IsolationLevels.IL_NONE;
 64  
     }
 65  
 
 66  
     public long getLockTimeout()
 67  
     {
 68  
         return lockTimeout;
 69  
     }
 70  
 
 71  
     public void setLockTimeout(long timeout)
 72  
     {
 73  
         this.lockTimeout = timeout;
 74  
     }
 75  
 
 76  
     public long getBlockTimeout()
 77  
     {
 78  
         return blockTimeout;
 79  
     }
 80  
 
 81  
     public void setBlockTimeout(long blockTimeout)
 82  
     {
 83  
         this.blockTimeout = blockTimeout;
 84  
     }
 85  
 
 86  
     public String getLockInfo()
 87  
     {
 88  
         String eol = SystemUtils.LINE_SEPARATOR;
 89  
         StringBuffer msg = new StringBuffer("Class: " + LockManagerCommonsImpl.class.getName() + eol);
 90  
         msg.append("lock timeout: " + getLockTimeout() + " [ms]" + eol);
 91  
         msg.append("block timeout: " + getBlockTimeout() + " [ms]" + eol);
 92  
         msg.append("commons-tx lock-manger info ==> " + eol);
 93  
         msg.append(lm);
 94  
         return msg.toString();
 95  
     }
 96  
 
 97  
     public boolean readLock(Object key, Object resourceId, int isolationLevel)
 98  
     {
 99  
         return ignore(isolationLevel) ? true : lm.readLock(key, resourceId, new Integer(isolationLevel), blockTimeout);
 100  
     }
 101  
 
 102  
     public boolean writeLock(Object key, Object resourceId, int isolationLevel)
 103  
     {
 104  
         return ignore(isolationLevel) ? true : lm.writeLock(key, resourceId, new Integer(isolationLevel), blockTimeout);
 105  
     }
 106  
 
 107  
     public boolean upgradeLock(Object key, Object resourceId, int isolationLevel)
 108  
     {
 109  
         return ignore(isolationLevel) ? true : lm.upgradeLock(key, resourceId, new Integer(isolationLevel), blockTimeout);
 110  
     }
 111  
 
 112  
     public boolean releaseLock(Object key, Object resourceId)
 113  
     {
 114  
         boolean result = true;
 115  
         try
 116  
         {
 117  
             lm.release(key, resourceId);
 118  
         }
 119  
         catch(RuntimeException e)
 120  
         {
 121  
             log.error("Can't release lock for owner key " + key + ", on resource " + resourceId, e);
 122  
             result = false;
 123  
         }
 124  
         return result;
 125  
     }
 126  
 
 127  
     public void releaseLocks(Object key)
 128  
     {
 129  
         try
 130  
         {
 131  
             lm.releaseAll(key);
 132  
         }
 133  
         catch(RuntimeException e)
 134  
         {
 135  
             log.error("Can't release all locks for owner key " + key, e);
 136  
         }
 137  
     }
 138  
 
 139  
     public boolean hasRead(Object key, Object resourceId)
 140  
     {
 141  
         return lm.hasRead(key, resourceId);
 142  
     }
 143  
 
 144  
     public boolean hasWrite(Object key, Object resourceId)
 145  
     {
 146  
         return lm.hasWrite(key, resourceId);
 147  
     }
 148  
 
 149  
     public boolean hasUpgrade(Object key, Object resourceId)
 150  
     {
 151  
         return lm.hasUpgrade(key, resourceId);
 152  
     }
 153  
 
 154  
 
 155  
     //===================================================
 156  
     // inner class, commons-tx lock manager
 157  
     //===================================================
 158  
     /**
 159  
      * Extension class of {@link CommonsOJBLockManager}
 160  
      * which supports additionally convenience methods for read/write/upgrade locks and checks
 161  
      * for these locks.
 162  
      */
 163  
     final class OJBLockManager extends CommonsOJBLockManager
 164  
     {
 165  
         public OJBLockManager(LoggerFacade logger, long timeoutMSecs, long checkThreshholdMSecs)
 166  
                 throws IllegalArgumentException
 167  
         {
 168  
             super(logger, timeoutMSecs, checkThreshholdMSecs);
 169  
         }
 170  
 
 171  
         private CommonsOJBLockManager.OJBLock lookupLock(Object resourceId)
 172  
         {
 173  
             return (CommonsOJBLockManager.OJBLock) getLock(resourceId);
 174  
         }
 175  
 
 176  
         boolean readLock(Object key, Object resourceId, Integer isolationLevel, long timeout)
 177  
         {
 178  
             /*
 179  
             arminw: Not sure what's the best way to go
 180  
             - a normal 'lock' call with enabled lock wait time (blocking)
 181  
             - or an immediately returning 'tryLock' call.
 182  
             E.g. assume the user query for 1000 objects and 100 objects has write locks
 183  
             by concurrent threads, then blocking could be counterproductive, because it could
 184  
             be that the app will wait seconds for the first read lock, get it, wait seconds
 185  
             for the next read lock,.... In the worst case app will wait for all 100 locked objects.
 186  
             So I chose the 'tryLock' call for read locks which immediately return.
 187  
             */
 188  
             int lockLevel = mapLockLevelDependendOnIsolationLevel(isolationLevel, COMMON_READ_LOCK);
 189  
             return tryLock(key, resourceId, lockLevel, true, isolationLevel);
 190  
         }
 191  
 
 192  
         boolean writeLock(Object key, Object resourceId, Integer isolationLevel, long timeout)
 193  
         {
 194  
             try
 195  
             {
 196  
                 int lockLevel = mapLockLevelDependendOnIsolationLevel(isolationLevel, COMMON_WRITE_LOCK);
 197  
                 lock(key, resourceId, lockLevel, GenericLock.COMPATIBILITY_REENTRANT,
 198  
                         false, timeout, isolationLevel);
 199  
                 return true;
 200  
             }
 201  
             catch(LockException e)
 202  
             {
 203  
                 if(log.isEnabledFor(Logger.INFO)) log.info("Can't get write lock for " + key, e);
 204  
                 return false;
 205  
             }
 206  
         }
 207  
 
 208  
         boolean upgradeLock(Object key, Object resourceId, Integer isolationLevel, long timeout)
 209  
         {
 210  
             try
 211  
             {
 212  
                 int lockLevel = mapLockLevelDependendOnIsolationLevel(isolationLevel, COMMON_UPGRADE_LOCK);
 213  
                 lock(key, resourceId, lockLevel, GenericLock.COMPATIBILITY_REENTRANT,
 214  
                         false, timeout, isolationLevel);
 215  
                 return true;
 216  
             }
 217  
             catch(LockException e)
 218  
             {
 219  
                 if(log.isEnabledFor(Logger.INFO)) log.info("Can't get upgrade lock for " + key, e);
 220  
                 return false;
 221  
             }
 222  
         }
 223  
 
 224  
         boolean hasRead(Object key, Object resourceId)
 225  
         {
 226  
             CommonsOJBLockManager.OJBLock lock = lookupLock(resourceId);
 227  
             boolean result = false;
 228  
             if(lock != null)
 229  
             {
 230  
                 result = lock.hasRead(key);
 231  
             }
 232  
             return result;
 233  
         }
 234  
 
 235  
         boolean hasWrite(Object key, Object resourceId)
 236  
         {
 237  
             CommonsOJBLockManager.OJBLock lock = lookupLock(resourceId);
 238  
             boolean result = false;
 239  
             if(lock != null)
 240  
             {
 241  
                 result = lock.hasWrite(key);
 242  
             }
 243  
             return result;
 244  
         }
 245  
 
 246  
         boolean hasUpgrade(Object key, Object resourceId)
 247  
         {
 248  
             CommonsOJBLockManager.OJBLock lock = lookupLock(resourceId);
 249  
             boolean result = false;
 250  
             if(lock != null)
 251  
             {
 252  
                 result = lock.hasUpgrade(key);
 253  
             }
 254  
             return result;
 255  
         }
 256  
     }
 257  
 
 258  
 
 259  
     //===================================================
 260  
     // inner class, logging facade
 261  
     //===================================================
 262  
     /**
 263  
      * Logging facade for apache's commons-transaction.
 264  
      */
 265  
     final class LoggerFacadeImpl implements LoggerFacade
 266  
     {
 267  
 
 268  
         public LoggerFacade createLogger(String name)
 269  
         {
 270  
             return this;
 271  
         }
 272  
 
 273  
         public void logInfo(String message)
 274  
         {
 275  
             log.info(message);
 276  
         }
 277  
 
 278  
         public void logFine(String message)
 279  
         {
 280  
             log.debug(message);
 281  
         }
 282  
 
 283  
         public boolean isFineEnabled()
 284  
         {
 285  
             return log.isDebugEnabled();
 286  
         }
 287  
 
 288  
         public void logFiner(String message)
 289  
         {
 290  
             log.debug(message);
 291  
         }
 292  
 
 293  
         public boolean isFinerEnabled()
 294  
         {
 295  
             return log.isDebugEnabled();
 296  
         }
 297  
 
 298  
         public void logFinest(String message)
 299  
         {
 300  
             log.debug(message);
 301  
         }
 302  
 
 303  
         public boolean isFinestEnabled()
 304  
         {
 305  
             return log.isDebugEnabled();
 306  
         }
 307  
 
 308  
         public void logWarning(String message)
 309  
         {
 310  
             log.warn(message);
 311  
         }
 312  
 
 313  
         public void logWarning(String message, Throwable t)
 314  
         {
 315  
             log.warn(message, t);
 316  
         }
 317  
 
 318  
         public void logSevere(String message)
 319  
         {
 320  
             log.error(message);
 321  
         }
 322  
 
 323  
         public void logSevere(String message, Throwable t)
 324  
         {
 325  
             log.error(message, t);
 326  
         }
 327  
     }
 328  
 }