001
014
015 package com.liferay.portlet.messageboards.util;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.search.BaseIndexer;
021 import com.liferay.portal.kernel.search.BooleanQuery;
022 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
023 import com.liferay.portal.kernel.search.Document;
024 import com.liferay.portal.kernel.search.DocumentImpl;
025 import com.liferay.portal.kernel.search.Field;
026 import com.liferay.portal.kernel.search.Hits;
027 import com.liferay.portal.kernel.search.Indexer;
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.util.HtmlUtil;
033 import com.liferay.portal.kernel.util.StringUtil;
034 import com.liferay.portal.kernel.util.Validator;
035 import com.liferay.portal.kernel.workflow.WorkflowConstants;
036 import com.liferay.portal.model.Group;
037 import com.liferay.portal.security.permission.ActionKeys;
038 import com.liferay.portal.security.permission.PermissionChecker;
039 import com.liferay.portal.service.GroupLocalServiceUtil;
040 import com.liferay.portal.util.PortalUtil;
041 import com.liferay.portal.util.PortletKeys;
042 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
043 import com.liferay.portlet.expando.model.ExpandoBridge;
044 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
045 import com.liferay.portlet.messageboards.model.MBCategory;
046 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
047 import com.liferay.portlet.messageboards.model.MBMessage;
048 import com.liferay.portlet.messageboards.model.MBThread;
049 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
050 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
051 import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
052
053 import java.util.ArrayList;
054 import java.util.Collection;
055 import java.util.Date;
056 import java.util.List;
057
058 import javax.portlet.PortletURL;
059
060
066 public class MBIndexer extends BaseIndexer {
067
068 public static final String[] CLASS_NAMES = {MBMessage.class.getName()};
069
070 public static final String PORTLET_ID = PortletKeys.MESSAGE_BOARDS;
071
072 public String[] getClassNames() {
073 return CLASS_NAMES;
074 }
075
076 public Summary getSummary(
077 Document document, String snippet, PortletURL portletURL) {
078
079 String title = document.get(Field.TITLE);
080
081 String content = snippet;
082
083 if (Validator.isNull(snippet)) {
084 content = StringUtil.shorten(document.get(Field.CONTENT), 200);
085 }
086
087 String messageId = document.get(Field.ENTRY_CLASS_PK);
088
089 portletURL.setParameter(
090 "struts_action", "/message_boards/view_message");
091 portletURL.setParameter("messageId", messageId);
092
093 return new Summary(title, content, portletURL);
094 }
095
096 protected void doDelete(Object obj) throws Exception {
097 if (obj instanceof MBCategory) {
098 MBCategory category = (MBCategory)obj;
099
100 BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
101
102 booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
103
104 booleanQuery.addRequiredTerm(
105 "categoryId", category.getCategoryId());
106
107 Hits hits = SearchEngineUtil.search(
108 category.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
109 QueryUtil.ALL_POS);
110
111 for (int i = 0; i < hits.getLength(); i++) {
112 Document document = hits.doc(i);
113
114 SearchEngineUtil.deleteDocument(
115 category.getCompanyId(), document.get(Field.UID));
116 }
117 }
118 else if (obj instanceof MBMessage) {
119 MBMessage message = (MBMessage)obj;
120
121 Document document = new DocumentImpl();
122
123 document.addUID(PORTLET_ID, message.getMessageId());
124
125 SearchEngineUtil.deleteDocument(
126 message.getCompanyId(), document.get(Field.UID));
127 }
128 else if (obj instanceof MBThread) {
129 MBThread thread = (MBThread)obj;
130
131 MBMessage message = MBMessageLocalServiceUtil.getMessage(
132 thread.getRootMessageId());
133
134 BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
135
136 booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
137
138 booleanQuery.addRequiredTerm("threadId", thread.getThreadId());
139
140 Hits hits = SearchEngineUtil.search(
141 message.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
142 QueryUtil.ALL_POS);
143
144 for (int i = 0; i < hits.getLength(); i++) {
145 Document document = hits.doc(i);
146
147 SearchEngineUtil.deleteDocument(
148 message.getCompanyId(), document.get(Field.UID));
149 }
150 }
151 }
152
153 protected Document doGetDocument(Object obj) throws Exception {
154 MBMessage message = (MBMessage)obj;
155
156 long companyId = message.getCompanyId();
157 long groupId = getParentGroupId(message.getGroupId());
158 long scopeGroupId = message.getGroupId();
159 long userId = message.getUserId();
160 String userName = PortalUtil.getUserName(userId, message.getUserName());
161 long categoryId = message.getCategoryId();
162 long threadId = message.getThreadId();
163 long messageId = message.getMessageId();
164 String title = message.getSubject();
165 String content = processContent(messageId, message.getBody());
166 boolean anonymous = message.isAnonymous();
167 Date modifiedDate = message.getModifiedDate();
168
169 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
170 MBMessage.class.getName(), messageId);
171
172 ExpandoBridge expandoBridge = message.getExpandoBridge();
173
174 Document document = new DocumentImpl();
175
176 document.addUID(PORTLET_ID, messageId);
177
178 document.addModifiedDate(modifiedDate);
179
180 document.addKeyword(Field.COMPANY_ID, companyId);
181 document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
182 document.addKeyword(Field.GROUP_ID, groupId);
183 document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
184 document.addKeyword(Field.USER_ID, userId);
185
186 if (!anonymous) {
187 document.addText(Field.USER_NAME, userName);
188 }
189
190 document.addText(Field.TITLE, title);
191 document.addText(Field.CONTENT, content);
192 document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
193
194 document.addKeyword(Field.CATEGORY_ID, categoryId);
195 document.addKeyword("threadId", threadId);
196 document.addKeyword(Field.ENTRY_CLASS_NAME, MBMessage.class.getName());
197 document.addKeyword(Field.ENTRY_CLASS_PK, messageId);
198 document.addKeyword(
199 Field.ROOT_ENTRY_CLASS_PK, message.getRootMessageId());
200
201 ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
202
203 return document;
204 }
205
206 protected void doReindex(Object obj) throws Exception {
207 MBMessage message = (MBMessage)obj;
208
209 if (message.isDiscussion() ||
210 (message.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
211
212 return;
213 }
214
215 Document document = getDocument(message);
216
217 SearchEngineUtil.updateDocument(message.getCompanyId(), document);
218 }
219
220 protected void doReindex(String className, long classPK) throws Exception {
221 MBMessage message = MBMessageLocalServiceUtil.getMessage(classPK);
222
223 doReindex(message);
224
225 if (message.isRoot()) {
226 List<MBMessage> messages =
227 MBMessageLocalServiceUtil.getThreadMessages(
228 message.getThreadId(), WorkflowConstants.STATUS_APPROVED);
229
230 for (MBMessage curMessage : messages) {
231 reindex(curMessage);
232 }
233 }
234 else {
235 reindex(message);
236 }
237 }
238
239 protected void doReindex(String[] ids) throws Exception {
240 long companyId = GetterUtil.getLong(ids[0]);
241
242 reindexCategories(companyId);
243 reindexRoot(companyId);
244 }
245
246 protected String getPortletId(SearchContext searchContext) {
247 return PORTLET_ID;
248 }
249
250 protected boolean hasPermission(
251 PermissionChecker permissionChecker, long entryClassPK,
252 String actionId)
253 throws Exception {
254
255 return MBMessagePermission.contains(
256 permissionChecker, entryClassPK, ActionKeys.VIEW);
257 }
258
259 protected boolean isFilterSearch() {
260 return _FILTER_SEARCH;
261 }
262
263 protected void postProcessContextQuery(
264 BooleanQuery contextQuery, SearchContext searchContext)
265 throws Exception {
266
267 long threadId = GetterUtil.getLong(
268 (String)searchContext.getAttribute("threadId"));
269
270 if (threadId > 0) {
271 contextQuery.addTerm("threadId", threadId);
272 }
273 }
274
275 protected String processContent(long messageId, String content) {
276 try {
277 content = BBCodeUtil.getHTML(content);
278 }
279 catch (Exception e) {
280 _log.error(
281 "Could not parse message " + messageId + ": " + e.getMessage());
282 }
283
284 content = HtmlUtil.extractText(content);
285
286 return content;
287 }
288
289 protected void reindexCategories(long companyId) throws Exception {
290 int categoryCount =
291 MBCategoryLocalServiceUtil.getCompanyCategoriesCount(companyId);
292
293 int categoryPages = categoryCount / Indexer.DEFAULT_INTERVAL;
294
295 for (int i = 0; i <= categoryPages; i++) {
296 int categoryStart = (i * Indexer.DEFAULT_INTERVAL);
297 int categoryEnd = categoryStart + Indexer.DEFAULT_INTERVAL;
298
299 reindexCategories(companyId, categoryStart, categoryEnd);
300 }
301 }
302
303 protected void reindexCategories(
304 long companyId, int categoryStart, int categoryEnd)
305 throws Exception {
306
307 List<MBCategory> categories =
308 MBCategoryLocalServiceUtil.getCompanyCategories(
309 companyId, categoryStart, categoryEnd);
310
311 for (MBCategory category : categories) {
312 long groupId = category.getGroupId();
313 long categoryId = category.getCategoryId();
314
315 int messageCount =
316 MBMessageLocalServiceUtil.getCategoryMessagesCount(
317 groupId, categoryId, WorkflowConstants.STATUS_APPROVED);
318
319 int messagePages = messageCount / Indexer.DEFAULT_INTERVAL;
320
321 for (int i = 0; i <= messagePages; i++) {
322 int messageStart = (i * Indexer.DEFAULT_INTERVAL);
323 int messageEnd = messageStart + Indexer.DEFAULT_INTERVAL;
324
325 reindexMessages(
326 companyId, groupId, categoryId, messageStart, messageEnd);
327 }
328 }
329 }
330
331 protected void reindexMessages(
332 long companyId, long groupId, long categoryId, int messageStart,
333 int messageEnd)
334 throws Exception {
335
336 List<MBMessage> messages =
337 MBMessageLocalServiceUtil.getCategoryMessages(
338 groupId, categoryId, WorkflowConstants.STATUS_APPROVED,
339 messageStart, messageEnd);
340
341 if (messages.isEmpty()) {
342 return;
343 }
344
345 Collection<Document> documents = new ArrayList<Document>();
346
347 for (MBMessage message : messages) {
348 Document document = getDocument(message);
349
350 documents.add(document);
351 }
352
353 SearchEngineUtil.updateDocuments(companyId, documents);
354 }
355
356 protected void reindexRoot(long companyId) throws Exception {
357 int groupCount = GroupLocalServiceUtil.getCompanyGroupsCount(companyId);
358
359 int groupPages = groupCount / Indexer.DEFAULT_INTERVAL;
360
361 for (int i = 0; i <= groupPages; i++) {
362 int groupStart = (i * Indexer.DEFAULT_INTERVAL);
363 int groupEnd = groupStart + Indexer.DEFAULT_INTERVAL;
364
365 reindexRoot(companyId, groupStart, groupEnd);
366 }
367 }
368
369 protected void reindexRoot(long companyId, int groupStart, int groupEnd)
370 throws Exception {
371
372 List<Group> groups = GroupLocalServiceUtil.getCompanyGroups(
373 companyId, groupStart, groupEnd);
374
375 for (Group group : groups) {
376 long groupId = group.getGroupId();
377 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
378
379 int entryCount = MBMessageLocalServiceUtil.getCategoryMessagesCount(
380 groupId, categoryId, WorkflowConstants.STATUS_APPROVED);
381
382 int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
383
384 for (int i = 0; i <= entryPages; i++) {
385 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
386 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
387
388 reindexMessages(
389 companyId, groupId, categoryId, entryStart, entryEnd);
390 }
391 }
392 }
393
394 private static final boolean _FILTER_SEARCH = true;
395
396 private static Log _log = LogFactoryUtil.getLog(MBIndexer.class);
397
398 }