001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.lock.util;
022:
023: import com.liferay.lock.DuplicateLockException;
024: import com.liferay.lock.ExpiredLockException;
025: import com.liferay.lock.NoSuchLockException;
026: import com.liferay.lock.model.Lock;
027: import com.liferay.lock.model.impl.LockImpl;
028: import com.liferay.util.CollectionFactory;
029:
030: import java.util.Collections;
031: import java.util.Iterator;
032: import java.util.Map;
033: import java.util.Set;
034: import java.util.TreeSet;
035:
036: /**
037: * <a href="LockPool.java.html"><b><i>View Source</i></b></a>
038: *
039: * @author Brian Wing Shun Chan
040: *
041: */
042: public class LockPool {
043:
044: public static void clear() {
045: _instance._clear();
046: }
047:
048: public static Lock getLock(String className, Comparable pk)
049: throws ExpiredLockException, NoSuchLockException {
050:
051: return _instance._getLock(className, pk);
052: }
053:
054: public static Set getLocksByCompanyId(long companyId) {
055: Set locksByCompanyId = _instance
056: ._getLocksByCompanyId(companyId);
057:
058: Iterator itr = locksByCompanyId.iterator();
059:
060: while (itr.hasNext()) {
061: Lock lock = (Lock) itr.next();
062:
063: if (lock.isExpired()) {
064: itr.remove();
065:
066: _instance._getLocks(lock.getClassName(),
067: lock.getPrimaryKey()).remove(lock);
068: _instance._getLocksByUserId(lock.getUserId()).remove(
069: lock);
070: }
071: }
072:
073: return locksByCompanyId;
074: }
075:
076: public static Set getLocksByUserId(long userId) {
077: Set locksByUserId = _instance._getLocksByUserId(userId);
078:
079: Iterator itr = locksByUserId.iterator();
080:
081: while (itr.hasNext()) {
082: Lock lock = (Lock) itr.next();
083:
084: if (lock.isExpired()) {
085: itr.remove();
086:
087: _instance._getLocks(lock.getClassName(),
088: lock.getPrimaryKey()).remove(lock);
089: _instance._getLocksByCompanyId(lock.getCompanyId())
090: .remove(lock);
091: }
092: }
093:
094: return locksByUserId;
095: }
096:
097: public static boolean hasLock(String className, Comparable pk,
098: long userId) {
099:
100: return _instance._hasLock(className, pk, userId);
101: }
102:
103: public static boolean isLocked(String className, Comparable pk) {
104: return _instance._isLocked(className, pk);
105: }
106:
107: public static void lock(String className, Comparable pk,
108: long companyId, long userId, long expirationTime)
109: throws DuplicateLockException {
110:
111: _instance._lock(className, pk, companyId, userId,
112: expirationTime);
113: }
114:
115: public static void unlock(String className, Comparable pk) {
116: _instance._unlock(className, pk);
117: }
118:
119: private LockPool() {
120: _locksByClassName = CollectionFactory.getSyncHashMap();
121: _locksByCompanyId = CollectionFactory.getSyncHashMap();
122: _locksByUserId = CollectionFactory.getSyncHashMap();
123: }
124:
125: private void _clear() {
126: _locksByClassName.clear();
127: _locksByCompanyId.clear();
128: _locksByUserId.clear();
129: }
130:
131: private Lock _getLock(String className, Comparable pk)
132: throws ExpiredLockException, NoSuchLockException {
133:
134: Map locksByPK = _getLocks(className, pk);
135:
136: Lock lock = (Lock) locksByPK.get(pk);
137:
138: if (lock == null) {
139: throw new NoSuchLockException();
140: } else if (lock.isExpired()) {
141: _unlock(className, pk);
142:
143: throw new ExpiredLockException();
144: }
145:
146: return lock;
147: }
148:
149: private Map _getLocks(String className, Comparable pk) {
150: Map locksByPK = (Map) _locksByClassName.get(className);
151:
152: if (locksByPK == null) {
153: locksByPK = CollectionFactory.getSyncHashMap();
154:
155: _locksByClassName.put(className, locksByPK);
156: }
157:
158: return locksByPK;
159: }
160:
161: private Set _getLocksByCompanyId(long companyId) {
162: Long companyIdObj = new Long(companyId);
163:
164: Set set = (Set) _locksByCompanyId.get(companyIdObj);
165:
166: if (set == null) {
167: set = Collections.synchronizedSet(new TreeSet());
168:
169: _locksByCompanyId.put(companyIdObj, set);
170: }
171:
172: return set;
173: }
174:
175: private Set _getLocksByUserId(long userId) {
176: Long userIdObj = new Long(userId);
177:
178: Set set = (Set) _locksByUserId.get(userIdObj);
179:
180: if (set == null) {
181: set = Collections.synchronizedSet(new TreeSet());
182:
183: _locksByUserId.put(userIdObj, set);
184: }
185:
186: return set;
187: }
188:
189: private boolean _hasLock(String className, Comparable pk,
190: long userId) {
191: try {
192: Lock lock = _getLock(className, pk);
193:
194: if (lock.getUserId() == userId) {
195: return true;
196: }
197: } catch (ExpiredLockException ele) {
198: } catch (NoSuchLockException nsle) {
199: }
200:
201: return false;
202: }
203:
204: private boolean _isLocked(String className, Comparable pk) {
205: try {
206: _getLock(className, pk);
207:
208: return true;
209: } catch (ExpiredLockException ele) {
210: } catch (NoSuchLockException nsle) {
211: }
212:
213: return false;
214: }
215:
216: private void _lock(String className, Comparable pk, long companyId,
217: long userId, long expirationTime)
218: throws DuplicateLockException {
219:
220: Map locksByPK = _getLocks(className, pk);
221:
222: Lock lock = (Lock) locksByPK.get(pk);
223:
224: if (lock != null && lock.isExpired()) {
225: _unlock(className, pk);
226:
227: lock = null;
228: } else if ((lock != null) && (lock.getUserId() != userId)) {
229: throw new DuplicateLockException(lock);
230: }
231:
232: if (lock == null) {
233: lock = new LockImpl(className, pk, companyId, userId,
234: expirationTime);
235:
236: locksByPK.put(pk, lock);
237:
238: _getLocksByCompanyId(companyId).add(lock);
239: _getLocksByUserId(userId).add(lock);
240: } else {
241: lock.setExpirationTime(expirationTime);
242: }
243: }
244:
245: private void _unlock(String className, Comparable pk) {
246: Map locksByPK = _getLocks(className, pk);
247:
248: Lock lock = (Lock) locksByPK.remove(pk);
249:
250: if (lock != null) {
251: _getLocksByCompanyId(lock.getCompanyId()).remove(lock);
252: _getLocksByUserId(lock.getUserId()).remove(lock);
253: }
254: }
255:
256: private static LockPool _instance = new LockPool();
257:
258: private Map _locksByClassName;
259: private Map _locksByCompanyId;
260: private Map _locksByUserId;
261:
262: }
|