001    /**
002     * Copyright (c) 2000-2012 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.transaction.Propagation;
024    import com.liferay.portal.kernel.transaction.Transactional;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.Lock;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.service.base.LockLocalServiceBaseImpl;
029    
030    import java.util.Date;
031    import java.util.List;
032    
033    /**
034     * @author Brian Wing Shun Chan
035     * @author Shuyang Zhou
036     */
037    public class LockLocalServiceImpl extends LockLocalServiceBaseImpl {
038    
039            public void clear() throws SystemException {
040                    lockPersistence.removeByLtExpirationDate(new Date());
041            }
042    
043            public Lock getLock(String className, long key)
044                    throws PortalException, SystemException {
045    
046                    return getLock(className, String.valueOf(key));
047            }
048    
049            public Lock getLock(String className, String key)
050                    throws PortalException, SystemException {
051    
052                    Lock lock = lockPersistence.findByC_K(className, key);
053    
054                    if (lock.isExpired()) {
055                            lockPersistence.remove(lock);
056    
057                            throw new ExpiredLockException();
058                    }
059    
060                    return lock;
061            }
062    
063            public Lock getLockByUuid(String uuid)
064                    throws PortalException, SystemException {
065    
066                    List<Lock> locks = lockPersistence.findByUuid(uuid);
067    
068                    if (locks.isEmpty()) {
069                            throw new NoSuchLockException();
070                    }
071    
072                    return locks.get(0);
073            }
074    
075            public boolean hasLock(long userId, String className, long key)
076                    throws SystemException {
077    
078                    return hasLock(userId, className, String.valueOf(key));
079            }
080    
081            public boolean hasLock(long userId, String className, String key)
082                    throws SystemException {
083    
084                    Lock lock = fetchLock(className, key);
085    
086                    if ((lock != null) && (lock.getUserId() == userId)) {
087                            return true;
088                    }
089                    else {
090                            return false;
091                    }
092            }
093    
094            public boolean isLocked(String className, long key)
095                    throws SystemException {
096    
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                                    lockPersistence.remove(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, false);
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, false);
201    
202                            lock.setNew(true);
203                    }
204                    else if (Validator.equals(lock.getOwner(), expectedOwner)) {
205                            lock.setCreateDate(new Date());
206                            lock.setClassName(className);
207                            lock.setKey(key);
208                            lock.setOwner(updatedOwner);
209    
210                            lockPersistence.update(lock, false);
211    
212                            lock.setNew(true);
213                    }
214    
215                    return lock;
216            }
217    
218            public Lock refresh(String uuid, long expirationTime)
219                    throws PortalException, SystemException {
220    
221                    Date now = new Date();
222    
223                    List<Lock> locks = lockPersistence.findByUuid(uuid);
224    
225                    if (locks.isEmpty()) {
226                            throw new NoSuchLockException();
227                    }
228    
229                    Lock lock = locks.get(0);
230    
231                    lock.setCreateDate(now);
232    
233                    if (expirationTime == 0) {
234                            lock.setExpirationDate(null);
235                    }
236                    else {
237                            lock.setExpirationDate(new Date(now.getTime() + expirationTime));
238                    }
239    
240                    lockPersistence.update(lock, false);
241    
242                    return lock;
243            }
244    
245            public void unlock(String className, long key) throws SystemException {
246                    unlock(className, String.valueOf(key));
247            }
248    
249            public void unlock(String className, String key) throws SystemException {
250                    try {
251                            lockPersistence.removeByC_K(className, key);
252                    }
253                    catch (NoSuchLockException nsle) {
254                    }
255            }
256    
257            @Transactional(propagation = Propagation.REQUIRES_NEW)
258            public void unlock(
259                            String className, String key, String owner,
260                            boolean retrieveFromCache)
261                    throws SystemException {
262    
263                    Lock lock = lockFinder.fetchByC_K(className, key, LockMode.UPGRADE);
264    
265                    if (lock == null) {
266                            return;
267                    }
268    
269                    if (Validator.equals(lock.getOwner(), owner)) {
270                            deleteLock(lock);
271                    }
272            }
273    
274            protected Lock fetchLock(String className, String key)
275                    throws SystemException {
276    
277                    Lock lock = lockPersistence.fetchByC_K(className, key);
278    
279                    if (lock != null) {
280                            if (lock.isExpired()) {
281                                    lockPersistence.remove(lock);
282    
283                                    lock = null;
284                            }
285                    }
286    
287                    return lock;
288            }
289    
290    }