001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.asset.kernel.AssetRendererFactoryRegistryUtil;
018 import com.liferay.asset.kernel.model.AssetCategory;
019 import com.liferay.asset.kernel.model.AssetEntry;
020 import com.liferay.asset.kernel.model.AssetRendererFactory;
021 import com.liferay.asset.kernel.model.AssetTag;
022 import com.liferay.asset.kernel.service.AssetCategoryLocalServiceUtil;
023 import com.liferay.asset.kernel.service.AssetEntryLocalServiceUtil;
024 import com.liferay.asset.kernel.service.AssetTagLocalServiceUtil;
025 import com.liferay.expando.kernel.model.ExpandoBridge;
026 import com.liferay.expando.kernel.model.ExpandoColumn;
027 import com.liferay.expando.kernel.model.ExpandoColumnConstants;
028 import com.liferay.expando.kernel.service.ExpandoColumnLocalServiceUtil;
029 import com.liferay.expando.kernel.util.ExpandoBridgeFactoryUtil;
030 import com.liferay.expando.kernel.util.ExpandoBridgeIndexerUtil;
031 import com.liferay.portal.kernel.exception.NoSuchCountryException;
032 import com.liferay.portal.kernel.exception.NoSuchModelException;
033 import com.liferay.portal.kernel.exception.NoSuchRegionException;
034 import com.liferay.portal.kernel.exception.PortalException;
035 import com.liferay.portal.kernel.language.LanguageUtil;
036 import com.liferay.portal.kernel.log.Log;
037 import com.liferay.portal.kernel.log.LogFactoryUtil;
038 import com.liferay.portal.kernel.model.Address;
039 import com.liferay.portal.kernel.model.AttachedModel;
040 import com.liferay.portal.kernel.model.AuditedModel;
041 import com.liferay.portal.kernel.model.BaseModel;
042 import com.liferay.portal.kernel.model.Country;
043 import com.liferay.portal.kernel.model.Group;
044 import com.liferay.portal.kernel.model.GroupedModel;
045 import com.liferay.portal.kernel.model.Region;
046 import com.liferay.portal.kernel.model.ResourcedModel;
047 import com.liferay.portal.kernel.model.TrashedModel;
048 import com.liferay.portal.kernel.model.User;
049 import com.liferay.portal.kernel.model.WorkflowedModel;
050 import com.liferay.portal.kernel.search.facet.AssetEntriesFacet;
051 import com.liferay.portal.kernel.search.facet.Facet;
052 import com.liferay.portal.kernel.search.facet.MultiValueFacet;
053 import com.liferay.portal.kernel.search.facet.ScopeFacet;
054 import com.liferay.portal.kernel.search.filter.BooleanFilter;
055 import com.liferay.portal.kernel.search.filter.Filter;
056 import com.liferay.portal.kernel.search.filter.QueryFilter;
057 import com.liferay.portal.kernel.search.filter.TermsFilter;
058 import com.liferay.portal.kernel.search.generic.BooleanQueryImpl;
059 import com.liferay.portal.kernel.search.generic.MatchAllQuery;
060 import com.liferay.portal.kernel.search.hits.HitsProcessorRegistryUtil;
061 import com.liferay.portal.kernel.security.permission.PermissionChecker;
062 import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
063 import com.liferay.portal.kernel.service.CountryServiceUtil;
064 import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
065 import com.liferay.portal.kernel.service.RegionServiceUtil;
066 import com.liferay.portal.kernel.service.ServiceContext;
067 import com.liferay.portal.kernel.service.ServiceContextThreadLocal;
068 import com.liferay.portal.kernel.service.UserLocalServiceUtil;
069 import com.liferay.portal.kernel.trash.TrashHandler;
070 import com.liferay.portal.kernel.trash.TrashRenderer;
071 import com.liferay.portal.kernel.util.ArrayUtil;
072 import com.liferay.portal.kernel.util.GetterUtil;
073 import com.liferay.portal.kernel.util.HashUtil;
074 import com.liferay.portal.kernel.util.ListUtil;
075 import com.liferay.portal.kernel.util.LocaleUtil;
076 import com.liferay.portal.kernel.util.LocalizationUtil;
077 import com.liferay.portal.kernel.util.PortalUtil;
078 import com.liferay.portal.kernel.util.PropsKeys;
079 import com.liferay.portal.kernel.util.PropsUtil;
080 import com.liferay.portal.kernel.util.SetUtil;
081 import com.liferay.portal.kernel.util.StringPool;
082 import com.liferay.portal.kernel.util.StringUtil;
083 import com.liferay.portal.kernel.util.UnicodeProperties;
084 import com.liferay.portal.kernel.util.Validator;
085 import com.liferay.portal.kernel.workflow.WorkflowConstants;
086 import com.liferay.ratings.kernel.model.RatingsStats;
087 import com.liferay.ratings.kernel.service.RatingsStatsLocalServiceUtil;
088 import com.liferay.trash.kernel.model.TrashEntry;
089
090 import java.io.Serializable;
091
092 import java.util.ArrayList;
093 import java.util.Collection;
094 import java.util.Collections;
095 import java.util.Date;
096 import java.util.HashMap;
097 import java.util.HashSet;
098 import java.util.List;
099 import java.util.Locale;
100 import java.util.Map;
101 import java.util.Objects;
102 import java.util.Set;
103
104 import javax.portlet.PortletRequest;
105 import javax.portlet.PortletResponse;
106
107
113 public abstract class BaseIndexer<T> implements Indexer<T> {
114
115 @Override
116 public void delete(long companyId, String uid) throws SearchException {
117 try {
118 IndexWriterHelperUtil.deleteDocument(
119 getSearchEngineId(), companyId, uid, _commitImmediately);
120 }
121 catch (SearchException se) {
122 throw se;
123 }
124 catch (Exception e) {
125 throw new SearchException(e);
126 }
127 }
128
129 @Override
130 public void delete(T object) throws SearchException {
131 if (object == null) {
132 return;
133 }
134
135 try {
136 doDelete(object);
137 }
138 catch (SearchException se) {
139 throw se;
140 }
141 catch (Exception e) {
142 throw new SearchException(e);
143 }
144 }
145
146 @Override
147 public boolean equals(Object object) {
148 if (object == this) {
149 return true;
150 }
151
152 if (!(object instanceof Indexer<?>)) {
153 return false;
154 }
155
156 Indexer<?> indexer = (Indexer<?>)object;
157
158 return Objects.equals(getClassName(), indexer.getClassName());
159 }
160
161
164 @Deprecated
165 @Override
166 public String[] getClassNames() {
167 return getSearchClassNames();
168 }
169
170 @Override
171 public Document getDocument(T object) throws SearchException {
172 try {
173 Document document = doGetDocument(object);
174
175 for (IndexerPostProcessor indexerPostProcessor :
176 _indexerPostProcessors) {
177
178 indexerPostProcessor.postProcessDocument(document, object);
179 }
180
181 if (document == null) {
182 return null;
183 }
184
185 Map<String, Field> fields = document.getFields();
186
187 Field groupIdField = fields.get(Field.GROUP_ID);
188
189 if (groupIdField != null) {
190 long groupId = GetterUtil.getLong(groupIdField.getValue());
191
192 addStagingGroupKeyword(document, groupId);
193 }
194
195 return document;
196 }
197 catch (SearchException se) {
198 throw se;
199 }
200 catch (Exception e) {
201 throw new SearchException(e);
202 }
203 }
204
205 @Override
206 public BooleanFilter getFacetBooleanFilter(
207 String className, SearchContext searchContext)
208 throws Exception {
209
210 BooleanFilter facetBooleanFilter = new BooleanFilter();
211
212 facetBooleanFilter.addTerm(Field.ENTRY_CLASS_NAME, className);
213
214 if (searchContext.getUserId() > 0) {
215 SearchPermissionChecker searchPermissionChecker =
216 SearchEngineHelperUtil.getSearchPermissionChecker();
217
218 facetBooleanFilter =
219 searchPermissionChecker.getPermissionBooleanFilter(
220 searchContext.getCompanyId(), searchContext.getGroupIds(),
221 searchContext.getUserId(), className, facetBooleanFilter,
222 searchContext);
223 }
224
225 return facetBooleanFilter;
226 }
227
228 @Override
229 public BooleanQuery getFullQuery(SearchContext searchContext)
230 throws SearchException {
231
232 try {
233 searchContext.setSearchEngineId(getSearchEngineId());
234
235 resetFullQuery(searchContext);
236
237 String[] fullQueryEntryClassNames =
238 searchContext.getFullQueryEntryClassNames();
239
240 if (ArrayUtil.isNotEmpty(fullQueryEntryClassNames)) {
241 searchContext.setAttribute(
242 "relatedEntryClassNames", getSearchClassNames());
243 }
244
245 String[] entryClassNames = ArrayUtil.append(
246 getSearchClassNames(), fullQueryEntryClassNames);
247
248 searchContext.setEntryClassNames(entryClassNames);
249
250 BooleanFilter fullQueryBooleanFilter = new BooleanFilter();
251
252 addSearchAssetCategoryIds(fullQueryBooleanFilter, searchContext);
253 addSearchAssetTagNames(fullQueryBooleanFilter, searchContext);
254 addSearchEntryClassNames(fullQueryBooleanFilter, searchContext);
255 addSearchFolderId(fullQueryBooleanFilter, searchContext);
256 addSearchGroupId(fullQueryBooleanFilter, searchContext);
257 addSearchLayout(fullQueryBooleanFilter, searchContext);
258 addSearchUserId(fullQueryBooleanFilter, searchContext);
259
260 BooleanQuery fullQuery = createFullQuery(
261 fullQueryBooleanFilter, searchContext);
262
263 fullQuery.setQueryConfig(searchContext.getQueryConfig());
264
265 return fullQuery;
266 }
267 catch (SearchException se) {
268 throw se;
269 }
270 catch (Exception e) {
271 throw new SearchException(e);
272 }
273 }
274
275 @Override
276 public IndexerPostProcessor[] getIndexerPostProcessors() {
277 return _indexerPostProcessors;
278 }
279
280
283 @Deprecated
284 @Override
285 public String getPortletId() {
286 return StringPool.BLANK;
287 }
288
289 @Override
290 public String[] getSearchClassNames() {
291 return new String[] {getClassName()};
292 }
293
294 @Override
295 public String getSearchEngineId() {
296 if (_searchEngineId != null) {
297 return _searchEngineId;
298 }
299
300 Class<?> clazz = getClass();
301
302 String searchEngineId = GetterUtil.getString(
303 PropsUtil.get(
304 PropsKeys.INDEX_SEARCH_ENGINE_ID,
305 new com.liferay.portal.kernel.configuration.Filter(
306 clazz.getName())));
307
308 if (Validator.isNotNull(searchEngineId)) {
309 SearchEngine searchEngine = SearchEngineHelperUtil.getSearchEngine(
310 searchEngineId);
311
312 if (searchEngine != null) {
313 _searchEngineId = searchEngineId;
314 }
315 }
316
317 if (_searchEngineId == null) {
318 _searchEngineId = SearchEngineHelperUtil.getDefaultSearchEngineId();
319 }
320
321 if (_log.isDebugEnabled()) {
322 _log.debug(
323 "Search engine ID for " + clazz.getName() + " is " +
324 searchEngineId);
325 }
326
327 return _searchEngineId;
328 }
329
330 @Override
331 public String getSortField(String orderByCol) {
332 String sortField = doGetSortField(orderByCol);
333
334 if (_document.isDocumentSortableTextField(sortField)) {
335 return DocumentImpl.getSortableFieldName(sortField);
336 }
337
338 return sortField;
339 }
340
341 @Override
342 public String getSortField(String orderByCol, int sortType) {
343 if ((sortType == Sort.DOUBLE_TYPE) || (sortType == Sort.FLOAT_TYPE) ||
344 (sortType == Sort.INT_TYPE) || (sortType == Sort.LONG_TYPE)) {
345
346 return DocumentImpl.getSortableFieldName(orderByCol);
347 }
348
349 return getSortField(orderByCol);
350 }
351
352
356 @Deprecated
357 @Override
358 public Summary getSummary(Document document, Locale locale, String snippet)
359 throws SearchException {
360
361 return getSummary(document, snippet, null, null);
362 }
363
364 @Override
365 public Summary getSummary(
366 Document document, String snippet, PortletRequest portletRequest,
367 PortletResponse portletResponse)
368 throws SearchException {
369
370 try {
371 Locale locale = getLocale(portletRequest);
372
373 Summary summary = doGetSummary(
374 document, locale, snippet, portletRequest, portletResponse);
375
376 for (IndexerPostProcessor indexerPostProcessor :
377 _indexerPostProcessors) {
378
379 indexerPostProcessor.postProcessSummary(
380 summary, document, locale, snippet);
381 }
382
383 return summary;
384 }
385 catch (SearchException se) {
386 throw se;
387 }
388 catch (Exception e) {
389 throw new SearchException(e);
390 }
391 }
392
393 @Override
394 public int hashCode() {
395 return HashUtil.hash(0, getClassName());
396 }
397
398 @Override
399 public boolean hasPermission(
400 PermissionChecker permissionChecker, String entryClassName,
401 long entryClassPK, String actionId)
402 throws Exception {
403
404 return true;
405 }
406
407 @Override
408 public boolean isCommitImmediately() {
409 return _commitImmediately;
410 }
411
412 @Override
413 public boolean isFilterSearch() {
414 return _filterSearch;
415 }
416
417 @Override
418 public boolean isIndexerEnabled() {
419 String className = getClassName();
420
421 if (_indexerEnabled == null) {
422 String indexerEnabled = PropsUtil.get(
423 PropsKeys.INDEXER_ENABLED,
424 new com.liferay.portal.kernel.configuration.Filter(className));
425
426 _indexerEnabled = GetterUtil.getBoolean(indexerEnabled, true);
427
428 return _indexerEnabled;
429 }
430
431 return _indexerEnabled;
432 }
433
434 @Override
435 public boolean isPermissionAware() {
436 return _permissionAware;
437 }
438
439 public boolean isSelectAllLocales() {
440 return _selectAllLocales;
441 }
442
443 @Override
444 public boolean isStagingAware() {
445 return _stagingAware;
446 }
447
448 @Override
449 public boolean isVisible(long classPK, int status) throws Exception {
450 return true;
451 }
452
453 @Override
454 public boolean isVisibleRelatedEntry(long classPK, int status)
455 throws Exception {
456
457 return true;
458 }
459
460 @Override
461 public void postProcessContextBooleanFilter(
462 BooleanFilter contextBooleanFilter, SearchContext searchContext)
463 throws Exception {
464 }
465
466
471 @Deprecated
472 @Override
473 public void postProcessContextQuery(
474 BooleanQuery contextQuery, SearchContext searchContext)
475 throws Exception {
476 }
477
478 @Override
479 public void postProcessSearchQuery(
480 BooleanQuery searchQuery, BooleanFilter fullQueryBooleanFilter,
481 SearchContext searchContext)
482 throws Exception {
483
484 String keywords = searchContext.getKeywords();
485
486 if (Validator.isNull(keywords)) {
487 addSearchTerm(searchQuery, searchContext, Field.DESCRIPTION, false);
488 addSearchTerm(searchQuery, searchContext, Field.TITLE, false);
489 addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
490 }
491 }
492
493
498 @Deprecated
499 @Override
500 public void postProcessSearchQuery(
501 BooleanQuery searchQuery, SearchContext searchContext)
502 throws Exception {
503 }
504
505 @Override
506 public void registerIndexerPostProcessor(
507 IndexerPostProcessor indexerPostProcessor) {
508
509 List<IndexerPostProcessor> indexerPostProcessorsList =
510 ListUtil.fromArray(_indexerPostProcessors);
511
512 indexerPostProcessorsList.add(indexerPostProcessor);
513
514 _indexerPostProcessors = indexerPostProcessorsList.toArray(
515 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
516 }
517
518 @Override
519 public void reindex(Collection<T> collection) {
520 if (IndexWriterHelperUtil.isIndexReadOnly() || !isIndexerEnabled() ||
521 collection.isEmpty()) {
522
523 return;
524 }
525
526 for (T element : collection) {
527 try {
528 reindex(element);
529 }
530 catch (SearchException se) {
531 _log.error("Unable to index object: " + element);
532 }
533 }
534 }
535
536 @Override
537 public void reindex(String className, long classPK) throws SearchException {
538 try {
539 if (IndexWriterHelperUtil.isIndexReadOnly() ||
540 !isIndexerEnabled() || (classPK <= 0)) {
541
542 return;
543 }
544
545 doReindex(className, classPK);
546 }
547 catch (NoSuchModelException nsme) {
548 if (_log.isWarnEnabled()) {
549 _log.warn("Unable to index " + className + " " + classPK, nsme);
550 }
551 }
552 catch (SearchException se) {
553 throw se;
554 }
555 catch (Exception e) {
556 throw new SearchException(e);
557 }
558 }
559
560 @Override
561 public void reindex(String[] ids) throws SearchException {
562 try {
563 if (IndexWriterHelperUtil.isIndexReadOnly() ||
564 !isIndexerEnabled()) {
565
566 return;
567 }
568
569 doReindex(ids);
570 }
571 catch (SearchException se) {
572 throw se;
573 }
574 catch (Exception e) {
575 throw new SearchException(e);
576 }
577 }
578
579 @Override
580 public void reindex(T object) throws SearchException {
581 try {
582 if (IndexWriterHelperUtil.isIndexReadOnly() ||
583 !isIndexerEnabled()) {
584
585 return;
586 }
587
588 if (object == null) {
589 return;
590 }
591
592 doReindex(object);
593 }
594 catch (SearchException se) {
595 throw se;
596 }
597 catch (Exception e) {
598 throw new SearchException(e);
599 }
600 }
601
602 @Override
603 public Hits search(SearchContext searchContext) throws SearchException {
604 try {
605 Hits hits = null;
606
607 QueryConfig queryConfig = searchContext.getQueryConfig();
608
609 addDefaultHighlightFieldNames(queryConfig);
610
611 if (ArrayUtil.isEmpty(queryConfig.getSelectedFieldNames())) {
612 addDefaultSelectedFieldNames(searchContext);
613 }
614
615 addFacetSelectedFieldNames(searchContext, queryConfig);
616
617 PermissionChecker permissionChecker =
618 PermissionThreadLocal.getPermissionChecker();
619
620 if ((permissionChecker != null) &&
621 isUseSearchResultPermissionFilter(searchContext)) {
622
623 if (searchContext.getUserId() == 0) {
624 searchContext.setUserId(permissionChecker.getUserId());
625 }
626
627 SearchResultPermissionFilter searchResultPermissionFilter =
628 new DefaultSearchResultPermissionFilter(
629 this, permissionChecker);
630
631 hits = searchResultPermissionFilter.search(searchContext);
632 }
633 else {
634 hits = doSearch(searchContext);
635 }
636
637 processHits(searchContext, hits);
638
639 return hits;
640 }
641 catch (SearchException se) {
642 throw se;
643 }
644 catch (Exception e) {
645 throw new SearchException(e);
646 }
647 }
648
649 @Override
650 public Hits search(
651 SearchContext searchContext, String... selectedFieldNames)
652 throws SearchException {
653
654 QueryConfig queryConfig = searchContext.getQueryConfig();
655
656 queryConfig.setSelectedFieldNames(selectedFieldNames);
657
658 return search(searchContext);
659 }
660
661 @Override
662 public long searchCount(SearchContext searchContext)
663 throws SearchException {
664
665 PermissionChecker permissionChecker =
666 PermissionThreadLocal.getPermissionChecker();
667
668 if ((permissionChecker != null) &&
669 isUseSearchResultPermissionFilter(searchContext)) {
670
671 Hits hits = search(searchContext);
672
673 return hits.getLength();
674 }
675
676 QueryConfig queryConfig = searchContext.getQueryConfig();
677
678 queryConfig.setHighlightEnabled(false);
679 queryConfig.setHitsProcessingEnabled(false);
680 queryConfig.setScoreEnabled(false);
681 queryConfig.setQueryIndexingEnabled(false);
682 queryConfig.setQuerySuggestionEnabled(false);
683
684 searchContext.setSearchEngineId(getSearchEngineId());
685
686 BooleanQuery fullQuery = getFullQuery(searchContext);
687
688 fullQuery.setQueryConfig(queryConfig);
689
690 return IndexSearcherHelperUtil.searchCount(searchContext, fullQuery);
691 }
692
693 public void setCommitImmediately(boolean commitImmediately) {
694 _commitImmediately = commitImmediately;
695 }
696
697 @Override
698 public void setIndexerEnabled(boolean indexerEnabled) {
699 _indexerEnabled = indexerEnabled;
700 }
701
702 public void setSelectAllLocales(boolean selectAllLocales) {
703 _selectAllLocales = selectAllLocales;
704 }
705
706 @Override
707 public void unregisterIndexerPostProcessor(
708 IndexerPostProcessor indexerPostProcessor) {
709
710 List<IndexerPostProcessor> indexerPostProcessorsList =
711 ListUtil.fromArray(_indexerPostProcessors);
712
713 indexerPostProcessorsList.remove(indexerPostProcessor);
714
715 _indexerPostProcessors = indexerPostProcessorsList.toArray(
716 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
717 }
718
719 protected void addAssetFields(
720 Document document, String className, long classPK) {
721
722 AssetRendererFactory<?> assetRendererFactory =
723 AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
724 className);
725
726 if ((assetRendererFactory == null) ||
727 !assetRendererFactory.isSelectable()) {
728
729 return;
730 }
731
732 AssetEntry assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
733 className, classPK);
734
735 if (assetEntry == null) {
736 return;
737 }
738
739 if (!document.hasField(Field.CREATE_DATE)) {
740 document.addDate(Field.CREATE_DATE, assetEntry.getCreateDate());
741 }
742
743 if (assetEntry.getExpirationDate() != null) {
744 document.addDate(
745 Field.EXPIRATION_DATE, assetEntry.getExpirationDate());
746 }
747 else {
748 document.addDate(Field.EXPIRATION_DATE, new Date(Long.MAX_VALUE));
749 }
750
751 if (!document.hasField(Field.MODIFIED_DATE)) {
752 document.addDate(Field.MODIFIED_DATE, assetEntry.getModifiedDate());
753 }
754
755 document.addNumber(Field.PRIORITY, assetEntry.getPriority());
756
757 if (assetEntry.getPublishDate() != null) {
758 document.addDate(Field.PUBLISH_DATE, assetEntry.getPublishDate());
759 }
760 else {
761 document.addDate(Field.PUBLISH_DATE, new Date(0));
762 }
763
764 RatingsStats ratingsStats = RatingsStatsLocalServiceUtil.fetchStats(
765 className, classPK);
766
767 if (ratingsStats != null) {
768 document.addNumber(Field.RATINGS, ratingsStats.getAverageScore());
769 }
770 else {
771 document.addNumber(Field.RATINGS, 0.0f);
772 }
773
774 document.addNumber(Field.VIEW_COUNT, assetEntry.getViewCount());
775
776 document.addLocalizedKeyword(
777 "localized_title",
778 populateMap(assetEntry, assetEntry.getTitleMap()), true, true);
779 document.addKeyword("visible", assetEntry.isVisible());
780 }
781
782 protected void addDefaultHighlightFieldNames(QueryConfig queryConfig) {
783 queryConfig.addHighlightFieldNames(Field.ASSET_CATEGORY_TITLES);
784
785 if (queryConfig.isHighlightEnabled()) {
786 queryConfig.addHighlightFieldNames(
787 Field.CONTENT, Field.DESCRIPTION, Field.TITLE);
788 }
789 }
790
791 protected void addDefaultSelectedFieldNames(SearchContext searchContext) {
792 QueryConfig queryConfig = searchContext.getQueryConfig();
793
794 Set<String> selectedFieldNames = null;
795
796 if (!ArrayUtil.isEmpty(getDefaultSelectedFieldNames())) {
797 selectedFieldNames = SetUtil.fromArray(
798 getDefaultSelectedFieldNames());
799
800 if (searchContext.isIncludeAttachments() ||
801 searchContext.isIncludeDiscussions()) {
802
803 selectedFieldNames.add(Field.CLASS_NAME_ID);
804 selectedFieldNames.add(Field.CLASS_PK);
805 }
806 }
807
808 if (!ArrayUtil.isEmpty(getDefaultSelectedLocalizedFieldNames())) {
809 if (selectedFieldNames == null) {
810 selectedFieldNames = new HashSet<>();
811 }
812
813 if (isSelectAllLocales()) {
814 addSelectedLocalizedFieldNames(
815 selectedFieldNames,
816 LocaleUtil.toLanguageIds(
817 LanguageUtil.getSupportedLocales()));
818 }
819 else {
820 addSelectedLocalizedFieldNames(
821 selectedFieldNames,
822 LocaleUtil.toLanguageId(queryConfig.getLocale()));
823 }
824 }
825
826 if ((selectedFieldNames != null) && !selectedFieldNames.isEmpty()) {
827 queryConfig.setSelectedFieldNames(
828 selectedFieldNames.toArray(
829 new String[selectedFieldNames.size()]));
830 }
831 }
832
833
836 @Deprecated
837 protected void addFacetClause(
838 SearchContext searchContext, BooleanFilter facetBooleanFilter,
839 Collection<Facet> facets)
840 throws ParseException {
841
842 BooleanQuery facetBooleanQuery = new BooleanQueryImpl();
843
844 for (Facet facet : facets) {
845 BooleanClause<Query> facetBooleanClause = facet.getFacetClause();
846
847 if (facetBooleanClause != null) {
848 facetBooleanQuery.add(
849 facetBooleanClause.getClause(),
850 facetBooleanClause.getBooleanClauseOccur());
851 }
852 }
853
854 if (!facetBooleanQuery.hasClauses()) {
855 return;
856 }
857
858 QueryFilter queryFilter = new QueryFilter(facetBooleanQuery);
859
860 facetBooleanFilter.add(queryFilter, BooleanClauseOccur.MUST);
861 }
862
863 protected void addFacetSelectedFieldNames(
864 SearchContext searchContext, QueryConfig queryConfig) {
865
866 String[] selectedFieldNames = queryConfig.getSelectedFieldNames();
867
868 if (ArrayUtil.isEmpty(selectedFieldNames) ||
869 (selectedFieldNames.length == 1) &&
870 selectedFieldNames[0].equals(Field.ANY)) {
871
872 return;
873 }
874
875 Set<String> selectedFieldNameSet = SetUtil.fromArray(
876 selectedFieldNames);
877
878 Map<String, Facet> facets = searchContext.getFacets();
879
880 selectedFieldNameSet.addAll(facets.keySet());
881
882 selectedFieldNames = selectedFieldNameSet.toArray(
883 new String[selectedFieldNameSet.size()]);
884
885 queryConfig.setSelectedFieldNames(selectedFieldNames);
886 }
887
888 protected void addSearchAssetCategoryIds(
889 BooleanFilter queryBooleanFilter, SearchContext searchContext)
890 throws Exception {
891
892 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
893
894 multiValueFacet.setFieldName(Field.ASSET_CATEGORY_IDS);
895 multiValueFacet.setStatic(true);
896 multiValueFacet.setValues(searchContext.getAssetCategoryIds());
897
898 searchContext.addFacet(multiValueFacet);
899 }
900
901 protected void addSearchAssetCategoryTitles(
902 Document document, String field, List<AssetCategory> assetCategories) {
903
904 Map<Locale, List<String>> assetCategoryTitles = new HashMap<>();
905
906 Locale defaultLocale = LocaleUtil.getDefault();
907
908 for (AssetCategory assetCategory : assetCategories) {
909 Map<Locale, String> titleMap = assetCategory.getTitleMap();
910
911 for (Map.Entry<Locale, String> entry : titleMap.entrySet()) {
912 Locale locale = entry.getKey();
913 String title = entry.getValue();
914
915 if (Validator.isNull(title)) {
916 continue;
917 }
918
919 List<String> titles = assetCategoryTitles.get(locale);
920
921 if (titles == null) {
922 titles = new ArrayList<>();
923
924 assetCategoryTitles.put(locale, titles);
925 }
926
927 titles.add(StringUtil.toLowerCase(title));
928 }
929 }
930
931 for (Map.Entry<Locale, List<String>> entry :
932 assetCategoryTitles.entrySet()) {
933
934 Locale locale = entry.getKey();
935 List<String> titles = entry.getValue();
936
937 String[] titlesArray = titles.toArray(new String[titles.size()]);
938
939 if (locale.equals(defaultLocale)) {
940 document.addText(field, titlesArray);
941 }
942
943 document.addText(
944 field.concat(StringPool.UNDERLINE).concat(locale.toString()),
945 titlesArray);
946 }
947 }
948
949 protected void addSearchAssetTagNames(
950 BooleanFilter queryBooleanFilter, SearchContext searchContext)
951 throws Exception {
952
953 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
954
955 multiValueFacet.setFieldName(Field.ASSET_TAG_NAMES);
956 multiValueFacet.setStatic(true);
957 multiValueFacet.setValues(searchContext.getAssetTagNames());
958
959 searchContext.addFacet(multiValueFacet);
960 }
961
962 protected Filter addSearchClassTypeIds(
963 BooleanFilter contextBooleanFilter, SearchContext searchContext)
964 throws Exception {
965
966 long[] classTypeIds = searchContext.getClassTypeIds();
967
968 if (ArrayUtil.isEmpty(classTypeIds)) {
969 return null;
970 }
971
972 TermsFilter classTypeIdsTermsFilter = new TermsFilter(
973 Field.CLASS_TYPE_ID);
974
975 classTypeIdsTermsFilter.addValues(
976 ArrayUtil.toStringArray(classTypeIds));
977
978 return contextBooleanFilter.add(
979 classTypeIdsTermsFilter, BooleanClauseOccur.MUST);
980 }
981
982 protected void addSearchEntryClassNames(
983 BooleanFilter queryBooleanFilter, SearchContext searchContext)
984 throws Exception {
985
986 Facet facet = new AssetEntriesFacet(searchContext);
987
988 facet.setStatic(true);
989
990 searchContext.addFacet(facet);
991 }
992
993 protected Map<String, Query> addSearchExpando(
994 BooleanQuery searchQuery, SearchContext searchContext,
995 String keywords)
996 throws Exception {
997
998 Map<String, Query> expandoQueries = new HashMap<>();
999
1000 ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
1001 searchContext.getCompanyId(), getClassName(searchContext));
1002
1003 Set<String> attributeNames = SetUtil.fromEnumeration(
1004 expandoBridge.getAttributeNames());
1005
1006 for (String attributeName : attributeNames) {
1007 UnicodeProperties properties = expandoBridge.getAttributeProperties(
1008 attributeName);
1009
1010 int indexType = GetterUtil.getInteger(
1011 properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
1012
1013 if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
1014 String fieldName = getExpandoFieldName(
1015 searchContext, expandoBridge, attributeName);
1016
1017 if (Validator.isNotNull(keywords)) {
1018 if (searchContext.isAndSearch()) {
1019 Query query = searchQuery.addRequiredTerm(
1020 fieldName, keywords);
1021
1022 expandoQueries.put(attributeName, query);
1023 }
1024 else {
1025 Query query = searchQuery.addTerm(fieldName, keywords);
1026
1027 expandoQueries.put(attributeName, query);
1028 }
1029 }
1030 }
1031 }
1032
1033 return expandoQueries;
1034 }
1035
1036 protected void addSearchFolderId(
1037 BooleanFilter queryBooleanFilter, SearchContext searchContext)
1038 throws Exception {
1039
1040 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
1041
1042 multiValueFacet.setFieldName(Field.TREE_PATH);
1043 multiValueFacet.setStatic(true);
1044
1045 long[] folderIds = searchContext.getFolderIds();
1046
1047 if (ArrayUtil.isNotEmpty(folderIds)) {
1048 folderIds = ArrayUtil.remove(folderIds, _DEFAULT_FOLDER_ID);
1049
1050 multiValueFacet.setValues(folderIds);
1051 }
1052
1053 searchContext.addFacet(multiValueFacet);
1054 }
1055
1056 protected void addSearchGroupId(
1057 BooleanFilter queryBooleanFilter, SearchContext searchContext)
1058 throws Exception {
1059
1060 Facet facet = new ScopeFacet(searchContext);
1061
1062 facet.setStatic(true);
1063
1064 searchContext.addFacet(facet);
1065 }
1066
1067 protected Map<String, Query> addSearchKeywords(
1068 BooleanQuery searchQuery, SearchContext searchContext)
1069 throws Exception {
1070
1071 String keywords = searchContext.getKeywords();
1072
1073 if (Validator.isNull(keywords)) {
1074 return Collections.emptyMap();
1075 }
1076
1077 addSearchExpando(searchQuery, searchContext, keywords);
1078
1079 addSearchLocalizedTerm(
1080 searchQuery, searchContext, Field.ASSET_CATEGORY_TITLES,
1081 searchContext.isLike());
1082
1083 return searchQuery.addTerms(
1084 Field.KEYWORDS, keywords, searchContext.isLike());
1085 }
1086
1087 protected void addSearchLayout(
1088 BooleanFilter queryBooleanFilter, SearchContext searchContext)
1089 throws Exception {
1090
1091 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
1092
1093 multiValueFacet.setFieldName(Field.LAYOUT_UUID);
1094 multiValueFacet.setStatic(true);
1095
1096 searchContext.addFacet(multiValueFacet);
1097 }
1098
1099 protected Map<String, Query> addSearchLocalizedTerm(
1100 BooleanQuery searchQuery, SearchContext searchContext, String field,
1101 boolean like)
1102 throws Exception {
1103
1104 Map<String, Query> queries = new HashMap<>();
1105
1106 Query query = addSearchTerm(searchQuery, searchContext, field, like);
1107
1108 queries.put(field, query);
1109
1110 String localizedFieldName = DocumentImpl.getLocalizedName(
1111 searchContext.getLocale(), field);
1112
1113 Query localizedQuery = addSearchTerm(
1114 searchQuery, searchContext, localizedFieldName, like);
1115
1116 queries.put(localizedFieldName, localizedQuery);
1117
1118 return queries;
1119 }
1120
1121 protected Query addSearchTerm(
1122 BooleanQuery searchQuery, SearchContext searchContext, String field,
1123 boolean like)
1124 throws Exception {
1125
1126 if (Validator.isNull(field)) {
1127 return null;
1128 }
1129
1130 String value = null;
1131
1132 Serializable serializable = searchContext.getAttribute(field);
1133
1134 if (serializable != null) {
1135 Class<?> clazz = serializable.getClass();
1136
1137 if (clazz.isArray()) {
1138 value = StringUtil.merge((Object[])serializable);
1139 }
1140 else {
1141 value = GetterUtil.getString(serializable);
1142 }
1143 }
1144 else {
1145 value = GetterUtil.getString(serializable);
1146 }
1147
1148 if (Validator.isNotNull(value) &&
1149 (searchContext.getFacet(field) != null)) {
1150
1151 return null;
1152 }
1153
1154 if (Validator.isNull(value)) {
1155 value = searchContext.getKeywords();
1156 }
1157
1158 if (Validator.isNull(value)) {
1159 return null;
1160 }
1161
1162 Query query = null;
1163
1164 if (searchContext.isAndSearch()) {
1165 query = searchQuery.addRequiredTerm(field, value, like);
1166 }
1167 else {
1168 query = searchQuery.addTerm(field, value, like);
1169 }
1170
1171 return query;
1172 }
1173
1174 protected void addSearchUserId(
1175 BooleanFilter queryBooleanFilter, SearchContext searchContext)
1176 throws Exception {
1177
1178 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
1179
1180 multiValueFacet.setFieldName(Field.USER_ID);
1181 multiValueFacet.setStatic(true);
1182
1183 long userId = GetterUtil.getLong(
1184 searchContext.getAttribute(Field.USER_ID));
1185
1186 if (userId > 0) {
1187 multiValueFacet.setValues(new long[] {userId});
1188 }
1189
1190 searchContext.addFacet(multiValueFacet);
1191 }
1192
1193 protected void addSelectedLocalizedFieldNames(
1194 Set<String> selectedFieldNames, String... languageIds) {
1195
1196 for (String defaultLocalizedSelectedFieldName :
1197 getDefaultSelectedLocalizedFieldNames()) {
1198
1199 selectedFieldNames.add(defaultLocalizedSelectedFieldName);
1200
1201 for (String languageId : languageIds) {
1202 String localizedFieldName = LocalizationUtil.getLocalizedName(
1203 defaultLocalizedSelectedFieldName, languageId);
1204
1205 selectedFieldNames.add(localizedFieldName);
1206 }
1207 }
1208 }
1209
1210 protected void addStagingGroupKeyword(Document document, long groupId) {
1211 if (!isStagingAware()) {
1212 return;
1213 }
1214
1215 document.addKeyword(Field.STAGING_GROUP, isStagingGroup(groupId));
1216 }
1217
1218 protected void addStatus(
1219 BooleanFilter contextBooleanFilter, SearchContext searchContext)
1220 throws Exception {
1221
1222 int[] statuses = GetterUtil.getIntegerValues(
1223 searchContext.getAttribute(Field.STATUS), null);
1224
1225 if (ArrayUtil.isEmpty(statuses)) {
1226 int status = GetterUtil.getInteger(
1227 searchContext.getAttribute(Field.STATUS),
1228 WorkflowConstants.STATUS_APPROVED);
1229
1230 statuses = new int[] {status};
1231 }
1232
1233 if (!ArrayUtil.contains(statuses, WorkflowConstants.STATUS_ANY)) {
1234 TermsFilter statusesTermsFilter = new TermsFilter(Field.STATUS);
1235
1236 statusesTermsFilter.addValues(ArrayUtil.toStringArray(statuses));
1237
1238 contextBooleanFilter.add(
1239 statusesTermsFilter, BooleanClauseOccur.MUST);
1240 }
1241 else {
1242 contextBooleanFilter.addTerm(
1243 Field.STATUS, String.valueOf(WorkflowConstants.STATUS_IN_TRASH),
1244 BooleanClauseOccur.MUST_NOT);
1245 }
1246 }
1247
1248 protected void addTrashFields(
1249 Document document, TrashedModel trashedModel) {
1250
1251 TrashEntry trashEntry = null;
1252
1253 try {
1254 trashEntry = trashedModel.getTrashEntry();
1255 }
1256 catch (PortalException pe) {
1257 if (_log.isDebugEnabled()) {
1258 _log.debug("Unable to get trash entry for " + trashedModel);
1259 }
1260 }
1261
1262 if (trashEntry == null) {
1263 document.addDate(Field.REMOVED_DATE, new Date());
1264
1265 ServiceContext serviceContext =
1266 ServiceContextThreadLocal.getServiceContext();
1267
1268 if (serviceContext != null) {
1269 try {
1270 User user = UserLocalServiceUtil.getUser(
1271 serviceContext.getUserId());
1272
1273 document.addKeyword(
1274 Field.REMOVED_BY_USER_NAME, user.getFullName(), true);
1275 }
1276 catch (PortalException pe) {
1277 if (_log.isDebugEnabled()) {
1278 _log.debug(
1279 "Unable to locate user: " +
1280 serviceContext.getUserId(),
1281 pe);
1282 }
1283 }
1284 }
1285 }
1286 else {
1287 document.addDate(Field.REMOVED_DATE, trashEntry.getCreateDate());
1288 document.addKeyword(
1289 Field.REMOVED_BY_USER_NAME, trashEntry.getUserName(), true);
1290
1291 if (trashedModel.isInTrash() &&
1292 !trashedModel.isInTrashExplicitly()) {
1293
1294 document.addKeyword(
1295 Field.ROOT_ENTRY_CLASS_NAME, trashEntry.getClassName());
1296 document.addKeyword(
1297 Field.ROOT_ENTRY_CLASS_PK, trashEntry.getClassPK());
1298 }
1299 }
1300
1301 TrashHandler trashHandler = trashedModel.getTrashHandler();
1302
1303 try {
1304 TrashRenderer trashRenderer = null;
1305
1306 if ((trashHandler != null) && (trashEntry != null)) {
1307 trashRenderer = trashHandler.getTrashRenderer(
1308 trashEntry.getClassPK());
1309 }
1310
1311 if (trashRenderer != null) {
1312 document.addKeyword(Field.TYPE, trashRenderer.getType(), true);
1313 }
1314 }
1315 catch (PortalException pe) {
1316 if (_log.isDebugEnabled()) {
1317 _log.debug(
1318 "Unable to get trash renderer for " +
1319 trashEntry.getClassName());
1320 }
1321 }
1322 }
1323
1324 protected BooleanQuery createFullQuery(
1325 BooleanFilter fullQueryBooleanFilter, SearchContext searchContext)
1326 throws Exception {
1327
1328 BooleanQuery searchQuery = new BooleanQueryImpl();
1329
1330 addSearchKeywords(searchQuery, searchContext);
1331 postProcessSearchQuery(
1332 searchQuery, fullQueryBooleanFilter, searchContext);
1333
1334 for (IndexerPostProcessor indexerPostProcessor :
1335 _indexerPostProcessors) {
1336
1337 indexerPostProcessor.postProcessSearchQuery(
1338 searchQuery, fullQueryBooleanFilter, searchContext);
1339 }
1340
1341 doPostProcessSearchQuery(this, searchQuery, searchContext);
1342
1343 Map<String, Facet> facets = searchContext.getFacets();
1344
1345 BooleanFilter facetBooleanFilter = new BooleanFilter();
1346
1347 for (Facet facet : facets.values()) {
1348 BooleanClause<Filter> filterBooleanClause =
1349 facet.getFacetFilterBooleanClause();
1350
1351 if (filterBooleanClause != null) {
1352 facetBooleanFilter.add(
1353 filterBooleanClause.getClause(),
1354 filterBooleanClause.getBooleanClauseOccur());
1355 }
1356 }
1357
1358 addFacetClause(searchContext, facetBooleanFilter, facets.values());
1359
1360 if (facetBooleanFilter.hasClauses()) {
1361 fullQueryBooleanFilter.add(
1362 facetBooleanFilter, BooleanClauseOccur.MUST);
1363 }
1364
1365 BooleanQuery fullBooleanQuery = new BooleanQueryImpl();
1366
1367 if (fullQueryBooleanFilter.hasClauses()) {
1368 fullBooleanQuery.setPreBooleanFilter(fullQueryBooleanFilter);
1369 }
1370
1371 if (searchQuery.hasClauses()) {
1372 fullBooleanQuery.add(searchQuery, BooleanClauseOccur.MUST);
1373 }
1374
1375 BooleanClause<Query>[] booleanClauses =
1376 searchContext.getBooleanClauses();
1377
1378 if (booleanClauses != null) {
1379 for (BooleanClause<Query> booleanClause : booleanClauses) {
1380 fullBooleanQuery.add(
1381 booleanClause.getClause(),
1382 booleanClause.getBooleanClauseOccur());
1383 }
1384 }
1385
1386 postProcessFullQuery(fullBooleanQuery, searchContext);
1387
1388 for (IndexerPostProcessor indexerPostProcessor :
1389 _indexerPostProcessors) {
1390
1391 indexerPostProcessor.postProcessFullQuery(
1392 fullBooleanQuery, searchContext);
1393 }
1394
1395 return fullBooleanQuery;
1396 }
1397
1398 protected Summary createSummary(Document document) {
1399 return createSummary(document, Field.TITLE, Field.CONTENT);
1400 }
1401
1402 protected Summary createSummary(
1403 Document document, String titleField, String contentField) {
1404
1405 String prefix = Field.SNIPPET + StringPool.UNDERLINE;
1406
1407 String title = document.get(prefix + titleField, titleField);
1408 String content = document.get(prefix + contentField, contentField);
1409
1410 return new Summary(title, content);
1411 }
1412
1413 protected void deleteDocument(long companyId, long field1)
1414 throws Exception {
1415
1416 deleteDocument(companyId, String.valueOf(field1));
1417 }
1418
1419 protected void deleteDocument(long companyId, long field1, String field2)
1420 throws Exception {
1421
1422 deleteDocument(companyId, String.valueOf(field1), field2);
1423 }
1424
1425 protected void deleteDocument(long companyId, String field1)
1426 throws Exception {
1427
1428 Document document = new DocumentImpl();
1429
1430 document.addUID(getClassName(), field1);
1431
1432 IndexWriterHelperUtil.deleteDocument(
1433 getSearchEngineId(), companyId, document.get(Field.UID),
1434 _commitImmediately);
1435 }
1436
1437 protected void deleteDocument(long companyId, String field1, String field2)
1438 throws Exception {
1439
1440 Document document = new DocumentImpl();
1441
1442 document.addUID(getClassName(), field1, field2);
1443
1444 IndexWriterHelperUtil.deleteDocument(
1445 getSearchEngineId(), companyId, document.get(Field.UID),
1446 _commitImmediately);
1447 }
1448
1449 protected abstract void doDelete(T object) throws Exception;
1450
1451 protected abstract Document doGetDocument(T object) throws Exception;
1452
1453 protected String doGetSortField(String orderByCol) {
1454 return orderByCol;
1455 }
1456
1457 protected abstract Summary doGetSummary(
1458 Document document, Locale locale, String snippet,
1459 PortletRequest portletRequest, PortletResponse portletResponse)
1460 throws Exception;
1461
1462
1467 @Deprecated
1468 protected void doPostProcessSearchQuery(
1469 Indexer<?> indexer, BooleanQuery searchQuery,
1470 SearchContext searchContext)
1471 throws Exception {
1472
1473 indexer.postProcessSearchQuery(searchQuery, searchContext);
1474
1475 for (IndexerPostProcessor indexerPostProcessor :
1476 indexer.getIndexerPostProcessors()) {
1477
1478 indexerPostProcessor.postProcessSearchQuery(
1479 searchQuery, searchContext);
1480 }
1481 }
1482
1483 protected abstract void doReindex(String className, long classPK)
1484 throws Exception;
1485
1486 protected abstract void doReindex(String[] ids) throws Exception;
1487
1488 protected abstract void doReindex(T object) throws Exception;
1489
1490 protected Hits doSearch(SearchContext searchContext)
1491 throws SearchException {
1492
1493 searchContext.setSearchEngineId(getSearchEngineId());
1494
1495 Query fullQuery = getFullQuery(searchContext);
1496
1497 if (!fullQuery.hasChildren()) {
1498 BooleanFilter preBooleanFilter = fullQuery.getPreBooleanFilter();
1499
1500 fullQuery = new MatchAllQuery();
1501
1502 fullQuery.setPreBooleanFilter(preBooleanFilter);
1503 }
1504
1505 QueryConfig queryConfig = searchContext.getQueryConfig();
1506
1507 fullQuery.setQueryConfig(queryConfig);
1508
1509 return IndexSearcherHelperUtil.search(searchContext, fullQuery);
1510 }
1511
1512 protected Document getBaseModelDocument(
1513 String portletId, BaseModel<?> baseModel) {
1514
1515 return getBaseModelDocument(portletId, baseModel, baseModel);
1516 }
1517
1518 protected Document getBaseModelDocument(
1519 String portletId, BaseModel<?> baseModel,
1520 BaseModel<?> workflowedBaseModel) {
1521
1522 Document document = newDocument();
1523
1524 String className = baseModel.getModelClassName();
1525
1526 long classPK = 0;
1527 long resourcePrimKey = 0;
1528
1529 if (baseModel instanceof ResourcedModel) {
1530 ResourcedModel resourcedModel = (ResourcedModel)baseModel;
1531
1532 classPK = resourcedModel.getResourcePrimKey();
1533 resourcePrimKey = resourcedModel.getResourcePrimKey();
1534 }
1535 else {
1536 classPK = (Long)baseModel.getPrimaryKeyObj();
1537 }
1538
1539 DocumentHelper documentHelper = new DocumentHelper(document);
1540
1541 documentHelper.setEntryKey(className, classPK);
1542
1543 document.addUID(className, classPK);
1544
1545 List<AssetCategory> assetCategories =
1546 AssetCategoryLocalServiceUtil.getCategories(className, classPK);
1547
1548 long[] assetCategoryIds = ListUtil.toLongArray(
1549 assetCategories, AssetCategory.CATEGORY_ID_ACCESSOR);
1550
1551 document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
1552
1553 addSearchAssetCategoryTitles(
1554 document, Field.ASSET_CATEGORY_TITLES, assetCategories);
1555
1556 long classNameId = PortalUtil.getClassNameId(className);
1557
1558 List<AssetTag> assetTags = AssetTagLocalServiceUtil.getTags(
1559 classNameId, classPK);
1560
1561 String[] assetTagNames = ListUtil.toArray(
1562 assetTags, AssetTag.NAME_ACCESSOR);
1563
1564 document.addText(Field.ASSET_TAG_NAMES, assetTagNames);
1565
1566 long[] assetTagsIds = ListUtil.toLongArray(
1567 assetTags, AssetTag.TAG_ID_ACCESSOR);
1568
1569 document.addKeyword(Field.ASSET_TAG_IDS, assetTagsIds);
1570
1571 if (resourcePrimKey > 0) {
1572 document.addKeyword(Field.ROOT_ENTRY_CLASS_PK, resourcePrimKey);
1573 }
1574
1575 if (baseModel instanceof AttachedModel) {
1576 AttachedModel attachedModel = (AttachedModel)baseModel;
1577
1578 documentHelper.setAttachmentOwnerKey(
1579 attachedModel.getClassNameId(), attachedModel.getClassPK());
1580 }
1581
1582 if (baseModel instanceof AuditedModel) {
1583 AuditedModel auditedModel = (AuditedModel)baseModel;
1584
1585 document.addKeyword(Field.COMPANY_ID, auditedModel.getCompanyId());
1586 document.addDate(Field.CREATE_DATE, auditedModel.getCreateDate());
1587 document.addDate(
1588 Field.MODIFIED_DATE, auditedModel.getModifiedDate());
1589 document.addKeyword(Field.USER_ID, auditedModel.getUserId());
1590
1591 String userName = PortalUtil.getUserName(
1592 auditedModel.getUserId(), auditedModel.getUserName());
1593
1594 document.addKeyword(Field.USER_NAME, userName, true);
1595 }
1596
1597 GroupedModel groupedModel = null;
1598
1599 if (baseModel instanceof GroupedModel) {
1600 groupedModel = (GroupedModel)baseModel;
1601
1602 document.addKeyword(
1603 Field.GROUP_ID, getSiteGroupId(groupedModel.getGroupId()));
1604 document.addKeyword(
1605 Field.SCOPE_GROUP_ID, groupedModel.getGroupId());
1606 }
1607
1608 if (workflowedBaseModel instanceof WorkflowedModel) {
1609 WorkflowedModel workflowedModel =
1610 (WorkflowedModel)workflowedBaseModel;
1611
1612 document.addKeyword(Field.STATUS, workflowedModel.getStatus());
1613 }
1614
1615 if ((groupedModel != null) && (baseModel instanceof TrashedModel)) {
1616 TrashedModel trashedModel = (TrashedModel)baseModel;
1617
1618 if (trashedModel.isInTrash()) {
1619 addTrashFields(document, trashedModel);
1620 }
1621 }
1622
1623 addAssetFields(document, className, classPK);
1624
1625 ExpandoBridgeIndexerUtil.addAttributes(
1626 document, baseModel.getExpandoBridge());
1627
1628 return document;
1629 }
1630
1631 protected String getClassName(SearchContext searchContext) {
1632 return getClassName();
1633 }
1634
1635 protected String[] getDefaultSelectedFieldNames() {
1636 return _defaultSelectedFieldNames;
1637 }
1638
1639 protected String[] getDefaultSelectedLocalizedFieldNames() {
1640 return _defaultSelectedLocalizedFieldNames;
1641 }
1642
1643 protected String getExpandoFieldName(
1644 SearchContext searchContext, ExpandoBridge expandoBridge,
1645 String attributeName) {
1646
1647 ExpandoColumn expandoColumn =
1648 ExpandoColumnLocalServiceUtil.getDefaultTableColumn(
1649 expandoBridge.getCompanyId(), expandoBridge.getClassName(),
1650 attributeName);
1651
1652 String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
1653 attributeName);
1654
1655 if (expandoColumn.getType() ==
1656 ExpandoColumnConstants.STRING_LOCALIZED) {
1657
1658 fieldName = DocumentImpl.getLocalizedName(
1659 searchContext.getLocale(), fieldName);
1660 }
1661
1662 return fieldName;
1663 }
1664
1665 protected Locale getLocale(PortletRequest portletRequest) {
1666 if (portletRequest != null) {
1667 return portletRequest.getLocale();
1668 }
1669
1670 return LocaleUtil.getMostRelevantLocale();
1671 }
1672
1673 protected Set<String> getLocalizedCountryNames(Country country) {
1674 Set<String> countryNames = new HashSet<>();
1675
1676 for (Locale locale : LanguageUtil.getAvailableLocales()) {
1677 String countryName = country.getName(locale);
1678
1679 countryName = StringUtil.toLowerCase(countryName);
1680
1681 countryNames.add(countryName);
1682 }
1683
1684 return countryNames;
1685 }
1686
1687
1690 @Deprecated
1691 protected String getPortletId(SearchContext searchContext) {
1692 return StringPool.BLANK;
1693 }
1694
1695 protected Group getSiteGroup(long groupId) {
1696 Group group = null;
1697
1698 try {
1699 group = GroupLocalServiceUtil.getGroup(groupId);
1700
1701 if (group.isLayout()) {
1702 group = group.getParentGroup();
1703 }
1704 }
1705 catch (PortalException pe) {
1706 if (_log.isDebugEnabled()) {
1707 _log.debug("Unable to get site group", pe);
1708 }
1709 }
1710
1711 return group;
1712 }
1713
1714 protected long getSiteGroupId(long groupId) {
1715 Group group = getSiteGroup(groupId);
1716
1717 if (group == null) {
1718 return groupId;
1719 }
1720
1721 return group.getGroupId();
1722 }
1723
1724 protected Locale getSnippetLocale(Document document, Locale locale) {
1725 String prefix = Field.SNIPPET + StringPool.UNDERLINE;
1726
1727 String localizedAssetCategoryTitlesName =
1728 prefix +
1729 DocumentImpl.getLocalizedName(
1730 locale, Field.ASSET_CATEGORY_TITLES);
1731 String localizedContentName =
1732 prefix + DocumentImpl.getLocalizedName(locale, Field.CONTENT);
1733 String localizedDescriptionName =
1734 prefix + DocumentImpl.getLocalizedName(locale, Field.DESCRIPTION);
1735 String localizedTitleName =
1736 prefix + DocumentImpl.getLocalizedName(locale, Field.TITLE);
1737
1738 if ((document.getField(localizedAssetCategoryTitlesName) != null) ||
1739 (document.getField(localizedContentName) != null) ||
1740 (document.getField(localizedDescriptionName) != null) ||
1741 (document.getField(localizedTitleName) != null)) {
1742
1743 return locale;
1744 }
1745
1746 return null;
1747 }
1748
1749 protected boolean isStagingGroup(long groupId) {
1750 Group group = getSiteGroup(groupId);
1751
1752 if (group == null) {
1753 return false;
1754 }
1755
1756 return group.isStagingGroup();
1757 }
1758
1759 protected boolean isUseSearchResultPermissionFilter(
1760 SearchContext searchContext) {
1761
1762 return isFilterSearch();
1763 }
1764
1765 protected boolean isVisible(int entryStatus, int queryStatus) {
1766 if (((queryStatus != WorkflowConstants.STATUS_ANY) &&
1767 (entryStatus == queryStatus)) ||
1768 (entryStatus != WorkflowConstants.STATUS_IN_TRASH)) {
1769
1770 return true;
1771 }
1772
1773 return false;
1774 }
1775
1776 protected Document newDocument() {
1777 return (Document)_document.clone();
1778 }
1779
1780 protected void populateAddresses(
1781 Document document, List<Address> addresses, long regionId,
1782 long countryId)
1783 throws PortalException {
1784
1785 List<String> cities = new ArrayList<>();
1786
1787 List<String> countries = new ArrayList<>();
1788
1789 if (countryId > 0) {
1790 try {
1791 Country country = CountryServiceUtil.getCountry(countryId);
1792
1793 countries.addAll(getLocalizedCountryNames(country));
1794 }
1795 catch (NoSuchCountryException nsce) {
1796 if (_log.isWarnEnabled()) {
1797 _log.warn(nsce.getMessage());
1798 }
1799 }
1800 }
1801
1802 List<String> regions = new ArrayList<>();
1803
1804 if (regionId > 0) {
1805 try {
1806 Region region = RegionServiceUtil.getRegion(regionId);
1807
1808 regions.add(StringUtil.toLowerCase(region.getName()));
1809 }
1810 catch (NoSuchRegionException nsre) {
1811 if (_log.isWarnEnabled()) {
1812 _log.warn(nsre.getMessage());
1813 }
1814 }
1815 }
1816
1817 List<String> streets = new ArrayList<>();
1818 List<String> zips = new ArrayList<>();
1819
1820 for (Address address : addresses) {
1821 cities.add(StringUtil.toLowerCase(address.getCity()));
1822 countries.addAll(getLocalizedCountryNames(address.getCountry()));
1823 regions.add(StringUtil.toLowerCase(address.getRegion().getName()));
1824 streets.add(StringUtil.toLowerCase(address.getStreet1()));
1825 streets.add(StringUtil.toLowerCase(address.getStreet2()));
1826 streets.add(StringUtil.toLowerCase(address.getStreet3()));
1827 zips.add(StringUtil.toLowerCase(address.getZip()));
1828 }
1829
1830 document.addText("city", cities.toArray(new String[cities.size()]));
1831 document.addText(
1832 "country", countries.toArray(new String[countries.size()]));
1833 document.addText("region", regions.toArray(new String[regions.size()]));
1834 document.addText("street", streets.toArray(new String[streets.size()]));
1835 document.addText("zip", zips.toArray(new String[zips.size()]));
1836 }
1837
1838 protected Map<Locale, String> populateMap(
1839 AssetEntry assetEntry, Map<Locale, String> map) {
1840
1841 String defaultValue = map.get(
1842 LocaleUtil.fromLanguageId(assetEntry.getDefaultLanguageId()));
1843
1844 for (Locale availableLocale : LanguageUtil.getAvailableLocales(
1845 assetEntry.getGroupId())) {
1846
1847 if (!map.containsKey(availableLocale) ||
1848 Validator.isNull(map.get(availableLocale))) {
1849
1850 map.put(availableLocale, defaultValue);
1851 }
1852 }
1853
1854 return map;
1855 }
1856
1857 protected void postProcessFullQuery(
1858 BooleanQuery fullQuery, SearchContext searchContext)
1859 throws Exception {
1860 }
1861
1862 protected void processHits(SearchContext searchContext, Hits hits)
1863 throws SearchException {
1864
1865 HitsProcessorRegistryUtil.process(searchContext, hits);
1866 }
1867
1868 protected void resetFullQuery(SearchContext searchContext) {
1869 searchContext.clearFullQueryEntryClassNames();
1870
1871 for (Indexer<?> indexer : IndexerRegistryUtil.getIndexers()) {
1872 if (indexer instanceof RelatedEntryIndexer) {
1873 RelatedEntryIndexer relatedEntryIndexer =
1874 (RelatedEntryIndexer)indexer;
1875
1876 relatedEntryIndexer.updateFullQuery(searchContext);
1877 }
1878 }
1879 }
1880
1881 protected void setDefaultSelectedFieldNames(
1882 String... defaultLocalizedFieldNames) {
1883
1884 _defaultSelectedFieldNames = defaultLocalizedFieldNames;
1885 }
1886
1887 protected void setDefaultSelectedLocalizedFieldNames(
1888 String... defaultLocalizedFieldNames) {
1889
1890 _defaultSelectedLocalizedFieldNames = defaultLocalizedFieldNames;
1891 }
1892
1893 protected void setFilterSearch(boolean filterSearch) {
1894 _filterSearch = filterSearch;
1895 }
1896
1897 protected void setPermissionAware(boolean permissionAware) {
1898 _permissionAware = permissionAware;
1899 }
1900
1901 protected void setStagingAware(boolean stagingAware) {
1902 _stagingAware = stagingAware;
1903 }
1904
1905 private static final long _DEFAULT_FOLDER_ID = 0L;
1906
1907 private static final Log _log = LogFactoryUtil.getLog(BaseIndexer.class);
1908
1909 private boolean _commitImmediately;
1910 private String[] _defaultSelectedFieldNames;
1911 private String[] _defaultSelectedLocalizedFieldNames;
1912 private final Document _document = new DocumentImpl();
1913 private boolean _filterSearch;
1914 private Boolean _indexerEnabled;
1915 private IndexerPostProcessor[] _indexerPostProcessors =
1916 new IndexerPostProcessor[0];
1917 private boolean _permissionAware;
1918 private String _searchEngineId;
1919 private boolean _selectAllLocales;
1920 private boolean _stagingAware = true;
1921
1922 }