1
19
20 package com.liferay.lock.util;
21
22 import com.liferay.lock.DuplicateLockException;
23 import com.liferay.lock.ExpiredLockException;
24 import com.liferay.lock.NoSuchLockException;
25 import com.liferay.lock.model.Lock;
26 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
27
28 import java.util.Map;
29 import java.util.concurrent.ConcurrentHashMap;
30
31
38 public class LockPool {
39
40 public static void clear() {
41 _instance._clear();
42 }
43
44 public static Lock getLock(String className, Comparable<?> pk)
45 throws ExpiredLockException, NoSuchLockException {
46
47 return _instance._getLock(className, pk);
48 }
49
50 public static boolean hasLock(
51 String className, Comparable<?> pk, long userId) {
52
53 return _instance._hasLock(className, pk, userId);
54 }
55
56 public static boolean isLocked(String className, Comparable<?> pk) {
57 return _instance._isLocked(className, pk);
58 }
59
60 public static Lock lock(
61 String className, Comparable<?> pk, long userId, String owner,
62 long expirationTime)
63 throws DuplicateLockException {
64
65 return _instance._lock(className, pk, userId, owner, expirationTime);
66 }
67
68 public static Lock refresh(String uuid, long expirationTime)
69 throws NoSuchLockException {
70
71 return _instance._refresh(uuid, expirationTime);
72 }
73
74 public static void unlock(String className, Comparable<?> pk) {
75 _instance._unlock(className, pk);
76 }
77
78 private LockPool() {
79 _locksByClassName =
80 new ConcurrentHashMap<String, Map<Comparable<?>, Lock>>();
81 _lockByUuid = new ConcurrentHashMap<String, Lock>();
82 }
83
84 private void _clear() {
85 _locksByClassName.clear();
86 _lockByUuid.clear();
87 }
88
89 private Lock _getLock(String className, Comparable<?> pk)
90 throws ExpiredLockException, NoSuchLockException {
91
92 Map<Comparable<?>, Lock> locksByPK = _getLocks(className);
93
94 Lock lock = locksByPK.get(pk);
95
96 if (lock == null) {
97 throw new NoSuchLockException();
98 }
99 else if (lock.isExpired()) {
100 _unlock(className, pk);
101
102 throw new ExpiredLockException();
103 }
104
105 return lock;
106 }
107
108 private Map<Comparable<?>, Lock> _getLocks(String className) {
109 Map<Comparable<?>, Lock> locksByPK = _locksByClassName.get(className);
110
111 if (locksByPK == null) {
112 locksByPK = new ConcurrentHashMap<Comparable<?>, Lock>();
113
114 _locksByClassName.put(className, locksByPK);
115 }
116
117 return locksByPK;
118 }
119
120 private boolean _hasLock(String className, Comparable<?> pk, long userId) {
121 try {
122 Lock lock = _getLock(className, pk);
123
124 if (lock.getUserId() == userId) {
125 return true;
126 }
127 }
128 catch (ExpiredLockException ele) {
129 }
130 catch (NoSuchLockException nsle) {
131 }
132
133 return false;
134 }
135
136 private boolean _isLocked(String className, Comparable<?> pk) {
137 try {
138 _getLock(className, pk);
139
140 return true;
141 }
142 catch (ExpiredLockException ele) {
143 }
144 catch (NoSuchLockException nsle) {
145 }
146
147 return false;
148 }
149
150 private Lock _lock(
151 String className, Comparable<?> pk, long userId, String owner,
152 long expirationTime)
153 throws DuplicateLockException {
154
155 Map<Comparable<?>, Lock> locksByPK = _getLocks(className);
156
157 Lock lock = locksByPK.get(pk);
158
159 if (lock != null) {
160 if (lock.isExpired()) {
161 _unlock(className, pk);
162
163 lock = null;
164 }
165 else if (!lock.getOwner().equals(owner)) {
166 throw new DuplicateLockException(lock);
167 }
168 }
169
170 if (lock == null) {
171 String uuid = PortalUUIDUtil.generate();
172
173 lock = new Lock(uuid, className, pk, userId, owner, expirationTime);
174
175 locksByPK.put(pk, lock);
176
177 _lockByUuid.put(uuid, lock);
178 }
179 else {
180 lock.setExpirationTime(expirationTime);
181 }
182
183 return lock;
184 }
185
186 private Lock _refresh(String uuid, long expirationTime)
187 throws NoSuchLockException {
188
189 Lock lock = _lockByUuid.get(uuid);
190
191 if (lock != null) {
192 lock.setExpirationTime(expirationTime);
193
194 return lock;
195 }
196
197 throw new NoSuchLockException();
198 }
199
200 private void _unlock(String className, Comparable<?> pk) {
201 Map<Comparable<?>, Lock> locksByPK = _getLocks(className);
202
203 Lock lock = locksByPK.remove(pk);
204
205 if (lock != null) {
206 _lockByUuid.remove(lock.getUuid());
207 }
208 }
209
210 private static LockPool _instance = new LockPool();
211
212 private Map<String, Map<Comparable<?>, Lock>> _locksByClassName;
213 private Map<String, Lock> _lockByUuid;
214
215 }