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)}
055             */
056            public static void addDocument(long companyId, Document document)
057                    throws SearchException {
058    
059                    addDocument(_getSearchEngineId(document), companyId, document);
060            }
061    
062            public static void addDocument(
063                            String searchEngineId, long companyId, Document document)
064                    throws SearchException {
065    
066                    if (isIndexReadOnly()) {
067                            return;
068                    }
069    
070                    if (_log.isDebugEnabled()) {
071                            _log.debug("Add document " + document.toString());
072                    }
073    
074                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
075    
076                    IndexWriter indexWriter = searchEngine.getIndexWriter();
077    
078                    _searchPermissionChecker.addPermissionFields(companyId, document);
079    
080                    SearchContext searchContext = new SearchContext();
081    
082                    searchContext.setCompanyId(companyId);
083                    searchContext.setSearchEngineId(searchEngineId);
084    
085                    indexWriter.addDocument(searchContext, document);
086            }
087    
088            /**
089             * @deprecated As of 6.2.0, replaced by {@link #addDocuments(String, long,
090             *             Collection)}
091             */
092            public static void addDocuments(
093                            long companyId, Collection<Document> documents)
094                    throws SearchException {
095    
096                    addDocuments(_getSearchEngineId(documents), companyId, documents);
097            }
098    
099            public static void addDocuments(
100                            String searchEngineId, long companyId,
101                            Collection<Document> documents)
102                    throws SearchException {
103    
104                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
105                            return;
106                    }
107    
108                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
109    
110                    IndexWriter indexWriter = searchEngine.getIndexWriter();
111    
112                    for (Document document : documents) {
113                            if (_log.isDebugEnabled()) {
114                                    _log.debug("Add document " + document.toString());
115                            }
116    
117                            _searchPermissionChecker.addPermissionFields(companyId, document);
118                    }
119    
120                    SearchContext searchContext = new SearchContext();
121    
122                    searchContext.setCompanyId(companyId);
123                    searchContext.setSearchEngineId(searchEngineId);
124    
125                    indexWriter.addDocuments(searchContext, documents);
126            }
127    
128            /**
129             * @deprecated As of 6.2.0, replaced by {@link #setSearchEngine(String,
130             *             SearchEngine)}
131             */
132            public static void addSearchEngine(SearchEngine searchEngine) {
133                    String searchEngineId = getDefaultSearchEngineId();
134    
135                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
136    
137                    _searchEngines.put(searchEngineId, searchEngine);
138            }
139    
140            /**
141             * @deprecated As of 6.2.0, replaced by {@link #deleteDocument(String, long,
142             *             String)}
143             */
144            public static void deleteDocument(long companyId, String uid)
145                    throws SearchException {
146    
147                    for (String searchEngineId : _searchEngines.keySet()) {
148                            deleteDocument(searchEngineId, companyId, uid);
149                    }
150            }
151    
152            public static void deleteDocument(
153                            String searchEngineId, long companyId, String uid)
154                    throws SearchException {
155    
156                    if (isIndexReadOnly()) {
157                            return;
158                    }
159    
160                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
161    
162                    IndexWriter indexWriter = searchEngine.getIndexWriter();
163    
164                    SearchContext searchContext = new SearchContext();
165    
166                    searchContext.setCompanyId(companyId);
167                    searchContext.setSearchEngineId(searchEngineId);
168    
169                    indexWriter.deleteDocument(searchContext, uid);
170            }
171    
172            /**
173             * @deprecated As of 6.2.0, replaced by {@link #deleteDocuments(String,
174             *             long, Collection)}
175             */
176            public static void deleteDocuments(long companyId, Collection<String> uids)
177                    throws SearchException {
178    
179                    for (String searchEngineId : _searchEngines.keySet()) {
180                            deleteDocuments(searchEngineId, companyId, uids);
181                    }
182            }
183    
184            public static void deleteDocuments(
185                            String searchEngineId, long companyId, Collection<String> uids)
186                    throws SearchException {
187    
188                    if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
189                            return;
190                    }
191    
192                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
193    
194                    IndexWriter indexWriter = searchEngine.getIndexWriter();
195    
196                    SearchContext searchContext = new SearchContext();
197    
198                    searchContext.setCompanyId(companyId);
199                    searchContext.setSearchEngineId(searchEngineId);
200    
201                    indexWriter.deleteDocuments(searchContext, uids);
202            }
203    
204            /**
205             * @deprecated As of 6.2.0, replaced by {@link
206             *             #deletePortletDocuments(String, long, String)}
207             */
208            public static void deletePortletDocuments(long companyId, String portletId)
209                    throws SearchException {
210    
211                    for (String searchEngineId : _searchEngines.keySet()) {
212                            deletePortletDocuments(searchEngineId, companyId, portletId);
213                    }
214            }
215    
216            public static void deletePortletDocuments(
217                            String searchEngineId, long companyId, String portletId)
218                    throws SearchException {
219    
220                    if (isIndexReadOnly()) {
221                            return;
222                    }
223    
224                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
225    
226                    if (searchEngine == null) {
227                            return;
228                    }
229    
230                    IndexWriter indexWriter = searchEngine.getIndexWriter();
231    
232                    SearchContext searchContext = new SearchContext();
233    
234                    searchContext.setCompanyId(companyId);
235                    searchContext.setSearchEngineId(searchEngineId);
236    
237                    indexWriter.deletePortletDocuments(searchContext, portletId);
238            }
239    
240            public static String getDefaultSearchEngineId() {
241                    if (_defaultSearchEngineId == null) {
242                            return SYSTEM_ENGINE_ID;
243                    }
244    
245                    return _defaultSearchEngineId;
246            }
247    
248            public static String[] getEntryClassNames() {
249                    Set<String> assetEntryClassNames = new HashSet<String>();
250    
251                    for (Indexer indexer : IndexerRegistryUtil.getIndexers()) {
252                            for (String className : indexer.getClassNames()) {
253                                    if (!_excludedEntryClassNames.contains(className)) {
254                                            assetEntryClassNames.add(className);
255                                    }
256                            }
257                    }
258    
259                    return assetEntryClassNames.toArray(
260                            new String[assetEntryClassNames.size()]);
261            }
262    
263            /**
264             * @deprecated As of 6.2.0, replaced by {@link #getSearchEngine(String)}
265             */
266            public static SearchEngine getSearchEngine() {
267                    return getSearchEngine(getDefaultSearchEngineId());
268            }
269    
270            public static SearchEngine getSearchEngine(String searchEngineId) {
271                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
272    
273                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
274    
275                    if (searchEngine == null) {
276                            if (getDefaultSearchEngineId().equals(searchEngineId)) {
277                                    throw new IllegalStateException(
278                                            "There is no default search engine configured with ID " +
279                                                    getDefaultSearchEngineId());
280                            }
281    
282                            if (_log.isWarnEnabled()) {
283                                    _log.warn(
284                                            "There is no search engine configured with ID " +
285                                                    searchEngineId);
286                            }
287                    }
288    
289                    return searchEngine;
290            }
291    
292            public static Set<String> getSearchEngineIds() {
293                    PortalRuntimePermission.checkGetBeanProperty(
294                            SearchEngineUtil.class, "searchEngineIds");
295    
296                    return _searchEngines.keySet();
297            }
298    
299            public static SearchEngine getSearchEngineSilent(String searchEngineId) {
300                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
301    
302                    return _searchEngines.get(searchEngineId);
303            }
304    
305            public static SearchPermissionChecker getSearchPermissionChecker() {
306                    PortalRuntimePermission.checkGetBeanProperty(
307                            SearchEngineUtil.class, "searchPermissionChecker");
308    
309                    return _searchPermissionChecker;
310            }
311    
312            public static String getSearchReaderDestinationName(String searchEngineId) {
313                    return DestinationNames.SEARCH_READER.concat(StringPool.SLASH).concat(
314                            searchEngineId);
315            }
316    
317            public static String getSearchWriterDestinationName(String searchEngineId) {
318                    return DestinationNames.SEARCH_WRITER.concat(StringPool.SLASH).concat(
319                            searchEngineId);
320            }
321    
322            public static void indexDictionaries(long companyId)
323                    throws SearchException {
324    
325                    Set<String> searchEngineIds = getSearchEngineIds();
326    
327                    for (String searchEngineId : searchEngineIds) {
328                            indexDictionaries(searchEngineId, companyId);
329                    }
330            }
331    
332            public static void indexDictionaries(String searchEngineId, long companyId)
333                    throws SearchException {
334    
335                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
336    
337                    IndexWriter indexWriter = searchEngine.getIndexWriter();
338    
339                    SearchContext searchContext = new SearchContext();
340    
341                    searchContext.setCompanyId(companyId);
342                    searchContext.setSearchEngineId(searchEngineId);
343    
344                    indexWriter.indexDictionaries(searchContext);
345            }
346    
347            public static void indexDictionary(long companyId, Locale locale)
348                    throws SearchException {
349    
350                    Set<String> searchEngineIds = getSearchEngineIds();
351    
352                    for (String searchEngineId : searchEngineIds) {
353                            indexDictionary(searchEngineId, companyId, locale);
354                    }
355            }
356    
357            public static void indexDictionary(
358                            String searchEngineId, long companyId, Locale locale)
359                    throws SearchException {
360    
361                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
362    
363                    IndexWriter indexWriter = searchEngine.getIndexWriter();
364    
365                    SearchContext searchContext = new SearchContext();
366    
367                    searchContext.setCompanyId(companyId);
368                    searchContext.setSearchEngineId(searchEngineId);
369                    searchContext.setLocale(locale);
370    
371                    indexWriter.indexDictionary(searchContext);
372            }
373    
374            public static boolean isIndexReadOnly() {
375                    PortalRuntimePermission.checkGetBeanProperty(
376                            SearchEngineUtil.class, "indexReadOnly");
377    
378                    return _indexReadOnly;
379            }
380    
381            public static SearchEngine removeSearchEngine(String searchEngineId) {
382                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
383    
384                    return _searchEngines.remove(searchEngineId);
385            }
386    
387            /**
388             * @deprecated As of 6.2.0
389             */
390            public static Hits search(
391                            long companyId, long[] groupIds, long userId, String className,
392                            Query query, int start, int end)
393                    throws SearchException {
394    
395                    SearchContext searchContext = new SearchContext();
396    
397                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
398    
399                    if (userId > 0) {
400                            query = _searchPermissionChecker.getPermissionQuery(
401                                    companyId, groupIds, userId, className, query, searchContext);
402                    }
403    
404                    return search(
405                            companyId, query, SortFactoryUtil.getDefaultSorts(), start, end);
406            }
407    
408            /**
409             * @deprecated As of 6.2.0
410             */
411            public static Hits search(
412                            long companyId, long[] groupIds, long userId, String className,
413                            Query query, Sort sort, int start, int end)
414                    throws SearchException {
415    
416                    SearchContext searchContext = new SearchContext();
417    
418                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
419    
420                    if (userId > 0) {
421                            query = _searchPermissionChecker.getPermissionQuery(
422                                    companyId, groupIds, userId, className, query, searchContext);
423                    }
424    
425                    return search(companyId, query, sort, start, end);
426            }
427    
428            /**
429             * @deprecated As of 6.2.0
430             */
431            public static Hits search(
432                            long companyId, long[] groupIds, long userId, String className,
433                            Query query, Sort[] sorts, int start, int end)
434                    throws SearchException {
435    
436                    SearchContext searchContext = new SearchContext();
437    
438                    searchContext.setSearchEngineId(getDefaultSearchEngineId());
439    
440                    if (userId > 0) {
441                            query = _searchPermissionChecker.getPermissionQuery(
442                                    companyId, groupIds, userId, className, query, searchContext);
443                    }
444    
445                    return search(companyId, query, sorts, start, end);
446            }
447    
448            /**
449             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
450             *             int, int)}
451             */
452            public static Hits search(long companyId, Query query, int start, int end)
453                    throws SearchException {
454    
455                    return search(getDefaultSearchEngineId(), companyId, query, start, end);
456            }
457    
458            /**
459             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
460             *             Sort, int, int)}
461             */
462            public static Hits search(
463                            long companyId, Query query, Sort sort, int start, int end)
464                    throws SearchException {
465    
466                    return search(
467                            getDefaultSearchEngineId(), companyId, query, sort, start, end);
468            }
469    
470            /**
471             * @deprecated As of 6.2.0, replaced by {@link #search(String, long, Query,
472             *             Sort[], int, int)}
473             */
474            public static Hits search(
475                            long companyId, Query query, Sort[] sorts, int start, int end)
476                    throws SearchException {
477    
478                    return search(
479                            getDefaultSearchEngineId(), companyId, query, sorts, start, end);
480            }
481    
482            public static Hits search(SearchContext searchContext, Query query)
483                    throws SearchException {
484    
485                    if (_log.isDebugEnabled()) {
486                            _log.debug("Search query " + query.toString());
487                    }
488    
489                    SearchEngine searchEngine = getSearchEngine(
490                            searchContext.getSearchEngineId());
491    
492                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
493    
494                    return indexSearcher.search(searchContext, query);
495            }
496    
497            public static Hits search(
498                            String searchEngineId, long companyId, Query query, int start,
499                            int end)
500                    throws SearchException {
501    
502                    if (_log.isDebugEnabled()) {
503                            _log.debug("Search query " + query.toString());
504                    }
505    
506                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
507    
508                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
509    
510                    return indexSearcher.search(
511                            searchEngineId, companyId, query, SortFactoryUtil.getDefaultSorts(),
512                            start, end);
513            }
514    
515            public static Hits search(
516                            String searchEngineId, long companyId, Query query, Sort sort,
517                            int start, int end)
518                    throws SearchException {
519    
520                    if (_log.isDebugEnabled()) {
521                            _log.debug("Search query " + query.toString());
522                    }
523    
524                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
525    
526                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
527    
528                    return indexSearcher.search(
529                            searchEngineId, companyId, query, new Sort[] {sort}, start, end);
530            }
531    
532            public static Hits search(
533                            String searchEngineId, long companyId, Query query, Sort[] sorts,
534                            int start, int end)
535                    throws SearchException {
536    
537                    if (_log.isDebugEnabled()) {
538                            _log.debug("Search query " + query.toString());
539                    }
540    
541                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
542    
543                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
544    
545                    return indexSearcher.search(
546                            searchEngineId, companyId, query, sorts, start, end);
547            }
548    
549            public static void setDefaultSearchEngineId(String defaultSearchEngineId) {
550                    PortalRuntimePermission.checkSetBeanProperty(
551                            SearchEngineUtil.class, "defaultSearchEngineId");
552    
553                    _defaultSearchEngineId = defaultSearchEngineId;
554            }
555    
556            public static void setIndexReadOnly(boolean indexReadOnly) {
557                    PortalRuntimePermission.checkSetBeanProperty(
558                            SearchEngineUtil.class, "indexReadOnly");
559    
560                    _indexReadOnly = indexReadOnly;
561            }
562    
563            public static void setSearchEngine(
564                    String searchEngineId, SearchEngine searchEngine) {
565    
566                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
567    
568                    _searchEngines.put(searchEngineId, searchEngine);
569            }
570    
571            public static String spellCheckKeywords(SearchContext searchContext)
572                    throws SearchException {
573    
574                    if (_log.isDebugEnabled()) {
575                            _log.debug("Spell checking " + searchContext.getKeywords());
576                    }
577    
578                    SearchEngine searchEngine = getSearchEngine(
579                            searchContext.getSearchEngineId());
580    
581                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
582    
583                    return indexSearcher.spellCheckKeywords(searchContext);
584            }
585    
586            public static Map<String, List<String>> spellCheckKeywords(
587                            SearchContext searchContext, int max)
588                    throws SearchException {
589    
590                    if (_log.isDebugEnabled()) {
591                            _log.debug("Spell checking " + searchContext.getKeywords());
592                    }
593    
594                    SearchEngine searchEngine = getSearchEngine(
595                            searchContext.getSearchEngineId());
596    
597                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
598    
599                    return indexSearcher.spellCheckKeywords(searchContext, max);
600            }
601    
602            public static String[] suggestKeywordQueries(
603                            SearchContext searchContext, int max)
604                    throws SearchException {
605    
606                    if (_log.isDebugEnabled()) {
607                            _log.debug(
608                                    "Suggesting keyword queries" + searchContext.getKeywords());
609                    }
610    
611                    SearchEngine searchEngine = getSearchEngine(
612                            searchContext.getSearchEngineId());
613    
614                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
615    
616                    return indexSearcher.suggestKeywordQueries(searchContext, max);
617            }
618    
619            /**
620             * @deprecated As of 6.2.0, replaced by {@link #updateDocument(String, long,
621             *             Document)}
622             */
623            public static void updateDocument(long companyId, Document document)
624                    throws SearchException {
625    
626                    updateDocument(_getSearchEngineId(document), companyId, document);
627            }
628    
629            public static void updateDocument(
630                            String searchEngineId, long companyId, Document document)
631                    throws SearchException {
632    
633                    if (isIndexReadOnly()) {
634                            return;
635                    }
636    
637                    if (_log.isDebugEnabled()) {
638                            _log.debug("Document " + document.toString());
639                    }
640    
641                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
642    
643                    IndexWriter indexWriter = searchEngine.getIndexWriter();
644    
645                    _searchPermissionChecker.addPermissionFields(companyId, document);
646    
647                    SearchContext searchContext = new SearchContext();
648    
649                    searchContext.setCompanyId(companyId);
650                    searchContext.setSearchEngineId(searchEngineId);
651    
652                    indexWriter.updateDocument(searchContext, document);
653            }
654    
655            /**
656             * @deprecated As of 6.2.0, replaced by {@link #updateDocuments(String,
657             *             long, Collection)}
658             */
659            public static void updateDocuments(
660                            long companyId, Collection<Document> documents)
661                    throws SearchException {
662    
663                    updateDocuments(_getSearchEngineId(documents), companyId, documents);
664            }
665    
666            public static void updateDocuments(
667                            String searchEngineId, long companyId,
668                            Collection<Document> documents)
669                    throws SearchException {
670    
671                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
672                            return;
673                    }
674    
675                    SearchEngine searchEngine = getSearchEngine(searchEngineId);
676    
677                    IndexWriter indexWriter = searchEngine.getIndexWriter();
678    
679                    for (Document document : documents) {
680                            if (_log.isDebugEnabled()) {
681                                    _log.debug("Document " + document.toString());
682                            }
683    
684                            _searchPermissionChecker.addPermissionFields(companyId, document);
685                    }
686    
687                    SearchContext searchContext = new SearchContext();
688    
689                    searchContext.setCompanyId(companyId);
690                    searchContext.setSearchEngineId(searchEngineId);
691    
692                    indexWriter.updateDocuments(searchContext, documents);
693            }
694    
695            public static void updatePermissionFields(String name, String primKey) {
696                    if (isIndexReadOnly() || !PermissionThreadLocal.isFlushEnabled()) {
697                            return;
698                    }
699    
700                    _searchPermissionChecker.updatePermissionFields(name, primKey);
701            }
702    
703            public void setExcludedEntryClassNames(
704                    List<String> excludedEntryClassNames) {
705    
706                    PortalRuntimePermission.checkSetBeanProperty(
707                            getClass(), "excludedEntryClassNames");
708    
709                    _excludedEntryClassNames.addAll(excludedEntryClassNames);
710            }
711    
712            /**
713             * @deprecated As of 6.2.0, replaced by {@link #setSearchEngine(String,
714             *             SearchEngine)}
715             */
716            public void setSearchEngine(SearchEngine searchEngine) {
717                    String searchEngineId = getDefaultSearchEngineId();
718    
719                    PortalRuntimePermission.checkSearchEngine(searchEngineId);
720    
721                    _searchEngines.put(searchEngineId, searchEngine);
722            }
723    
724            public void setSearchPermissionChecker(
725                    SearchPermissionChecker searchPermissionChecker) {
726    
727                    PortalRuntimePermission.checkSetBeanProperty(
728                            getClass(), "searchPermissionChecker");
729    
730                    _searchPermissionChecker = searchPermissionChecker;
731            }
732    
733            private static String _getSearchEngineId(Collection<Document> documents) {
734                    if (!documents.isEmpty()) {
735                            Document document = documents.iterator().next();
736    
737                            return _getSearchEngineId(document);
738                    }
739    
740                    return getDefaultSearchEngineId();
741            }
742    
743            private static String _getSearchEngineId(Document document) {
744                    String entryClassName = document.get("entryClassName");
745    
746                    Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
747    
748                    String searchEngineId = indexer.getSearchEngineId();
749    
750                    if (_log.isDebugEnabled()) {
751                            _log.debug(
752                                    "Search engine ID for " + indexer.getClass() + " is " +
753                                            searchEngineId);
754                    }
755    
756                    return searchEngineId;
757            }
758    
759            private static Log _log = LogFactoryUtil.getLog(SearchEngineUtil.class);
760    
761            private static String _defaultSearchEngineId;
762            private static Set<String> _excludedEntryClassNames = new HashSet<String>();
763            private static boolean _indexReadOnly = GetterUtil.getBoolean(
764                    PropsUtil.get(PropsKeys.INDEX_READ_ONLY));
765            private static Map<String, SearchEngine> _searchEngines =
766                    new ConcurrentHashMap<String, SearchEngine>();
767            private static SearchPermissionChecker _searchPermissionChecker;
768    
769    }