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