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