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<MBThread> {
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(MBThread mbThread) throws Exception {
114                    SearchContext searchContext = new SearchContext();
115    
116                    searchContext.setSearchEngineId(getSearchEngineId());
117    
118                    Document document = new DocumentImpl();
119    
120                    document.addUID(CLASS_NAME, mbThread.getThreadId());
121    
122                    SearchEngineUtil.deleteDocument(
123                            getSearchEngineId(), mbThread.getCompanyId(),
124                            document.get(Field.UID), isCommitImmediately());
125            }
126    
127            @Override
128            protected Document doGetDocument(MBThread mbThread) throws Exception {
129                    Document document = getBaseModelDocument(CLASS_NAME, mbThread);
130    
131                    MBDiscussion discussion =
132                            MBDiscussionLocalServiceUtil.fetchThreadDiscussion(
133                                    mbThread.getThreadId());
134    
135                    if (discussion == null) {
136                            document.addKeyword("discussion", false);
137                    }
138                    else {
139                            document.addKeyword("discussion", true);
140                    }
141    
142                    document.addKeyword(
143                            "lastPostDate", mbThread.getLastPostDate().getTime());
144                    document.addKeyword(
145                            "participantUserIds", mbThread.getParticipantUserIds());
146    
147                    return document;
148            }
149    
150            @Override
151            protected Summary doGetSummary(
152                    Document document, Locale locale, String snippet,
153                    PortletRequest portletRequest, PortletResponse portletResponse) {
154    
155                    return null;
156            }
157    
158            @Override
159            protected void doReindex(MBThread mbThread) throws Exception {
160                    Document document = getDocument(mbThread);
161    
162                    SearchEngineUtil.updateDocument(
163                            getSearchEngineId(), mbThread.getCompanyId(), document,
164                            isCommitImmediately());
165            }
166    
167            @Override
168            protected void doReindex(String className, long classPK) throws Exception {
169                    MBThread thread = MBThreadLocalServiceUtil.getThread(classPK);
170    
171                    doReindex(thread);
172            }
173    
174            @Override
175            protected void doReindex(String[] ids) throws Exception {
176                    long companyId = GetterUtil.getLong(ids[0]);
177    
178                    reindexCategories(companyId);
179                    reindexDiscussions(companyId);
180                    reindexRoot(companyId);
181            }
182    
183            protected void reindexCategories(final long companyId)
184                    throws PortalException {
185    
186                    ActionableDynamicQuery actionableDynamicQuery =
187                            MBCategoryLocalServiceUtil.getActionableDynamicQuery();
188    
189                    actionableDynamicQuery.setCompanyId(companyId);
190                    actionableDynamicQuery.setPerformActionMethod(
191                            new ActionableDynamicQuery.PerformActionMethod<MBCategory>() {
192    
193                                    @Override
194                                    public void performAction(MBCategory category)
195                                            throws PortalException {
196    
197                                            reindexThreads(
198                                                    companyId, category.getGroupId(),
199                                                    category.getCategoryId());
200                                    }
201    
202                            });
203    
204                    actionableDynamicQuery.performActions();
205            }
206    
207            protected void reindexDiscussions(final long companyId)
208                    throws PortalException {
209    
210                    ActionableDynamicQuery actionableDynamicQuery =
211                            GroupLocalServiceUtil.getActionableDynamicQuery();
212    
213                    actionableDynamicQuery.setCompanyId(companyId);
214                    actionableDynamicQuery.setPerformActionMethod(
215                            new ActionableDynamicQuery.PerformActionMethod<Group>() {
216    
217                                    @Override
218                                    public void performAction(Group group) throws PortalException {
219                                            reindexThreads(
220                                                    companyId, group.getGroupId(),
221                                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID);
222                                    }
223    
224                            });
225    
226                    actionableDynamicQuery.performActions();
227            }
228    
229            protected void reindexRoot(final long companyId) throws PortalException {
230                    ActionableDynamicQuery actionableDynamicQuery =
231                            GroupLocalServiceUtil.getActionableDynamicQuery();
232    
233                    actionableDynamicQuery.setCompanyId(companyId);
234                    actionableDynamicQuery.setPerformActionMethod(
235                            new ActionableDynamicQuery.PerformActionMethod<Group>() {
236    
237                                    @Override
238                                    public void performAction(Group group) throws PortalException {
239                                            reindexThreads(
240                                                    companyId, group.getGroupId(),
241                                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
242                                    }
243    
244                            });
245    
246                    actionableDynamicQuery.performActions();
247            }
248    
249            protected void reindexThreads(
250                            long companyId, long groupId, final long categoryId)
251                    throws PortalException {
252    
253                    final ActionableDynamicQuery actionableDynamicQuery =
254                            MBThreadLocalServiceUtil.getActionableDynamicQuery();
255    
256                    actionableDynamicQuery.setAddCriteriaMethod(
257                            new ActionableDynamicQuery.AddCriteriaMethod() {
258    
259                                    @Override
260                                    public void addCriteria(DynamicQuery dynamicQuery) {
261                                            Property categoryIdProperty = PropertyFactoryUtil.forName(
262                                                    "categoryId");
263    
264                                            dynamicQuery.add(categoryIdProperty.eq(categoryId));
265    
266                                            Property statusProperty = PropertyFactoryUtil.forName(
267                                                    "status");
268    
269                                            dynamicQuery.add(
270                                                    statusProperty.eq(WorkflowConstants.STATUS_APPROVED));
271                                    }
272    
273                            });
274                    actionableDynamicQuery.setCompanyId(companyId);
275                    actionableDynamicQuery.setGroupId(groupId);
276                    actionableDynamicQuery.setPerformActionMethod(
277                            new ActionableDynamicQuery.PerformActionMethod<MBThread>() {
278    
279                                    @Override
280                                    public void performAction(MBThread thread) {
281                                            try {
282                                                    Document document = getDocument(thread);
283    
284                                                    actionableDynamicQuery.addDocument(document);
285                                            }
286                                            catch (PortalException pe) {
287                                                    if (_log.isWarnEnabled()) {
288                                                            _log.warn(
289                                                                    "Unable to index message boards thread " +
290                                                                            thread.getThreadId(),
291                                                                    pe);
292                                                    }
293                                            }
294                                    }
295    
296                            });
297                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
298    
299                    actionableDynamicQuery.performActions();
300            }
301    
302            private static final Log _log = LogFactoryUtil.getLog(
303                    MBThreadIndexer.class);
304    
305    }