2 * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 2.1 of the License, or (at your option)
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 package com.liferay.portal.kernel.search;
17 import com.liferay.portal.NoSuchCountryException;
18 import com.liferay.portal.NoSuchModelException;
19 import com.liferay.portal.NoSuchRegionException;
20 import com.liferay.portal.kernel.configuration.Filter;
21 import com.liferay.portal.kernel.dao.orm.QueryUtil;
22 import com.liferay.portal.kernel.exception.PortalException;
23 import com.liferay.portal.kernel.exception.SystemException;
24 import com.liferay.portal.kernel.log.Log;
25 import com.liferay.portal.kernel.log.LogFactoryUtil;
26 import com.liferay.portal.kernel.search.facet.AssetEntriesFacet;
27 import com.liferay.portal.kernel.search.facet.Facet;
28 import com.liferay.portal.kernel.search.facet.MultiValueFacet;
29 import com.liferay.portal.kernel.search.facet.ScopeFacet;
30 import com.liferay.portal.kernel.util.GetterUtil;
31 import com.liferay.portal.kernel.util.ListUtil;
32 import com.liferay.portal.kernel.util.LocaleUtil;
33 import com.liferay.portal.kernel.util.PropsKeys;
34 import com.liferay.portal.kernel.util.PropsUtil;
35 import com.liferay.portal.kernel.util.SetUtil;
36 import com.liferay.portal.kernel.util.StringPool;
37 import com.liferay.portal.kernel.util.StringUtil;
38 import com.liferay.portal.kernel.util.Time;
39 import com.liferay.portal.kernel.util.UnicodeProperties;
40 import com.liferay.portal.kernel.util.Validator;
41 import com.liferay.portal.model.Address;
42 import com.liferay.portal.model.AttachedModel;
43 import com.liferay.portal.model.AuditedModel;
44 import com.liferay.portal.model.BaseModel;
45 import com.liferay.portal.model.Country;
46 import com.liferay.portal.model.Group;
47 import com.liferay.portal.model.GroupedModel;
48 import com.liferay.portal.model.Region;
49 import com.liferay.portal.model.ResourcedModel;
50 import com.liferay.portal.model.WorkflowedModel;
51 import com.liferay.portal.security.permission.ActionKeys;
52 import com.liferay.portal.security.permission.PermissionChecker;
53 import com.liferay.portal.security.permission.PermissionThreadLocal;
54 import com.liferay.portal.service.CountryServiceUtil;
55 import com.liferay.portal.service.GroupLocalServiceUtil;
56 import com.liferay.portal.service.RegionServiceUtil;
57 import com.liferay.portal.util.PortalUtil;
58 import com.liferay.portlet.asset.model.AssetCategory;
59 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
60 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
61 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
62 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
63 import com.liferay.portlet.expando.model.ExpandoBridge;
64 import com.liferay.portlet.expando.model.ExpandoColumnConstants;
65 import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
66 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
68 import java.util.ArrayList;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Locale;
75 import javax.portlet.PortletURL;
78 * @author Brian Wing Shun Chan
79 * @author Hugo Huijser
81 * @author Raymond Augé
83 public abstract class BaseIndexer implements Indexer {
85 public static final int INDEX_FILTER_SEARCH_LIMIT = GetterUtil.getInteger(
86 PropsUtil.get(PropsKeys.INDEX_FILTER_SEARCH_LIMIT));
88 public void delete(long companyId, String uid) throws SearchException {
90 SearchEngineUtil.deleteDocument(
91 getSearchEngineId(), companyId, uid);
93 catch (SearchException se) {
97 throw new SearchException(e);
101 public void delete(Object obj) throws SearchException {
105 catch (SearchException se) {
108 catch (Exception e) {
109 throw new SearchException(e);
113 public Document getDocument(Object obj) throws SearchException {
115 Document document = doGetDocument(obj);
117 for (IndexerPostProcessor indexerPostProcessor :
118 _indexerPostProcessors) {
120 indexerPostProcessor.postProcessDocument(document, obj);
123 if (document == null) {
127 Map<String, Field> fields = document.getFields();
129 Field groupIdField = fields.get(Field.GROUP_ID);
131 if (groupIdField != null) {
132 long groupId = GetterUtil.getLong(groupIdField.getValue());
134 addStagingGroupKeyword(document, groupId);
139 catch (SearchException se) {
142 catch (Exception e) {
143 throw new SearchException(e);
147 public BooleanQuery getFacetQuery(
148 String className, SearchContext searchContext)
151 BooleanQuery facetQuery = BooleanQueryFactoryUtil.create(searchContext);
153 facetQuery.addExactTerm(Field.ENTRY_CLASS_NAME, className);
155 if (searchContext.getUserId() > 0) {
156 SearchPermissionChecker searchPermissionChecker =
157 SearchEngineUtil.getSearchPermissionChecker();
160 (BooleanQuery)searchPermissionChecker.getPermissionQuery(
161 searchContext.getCompanyId(), searchContext.getGroupIds(),
162 searchContext.getUserId(), className, facetQuery,
169 public BooleanQuery getFullQuery(SearchContext searchContext)
170 throws SearchException {
173 searchContext.setSearchEngineId(getSearchEngineId());
175 searchContext.setEntryClassNames(
176 new String[] {getClassName(searchContext)});
178 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
181 addSearchAssetCategoryIds(contextQuery, searchContext);
182 addSearchAssetTagNames(contextQuery, searchContext);
183 addSearchEntryClassNames(contextQuery, searchContext);
184 addSearchGroupId(contextQuery, searchContext);
186 BooleanQuery fullQuery = createFullQuery(
187 contextQuery, searchContext);
189 fullQuery.setQueryConfig(searchContext.getQueryConfig());
193 catch (SearchException se) {
196 catch (Exception e) {
197 throw new SearchException(e);
201 public IndexerPostProcessor[] getIndexerPostProcessors() {
202 return _indexerPostProcessors;
205 public String getSearchEngineId() {
206 if (_searchEngineId != null) {
207 return _searchEngineId;
210 Class<?> clazz = getClass();
212 String searchEngineId = GetterUtil.getString(
214 PropsKeys.INDEX_SEARCH_ENGINE_ID, new Filter(clazz.getName())));
216 if (Validator.isNotNull(searchEngineId)) {
217 SearchEngine searchEngine = SearchEngineUtil.getSearchEngine(
220 if (searchEngine != null) {
221 _searchEngineId = searchEngineId;
225 if (_searchEngineId == null) {
226 _searchEngineId = SearchEngineUtil.getDefaultSearchEngineId();
229 if (_log.isDebugEnabled()) {
231 "Search engine ID for " + clazz.getName() + " is " +
235 return _searchEngineId;
238 public String getSortField(String orderByCol) {
239 String sortField = doGetSortField(orderByCol);
241 if (DocumentImpl.isSortableTextField(sortField)) {
242 return DocumentImpl.getSortableFieldName(sortField);
248 public Summary getSummary(
249 Document document, Locale locale, String snippet,
250 PortletURL portletURL)
251 throws SearchException {
254 Summary summary = doGetSummary(
255 document, locale, snippet, portletURL);
257 for (IndexerPostProcessor indexerPostProcessor :
258 _indexerPostProcessors) {
260 indexerPostProcessor.postProcessSummary(
261 summary, document, locale, snippet, portletURL);
266 catch (SearchException se) {
269 catch (Exception e) {
270 throw new SearchException(e);
274 public boolean hasPermission(
275 PermissionChecker permissionChecker, long entryClassPK,
282 public boolean isFilterSearch() {
283 return _FILTER_SEARCH;
286 public boolean isIndexerEnabled() {
287 return _INDEXER_ENABLED;
290 public boolean isPermissionAware() {
291 return _PERMISSION_AWARE;
294 public boolean isStagingAware() {
295 return _stagingAware;
298 public void postProcessContextQuery(
299 BooleanQuery contextQuery, SearchContext searchContext)
303 public void postProcessSearchQuery(
304 BooleanQuery searchQuery, SearchContext searchContext)
308 public void registerIndexerPostProcessor(
309 IndexerPostProcessor indexerPostProcessor) {
311 List<IndexerPostProcessor> indexerPostProcessorsList =
312 ListUtil.fromArray(_indexerPostProcessors);
314 indexerPostProcessorsList.add(indexerPostProcessor);
316 _indexerPostProcessors = indexerPostProcessorsList.toArray(
317 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
320 public void reindex(Object obj) throws SearchException {
322 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
328 catch (SearchException se) {
331 catch (Exception e) {
332 throw new SearchException(e);
336 public void reindex(String className, long classPK) throws SearchException {
338 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
342 doReindex(className, classPK);
344 catch (NoSuchModelException nsme) {
345 if (_log.isWarnEnabled()) {
346 _log.warn("Unable to index " + className + " " + classPK);
349 catch (SearchException se) {
352 catch (Exception e) {
353 throw new SearchException(e);
357 public void reindex(String[] ids) throws SearchException {
359 if (SearchEngineUtil.isIndexReadOnly() || !isIndexerEnabled()) {
365 catch (SearchException se) {
368 catch (Exception e) {
369 throw new SearchException(e);
373 public Hits search(SearchContext searchContext) throws SearchException {
375 searchContext.setSearchEngineId(getSearchEngineId());
377 BooleanQuery fullQuery = getFullQuery(searchContext);
379 fullQuery.setQueryConfig(searchContext.getQueryConfig());
381 PermissionChecker permissionChecker =
382 PermissionThreadLocal.getPermissionChecker();
384 int end = searchContext.getEnd();
385 int start = searchContext.getStart();
387 if (isFilterSearch() && (permissionChecker != null)) {
388 searchContext.setEnd(end + INDEX_FILTER_SEARCH_LIMIT);
389 searchContext.setStart(0);
392 Hits hits = SearchEngineUtil.search(searchContext, fullQuery);
394 searchContext.setEnd(end);
395 searchContext.setStart(start);
397 if (isFilterSearch() && (permissionChecker != null)) {
398 hits = filterSearch(hits, permissionChecker, searchContext);
403 catch (SearchException se) {
406 catch (Exception e) {
407 throw new SearchException(e);
411 public void unregisterIndexerPostProcessor(
412 IndexerPostProcessor indexerPostProcessor) {
414 List<IndexerPostProcessor> indexerPostProcessorsList =
415 ListUtil.fromArray(_indexerPostProcessors);
417 indexerPostProcessorsList.remove(indexerPostProcessor);
419 _indexerPostProcessors = indexerPostProcessorsList.toArray(
420 new IndexerPostProcessor[indexerPostProcessorsList.size()]);
424 * @deprecated {@link #addSearchLocalizedTerm(BooleanQuery, SearchContext,
427 protected void addLocalizedSearchTerm(
428 BooleanQuery searchQuery, SearchContext searchContext, String field,
432 addSearchLocalizedTerm(searchQuery, searchContext, field, like);
435 protected void addSearchArrayQuery(
436 BooleanQuery searchQuery, SearchContext searchContext, String field)
439 if (Validator.isNull(field)) {
443 Object fieldValues = searchContext.getAttribute(field);
445 if (fieldValues == null) {
449 BooleanQuery fieldQuery = null;
451 if (fieldValues instanceof int[]) {
452 int[] fieldValuesArray = (int[])fieldValues;
454 if (fieldValuesArray.length == 0) {
458 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
460 for (int fieldValue : fieldValuesArray) {
461 fieldQuery.addTerm(field, fieldValue);
464 else if (fieldValues instanceof Integer[]) {
465 Integer[] fieldValuesArray = (Integer[])fieldValues;
467 if (fieldValuesArray.length == 0) {
471 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
473 for (Integer fieldValue : fieldValuesArray) {
474 fieldQuery.addTerm(field, fieldValue);
477 else if (fieldValues instanceof long[]) {
478 long[] fieldValuesArray = (long[])fieldValues;
480 if (fieldValuesArray.length == 0) {
484 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
486 for (long fieldValue : fieldValuesArray) {
487 fieldQuery.addTerm(field, fieldValue);
490 else if (fieldValues instanceof Long[]) {
491 Long[] fieldValuesArray = (Long[])fieldValues;
493 if (fieldValuesArray.length == 0) {
497 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
499 for (Long fieldValue : fieldValuesArray) {
500 fieldQuery.addTerm(field, fieldValue);
503 else if (fieldValues instanceof short[]) {
504 short[] fieldValuesArray = (short[])fieldValues;
506 if (fieldValuesArray.length == 0) {
510 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
512 for (short fieldValue : fieldValuesArray) {
513 fieldQuery.addTerm(field, fieldValue);
516 else if (fieldValues instanceof Short[]) {
517 Short[] fieldValuesArray = (Short[])fieldValues;
519 if (fieldValuesArray.length == 0) {
523 fieldQuery = BooleanQueryFactoryUtil.create(searchContext);
525 for (Short fieldValue : fieldValuesArray) {
526 fieldQuery.addTerm(field, fieldValue);
530 if (fieldQuery != null) {
531 if (searchContext.isAndSearch()) {
532 searchQuery.add(fieldQuery, BooleanClauseOccur.MUST);
535 searchQuery.add(fieldQuery, BooleanClauseOccur.SHOULD);
540 protected void addSearchAssetCategoryIds(
541 BooleanQuery contextQuery, SearchContext searchContext)
544 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
546 multiValueFacet.setFieldName(Field.ASSET_CATEGORY_IDS);
547 multiValueFacet.setStatic(true);
549 searchContext.addFacet(multiValueFacet);
552 protected void addSearchAssetCategoryTitles(
553 Document document, String field, List<AssetCategory> assetCategories) {
555 Map<Locale, List<String>> assetCategoryTitles =
556 new HashMap<Locale, List<String>>();
558 Locale defaultLocale = LocaleUtil.getDefault();
560 for (AssetCategory assetCategory : assetCategories) {
561 Map<Locale, String> titleMap = assetCategory.getTitleMap();
563 for (Map.Entry<Locale, String> entry : titleMap.entrySet()) {
564 Locale locale = entry.getKey();
565 String title = entry.getValue();
567 if (Validator.isNull(title)) {
571 List<String> titles = assetCategoryTitles.get(locale);
573 if (titles == null) {
574 titles = new ArrayList<String>();
576 assetCategoryTitles.put(locale, titles);
583 for (Map.Entry<Locale, List<String>> entry :
584 assetCategoryTitles.entrySet()) {
586 Locale locale = entry.getKey();
587 List<String> titles = entry.getValue();
589 String[] titlesArray = titles.toArray(new String[0]);
591 if (locale.equals(defaultLocale)) {
592 document.addKeyword(field, titlesArray);
596 field.concat(StringPool.UNDERLINE).concat(locale.toString()),
601 protected void addSearchAssetTagNames(
602 BooleanQuery contextQuery, SearchContext searchContext)
605 MultiValueFacet multiValueFacet = new MultiValueFacet(searchContext);
607 multiValueFacet.setFieldName(Field.ASSET_TAG_NAMES);
608 multiValueFacet.setStatic(true);
610 searchContext.addFacet(multiValueFacet);
613 protected void addSearchDDMStruture(
614 BooleanQuery searchQuery, SearchContext searchContext,
615 DDMStructure ddmStructure)
618 Set<String> fieldNames = ddmStructure.getFieldNames();
620 for (String fieldName : fieldNames) {
621 String name = DDMIndexerUtil.encodeName(
622 ddmStructure.getStructureId(), fieldName);
624 addSearchTerm(searchQuery, searchContext, name, false);
628 protected void addSearchEntryClassNames(
629 BooleanQuery contextQuery, SearchContext searchContext)
632 Facet facet = new AssetEntriesFacet(searchContext);
634 facet.setStatic(true);
636 searchContext.addFacet(facet);
639 protected void addSearchExpando(
640 BooleanQuery searchQuery, SearchContext searchContext,
644 ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
645 searchContext.getCompanyId(), getClassName(searchContext));
647 Set<String> attributeNames = SetUtil.fromEnumeration(
648 expandoBridge.getAttributeNames());
650 for (String attributeName : attributeNames) {
651 UnicodeProperties properties = expandoBridge.getAttributeProperties(
654 int indexType = GetterUtil.getInteger(
655 properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
657 if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
658 String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
661 if (Validator.isNotNull(keywords)) {
662 if (searchContext.isAndSearch()) {
663 searchQuery.addRequiredTerm(fieldName, keywords);
666 searchQuery.addTerm(fieldName, keywords);
673 protected void addSearchGroupId(
674 BooleanQuery contextQuery, SearchContext searchContext)
677 Facet facet = new ScopeFacet(searchContext);
679 facet.setStatic(true);
681 searchContext.addFacet(facet);
684 protected void addSearchKeywords(
685 BooleanQuery searchQuery, SearchContext searchContext)
688 String keywords = searchContext.getKeywords();
690 if (Validator.isNull(keywords)) {
694 searchQuery.addTerms(Field.KEYWORDS, keywords);
696 addSearchExpando(searchQuery, searchContext, keywords);
699 protected void addSearchLocalizedTerm(
700 BooleanQuery searchQuery, SearchContext searchContext, String field,
704 addSearchTerm(searchQuery, searchContext, field, like);
706 searchQuery, searchContext,
707 DocumentImpl.getLocalizedName(searchContext.getLocale(), field),
711 protected void addSearchTerm(
712 BooleanQuery searchQuery, SearchContext searchContext, String field,
716 if (Validator.isNull(field)) {
720 String value = String.valueOf(searchContext.getAttribute(field));
722 if (Validator.isNull(value)) {
723 value = searchContext.getKeywords();
726 if (Validator.isNull(value)) {
730 if (searchContext.isAndSearch()) {
731 searchQuery.addRequiredTerm(field, value, like);
734 searchQuery.addTerm(field, value, like);
738 protected void addStagingGroupKeyword(Document document, long groupId)
741 if (!isStagingAware()) {
745 boolean stagingGroup = false;
747 Group group = GroupLocalServiceUtil.getGroup(groupId);
749 if (group.isLayout()) {
750 group = GroupLocalServiceUtil.getGroup(group.getParentGroupId());
753 if (group.isStagingGroup()) {
757 document.addKeyword(Field.STAGING_GROUP, stagingGroup);
760 protected BooleanQuery createFullQuery(
761 BooleanQuery contextQuery, SearchContext searchContext)
764 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
767 addSearchKeywords(searchQuery, searchContext);
768 postProcessSearchQuery(searchQuery, searchContext);
770 for (IndexerPostProcessor indexerPostProcessor :
771 _indexerPostProcessors) {
773 indexerPostProcessor.postProcessSearchQuery(
774 searchQuery, searchContext);
777 Map<String, Facet> facets = searchContext.getFacets();
779 for (Facet facet : facets.values()) {
780 BooleanClause facetClause = facet.getFacetClause();
782 if (facetClause != null) {
784 facetClause.getQuery(),
785 facetClause.getBooleanClauseOccur());
789 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
791 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
793 if (searchQuery.hasClauses()) {
794 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
797 BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
799 if (booleanClauses != null) {
800 for (BooleanClause booleanClause : booleanClauses) {
802 booleanClause.getQuery(),
803 booleanClause.getBooleanClauseOccur());
807 postProcessFullQuery(fullQuery, searchContext);
809 for (IndexerPostProcessor indexerPostProcessor :
810 _indexerPostProcessors) {
812 indexerPostProcessor.postProcessFullQuery(fullQuery, searchContext);
818 protected void deleteDocument(long companyId, long field1)
821 deleteDocument(companyId, String.valueOf(field1));
824 protected void deleteDocument(long companyId, long field1, String field2)
827 deleteDocument(companyId, String.valueOf(field1), field2);
830 protected void deleteDocument(long companyId, String field1)
833 Document document = new DocumentImpl();
835 document.addUID(getPortletId(), field1);
837 SearchEngineUtil.deleteDocument(
838 getSearchEngineId(), companyId, document.get(Field.UID));
841 protected void deleteDocument(long companyId, String field1, String field2)
844 Document document = new DocumentImpl();
846 document.addUID(getPortletId(), field1, field2);
848 SearchEngineUtil.deleteDocument(
849 getSearchEngineId(), companyId, document.get(Field.UID));
852 protected abstract void doDelete(Object obj) throws Exception;
854 protected abstract Document doGetDocument(Object obj) throws Exception;
856 protected String doGetSortField(String orderByCol) {
860 protected abstract Summary doGetSummary(
861 Document document, Locale locale, String snippet,
862 PortletURL portletURL)
865 protected abstract void doReindex(Object obj) throws Exception;
867 protected abstract void doReindex(String className, long classPK)
870 protected abstract void doReindex(String[] ids) throws Exception;
872 protected Hits filterSearch(
873 Hits hits, PermissionChecker permissionChecker,
874 SearchContext searchContext) {
876 List<Document> docs = new ArrayList<Document>();
877 List<Float> scores = new ArrayList<Float>();
879 int start = searchContext.getStart();
880 int end = searchContext.getEnd();
882 String paginationType = GetterUtil.getString(
883 searchContext.getAttribute("paginationType"), "more");
885 boolean hasMore = false;
887 Document[] documents = hits.getDocs();
889 for (int i = 0; i < documents.length; i++) {
891 Document document = documents[i];
893 String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
894 long entryClassPK = GetterUtil.getLong(
895 document.get(Field.ENTRY_CLASS_PK));
897 Indexer indexer = IndexerRegistryUtil.getIndexer(
900 if ((indexer.isFilterSearch() &&
901 indexer.hasPermission(
902 permissionChecker, entryClassPK, ActionKeys.VIEW)) ||
903 !indexer.isFilterSearch() ||
904 !indexer.isPermissionAware()) {
907 scores.add(hits.score(i));
910 catch (Exception e) {
913 if (paginationType.equals("more") && (docs.size() > end)) {
920 int length = docs.size();
923 length = length + (end - start);
926 hits.setLength(length);
928 if ((start != QueryUtil.ALL_POS) && (end != QueryUtil.ALL_POS)) {
933 docs = docs.subList(start, end);
936 hits.setDocs(docs.toArray(new Document[docs.size()]));
937 hits.setScores(scores.toArray(new Float[docs.size()]));
940 (float)(System.currentTimeMillis() - hits.getStart()) /
946 protected Document getBaseModelDocument(
947 String portletId, BaseModel<?> baseModel)
948 throws SystemException {
950 Document document = new DocumentImpl();
952 String className = baseModel.getModelClassName();
955 long resourcePrimKey = 0;
957 if (baseModel instanceof ResourcedModel) {
958 ResourcedModel resourcedModel = (ResourcedModel)baseModel;
960 classPK = resourcedModel.getResourcePrimKey();
961 resourcePrimKey = resourcedModel.getResourcePrimKey();
964 classPK = (Long)baseModel.getPrimaryKeyObj();
967 document.addUID(portletId, classPK);
970 List<AssetCategory> assetCategories =
971 AssetCategoryLocalServiceUtil.getCategories(className, classPK);
973 long[] assetCategoryIds = StringUtil.split(
975 assetCategories, AssetCategory.CATEGORY_ID_ACCESSOR),
978 document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
980 addSearchAssetCategoryTitles(
981 document, Field.ASSET_CATEGORY_TITLES, assetCategories);
984 // No Asset Categories
988 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
991 document.addText(Field.ASSET_TAG_NAMES, assetTagNames);
994 // No Asset Tag Names
997 document.addKeyword(Field.ENTRY_CLASS_NAME, className);
998 document.addKeyword(Field.ENTRY_CLASS_PK, classPK);
999 document.addKeyword(Field.PORTLET_ID, portletId);
1001 if (resourcePrimKey > 0) {
1002 document.addKeyword(Field.ROOT_ENTRY_CLASS_PK, resourcePrimKey);
1005 if (baseModel instanceof AttachedModel) {
1006 AttachedModel attachedModel = (AttachedModel)baseModel;
1008 document.addKeyword(
1009 Field.CLASS_NAME_ID, attachedModel.getClassNameId());
1010 document.addKeyword(Field.CLASS_PK, attachedModel.getClassPK());
1013 if (baseModel instanceof AuditedModel) {
1014 AuditedModel auditedModel = (AuditedModel)baseModel;
1016 document.addKeyword(Field.COMPANY_ID, auditedModel.getCompanyId());
1017 document.addDate(Field.CREATE_DATE, auditedModel.getCreateDate());
1019 Field.MODIFIED_DATE, auditedModel.getModifiedDate());
1020 document.addKeyword(Field.USER_ID, auditedModel.getUserId());
1022 String userName = PortalUtil.getUserName(
1023 auditedModel.getUserId(), auditedModel.getUserName());
1025 document.addKeyword(Field.USER_NAME, userName, true);
1028 if (baseModel instanceof GroupedModel) {
1029 GroupedModel groupedModel = (GroupedModel)baseModel;
1031 document.addKeyword(
1032 Field.GROUP_ID, getParentGroupId(groupedModel.getGroupId()));
1033 document.addKeyword(
1034 Field.SCOPE_GROUP_ID, groupedModel.getGroupId());
1037 if (baseModel instanceof WorkflowedModel) {
1038 WorkflowedModel workflowedModel = (WorkflowedModel)baseModel;
1040 document.addKeyword(Field.STATUS, workflowedModel.getStatus());
1043 ExpandoBridgeIndexerUtil.addAttributes(
1044 document, baseModel.getExpandoBridge());
1049 protected String getClassName(SearchContext searchContext) {
1050 String[] classNames = getClassNames();
1052 if (classNames.length != 1) {
1053 throw new UnsupportedOperationException(
1054 "Search method needs to be manually implemented for " +
1055 "indexers with more than one class name");
1058 return classNames[0];
1061 protected long getParentGroupId(long groupId) {
1062 long parentGroupId = groupId;
1065 Group group = GroupLocalServiceUtil.getGroup(groupId);
1067 if (group.isLayout()) {
1068 parentGroupId = group.getParentGroupId();
1071 catch (Exception e) {
1074 return parentGroupId;
1077 protected abstract String getPortletId(SearchContext searchContext);
1079 protected void populateAddresses(
1080 Document document, List<Address> addresses, long regionId,
1082 throws PortalException, SystemException {
1084 List<String> cities = new ArrayList<String>();
1086 List<String> countries = new ArrayList<String>();
1088 if (countryId > 0) {
1090 Country country = CountryServiceUtil.getCountry(countryId);
1092 countries.add(country.getName().toLowerCase());
1094 catch (NoSuchCountryException nsce) {
1095 if (_log.isWarnEnabled()) {
1096 _log.warn(nsce.getMessage());
1101 List<String> regions = new ArrayList<String>();
1105 Region region = RegionServiceUtil.getRegion(regionId);
1107 regions.add(region.getName().toLowerCase());
1109 catch (NoSuchRegionException nsre) {
1110 if (_log.isWarnEnabled()) {
1111 _log.warn(nsre.getMessage());
1116 List<String> streets = new ArrayList<String>();
1117 List<String> zips = new ArrayList<String>();
1119 for (Address address : addresses) {
1120 cities.add(address.getCity().toLowerCase());
1121 countries.add(address.getCountry().getName().toLowerCase());
1122 regions.add(address.getRegion().getName().toLowerCase());
1123 streets.add(address.getStreet1().toLowerCase());
1124 streets.add(address.getStreet2().toLowerCase());
1125 streets.add(address.getStreet3().toLowerCase());
1126 zips.add(address.getZip().toLowerCase());
1129 document.addText("city", cities.toArray(new String[cities.size()]));
1131 "country", countries.toArray(new String[countries.size()]));
1132 document.addText("region", regions.toArray(new String[regions.size()]));
1133 document.addText("street", streets.toArray(new String[streets.size()]));
1134 document.addText("zip", zips.toArray(new String[zips.size()]));
1137 protected void postProcessFullQuery(
1138 BooleanQuery fullQuery, SearchContext searchContext)
1142 protected void setStagingAware(boolean stagingAware) {
1143 _stagingAware = stagingAware;
1146 private static final boolean _FILTER_SEARCH = false;
1148 private static final boolean _INDEXER_ENABLED = true;
1150 private static final boolean _PERMISSION_AWARE = false;
1152 private static Log _log = LogFactoryUtil.getLog(BaseIndexer.class);
1154 private IndexerPostProcessor[] _indexerPostProcessors =
1155 new IndexerPostProcessor[0];
1156 private String _searchEngineId;
1157 private boolean _stagingAware = true;