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