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