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 getLockByUuidAndCompanyId(String uuid, long companyId)
070                    throws PortalException, SystemException {
071    
072                    List<Lock> locks = lockPersistence.findByUuid_C(uuid, companyId);
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);
179    
180                    return lock;
181            }
182    
183            @Override
184            @Transactional(propagation = Propagation.REQUIRES_NEW)
185            public Lock lock(String className, String key, String owner)
186                    throws SystemException {
187    
188                    return lock(className, key, null, owner);
189            }
190    
191            /**
192             * @deprecated As of 6.2.0, replaced by {@link #lock(String, String,
193             *             String)}
194             */
195            @Override
196            @Transactional(propagation = Propagation.REQUIRES_NEW)
197            public Lock lock(
198                            String className, String key, String owner,
199                            boolean retrieveFromCache)
200                    throws SystemException {
201    
202                    return lock(className, key, null, owner);
203            }
204    
205            @Override
206            @Transactional(propagation = Propagation.REQUIRES_NEW)
207            public Lock lock(
208                            String className, String key, String expectedOwner,
209                            String updatedOwner)
210                    throws SystemException {
211    
212                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
213    
214                    if (lock == null) {
215                            long lockId = counterLocalService.increment();
216    
217                            lock = lockPersistence.create(lockId);
218    
219                            lock.setCreateDate(new Date());
220                            lock.setClassName(className);
221                            lock.setKey(key);
222                            lock.setOwner(updatedOwner);
223    
224                            lockPersistence.update(lock);
225    
226                            lock.setNew(true);
227    
228                            lockPersistence.flush();
229                    }
230                    else if (Validator.equals(lock.getOwner(), expectedOwner)) {
231                            lock.setCreateDate(new Date());
232                            lock.setClassName(className);
233                            lock.setKey(key);
234                            lock.setOwner(updatedOwner);
235    
236                            lockPersistence.update(lock);
237    
238                            lock.setNew(true);
239    
240                            lockPersistence.flush();
241                    }
242    
243                    return lock;
244            }
245    
246            /**
247             * @deprecated As of 6.2.0, replaced by {@link #lock(String, String, String,
248             *             String)}
249             */
250            @Override
251            @Transactional(propagation = Propagation.REQUIRES_NEW)
252            public Lock lock(
253                            String className, String key, String expectedOwner,
254                            String updatedOwner, boolean retrieveFromCache)
255                    throws SystemException {
256    
257                    return lock(className, key, expectedOwner, updatedOwner);
258            }
259    
260            @Override
261            public Lock refresh(String uuid, long companyId, long expirationTime)
262                    throws PortalException, SystemException {
263    
264                    Date now = new Date();
265    
266                    List<Lock> locks = lockPersistence.findByUuid_C(uuid, companyId);
267    
268                    if (locks.isEmpty()) {
269                            throw new NoSuchLockException();
270                    }
271    
272                    Lock lock = locks.get(0);
273    
274                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
275                            lock.getClassName());
276    
277                    String key = lock.getKey();
278    
279                    if (lockListener != null) {
280                            lockListener.onBeforeRefresh(key);
281                    }
282    
283                    try {
284                            lock.setCreateDate(now);
285    
286                            if (expirationTime == 0) {
287                                    lock.setExpirationDate(null);
288                            }
289                            else {
290                                    lock.setExpirationDate(
291                                            new Date(now.getTime() + expirationTime));
292                            }
293    
294                            lockPersistence.update(lock);
295    
296                            return lock;
297                    }
298                    finally {
299                            if (lockListener != null) {
300                                    lockListener.onAfterRefresh(key);
301                            }
302                    }
303            }
304    
305            @Override
306            public void unlock(String className, long key) throws SystemException {
307                    unlock(className, String.valueOf(key));
308            }
309    
310            @Override
311            public void unlock(String className, String key) throws SystemException {
312                    try {
313                            lockPersistence.removeByC_K(className, key);
314                    }
315                    catch (NoSuchLockException nsle) {
316                    }
317            }
318    
319            @Override
320            @Transactional(propagation = Propagation.REQUIRES_NEW)
321            public void unlock(String className, String key, String owner)
322                    throws SystemException {
323    
324                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
325    
326                    if (lock == null) {
327                            return;
328                    }
329    
330                    if (Validator.equals(lock.getOwner(), owner)) {
331                            lockPersistence.remove(lock);
332                            lockPersistence.flush();
333                    }
334            }
335    
336            /**
337             * @deprecated As of 6.2.0, replaced by {@link #unlock(String, String,
338             *             String)}
339             */
340            @Override
341            @Transactional(propagation = Propagation.REQUIRES_NEW)
342            public void unlock(
343                            String className, String key, String owner,
344                            boolean retrieveFromCache)
345                    throws SystemException {
346    
347                    unlock(className, key, owner);
348            }
349    
350            protected void expireLock(Lock lock) throws SystemException {
351                    LockListener lockListener = LockListenerRegistryUtil.getLockListener(
352                            lock.getClassName());
353    
354                    String key = lock.getKey();
355    
356                    if (lockListener != null) {
357                            lockListener.onBeforeExpire(key);
358                    }
359    
360                    try {
361                            lockPersistence.remove(lock);
362                    }
363                    finally {
364                            if (lockListener != null) {
365                                    lockListener.onAfterExpire(key);
366                            }
367                    }
368            }
369    
370            protected Lock fetchLock(String className, String key)
371                    throws SystemException {
372    
373                    Lock lock = lockPersistence.fetchByC_K(className, key);
374    
375                    if (lock != null) {
376                            if (lock.isExpired()) {
377                                    expireLock(lock);
378    
379                                    lock = null;
380                            }
381                    }
382    
383                    return lock;
384            }
385    
386    }