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