001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateLockException;
018    import com.liferay.portal.ExpiredLockException;
019    import com.liferay.portal.NoSuchLockException;
020    import com.liferay.portal.kernel.dao.orm.LockMode;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.lock.LockListener;
024    import com.liferay.portal.kernel.lock.LockListenerRegistryUtil;
025    import com.liferay.portal.kernel.transaction.Propagation;
026    import com.liferay.portal.kernel.transaction.Transactional;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.model.Lock;
029    import com.liferay.portal.model.User;
030    import com.liferay.portal.service.base.LockLocalServiceBaseImpl;
031    
032    import java.util.Date;
033    import java.util.List;
034    
035    /**
036     * @author Brian Wing Shun Chan
037     * @author Shuyang Zhou
038     */
039    public class LockLocalServiceImpl extends LockLocalServiceBaseImpl {
040    
041            public void clear() throws SystemException {
042                    lockPersistence.removeByLtExpirationDate(new Date());
043            }
044    
045            public Lock getLock(String className, long key)
046                    throws PortalException, SystemException {
047    
048                    return getLock(className, String.valueOf(key));
049            }
050    
051            public Lock getLock(String className, String key)
052                    throws PortalException, SystemException {
053    
054                    Lock lock = lockPersistence.findByC_K(className, key);
055    
056                    if (lock.isExpired()) {
057                            expireLock(lock);
058    
059                            throw new ExpiredLockException();
060                    }
061    
062                    return lock;
063            }
064    
065            public Lock getLockByUuid(String uuid)
066                    throws PortalException, SystemException {
067    
068                    List<Lock> locks = lockPersistence.findByUuid(uuid);
069    
070                    if (locks.isEmpty()) {
071                            throw new NoSuchLockException();
072                    }
073    
074                    return locks.get(0);
075            }
076    
077            public boolean hasLock(long userId, String className, long key)
078                    throws SystemException {
079    
080                    return hasLock(userId, className, String.valueOf(key));
081            }
082    
083            public boolean hasLock(long userId, String className, String key)
084                    throws SystemException {
085    
086                    Lock lock = fetchLock(className, key);
087    
088                    if ((lock != null) && (lock.getUserId() == userId)) {
089                            return true;
090                    }
091                    else {
092                            return false;
093                    }
094            }
095    
096            public boolean isLocked(String className, long key) throws SystemException {
097                    return isLocked(className, String.valueOf(key));
098            }
099    
100            public boolean isLocked(String className, String key)
101                    throws SystemException {
102    
103                    Lock lock = fetchLock(className, key);
104    
105                    if (lock == null) {
106                            return false;
107                    }
108                    else {
109                            return true;
110                    }
111            }
112    
113            public Lock lock(
114                            long userId, String className, long key, String owner,
115                            boolean inheritable, long expirationTime)
116                    throws PortalException, SystemException {
117    
118                    return lock(
119                            userId, className, String.valueOf(key), owner, inheritable,
120                            expirationTime);
121            }
122    
123            public Lock lock(
124                            long userId, String className, String key, String owner,
125                            boolean inheritable, long expirationTime)
126                    throws PortalException, SystemException {
127    
128                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
129                            className);
130    
131                    if (lockListener != null) {
132                            lockListener.onBeforeLock(key);
133                    }
134    
135                    try {
136                            Date now = new Date();
137    
138                            Lock lock = lockPersistence.fetchByC_K(className, key);
139    
140                            if (lock != null) {
141                                    if (lock.isExpired()) {
142                                            expireLock(lock);
143    
144                                            lock = null;
145                                    }
146                                    else if (lock.getUserId() != userId) {
147                                            throw new DuplicateLockException(lock);
148                                    }
149                            }
150    
151                            if (lock == null) {
152                                    User user = userPersistence.findByPrimaryKey(userId);
153    
154                                    long lockId = counterLocalService.increment();
155    
156                                    lock = lockPersistence.create(lockId);
157    
158                                    lock.setCompanyId(user.getCompanyId());
159                                    lock.setUserId(user.getUserId());
160                                    lock.setUserName(user.getFullName());
161                                    lock.setClassName(className);
162                                    lock.setKey(key);
163                                    lock.setOwner(owner);
164                                    lock.setInheritable(inheritable);
165                            }
166    
167                            lock.setCreateDate(now);
168    
169                            if (expirationTime == 0) {
170                                    lock.setExpirationDate(null);
171                            }
172                            else {
173                                    lock.setExpirationDate(
174                                            new Date(now.getTime() + expirationTime));
175                            }
176    
177                            lockPersistence.update(lock, false);
178    
179                            return lock;
180                    }
181                    finally {
182                            if (lockListener != null) {
183                                    lockListener.onAfterLock(key);
184                            }
185                    }
186            }
187    
188            @Transactional(propagation = Propagation.REQUIRES_NEW)
189            public Lock lock(
190                            String className, String key, String owner,
191                            boolean retrieveFromCache)
192                    throws SystemException {
193    
194                    return lock(className, key, null, owner, retrieveFromCache);
195            }
196    
197            @Transactional(propagation = Propagation.REQUIRES_NEW)
198            public Lock lock(
199                            String className, String key, String expectedOwner,
200                            String updatedOwner, boolean retrieveFromCache)
201                    throws SystemException {
202    
203                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
204                            className);
205    
206                    if (lockListener != null) {
207                            lockListener.onBeforeLock(key);
208                    }
209    
210                    try {
211                            Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
212    
213                            if (lock == null) {
214                                    long lockId = counterLocalService.increment();
215    
216                                    lock = lockPersistence.create(lockId);
217    
218                                    lock.setCreateDate(new Date());
219                                    lock.setClassName(className);
220                                    lock.setKey(key);
221                                    lock.setOwner(updatedOwner);
222    
223                                    lockPersistence.update(lock, false);
224    
225                                    lock.setNew(true);
226                            }
227                            else if (Validator.equals(lock.getOwner(), expectedOwner)) {
228                                    lock.setCreateDate(new Date());
229                                    lock.setClassName(className);
230                                    lock.setKey(key);
231                                    lock.setOwner(updatedOwner);
232    
233                                    lockPersistence.update(lock, false);
234    
235                                    lock.setNew(true);
236                            }
237    
238                            return lock;
239                    }
240                    finally {
241                            if (lockListener != null) {
242                                    lockListener.onAfterLock(key);
243                            }
244                    }
245            }
246    
247            public Lock refresh(String uuid, long expirationTime)
248                    throws PortalException, SystemException {
249    
250                    Date now = new Date();
251    
252                    List<Lock> locks = lockPersistence.findByUuid(uuid);
253    
254                    if (locks.isEmpty()) {
255                            throw new NoSuchLockException();
256                    }
257    
258                    Lock lock = locks.get(0);
259    
260                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
261                            lock.getClassName());
262    
263                    String key = lock.getKey();
264    
265                    if (lockListener != null) {
266                            lockListener.onBeforeRefresh(key);
267                    }
268    
269                    try {
270                            lock.setCreateDate(now);
271    
272                            if (expirationTime == 0) {
273                                    lock.setExpirationDate(null);
274                            }
275                            else {
276                                    lock.setExpirationDate(
277                                            new Date(now.getTime() + expirationTime));
278                            }
279    
280                            lockPersistence.update(lock, false);
281    
282                            return lock;
283                    }
284                    finally {
285                            if (lockListener != null) {
286                                    lockListener.onAfterRefresh(key);
287                            }
288                    }
289            }
290    
291            public void unlock(String className, long key) throws SystemException {
292                    unlock(className, String.valueOf(key));
293            }
294    
295            public void unlock(String className, String key) throws SystemException {
296                    try {
297                            lockPersistence.removeByC_K(className, key);
298                    }
299                    catch (NoSuchLockException nsle) {
300                    }
301            }
302    
303            @Transactional(propagation = Propagation.REQUIRES_NEW)
304            public void unlock(
305                            String className, String key, String owner,
306                            boolean retrieveFromCache)
307                    throws SystemException {
308    
309                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
310    
311                    if (lock == null) {
312                            return;
313                    }
314    
315                    if (Validator.equals(lock.getOwner(), owner)) {
316                            LockListener lockListener =
317                                    LockListenerRegistryUtil.getLockListener(lock.getClassName());
318    
319                            if (lockListener != null) {
320                                    lockListener.onBeforeUnlock(key);
321                            }
322    
323                            try {
324                                    lockPersistence.remove(lock);
325                            }
326                            finally {
327                                    if (lockListener != null) {
328                                            lockListener.onAfterUnlock(key);
329                                    }
330                            }
331                    }
332            }
333    
334            protected void expireLock(Lock lock) throws SystemException {
335                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
336                            lock.getClassName());
337    
338                    String key = lock.getKey();
339    
340                    if (lockListener != null) {
341                            lockListener.onBeforeExpire(key);
342                    }
343    
344                    try {
345                            lockPersistence.remove(lock);
346                    }
347                    finally {
348                            if (lockListener != null) {
349                                    lockListener.onAfterExpire(key);
350                            }
351                    }
352            }
353    
354            protected Lock fetchLock(String className, String key)
355                    throws SystemException {
356    
357                    Lock lock = lockPersistence.fetchByC_K(className, key);
358    
359                    if (lock != null) {
360                            if (lock.isExpired()) {
361                                    expireLock(lock);
362    
363                                    lock = null;
364                            }
365                    }
366    
367                    return lock;
368            }
369    
370    }