001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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 getLockByUuidAndCompanyId(String uuid, long companyId)
066                    throws PortalException, SystemException {
067    
068                    List<Lock> locks = lockPersistence.findByUuid_C(uuid, companyId);
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                    Date now = new Date();
129    
130                    Lock lock = lockPersistence.fetchByC_K(className, key);
131    
132                    if (lock != null) {
133                            if (lock.isExpired()) {
134                                    expireLock(lock);
135    
136                                    lock = null;
137                            }
138                            else if (lock.getUserId() != userId) {
139                                    throw new DuplicateLockException(lock);
140                            }
141                    }
142    
143                    if (lock == null) {
144                            User user = userPersistence.findByPrimaryKey(userId);
145    
146                            long lockId = counterLocalService.increment();
147    
148                            lock = lockPersistence.create(lockId);
149    
150                            lock.setCompanyId(user.getCompanyId());
151                            lock.setUserId(user.getUserId());
152                            lock.setUserName(user.getFullName());
153                            lock.setClassName(className);
154                            lock.setKey(key);
155                            lock.setOwner(owner);
156                            lock.setInheritable(inheritable);
157                    }
158    
159                    lock.setCreateDate(now);
160    
161                    if (expirationTime == 0) {
162                            lock.setExpirationDate(null);
163                    }
164                    else {
165                            lock.setExpirationDate(new Date(now.getTime() + expirationTime));
166                    }
167    
168                    lockPersistence.update(lock);
169    
170                    return lock;
171            }
172    
173            @Transactional(propagation = Propagation.REQUIRES_NEW)
174            public Lock lock(
175                            String className, String key, String owner,
176                            boolean retrieveFromCache)
177                    throws SystemException {
178    
179                    return lock(className, key, null, owner, retrieveFromCache);
180            }
181    
182            @Transactional(propagation = Propagation.REQUIRES_NEW)
183            public Lock lock(
184                            String className, String key, String expectedOwner,
185                            String updatedOwner, boolean retrieveFromCache)
186                    throws SystemException {
187    
188                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
189    
190                    if (lock == null) {
191                            long lockId = counterLocalService.increment();
192    
193                            lock = lockPersistence.create(lockId);
194    
195                            lock.setCreateDate(new Date());
196                            lock.setClassName(className);
197                            lock.setKey(key);
198                            lock.setOwner(updatedOwner);
199    
200                            lockPersistence.update(lock);
201    
202                            lock.setNew(true);
203    
204                            lockPersistence.flush();
205                    }
206                    else if (Validator.equals(lock.getOwner(), expectedOwner)) {
207                            lock.setCreateDate(new Date());
208                            lock.setClassName(className);
209                            lock.setKey(key);
210                            lock.setOwner(updatedOwner);
211    
212                            lockPersistence.update(lock);
213    
214                            lock.setNew(true);
215    
216                            lockPersistence.flush();
217                    }
218    
219                    return lock;
220            }
221    
222            public Lock refresh(String uuid, long companyId, long expirationTime)
223                    throws PortalException, SystemException {
224    
225                    Date now = new Date();
226    
227                    List<Lock> locks = lockPersistence.findByUuid_C(uuid, companyId);
228    
229                    if (locks.isEmpty()) {
230                            throw new NoSuchLockException();
231                    }
232    
233                    Lock lock = locks.get(0);
234    
235                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
236                            lock.getClassName());
237    
238                    String key = lock.getKey();
239    
240                    if (lockListener != null) {
241                            lockListener.onBeforeRefresh(key);
242                    }
243    
244                    try {
245                            lock.setCreateDate(now);
246    
247                            if (expirationTime == 0) {
248                                    lock.setExpirationDate(null);
249                            }
250                            else {
251                                    lock.setExpirationDate(
252                                            new Date(now.getTime() + expirationTime));
253                            }
254    
255                            lockPersistence.update(lock);
256    
257                            return lock;
258                    }
259                    finally {
260                            if (lockListener != null) {
261                                    lockListener.onAfterRefresh(key);
262                            }
263                    }
264            }
265    
266            public void unlock(String className, long key) throws SystemException {
267                    unlock(className, String.valueOf(key));
268            }
269    
270            public void unlock(String className, String key) throws SystemException {
271                    try {
272                            lockPersistence.removeByC_K(className, key);
273                    }
274                    catch (NoSuchLockException nsle) {
275                    }
276            }
277    
278            @Transactional(propagation = Propagation.REQUIRES_NEW)
279            public void unlock(
280                            String className, String key, String owner,
281                            boolean retrieveFromCache)
282                    throws SystemException {
283    
284                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
285    
286                    if (lock == null) {
287                            return;
288                    }
289    
290                    if (Validator.equals(lock.getOwner(), owner)) {
291                            lockPersistence.remove(lock);
292                            lockPersistence.flush();
293                    }
294            }
295    
296            protected void expireLock(Lock lock) throws SystemException {
297                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
298                            lock.getClassName());
299    
300                    String key = lock.getKey();
301    
302                    if (lockListener != null) {
303                            lockListener.onBeforeExpire(key);
304                    }
305    
306                    try {
307                            lockPersistence.remove(lock);
308                    }
309                    finally {
310                            if (lockListener != null) {
311                                    lockListener.onAfterExpire(key);
312                            }
313                    }
314            }
315    
316            protected Lock fetchLock(String className, String key)
317                    throws SystemException {
318    
319                    Lock lock = lockPersistence.fetchByC_K(className, key);
320    
321                    if (lock != null) {
322                            if (lock.isExpired()) {
323                                    expireLock(lock);
324    
325                                    lock = null;
326                            }
327                    }
328    
329                    return lock;
330            }
331    
332    }