1
14
15 package com.liferay.portal.search;
16
17 import com.liferay.portal.NoSuchModelException;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.search.BooleanClause;
21 import com.liferay.portal.kernel.search.BooleanClauseOccur;
22 import com.liferay.portal.kernel.search.BooleanQuery;
23 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
24 import com.liferay.portal.kernel.search.Document;
25 import com.liferay.portal.kernel.search.Field;
26 import com.liferay.portal.kernel.search.Hits;
27 import com.liferay.portal.kernel.search.Indexer;
28 import com.liferay.portal.kernel.search.SearchContext;
29 import com.liferay.portal.kernel.search.SearchEngineUtil;
30 import com.liferay.portal.kernel.search.SearchException;
31 import com.liferay.portal.kernel.search.TermQuery;
32 import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.model.Group;
35 import com.liferay.portal.service.GroupLocalServiceUtil;
36
37
42 public abstract class BaseIndexer implements Indexer {
43
44 public void delete(Object obj) throws SearchException {
45 try {
46 doDelete(obj);
47 }
48 catch (SearchException se) {
49 throw se;
50 }
51 catch (Exception e) {
52 throw new SearchException(e);
53 }
54 }
55
56 public Document getDocument(Object obj) throws SearchException {
57 try {
58 return doGetDocument(obj);
59 }
60 catch (SearchException se) {
61 throw se;
62 }
63 catch (Exception e) {
64 throw new SearchException(e);
65 }
66 }
67
68 public void reindex(Object obj) throws SearchException {
69 try {
70 if (SearchEngineUtil.isIndexReadOnly()) {
71 return;
72 }
73
74 doReindex(obj);
75 }
76 catch (SearchException se) {
77 throw se;
78 }
79 catch (Exception e) {
80 throw new SearchException(e);
81 }
82 }
83
84 public void reindex(String className, long classPK) throws SearchException {
85 try {
86 if (SearchEngineUtil.isIndexReadOnly()) {
87 return;
88 }
89
90 doReindex(className, classPK);
91 }
92 catch (NoSuchModelException nsme) {
93 if (_log.isWarnEnabled()) {
94 _log.warn("Unable to index " + className + " " + classPK);
95 }
96 }
97 catch (SearchException se) {
98 throw se;
99 }
100 catch (Exception e) {
101 throw new SearchException(e);
102 }
103 }
104
105 public void reindex(String[] ids) throws SearchException {
106 try {
107 if (SearchEngineUtil.isIndexReadOnly()) {
108 return;
109 }
110
111 doReindex(ids);
112 }
113 catch (SearchException se) {
114 throw se;
115 }
116 catch (Exception e) {
117 throw new SearchException(e);
118 }
119 }
120
121 public Hits search(SearchContext searchContext) throws SearchException {
122 try {
123 String className = getClassName(searchContext);
124
125 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
126
127 contextQuery.addRequiredTerm(
128 Field.PORTLET_ID, getPortletId(searchContext));
129
130 addSearchGroupId(contextQuery, searchContext);
131 addSearchOwnerUserId(contextQuery, searchContext);
132 addSearchCategoryIds(contextQuery, searchContext);
133 addSearchNodeIds(contextQuery, searchContext);
134 addSearchFolderIds(contextQuery, searchContext);
135
136 BooleanQuery fullQuery = createFullQuery(
137 contextQuery, searchContext);
138
139 return SearchEngineUtil.search(
140 searchContext.getCompanyId(), searchContext.getGroupId(),
141 searchContext.getUserId(), className, fullQuery,
142 searchContext.getSorts(), searchContext.getStart(),
143 searchContext.getEnd());
144 }
145 catch (SearchException se) {
146 throw se;
147 }
148 catch (Exception e) {
149 throw new SearchException(e);
150 }
151 }
152
153 protected void addSearchCategoryIds(
154 BooleanQuery contextQuery, SearchContext searchContext)
155 throws Exception {
156
157 long[] categoryIds = searchContext.getCategoryIds();
158
159 if ((categoryIds == null) || (categoryIds.length == 0)) {
160 return;
161 }
162
163 BooleanQuery categoryIdsQuery = BooleanQueryFactoryUtil.create();
164
165 for (long categoryId : categoryIds) {
166 if (searchContext.getUserId() > 0) {
167 try {
168 checkSearchCategoryId(categoryId, searchContext);
169 }
170 catch (Exception e) {
171 continue;
172 }
173 }
174
175 TermQuery termQuery = TermQueryFactoryUtil.create(
176 Field.CATEGORY_ID, categoryId);
177
178 categoryIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
179 }
180
181 contextQuery.add(categoryIdsQuery, BooleanClauseOccur.MUST);
182 }
183
184 protected void addSearchFolderIds(
185 BooleanQuery contextQuery, SearchContext searchContext)
186 throws Exception {
187
188 long[] folderIds = searchContext.getFolderIds();
189
190 if ((folderIds == null) || (folderIds.length == 0)) {
191 return;
192 }
193
194 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
195
196 for (long folderId : folderIds) {
197 if (searchContext.getUserId() > 0) {
198 try {
199 checkSearchFolderId(folderId, searchContext);
200 }
201 catch (Exception e) {
202 continue;
203 }
204 }
205
206 TermQuery termQuery = TermQueryFactoryUtil.create(
207 Field.FOLDER_ID, folderId);
208
209 folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
210 }
211
212 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
213 }
214
215 protected void addSearchGroupId(
216 BooleanQuery contextQuery, SearchContext searchContext)
217 throws Exception {
218
219 long groupId = searchContext.getGroupId();
220
221 if (groupId <= 0) {
222 return;
223 }
224
225 Group group = GroupLocalServiceUtil.getGroup(groupId);
226
227 long parentGroupId = groupId;
228
229 if (group.isLayout() || searchContext.isScopeStrict()) {
230 contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
231 }
232
233 if (group.isLayout()) {
234 parentGroupId = group.getParentGroupId();
235 }
236
237 contextQuery.addRequiredTerm(Field.GROUP_ID, parentGroupId);
238
239 searchContext.setGroupId(parentGroupId);
240 }
241
242 protected void addSearchKeywords(
243 BooleanQuery searchQuery, SearchContext searchContext)
244 throws Exception {
245
246 String keywords = searchContext.getKeywords();
247
248 if (Validator.isNull(keywords)) {
249 return;
250 }
251
252 searchQuery.addTerm(Field.USER_NAME, keywords);
253 searchQuery.addTerm(Field.TITLE, keywords);
254 searchQuery.addTerm(Field.CONTENT, keywords);
255 searchQuery.addTerm(Field.DESCRIPTION, keywords);
256 searchQuery.addTerm(Field.PROPERTIES, keywords);
257 searchQuery.addTerm(Field.ASSET_TAG_NAMES, keywords, true);
258 searchQuery.addTerm(Field.URL, keywords);
259 searchQuery.addTerm(Field.COMMENTS, keywords);
260 }
261
262 protected void addSearchNodeIds(
263 BooleanQuery contextQuery, SearchContext searchContext)
264 throws Exception {
265
266 long[] nodeIds = searchContext.getNodeIds();
267
268 if ((nodeIds == null) || (nodeIds.length == 0)) {
269 return;
270 }
271
272 BooleanQuery nodeIdsQuery = BooleanQueryFactoryUtil.create();
273
274 for (long nodeId : nodeIds) {
275 if (searchContext.getUserId() > 0) {
276 try {
277 checkSearchNodeId(nodeId, searchContext);
278 }
279 catch (Exception e) {
280 continue;
281 }
282 }
283
284 TermQuery termQuery = TermQueryFactoryUtil.create(
285 Field.NODE_ID, nodeId);
286
287 nodeIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
288 }
289
290 contextQuery.add(nodeIdsQuery, BooleanClauseOccur.MUST);
291 }
292
293 protected void addSearchOwnerUserId(
294 BooleanQuery contextQuery, SearchContext searchContext) {
295
296 long ownerUserId = searchContext.getOwnerUserId();
297
298 if (ownerUserId > 0) {
299 contextQuery.addRequiredTerm(Field.USER_ID, ownerUserId);
300 }
301 }
302
303 protected void checkSearchCategoryId(
304 long categoryId, SearchContext searchContext)
305 throws Exception {
306 }
307
308 protected void checkSearchFolderId(
309 long folderId, SearchContext searchContext)
310 throws Exception {
311 }
312
313 protected void checkSearchNodeId(
314 long nodeId, SearchContext searchContext)
315 throws Exception {
316 }
317
318 protected BooleanQuery createFullQuery(
319 BooleanQuery contextQuery, SearchContext searchContext)
320 throws Exception {
321
322 postProcessContextQuery(contextQuery, searchContext);
323
324 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
325
326 addSearchKeywords(searchQuery, searchContext);
327 postProcessSearchQuery(searchQuery, searchContext);
328
329 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
330
331 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
332
333 if (searchQuery.clauses().size() > 0) {
334 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
335 }
336
337 BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
338
339 if (booleanClauses != null) {
340 for (BooleanClause booleanClause : booleanClauses) {
341 fullQuery.add(
342 booleanClause.getQuery(),
343 booleanClause.getBooleanClauseOccur());
344 }
345 }
346
347 postProcessFullQuery(fullQuery, searchContext);
348
349 return fullQuery;
350 }
351
352 protected abstract void doDelete(Object obj) throws Exception;
353
354 protected abstract Document doGetDocument(Object obj) throws Exception;
355
356 protected abstract void doReindex(Object obj) throws Exception;
357
358 protected abstract void doReindex(String className, long classPK)
359 throws Exception;
360
361 protected abstract void doReindex(String[] ids) throws Exception;
362
363 protected String getClassName(SearchContext searchContext) {
364 String[] classNames = getClassNames();
365
366 if (classNames.length != 1) {
367 throw new UnsupportedOperationException(
368 "Search method needs to be manually implemented for " +
369 "indexers with more than one class name");
370 }
371
372 return classNames[0];
373 }
374
375 protected long getParentGroupId(long groupId) {
376 long parentGroupId = groupId;
377
378 try {
379 Group group = GroupLocalServiceUtil.getGroup(groupId);
380
381 if (group.isLayout()) {
382 parentGroupId = group.getParentGroupId();
383 }
384 }
385 catch (Exception e) {
386 }
387
388 return parentGroupId;
389 }
390
391 protected abstract String getPortletId(SearchContext searchContext);
392
393 protected void postProcessContextQuery(
394 BooleanQuery contextQuery, SearchContext searchContext)
395 throws Exception {
396 }
397
398 protected void postProcessFullQuery(
399 BooleanQuery fullQuery, SearchContext searchContext)
400 throws Exception {
401 }
402
403 protected void postProcessSearchQuery(
404 BooleanQuery searchQuery, SearchContext searchContext)
405 throws Exception {
406 }
407
408 private static Log _log = LogFactoryUtil.getLog(BaseIndexer.class);
409
410 }