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.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.messaging.DestinationNames;
020    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.PropsKeys;
023    import com.liferay.portal.kernel.util.PropsUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.security.permission.PermissionThreadLocal;
026    
027    import java.util.Collection;
028    import java.util.HashSet;
029    import java.util.List;
030    import java.util.Locale;
031    import java.util.Map;
032    import java.util.Set;
033    import java.util.concurrent.ConcurrentHashMap;
034    
035    /**
036     * @author Bruno Farache
037     * @author Raymond Aug??
038     * @author Michael C. Han
039     */
040    public class SearchEngineUtil {
041    
042            /**
043             * @deprecated As of 6.2.0, replaced by {@link
044             *             com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS}
045             */
046            public static final int ALL_POS = -1;
047    
048            public static final String GENERIC_ENGINE_ID = "GENERIC_ENGINE";
049    
050            public static final String SYSTEM_ENGINE_ID = "SYSTEM_ENGINE";
051    
052            /**
053             * @deprecated As of 6.2.0, replaced by {@link #addDocument(String, long,
054             *             Document, boolean)}
055             */
056            public static void addDocument(long companyId, Document document)
057                    throws SearchException {
058    
059                    addDocument(getSearchEngineId(document), companyId, document, true);
060            }
061    
062            /**
063             * @deprecated As of 7.0.0, replaced by {@link #addDocument(String, long,
064             *             Document, boolean)}
065             */
066            @Deprecated
067            public static void addDocument(
068                            String searchEngineId, long companyId, Document document)
069                    throws SearchException {
070    
071                    addDocument(searchEngineId, companyId, document, false);
072            }
073    
074            public static void addDocument(
075                            String searchEngineId, long companyId, Document document,
076                            boolean commitImmediately)
077                    throws SearchException {
078    
079                    if (isIndexReadOnly()) {
080                            return;
081                    }
082    
083                    if (_log.isDebugEnabled()) {
084                            _log.debug("Add document " + document.toString());
085                    }
086    
087                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
088    
089                    IndexWriter indexWriter = searchEngine.getIndexWriter();
090    
091                    _searchPermissionChecker.addPermissionFields(companyId, document);
092    
093                    SearchContext searchContext = new SearchContext();
094    
095                    searchContext.setCommitImmediately(commitImmediately);
096                    searchContext.setCompanyId(companyId);
097                    searchContext.setSearchEngineId(searchEngineId);
098    
099                    indexWriter.addDocument(searchContext, document);
100            }
101    
102            /**
103             * @deprecated As of 6.2.0, replaced by {@link #addDocuments(String, long,
104             *             Collection, boolean)}
105             */
106            public static void addDocuments(
107                            long companyId, Collection<Document> documents)
108                    throws SearchException {
109    
110                    addDocuments(getSearchEngineId(documents), companyId, documents, false);
111            }
112    
113            /**
114             * @deprecated As of 7.0.0, replaced by {@link #addDocuments(String, long,
115             *             Collection, boolean)}
116             */
117            @Deprecated
118            public static void addDocuments(
119                            String searchEngineId, long companyId,
120                            Collection<Document> documents)
121                    throws SearchException {
122    
123                    addDocuments(searchEngineId, companyId, documents, false);
124            }
125    
126            public static void addDocuments(
127                            String searchEngineId, long companyId,
128                            Collection<Document> documents, boolean commitImmediately)
129                    throws SearchException {
130    
131                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
132                            return;
133                    }
134    
135                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
136    
137                    IndexWriter indexWriter = searchEngine.getIndexWriter();
138    
139                    for (Document document : documents) {
140                            if (_log.isDebugEnabled()) {
141                                    _log.debug("Add document " + document.toString());
142                            }
143    
144                            _searchPermissionChecker.addPermissionFields(companyId, document);
145                    }
146    
147                    SearchContext searchContext = new SearchContext();
148    
149                    searchContext.setCommitImmediately(commitImmediately);
150                    searchContext.setCompanyId(companyId);
151                    searchContext.setSearchEngineId(searchEngineId);
152    
153                    indexWriter.addDocuments(searchContext, documents);
154            }
155    
156            /**
157             * @deprecated As of 6.2.0, replaced by {@link #setSearchEngine(String,
158             *             SearchEngine)}
159             */
160            public static void addSearchEngine(SearchEngine searchEngine) {
161                    String searchEngineId = getDefaultSearchEngineId();
162    
163                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
164    
165                    _searchEngines.put(searchEngineId, searchEngine);
166            }
167    
168            /**
169             * @deprecated As of 6.2.0, replaced by {@link #deleteDocument(String, long,
170             *             String)}
171             */
172            public static void deleteDocument(long companyId, String uid)
173                    throws SearchException {
174    
175                    for (String searchEngineId : _searchEngines.keySet()) {
176                            deleteDocument(searchEngineId, companyId, uid, true);
177                    }
178            }
179    
180            /**
181             * @deprecated As of 7.0.0, replaced by {@link #deleteDocument(String, long,
182             *             String, boolean)}
183             */
184            @Deprecated
185            public static void deleteDocument(
186                            String searchEngineId, long companyId, String uid)
187                    throws SearchException {
188    
189                    deleteDocument(searchEngineId, companyId, uid, false);
190            }
191    
192            public static void deleteDocument(
193                            String searchEngineId, long companyId, String uid,
194                            boolean commitImmediately)
195                    throws SearchException {
196    
197                    if (isIndexReadOnly()) {
198                            return;
199                    }
200    
201                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
202    
203                    IndexWriter indexWriter = searchEngine.getIndexWriter();
204    
205                    SearchContext searchContext = new SearchContext();
206    
207                    searchContext.setCommitImmediately(commitImmediately);
208                    searchContext.setCompanyId(companyId);
209                    searchContext.setSearchEngineId(searchEngineId);
210    
211                    indexWriter.deleteDocument(searchContext, uid);
212            }
213    
214            /**
215             * @deprecated As of 6.2.0, replaced by {@link #deleteDocuments(String,
216             *             long, Collection, boolean)}
217             */
218            public static void deleteDocuments(long companyId, Collection<String> uids)
219                    throws SearchException {
220    
221                    for (String searchEngineId : _searchEngines.keySet()) {
222                            deleteDocuments(searchEngineId, companyId, uids, true);
223                    }
224            }
225    
226            /**
227             * @deprecated As of 7.0.0, replaced by {@link #deleteDocuments(String,
228             *             long, Collection, boolean)}
229             */
230            @Deprecated
231            public static void deleteDocuments(
232                            String searchEngineId, long companyId, Collection<String> uids)
233                    throws SearchException {
234    
235                    deleteDocuments(searchEngineId, companyId, uids, false);
236            }
237    
238            public static void deleteDocuments(
239                            String searchEngineId, long companyId, Collection<String> uids,
240                            boolean commitImmediately)
241                    throws SearchException {
242    
243                    if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
244                            return;
245                    }
246    
247                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
248    
249                    IndexWriter indexWriter = searchEngine.getIndexWriter();
250    
251                    SearchContext searchContext = new SearchContext();
252    
253                    searchContext.setCommitImmediately(commitImmediately);
254                    searchContext.setCompanyId(companyId);
255                    searchContext.setSearchEngineId(searchEngineId);
256    
257                    indexWriter.deleteDocuments(searchContext, uids);
258            }
259    
260            /**
261             * @deprecated As of 6.2.0, replaced by {@link
262             *             #deletePortletDocuments(String, long, String, boolean)}
263             */
264            public static void deletePortletDocuments(long companyId, String portletId)
265                    throws SearchException {
266    
267                    for (String searchEngineId : _searchEngines.keySet()) {
268                            deletePortletDocuments(searchEngineId, companyId, portletId, true);
269                    }
270            }
271    
272            /**
273             * @deprecated As of 7.0.0, replaced by {@link
274             *             #deletePortletDocuments(String, long, String, boolean)}
275             */
276            @Deprecated
277            public static void deletePortletDocuments(
278                            String searchEngineId, long companyId, String portletId)
279                    throws SearchException {
280    
281                    deletePortletDocuments(searchEngineId, companyId, portletId, false);
282            }
283    
284            public static void deletePortletDocuments(
285                            String searchEngineId, long companyId, String portletId,
286                            boolean commitImmediately)
287                    throws SearchException {
288    
289                    if (isIndexReadOnly()) {
290                            return;
291                    }
292    
293                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
294    
295                    if (searchEngine == null) {
296                            return;
297                    }
298    
299                    IndexWriter indexWriter = searchEngine.getIndexWriter();
300    
301                    SearchContext searchContext = new SearchContext();
302    
303                    searchContext.setCommitImmediately(commitImmediately);
304                    searchContext.setCompanyId(companyId);
305                    searchContext.setSearchEngineId(searchEngineId);
306    
307                    indexWriter.deletePortletDocuments(searchContext, portletId);
308            }
309    
310            public static String getDefaultSearchEngineId() {
311                    if (_defaultSearchEngineId == null) {
312                            return SYSTEM_ENGINE_ID;
313                    }
314    
315                    return _defaultSearchEngineId;
316            }
317    
318            public static String[] getEntryClassNames() {
319                    Set<String> assetEntryClassNames = new HashSet<String>();
320    
321                    for (Indexer indexer : IndexerRegistryUtil.getIndexers()) {
322                            for (String className : indexer.getClassNames()) {
323                                    if (!_excludedEntryClassNames.contains(className)) {
324                                            assetEntryClassNames.add(className);
325                                    }
326                            }
327                    }
328    
329                    return assetEntryClassNames.toArray(
330                            new String[assetEntryClassNames.size()]);
331            }
332    
333            /**
334             * @deprecated As of 6.2.0, replaced by {@link #getSearchEngine(String)}
335             */
336            public static SearchEngine getSearchEngine() {
337                    return getSearchEngine(getDefaultSearchEngineId());
338            }
339    
340            public static SearchEngine getSearchEngine(String searchEngineId) {
341                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
342    
343                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
344    
345                    if (searchEngine == null) {
346                            if (getDefaultSearchEngineId().equals(searchEngineId)) {
347                                    throw new IllegalStateException(
348                                            "There is no default search engine configured with ID " +
349                                                    getDefaultSearchEngineId());
350                            }
351    
352                            if (_log.isWarnEnabled()) {
353                                    _log.warn(
354                                            "There is no search engine configured with ID " +
355                                                    searchEngineId);
356                            }
357                    }
358    
359                    return searchEngine;
360            }
361    
362            public static String getSearchEngineId(Collection<Document> documents) {
363                    if (!documents.isEmpty()) {
364                            Document document = documents.iterator().next();
365    
366                            return getSearchEngineId(document);
367                    }
368    
369                    return getDefaultSearchEngineId();
370            }
371    
372            public static String getSearchEngineId(Document document) {
373                    String entryClassName = document.get("entryClassName");
374    
375                    Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
376    
377                    String searchEngineId = indexer.getSearchEngineId();
378    
379                    if (_log.isDebugEnabled()) {
380                            _log.debug(
381                                    "Search engine ID for " + indexer.getClass() + " is " +
382                                            searchEngineId);
383                    }
384    
385                    return searchEngineId;
386            }
387    
388            public static Set<String> getSearchEngineIds() {
389                    PortalRuntimePermission.checkGetBeanProperty(
390                            SearchEngineUtil.class, "searchEngineIds");
391    
392                    return _searchEngines.keySet();
393            }
394    
395            public static SearchEngine getSearchEngineSilent(String searchEngineId) {
396                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
397    
398                    return _searchEngines.get(searchEngineId);
399            }
400    
401            public static SearchPermissionChecker getSearchPermissionChecker() {
402                    PortalRuntimePermission.checkGetBeanProperty(
403                            SearchEngineUtil.class, "searchPermissionChecker");
404    
405                    return _searchPermissionChecker;
406            }
407    
408            public static String getSearchReaderDestinationName(String searchEngineId) {
409                    return DestinationNames.SEARCH_READER.concat(StringPool.SLASH).concat(
410                            searchEngineId);
411            }
412    
413            public static String getSearchWriterDestinationName(String searchEngineId) {
414                    return DestinationNames.SEARCH_WRITER.concat(StringPool.SLASH).concat(
415                            searchEngineId);
416            }
417    
418            public static void indexKeyword(
419                            long companyId, String querySuggestion, float weight,
420                            String keywordType, Locale locale)
421                    throws SearchException {
422    
423                    String searchEngineId = getDefaultSearchEngineId();
424    
425                    indexKeyword(
426                            searchEngineId, companyId, querySuggestion, weight, keywordType,
427                            locale);
428            }
429    
430            public static void indexKeyword(
431                            String searchEngineId, long companyId, String querySuggestion,
432                            float weight, String keywordType, Locale locale)
433                    throws SearchException {
434    
435                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
436    
437                    IndexWriter indexWriter = searchEngine.getIndexWriter();
438    
439                    SearchContext searchContext = new SearchContext();
440    
441                    searchContext.setCompanyId(companyId);
442                    searchContext.setSearchEngineId(searchEngineId);
443                    searchContext.setKeywords(querySuggestion);
444                    searchContext.setLocale(locale);
445    
446                    indexWriter.indexKeyword(searchContext, weight, keywordType);
447            }
448    
449            public static void indexQuerySuggestionDictionaries(long companyId)
450                    throws SearchException {
451    
452                    Set<String> searchEngineIds = getSearchEngineIds();
453    
454                    for (String searchEngineId : searchEngineIds) {
455                            indexQuerySuggestionDictionaries(searchEngineId, companyId);
456                    }
457            }
458    
459            public static void indexQuerySuggestionDictionaries(
460                            String searchEngineId, long companyId)
461                    throws SearchException {
462    
463                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
464    
465                    IndexWriter indexWriter = searchEngine.getIndexWriter();
466    
467                    SearchContext searchContext = new SearchContext();
468    
469                    searchContext.setCompanyId(companyId);
470                    searchContext.setSearchEngineId(searchEngineId);
471    
472                    indexWriter.indexQuerySuggestionDictionaries(searchContext);
473            }
474    
475            public static void indexQuerySuggestionDictionary(
476                            long companyId, Locale locale)
477                    throws SearchException {
478    
479                    String searchEngineId = getDefaultSearchEngineId();
480    
481                    indexQuerySuggestionDictionary(searchEngineId, companyId, locale);
482            }
483    
484            public static void indexQuerySuggestionDictionary(
485                            String searchEngineId, long companyId, Locale locale)
486                    throws SearchException {
487    
488                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
489    
490                    IndexWriter indexWriter = searchEngine.getIndexWriter();
491    
492                    SearchContext searchContext = new SearchContext();
493    
494                    searchContext.setCompanyId(companyId);
495                    searchContext.setSearchEngineId(searchEngineId);
496                    searchContext.setLocale(locale);
497    
498                    indexWriter.indexQuerySuggestionDictionary(searchContext);
499            }
500    
501            public static void indexSpellCheckerDictionaries(long companyId)
502                    throws SearchException {
503    
504                    String searchEngineId = getDefaultSearchEngineId();
505    
506                    indexSpellCheckerDictionaries(searchEngineId, companyId);
507            }
508    
509            public static void indexSpellCheckerDictionaries(
510                            String searchEngineId, long companyId)
511                    throws SearchException {
512    
513                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
514    
515                    IndexWriter indexWriter = searchEngine.getIndexWriter();
516    
517                    SearchContext searchContext = new SearchContext();
518    
519                    searchContext.setCompanyId(companyId);
520                    searchContext.setSearchEngineId(searchEngineId);
521    
522                    indexWriter.indexSpellCheckerDictionaries(searchContext);
523            }
524    
525            public static void indexSpellCheckerDictionary(
526                            long companyId, Locale locale)
527                    throws SearchException {
528    
529                    String searchEngineId = getDefaultSearchEngineId();
530    
531                    indexSpellCheckerDictionary(searchEngineId, companyId, locale);
532            }
533    
534            public static void indexSpellCheckerDictionary(
535                            String searchEngineId, long companyId, Locale locale)
536                    throws SearchException {
537    
538                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
539    
540                    IndexWriter indexWriter = searchEngine.getIndexWriter();
541    
542                    SearchContext searchContext = new SearchContext();
543    
544                    searchContext.setCompanyId(companyId);
545                    searchContext.setSearchEngineId(searchEngineId);
546                    searchContext.setLocale(locale);
547    
548                    indexWriter.indexSpellCheckerDictionary(searchContext);
549            }
550    
551            public static boolean isIndexReadOnly() {
552                    PortalRuntimePermission.checkGetBeanProperty(
553                            SearchEngineUtil.class, "indexReadOnly");
554    
555                    return _indexReadOnly;
556            }
557    
558            public static SearchEngine removeSearchEngine(String searchEngineId) {
559                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
560    
561                    return _searchEngines.remove(searchEngineId);
562            }
563    
564            /**
565             * @deprecated As of 6.2.0
566             */
567            public static Hits search(
568                            long companyId, long[] groupIds, long userId, String className,
569                            Query query, int start, int end)
570                    throws SearchException {
571    
572                    SearchContext searchContext = new SearchContext();
573    
574                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
575    
576                    if (userId > 0) {
577                            query = _searchPermissionChecker.getPermissionQuery(
578                                    companyId, groupIds, userId, className, query, searchContext);
579                    }
580    
581                    return search(
582                            companyId, query, SortFactoryUtil.getDefaultSorts(), start, end);
583            }
584    
585            /**
586             * @deprecated As of 6.2.0
587             */
588            public static Hits search(
589                            long companyId, long[] groupIds, long userId, String className,
590                            Query query, Sort sort, int start, int end)
591                    throws SearchException {
592    
593                    SearchContext searchContext = new SearchContext();
594    
595                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
596    
597                    if (userId > 0) {
598                            query = _searchPermissionChecker.getPermissionQuery(
599                                    companyId, groupIds, userId, className, query, searchContext);
600                    }
601    
602                    return search(companyId, query, sort, start, end);
603            }
604    
605            /**
606             * @deprecated As of 6.2.0
607             */
608            public static Hits search(
609                            long companyId, long[] groupIds, long userId, String className,
610                            Query query, Sort[] sorts, int start, int end)
611                    throws SearchException {
612    
613                    SearchContext searchContext = new SearchContext();
614    
615                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
616    
617                    if (userId > 0) {
618                            query = _searchPermissionChecker.getPermissionQuery(
619                                    companyId, groupIds, userId, className, query, searchContext);
620                    }
621    
622                    return search(companyId, query, sorts, start, end);
623            }
624    
625            /**
626             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
627             *             int, int)}
628             */
629            public static Hits search(long companyId, Query query, int start, int end)
630                    throws SearchException {
631    
632                    return search(getDefaultSearchEngineId(), companyId, query, start, end);
633            }
634    
635            /**
636             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
637             *             Sort, int, int)}
638             */
639            public static Hits search(
640                            long companyId, Query query, Sort sort, int start, int end)
641                    throws SearchException {
642    
643                    return search(
644                            getDefaultSearchEngineId(), companyId, query, sort, start, end);
645            }
646    
647            /**
648             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
649             *             Sort[], int, int)}
650             */
651            public static Hits search(
652                            long companyId, Query query, Sort[] sorts, int start, int end)
653                    throws SearchException {
654    
655                    return search(
656                            getDefaultSearchEngineId(), companyId, query, sorts, start, end);
657            }
658    
659            public static Hits search(SearchContext searchContext, Query query)
660                    throws SearchException {
661    
662                    if (_log.isDebugEnabled()) {
663                            _log.debug("Search query " + query.toString());
664                    }
665    
666                    SearchEngine searchEngine = getSearchEngine(
667                            searchContext.getSearchEngineId());
668    
669                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
670    
671                    return indexSearcher.search(searchContext, query);
672            }
673    
674            public static Hits search(
675                            String searchEngineId, long companyId, Query query, int start,
676                            int end)
677                    throws SearchException {
678    
679                    if (_log.isDebugEnabled()) {
680                            _log.debug("Search query " + query.toString());
681                    }
682    
683                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
684    
685                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
686    
687                    return indexSearcher.search(
688                            searchEngineId, companyId, query, SortFactoryUtil.getDefaultSorts(),
689                            start, end);
690            }
691    
692            public static Hits search(
693                            String searchEngineId, long companyId, Query query, Sort sort,
694                            int start, int end)
695                    throws SearchException {
696    
697                    if (_log.isDebugEnabled()) {
698                            _log.debug("Search query " + query.toString());
699                    }
700    
701                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
702    
703                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
704    
705                    return indexSearcher.search(
706                            searchEngineId, companyId, query, new Sort[] {sort}, start, end);
707            }
708    
709            public static Hits search(
710                            String searchEngineId, long companyId, Query query, Sort[] sorts,
711                            int start, int end)
712                    throws SearchException {
713    
714                    if (_log.isDebugEnabled()) {
715                            _log.debug("Search query " + query.toString());
716                    }
717    
718                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
719    
720                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
721    
722                    return indexSearcher.search(
723                            searchEngineId, companyId, query, sorts, start, end);
724            }
725    
726            public static void setDefaultSearchEngineId(String defaultSearchEngineId) {
727                    PortalRuntimePermission.checkSetBeanProperty(
728                            SearchEngineUtil.class, "defaultSearchEngineId");
729    
730                    _defaultSearchEngineId = defaultSearchEngineId;
731            }
732    
733            public static void setIndexReadOnly(boolean indexReadOnly) {
734                    PortalRuntimePermission.checkSetBeanProperty(
735                            SearchEngineUtil.class, "indexReadOnly");
736    
737                    _indexReadOnly = indexReadOnly;
738            }
739    
740            public static void setSearchEngine(
741                    String searchEngineId, SearchEngine searchEngine) {
742    
743                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
744    
745                    _searchEngines.put(searchEngineId, searchEngine);
746            }
747    
748            public static String spellCheckKeywords(SearchContext searchContext)
749                    throws SearchException {
750    
751                    if (_log.isDebugEnabled()) {
752                            _log.debug("Spell checking " + searchContext.getKeywords());
753                    }
754    
755                    SearchEngine searchEngine = getSearchEngine(
756                            searchContext.getSearchEngineId());
757    
758                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
759    
760                    return indexSearcher.spellCheckKeywords(searchContext);
761            }
762    
763            public static Map<String, List<String>> spellCheckKeywords(
764                            SearchContext searchContext, int max)
765                    throws SearchException {
766    
767                    if (_log.isDebugEnabled()) {
768                            _log.debug("Spell checking " + searchContext.getKeywords());
769                    }
770    
771                    SearchEngine searchEngine = getSearchEngine(
772                            searchContext.getSearchEngineId());
773    
774                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
775    
776                    return indexSearcher.spellCheckKeywords(searchContext, max);
777            }
778    
779            public static String[] suggestKeywordQueries(
780                            SearchContext searchContext, int max)
781                    throws SearchException {
782    
783                    if (_log.isDebugEnabled()) {
784                            _log.debug(
785                                    "Suggesting keyword queries" + searchContext.getKeywords());
786                    }
787    
788                    SearchEngine searchEngine = getSearchEngine(
789                            searchContext.getSearchEngineId());
790    
791                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
792    
793                    return indexSearcher.suggestKeywordQueries(searchContext, max);
794            }
795    
796            /**
797             * @deprecated As of 6.2.0, replaced by {@link #updateDocument(String, long,
798             *             Document)}
799             */
800            public static void updateDocument(long companyId, Document document)
801                    throws SearchException {
802    
803                    updateDocument(getSearchEngineId(document), companyId, document, true);
804            }
805    
806            /**
807             * @deprecated As of 7.0.0, replaced by {@link #updateDocument(String, long,
808             *             Document, boolean)}
809             */
810            @Deprecated
811            public static void updateDocument(
812                            String searchEngineId, long companyId, Document document)
813                    throws SearchException {
814    
815                    updateDocument(searchEngineId, companyId, document, false);
816            }
817    
818            public static void updateDocument(
819                            String searchEngineId, long companyId, Document document,
820                            boolean commitImmediately)
821                    throws SearchException {
822    
823                    if (isIndexReadOnly()) {
824                            return;
825                    }
826    
827                    if (_log.isDebugEnabled()) {
828                            _log.debug("Document " + document.toString());
829                    }
830    
831                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
832    
833                    IndexWriter indexWriter = searchEngine.getIndexWriter();
834    
835                    _searchPermissionChecker.addPermissionFields(companyId, document);
836    
837                    SearchContext searchContext = new SearchContext();
838    
839                    searchContext.setCommitImmediately(commitImmediately);
840                    searchContext.setCompanyId(companyId);
841                    searchContext.setSearchEngineId(searchEngineId);
842    
843                    indexWriter.updateDocument(searchContext, document);
844            }
845    
846            /**
847             * @deprecated As of 6.2.0, replaced by {@link #updateDocuments(String,
848             *             long, Collection)}
849             */
850            public static void updateDocuments(
851                            long companyId, Collection<Document> documents)
852                    throws SearchException {
853    
854                    updateDocuments(
855                            getSearchEngineId(documents), companyId, documents, true);
856            }
857    
858            /**
859             * @deprecated As of 7.0.0, replaced by {@link #updateDocuments(String,
860             *             long, Collection, boolean)}
861             */
862            @Deprecated
863            public static void updateDocuments(
864                            String searchEngineId, long companyId,
865                            Collection<Document> documents)
866                    throws SearchException {
867    
868                    updateDocuments(searchEngineId, companyId, documents, false);
869            }
870    
871            public static void updateDocuments(
872                            String searchEngineId, long companyId,
873                            Collection<Document> documents, boolean commitImmediately)
874                    throws SearchException {
875    
876                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
877                            return;
878                    }
879    
880                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
881    
882                    IndexWriter indexWriter = searchEngine.getIndexWriter();
883    
884                    for (Document document : documents) {
885                            if (_log.isDebugEnabled()) {
886                                    _log.debug("Document " + document.toString());
887                            }
888    
889                            _searchPermissionChecker.addPermissionFields(companyId, document);
890                    }
891    
892                    SearchContext searchContext = new SearchContext();
893    
894                    searchContext.setCommitImmediately(commitImmediately);
895                    searchContext.setCompanyId(companyId);
896                    searchContext.setSearchEngineId(searchEngineId);
897    
898                    indexWriter.updateDocuments(searchContext, documents);
899            }
900    
901            public static void updatePermissionFields(String name, String primKey) {
902                    if (isIndexReadOnly()) {
903                            return;
904                    }
905    
906                    if (PermissionThreadLocal.isFlushResourcePermissionEnabled(
907                                    name, primKey)) {
908    
909                            _searchPermissionChecker.updatePermissionFields(name, primKey);
910                    }
911            }
912    
913            public void setExcludedEntryClassNames(
914                    List<String> excludedEntryClassNames) {
915    
916                    PortalRuntimePermission.checkSetBeanProperty(
917                            getClass(), "excludedEntryClassNames");
918    
919                    _excludedEntryClassNames.addAll(excludedEntryClassNames);
920            }
921    
922            /**
923             * @deprecated As of 6.2.0, replaced by {@link #setSearchEngine(String,
924             *             SearchEngine)}
925             */
926            public void setSearchEngine(SearchEngine searchEngine) {
927                    String searchEngineId = getDefaultSearchEngineId();
928    
929                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
930    
931                    _searchEngines.put(searchEngineId, searchEngine);
932            }
933    
934            public void setSearchPermissionChecker(
935                    SearchPermissionChecker searchPermissionChecker) {
936    
937                    PortalRuntimePermission.checkSetBeanProperty(
938                            getClass(), "searchPermissionChecker");
939    
940                    _searchPermissionChecker = searchPermissionChecker;
941            }
942    
943            private static Log _log = LogFactoryUtil.getLog(SearchEngineUtil.class);
944    
945            private static String _defaultSearchEngineId;
946            private static Set<String> _excludedEntryClassNames = new HashSet<String>();
947            private static boolean _indexReadOnly = GetterUtil.getBoolean(
948                    PropsUtil.get(PropsKeys.INDEX_READ_ONLY));
949            private static Map<String, SearchEngine> _searchEngines =
950                    new ConcurrentHashMap<String, SearchEngine>();
951            private static SearchPermissionChecker _searchPermissionChecker;
952    
953    }