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