KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > locking > LockManagerCommonsImpl


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.2.2 2005/12/21 22:25:32 tomdz 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 JavaDoc getLockInfo()
87     {
88         String JavaDoc eol = SystemUtils.LINE_SEPARATOR;
89         StringBuffer JavaDoc msg = new StringBuffer JavaDoc("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 JavaDoc key, Object JavaDoc resourceId, int isolationLevel)
98     {
99         return ignore(isolationLevel) ? true : lm.readLock(key, resourceId, new Integer JavaDoc(isolationLevel), blockTimeout);
100     }
101
102     public boolean writeLock(Object JavaDoc key, Object JavaDoc resourceId, int isolationLevel)
103     {
104         return ignore(isolationLevel) ? true : lm.writeLock(key, resourceId, new Integer JavaDoc(isolationLevel), blockTimeout);
105     }
106
107     public boolean upgradeLock(Object JavaDoc key, Object JavaDoc resourceId, int isolationLevel)
108     {
109         return ignore(isolationLevel) ? true : lm.upgradeLock(key, resourceId, new Integer JavaDoc(isolationLevel), blockTimeout);
110     }
111
112     public boolean releaseLock(Object JavaDoc key, Object JavaDoc resourceId)
113     {
114         boolean result = true;
115         try
116         {
117             lm.release(key, resourceId);
118         }
119         catch(RuntimeException JavaDoc 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 JavaDoc key)
128     {
129         try
130         {
131             lm.releaseAll(key);
132         }
133         catch(RuntimeException JavaDoc e)
134         {
135             log.error("Can't release all locks for owner key " + key, e);
136         }
137     }
138
139     public boolean hasRead(Object JavaDoc key, Object JavaDoc resourceId)
140     {
141         return lm.hasRead(key, resourceId);
142     }
143
144     public boolean hasWrite(Object JavaDoc key, Object JavaDoc resourceId)
145     {
146         return lm.hasWrite(key, resourceId);
147     }
148
149     public boolean hasUpgrade(Object JavaDoc key, Object JavaDoc 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 JavaDoc
167         {
168             super(logger, timeoutMSecs, checkThreshholdMSecs);
169         }
170
171         private CommonsOJBLockManager.OJBLock lookupLock(Object JavaDoc resourceId)
172         {
173             return (CommonsOJBLockManager.OJBLock) getLock(resourceId);
174         }
175
176         boolean readLock(Object JavaDoc key, Object JavaDoc resourceId, Integer JavaDoc 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 JavaDoc key, Object JavaDoc resourceId, Integer JavaDoc 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 JavaDoc key, Object JavaDoc resourceId, Integer JavaDoc 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 JavaDoc key, Object JavaDoc 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 JavaDoc key, Object JavaDoc 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 JavaDoc key, Object JavaDoc 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 JavaDoc name)
269         {
270             return this;
271         }
272
273         public void logInfo(String JavaDoc message)
274         {
275             log.info(message);
276         }
277
278         public void logFine(String JavaDoc message)
279         {
280             log.debug(message);
281         }
282
283         public boolean isFineEnabled()
284         {
285             return log.isDebugEnabled();
286         }
287
288         public void logFiner(String JavaDoc message)
289         {
290             log.debug(message);
291         }
292
293         public boolean isFinerEnabled()
294         {
295             return log.isDebugEnabled();
296         }
297
298         public void logFinest(String JavaDoc message)
299         {
300             log.debug(message);
301         }
302
303         public boolean isFinestEnabled()
304         {
305             return log.isDebugEnabled();
306         }
307
308         public void logWarning(String JavaDoc message)
309         {
310             log.warn(message);
311         }
312
313         public void logWarning(String JavaDoc message, Throwable JavaDoc t)
314         {
315             log.warn(message, t);
316         }
317
318         public void logSevere(String JavaDoc message)
319         {
320             log.error(message);
321         }
322
323         public void logSevere(String JavaDoc message, Throwable JavaDoc t)
324         {
325             log.error(message, t);
326         }
327     }
328 }
329
Popular Tags