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            @Override
042            public void clear() throws SystemException {
043                    lockPersistence.removeByLtExpirationDate(new Date());
044            }
045    
046            @Override
047            public Lock getLock(String className, long key)
048                    throws PortalException, SystemException {
049    
050                    return getLock(className, String.valueOf(key));
051            }
052    
053            @Override
054            public Lock getLock(String className, String key)
055                    throws PortalException, SystemException {
056    
057                    Lock lock = lockPersistence.findByC_K(className, key);
058    
059                    if (lock.isExpired()) {
060                            expireLock(lock);
061    
062                            throw new ExpiredLockException();
063                    }
064    
065                    return lock;
066            }
067    
068            @Override
069            public Lock getLockByUuid(String uuid)
070                    throws PortalException, SystemException {
071    
072                    List<Lock> locks = lockPersistence.findByUuid(uuid);
073    
074                    if (locks.isEmpty()) {
075                            throw new NoSuchLockException();
076                    }
077    
078                    return locks.get(0);
079            }
080    
081            @Override
082            public boolean hasLock(long userId, String className, long key)
083                    throws SystemException {
084    
085                    return hasLock(userId, className, String.valueOf(key));
086            }
087    
088            @Override
089            public boolean hasLock(long userId, String className, String key)
090                    throws SystemException {
091    
092                    Lock lock = fetchLock(className, key);
093    
094                    if ((lock != null) && (lock.getUserId() == userId)) {
095                            return true;
096                    }
097                    else {
098                            return false;
099                    }
100            }
101    
102            @Override
103            public boolean isLocked(String className, long key) throws SystemException {
104                    return isLocked(className, String.valueOf(key));
105            }
106    
107            @Override
108            public boolean isLocked(String className, String key)
109                    throws SystemException {
110    
111                    Lock lock = fetchLock(className, key);
112    
113                    if (lock == null) {
114                            return false;
115                    }
116                    else {
117                            return true;
118                    }
119            }
120    
121            @Override
122            public Lock lock(
123                            long userId, String className, long key, String owner,
124                            boolean inheritable, long expirationTime)
125                    throws PortalException, SystemException {
126    
127                    return lock(
128                            userId, className, String.valueOf(key), owner, inheritable,
129                            expirationTime);
130            }
131    
132            @Override
133            public Lock lock(
134                            long userId, String className, String key, String owner,
135                            boolean inheritable, long expirationTime)
136                    throws PortalException, SystemException {
137    
138                    Date now = new Date();
139    
140                    Lock lock = lockPersistence.fetchByC_K(className, key);
141    
142                    if (lock != null) {
143                            if (lock.isExpired()) {
144                                    expireLock(lock);
145    
146                                    lock = null;
147                            }
148                            else if (lock.getUserId() != userId) {
149                                    throw new DuplicateLockException(lock);
150                            }
151                    }
152    
153                    if (lock == null) {
154                            User user = userPersistence.findByPrimaryKey(userId);
155    
156                            long lockId = counterLocalService.increment();
157    
158                            lock = lockPersistence.create(lockId);
159    
160                            lock.setCompanyId(user.getCompanyId());
161                            lock.setUserId(user.getUserId());
162                            lock.setUserName(user.getFullName());
163                            lock.setClassName(className);
164                            lock.setKey(key);
165                            lock.setOwner(owner);
166                            lock.setInheritable(inheritable);
167                    }
168    
169                    lock.setCreateDate(now);
170    
171                    if (expirationTime == 0) {
172                            lock.setExpirationDate(null);
173                    }
174                    else {
175                            lock.setExpirationDate(new Date(now.getTime() + expirationTime));
176                    }
177    
178                    lockPersistence.update(lock, false);
179    
180                    return lock;
181            }
182    
183            @Override
184            @Transactional(propagation = Propagation.REQUIRES_NEW)
185            public Lock lock(
186                            String className, String key, String owner,
187                            boolean retrieveFromCache)
188                    throws SystemException {
189    
190                    return lock(className, key, null, owner, retrieveFromCache);
191            }
192    
193            @Override
194            @Transactional(propagation = Propagation.REQUIRES_NEW)
195            public Lock lock(
196                            String className, String key, String expectedOwner,
197                            String updatedOwner, boolean retrieveFromCache)
198                    throws SystemException {
199    
200                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
201    
202                    if (lock == null) {
203                            long lockId = counterLocalService.increment();
204    
205                            lock = lockPersistence.create(lockId);
206    
207                            lock.setCreateDate(new Date());
208                            lock.setClassName(className);
209                            lock.setKey(key);
210                            lock.setOwner(updatedOwner);
211    
212                            lockPersistence.update(lock, false);
213    
214                            lock.setNew(true);
215                    }
216                    else if (Validator.equals(lock.getOwner(), expectedOwner)) {
217                            lock.setCreateDate(new Date());
218                            lock.setClassName(className);
219                            lock.setKey(key);
220                            lock.setOwner(updatedOwner);
221    
222                            lockPersistence.update(lock, false);
223    
224                            lock.setNew(true);
225                    }
226    
227                    return lock;
228            }
229    
230            @Override
231            public Lock refresh(String uuid, long expirationTime)
232                    throws PortalException, SystemException {
233    
234                    Date now = new Date();
235    
236                    List<Lock> locks = lockPersistence.findByUuid(uuid);
237    
238                    if (locks.isEmpty()) {
239                            throw new NoSuchLockException();
240                    }
241    
242                    Lock lock = locks.get(0);
243    
244                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
245                            lock.getClassName());
246    
247                    String key = lock.getKey();
248    
249                    if (lockListener != null) {
250                            lockListener.onBeforeRefresh(key);
251                    }
252    
253                    try {
254                            lock.setCreateDate(now);
255    
256                            if (expirationTime == 0) {
257                                    lock.setExpirationDate(null);
258                            }
259                            else {
260                                    lock.setExpirationDate(
261                                            new Date(now.getTime() + expirationTime));
262                            }
263    
264                            lockPersistence.update(lock, false);
265    
266                            return lock;
267                    }
268                    finally {
269                            if (lockListener != null) {
270                                    lockListener.onAfterRefresh(key);
271                            }
272                    }
273            }
274    
275            @Override
276            public void unlock(String className, long key) throws SystemException {
277                    unlock(className, String.valueOf(key));
278            }
279    
280            @Override
281            public void unlock(String className, String key) throws SystemException {
282                    try {
283                            lockPersistence.removeByC_K(className, key);
284                    }
285                    catch (NoSuchLockException nsle) {
286                    }
287            }
288    
289            @Override
290            @Transactional(propagation = Propagation.REQUIRES_NEW)
291            public void unlock(
292                            String className, String key, String owner,
293                            boolean retrieveFromCache)
294                    throws SystemException {
295    
296                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
297    
298                    if (lock == null) {
299                            return;
300                    }
301    
302                    if (Validator.equals(lock.getOwner(), owner)) {
303                            lockPersistence.remove(lock);
304                    }
305            }
306    
307            protected void expireLock(Lock lock) throws SystemException {
308                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
309                            lock.getClassName());
310    
311                    String key = lock.getKey();
312    
313                    if (lockListener != null) {
314                            lockListener.onBeforeExpire(key);
315                    }
316    
317                    try {
318                            lockPersistence.remove(lock);
319                    }
320                    finally {
321                            if (lockListener != null) {
322                                    lockListener.onAfterExpire(key);
323                            }
324                    }
325            }
326    
327            protected Lock fetchLock(String className, String key)
328                    throws SystemException {
329    
330                    Lock lock = lockPersistence.fetchByC_K(className, key);
331    
332                    if (lock != null) {
333                            if (lock.isExpired()) {
334                                    expireLock(lock);
335    
336                                    lock = null;
337                            }
338                    }
339    
340                    return lock;
341            }
342    
343    }