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
171 for (String entryClassName : searchContext.getEntryClassNames()) {
172 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
173
174 if (indexer == null) {
175 continue;
176 }
177
178 String searchEngineId = searchContext.getSearchEngineId();
179
180 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
181 continue;
182 }
183
184 if (Validator.isNotNull(keywords)) {
185 addSearchExpandoKeywords(
186 searchQuery, searchContext, keywords, entryClassName);
187 }
188
189 indexer.postProcessSearchQuery(searchQuery, searchContext);
190
191 for (IndexerPostProcessor indexerPostProcessor :
192 indexer.getIndexerPostProcessors()) {
193
194 indexerPostProcessor.postProcessSearchQuery(
195 searchQuery, searchContext);
196 }
197 }
198
199 Map<String, Facet> facets = searchContext.getFacets();
200
201 for (Facet facet : facets.values()) {
202 BooleanClause facetClause = facet.getFacetClause();
203
204 if (facetClause != null) {
205 contextQuery.add(
206 facetClause.getQuery(),
207 facetClause.getBooleanClauseOccur());
208 }
209 }
210
211 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
212
213 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
214
215 if (searchQuery.hasClauses()) {
216 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
217 }
218
219 BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
220
221 if (booleanClauses != null) {
222 for (BooleanClause booleanClause : booleanClauses) {
223 fullQuery.add(
224 booleanClause.getQuery(),
225 booleanClause.getBooleanClauseOccur());
226 }
227 }
228
229 for (String entryClassName : searchContext.getEntryClassNames()) {
230 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
231
232 if (indexer == null) {
233 continue;
234 }
235
236 String searchEngineId = searchContext.getSearchEngineId();
237
238 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
239 continue;
240 }
241
242 for (IndexerPostProcessor indexerPostProcessor :
243 indexer.getIndexerPostProcessors()) {
244
245 indexerPostProcessor.postProcessFullQuery(
246 fullQuery, searchContext);
247 }
248 }
249
250 return fullQuery;
251 }
252
253 @Override
254 protected void doDelete(Object obj) throws Exception {
255 throw new UnsupportedOperationException();
256 }
257
258 @Override
259 protected Document doGetDocument(Object obj) throws Exception {
260 throw new UnsupportedOperationException();
261 }
262
263 @Override
264 protected Summary doGetSummary(
265 Document document, Locale locale, String snippet,
266 PortletURL portletURL)
267 throws Exception {
268
269 throw new UnsupportedOperationException();
270 }
271
272 @Override
273 protected void doReindex(Object obj) throws Exception {
274 throw new UnsupportedOperationException();
275 }
276
277 @Override
278 protected void doReindex(String className, long classPK) throws Exception {
279 throw new UnsupportedOperationException();
280 }
281
282 @Override
283 protected void doReindex(String[] ids) throws Exception {
284 throw new UnsupportedOperationException();
285 }
286
287 @Override
288 protected String getPortletId(SearchContext searchContext) {
289 return null;
290 }
291
292 protected boolean isFilterSearch(SearchContext searchContext) {
293 if (searchContext.getEntryClassNames() == null) {
294 return super.isFilterSearch();
295 }
296
297 for (String entryClassName : searchContext.getEntryClassNames()) {
298 Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
299
300 if (indexer == null) {
301 continue;
302 }
303
304 if (indexer.isFilterSearch()) {
305 return true;
306 }
307 }
308
309 return super.isFilterSearch();
310 }
311
312 }