1 /************************************************************************ 2 * Copyright (c) 2000-2006 The Apache Software Foundation. * 3 * All rights reserved. * 4 * ------------------------------------------------------------------- * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you * 6 * may not use this file except in compliance with the License. You * 7 * 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 * 14 * implied. See the License for the specific language governing * 15 * permissions and limitations under the License. * 16 ***********************************************************************/ 17 18 package org.apache.james.util; 19 20 import java.util.Hashtable; 21 22 /*** 23 * Provides Lock functionality 24 * 25 */ 26 public class Lock { 27 /*** 28 * An internal hash table of keys to locks 29 */ 30 private Hashtable locks = new Hashtable(); 31 32 /*** 33 * Check to see if the object is locked 34 * 35 * @param key the Object on which to check the lock 36 * @return true if the object is locked, false otherwise 37 */ 38 public boolean isLocked(final Object key) { 39 return (locks.get(key) != null); 40 } 41 42 /*** 43 * Check to see if we can lock on a given object. 44 * 45 * @param key the Object on which to lock 46 * @return true if the calling thread can lock, false otherwise 47 */ 48 public boolean canI(final Object key) { 49 Object o = locks.get( key ); 50 51 if (null == o || o == this.getCallerId()) { 52 return true; 53 } 54 55 return false; 56 } 57 58 /*** 59 * Lock on a given object. 60 * 61 * @param key the Object on which to lock 62 * @return true if the locking was successful, false otherwise 63 */ 64 public boolean lock(final Object key) { 65 Object theLock; 66 67 synchronized(this) { 68 theLock = locks.get(key); 69 70 if (null == theLock) { 71 locks.put(key, getCallerId()); 72 return true; 73 } else if (getCallerId() == theLock) { 74 return true; 75 } else { 76 return false; 77 } 78 } 79 } 80 81 /*** 82 * Release the lock on a given object. 83 * 84 * @param key the Object on which the lock is held 85 * @return true if the unlocking was successful, false otherwise 86 */ 87 public boolean unlock(final Object key) { 88 Object theLock; 89 synchronized (this) { 90 theLock = locks.get(key); 91 92 if (null == theLock) { 93 return true; 94 } else if (getCallerId() == theLock) { 95 locks.remove(key); 96 return true; 97 } else { 98 return false; 99 } 100 } 101 } 102 103 /*** 104 * Private helper method to abstract away caller ID. 105 * 106 * @return the id of the caller (i.e. the Thread reference) 107 */ 108 private Object getCallerId() { 109 return Thread.currentThread(); 110 } 111 }