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