001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.search.BaseIndexer;
026    import com.liferay.portal.kernel.search.BooleanQuery;
027    import com.liferay.portal.kernel.search.Document;
028    import com.liferay.portal.kernel.search.DocumentImpl;
029    import com.liferay.portal.kernel.search.Field;
030    import com.liferay.portal.kernel.search.SearchContext;
031    import com.liferay.portal.kernel.search.SearchEngineUtil;
032    import com.liferay.portal.kernel.search.Summary;
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.persistence.GroupActionableDynamicQuery;
038    import com.liferay.portal.util.PortletKeys;
039    import com.liferay.portlet.messageboards.NoSuchDiscussionException;
040    import com.liferay.portlet.messageboards.model.MBCategory;
041    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
042    import com.liferay.portlet.messageboards.model.MBThread;
043    import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
044    import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
045    import com.liferay.portlet.messageboards.service.persistence.MBCategoryActionableDynamicQuery;
046    import com.liferay.portlet.messageboards.service.persistence.MBThreadActionableDynamicQuery;
047    
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                    ActionableDynamicQuery actionableDynamicQuery =
270                            new MBThreadActionableDynamicQuery() {
271    
272                            @Override
273                            protected void addCriteria(DynamicQuery dynamicQuery) {
274                                    Property categoryIdProperty = PropertyFactoryUtil.forName(
275                                            "categoryId");
276    
277                                    dynamicQuery.add(categoryIdProperty.eq(categoryId));
278    
279                                    Property statusProperty = PropertyFactoryUtil.forName("status");
280    
281                                    dynamicQuery.add(
282                                            statusProperty.eq(WorkflowConstants.STATUS_APPROVED));
283                            }
284    
285                            @Override
286                            protected void performAction(Object object) {
287                                    MBThread thread = (MBThread)object;
288    
289                                    try {
290                                            Document document = getDocument(thread);
291    
292                                            addDocument(document);
293                                    }
294                                    catch (PortalException pe) {
295                                            if (_log.isWarnEnabled()) {
296                                                    _log.warn(
297                                                            "Unable to index message boards thread " +
298                                                                    thread.getThreadId(),
299                                                            pe);
300                                            }
301                                    }
302                            }
303    
304                    };
305    
306                    actionableDynamicQuery.setCompanyId(companyId);
307                    actionableDynamicQuery.setGroupId(groupId);
308                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
309    
310                    actionableDynamicQuery.performActions();
311            }
312    
313            private static Log _log = LogFactoryUtil.getLog(MBThreadIndexer.class);
314    
315    }