View Javadoc

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 }