001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.portal.kernel.search.facet.Facet;
018 import com.liferay.portal.kernel.util.GetterUtil;
019 import com.liferay.portal.kernel.util.SetUtil;
020 import com.liferay.portal.kernel.util.UnicodeProperties;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.security.permission.PermissionChecker;
023 import com.liferay.portal.security.permission.PermissionThreadLocal;
024 import com.liferay.portlet.expando.model.ExpandoBridge;
025 import com.liferay.portlet.expando.model.ExpandoColumnConstants;
026 import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
027 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
028
029 import java.util.Locale;
030 import java.util.Map;
031 import java.util.Set;
032
033 import javax.portlet.PortletURL;
034
035
038 public class FacetedSearcher extends BaseIndexer {
039
040 public static Indexer getInstance() {
041 return new FacetedSearcher();
042 }
043
044 @Override
045 public String[] getClassNames() {
046 return null;
047 }
048
049 @Override
050 public IndexerPostProcessor[] getIndexerPostProcessors() {
051 throw new UnsupportedOperationException();
052 }
053
054 @Override
055 public String getPortletId() {
056 return null;
057 }
058
059 @Override
060 public void registerIndexerPostProcessor(
061 IndexerPostProcessor indexerPostProcessor) {
062
063 throw new UnsupportedOperationException();
064 }
065
066 @Override
067 public Hits search(SearchContext searchContext) throws SearchException {
068 try {
069 searchContext.setSearchEngineId(getSearchEngineId());
070
071 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
072 searchContext);
073
074 contextQuery.addRequiredTerm(
075 Field.COMPANY_ID, searchContext.getCompanyId());
076
077 BooleanQuery fullQuery = createFullQuery(
078 contextQuery, searchContext);
079
080 fullQuery.setQueryConfig(searchContext.getQueryConfig());
081
082 PermissionChecker permissionChecker =
083 PermissionThreadLocal.getPermissionChecker();
084
085 int end = searchContext.getEnd();
086 int start = searchContext.getStart();
087
088 if (isFilterSearch(searchContext) && (permissionChecker != null)) {
089 searchContext.setEnd(end + INDEX_FILTER_SEARCH_LIMIT);
090 searchContext.setStart(0);
091 }
092
093 Hits hits = SearchEngineUtil.search(searchContext, fullQuery);
094
095 searchContext.setEnd(end);
096 searchContext.setStart(start);
097
098 if (isFilterSearch(searchContext) && (permissionChecker != null)) {
099 hits = filterSearch(hits, permissionChecker, searchContext);
100 }
101
102 processHits(searchContext, hits);
103
104 return hits;
105 }
106 catch (SearchException se) {
107 throw se;
108 }
109 catch (Exception e) {
110 throw new SearchException(e);
111 }
112 }
113
114 @Override
115 public void unregisterIndexerPostProcessor(
116 IndexerPostProcessor indexerPostProcessor) {
117
118 throw new UnsupportedOperationException();
119 }
120
121 protected void addSearchExpandoKeywords(
122 BooleanQuery searchQuery, SearchContext searchContext,
123 String keywords, String className)
124 throws Exception {
125
126 ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
127 searchContext.getCompanyId(), className);
128
129 Set<String> attributeNames = SetUtil.fromEnumeration(
130 expandoBridge.getAttributeNames());
131
132 for (String attributeName : attributeNames) {
133 UnicodeProperties properties = expandoBridge.getAttributeProperties(
134 attributeName);
135
136 int indexType = GetterUtil.getInteger(
137 properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
138
139 if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
140 String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
141 attributeName);
142
143 if (searchContext.isAndSearch()) {
144 searchQuery.addRequiredTerm(fieldName, keywords);
145 }
146 else {
147 searchQuery.addTerm(fieldName, keywords);
148 }
149 }
150 }
151 }
152
153 @Override
154 protected BooleanQuery createFullQuery(
155 BooleanQuery contextQuery, SearchContext searchContext)
156 throws Exception {
157
158 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
159 searchContext);
160
161 String keywords = searchContext.getKeywords();
162
163 if (Validator.isNotNull(keywords)) {
164 addSearchLocalizedTerm(
165 searchQuery, searchContext, Field.ASSET_CATEGORY_TITLES, false);
166
167 searchQuery.addExactTerm(Field.ASSET_TAG_NAMES, keywords);
168 searchQuery.addTerms(Field.KEYWORDS, keywords);
169
170 int groupId = GetterUtil.getInteger(
171 searchContext.getAttribute(Field.GROUP_ID));
172
173 if (groupId == 0) {
174 searchQuery.addTerm(
175 Field.STAGING_GROUP, "true", false,
176 BooleanClauseOccur.MUST_NOT);
177 }
178 }
179
180 for (String entryClassName : searchContext.getEntryClassNames()) {
181 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
182
183 if (indexer == null) {
184 continue;
185 }
186
187 String searchEngineId = searchContext.getSearchEngineId();
188
189 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
190 continue;
191 }
192
193 if (Validator.isNotNull(keywords)) {
194 addSearchExpandoKeywords(
195 searchQuery, searchContext, keywords, entryClassName);
196 }
197
198 indexer.postProcessSearchQuery(searchQuery, searchContext);
199
200 for (IndexerPostProcessor indexerPostProcessor :
201 indexer.getIndexerPostProcessors()) {
202
203 indexerPostProcessor.postProcessSearchQuery(
204 searchQuery, searchContext);
205 }
206 }
207
208 Map<String, Facet> facets = searchContext.getFacets();
209
210 for (Facet facet : facets.values()) {
211 BooleanClause facetClause = facet.getFacetClause();
212
213 if (facetClause != null) {
214 contextQuery.add(
215 facetClause.getQuery(),
216 facetClause.getBooleanClauseOccur());
217 }
218 }
219
220 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
221
222 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
223
224 if (searchQuery.hasClauses()) {
225 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
226 }
227
228 BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
229
230 if (booleanClauses != null) {
231 for (BooleanClause booleanClause : booleanClauses) {
232 fullQuery.add(
233 booleanClause.getQuery(),
234 booleanClause.getBooleanClauseOccur());
235 }
236 }
237
238 for (String entryClassName : searchContext.getEntryClassNames()) {
239 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
240
241 if (indexer == null) {
242 continue;
243 }
244
245 String searchEngineId = searchContext.getSearchEngineId();
246
247 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
248 continue;
249 }
250
251 for (IndexerPostProcessor indexerPostProcessor :
252 indexer.getIndexerPostProcessors()) {
253
254 indexerPostProcessor.postProcessFullQuery(
255 fullQuery, searchContext);
256 }
257 }
258
259 return fullQuery;
260 }
261
262 @Override
263 protected void doDelete(Object obj) throws Exception {
264 throw new UnsupportedOperationException();
265 }
266
267 @Override
268 protected Document doGetDocument(Object obj) throws Exception {
269 throw new UnsupportedOperationException();
270 }
271
272 @Override
273 protected Summary doGetSummary(
274 Document document, Locale locale, String snippet,
275 PortletURL portletURL)
276 throws Exception {
277
278 throw new UnsupportedOperationException();
279 }
280
281 @Override
282 protected void doReindex(Object obj) throws Exception {
283 throw new UnsupportedOperationException();
284 }
285
286 @Override
287 protected void doReindex(String className, long classPK) throws Exception {
288 throw new UnsupportedOperationException();
289 }
290
291 @Override
292 protected void doReindex(String[] ids) throws Exception {
293 throw new UnsupportedOperationException();
294 }
295
296 @Override
297 protected String getPortletId(SearchContext searchContext) {
298 return null;
299 }
300
301 protected boolean isFilterSearch(SearchContext searchContext) {
302 if (searchContext.getEntryClassNames() == null) {
303 return super.isFilterSearch();
304 }
305
306 for (String entryClassName : searchContext.getEntryClassNames()) {
307 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
308
309 if (indexer == null) {
310 continue;
311 }
312
313 if (indexer.isFilterSearch()) {
314 return true;
315 }
316 }
317
318 return super.isFilterSearch();
319 }
320
321 }