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