001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.Property;
020    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.portlet.PortletRequestModel;
025    import com.liferay.portal.kernel.search.BaseIndexer;
026    import com.liferay.portal.kernel.search.BooleanClauseOccur;
027    import com.liferay.portal.kernel.search.BooleanQuery;
028    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
029    import com.liferay.portal.kernel.search.Document;
030    import com.liferay.portal.kernel.search.DocumentImpl;
031    import com.liferay.portal.kernel.search.Field;
032    import com.liferay.portal.kernel.search.SearchContext;
033    import com.liferay.portal.kernel.search.SearchEngineUtil;
034    import com.liferay.portal.kernel.search.Summary;
035    import com.liferay.portal.kernel.util.CharPool;
036    import com.liferay.portal.kernel.util.Constants;
037    import com.liferay.portal.kernel.util.GetterUtil;
038    import com.liferay.portal.kernel.util.HtmlUtil;
039    import com.liferay.portal.kernel.util.LocaleUtil;
040    import com.liferay.portal.kernel.util.LocalizationUtil;
041    import com.liferay.portal.kernel.util.StringPool;
042    import com.liferay.portal.kernel.util.StringUtil;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.kernel.util.WebKeys;
045    import com.liferay.portal.kernel.workflow.WorkflowConstants;
046    import com.liferay.portal.security.permission.ActionKeys;
047    import com.liferay.portal.security.permission.PermissionChecker;
048    import com.liferay.portal.theme.ThemeDisplay;
049    import com.liferay.portal.util.PortalUtil;
050    import com.liferay.portal.util.PortletKeys;
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.DDMIndexerUtil;
057    import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
058    import com.liferay.portlet.journal.model.JournalArticle;
059    import com.liferay.portlet.journal.model.JournalArticleDisplay;
060    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
061    import com.liferay.portlet.journal.service.permission.JournalArticlePermission;
062    import com.liferay.portlet.trash.util.TrashUtil;
063    
064    import java.io.Serializable;
065    
066    import java.util.ArrayList;
067    import java.util.Collection;
068    import java.util.LinkedHashMap;
069    import java.util.List;
070    import java.util.Locale;
071    
072    import javax.portlet.PortletRequest;
073    import javax.portlet.PortletResponse;
074    import javax.portlet.PortletURL;
075    
076    /**
077     * @author Brian Wing Shun Chan
078     * @author Harry Mark
079     * @author Bruno Farache
080     * @author Raymond Aug??
081     * @author Hugo Huijser
082     * @author Tibor Lipusz
083     */
084    public class JournalArticleIndexer extends BaseIndexer {
085    
086            public static final String[] CLASS_NAMES = {JournalArticle.class.getName()};
087    
088            public static final String PORTLET_ID = PortletKeys.JOURNAL;
089    
090            public JournalArticleIndexer() {
091                    setDefaultSelectedFieldNames(
092                            Field.ARTICLE_ID, Field.COMPANY_ID, Field.DEFAULT_LANGUAGE_ID,
093                            Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.GROUP_ID,
094                            Field.VERSION, Field.UID);
095                    setDefaultSelectedLocalizedFieldNames(
096                            Field.CONTENT, Field.DESCRIPTION, Field.TITLE);
097                    setFilterSearch(true);
098                    setPermissionAware(true);
099                    setSelectAllLocales(true);
100            }
101    
102            @Override
103            public String[] getClassNames() {
104                    return CLASS_NAMES;
105            }
106    
107            @Override
108            public String getPortletId() {
109                    return PORTLET_ID;
110            }
111    
112            @Override
113            public boolean hasPermission(
114                            PermissionChecker permissionChecker, String entryClassName,
115                            long entryClassPK, String actionId)
116                    throws Exception {
117    
118                    return JournalArticlePermission.contains(
119                            permissionChecker, entryClassPK, ActionKeys.VIEW);
120            }
121    
122            @Override
123            public boolean isVisible(long classPK, int status) throws Exception {
124                    List<JournalArticle> articles =
125                            JournalArticleLocalServiceUtil.getArticlesByResourcePrimKey(
126                                    classPK);
127    
128                    for (JournalArticle article : articles) {
129                            if (isVisible(article.getStatus(), status)) {
130                                    return true;
131                            }
132                    }
133    
134                    return false;
135            }
136    
137            @Override
138            public void postProcessContextQuery(
139                            BooleanQuery contextQuery, SearchContext searchContext)
140                    throws Exception {
141    
142                    Long classNameId = (Long)searchContext.getAttribute(
143                            Field.CLASS_NAME_ID);
144    
145                    if ((classNameId != null) && (classNameId.longValue() != 0)) {
146                            contextQuery.addRequiredTerm(
147                                    Field.CLASS_NAME_ID, classNameId.toString());
148                    }
149    
150                    addStatus(contextQuery, searchContext);
151    
152                    addSearchClassTypeIds(contextQuery, searchContext);
153    
154                    String ddmStructureFieldName = (String)searchContext.getAttribute(
155                            "ddmStructureFieldName");
156                    Serializable ddmStructureFieldValue = searchContext.getAttribute(
157                            "ddmStructureFieldValue");
158    
159                    if (Validator.isNotNull(ddmStructureFieldName) &&
160                            Validator.isNotNull(ddmStructureFieldValue)) {
161    
162                            String[] ddmStructureFieldNameParts = StringUtil.split(
163                                    ddmStructureFieldName, StringPool.DOUBLE_UNDERLINE);
164    
165                            DDMStructure structure = DDMStructureLocalServiceUtil.getStructure(
166                                    GetterUtil.getLong(ddmStructureFieldNameParts[1]));
167    
168                            String fieldName = StringUtil.replaceLast(
169                                    ddmStructureFieldNameParts[2],
170                                    StringPool.UNDERLINE.concat(
171                                            LocaleUtil.toLanguageId(searchContext.getLocale())),
172                                    StringPool.BLANK);
173    
174                            try {
175                                    ddmStructureFieldValue = DDMUtil.getIndexedFieldValue(
176                                            ddmStructureFieldValue, structure.getFieldType(fieldName));
177                            }
178                            catch (StructureFieldException sfe) {
179                            }
180    
181                            contextQuery.addRequiredTerm(
182                                    ddmStructureFieldName,
183                                    StringPool.QUOTE + ddmStructureFieldValue + StringPool.QUOTE);
184                    }
185    
186                    String articleType = (String)searchContext.getAttribute("articleType");
187    
188                    if (Validator.isNotNull(articleType)) {
189                            contextQuery.addRequiredTerm(Field.TYPE, articleType);
190                    }
191    
192                    String ddmStructureKey = (String)searchContext.getAttribute(
193                            "ddmStructureKey");
194    
195                    if (Validator.isNotNull(ddmStructureKey)) {
196                            contextQuery.addRequiredTerm("ddmStructureKey", ddmStructureKey);
197                    }
198    
199                    String ddmTemplateKey = (String)searchContext.getAttribute(
200                            "ddmTemplateKey");
201    
202                    if (Validator.isNotNull(ddmTemplateKey)) {
203                            contextQuery.addRequiredTerm("ddmTemplateKey", ddmTemplateKey);
204                    }
205    
206                    boolean head = GetterUtil.getBoolean(
207                            searchContext.getAttribute("head"), Boolean.TRUE);
208                    boolean relatedClassName = GetterUtil.getBoolean(
209                            searchContext.getAttribute("relatedClassName"));
210    
211                    if (head && !relatedClassName) {
212                            contextQuery.addRequiredTerm("head", Boolean.TRUE);
213                    }
214            }
215    
216            @Override
217            public void postProcessSearchQuery(
218                            BooleanQuery searchQuery, SearchContext searchContext)
219                    throws Exception {
220    
221                    addSearchTerm(searchQuery, searchContext, Field.ARTICLE_ID, false);
222                    addSearchTerm(searchQuery, searchContext, Field.CLASS_PK, false);
223                    addSearchLocalizedTerm(
224                            searchQuery, searchContext, Field.CONTENT, false);
225                    addSearchLocalizedTerm(
226                            searchQuery, searchContext, Field.DESCRIPTION, false);
227                    addSearchTerm(searchQuery, searchContext, Field.ENTRY_CLASS_PK, false);
228                    addSearchLocalizedTerm(searchQuery, searchContext, Field.TITLE, false);
229                    addSearchTerm(searchQuery, searchContext, Field.TYPE, false);
230                    addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
231    
232                    LinkedHashMap<String, Object> params =
233                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
234    
235                    if (params != null) {
236                            String expandoAttributes = (String)params.get("expandoAttributes");
237    
238                            if (Validator.isNotNull(expandoAttributes)) {
239                                    addSearchExpando(searchQuery, searchContext, expandoAttributes);
240                            }
241                    }
242            }
243    
244            protected void addDDMStructureAttributes(
245                            Document document, JournalArticle article)
246                    throws Exception {
247    
248                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
249                            article.getGroupId(),
250                            PortalUtil.getClassNameId(JournalArticle.class),
251                            article.getDDMStructureKey(), true);
252    
253                    if (ddmStructure == null) {
254                            return;
255                    }
256    
257                    document.addKeyword(Field.CLASS_TYPE_ID, ddmStructure.getStructureId());
258    
259                    Fields fields = null;
260    
261                    try {
262                            fields = JournalConverterUtil.getDDMFields(
263                                    ddmStructure, article.getDocument());
264                    }
265                    catch (Exception e) {
266                            return;
267                    }
268    
269                    if (fields != null) {
270                            DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
271                    }
272            }
273    
274            @Override
275            protected void addSearchLocalizedTerm(
276                            BooleanQuery searchQuery, SearchContext searchContext, String field,
277                            boolean like)
278                    throws Exception {
279    
280                    if (Validator.isNull(field)) {
281                            return;
282                    }
283    
284                    String value = String.valueOf(searchContext.getAttribute(field));
285    
286                    if (Validator.isNull(value)) {
287                            value = searchContext.getKeywords();
288                    }
289    
290                    if (Validator.isNull(value)) {
291                            return;
292                    }
293    
294                    String localizedField = DocumentImpl.getLocalizedName(
295                            searchContext.getLocale(), field);
296    
297                    if (Validator.isNull(searchContext.getKeywords())) {
298                            BooleanQuery localizedQuery = BooleanQueryFactoryUtil.create(
299                                    searchContext);
300    
301                            localizedQuery.addTerm(field, value, like);
302                            localizedQuery.addTerm(localizedField, value, like);
303    
304                            BooleanClauseOccur booleanClauseOccur = BooleanClauseOccur.SHOULD;
305    
306                            if (searchContext.isAndSearch()) {
307                                    booleanClauseOccur = BooleanClauseOccur.MUST;
308                            }
309    
310                            searchQuery.add(localizedQuery, booleanClauseOccur);
311                    }
312                    else {
313                            searchQuery.addTerm(localizedField, value, like);
314                    }
315            }
316    
317            @Override
318            protected void doDelete(Object obj) throws Exception {
319                    JournalArticle article = (JournalArticle)obj;
320    
321                    long classPK = article.getId();
322    
323                    if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
324                            classPK = article.getResourcePrimKey();
325                    }
326    
327                    deleteDocument(article.getCompanyId(), classPK);
328    
329                    if (!article.isApproved()) {
330                            return;
331                    }
332    
333                    JournalArticle latestIndexableArticle =
334                            JournalArticleLocalServiceUtil.fetchLatestIndexableArticle(
335                                    article.getResourcePrimKey());
336    
337                    if ((latestIndexableArticle == null) ||
338                            (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS &&
339                             (latestIndexableArticle.getVersion() > article.getVersion()))) {
340    
341                            return;
342                    }
343    
344                    SearchEngineUtil.updateDocument(
345                            getSearchEngineId(), article.getCompanyId(),
346                            getDocument(latestIndexableArticle), isCommitImmediately());
347            }
348    
349            @Override
350            protected Document doGetDocument(Object obj) throws Exception {
351                    JournalArticle article = (JournalArticle)obj;
352    
353                    Document document = getBaseModelDocument(PORTLET_ID, article);
354    
355                    long classPK = article.getId();
356    
357                    if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
358                            classPK = article.getResourcePrimKey();
359                    }
360    
361                    document.addUID(PORTLET_ID, classPK);
362    
363                    String articleDefaultLanguageId = LocalizationUtil.getDefaultLanguageId(
364                            article.getDocument());
365    
366                    String[] languageIds = LocalizationUtil.getAvailableLanguageIds(
367                            article.getDocument());
368    
369                    for (String languageId : languageIds) {
370                            String content = extractDDMContent(article, languageId);
371    
372                            String description = article.getDescription(languageId);
373    
374                            String title = article.getTitle(languageId);
375    
376                            if (languageId.equals(articleDefaultLanguageId)) {
377                                    document.addText(Field.CONTENT, content);
378                                    document.addText(Field.DESCRIPTION, description);
379                                    document.addText(Field.TITLE, title);
380                                    document.addText("defaultLanguageId", languageId);
381                            }
382    
383                            document.addText(
384                                    LocalizationUtil.getLocalizedName(Field.CONTENT, languageId),
385                                    content);
386                            document.addText(
387                                    LocalizationUtil.getLocalizedName(
388                                            Field.DESCRIPTION, languageId),
389                                    description);
390                            document.addText(
391                                    LocalizationUtil.getLocalizedName(Field.TITLE, languageId),
392                                    title);
393                    }
394    
395                    document.addKeyword(Field.FOLDER_ID, article.getFolderId());
396    
397                    String articleId = article.getArticleId();
398    
399                    if (article.isInTrash()) {
400                            articleId = TrashUtil.getOriginalTitle(articleId);
401                    }
402    
403                    document.addKeyword(Field.ARTICLE_ID, articleId);
404    
405                    document.addKeyword(Field.LAYOUT_UUID, article.getLayoutUuid());
406                    document.addKeyword(
407                            Field.TREE_PATH,
408                            StringUtil.split(article.getTreePath(), CharPool.SLASH));
409                    document.addKeyword(Field.VERSION, article.getVersion());
410    
411                    document.addKeyword("ddmStructureKey", article.getDDMStructureKey());
412                    document.addKeyword("ddmTemplateKey", article.getDDMTemplateKey());
413                    document.addDate("displayDate", article.getDisplayDate());
414                    document.addKeyword("head", isHead(article));
415    
416                    addDDMStructureAttributes(document, article);
417    
418                    return document;
419            }
420    
421            @Override
422            protected String doGetSortField(String orderByCol) {
423                    if (orderByCol.equals("display-date")) {
424                            return "displayDate";
425                    }
426                    else if (orderByCol.equals("id")) {
427                            return Field.ENTRY_CLASS_PK;
428                    }
429                    else if (orderByCol.equals("modified-date")) {
430                            return Field.MODIFIED_DATE;
431                    }
432                    else if (orderByCol.equals("title")) {
433                            return Field.TITLE;
434                    }
435                    else {
436                            return orderByCol;
437                    }
438            }
439    
440            @Override
441            protected Summary doGetSummary(
442                    Document document, Locale locale, String snippet, PortletURL portletURL,
443                    PortletRequest portletRequest, PortletResponse portletResponse) {
444    
445                    Locale snippetLocale = getSnippetLocale(document, locale);
446    
447                    String localizedTitleName = DocumentImpl.getLocalizedName(
448                            locale, Field.TITLE);
449    
450                    if ((snippetLocale == null) ||
451                            (document.getField(localizedTitleName) == null)) {
452    
453                            snippetLocale = LocaleUtil.fromLanguageId(
454                                    document.get("defaultLanguageId"));
455                    }
456    
457                    String title = document.get(
458                            snippetLocale, Field.SNIPPET + StringPool.UNDERLINE + Field.TITLE,
459                            Field.TITLE);
460    
461                    String content = getDDMContentSummary(
462                            document, snippetLocale, portletRequest, portletResponse);
463    
464                    String articleId = document.get(Field.ARTICLE_ID);
465                    String groupId = document.get(Field.GROUP_ID);
466                    String version = document.get(Field.VERSION);
467    
468                    portletURL.setParameter("struts_action", "/journal/edit_article");
469                    portletURL.setParameter("groupId", groupId);
470                    portletURL.setParameter("articleId", articleId);
471                    portletURL.setParameter("version", version);
472    
473                    return new Summary(snippetLocale, title, content, portletURL);
474            }
475    
476            protected void doReindex(JournalArticle article, boolean allVersions)
477                    throws Exception {
478    
479                    if (PortalUtil.getClassNameId(DDMStructure.class) ==
480                                    article.getClassNameId()) {
481    
482                            Document document = getDocument(article);
483    
484                            SearchEngineUtil.deleteDocument(
485                                    getSearchEngineId(), article.getCompanyId(),
486                                    document.get(Field.UID), isCommitImmediately());
487    
488                            return;
489                    }
490    
491                    if (allVersions) {
492                            reindexArticleVersions(article);
493                    }
494                    else {
495                            SearchEngineUtil.updateDocument(
496                                    getSearchEngineId(), article.getCompanyId(),
497                                    getDocument(article), isCommitImmediately());
498                    }
499            }
500    
501            @Override
502            protected void doReindex(Object obj) throws Exception {
503                    JournalArticle article = (JournalArticle)obj;
504    
505                    doReindex(article, true);
506            }
507    
508            @Override
509            protected void doReindex(String className, long classPK) throws Exception {
510                    JournalArticle article =
511                            JournalArticleLocalServiceUtil.fetchJournalArticle(classPK);
512    
513                    if (article == null) {
514                            article =
515                                    JournalArticleLocalServiceUtil.fetchLatestIndexableArticle(
516                                            classPK);
517                    }
518    
519                    if (article != null) {
520                            doReindex(article);
521                    }
522            }
523    
524            @Override
525            protected void doReindex(String[] ids) throws Exception {
526                    long companyId = GetterUtil.getLong(ids[0]);
527    
528                    reindexArticles(companyId);
529            }
530    
531            @Override
532            protected void doReindexDDMStructures(List<Long> ddmStructureIds)
533                    throws Exception {
534    
535                    String[] ddmStructureKeys = new String[ddmStructureIds.size()];
536    
537                    for (int i = 0; i < ddmStructureIds.size(); i++) {
538                            long ddmStructureId = ddmStructureIds.get(i);
539    
540                            DDMStructure ddmStructure =
541                                    DDMStructureLocalServiceUtil.getDDMStructure(ddmStructureId);
542    
543                            ddmStructureKeys[i] = ddmStructure.getStructureKey();
544                    }
545    
546                    List<JournalArticle> articles =
547                            JournalArticleLocalServiceUtil.getStructureArticles(
548                                    ddmStructureKeys);
549    
550                    for (JournalArticle article : articles) {
551                            doReindex(article, false);
552                    }
553            }
554    
555            protected String extractDDMContent(
556                            JournalArticle article, String languageId)
557                    throws Exception {
558    
559                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
560                            article.getGroupId(),
561                            PortalUtil.getClassNameId(JournalArticle.class),
562                            article.getDDMStructureKey(), true);
563    
564                    if (ddmStructure == null) {
565                            return StringPool.BLANK;
566                    }
567    
568                    Fields fields = null;
569    
570                    try {
571                            fields = JournalConverterUtil.getDDMFields(
572                                    ddmStructure, article.getDocument());
573                    }
574                    catch (Exception e) {
575                            return StringPool.BLANK;
576                    }
577    
578                    if (fields == null) {
579                            return StringPool.BLANK;
580                    }
581    
582                    return DDMIndexerUtil.extractAttributes(
583                            ddmStructure, fields, LocaleUtil.fromLanguageId(languageId));
584            }
585    
586            protected Collection<Document> getArticleVersions(JournalArticle article)
587                    throws PortalException {
588    
589                    Collection<Document> documents = new ArrayList<Document>();
590    
591                    List<JournalArticle> articles = null;
592    
593                    if (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
594                            articles =
595                                    JournalArticleLocalServiceUtil.
596                                            getIndexableArticlesByResourcePrimKey(
597                                                    article.getResourcePrimKey());
598                    }
599                    else {
600                            articles = new ArrayList<JournalArticle>();
601    
602                            JournalArticle latestIndexableArticle =
603                                    JournalArticleLocalServiceUtil.fetchLatestIndexableArticle(
604                                            article.getResourcePrimKey());
605    
606                            if (latestIndexableArticle != null) {
607                                    articles.add(latestIndexableArticle);
608                            }
609                    }
610    
611                    for (JournalArticle curArticle : articles) {
612                            Document document = getDocument(curArticle);
613    
614                            documents.add(document);
615                    }
616    
617                    return documents;
618            }
619    
620            protected String getDDMContentSummary(
621                    Document document, Locale snippetLocale, PortletRequest portletRequest,
622                    PortletResponse portletResponse) {
623    
624                    String content = StringPool.BLANK;
625    
626                    if ((portletRequest == null) || (portletResponse == null)) {
627                            return content;
628                    }
629    
630                    try {
631                            String articleId = document.get(Field.ARTICLE_ID);
632                            long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
633                            double version = GetterUtil.getDouble(document.get(Field.VERSION));
634                            PortletRequestModel portletRequestModel = new PortletRequestModel(
635                                    portletRequest, portletResponse);
636                            ThemeDisplay themeDisplay =
637                                    (ThemeDisplay)portletRequest.getAttribute(
638                                            WebKeys.THEME_DISPLAY);
639    
640                            JournalArticleDisplay articleDisplay =
641                                    JournalContentUtil.getDisplay(
642                                            groupId, articleId, version, null, Constants.VIEW,
643                                            LocaleUtil.toLanguageId(snippetLocale), 1,
644                                            portletRequestModel, themeDisplay);
645    
646                            content = HtmlUtil.escape(articleDisplay.getDescription());
647                            content = HtmlUtil.replaceNewLine(content);
648    
649                            if (Validator.isNull(content)) {
650                                    content = HtmlUtil.extractText(articleDisplay.getContent());
651                            }
652                    }
653                    catch (Exception e) {
654                            if (_log.isDebugEnabled()) {
655                                    _log.debug(e, e);
656                            }
657                    }
658    
659                    return content;
660            }
661    
662            @Override
663            protected String getPortletId(SearchContext searchContext) {
664                    return PORTLET_ID;
665            }
666    
667            protected boolean isHead(JournalArticle article) {
668                    if (!PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
669                            return true;
670                    }
671    
672                    JournalArticle latestArticle =
673                            JournalArticleLocalServiceUtil.fetchLatestArticle(
674                                    article.getResourcePrimKey(),
675                                    new int[] {
676                                            WorkflowConstants.STATUS_APPROVED,
677                                            WorkflowConstants.STATUS_IN_TRASH});
678    
679                    if ((latestArticle != null) && !latestArticle.isIndexable()) {
680                            return false;
681                    }
682                    else if ((latestArticle != null) &&
683                                     (article.getId() == latestArticle.getId())) {
684    
685                            return true;
686                    }
687    
688                    return false;
689            }
690    
691            protected void reindexArticles(long companyId) throws PortalException {
692                    final ActionableDynamicQuery actionableDynamicQuery =
693                            JournalArticleLocalServiceUtil.getActionableDynamicQuery();
694    
695                    actionableDynamicQuery.setAddCriteriaMethod(
696                            new ActionableDynamicQuery.AddCriteriaMethod() {
697    
698                                    @Override
699                                    public void addCriteria(DynamicQuery dynamicQuery) {
700                                            if (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
701                                                    return;
702                                            }
703    
704                                            Property statusProperty = PropertyFactoryUtil.forName(
705                                                    "status");
706    
707                                            Integer[] statuses = {
708                                                    WorkflowConstants.STATUS_APPROVED,
709                                                    WorkflowConstants.STATUS_IN_TRASH
710                                            };
711    
712                                            dynamicQuery.add(statusProperty.in(statuses));
713                                    }
714    
715                            });
716                    actionableDynamicQuery.setCompanyId(companyId);
717                    actionableDynamicQuery.setPerformActionMethod(
718                            new ActionableDynamicQuery.PerformActionMethod() {
719    
720                                    @Override
721                                    public void performAction(Object object)
722                                            throws PortalException {
723    
724                                            JournalArticle article = (JournalArticle)object;
725    
726                                            Document document = getDocument(article);
727    
728                                            actionableDynamicQuery.addDocument(document);
729                                    }
730    
731                            });
732                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
733    
734                    actionableDynamicQuery.performActions();
735            }
736    
737            protected void reindexArticleVersions(JournalArticle article)
738                    throws PortalException {
739    
740                    SearchEngineUtil.updateDocuments(
741                            getSearchEngineId(), article.getCompanyId(),
742                            getArticleVersions(article), isCommitImmediately());
743            }
744    
745            private static Log _log = LogFactoryUtil.getLog(
746                    JournalArticleIndexer.class);
747    
748    }