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.util;
016    
017    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.Property;
020    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.search.BaseIndexer;
025    import com.liferay.portal.kernel.search.Document;
026    import com.liferay.portal.kernel.search.DocumentImpl;
027    import com.liferay.portal.kernel.search.Field;
028    import com.liferay.portal.kernel.search.SearchContext;
029    import com.liferay.portal.kernel.search.SearchEngineUtil;
030    import com.liferay.portal.kernel.search.Summary;
031    import com.liferay.portal.kernel.search.filter.BooleanFilter;
032    import com.liferay.portal.kernel.spring.osgi.OSGiBeanProperties;
033    import com.liferay.portal.kernel.util.GetterUtil;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.security.permission.PermissionChecker;
037    import com.liferay.portal.service.GroupLocalServiceUtil;
038    import com.liferay.portlet.messageboards.model.MBCategory;
039    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
040    import com.liferay.portlet.messageboards.model.MBDiscussion;
041    import com.liferay.portlet.messageboards.model.MBThread;
042    import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
043    import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
044    import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
045    
046    import java.util.Locale;
047    
048    import javax.portlet.PortletRequest;
049    import javax.portlet.PortletResponse;
050    
051    /**
052     * @author Eudaldo Alonso
053     */
054    @OSGiBeanProperties
055    public class MBThreadIndexer extends BaseIndexer {
056    
057            public static final String CLASS_NAME = MBThread.class.getName();
058    
059            public MBThreadIndexer() {
060                    setDefaultSelectedFieldNames(
061                            Field.CLASS_NAME_ID, Field.CLASS_PK, Field.COMPANY_ID,
062                            Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.UID);
063                    setFilterSearch(true);
064                    setPermissionAware(true);
065            }
066    
067            @Override
068            public String getClassName() {
069                    return CLASS_NAME;
070            }
071    
072            @Override
073            public boolean hasPermission(
074                            PermissionChecker permissionChecker, String entryClassName,
075                            long entryClassPK, String actionId)
076                    throws Exception {
077    
078                    return true;
079            }
080    
081            @Override
082            public void postProcessContextBooleanFilter(
083                            BooleanFilter contextBooleanFilter, SearchContext searchContext)
084                    throws Exception {
085    
086                    addStatus(contextBooleanFilter, searchContext);
087    
088                    boolean discussion = GetterUtil.getBoolean(
089                            searchContext.getAttribute("discussion"), false);
090    
091                    contextBooleanFilter.addRequiredTerm("discussion", discussion);
092    
093                    long endDate = GetterUtil.getLong(
094                            searchContext.getAttribute("endDate"));
095                    long startDate = GetterUtil.getLong(
096                            searchContext.getAttribute("startDate"));
097    
098                    if ((endDate > 0) && (startDate > 0)) {
099                            contextBooleanFilter.addRangeTerm(
100                                    "lastPostDate", startDate, endDate);
101                    }
102    
103                    long participantUserId = GetterUtil.getLong(
104                            searchContext.getAttribute("participantUserId"));
105    
106                    if (participantUserId > 0) {
107                            contextBooleanFilter.addRequiredTerm(
108                                    "participantUserIds", participantUserId);
109                    }
110            }
111    
112            @Override
113            protected void doDelete(Object obj) throws Exception {
114                    SearchContext searchContext = new SearchContext();
115    
116                    searchContext.setSearchEngineId(getSearchEngineId());
117    
118                    MBThread thread = (MBThread)obj;
119    
120                    Document document = new DocumentImpl();
121    
122                    document.addUID(CLASS_NAME, thread.getThreadId());
123    
124                    SearchEngineUtil.deleteDocument(
125                            getSearchEngineId(), thread.getCompanyId(), document.get(Field.UID),
126                            isCommitImmediately());
127            }
128    
129            @Override
130            protected Document doGetDocument(Object obj) throws Exception {
131                    MBThread thread = (MBThread)obj;
132    
133                    Document document = getBaseModelDocument(CLASS_NAME, thread);
134    
135                    MBDiscussion discussion =
136                            MBDiscussionLocalServiceUtil.fetchThreadDiscussion(
137                                    thread.getThreadId());
138    
139                    if (discussion == null) {
140                            document.addKeyword("discussion", false);
141                    }
142                    else {
143                            document.addKeyword("discussion", true);
144                    }
145    
146                    document.addKeyword("lastPostDate", thread.getLastPostDate().getTime());
147                    document.addKeyword(
148                            "participantUserIds", thread.getParticipantUserIds());
149    
150                    return document;
151            }
152    
153            @Override
154            protected Summary doGetSummary(
155                    Document document, Locale locale, String snippet,
156                    PortletRequest portletRequest, PortletResponse portletResponse) {
157    
158                    return null;
159            }
160    
161            @Override
162            protected void doReindex(Object obj) throws Exception {
163                    MBThread thread = (MBThread)obj;
164    
165                    Document document = getDocument(thread);
166    
167                    SearchEngineUtil.updateDocument(
168                            getSearchEngineId(), thread.getCompanyId(), document,
169                            isCommitImmediately());
170            }
171    
172            @Override
173            protected void doReindex(String className, long classPK) throws Exception {
174                    MBThread thread = MBThreadLocalServiceUtil.getThread(classPK);
175    
176                    doReindex(thread);
177            }
178    
179            @Override
180            protected void doReindex(String[] ids) throws Exception {
181                    long companyId = GetterUtil.getLong(ids[0]);
182    
183                    reindexCategories(companyId);
184                    reindexDiscussions(companyId);
185                    reindexRoot(companyId);
186            }
187    
188            protected void reindexCategories(final long companyId)
189                    throws PortalException {
190    
191                    ActionableDynamicQuery actionableDynamicQuery =
192                            MBCategoryLocalServiceUtil.getActionableDynamicQuery();
193    
194                    actionableDynamicQuery.setCompanyId(companyId);
195                    actionableDynamicQuery.setPerformActionMethod(
196                            new ActionableDynamicQuery.PerformActionMethod() {
197    
198                                    @Override
199                                    public void performAction(Object object)
200                                            throws PortalException {
201    
202                                            MBCategory category = (MBCategory)object;
203    
204                                            reindexThreads(
205                                                    companyId, category.getGroupId(),
206                                                    category.getCategoryId());
207                                    }
208    
209                            });
210    
211                    actionableDynamicQuery.performActions();
212            }
213    
214            protected void reindexDiscussions(final long companyId)
215                    throws PortalException {
216    
217                    ActionableDynamicQuery actionableDynamicQuery =
218                            GroupLocalServiceUtil.getActionableDynamicQuery();
219    
220                    actionableDynamicQuery.setCompanyId(companyId);
221                    actionableDynamicQuery.setPerformActionMethod(
222                            new ActionableDynamicQuery.PerformActionMethod() {
223    
224                                    @Override
225                                    public void performAction(Object object)
226                                            throws PortalException {
227    
228                                            Group group = (Group)object;
229    
230                                            reindexThreads(
231                                                    companyId, group.getGroupId(),
232                                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID);
233                                    }
234    
235                            });
236    
237                    actionableDynamicQuery.performActions();
238            }
239    
240            protected void reindexRoot(final long companyId) throws PortalException {
241                    ActionableDynamicQuery actionableDynamicQuery =
242                            GroupLocalServiceUtil.getActionableDynamicQuery();
243    
244                    actionableDynamicQuery.setCompanyId(companyId);
245                    actionableDynamicQuery.setPerformActionMethod(
246                            new ActionableDynamicQuery.PerformActionMethod() {
247    
248                                    @Override
249                                    public void performAction(Object object)
250                                            throws PortalException {
251    
252                                            Group group = (Group)object;
253    
254                                            reindexThreads(
255                                                    companyId, group.getGroupId(),
256                                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
257                                    }
258    
259                            });
260    
261                    actionableDynamicQuery.performActions();
262            }
263    
264            protected void reindexThreads(
265                            long companyId, long groupId, final long categoryId)
266                    throws PortalException {
267    
268                    final ActionableDynamicQuery actionableDynamicQuery =
269                            MBThreadLocalServiceUtil.getActionableDynamicQuery();
270    
271                    actionableDynamicQuery.setAddCriteriaMethod(
272                            new ActionableDynamicQuery.AddCriteriaMethod() {
273    
274                                    @Override
275                                    public void addCriteria(DynamicQuery dynamicQuery) {
276                                            Property categoryIdProperty = PropertyFactoryUtil.forName(
277                                                    "categoryId");
278    
279                                            dynamicQuery.add(categoryIdProperty.eq(categoryId));
280    
281                                            Property statusProperty = PropertyFactoryUtil.forName(
282                                                    "status");
283    
284                                            dynamicQuery.add(
285                                                    statusProperty.eq(WorkflowConstants.STATUS_APPROVED));
286                                    }
287    
288                            });
289                    actionableDynamicQuery.setCompanyId(companyId);
290                    actionableDynamicQuery.setGroupId(groupId);
291                    actionableDynamicQuery.setPerformActionMethod(
292                            new ActionableDynamicQuery.PerformActionMethod() {
293    
294                                    @Override
295                                    public void performAction(Object object) {
296                                            MBThread thread = (MBThread)object;
297    
298                                            try {
299                                                    Document document = getDocument(thread);
300    
301                                                    actionableDynamicQuery.addDocument(document);
302                                            }
303                                            catch (PortalException pe) {
304                                                    if (_log.isWarnEnabled()) {
305                                                            _log.warn(
306                                                                    "Unable to index message boards thread " +
307                                                                            thread.getThreadId(),
308                                                                    pe);
309                                                    }
310                                            }
311                                    }
312    
313                            });
314                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
315    
316                    actionableDynamicQuery.performActions();
317            }
318    
319            private static final Log _log = LogFactoryUtil.getLog(
320                    MBThreadIndexer.class);
321    
322    }