001    /**
002     * Copyright (c) 2000-present 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.portlet.messageboards.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryDefinition;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.lock.Lock;
020    import com.liferay.portal.kernel.lock.LockManagerUtil;
021    import com.liferay.portal.kernel.search.Hits;
022    import com.liferay.portal.kernel.workflow.WorkflowConstants;
023    import com.liferay.portal.security.permission.ActionKeys;
024    import com.liferay.portal.security.permission.InlineSQLHelperUtil;
025    import com.liferay.portal.service.ServiceContext;
026    import com.liferay.portlet.messageboards.LockedThreadException;
027    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
028    import com.liferay.portlet.messageboards.model.MBMessage;
029    import com.liferay.portlet.messageboards.model.MBThread;
030    import com.liferay.portlet.messageboards.model.impl.MBThreadModelImpl;
031    import com.liferay.portlet.messageboards.service.base.MBThreadServiceBaseImpl;
032    import com.liferay.portlet.messageboards.service.permission.MBCategoryPermission;
033    import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
034    
035    import java.util.ArrayList;
036    import java.util.Collections;
037    import java.util.Date;
038    import java.util.List;
039    
040    /**
041     * @author Jorge Ferrer
042     * @author Deepak Gothe
043     * @author Mika Koivisto
044     * @author Shuyang Zhou
045     */
046    public class MBThreadServiceImpl extends MBThreadServiceBaseImpl {
047    
048            @Override
049            public void deleteThread(long threadId) throws PortalException {
050                    if (LockManagerUtil.isLocked(MBThread.class.getName(), threadId)) {
051                            throw new LockedThreadException();
052                    }
053    
054                    List<MBMessage> messages = mbMessagePersistence.findByThreadId(
055                            threadId);
056    
057                    for (MBMessage message : messages) {
058                            MBMessagePermission.check(
059                                    getPermissionChecker(), message.getMessageId(),
060                                    ActionKeys.DELETE);
061                    }
062    
063                    mbThreadLocalService.deleteThread(threadId);
064            }
065    
066            @Override
067            public List<MBThread> getGroupThreads(
068                            long groupId, long userId, Date modifiedDate, int status, int start,
069                            int end)
070                    throws PortalException {
071    
072                    if (!InlineSQLHelperUtil.isEnabled(groupId)) {
073                            QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
074                                    status, start, end, null);
075    
076                            return mbThreadFinder.findByG_U_LPD(
077                                    groupId, userId, modifiedDate, queryDefinition);
078                    }
079    
080                    long[] categoryIds = mbCategoryService.getCategoryIds(
081                            groupId, MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
082    
083                    if (categoryIds.length == 0) {
084                            return Collections.emptyList();
085                    }
086    
087                    List<Long> threadIds = mbMessageFinder.filterFindByG_U_MD_C_S(
088                            groupId, userId, modifiedDate, categoryIds, status, start, end);
089    
090                    List<MBThread> threads = new ArrayList<>(threadIds.size());
091    
092                    for (long threadId : threadIds) {
093                            MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
094    
095                            threads.add(thread);
096                    }
097    
098                    return threads;
099            }
100    
101            @Override
102            public List<MBThread> getGroupThreads(
103                            long groupId, long userId, int status, boolean subscribed,
104                            boolean includeAnonymous, int start, int end)
105                    throws PortalException {
106    
107                    if (!InlineSQLHelperUtil.isEnabled(groupId)) {
108                            return doGetGroupThreads(
109                                    groupId, userId, status, subscribed, includeAnonymous, start,
110                                    end);
111                    }
112    
113                    long[] categoryIds = mbCategoryService.getCategoryIds(
114                            groupId, MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
115    
116                    if (categoryIds.length == 0) {
117                            return Collections.emptyList();
118                    }
119    
120                    List<Long> threadIds = null;
121    
122                    if (userId <= 0) {
123                            threadIds = mbMessageFinder.filterFindByG_U_C_S(
124                                    groupId, 0, categoryIds, status, start, end);
125                    }
126                    else {
127                            if (subscribed) {
128                                    QueryDefinition<MBThread> queryDefinition =
129                                            new QueryDefinition<>(status, start, end, null);
130    
131                                    return mbThreadFinder.filterFindByS_G_U_C(
132                                            groupId, userId, categoryIds, queryDefinition);
133                            }
134                            else {
135                                    if (includeAnonymous) {
136                                            threadIds = mbMessageFinder.filterFindByG_U_C_S(
137                                                    groupId, userId, categoryIds, status, start, end);
138                                    }
139                                    else {
140                                            threadIds = mbMessageFinder.filterFindByG_U_C_A_S(
141                                                    groupId, userId, categoryIds, false, status, start,
142                                                    end);
143                                    }
144                            }
145                    }
146    
147                    List<MBThread> threads = new ArrayList<>(threadIds.size());
148    
149                    for (long threadId : threadIds) {
150                            MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
151    
152                            threads.add(thread);
153                    }
154    
155                    return threads;
156            }
157    
158            @Override
159            public List<MBThread> getGroupThreads(
160                            long groupId, long userId, int status, boolean subscribed,
161                            int start, int end)
162                    throws PortalException {
163    
164                    return getGroupThreads(
165                            groupId, userId, status, subscribed, true, start, end);
166            }
167    
168            @Override
169            public List<MBThread> getGroupThreads(
170                            long groupId, long userId, int status, int start, int end)
171                    throws PortalException {
172    
173                    return getGroupThreads(groupId, userId, status, false, start, end);
174            }
175    
176            @Override
177            public int getGroupThreadsCount(
178                    long groupId, long userId, Date modifiedDate, int status) {
179    
180                    if (!InlineSQLHelperUtil.isEnabled(groupId)) {
181                            QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
182                                    status);
183    
184                            return mbThreadFinder.countByG_U_LPD(
185                                    groupId, userId, modifiedDate, queryDefinition);
186                    }
187    
188                    long[] categoryIds = mbCategoryService.getCategoryIds(
189                            groupId, MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
190    
191                    if (categoryIds.length == 0) {
192                            return 0;
193                    }
194    
195                    return mbMessageFinder.filterCountByG_U_MD_C_S(
196                            groupId, userId, modifiedDate, categoryIds, status);
197            }
198    
199            @Override
200            public int getGroupThreadsCount(long groupId, long userId, int status) {
201                    return getGroupThreadsCount(groupId, userId, status, false);
202            }
203    
204            @Override
205            public int getGroupThreadsCount(
206                    long groupId, long userId, int status, boolean subscribed) {
207    
208                    return getGroupThreadsCount(groupId, userId, status, subscribed, true);
209            }
210    
211            @Override
212            public int getGroupThreadsCount(
213                    long groupId, long userId, int status, boolean subscribed,
214                    boolean includeAnonymous) {
215    
216                    if (!InlineSQLHelperUtil.isEnabled(groupId)) {
217                            return doGetGroupThreadsCount(
218                                    groupId, userId, status, subscribed, includeAnonymous);
219                    }
220    
221                    long[] categoryIds = mbCategoryService.getCategoryIds(
222                            groupId, MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
223    
224                    if (categoryIds.length == 0) {
225                            return 0;
226                    }
227    
228                    if (userId <= 0) {
229                            return mbMessageFinder.filterCountByG_U_C_S(
230                                    groupId, 0, categoryIds, status);
231                    }
232                    else {
233                            if (subscribed) {
234                                    QueryDefinition<MBThread> queryDefinition =
235                                            new QueryDefinition<>(status);
236    
237                                    return mbThreadFinder.filterCountByS_G_U_C(
238                                            groupId, userId, categoryIds, queryDefinition);
239                            }
240                            else {
241                                    if (includeAnonymous) {
242                                            return mbMessageFinder.filterCountByG_U_C_S(
243                                                    groupId, userId, categoryIds, status);
244                                    }
245                                    else {
246                                            return mbMessageFinder.filterCountByG_U_C_A_S(
247                                                    groupId, userId, categoryIds, false, status);
248                                    }
249                            }
250                    }
251            }
252    
253            @Override
254            public List<MBThread> getThreads(
255                    long groupId, long categoryId, int status, int start, int end) {
256    
257                    QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
258                            status, start, end, null);
259    
260                    return mbThreadFinder.filterFindByG_C(
261                            groupId, categoryId, queryDefinition);
262            }
263    
264            @Override
265            public int getThreadsCount(long groupId, long categoryId, int status) {
266                    if (status == WorkflowConstants.STATUS_ANY) {
267                            return mbThreadFinder.filterCountByG_C(groupId, categoryId);
268                    }
269                    else {
270                            QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
271                                    status);
272    
273                            return mbThreadFinder.filterCountByG_C(
274                                    groupId, categoryId, queryDefinition);
275                    }
276            }
277    
278            @Override
279            public Lock lockThread(long threadId) throws PortalException {
280                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
281    
282                    MBCategoryPermission.check(
283                            getPermissionChecker(), thread.getGroupId(), thread.getCategoryId(),
284                            ActionKeys.LOCK_THREAD);
285    
286                    return LockManagerUtil.lock(
287                            getUserId(), MBThread.class.getName(), threadId,
288                            String.valueOf(threadId), false,
289                            MBThreadModelImpl.LOCK_EXPIRATION_TIME);
290            }
291    
292            @Override
293            public MBThread moveThread(long categoryId, long threadId)
294                    throws PortalException {
295    
296                    if (LockManagerUtil.isLocked(MBThread.class.getName(), threadId)) {
297                            throw new LockedThreadException();
298                    }
299    
300                    MBThread thread = mbThreadLocalService.getThread(threadId);
301    
302                    MBCategoryPermission.check(
303                            getPermissionChecker(), thread.getGroupId(), thread.getCategoryId(),
304                            ActionKeys.MOVE_THREAD);
305    
306                    MBCategoryPermission.check(
307                            getPermissionChecker(), thread.getGroupId(), categoryId,
308                            ActionKeys.MOVE_THREAD);
309    
310                    return mbThreadLocalService.moveThread(
311                            thread.getGroupId(), categoryId, threadId);
312            }
313    
314            @Override
315            public MBThread moveThreadFromTrash(long categoryId, long threadId)
316                    throws PortalException {
317    
318                    MBThread thread = mbThreadLocalService.getThread(threadId);
319    
320                    MBCategoryPermission.check(
321                            getPermissionChecker(), thread.getGroupId(), thread.getCategoryId(),
322                            ActionKeys.UPDATE);
323    
324                    return mbThreadLocalService.moveThreadFromTrash(
325                            getUserId(), categoryId, threadId);
326            }
327    
328            @Override
329            public MBThread moveThreadToTrash(long threadId) throws PortalException {
330                    if (LockManagerUtil.isLocked(MBThread.class.getName(), threadId)) {
331                            throw new LockedThreadException();
332                    }
333    
334                    List<MBMessage> messages = mbMessagePersistence.findByThreadId(
335                            threadId);
336    
337                    for (MBMessage message : messages) {
338                            MBMessagePermission.check(
339                                    getPermissionChecker(), message.getMessageId(),
340                                    ActionKeys.DELETE);
341                    }
342    
343                    return mbThreadLocalService.moveThreadToTrash(getUserId(), threadId);
344            }
345    
346            @Override
347            public void restoreThreadFromTrash(long threadId) throws PortalException {
348                    List<MBMessage> messages = mbMessagePersistence.findByThreadId(
349                            threadId);
350    
351                    for (MBMessage message : messages) {
352                            MBMessagePermission.check(
353                                    getPermissionChecker(), message.getMessageId(),
354                                    ActionKeys.DELETE);
355                    }
356    
357                    mbThreadLocalService.restoreThreadFromTrash(getUserId(), threadId);
358            }
359    
360            @Override
361            public Hits search(
362                            long groupId, long creatorUserId, int status, int start, int end)
363                    throws PortalException {
364    
365                    return mbThreadLocalService.search(
366                            groupId, getUserId(), creatorUserId, status, start, end);
367            }
368    
369            @Override
370            public Hits search(
371                            long groupId, long creatorUserId, long startDate, long endDate,
372                            int status, int start, int end)
373                    throws PortalException {
374    
375                    return mbThreadLocalService.search(
376                            groupId, getUserId(), creatorUserId, startDate, endDate, status,
377                            start, end);
378            }
379    
380            @Override
381            public MBThread splitThread(
382                            long messageId, String subject, ServiceContext serviceContext)
383                    throws PortalException {
384    
385                    MBMessage message = mbMessageLocalService.getMessage(messageId);
386    
387                    MBCategoryPermission.check(
388                            getPermissionChecker(), message.getGroupId(),
389                            message.getCategoryId(), ActionKeys.MOVE_THREAD);
390    
391                    return mbThreadLocalService.splitThread(
392                            messageId, subject, serviceContext);
393            }
394    
395            @Override
396            public void unlockThread(long threadId) throws PortalException {
397                    MBThread thread = mbThreadLocalService.getThread(threadId);
398    
399                    MBCategoryPermission.check(
400                            getPermissionChecker(), thread.getGroupId(), thread.getCategoryId(),
401                            ActionKeys.LOCK_THREAD);
402    
403                    LockManagerUtil.unlock(MBThread.class.getName(), threadId);
404            }
405    
406            protected List<MBThread> doGetGroupThreads(
407                    long groupId, long userId, int status, boolean subscribed,
408                    boolean includeAnonymous, int start, int end) {
409    
410                    if (userId <= 0) {
411                            if (status == WorkflowConstants.STATUS_ANY) {
412                                    return mbThreadPersistence.findByGroupId(groupId, start, end);
413                            }
414                            else {
415                                    return mbThreadPersistence.findByG_S(
416                                            groupId, status, start, end);
417                            }
418                    }
419    
420                    QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
421                            status, start, end, null);
422    
423                    if (subscribed) {
424                            return mbThreadFinder.findByS_G_U(groupId, userId, queryDefinition);
425                    }
426                    else if (includeAnonymous) {
427                            return mbThreadFinder.findByG_U(groupId, userId, queryDefinition);
428                    }
429                    else {
430                            return mbThreadFinder.findByG_U_A(
431                                    groupId, userId, false, queryDefinition);
432                    }
433            }
434    
435            protected int doGetGroupThreadsCount(
436                    long groupId, long userId, int status, boolean subscribed,
437                    boolean includeAnonymous) {
438    
439                    if (userId <= 0) {
440                            if (status == WorkflowConstants.STATUS_ANY) {
441                                    return mbThreadPersistence.countByGroupId(groupId);
442                            }
443                            else {
444                                    return mbThreadPersistence.countByG_S(groupId, status);
445                            }
446                    }
447    
448                    QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
449                            status);
450    
451                    if (subscribed) {
452                            return mbThreadFinder.countByS_G_U(
453                                    groupId, userId, queryDefinition);
454                    }
455                    else if (includeAnonymous) {
456                            return mbThreadFinder.countByG_U(groupId, userId, queryDefinition);
457                    }
458                    else {
459                            return mbThreadFinder.countByG_U_A(
460                                    groupId, userId, false, queryDefinition);
461                    }
462            }
463    
464    }