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