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.dao.orm.QueryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.search.facet.AssetEntriesFacet;
026 import com.liferay.portal.kernel.search.facet.Facet;
027 import com.liferay.portal.kernel.search.facet.MultiValueFacet;
028 import com.liferay.portal.kernel.search.facet.ScopeFacet;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.ListUtil;
031 import com.liferay.portal.kernel.util.PropsKeys;
032 import com.liferay.portal.kernel.util.PropsUtil;
033 import com.liferay.portal.kernel.util.SetUtil;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.Time;
036 import com.liferay.portal.kernel.util.UnicodeProperties;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.model.Address;
039 import com.liferay.portal.model.AttachedModel;
040 import com.liferay.portal.model.AuditedModel;
041 import com.liferay.portal.model.BaseModel;
042 import com.liferay.portal.model.Country;
043 import com.liferay.portal.model.Group;
044 import com.liferay.portal.model.GroupedModel;
045 import com.liferay.portal.model.Region;
046 import com.liferay.portal.model.ResourcedModel;
047 import com.liferay.portal.model.WorkflowedModel;
048 import com.liferay.portal.security.permission.ActionKeys;
049 import com.liferay.portal.security.permission.PermissionChecker;
050 import com.liferay.portal.security.permission.PermissionThreadLocal;
051 import com.liferay.portal.service.CountryServiceUtil;
052 import com.liferay.portal.service.GroupLocalServiceUtil;
053 import com.liferay.portal.service.RegionServiceUtil;
054 import com.liferay.portal.util.PortalUtil;
055 import com.liferay.portlet.asset.model.AssetCategory;
056 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
057 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
058 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
059 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
060 import com.liferay.portlet.expando.model.ExpandoBridge;
061 import com.liferay.portlet.expando.model.ExpandoColumnConstants;
062 import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
063 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
064
065 import java.util.ArrayList;
066 import java.util.List;
067 import java.util.Locale;
068 import java.util.Map;
069 import java.util.Set;
070
071 import javax.portlet.PortletURL;
072
073
079 public abstract class BaseIndexer implements Indexer {
080
081 public static final int INDEX_FILTER_SEARCH_LIMIT = GetterUtil.getInteger(
082 PropsUtil.get(PropsKeys.INDEX_FILTER_SEARCH_LIMIT));
083
084 public void delete(long companyId, String uid) throws SearchException {
085 try {
086 SearchEngineUtil.deleteDocument(companyId, uid);
087 }
088 catch (SearchException se) {
089 throw se;
090 }
091 catch (Exception e) {
092 throw new SearchException(e);
093 }
094 }
095
096 public void delete(Object obj) throws SearchException {
097 try {
098 doDelete(obj);
099 }
100 catch (SearchException se) {
101 throw se;
102 }
103 catch (Exception e) {
104 throw new SearchException(e);
105 }
106 }
107
108 public Document getDocument(Object obj) throws SearchException {
109 try {
110 Document document = doGetDocument(obj);
111
112 for (IndexerPostProcessor indexerPostProcessor :
113 _indexerPostProcessors) {
114
115 indexerPostProcessor.postProcessDocument(document, obj);
116 }
117
118 if (document == null) {
119 return null;
120 }
121
122 Map<String, Field> fields = document.getFields();
123
124 Field groupIdField = fields.get(Field.GROUP_ID);
125
126 if (groupIdField != null) {
127 long groupId = GetterUtil.getLong(groupIdField.getValue());
128
129 addStagingGroupKeyword(document, groupId);
130 }
131
132 return document;
133 }
134 catch (SearchException se) {
135 throw se;
136 }
137 catch (Exception e) {
138 throw new SearchException(e);
139 }
140 }
141
142 public BooleanQuery getFacetQuery(
143 String className, SearchContext searchContext)
144 throws Exception {
145
146 BooleanQuery facetQuery = BooleanQueryFactoryUtil.create(searchContext);
147
148 facetQuery.addExactTerm(Field.ENTRY_CLASS_NAME, className);
149
150 if (searchContext.getUserId() > 0) {
151 SearchPermissionChecker searchPermissionChecker =
152 SearchEngineUtil.getSearchPermissionChecker();
153
154 facetQuery =
155 (BooleanQuery)searchPermissionChecker.getPermissionQuery(
156 searchContext.getCompanyId(), searchContext.getGroupIds(),
157 searchContext.getUserId(), className, facetQuery,
158 searchContext);
159 }
160
161 return facetQuery;
162 }
163
164 public BooleanQuery getFullQuery(SearchContext searchContext)
165 throws SearchException {
166
167 try {
168 searchContext.setSearchEngineId(getSearchEngineId());
169
170 searchContext.setEntryClassNames(
171 new String[] {getClassName(searchContext)});
172
173 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
174 searchContext);
175
176 addSearchAssetCategoryIds(contextQuery, searchContext);
177 addSearchAssetTagNames(contextQuery, searchContext);
178 addSearchEntryClassNames(contextQuery, searchContext);
179 addSearchGroupId(contextQuery, searchContext);
180
181 BooleanQuery fullQuery = createFullQuery(
182 contextQuery, searchContext);
183
184 fullQuery.setQueryConfig(searchContext.getQueryConfig());
185
186 return fullQuery;
187 }
188 catch (SearchException se) {
189 throw se;
190 }
191 catch (Exception e) {
192 throw new SearchException(e);
193 }
194 }
195
196 public IndexerPostProcessor[] getIndexerPostProcessors() {
197 return _indexerPostProcessors;
198 }
199
200 public String getSearchEngineId() {
201 return SearchEngineUtil.SYSTEM_ENGINE_ID;
202 }
203
204 public String getSortField(String orderByCol) {
205 return doGetSortField(orderByCol);
206 }
207
208 public Summary getSummary(
209 Document document, Locale locale, String snippet,
210 PortletURL portletURL)
211 throws SearchException {
212
213 try {
214 Summary summary = doGetSummary(
215 document, locale, snippet, portletURL);
216
217 for (IndexerPostProcessor indexerPostProcessor :
218 _indexerPostProcessors) {
219
220 indexerPostProcessor.postProcessSummary(
221 summary, document, locale, snippet, portletURL);
222 }
223
224 return summary;
225 }
226 catch (SearchException se) {
227 throw se;
228 }
229 catch (Exception e) {
230 throw new SearchException(e);
231 }
232 }
233
234 public boolean hasPermission(
235 PermissionChecker permissionChecker, long entryClassPK,
236 String actionId)
237 throws Exception {
238
239 return true;
240 }
241
242 public boolean isFilterSearch() {
243 return _FILTER_SEARCH;
244 }
245
246 public boolean isIndexerEnabled() {
247 return _INDEXER_ENABLED;
248 }
249
250 public boolean isStagingAware() {
251 return _stagingAware;
252 }
253
254 public void postProcessContextQuery(
255 BooleanQuery contextQuery, SearchContext searchContext)
256 throws Exception {
257 }
258
259 public void postProcessSearchQuery(
260 BooleanQuery searchQuery, SearchContext searchContext)
261 throws Exception {
262 }
263
264 public void registerIndexerPostProcessor(
265 IndexerPostProcessor indexerPostProcessor) {
266
267 List<IndexerPostProcessor> indexerPostProcessorsList =
268 ListUtil.fromArray(_indexerPostProcessors);
269
270 indexerPostProcessorsList.add(indexerPostProcessor);
271
272 _indexerPostProcessors = indexerPostProcessorsList.toArray(
273 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
274 }
275
276 public void reindex(Object obj) throws SearchException {
277 try {
278 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
279 return;
280 }
281
282 doReindex(obj);
283 }
284 catch (SearchException se) {
285 throw se;
286 }
287 catch (Exception e) {
288 throw new SearchException(e);
289 }
290 }
291
292 public void reindex(String className, long classPK) throws SearchException {
293 try {
294 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
295 return;
296 }
297
298 doReindex(className, classPK);
299 }
300 catch (NoSuchModelException nsme) {
301 if (_log.isWarnEnabled()) {
302 _log.warn("Unable to index " + className + " " + classPK);
303 }
304 }
305 catch (SearchException se) {
306 throw se;
307 }
308 catch (Exception e) {
309 throw new SearchException(e);
310 }
311 }
312
313 public void reindex(String[] ids) throws SearchException {
314 try {
315 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
316 return;
317 }
318
319 doReindex(ids);
320 }
321 catch (SearchException se) {
322 throw se;
323 }
324 catch (Exception e) {
325 throw new SearchException(e);
326 }
327 }
328
329 public Hits search(SearchContext searchContext) throws SearchException {
330 try {
331 BooleanQuery fullQuery = getFullQuery(searchContext);
332
333 fullQuery.setQueryConfig(searchContext.getQueryConfig());
334
335 PermissionChecker permissionChecker =
336 PermissionThreadLocal.getPermissionChecker();
337
338 int start = searchContext.getStart();
339 int end = searchContext.getEnd();
340
341 if (isFilterSearch() && (permissionChecker != null)) {
342 searchContext.setStart(0);
343 searchContext.setEnd(end + INDEX_FILTER_SEARCH_LIMIT);
344 }
345
346 Hits hits = SearchEngineUtil.search(searchContext, fullQuery);
347
348 searchContext.setStart(start);
349 searchContext.setEnd(end);
350
351 if (isFilterSearch() && (permissionChecker != null)) {
352 hits = filterSearch(hits, permissionChecker, searchContext);
353 }
354
355 return hits;
356 }
357 catch (SearchException se) {
358 throw se;
359 }
360 catch (Exception e) {
361 throw new SearchException(e);
362 }
363 }
364
365 public void unregisterIndexerPostProcessor(
366 IndexerPostProcessor indexerPostProcessor) {
367
368 List<IndexerPostProcessor> indexerPostProcessorsList =
369 ListUtil.fromArray(_indexerPostProcessors);
370
371 ListUtil.remove(indexerPostProcessorsList, indexerPostProcessor);
372
373 _indexerPostProcessors = indexerPostProcessorsList.toArray(
374 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
375 }
376
377 protected void addLocalizedSearchTerm(
378 BooleanQuery searchQuery, SearchContext searchContext,
379 String field, boolean like)
380 throws Exception {
381
382 addSearchTerm(searchQuery, searchContext, field, like);
383 addSearchTerm(
384 searchQuery, searchContext,
385 DocumentImpl.getLocalizedName(searchContext.getLocale(), field),
386 like);
387 }
388
389 protected void addSearchAssetCategoryIds(
390 BooleanQuery contextQuery, SearchContext searchContext)
391 throws Exception {
392
393 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
394
395 multiValueFacet.setFieldName(Field.ASSET_CATEGORY_IDS);
396 multiValueFacet.setStatic(true);
397
398 searchContext.addFacet(multiValueFacet);
399 }
400
401 protected void addSearchAssetTagNames(
402 BooleanQuery contextQuery, SearchContext searchContext)
403 throws Exception {
404
405 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
406
407 multiValueFacet.setFieldName(Field.ASSET_TAG_NAMES);
408 multiValueFacet.setStatic(true);
409
410 searchContext.addFacet(multiValueFacet);
411 }
412
413 protected void addSearchDDMStruture(
414 BooleanQuery searchQuery, SearchContext searchContext,
415 DDMStructure ddmStructure)
416 throws Exception {
417
418 Set<String> fieldNames = ddmStructure.getFieldNames();
419
420 for (String fieldName : fieldNames) {
421 String name = DDMIndexerUtil.encodeName(
422 ddmStructure.getStructureId(), fieldName);
423
424 addSearchTerm(searchQuery, searchContext, name, false);
425 }
426 }
427
428 protected void addSearchEntryClassNames(
429 BooleanQuery contextQuery, SearchContext searchContext)
430 throws Exception {
431
432 Facet facet = new AssetEntriesFacet(searchContext);
433
434 facet.setStatic(true);
435
436 searchContext.addFacet(facet);
437 }
438
439 protected void addSearchExpando(
440 BooleanQuery searchQuery, SearchContext searchContext,
441 String keywords)
442 throws Exception {
443
444 ExpandoBridge expandoBridge =
445 ExpandoBridgeFactoryUtil.getExpandoBridge(
446 searchContext.getCompanyId(), getClassName(searchContext));
447
448 Set<String> attributeNames = SetUtil.fromEnumeration(
449 expandoBridge.getAttributeNames());
450
451 for (String attributeName : attributeNames) {
452 UnicodeProperties properties = expandoBridge.getAttributeProperties(
453 attributeName);
454
455 int indexType = GetterUtil.getInteger(
456 properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
457
458 if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
459 String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
460 attributeName);
461
462 if (Validator.isNotNull(keywords)) {
463 if (searchContext.isAndSearch()) {
464 searchQuery.addRequiredTerm(fieldName, keywords);
465 }
466 else {
467 searchQuery.addTerm(fieldName, keywords);
468 }
469 }
470 }
471 }
472 }
473
474 protected void addSearchGroupId(
475 BooleanQuery contextQuery, SearchContext searchContext)
476 throws Exception {
477
478 Facet facet = new ScopeFacet(searchContext);
479
480 facet.setStatic(true);
481
482 searchContext.addFacet(facet);
483 }
484
485 protected void addSearchKeywords(
486 BooleanQuery searchQuery, SearchContext searchContext)
487 throws Exception {
488
489 String keywords = searchContext.getKeywords();
490
491 if (Validator.isNull(keywords)) {
492 return;
493 }
494
495 searchQuery.addTerms(Field.KEYWORDS, keywords);
496
497 addSearchExpando(searchQuery, searchContext, keywords);
498 }
499
500 protected void addSearchTerm(
501 BooleanQuery searchQuery, SearchContext searchContext,
502 String field, boolean like)
503 throws Exception {
504
505 if (Validator.isNull(field)) {
506 return;
507 }
508
509 String value = String.valueOf(searchContext.getAttribute(field));
510
511 if (Validator.isNull(value)) {
512 value = searchContext.getKeywords();
513 }
514
515 if (Validator.isNull(value)) {
516 return;
517 }
518
519 if (searchContext.isAndSearch()) {
520 searchQuery.addRequiredTerm(field, value, like);
521 }
522 else {
523 searchQuery.addTerm(field, value, like);
524 }
525 }
526
527 protected void addStagingGroupKeyword(Document document, long groupId)
528 throws Exception {
529
530 if (!isStagingAware()) {
531 return;
532 }
533
534 boolean stagingGroup = false;
535
536 Group group = GroupLocalServiceUtil.getGroup(groupId);
537
538 if (group.isLayout()) {
539 group = GroupLocalServiceUtil.getGroup(group.getParentGroupId());
540 }
541
542 if (group.isStagingGroup()) {
543 stagingGroup = true;
544 }
545
546 document.addKeyword(Field.STAGING_GROUP, stagingGroup);
547 }
548
549 protected BooleanQuery createFullQuery(
550 BooleanQuery contextQuery, SearchContext searchContext)
551 throws Exception {
552
553 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
554 searchContext);
555
556 addSearchKeywords(searchQuery, searchContext);
557 postProcessSearchQuery(searchQuery, searchContext);
558
559 for (IndexerPostProcessor indexerPostProcessor :
560 _indexerPostProcessors) {
561
562 indexerPostProcessor.postProcessSearchQuery(
563 searchQuery, searchContext);
564 }
565
566 Map<String, Facet> facets = searchContext.getFacets();
567
568 for (Facet facet : facets.values()) {
569 BooleanClause facetClause = facet.getFacetClause();
570
571 if (facetClause != null) {
572 contextQuery.add(
573 facetClause.getQuery(),
574 facetClause.getBooleanClauseOccur());
575 }
576 }
577
578 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
579
580 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
581
582 if (!searchQuery.clauses().isEmpty()) {
583 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
584 }
585
586 BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
587
588 if (booleanClauses != null) {
589 for (BooleanClause booleanClause : booleanClauses) {
590 fullQuery.add(
591 booleanClause.getQuery(),
592 booleanClause.getBooleanClauseOccur());
593 }
594 }
595
596 postProcessFullQuery(fullQuery, searchContext);
597
598 for (IndexerPostProcessor indexerPostProcessor :
599 _indexerPostProcessors) {
600
601 indexerPostProcessor.postProcessFullQuery(fullQuery, searchContext);
602 }
603
604 return fullQuery;
605 }
606
607 protected void deleteDocument(long companyId, long field1)
608 throws Exception {
609
610 deleteDocument(companyId, String.valueOf(field1));
611 }
612
613 protected void deleteDocument(long companyId, long field1, String field2)
614 throws Exception {
615
616 deleteDocument(companyId, String.valueOf(field1), field2);
617 }
618
619 protected void deleteDocument(long companyId, String field1)
620 throws Exception {
621
622 Document document = new DocumentImpl();
623
624 document.addUID(getPortletId(), field1);
625
626 SearchEngineUtil.deleteDocument(companyId, document.get(Field.UID));
627 }
628
629 protected void deleteDocument(long companyId, String field1, String field2)
630 throws Exception {
631
632 Document document = new DocumentImpl();
633
634 document.addUID(getPortletId(), field1, field2);
635
636 SearchEngineUtil.deleteDocument(companyId, document.get(Field.UID));
637 }
638
639 protected abstract void doDelete(Object obj) throws Exception;
640
641 protected abstract Document doGetDocument(Object obj) throws Exception;
642
643 protected String doGetSortField(String orderByCol) {
644 return orderByCol;
645 }
646
647 protected abstract Summary doGetSummary(
648 Document document, Locale locale, String snippet,
649 PortletURL portletURL)
650 throws Exception;
651
652 protected abstract void doReindex(Object obj) throws Exception;
653
654 protected abstract void doReindex(String className, long classPK)
655 throws Exception;
656
657 protected abstract void doReindex(String[] ids) throws Exception;
658
659 protected Hits filterSearch(
660 Hits hits, PermissionChecker permissionChecker,
661 SearchContext searchContext) {
662
663 List<Document> docs = new ArrayList<Document>();
664 List<Float> scores = new ArrayList<Float>();
665
666 int start = searchContext.getStart();
667 int end = searchContext.getEnd();
668
669 String paginationType = GetterUtil.getString(
670 searchContext.getAttribute("paginationType"), "more");
671
672 boolean hasMore = false;
673
674 Document[] documents = hits.getDocs();
675
676 for (int i = 0; i < documents.length; i++) {
677 try {
678 Document document = documents[i];
679
680 String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
681 long entryClassPK = GetterUtil.getLong(
682 document.get(Field.ENTRY_CLASS_PK));
683
684 Indexer indexer = IndexerRegistryUtil.getIndexer(
685 entryClassName);
686
687 if ((indexer.isFilterSearch() && indexer.hasPermission(
688 permissionChecker, entryClassPK, ActionKeys.VIEW)) ||
689 !indexer.isFilterSearch()) {
690
691 docs.add(document);
692 scores.add(hits.score(i));
693 }
694 }
695 catch (Exception e) {
696 }
697
698 if (paginationType.equals("more") && (docs.size() > end)) {
699 hasMore = true;
700
701 break;
702 }
703 }
704
705 int length = docs.size();
706
707 if (hasMore) {
708 length = length + (end - start);
709 }
710
711 hits.setLength(length);
712
713 if ((start != QueryUtil.ALL_POS) && (end != QueryUtil.ALL_POS)) {
714 if (end > length) {
715 end = length;
716 }
717
718 docs = docs.subList(start, end);
719 }
720
721 hits.setDocs(docs.toArray(new Document[docs.size()]));
722 hits.setScores(scores.toArray(new Float[docs.size()]));
723
724 hits.setSearchTime(
725 (float)(System.currentTimeMillis() - hits.getStart()) /
726 Time.SECOND);
727
728 return hits;
729 }
730
731 protected Document getBaseModelDocument(
732 String portletId, BaseModel<?> baseModel)
733 throws SystemException {
734
735 Document document = new DocumentImpl();
736
737 String className = baseModel.getModelClassName();
738
739 long classPK = 0;
740 long resourcePrimKey = 0;
741
742 if (baseModel instanceof ResourcedModel) {
743 ResourcedModel resourcedModel = (ResourcedModel)baseModel;
744
745 classPK = resourcedModel.getResourcePrimKey();
746 resourcePrimKey = resourcedModel.getResourcePrimKey();
747 }
748 else {
749 classPK = (Long)baseModel.getPrimaryKeyObj();
750 }
751
752 document.addUID(portletId, classPK);
753
754 List<AssetCategory> assetCategories =
755 AssetCategoryLocalServiceUtil.getCategories(className, classPK);
756
757 long[] assetCategoryIds = StringUtil.split(
758 ListUtil.toString(
759 assetCategories, AssetCategory.CATEGORY_ID_ACCESSOR),
760 0L);
761
762 document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
763
764 String[] assetCategoryNames = StringUtil.split(
765 ListUtil.toString(assetCategories, AssetCategory.NAME_ACCESSOR));
766
767 document.addText(Field.ASSET_CATEGORY_NAMES, assetCategoryNames);
768
769 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
770 className, classPK);
771
772 document.addText(Field.ASSET_TAG_NAMES, assetTagNames);
773
774 document.addKeyword(Field.ENTRY_CLASS_NAME, className);
775 document.addKeyword(Field.ENTRY_CLASS_PK, classPK);
776 document.addKeyword(Field.PORTLET_ID, portletId);
777
778 if (resourcePrimKey > 0) {
779 document.addKeyword(Field.ROOT_ENTRY_CLASS_PK, resourcePrimKey);
780 }
781
782 if (baseModel instanceof AttachedModel) {
783 AttachedModel attachedModel = (AttachedModel)baseModel;
784
785 document.addKeyword(
786 Field.CLASS_NAME_ID, attachedModel.getClassNameId());
787 document.addKeyword(Field.CLASS_PK, attachedModel.getClassPK());
788 }
789
790 if (baseModel instanceof AuditedModel) {
791 AuditedModel auditedModel = (AuditedModel)baseModel;
792
793 document.addKeyword(Field.COMPANY_ID, auditedModel.getCompanyId());
794 document.addDate(Field.CREATE_DATE, auditedModel.getCreateDate());
795 document.addDate(
796 Field.MODIFIED_DATE, auditedModel.getModifiedDate());
797 document.addKeyword(Field.USER_ID, auditedModel.getUserId());
798
799 String userName = PortalUtil.getUserName(
800 auditedModel.getUserId(), auditedModel.getUserName());
801
802 document.addKeyword(Field.USER_NAME, userName, true);
803 }
804
805 if (baseModel instanceof GroupedModel) {
806 GroupedModel groupedModel = (GroupedModel)baseModel;
807
808 document.addKeyword(
809 Field.GROUP_ID, getParentGroupId(groupedModel.getGroupId()));
810 document.addKeyword(
811 Field.SCOPE_GROUP_ID, groupedModel.getGroupId());
812 }
813
814 if (baseModel instanceof WorkflowedModel) {
815 WorkflowedModel workflowedModel = (WorkflowedModel)baseModel;
816
817 document.addKeyword(Field.STATUS, workflowedModel.getStatus());
818 }
819
820 ExpandoBridgeIndexerUtil.addAttributes(
821 document, baseModel.getExpandoBridge());
822
823 return document;
824 }
825
826 protected String getClassName(SearchContext searchContext) {
827 String[] classNames = getClassNames();
828
829 if (classNames.length != 1) {
830 throw new UnsupportedOperationException(
831 "Search method needs to be manually implemented for " +
832 "indexers with more than one class name");
833 }
834
835 return classNames[0];
836 }
837
838 protected long getParentGroupId(long groupId) {
839 long parentGroupId = groupId;
840
841 try {
842 Group group = GroupLocalServiceUtil.getGroup(groupId);
843
844 if (group.isLayout()) {
845 parentGroupId = group.getParentGroupId();
846 }
847 }
848 catch (Exception e) {
849 }
850
851 return parentGroupId;
852 }
853
854 protected abstract String getPortletId(SearchContext searchContext);
855
856 protected void populateAddresses(
857 Document document, List<Address> addresses, long regionId,
858 long countryId)
859 throws PortalException, SystemException {
860
861 List<String> cities = new ArrayList<String>();
862
863 List<String> countries = new ArrayList<String>();
864
865 if (countryId > 0) {
866 try {
867 Country country = CountryServiceUtil.getCountry(countryId);
868
869 countries.add(country.getName().toLowerCase());
870 }
871 catch (NoSuchCountryException nsce) {
872 if (_log.isWarnEnabled()) {
873 _log.warn(nsce.getMessage());
874 }
875 }
876 }
877
878 List<String> regions = new ArrayList<String>();
879
880 if (regionId > 0) {
881 try {
882 Region region = RegionServiceUtil.getRegion(regionId);
883
884 regions.add(region.getName().toLowerCase());
885 }
886 catch (NoSuchRegionException nsre) {
887 if (_log.isWarnEnabled()) {
888 _log.warn(nsre.getMessage());
889 }
890 }
891 }
892
893 List<String> streets = new ArrayList<String>();
894 List<String> zips = new ArrayList<String>();
895
896 for (Address address : addresses) {
897 cities.add(address.getCity().toLowerCase());
898 countries.add(address.getCountry().getName().toLowerCase());
899 regions.add(address.getRegion().getName().toLowerCase());
900 streets.add(address.getStreet1().toLowerCase());
901 streets.add(address.getStreet2().toLowerCase());
902 streets.add(address.getStreet3().toLowerCase());
903 zips.add(address.getZip().toLowerCase());
904 }
905
906 document.addText("city", cities.toArray(new String[cities.size()]));
907 document.addText(
908 "country", countries.toArray(new String[countries.size()]));
909 document.addText("region", regions.toArray(new String[regions.size()]));
910 document.addText("street", streets.toArray(new String[streets.size()]));
911 document.addText("zip", zips.toArray(new String[zips.size()]));
912 }
913
914 protected void postProcessFullQuery(
915 BooleanQuery fullQuery, SearchContext searchContext)
916 throws Exception {
917 }
918
919 protected void setStagingAware(boolean stagingAware) {
920 _stagingAware = stagingAware;
921 }
922
923 private static final boolean _FILTER_SEARCH = false;
924
925 private static final boolean _INDEXER_ENABLED = true;
926
927 private static Log _log = LogFactoryUtil.getLog(BaseIndexer.class);
928
929 private IndexerPostProcessor[] _indexerPostProcessors =
930 new IndexerPostProcessor[0];
931 private boolean _stagingAware = true;
932
933 }