001
014
015 package com.liferay.portlet.journal.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.OrderFactoryUtil;
020 import com.liferay.portal.kernel.exception.PortalException;
021 import com.liferay.portal.kernel.exception.SystemException;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.search.BaseIndexer;
025 import com.liferay.portal.kernel.search.BooleanClauseOccur;
026 import com.liferay.portal.kernel.search.BooleanQuery;
027 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
028 import com.liferay.portal.kernel.search.Document;
029 import com.liferay.portal.kernel.search.DocumentImpl;
030 import com.liferay.portal.kernel.search.Field;
031 import com.liferay.portal.kernel.search.SearchContext;
032 import com.liferay.portal.kernel.search.SearchEngineUtil;
033 import com.liferay.portal.kernel.search.Summary;
034 import com.liferay.portal.kernel.util.CharPool;
035 import com.liferay.portal.kernel.util.Constants;
036 import com.liferay.portal.kernel.util.GetterUtil;
037 import com.liferay.portal.kernel.util.HtmlUtil;
038 import com.liferay.portal.kernel.util.LocaleUtil;
039 import com.liferay.portal.kernel.util.LocalizationUtil;
040 import com.liferay.portal.kernel.util.StringPool;
041 import com.liferay.portal.kernel.util.StringUtil;
042 import com.liferay.portal.kernel.util.Validator;
043 import com.liferay.portal.kernel.util.WebKeys;
044 import com.liferay.portal.kernel.workflow.WorkflowConstants;
045 import com.liferay.portal.security.permission.ActionKeys;
046 import com.liferay.portal.security.permission.PermissionChecker;
047 import com.liferay.portal.theme.ThemeDisplay;
048 import com.liferay.portal.util.PortalUtil;
049 import com.liferay.portal.util.PortletKeys;
050 import com.liferay.portal.util.PropsUtil;
051 import com.liferay.portal.util.PropsValues;
052 import com.liferay.portlet.dynamicdatamapping.StructureFieldException;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
054 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
055 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
056 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexer;
057 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
058 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
059 import com.liferay.portlet.journal.model.JournalArticle;
060 import com.liferay.portlet.journal.model.JournalArticleDisplay;
061 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
062 import com.liferay.portlet.journal.service.permission.JournalArticlePermission;
063 import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
064 import com.liferay.portlet.journal.util.comparator.ArticleResourcePKComparator;
065 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
066 import com.liferay.portlet.trash.util.TrashUtil;
067 import com.liferay.util.portlet.PortletRequestUtil;
068
069 import java.io.Serializable;
070
071 import java.util.ArrayList;
072 import java.util.Collection;
073 import java.util.LinkedHashMap;
074 import java.util.List;
075 import java.util.Locale;
076
077 import javax.portlet.PortletRequest;
078 import javax.portlet.PortletResponse;
079 import javax.portlet.PortletURL;
080
081
089 public class JournalArticleIndexer extends BaseIndexer {
090
091 public static final String[] CLASS_NAMES = {JournalArticle.class.getName()};
092
093 public static boolean JOURNAL_ARTICLE_INDEX_ALL_VERSIONS =
094 GetterUtil.getBoolean(
095 PropsUtil.get("journal.articles.index.all.versions"));
096
097 public static final String PORTLET_ID = PortletKeys.JOURNAL;
098
099 public JournalArticleIndexer() {
100 setFilterSearch(true);
101 setPermissionAware(true);
102 setSummaryNeedsRequestResponse(true);
103 }
104
105 @Override
106 public String[] getClassNames() {
107 return CLASS_NAMES;
108 }
109
110 @Override
111 public String getPortletId() {
112 return PORTLET_ID;
113 }
114
115 @Override
116 public boolean hasPermission(
117 PermissionChecker permissionChecker, String entryClassName,
118 long entryClassPK, String actionId)
119 throws Exception {
120
121 return JournalArticlePermission.contains(
122 permissionChecker, entryClassPK, ActionKeys.VIEW);
123 }
124
125 @Override
126 public boolean isVisible(long classPK, int status) throws Exception {
127 List<JournalArticle> articles =
128 JournalArticleLocalServiceUtil.getArticlesByResourcePrimKey(
129 classPK);
130
131 for (JournalArticle article : articles) {
132 if (isVisible(article.getStatus(), status)) {
133 return true;
134 }
135 }
136
137 return false;
138 }
139
140 @Override
141 public void postProcessContextQuery(
142 BooleanQuery contextQuery, SearchContext searchContext)
143 throws Exception {
144
145 Long classNameId = (Long)searchContext.getAttribute(
146 Field.CLASS_NAME_ID);
147
148 if ((classNameId != null) && (classNameId.longValue() != 0)) {
149 contextQuery.addRequiredTerm("classNameId", classNameId.toString());
150 }
151
152 addStatus(contextQuery, searchContext);
153
154 addSearchClassTypeIds(contextQuery, searchContext);
155
156 String ddmStructureFieldName = (String)searchContext.getAttribute(
157 "ddmStructureFieldName");
158 Serializable ddmStructureFieldValue = searchContext.getAttribute(
159 "ddmStructureFieldValue");
160
161 if (Validator.isNotNull(ddmStructureFieldName) &&
162 Validator.isNotNull(ddmStructureFieldValue)) {
163
164 String[] ddmStructureFieldNameParts = StringUtil.split(
165 ddmStructureFieldName, DDMIndexer.DDM_FIELD_SEPARATOR);
166
167 DDMStructure structure = DDMStructureLocalServiceUtil.getStructure(
168 GetterUtil.getLong(ddmStructureFieldNameParts[1]));
169
170 String fieldName = StringUtil.replaceLast(
171 ddmStructureFieldNameParts[2],
172 StringPool.UNDERLINE.concat(
173 LocaleUtil.toLanguageId(searchContext.getLocale())),
174 StringPool.BLANK);
175
176 try {
177 ddmStructureFieldValue = DDMUtil.getIndexedFieldValue(
178 ddmStructureFieldValue, structure.getFieldType(fieldName));
179 }
180 catch (StructureFieldException sfe) {
181 }
182
183 contextQuery.addRequiredTerm(
184 ddmStructureFieldName,
185 StringPool.QUOTE + ddmStructureFieldValue + StringPool.QUOTE);
186 }
187
188 String articleType = (String)searchContext.getAttribute("articleType");
189
190 if (Validator.isNotNull(articleType)) {
191 contextQuery.addRequiredTerm(Field.TYPE, articleType);
192 }
193
194 String ddmStructureKey = (String)searchContext.getAttribute(
195 "ddmStructureKey");
196
197 if (Validator.isNotNull(ddmStructureKey)) {
198 contextQuery.addRequiredTerm("ddmStructureKey", ddmStructureKey);
199 }
200
201 String ddmTemplateKey = (String)searchContext.getAttribute(
202 "ddmTemplateKey");
203
204 if (Validator.isNotNull(ddmTemplateKey)) {
205 contextQuery.addRequiredTerm("ddmTemplateKey", ddmTemplateKey);
206 }
207 }
208
209 @Override
210 public void postProcessSearchQuery(
211 BooleanQuery searchQuery, SearchContext searchContext)
212 throws Exception {
213
214 addSearchTerm(searchQuery, searchContext, Field.CLASS_PK, false);
215 addSearchLocalizedTerm(
216 searchQuery, searchContext, Field.CONTENT, false);
217 addSearchLocalizedTerm(
218 searchQuery, searchContext, Field.DESCRIPTION, false);
219 addSearchTerm(searchQuery, searchContext, Field.ENTRY_CLASS_PK, false);
220 addSearchLocalizedTerm(searchQuery, searchContext, Field.TITLE, false);
221
222 if (Validator.isNull(searchContext.getAttribute("articleType"))) {
223 addSearchTerm(searchQuery, searchContext, Field.TYPE, false);
224 }
225
226 addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
227
228 addSearchTerm(searchQuery, searchContext, "articleId", false);
229
230 LinkedHashMap<String, Object> params =
231 (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
232
233 if (params != null) {
234 String expandoAttributes = (String)params.get("expandoAttributes");
235
236 if (Validator.isNotNull(expandoAttributes)) {
237 addSearchExpando(searchQuery, searchContext, expandoAttributes);
238 }
239 }
240 }
241
242 protected void addDDMStructureAttributes(
243 Document document, JournalArticle article)
244 throws Exception {
245
246 if (Validator.isNull(article.getStructureId())) {
247 return;
248 }
249
250 DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
251 article.getGroupId(),
252 PortalUtil.getClassNameId(JournalArticle.class),
253 article.getStructureId(), true);
254
255 if (ddmStructure == null) {
256 return;
257 }
258
259 document.addKeyword(Field.CLASS_TYPE_ID, ddmStructure.getStructureId());
260
261 Fields fields = null;
262
263 try {
264 fields = JournalConverterUtil.getDDMFields(
265 ddmStructure, article.getContent());
266 }
267 catch (Exception e) {
268 return;
269 }
270
271 if (fields != null) {
272 DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
273 }
274 }
275
276 @Override
277 protected void addSearchLocalizedTerm(
278 BooleanQuery searchQuery, SearchContext searchContext, String field,
279 boolean like)
280 throws Exception {
281
282 if (Validator.isNull(field)) {
283 return;
284 }
285
286 String value = String.valueOf(searchContext.getAttribute(field));
287
288 if (Validator.isNull(value)) {
289 value = searchContext.getKeywords();
290 }
291
292 if (Validator.isNull(value)) {
293 return;
294 }
295
296 String localizedField = DocumentImpl.getLocalizedName(
297 searchContext.getLocale(), field);
298
299 if (Validator.isNull(searchContext.getKeywords())) {
300 BooleanQuery localizedQuery = BooleanQueryFactoryUtil.create(
301 searchContext);
302
303 localizedQuery.addTerm(field, value, like);
304 localizedQuery.addTerm(localizedField, value, like);
305
306 BooleanClauseOccur booleanClauseOccur = BooleanClauseOccur.SHOULD;
307
308 if (searchContext.isAndSearch()) {
309 booleanClauseOccur = BooleanClauseOccur.MUST;
310 }
311
312 searchQuery.add(localizedQuery, booleanClauseOccur);
313 }
314 else {
315 searchQuery.addTerm(localizedField, value, like);
316 }
317 }
318
319 @Override
320 protected void addStatus(
321 BooleanQuery contextQuery, SearchContext searchContext)
322 throws Exception {
323
324 LinkedHashMap<String, Object> params =
325 (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
326
327 boolean showNonindexable = false;
328
329 if (params != null) {
330 showNonindexable = GetterUtil.getBoolean(
331 params.get("showNonindexable"));
332 }
333
334 super.addStatus(contextQuery, searchContext);
335
336 boolean head = GetterUtil.getBoolean(
337 searchContext.getAttribute("head"), Boolean.TRUE);
338 boolean relatedClassName = GetterUtil.getBoolean(
339 searchContext.getAttribute("relatedClassName"));
340
341 if (head && !relatedClassName && !showNonindexable) {
342 contextQuery.addRequiredTerm("head", Boolean.TRUE);
343 }
344
345 if (!relatedClassName && showNonindexable) {
346 contextQuery.addRequiredTerm("headListable", Boolean.TRUE);
347 }
348 }
349
350 @Override
351 protected void doDelete(Object obj) throws Exception {
352 JournalArticle article = (JournalArticle)obj;
353
354 long classPK = article.getId();
355
356 if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
357 if (JournalArticleLocalServiceUtil.getArticlesCount(
358 article.getGroupId(), article.getArticleId()) > 0) {
359
360 doReindex(obj);
361
362 return;
363 }
364 else {
365 classPK = article.getResourcePrimKey();
366 }
367 }
368
369 deleteDocument(article.getCompanyId(), classPK);
370
371 if (!article.isApproved()) {
372 return;
373 }
374
375 JournalArticle latestIndexableArticle =
376 JournalArticleLocalServiceUtil.fetchLatestIndexableArticle(
377 article.getResourcePrimKey());
378
379 if ((latestIndexableArticle == null) ||
380 (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS &&
381 (latestIndexableArticle.getVersion() > article.getVersion()))) {
382
383 return;
384 }
385
386 SearchEngineUtil.updateDocument(
387 getSearchEngineId(), article.getCompanyId(),
388 getDocument(latestIndexableArticle), isCommitImmediately());
389 }
390
391 @Override
392 protected Document doGetDocument(Object obj) throws Exception {
393 JournalArticle article = (JournalArticle)obj;
394
395 Document document = getBaseModelDocument(PORTLET_ID, article);
396
397 long classPK = article.getId();
398
399 if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
400 classPK = article.getResourcePrimKey();
401 }
402
403 document.addUID(PORTLET_ID, classPK);
404
405 String articleDefaultLanguageId = LocalizationUtil.getDefaultLanguageId(
406 article.getContent());
407
408 Locale defaultLocale = LocaleUtil.getSiteDefault();
409
410 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
411
412 String[] languageIds = getLanguageIds(
413 defaultLanguageId, article.getContent());
414
415 for (String languageId : languageIds) {
416 String content = extractContent(article, languageId);
417
418 String description = article.getDescription(languageId);
419
420 String title = article.getTitle(languageId);
421
422 if (languageId.equals(articleDefaultLanguageId)) {
423 document.addText(Field.CONTENT, content);
424 document.addText(Field.DESCRIPTION, description);
425 document.addText(Field.TITLE, title);
426 document.addText("defaultLanguageId", languageId);
427 }
428
429 document.addText(
430 Field.CONTENT.concat(StringPool.UNDERLINE).concat(languageId),
431 content);
432 document.addText(
433 Field.DESCRIPTION.concat(StringPool.UNDERLINE).concat(
434 languageId), description);
435 document.addText(
436 Field.TITLE.concat(StringPool.UNDERLINE).concat(languageId),
437 title);
438 }
439
440 document.addKeyword(Field.FOLDER_ID, article.getFolderId());
441 document.addKeyword(Field.LAYOUT_UUID, article.getLayoutUuid());
442 document.addKeyword(
443 Field.TREE_PATH,
444 StringUtil.split(article.getTreePath(), CharPool.SLASH));
445 document.addKeyword(Field.TYPE, article.getType());
446 document.addKeyword(Field.VERSION, article.getVersion());
447
448 String articleId = article.getArticleId();
449
450 if (article.isInTrash()) {
451 articleId = TrashUtil.getOriginalTitle(articleId);
452 }
453
454 document.addKeyword("articleId", articleId);
455 document.addKeyword("ddmStructureKey", article.getStructureId());
456 document.addKeyword("ddmTemplateKey", article.getTemplateId());
457 document.addDate("displayDate", article.getDisplayDate());
458
459 addDDMStructureAttributes(document, article);
460
461 boolean head = isHead(article);
462 boolean headListable = isHeadListable(article);
463
464 document.addKeyword("head", head);
465 document.addKeyword("headListable", headListable);
466
467 return document;
468 }
469
470 @Override
471 protected String doGetSortField(String orderByCol) {
472 if (orderByCol.equals("display-date")) {
473 return "displayDate";
474 }
475 else if (orderByCol.equals("id")) {
476 return Field.ENTRY_CLASS_PK;
477 }
478 else if (orderByCol.equals("modified-date")) {
479 return Field.MODIFIED_DATE;
480 }
481 else if (orderByCol.equals("title")) {
482 return Field.TITLE;
483 }
484 else {
485 return orderByCol;
486 }
487 }
488
489 @Override
490 protected Summary doGetSummary(
491 Document document, Locale locale, String snippet, PortletURL portletURL,
492 PortletRequest portletRequest, PortletResponse portletReponse) {
493
494 Locale defaultLocale = LocaleUtil.fromLanguageId(
495 document.get("defaultLanguageId"));
496
497 Locale snippetLocale = getSnippetLocale(document, locale);
498
499 String localizedTitleName = DocumentImpl.getLocalizedName(
500 locale, Field.TITLE);
501
502 if ((snippetLocale == null) &&
503 (document.getField(localizedTitleName) == null)) {
504
505 snippetLocale = defaultLocale;
506 }
507 else {
508 snippetLocale = locale;
509 }
510
511 String title = document.get(
512 snippetLocale, Field.SNIPPET + StringPool.UNDERLINE + Field.TITLE,
513 Field.TITLE);
514
515 if (Validator.isNull(title) && !snippetLocale.equals(defaultLocale)) {
516 title = document.get(
517 defaultLocale,
518 Field.SNIPPET + StringPool.UNDERLINE + Field.TITLE,
519 Field.TITLE);
520 }
521
522 String ddmStructureKey = document.get("ddmStructureKey");
523
524 String content = StringPool.BLANK;
525
526 if (Validator.isNull(ddmStructureKey)) {
527 content = getBasicContentSummary(document, snippetLocale);
528
529 if (Validator.isNull(content) &&
530 !snippetLocale.equals(defaultLocale)) {
531
532 content = getBasicContentSummary(document, defaultLocale);
533 }
534 }
535 else {
536 content = getDDMContentSummary(
537 document, snippetLocale, portletRequest, portletReponse);
538
539 if (Validator.isNull(content) &&
540 !snippetLocale.equals(defaultLocale)) {
541
542 content = getDDMContentSummary(
543 document, defaultLocale, portletRequest, portletReponse);
544 }
545 }
546
547 String groupId = document.get(Field.GROUP_ID);
548 String articleId = document.get("articleId");
549 String version = document.get(Field.VERSION);
550
551 portletURL.setParameter("struts_action", "/journal/edit_article");
552 portletURL.setParameter("groupId", groupId);
553 portletURL.setParameter("articleId", articleId);
554 portletURL.setParameter("version", version);
555
556 Summary summary = new Summary(
557 snippetLocale, title, content, portletURL);
558
559 summary.setMaxContentLength(200);
560
561 return summary;
562 }
563
564 public void doReindex(JournalArticle article, boolean allVersions)
565 throws Exception {
566
567 if (PortalUtil.getClassNameId(DDMStructure.class) ==
568 article.getClassNameId()) {
569
570 Document document = getDocument(article);
571
572 SearchEngineUtil.deleteDocument(
573 getSearchEngineId(), article.getCompanyId(),
574 document.get(Field.UID), isCommitImmediately());
575
576 return;
577 }
578
579 if (allVersions || !PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
580 reindexArticleVersions(article);
581 }
582 else {
583 SearchEngineUtil.updateDocument(
584 getSearchEngineId(), article.getCompanyId(),
585 getDocument(article), isCommitImmediately());
586 }
587 }
588
589 @Override
590 protected void doReindex(Object obj) throws Exception {
591 JournalArticle article = (JournalArticle)obj;
592
593 doReindex(article, true);
594 }
595
596 @Override
597 protected void doReindex(String className, long classPK) throws Exception {
598 JournalArticle article =
599 JournalArticleLocalServiceUtil.fetchJournalArticle(classPK);
600
601 if (article == null) {
602 article = JournalArticleLocalServiceUtil.fetchLatestArticle(
603 classPK);
604 }
605
606 if (article != null) {
607 doReindex(article);
608 }
609 }
610
611 @Override
612 protected void doReindex(String[] ids) throws Exception {
613 long companyId = GetterUtil.getLong(ids[0]);
614
615 reindexArticles(companyId);
616 }
617
618 @Override
619 protected void doReindexDDMStructures(List<Long> ddmStructureIds)
620 throws Exception {
621
622 String[] ddmStructureKeys = new String[ddmStructureIds.size()];
623
624 for (int i = 0; i < ddmStructureIds.size(); i++) {
625 long structureId = ddmStructureIds.get(i);
626
627 DDMStructure ddmStructure =
628 DDMStructureLocalServiceUtil.getDDMStructure(structureId);
629
630 ddmStructureKeys[i] = ddmStructure.getStructureKey();
631 }
632
633 List<JournalArticle> articles =
634 JournalArticleLocalServiceUtil.
635 getIndexableArticlesByDDMStructureKey(ddmStructureKeys);
636
637 for (JournalArticle article : articles) {
638 doReindex(article, false);
639 }
640 }
641
642 protected String extractBasicContent(
643 JournalArticle article, String languageId) {
644
645 String content = article.getContentByLocale(languageId);
646
647 content = StringUtil.replace(content, "<![CDATA[", StringPool.BLANK);
648 content = StringUtil.replace(content, "]]>", StringPool.BLANK);
649 content = StringUtil.replace(content, "&", "&");
650 content = StringUtil.replace(content, "<", "<");
651 content = StringUtil.replace(content, ">", ">");
652
653 content = HtmlUtil.extractText(content);
654
655 return content;
656 }
657
658 protected String extractContent(JournalArticle article, String languageId)
659 throws Exception {
660
661 if (Validator.isNotNull(article.getStructureId())) {
662 return extractDDMContent(article, languageId);
663 }
664
665 return extractBasicContent(article, languageId);
666 }
667
668 protected String extractDDMContent(
669 JournalArticle article, String languageId)
670 throws Exception {
671
672 if (Validator.isNull(article.getStructureId())) {
673 return StringPool.BLANK;
674 }
675
676 DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
677 article.getGroupId(),
678 PortalUtil.getClassNameId(JournalArticle.class),
679 article.getStructureId(), true);
680
681 if (ddmStructure == null) {
682 return StringPool.BLANK;
683 }
684
685 Fields fields = null;
686
687 try {
688 fields = JournalConverterUtil.getDDMFields(
689 ddmStructure, article.getContent());
690 }
691 catch (Exception e) {
692 return StringPool.BLANK;
693 }
694
695 if (fields == null) {
696 return StringPool.BLANK;
697 }
698
699 return DDMIndexerUtil.extractAttributes(
700 ddmStructure, fields, LocaleUtil.fromLanguageId(languageId));
701 }
702
703 protected JournalArticle fetchLatestIndexableArticleVersion(
704 long resourcePrimKey)
705 throws SystemException {
706
707 JournalArticle latestIndexableArticle =
708 JournalArticleLocalServiceUtil.fetchLatestArticle(
709 resourcePrimKey,
710 new int[] {
711 WorkflowConstants.STATUS_APPROVED,
712 WorkflowConstants.STATUS_IN_TRASH
713 });
714
715 if (latestIndexableArticle == null) {
716 latestIndexableArticle =
717 JournalArticleLocalServiceUtil.fetchLatestArticle(
718 resourcePrimKey);
719 }
720
721 return latestIndexableArticle;
722 }
723
724 protected Collection<Document> getArticleVersions(JournalArticle article)
725 throws PortalException, SystemException {
726
727 Collection<Document> documents = new ArrayList<Document>();
728
729 List<JournalArticle> articles = null;
730
731 if (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
732 articles =
733 JournalArticleLocalServiceUtil.getArticlesByResourcePrimKey(
734 article.getResourcePrimKey());
735 }
736 else {
737 articles = new ArrayList<JournalArticle>();
738
739 JournalArticle latestIndexableArticle =
740 fetchLatestIndexableArticleVersion(
741 article.getResourcePrimKey());
742
743 if (latestIndexableArticle != null) {
744 articles.add(latestIndexableArticle);
745 }
746 }
747
748 for (JournalArticle curArticle : articles) {
749 Document document = getDocument(curArticle);
750
751 documents.add(document);
752 }
753
754 return documents;
755 }
756
757 protected String getBasicContentSummary(
758 Document document, Locale snippetLocale) {
759
760 String prefix = Field.SNIPPET + StringPool.UNDERLINE;
761
762 String content = document.get(
763 snippetLocale, prefix + Field.DESCRIPTION, prefix + Field.CONTENT);
764
765 if (Validator.isBlank(content)) {
766 content = document.get(
767 prefix + Field.DESCRIPTION, prefix + Field.CONTENT);
768 }
769
770 if (Validator.isBlank(content)) {
771 content = document.get(
772 snippetLocale, Field.DESCRIPTION, Field.CONTENT);
773 }
774
775 if (content.length() > 200) {
776 content = StringUtil.shorten(content, 200);
777 }
778
779 return content;
780 }
781
782 protected String getDDMContentSummary(
783 Document document, Locale snippetLocale, PortletRequest portletRequest,
784 PortletResponse portletResponse) {
785
786 String content = StringPool.BLANK;
787
788 if ((portletRequest == null) || (portletResponse == null)) {
789 return content;
790 }
791
792 try {
793 long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
794 String articleId = document.get("articleId");
795 double version = GetterUtil.getDouble(document.get(Field.VERSION));
796
797 ThemeDisplay themeDisplay =
798 (ThemeDisplay)portletRequest.getAttribute(
799 WebKeys.THEME_DISPLAY);
800
801 String xmlRequest = PortletRequestUtil.toXML(
802 portletRequest, portletResponse);
803
804 JournalArticleDisplay articleDisplay =
805 JournalContentUtil.getDisplay(
806 groupId, articleId, version, null, Constants.VIEW,
807 LocaleUtil.toLanguageId(snippetLocale), themeDisplay, 1,
808 xmlRequest);
809
810 content = articleDisplay.getDescription();
811
812 if (Validator.isNull(content)) {
813 content = HtmlUtil.extractText(articleDisplay.getContent());
814 }
815 }
816 catch (Exception e) {
817 if (_log.isDebugEnabled()) {
818 _log.debug(e, e);
819 }
820 }
821
822 return content;
823 }
824
825 protected String[] getLanguageIds(
826 String defaultLanguageId, String content) {
827
828 String[] languageIds = LocalizationUtil.getAvailableLanguageIds(
829 content);
830
831 if (languageIds.length == 0) {
832 languageIds = new String[] {defaultLanguageId};
833 }
834
835 return languageIds;
836 }
837
838 @Override
839 protected String getPortletId(SearchContext searchContext) {
840 return PORTLET_ID;
841 }
842
843 protected boolean isHead(JournalArticle article) throws SystemException {
844 JournalArticle latestArticle =
845 JournalArticleLocalServiceUtil.fetchLatestArticle(
846 article.getResourcePrimKey(),
847 new int[] {
848 WorkflowConstants.STATUS_APPROVED,
849 WorkflowConstants.STATUS_IN_TRASH
850 });
851
852 if ((latestArticle != null) && !latestArticle.isIndexable()) {
853 return false;
854 }
855 else if ((latestArticle != null) &&
856 (article.getId() == latestArticle.getId())) {
857
858 return true;
859 }
860
861 return false;
862 }
863
864 protected boolean isHeadListable(JournalArticle article)
865 throws SystemException {
866
867 JournalArticle latestArticle =
868 JournalArticleLocalServiceUtil.fetchLatestArticle(
869 article.getResourcePrimKey(),
870 new int[] {
871 WorkflowConstants.STATUS_APPROVED,
872 WorkflowConstants.STATUS_IN_TRASH,
873 WorkflowConstants.STATUS_SCHEDULED
874 });
875
876 if ((latestArticle != null) &&
877 (article.getId() == latestArticle.getId())) {
878
879 return true;
880 }
881
882 return false;
883 }
884
885 protected void reindexArticles(long companyId)
886 throws PortalException, SystemException {
887
888 ActionableDynamicQuery actionableDynamicQuery =
889 new JournalArticleActionableDynamicQuery() {
890
891 @Override
892 protected void performAction(Object object) throws SystemException {
893
894 JournalArticle article = (JournalArticle)object;
895
896 if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
897 if (article.getResourcePrimKey() ==
898 _processedArticleResourcePrimKey) {
899
900 return;
901 }
902
903 _processedArticleResourcePrimKey =
904 article.getResourcePrimKey();
905
906 JournalArticle latestIndexableArticle =
907 fetchLatestIndexableArticleVersion(
908 article.getResourcePrimKey());
909
910 if (latestIndexableArticle == null) {
911 return;
912 }
913
914 article = latestIndexableArticle;
915 }
916
917 try {
918 Document document = getDocument(article);
919
920 addDocument(document);
921 }
922 catch (PortalException pe) {
923 if (_log.isWarnEnabled()) {
924 _log.warn(
925 "Unable to index journal article " +
926 article.getId(),
927 pe);
928 }
929 }
930 }
931
932 @Override
933 protected void addOrderCriteria(DynamicQuery dynamicQuery) {
934 if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
935 OrderFactoryUtil.addOrderByComparator(
936 dynamicQuery, new ArticleResourcePKComparator(true));
937 }
938 }
939
940 private long _processedArticleResourcePrimKey;
941
942 };
943
944 actionableDynamicQuery.setCompanyId(companyId);
945 actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
946
947 actionableDynamicQuery.performActions();
948 }
949
950 protected void reindexArticleVersions(JournalArticle article)
951 throws PortalException, SystemException {
952
953 SearchEngineUtil.updateDocuments(
954 getSearchEngineId(), article.getCompanyId(),
955 getArticleVersions(article), isCommitImmediately());
956 }
957
958 private static Log _log = LogFactoryUtil.getLog(
959 JournalArticleIndexer.class);
960
961 }