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