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