1
22
23 package com.liferay.lock.util;
24
25 import com.liferay.lock.DuplicateLockException;
26 import com.liferay.lock.ExpiredLockException;
27 import com.liferay.lock.NoSuchLockException;
28 import com.liferay.lock.model.Lock;
29 import com.liferay.lock.model.impl.LockImpl;
30 import com.liferay.util.CollectionFactory;
31
32 import java.util.Collections;
33 import java.util.Iterator;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.TreeSet;
37
38
44 public class LockPool {
45
46 public static void clear() {
47 _instance._clear();
48 }
49
50 public static Lock getLock(String className, Comparable pk)
51 throws ExpiredLockException, NoSuchLockException {
52
53 return _instance._getLock(className, pk);
54 }
55
56 public static Set getLocksByCompanyId(long companyId) {
57 Set locksByCompanyId = _instance._getLocksByCompanyId(companyId);
58
59 Iterator itr = locksByCompanyId.iterator();
60
61 while (itr.hasNext()) {
62 Lock lock = (Lock)itr.next();
63
64 if (lock.isExpired()) {
65 itr.remove();
66
67 _instance._getLocks(
68 lock.getClassName(), lock.getPrimaryKey()).remove(lock);
69 _instance._getLocksByUserId(lock.getUserId()).remove(lock);
70 }
71 }
72
73 return locksByCompanyId;
74 }
75
76 public static Set getLocksByUserId(long userId) {
77 Set locksByUserId = _instance._getLocksByUserId(userId);
78
79 Iterator itr = locksByUserId.iterator();
80
81 while (itr.hasNext()) {
82 Lock lock = (Lock)itr.next();
83
84 if (lock.isExpired()) {
85 itr.remove();
86
87 _instance._getLocks(
88 lock.getClassName(), lock.getPrimaryKey()).remove(lock);
89 _instance._getLocksByCompanyId(
90 lock.getCompanyId()).remove(lock);
91 }
92 }
93
94 return locksByUserId;
95 }
96
97 public static boolean hasLock(
98 String className, Comparable pk, long userId) {
99
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(
108 String className, Comparable pk, long companyId, long userId,
109 long expirationTime)
110 throws DuplicateLockException {
111
112 _instance._lock(className, pk, companyId, userId, 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 }
141 else if (lock.isExpired()) {
142 _unlock(className, pk);
143
144 throw new ExpiredLockException();
145 }
146
147 return lock;
148 }
149
150 private Map _getLocks(String className, Comparable pk) {
151 Map locksByPK = (Map)_locksByClassName.get(className);
152
153 if (locksByPK == null) {
154 locksByPK = CollectionFactory.getSyncHashMap();
155
156 _locksByClassName.put(className, locksByPK);
157 }
158
159 return locksByPK;
160 }
161
162 private Set _getLocksByCompanyId(long companyId) {
163 Long companyIdObj = new Long(companyId);
164
165 Set set = (Set)_locksByCompanyId.get(companyIdObj);
166
167 if (set == null) {
168 set = Collections.synchronizedSet(new TreeSet());
169
170 _locksByCompanyId.put(companyIdObj, set);
171 }
172
173 return set;
174 }
175
176 private Set _getLocksByUserId(long userId) {
177 Long userIdObj = new Long(userId);
178
179 Set set = (Set)_locksByUserId.get(userIdObj);
180
181 if (set == null) {
182 set = Collections.synchronizedSet(new TreeSet());
183
184 _locksByUserId.put(userIdObj, set);
185 }
186
187 return set;
188 }
189
190 private boolean _hasLock(String className, Comparable pk, long userId) {
191 try {
192 Lock lock = _getLock(className, pk);
193
194 if (lock.getUserId() == userId) {
195 return true;
196 }
197 }
198 catch (ExpiredLockException ele) {
199 }
200 catch (NoSuchLockException nsle) {
201 }
202
203 return false;
204 }
205
206 private boolean _isLocked(String className, Comparable pk) {
207 try {
208 _getLock(className, pk);
209
210 return true;
211 }
212 catch (ExpiredLockException ele) {
213 }
214 catch (NoSuchLockException nsle) {
215 }
216
217 return false;
218 }
219
220 private void _lock(
221 String className, Comparable pk, long companyId, long userId,
222 long expirationTime)
223 throws DuplicateLockException {
224
225 Map locksByPK = _getLocks(className, pk);
226
227 Lock lock = (Lock)locksByPK.get(pk);
228
229 if (lock != null && lock.isExpired()) {
230 _unlock(className, pk);
231
232 lock = null;
233 }
234 else if ((lock != null) && (lock.getUserId() != userId)) {
235 throw new DuplicateLockException(lock);
236 }
237
238 if (lock == null) {
239 lock = new LockImpl(
240 className, pk, companyId, userId, expirationTime);
241
242 locksByPK.put(pk, lock);
243
244 _getLocksByCompanyId(companyId).add(lock);
245 _getLocksByUserId(userId).add(lock);
246 }
247 else {
248 lock.setExpirationTime(expirationTime);
249 }
250 }
251
252 private void _unlock(String className, Comparable pk) {
253 Map locksByPK = _getLocks(className, pk);
254
255 Lock lock = (Lock)locksByPK.remove(pk);
256
257 if (lock != null) {
258 _getLocksByCompanyId(lock.getCompanyId()).remove(lock);
259 _getLocksByUserId(lock.getUserId()).remove(lock);
260 }
261 }
262
263 private static LockPool _instance = new LockPool();
264
265 private Map _locksByClassName;
266 private Map _locksByCompanyId;
267 private Map _locksByUserId;
268
269 }