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