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