001    /**
002     * Copyright (c) 2000-2012 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.Junction;
020    import com.liferay.portal.kernel.dao.orm.Property;
021    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
022    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.search.BaseIndexer;
028    import com.liferay.portal.kernel.search.BooleanClauseOccur;
029    import com.liferay.portal.kernel.search.BooleanQuery;
030    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
031    import com.liferay.portal.kernel.search.Document;
032    import com.liferay.portal.kernel.search.DocumentImpl;
033    import com.liferay.portal.kernel.search.Field;
034    import com.liferay.portal.kernel.search.SearchContext;
035    import com.liferay.portal.kernel.search.SearchEngineUtil;
036    import com.liferay.portal.kernel.search.Summary;
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.StringBundler;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.Validator;
045    import com.liferay.portal.kernel.workflow.WorkflowConstants;
046    import com.liferay.portal.kernel.xml.DocumentException;
047    import com.liferay.portal.kernel.xml.Element;
048    import com.liferay.portal.kernel.xml.Node;
049    import com.liferay.portal.kernel.xml.SAXReaderUtil;
050    import com.liferay.portal.util.PortalUtil;
051    import com.liferay.portal.util.PortletKeys;
052    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
053    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
054    import com.liferay.portlet.journal.NoSuchStructureException;
055    import com.liferay.portlet.journal.model.JournalArticle;
056    import com.liferay.portlet.journal.model.JournalArticleConstants;
057    import com.liferay.portlet.journal.model.JournalFolderConstants;
058    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
059    import com.liferay.portlet.journal.service.JournalFolderServiceUtil;
060    import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
061    import com.liferay.portlet.trash.util.TrashUtil;
062    
063    import java.util.ArrayList;
064    import java.util.Collection;
065    import java.util.LinkedHashMap;
066    import java.util.LinkedList;
067    import java.util.List;
068    import java.util.Locale;
069    
070    import javax.portlet.PortletURL;
071    
072    /**
073     * @author Brian Wing Shun Chan
074     * @author Harry Mark
075     * @author Bruno Farache
076     * @author Raymond Augé
077     * @author Hugo Huijser
078     */
079    public class JournalArticleIndexer extends BaseIndexer {
080    
081            public static final String[] CLASS_NAMES = {JournalArticle.class.getName()};
082    
083            public static final String PORTLET_ID = PortletKeys.JOURNAL;
084    
085            public JournalArticleIndexer() {
086                    setPermissionAware(true);
087            }
088    
089            public String[] getClassNames() {
090                    return CLASS_NAMES;
091            }
092    
093            public String getPortletId() {
094                    return PORTLET_ID;
095            }
096    
097            @Override
098            public void postProcessContextQuery(
099                            BooleanQuery contextQuery, SearchContext searchContext)
100                    throws Exception {
101    
102                    Long classNameId = (Long)searchContext.getAttribute(
103                            Field.CLASS_NAME_ID);
104    
105                    if ((classNameId != null) && (classNameId.longValue() != 0)) {
106                            contextQuery.addRequiredTerm("classNameId", classNameId.toString());
107                    }
108    
109                    int status = GetterUtil.getInteger(
110                            searchContext.getAttribute(Field.STATUS),
111                            WorkflowConstants.STATUS_APPROVED);
112    
113                    if (status != WorkflowConstants.STATUS_ANY) {
114                            contextQuery.addRequiredTerm(Field.STATUS, status);
115                    }
116    
117                    long[] folderIds = searchContext.getFolderIds();
118    
119                    if ((folderIds != null) && (folderIds.length > 0)) {
120                            if (folderIds[0] ==
121                                            JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
122    
123                                    return;
124                            }
125    
126                            BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create(
127                                    searchContext);
128    
129                            for (long folderId : folderIds) {
130                                    try {
131                                            JournalFolderServiceUtil.getFolder(folderId);
132                                    }
133                                    catch (Exception e) {
134                                            continue;
135                                    }
136    
137                                    folderIdsQuery.addTerm(Field.FOLDER_ID, folderId);
138                            }
139    
140                            contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
141                    }
142    
143                    String articleType = (String)searchContext.getAttribute("articleType");
144    
145                    if (Validator.isNotNull(articleType)) {
146                            contextQuery.addRequiredTerm(Field.TYPE, articleType);
147                    }
148    
149                    String ddmStructureKey = (String)searchContext.getAttribute(
150                            "ddmStructureKey");
151    
152                    if (Validator.isNotNull(ddmStructureKey)) {
153                            contextQuery.addRequiredTerm("ddmStructureKey", ddmStructureKey);
154                    }
155    
156                    String ddmTemplateKey = (String)searchContext.getAttribute(
157                            "ddmTemplateKey");
158    
159                    if (Validator.isNotNull(ddmTemplateKey)) {
160                            contextQuery.addRequiredTerm("ddmTemplateKey", ddmTemplateKey);
161                    }
162            }
163    
164            @Override
165            public void postProcessSearchQuery(
166                            BooleanQuery searchQuery, SearchContext searchContext)
167                    throws Exception {
168    
169                    addSearchTerm(searchQuery, searchContext, Field.CLASS_PK, false);
170                    addSearchLocalizedTerm(
171                            searchQuery, searchContext, Field.CONTENT, false);
172                    addSearchLocalizedTerm(
173                            searchQuery, searchContext, Field.DESCRIPTION, false);
174                    addSearchTerm(searchQuery, searchContext, Field.ENTRY_CLASS_PK, false);
175                    addSearchLocalizedTerm(searchQuery, searchContext, Field.TITLE, false);
176                    addSearchTerm(searchQuery, searchContext, Field.TYPE, false);
177                    addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
178    
179                    addSearchTerm(searchQuery, searchContext, "articleId", false);
180    
181                    LinkedHashMap<String, Object> params =
182                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
183    
184                    if (params != null) {
185                            String expandoAttributes = (String)params.get("expandoAttributes");
186    
187                            if (Validator.isNotNull(expandoAttributes)) {
188                                    addSearchExpando(searchQuery, searchContext, expandoAttributes);
189                            }
190                    }
191            }
192    
193            @Override
194            protected void addSearchLocalizedTerm(
195                            BooleanQuery searchQuery, SearchContext searchContext, String field,
196                            boolean like)
197                    throws Exception {
198    
199                    if (Validator.isNull(field)) {
200                            return;
201                    }
202    
203                    String value = String.valueOf(searchContext.getAttribute(field));
204    
205                    if (Validator.isNull(value)) {
206                            value = searchContext.getKeywords();
207                    }
208    
209                    if (Validator.isNull(value)) {
210                            return;
211                    }
212    
213                    field = DocumentImpl.getLocalizedName(searchContext.getLocale(), field);
214    
215                    if (searchContext.isAndSearch()) {
216                            searchQuery.addRequiredTerm(field, value, like);
217                    }
218                    else {
219                            searchQuery.addTerm(field, value, like);
220                    }
221            }
222    
223            @Override
224            protected void doDelete(Object obj) throws Exception {
225                    JournalArticle article = (JournalArticle)obj;
226    
227                    deleteDocument(
228                            article.getCompanyId(), article.getGroupId(),
229                            article.getArticleId());
230            }
231    
232            @Override
233            protected Document doGetDocument(Object obj) throws Exception {
234                    JournalArticle article = (JournalArticle)obj;
235    
236                    Document document = getBaseModelDocument(PORTLET_ID, article);
237    
238                    document.addUID(
239                            PORTLET_ID, article.getGroupId(), article.getArticleId());
240    
241                    Locale defaultLocale = LocaleUtil.getDefault();
242    
243                    String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
244    
245                    String[] languageIds = getLanguageIds(
246                            defaultLanguageId, article.getContent());
247    
248                    for (String languageId : languageIds) {
249                            String content = extractContent(article, languageId);
250    
251                            if (languageId.equals(defaultLanguageId)) {
252                                    document.addText(Field.CONTENT, content);
253                            }
254    
255                            document.addText(
256                                    Field.CONTENT.concat(StringPool.UNDERLINE).concat(languageId),
257                                    content);
258                    }
259    
260                    document.addLocalizedText(
261                            Field.DESCRIPTION, article.getDescriptionMap());
262                    document.addKeyword(Field.FOLDER_ID, article.getFolderId());
263                    document.addLocalizedText(Field.TITLE, article.getTitleMap());
264                    document.addKeyword(Field.TYPE, article.getType());
265                    document.addKeyword(Field.VERSION, article.getVersion());
266    
267                    String articleId = article.getArticleId();
268    
269                    if (article.isInTrash()) {
270                            articleId = TrashUtil.getOriginalTitle(articleId);
271                    }
272    
273                    document.addKeyword("articleId", articleId);
274                    document.addKeyword("ddmStructureKey", article.getStructureId());
275                    document.addKeyword("ddmTemplateKey", article.getTemplateId());
276                    document.addDate("displayDate", article.getDisplayDate());
277                    document.addKeyword("layoutUuid", article.getLayoutUuid());
278    
279                    DDMStructure ddmStructure = null;
280    
281                    if (Validator.isNotNull(article.getStructureId())) {
282                            try {
283                                    ddmStructure = DDMStructureLocalServiceUtil.getStructure(
284                                            article.getGroupId(),
285                                            PortalUtil.getClassNameId(JournalArticle.class),
286                                            article.getStructureId(), true);
287                            }
288                            catch (NoSuchStructureException nsse) {
289                            }
290                    }
291    
292                    processDDMStructure(ddmStructure, document, article.getContent());
293    
294                    return document;
295            }
296    
297            @Override
298            protected String doGetSortField(String orderByCol) {
299                    if (orderByCol.equals("display-date")) {
300                            return "displayDate";
301                    }
302                    else if (orderByCol.equals("id")) {
303                            return Field.ENTRY_CLASS_PK;
304                    }
305                    else if (orderByCol.equals("modified-date")) {
306                            return Field.MODIFIED_DATE;
307                    }
308                    else if (orderByCol.equals("title")) {
309                            return Field.TITLE;
310                    }
311                    else {
312                            return orderByCol;
313                    }
314            }
315    
316            @Override
317            protected Summary doGetSummary(
318                    Document document, Locale locale, String snippet,
319                    PortletURL portletURL) {
320    
321                    Locale snippetLocale = getSnippetLocale(document, locale);
322    
323                    String prefix = Field.SNIPPET + StringPool.UNDERLINE;
324    
325                    String title = document.get(
326                            snippetLocale, prefix + Field.TITLE, Field.TITLE);
327    
328                    String content = document.get(
329                            snippetLocale, prefix + Field.DESCRIPTION, prefix + Field.CONTENT);
330    
331                    if (Validator.isBlank(content)) {
332                            content = document.get(locale, Field.DESCRIPTION, Field.CONTENT);
333    
334                            if (Validator.isBlank(content)) {
335                                    content = document.get(Field.DESCRIPTION, Field.CONTENT);
336                            }
337                    }
338    
339                    if (content.length() > 200) {
340                            content = StringUtil.shorten(content, 200);
341                    }
342    
343                    String groupId = document.get(Field.GROUP_ID);
344                    String articleId = document.get("articleId");
345                    String version = document.get(Field.VERSION);
346    
347                    portletURL.setParameter("struts_action", "/journal/edit_article");
348                    portletURL.setParameter("groupId", groupId);
349                    portletURL.setParameter("articleId", articleId);
350                    portletURL.setParameter("version", version);
351    
352                    return new Summary(snippetLocale, title, content, portletURL);
353            }
354    
355            @Override
356            protected void doReindex(Object obj) throws Exception {
357                    JournalArticle article = (JournalArticle)obj;
358    
359                    Document document = getDocument(article);
360    
361                    if (!article.isIndexable() ||
362                            (!article.isApproved() && !article.isInTrash() &&
363                             (article.getVersion() !=
364                                      JournalArticleConstants.VERSION_DEFAULT))) {
365    
366                            SearchEngineUtil.deleteDocument(
367                                    getSearchEngineId(), article.getCompanyId(),
368                                    document.get(Field.UID));
369    
370                            return;
371                    }
372    
373                    SearchEngineUtil.updateDocument(
374                            getSearchEngineId(), article.getCompanyId(), document);
375            }
376    
377            @Override
378            protected void doReindex(String className, long classPK) throws Exception {
379                    JournalArticle article =
380                            JournalArticleLocalServiceUtil.getLatestArticle(
381                                    classPK, WorkflowConstants.STATUS_APPROVED);
382    
383                    doReindex(article);
384            }
385    
386            @Override
387            protected void doReindex(String[] ids) throws Exception {
388                    long companyId = GetterUtil.getLong(ids[0]);
389    
390                    reindexArticles(companyId);
391            }
392    
393            protected String encodeFieldName(String name) {
394                    return _FIELD_NAMESPACE.concat(StringPool.FORWARD_SLASH).concat(name);
395            }
396    
397            protected String extractContent(JournalArticle article, String languageId) {
398                    String content = article.getContentByLocale(languageId);
399    
400                    if (Validator.isNotNull(article.getStructureId())) {
401                            content = extractDynamicContent(content);
402                    }
403                    else {
404                            content = extractStaticContent(content);
405                    }
406    
407                    content = HtmlUtil.extractText(content);
408    
409                    return content;
410            }
411    
412            protected String extractDynamicContent(Element rootElement) {
413                    StringBundler sb = new StringBundler();
414    
415                    List<Element> dynamicElementElements = rootElement.elements(
416                            "dynamic-element");
417    
418                    for (Element dynamicElementElement : dynamicElementElements) {
419                            String type = dynamicElementElement.attributeValue(
420                                    "type", StringPool.BLANK);
421    
422                            if (!type.equals("boolean") && !type.equals("document_library") &&
423                                    !type.equals("image") && !type.equals("list") &&
424                                    !type.equals("link_to_layout") && !type.equals("multi-list") &&
425                                    !type.equals("selection_break")) {
426    
427                                    Element dynamicContentElement = dynamicElementElement.element(
428                                            "dynamic-content");
429    
430                                    if (dynamicContentElement != null) {
431                                            String dynamicContent = dynamicContentElement.getText();
432    
433                                            sb.append(dynamicContent);
434                                            sb.append(StringPool.SPACE);
435                                    }
436                            }
437    
438                            sb.append(extractDynamicContent(dynamicElementElement));
439                    }
440    
441                    return sb.toString();
442            }
443    
444            protected String extractDynamicContent(String content) {
445                    try {
446                            com.liferay.portal.kernel.xml.Document document =
447                                    SAXReaderUtil.read(content);
448    
449                            Element rootElement = document.getRootElement();
450    
451                            return extractDynamicContent(rootElement);
452                    }
453                    catch (DocumentException de) {
454                            _log.error(de);
455                    }
456    
457                    return StringPool.BLANK;
458            }
459    
460            protected String extractStaticContent(String content) {
461                    content = StringUtil.replace(content, "<![CDATA[", StringPool.BLANK);
462                    content = StringUtil.replace(content, "]]>", StringPool.BLANK);
463                    content = StringUtil.replace(content, "&amp;", "&");
464                    content = StringUtil.replace(content, "&lt;", "<");
465                    content = StringUtil.replace(content, "&gt;", ">");
466    
467                    return content;
468            }
469    
470            protected String[] getLanguageIds(
471                    String defaultLanguageId, String content) {
472    
473                    String[] languageIds = LocalizationUtil.getAvailableLocales(content);
474    
475                    if (languageIds.length == 0) {
476                            languageIds = new String[] {defaultLanguageId};
477                    }
478    
479                    return languageIds;
480            }
481    
482            @Override
483            protected String getPortletId(SearchContext searchContext) {
484                    return PORTLET_ID;
485            }
486    
487            protected void indexField(
488                    Document document, Element element, String elType, String elIndexType) {
489    
490                    if (Validator.isNull(elIndexType)) {
491                            return;
492                    }
493    
494                    com.liferay.portal.kernel.xml.Document contentDocument =
495                            element.getDocument();
496    
497                    Element rootElement = contentDocument.getRootElement();
498    
499                    String defaultLocale = GetterUtil.getString(
500                            rootElement.attributeValue("default-locale"));
501    
502                    String name = encodeFieldName(element.attributeValue("name"));
503    
504                    List<Element> dynamicContentElements = element.elements(
505                            "dynamic-content");
506    
507                    for (Element dynamicContentElement : dynamicContentElements) {
508                            String contentLocale = GetterUtil.getString(
509                                    dynamicContentElement.attributeValue("language-id"));
510    
511                            String[] value = new String[] {dynamicContentElement.getText()};
512    
513                            if (elType.equals("multi-list")) {
514                                    List<Element> optionElements = dynamicContentElement.elements(
515                                            "option");
516    
517                                    value = new String[optionElements.size()];
518    
519                                    for (int i = 0; i < optionElements.size(); i++) {
520                                            value[i] = optionElements.get(i).getText();
521                                    }
522                            }
523    
524                            if (elIndexType.equals("keyword")) {
525                                    if (Validator.isNull(contentLocale)) {
526                                            document.addKeyword(name, value);
527                                    }
528                                    else {
529                                            if (defaultLocale.equals(contentLocale)) {
530                                                    document.addKeyword(name, value);
531                                            }
532    
533                                            document.addKeyword(
534                                                    name.concat(StringPool.UNDERLINE).concat(contentLocale),
535                                                    value);
536                                    }
537                            }
538                            else if (elIndexType.equals("text")) {
539                                    if (Validator.isNull(contentLocale)) {
540                                            document.addText(
541                                                    name, StringUtil.merge(value, StringPool.SPACE));
542                                    }
543                                    else {
544                                            if (defaultLocale.equals(contentLocale)) {
545                                                    document.addText(
546                                                            name, StringUtil.merge(value, StringPool.SPACE));
547                                            }
548    
549                                            document.addText(
550                                                    name.concat(StringPool.UNDERLINE).concat(contentLocale),
551                                                    StringUtil.merge(value, StringPool.SPACE));
552                                    }
553                            }
554                    }
555            }
556    
557            protected void processDDMStructure(
558                            com.liferay.portal.kernel.xml.Document ddmStructureDocument,
559                            Document document, Element rootElement)
560                    throws Exception {
561    
562                    LinkedList<Element> queue = new LinkedList<Element>(
563                            rootElement.elements());
564    
565                    Element element = null;
566    
567                    while ((element = queue.poll()) != null) {
568                            String elName = element.attributeValue("name", StringPool.BLANK);
569                            String elType = element.attributeValue("type", StringPool.BLANK);
570                            String elIndexType = element.attributeValue(
571                                    "index-type", StringPool.BLANK);
572    
573                            if (ddmStructureDocument != null) {
574                                    String path = element.getPath();
575    
576                                    path = path.concat("[@name=").concat(
577                                            HtmlUtil.escapeXPathAttribute(elName)).concat("]");
578    
579                                    Node ddmStructureNode = ddmStructureDocument.selectSingleNode(
580                                            path);
581    
582                                    if (ddmStructureNode != null) {
583                                            Element ddmStructureElement = (Element)ddmStructureNode;
584    
585                                            elType = ddmStructureElement.attributeValue(
586                                                    "type", StringPool.BLANK);
587                                            elIndexType = ddmStructureElement.attributeValue(
588                                                    "indexType", StringPool.BLANK);
589                                    }
590                            }
591    
592                            if (Validator.isNotNull(elType)) {
593                                    indexField(document, element, elType, elIndexType);
594                            }
595    
596                            queue.addAll(element.elements());
597                    }
598            }
599    
600            protected void processDDMStructure(
601                    DDMStructure ddmStructure, Document document, String content) {
602    
603                    try {
604                            com.liferay.portal.kernel.xml.Document ddmStructureDocument = null;
605    
606                            if (ddmStructure != null) {
607                                    ddmStructureDocument = SAXReaderUtil.read(
608                                            ddmStructure.getXsd());
609                            }
610    
611                            com.liferay.portal.kernel.xml.Document contentDocument =
612                                    SAXReaderUtil.read(content);
613    
614                            Element rootElement = contentDocument.getRootElement();
615    
616                            processDDMStructure(ddmStructureDocument, document, rootElement);
617                    }
618                    catch (Exception e) {
619                            _log.error(e, e);
620                    }
621            }
622    
623            protected void reindexArticles(long companyId)
624                    throws PortalException, SystemException {
625    
626                    final Collection<Document> documents = new ArrayList<Document>();
627    
628                    ActionableDynamicQuery actionableDynamicQuery =
629                            new JournalArticleActionableDynamicQuery() {
630    
631                            @Override
632                            protected void addCriteria(DynamicQuery dynamicQuery) {
633                                    Junction junction = RestrictionsFactoryUtil.disjunction();
634    
635                                    Junction approvedArticlesJunction =
636                                            RestrictionsFactoryUtil.conjunction();
637    
638                                    Property statusProperty = PropertyFactoryUtil.forName("status");
639    
640                                    approvedArticlesJunction.add(
641                                            statusProperty.eq(WorkflowConstants.STATUS_APPROVED));
642    
643                                    junction.add(approvedArticlesJunction);
644    
645                                    Junction draftArticlesJunction =
646                                            RestrictionsFactoryUtil.conjunction();
647    
648                                    Property versionProperty = PropertyFactoryUtil.forName(
649                                            "version");
650    
651                                    draftArticlesJunction.add(
652                                            versionProperty.eq(
653                                                    JournalArticleConstants.VERSION_DEFAULT));
654    
655                                    draftArticlesJunction.add(
656                                            statusProperty.eq(WorkflowConstants.STATUS_DRAFT));
657    
658                                    junction.add(draftArticlesJunction);
659    
660                                    dynamicQuery.add(junction);
661    
662                                    Property indexableProperty = PropertyFactoryUtil.forName(
663                                            "indexable");
664    
665                                    dynamicQuery.add(indexableProperty.eq(true));
666                            }
667    
668                            @Override
669                            protected void performAction(Object object)
670                                    throws PortalException, SystemException {
671    
672                                    JournalArticle article = (JournalArticle)object;
673    
674                                    if (article.isApproved()) {
675                                            JournalArticle latestArticle =
676                                                    JournalArticleLocalServiceUtil.getLatestArticle(
677                                                            article.getResourcePrimKey(),
678                                                            WorkflowConstants.STATUS_APPROVED);
679    
680                                            if (!latestArticle.isIndexable()) {
681                                                    return;
682                                            }
683                                    }
684    
685                                    Document document = getDocument(article);
686    
687                                    documents.add(document);
688                            }
689    
690                    };
691    
692                    actionableDynamicQuery.setCompanyId(companyId);
693    
694                    actionableDynamicQuery.performActions();
695    
696                    SearchEngineUtil.updateDocuments(
697                            getSearchEngineId(), companyId, documents);
698            }
699    
700            private static final String _FIELD_NAMESPACE = "web_content";
701    
702            private static Log _log = LogFactoryUtil.getLog(
703                    JournalArticleIndexer.class);
704    
705    }