1
14
15 package com.liferay.portlet.messageboards.util;
16
17 import com.liferay.portal.kernel.dao.orm.QueryUtil;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.search.BooleanQuery;
21 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
22 import com.liferay.portal.kernel.search.Document;
23 import com.liferay.portal.kernel.search.DocumentImpl;
24 import com.liferay.portal.kernel.search.Field;
25 import com.liferay.portal.kernel.search.Hits;
26 import com.liferay.portal.kernel.search.Indexer;
27 import com.liferay.portal.kernel.search.SearchContext;
28 import com.liferay.portal.kernel.search.SearchEngineUtil;
29 import com.liferay.portal.kernel.search.Summary;
30 import com.liferay.portal.kernel.util.GetterUtil;
31 import com.liferay.portal.kernel.util.HtmlUtil;
32 import com.liferay.portal.kernel.util.StringUtil;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.kernel.workflow.StatusConstants;
35 import com.liferay.portal.model.Group;
36 import com.liferay.portal.search.BaseIndexer;
37 import com.liferay.portal.service.GroupLocalServiceUtil;
38 import com.liferay.portal.util.PortalUtil;
39 import com.liferay.portal.util.PortletKeys;
40 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
41 import com.liferay.portlet.expando.model.ExpandoBridge;
42 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
43 import com.liferay.portlet.messageboards.model.MBCategory;
44 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
45 import com.liferay.portlet.messageboards.model.MBMessage;
46 import com.liferay.portlet.messageboards.model.MBThread;
47 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
48 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
49 import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
50
51 import java.util.Date;
52 import java.util.List;
53
54 import javax.portlet.PortletURL;
55
56
64 public class MBIndexer extends BaseIndexer {
65
66 public static final String[] CLASS_NAMES = {MBMessage.class.getName()};
67
68 public static final String PORTLET_ID = PortletKeys.MESSAGE_BOARDS;
69
70 public String[] getClassNames() {
71 return CLASS_NAMES;
72 }
73
74 public Summary getSummary(
75 Document document, String snippet, PortletURL portletURL) {
76
77 String title = document.get(Field.TITLE);
78
79 String content = snippet;
80
81 if (Validator.isNull(snippet)) {
82 content = StringUtil.shorten(document.get(Field.CONTENT), 200);
83 }
84
85 String messageId = document.get(Field.ENTRY_CLASS_PK);
86
87 portletURL.setParameter(
88 "struts_action", "/message_boards/view_message");
89 portletURL.setParameter("messageId", messageId);
90
91 return new Summary(title, content, portletURL);
92 }
93
94 protected void doDelete(Object obj) throws Exception {
95 if (obj instanceof MBCategory) {
96 MBCategory category = (MBCategory)obj;
97
98 BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
99
100 booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
101
102 booleanQuery.addRequiredTerm(
103 "categoryId", category.getCategoryId());
104
105 Hits hits = SearchEngineUtil.search(
106 category.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
107 QueryUtil.ALL_POS);
108
109 for (int i = 0; i < hits.getLength(); i++) {
110 Document document = hits.doc(i);
111
112 SearchEngineUtil.deleteDocument(
113 category.getCompanyId(), document.get(Field.UID));
114 }
115 }
116 else if (obj instanceof MBMessage) {
117 MBMessage message = (MBMessage)obj;
118
119 Document document = new DocumentImpl();
120
121 document.addUID(PORTLET_ID, message.getMessageId());
122
123 SearchEngineUtil.deleteDocument(
124 message.getCompanyId(), document.get(Field.UID));
125 }
126 else if (obj instanceof MBThread) {
127 MBThread thread = (MBThread)obj;
128
129 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
130 thread.getCategoryId());
131
132 BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
133
134 booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
135
136 booleanQuery.addRequiredTerm("threadId", thread.getThreadId());
137
138 Hits hits = SearchEngineUtil.search(
139 category.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
140 QueryUtil.ALL_POS);
141
142 for (int i = 0; i < hits.getLength(); i++) {
143 Document document = hits.doc(i);
144
145 SearchEngineUtil.deleteDocument(
146 category.getCompanyId(), document.get(Field.UID));
147 }
148 }
149 }
150
151 protected Document doGetDocument(Object obj) throws Exception {
152 MBMessage message = (MBMessage)obj;
153
154 long companyId = message.getCompanyId();
155 long groupId = getParentGroupId(message.getGroupId());
156 long scopeGroupId = message.getGroupId();
157 long userId = message.getUserId();
158 String userName = PortalUtil.getUserName(userId, message.getUserName());
159 long categoryId = message.getCategoryId();
160 long threadId = message.getThreadId();
161 long messageId = message.getMessageId();
162 String title = message.getSubject();
163 String content = processContent(messageId, message.getBody());
164 boolean anonymous = message.isAnonymous();
165 Date modifiedDate = message.getModifiedDate();
166
167 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
168 MBMessage.class.getName(), messageId);
169
170 ExpandoBridge expandoBridge = message.getExpandoBridge();
171
172 Document document = new DocumentImpl();
173
174 document.addUID(PORTLET_ID, messageId);
175
176 document.addModifiedDate(modifiedDate);
177
178 document.addKeyword(Field.COMPANY_ID, companyId);
179 document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
180 document.addKeyword(Field.GROUP_ID, groupId);
181 document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
182 document.addKeyword(Field.USER_ID, userId);
183
184 if (!anonymous) {
185 document.addText(Field.USER_NAME, userName);
186 }
187
188 document.addText(Field.TITLE, title);
189 document.addText(Field.CONTENT, content);
190 document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
191
192 document.addKeyword(Field.CATEGORY_ID, categoryId);
193 document.addKeyword("threadId", threadId);
194 document.addKeyword(Field.ENTRY_CLASS_NAME, MBMessage.class.getName());
195 document.addKeyword(Field.ENTRY_CLASS_PK, messageId);
196
197 try {
198 MBThread thread = MBThreadLocalServiceUtil.getMBThread(threadId);
199
200 document.addKeyword(
201 Field.ROOT_ENTRY_CLASS_PK, thread.getRootMessageId());
202 }
203 catch (Exception e) {
204 }
205
206 ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
207
208 return document;
209 }
210 protected void doReindex(Object obj) throws Exception {
211 MBMessage message = (MBMessage)obj;
212
213 if (message.isDiscussion() ||
214 (message.getStatus() != StatusConstants.APPROVED)) {
215
216 return;
217 }
218
219 Document document = getDocument(message);
220
221 SearchEngineUtil.updateDocument(
222 message.getCompanyId(), document.get(Field.UID), document);
223 }
224
225 protected void doReindex(String className, long classPK) throws Exception {
226 MBMessage message = MBMessageLocalServiceUtil.getMessage(classPK);
227
228 doReindex(message);
229
230 if (message.isRoot()) {
231 List<MBMessage> messages =
232 MBMessageLocalServiceUtil.getThreadMessages(
233 message.getThreadId(), StatusConstants.APPROVED);
234
235 for (MBMessage curMessage : messages) {
236 reindex(curMessage);
237 }
238 }
239 else {
240 reindex(message);
241 }
242 }
243
244 protected void doReindex(String[] ids) throws Exception {
245 long companyId = GetterUtil.getLong(ids[0]);
246
247 reindexCategories(companyId);
248 reindexRoot(companyId);
249 }
250
251 protected String getPortletId(SearchContext searchContext) {
252 return PORTLET_ID;
253 }
254
255 protected void postProcessContextQuery(
256 BooleanQuery contextQuery, SearchContext searchContext)
257 throws Exception {
258
259 Long threadId = (Long)searchContext.getAttribute("threadId");
260
261 if ((threadId != null) && (threadId.longValue() > 0)) {
262 contextQuery.addTerm("threadId", threadId.longValue());
263 }
264 }
265
266 protected String processContent(long messageId, String content) {
267 try {
268 content = BBCodeUtil.getHTML(content);
269 }
270 catch (Exception e) {
271 _log.error(
272 "Could not parse message " + messageId + ": " + e.getMessage());
273 }
274
275 content = HtmlUtil.extractText(content);
276
277 return content;
278 }
279
280 protected void reindexCategories(long companyId) throws Exception {
281 int categoryCount =
282 MBCategoryLocalServiceUtil.getCompanyCategoriesCount(companyId);
283
284 int categoryPages = categoryCount / Indexer.DEFAULT_INTERVAL;
285
286 for (int i = 0; i <= categoryPages; i++) {
287 int categoryStart = (i * Indexer.DEFAULT_INTERVAL);
288 int categoryEnd = categoryStart + Indexer.DEFAULT_INTERVAL;
289
290 reindexCategories(companyId, categoryStart, categoryEnd);
291 }
292 }
293
294 protected void reindexCategories(
295 long companyId, int categoryStart, int categoryEnd)
296 throws Exception {
297
298 List<MBCategory> categories =
299 MBCategoryLocalServiceUtil.getCompanyCategories(
300 companyId, categoryStart, categoryEnd);
301
302 for (MBCategory category : categories) {
303 long groupId = category.getGroupId();
304 long categoryId = category.getCategoryId();
305
306 int messageCount =
307 MBMessageLocalServiceUtil.getCategoryMessagesCount(
308 groupId, categoryId, StatusConstants.APPROVED);
309
310 int messagePages = messageCount / Indexer.DEFAULT_INTERVAL;
311
312 for (int i = 0; i <= messagePages; i++) {
313 int messageStart = (i * Indexer.DEFAULT_INTERVAL);
314 int messageEnd = messageStart + Indexer.DEFAULT_INTERVAL;
315
316 reindexMessages(groupId, categoryId, messageStart, messageEnd);
317 }
318 }
319 }
320
321 protected void reindexMessages(
322 long groupId, long categoryId, int messageStart, int messageEnd)
323 throws Exception {
324
325 List<MBMessage> messages =
326 MBMessageLocalServiceUtil.getCategoryMessages(
327 groupId, categoryId, StatusConstants.APPROVED, messageStart,
328 messageEnd);
329
330 for (MBMessage message : messages) {
331 reindex(message);
332 }
333 }
334
335 protected void reindexRoot(long companyId) throws Exception {
336 int groupCount = GroupLocalServiceUtil.getCompanyGroupsCount(companyId);
337
338 int groupPages = groupCount / Indexer.DEFAULT_INTERVAL;
339
340 for (int i = 0; i <= groupPages; i++) {
341 int groupStart = (i * Indexer.DEFAULT_INTERVAL);
342 int groupEnd = groupStart + Indexer.DEFAULT_INTERVAL;
343
344 reindexRoot(companyId, groupStart, groupEnd);
345 }
346 }
347
348 protected void reindexRoot(long companyId, int groupStart, int groupEnd)
349 throws Exception {
350
351 List<Group> groups = GroupLocalServiceUtil.getCompanyGroups(
352 companyId, groupStart, groupEnd);
353
354 for (Group group : groups) {
355 long groupId = group.getGroupId();
356 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
357
358 int entryCount = MBMessageLocalServiceUtil.getCategoryMessagesCount(
359 groupId, categoryId, StatusConstants.APPROVED);
360
361 int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
362
363 for (int i = 0; i <= entryPages; i++) {
364 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
365 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
366
367 reindexMessages(groupId, categoryId, entryStart, entryEnd);
368 }
369 }
370 }
371
372 private static Log _log = LogFactoryUtil.getLog(MBIndexer.class);
373
374 }