1
22
23 package com.liferay.portlet.messageboards.service.impl;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.search.Hits;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.Validator;
30 import com.liferay.portal.lucene.LuceneFields;
31 import com.liferay.portal.lucene.LuceneUtil;
32 import com.liferay.portal.model.CompanyConstants;
33 import com.liferay.portal.model.ResourceConstants;
34 import com.liferay.portal.model.User;
35 import com.liferay.portal.util.PortalUtil;
36 import com.liferay.portlet.messageboards.CategoryNameException;
37 import com.liferay.portlet.messageboards.model.MBCategory;
38 import com.liferay.portlet.messageboards.model.MBMessage;
39 import com.liferay.portlet.messageboards.model.MBThread;
40 import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
41 import com.liferay.portlet.messageboards.service.base.MBCategoryLocalServiceBaseImpl;
42 import com.liferay.portlet.messageboards.util.Indexer;
43 import com.liferay.util.lucene.HitsImpl;
44
45 import java.io.IOException;
46
47 import java.util.ArrayList;
48 import java.util.Date;
49 import java.util.List;
50
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53 import org.apache.lucene.document.Document;
54 import org.apache.lucene.index.IndexWriter;
55 import org.apache.lucene.index.Term;
56 import org.apache.lucene.queryParser.ParseException;
57 import org.apache.lucene.search.BooleanClause;
58 import org.apache.lucene.search.BooleanQuery;
59 import org.apache.lucene.search.Searcher;
60 import org.apache.lucene.search.TermQuery;
61
62
68 public class MBCategoryLocalServiceImpl extends MBCategoryLocalServiceBaseImpl {
69
70 public MBCategory addCategory(
71 long userId, long plid, long parentCategoryId, String name,
72 String description, boolean addCommunityPermissions,
73 boolean addGuestPermissions)
74 throws PortalException, SystemException {
75
76 return addCategory(
77 null, userId, plid, parentCategoryId, name, description,
78 Boolean.valueOf(addCommunityPermissions),
79 Boolean.valueOf(addGuestPermissions), null, null);
80 }
81
82 public MBCategory addCategory(
83 String uuid, long userId, long plid, long parentCategoryId,
84 String name, String description, boolean addCommunityPermissions,
85 boolean addGuestPermissions)
86 throws PortalException, SystemException {
87
88 return addCategory(
89 uuid, userId, plid, parentCategoryId, name, description,
90 Boolean.valueOf(addCommunityPermissions),
91 Boolean.valueOf(addGuestPermissions), null, null);
92 }
93
94 public MBCategory addCategory(
95 long userId, long plid, long parentCategoryId, String name,
96 String description, String[] communityPermissions,
97 String[] guestPermissions)
98 throws PortalException, SystemException {
99
100 return addCategory(
101 null, userId, plid, parentCategoryId, name, description, null, null,
102 communityPermissions, guestPermissions);
103 }
104
105 public MBCategory addCategory(
106 String uuid, long userId, long plid, long parentCategoryId,
107 String name, String description, Boolean addCommunityPermissions,
108 Boolean addGuestPermissions, String[] communityPermissions,
109 String[] guestPermissions)
110 throws PortalException, SystemException {
111
112
114 User user = userPersistence.findByPrimaryKey(userId);
115 long groupId = PortalUtil.getPortletGroupId(plid);
116 parentCategoryId = getParentCategoryId(groupId, parentCategoryId);
117 Date now = new Date();
118
119 validate(name);
120
121 long categoryId = counterLocalService.increment();
122
123 MBCategory category = mbCategoryPersistence.create(categoryId);
124
125 category.setUuid(uuid);
126 category.setGroupId(groupId);
127 category.setCompanyId(user.getCompanyId());
128 category.setUserId(user.getUserId());
129 category.setUserName(user.getFullName());
130 category.setCreateDate(now);
131 category.setModifiedDate(now);
132 category.setParentCategoryId(parentCategoryId);
133 category.setName(name);
134 category.setDescription(description);
135
136 mbCategoryPersistence.update(category, false);
137
138
140 if ((addCommunityPermissions != null) &&
141 (addGuestPermissions != null)) {
142
143 addCategoryResources(
144 category, addCommunityPermissions.booleanValue(),
145 addGuestPermissions.booleanValue());
146 }
147 else {
148 addCategoryResources(
149 category, communityPermissions, guestPermissions);
150 }
151
152 return category;
153 }
154
155 public void addCategoryResources(
156 long categoryId, boolean addCommunityPermissions,
157 boolean addGuestPermissions)
158 throws PortalException, SystemException {
159
160 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
161 categoryId);
162
163 addCategoryResources(
164 category, addCommunityPermissions, addGuestPermissions);
165 }
166
167 public void addCategoryResources(
168 MBCategory category, boolean addCommunityPermissions,
169 boolean addGuestPermissions)
170 throws PortalException, SystemException {
171
172 resourceLocalService.addResources(
173 category.getCompanyId(), category.getGroupId(),
174 category.getUserId(), MBCategory.class.getName(),
175 category.getCategoryId(), false, addCommunityPermissions,
176 addGuestPermissions);
177 }
178
179 public void addCategoryResources(
180 long categoryId, String[] communityPermissions,
181 String[] guestPermissions)
182 throws PortalException, SystemException {
183
184 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
185 categoryId);
186
187 addCategoryResources(category, communityPermissions, guestPermissions);
188 }
189
190 public void addCategoryResources(
191 MBCategory category, String[] communityPermissions,
192 String[] guestPermissions)
193 throws PortalException, SystemException {
194
195 resourceLocalService.addModelResources(
196 category.getCompanyId(), category.getGroupId(),
197 category.getUserId(), MBCategory.class.getName(),
198 category.getCategoryId(), communityPermissions, guestPermissions);
199 }
200
201 public void deleteCategories(long groupId)
202 throws PortalException, SystemException {
203
204 List<MBCategory> categories = mbCategoryPersistence.findByG_P(
205 groupId, MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID);
206
207 for (MBCategory category : categories) {
208 deleteCategory(category);
209 }
210 }
211
212 public void deleteCategory(long categoryId)
213 throws PortalException, SystemException {
214
215 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
216 categoryId);
217
218 deleteCategory(category);
219 }
220
221 public void deleteCategory(MBCategory category)
222 throws PortalException, SystemException {
223
224
226 List<MBCategory> categories = mbCategoryPersistence.findByG_P(
227 category.getGroupId(), category.getCategoryId());
228
229 for (MBCategory curCategory : categories) {
230 deleteCategory(curCategory);
231 }
232
233
235 try {
236 Indexer.deleteMessages(
237 category.getCompanyId(), category.getCategoryId());
238 }
239 catch (IOException ioe) {
240 _log.error("Deleting index " + category.getCategoryId(), ioe);
241 }
242 catch (ParseException pe) {
243 _log.error("Deleting index " + category.getCategoryId(), pe);
244 }
245
246
248 mbThreadLocalService.deleteThreads(category.getCategoryId());
249
250
252 resourceLocalService.deleteResource(
253 category.getCompanyId(), MBCategory.class.getName(),
254 ResourceConstants.SCOPE_INDIVIDUAL, category.getCategoryId());
255
256
258 mbCategoryPersistence.remove(category.getCategoryId());
259 }
260
261 public List<MBCategory> getCategories(long groupId, long parentCategoryId)
262 throws SystemException {
263
264 return mbCategoryPersistence.findByG_P(groupId, parentCategoryId);
265 }
266
267 public List<MBCategory> getCategories(
268 long groupId, long parentCategoryId, int begin, int end)
269 throws SystemException {
270
271 return mbCategoryPersistence.findByG_P(
272 groupId, parentCategoryId, begin, end);
273 }
274
275 public int getCategoriesCount(long groupId) throws SystemException {
276 return mbCategoryPersistence.countByGroupId(groupId);
277 }
278
279 public int getCategoriesCount(long groupId, long parentCategoryId)
280 throws SystemException {
281
282 return mbCategoryPersistence.countByG_P(groupId, parentCategoryId);
283 }
284
285 public MBCategory getCategory(long categoryId)
286 throws PortalException, SystemException {
287
288 return mbCategoryPersistence.findByPrimaryKey(categoryId);
289 }
290
291 public void getSubcategoryIds(
292 List<Long> categoryIds, long groupId, long categoryId)
293 throws SystemException {
294
295 List<MBCategory> categories = mbCategoryPersistence.findByG_P(
296 groupId, categoryId);
297
298 for (MBCategory category : categories) {
299 categoryIds.add(category.getCategoryId());
300
301 getSubcategoryIds(
302 categoryIds, category.getGroupId(), category.getCategoryId());
303 }
304 }
305
306 public List<MBCategory> getSubscribedCategories(
307 long groupId, long userId, int begin, int end)
308 throws SystemException {
309
310 return mbCategoryFinder.findByS_G_U(groupId, userId, begin, end);
311 }
312
313 public int getSubscribedCategoriesCount(long groupId, long userId)
314 throws SystemException {
315
316 return mbCategoryFinder.countByS_G_U(groupId, userId);
317 }
318
319 public MBCategory getSystemCategory()
320 throws PortalException, SystemException {
321
322 long categoryId = CompanyConstants.SYSTEM;
323
324 MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(
325 categoryId);
326
327 if (category == null) {
328 category = mbCategoryPersistence.create(categoryId);
329
330 category.setCompanyId(CompanyConstants.SYSTEM);
331 category.setUserId(CompanyConstants.SYSTEM);
332
333 mbCategoryPersistence.update(category, false);
334 }
335
336 return category;
337 }
338
339 public void reIndex(String[] ids) throws SystemException {
340 if (LuceneUtil.INDEX_READ_ONLY) {
341 return;
342 }
343
344 long companyId = GetterUtil.getLong(ids[0]);
345
346 IndexWriter writer = null;
347
348 try {
349 writer = LuceneUtil.getWriter(companyId);
350
351 List<MBCategory> categories = mbCategoryPersistence.findByCompanyId(
352 companyId);
353
354 for (MBCategory category : categories) {
355 long categoryId = category.getCategoryId();
356
357 List<MBMessage> messages =
358 mbMessagePersistence.findByCategoryId(categoryId);
359
360 for (MBMessage message : messages) {
361 long groupId = category.getGroupId();
362 String userName = message.getUserName();
363 long threadId = message.getThreadId();
364 long messageId = message.getMessageId();
365 String title = message.getSubject();
366 String content = message.getBody();
367
368 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
369 MBMessage.class.getName(), messageId);
370
371 try {
372 Document doc = Indexer.getAddMessageDocument(
373 companyId, groupId, userName, categoryId, threadId,
374 messageId, title, content, tagsEntries);
375
376 writer.addDocument(doc);
377 }
378 catch (Exception e1) {
379 _log.error("Reindexing " + messageId, e1);
380 }
381 }
382 }
383 }
384 catch (SystemException se) {
385 throw se;
386 }
387 catch (Exception e2) {
388 throw new SystemException(e2);
389 }
390 finally {
391 try {
392 if (writer != null) {
393 LuceneUtil.write(companyId);
394 }
395 }
396 catch (Exception e) {
397 _log.error(e);
398 }
399 }
400 }
401
402 public Hits search(
403 long companyId, long groupId, long[] categoryIds, long threadId,
404 String keywords)
405 throws SystemException {
406
407 Searcher searcher = null;
408
409 try {
410 HitsImpl hits = new HitsImpl();
411
412 BooleanQuery contextQuery = new BooleanQuery();
413
414 LuceneUtil.addRequiredTerm(
415 contextQuery, LuceneFields.PORTLET_ID, Indexer.PORTLET_ID);
416
417 if (groupId > 0) {
418 LuceneUtil.addRequiredTerm(
419 contextQuery, LuceneFields.GROUP_ID, groupId);
420 }
421
422 if ((categoryIds != null) && (categoryIds.length > 0)) {
423 BooleanQuery categoryIdsQuery = new BooleanQuery();
424
425 for (int i = 0; i < categoryIds.length; i++) {
426 Term term = new Term(
427 "categoryId", String.valueOf(categoryIds[i]));
428 TermQuery termQuery = new TermQuery(term);
429
430 categoryIdsQuery.add(termQuery, BooleanClause.Occur.SHOULD);
431 }
432
433 contextQuery.add(categoryIdsQuery, BooleanClause.Occur.MUST);
434 }
435
436 if (threadId > 0) {
437 LuceneUtil.addTerm(contextQuery, "threadId", threadId);
438 }
439
440 BooleanQuery searchQuery = new BooleanQuery();
441
442 if (Validator.isNotNull(keywords)) {
443 LuceneUtil.addTerm(
444 searchQuery, LuceneFields.USER_NAME, keywords);
445 LuceneUtil.addTerm(searchQuery, LuceneFields.TITLE, keywords);
446 LuceneUtil.addTerm(searchQuery, LuceneFields.CONTENT, keywords);
447 LuceneUtil.addTerm(
448 searchQuery, LuceneFields.TAG_ENTRY, keywords);
449 }
450
451 BooleanQuery fullQuery = new BooleanQuery();
452
453 fullQuery.add(contextQuery, BooleanClause.Occur.MUST);
454
455 if (searchQuery.clauses().size() > 0) {
456 fullQuery.add(searchQuery, BooleanClause.Occur.MUST);
457 }
458
459 searcher = LuceneUtil.getSearcher(companyId);
460
461 hits.recordHits(searcher.search(fullQuery), searcher);
462
463 return hits;
464 }
465 catch (Exception e) {
466 return LuceneUtil.closeSearcher(searcher, keywords, e);
467 }
468 }
469
470 public MBCategory updateCategory(
471 long categoryId, long parentCategoryId, String name,
472 String description, boolean mergeWithParentCategory)
473 throws PortalException, SystemException {
474
475
477 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
478 categoryId);
479
480 parentCategoryId = getParentCategoryId(category, parentCategoryId);
481
482 validate(name);
483
484 category.setModifiedDate(new Date());
485 category.setParentCategoryId(parentCategoryId);
486 category.setName(name);
487 category.setDescription(description);
488
489 mbCategoryPersistence.update(category, false);
490
491
493 if (mergeWithParentCategory &&
494 (categoryId != parentCategoryId) &&
495 (parentCategoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID)) {
496
497 mergeCategories(category, parentCategoryId);
498 }
499
500 return category;
501 }
502
503 protected long getParentCategoryId(long groupId, long parentCategoryId)
504 throws SystemException {
505
506 if (parentCategoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) {
507 MBCategory parentCategory = mbCategoryPersistence.fetchByPrimaryKey(
508 parentCategoryId);
509
510 if ((parentCategory == null) ||
511 (groupId != parentCategory.getGroupId())) {
512
513 parentCategoryId = MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID;
514 }
515 }
516
517 return parentCategoryId;
518 }
519
520 protected long getParentCategoryId(
521 MBCategory category, long parentCategoryId)
522 throws SystemException {
523
524 if (parentCategoryId == MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) {
525 return parentCategoryId;
526 }
527
528 if (category.getCategoryId() == parentCategoryId) {
529 return category.getParentCategoryId();
530 }
531 else {
532 MBCategory parentCategory = mbCategoryPersistence.fetchByPrimaryKey(
533 parentCategoryId);
534
535 if ((parentCategory == null) ||
536 (category.getGroupId() != parentCategory.getGroupId())) {
537
538 return category.getParentCategoryId();
539 }
540
541 List<Long> subcategoryIds = new ArrayList<Long>();
542
543 getSubcategoryIds(
544 subcategoryIds, category.getGroupId(),
545 category.getCategoryId());
546
547 if (subcategoryIds.contains(parentCategoryId)) {
548 return category.getParentCategoryId();
549 }
550
551 return parentCategoryId;
552 }
553 }
554
555 protected void mergeCategories(MBCategory fromCategory, long toCategoryId)
556 throws PortalException, SystemException {
557
558 List<MBCategory> categories = mbCategoryPersistence.findByG_P(
559 fromCategory.getGroupId(), fromCategory.getCategoryId());
560
561 for (MBCategory category : categories) {
562 mergeCategories(category, toCategoryId);
563 }
564
565 List<MBThread> threads = mbThreadPersistence.findByCategoryId(
566 fromCategory.getCategoryId());
567
568 for (MBThread thread : threads) {
569
570
572 thread.setCategoryId(toCategoryId);
573
574 mbThreadPersistence.update(thread, false);
575
576 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
577 thread.getThreadId());
578
579 for (MBMessage message : messages) {
580
581
583 message.setCategoryId(toCategoryId);
584
585 mbMessagePersistence.update(message, false);
586
587
589 try {
590 if (!fromCategory.isDiscussion()) {
591 String[] tagsEntries =
592 tagsEntryLocalService.getEntryNames(
593 MBMessage.class.getName(),
594 message.getMessageId());
595
596 Indexer.updateMessage(
597 message.getCompanyId(), fromCategory.getGroupId(),
598 message.getUserName(), toCategoryId,
599 message.getThreadId(), message.getMessageId(),
600 message.getSubject(), message.getBody(),
601 tagsEntries);
602 }
603 }
604 catch (IOException ioe) {
605 _log.error("Indexing " + message.getMessageId(), ioe);
606 }
607 }
608 }
609
610 mbCategoryPersistence.remove(fromCategory.getCategoryId());
611 }
612
613 public void subscribeCategory(long userId, long categoryId)
614 throws PortalException, SystemException {
615
616 subscriptionLocalService.addSubscription(
617 userId, MBCategory.class.getName(), categoryId);
618 }
619
620 public void unsubscribeCategory(long userId, long categoryId)
621 throws PortalException, SystemException {
622
623 subscriptionLocalService.deleteSubscription(
624 userId, MBCategory.class.getName(), categoryId);
625 }
626
627 protected void validate(String name) throws PortalException {
628 if (Validator.isNull(name)) {
629 throw new CategoryNameException();
630 }
631 }
632
633 private static Log _log =
634 LogFactory.getLog(MBCategoryLocalServiceImpl.class);
635
636 }