001
014
015 package com.liferay.portlet.wiki.util;
016
017 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
018 import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
019 import com.liferay.portal.kernel.dao.orm.Projection;
020 import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
021 import com.liferay.portal.kernel.dao.orm.ProjectionList;
022 import com.liferay.portal.kernel.dao.orm.Property;
023 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
024 import com.liferay.portal.kernel.dao.orm.QueryUtil;
025 import com.liferay.portal.kernel.search.BaseIndexer;
026 import com.liferay.portal.kernel.search.BooleanClauseOccur;
027 import com.liferay.portal.kernel.search.BooleanQuery;
028 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
029 import com.liferay.portal.kernel.search.Document;
030 import com.liferay.portal.kernel.search.DocumentImpl;
031 import com.liferay.portal.kernel.search.Field;
032 import com.liferay.portal.kernel.search.Hits;
033 import com.liferay.portal.kernel.search.SearchContext;
034 import com.liferay.portal.kernel.search.SearchEngineUtil;
035 import com.liferay.portal.kernel.search.Summary;
036 import com.liferay.portal.kernel.util.GetterUtil;
037 import com.liferay.portal.kernel.util.HtmlUtil;
038 import com.liferay.portal.kernel.util.StringUtil;
039 import com.liferay.portal.kernel.util.Validator;
040 import com.liferay.portal.kernel.workflow.WorkflowConstants;
041 import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
042 import com.liferay.portal.util.PortletKeys;
043 import com.liferay.portlet.wiki.model.WikiNode;
044 import com.liferay.portlet.wiki.model.WikiPage;
045 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
046 import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
047 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
048
049 import java.util.ArrayList;
050 import java.util.Collection;
051 import java.util.List;
052 import java.util.Locale;
053
054 import javax.portlet.PortletURL;
055
056
062 public class WikiIndexer extends BaseIndexer {
063
064 public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
065
066 public static final String PORTLET_ID = PortletKeys.WIKI;
067
068 public String[] getClassNames() {
069 return CLASS_NAMES;
070 }
071
072 public String getPortletId() {
073 return PORTLET_ID;
074 }
075
076 @Override
077 public boolean isPermissionAware() {
078 return _PERMISSION_AWARE;
079 }
080
081 @Override
082 public void postProcessContextQuery(
083 BooleanQuery contextQuery, SearchContext searchContext)
084 throws Exception {
085
086 int status = GetterUtil.getInteger(
087 searchContext.getAttribute(Field.STATUS),
088 WorkflowConstants.STATUS_ANY);
089
090 if (status != WorkflowConstants.STATUS_ANY) {
091 contextQuery.addRequiredTerm(Field.STATUS, status);
092 }
093
094 long[] nodeIds = searchContext.getNodeIds();
095
096 if ((nodeIds != null) && (nodeIds.length > 0)) {
097 BooleanQuery nodeIdsQuery = BooleanQueryFactoryUtil.create(
098 searchContext);
099
100 for (long nodeId : nodeIds) {
101 try {
102 WikiNodeServiceUtil.getNode(nodeId);
103 }
104 catch (Exception e) {
105 continue;
106 }
107
108 nodeIdsQuery.addTerm(Field.NODE_ID, nodeId);
109 }
110
111 contextQuery.add(nodeIdsQuery, BooleanClauseOccur.MUST);
112 }
113 }
114
115 protected void addReindexCriteria(
116 DynamicQuery dynamicQuery, long companyId) {
117
118 Property property = PropertyFactoryUtil.forName("companyId");
119
120 dynamicQuery.add(property.eq(companyId));
121 }
122
123 protected void addReindexCriteria(
124 DynamicQuery dynamicQuery, long groupId, long nodeId) {
125
126 Property groupIdProperty = PropertyFactoryUtil.forName("groupId");
127
128 dynamicQuery.add(groupIdProperty.eq(groupId));
129
130 Property nodeIdProperty = PropertyFactoryUtil.forName("nodeId");
131
132 dynamicQuery.add(nodeIdProperty.eq(nodeId));
133
134 Property headProperty = PropertyFactoryUtil.forName("head");
135
136 dynamicQuery.add(headProperty.eq(true));
137 }
138
139 @Override
140 protected void doDelete(Object obj) throws Exception {
141 SearchContext searchContext = new SearchContext();
142
143 searchContext.setSearchEngineId(getSearchEngineId());
144
145 if (obj instanceof Object[]) {
146 Object[] array = (Object[])obj;
147
148 long companyId = (Long)array[0];
149 long nodeId = (Long)array[1];
150 String title = (String)array[2];
151
152 Document document = new DocumentImpl();
153
154 document.addUID(PORTLET_ID, nodeId, title);
155
156 SearchEngineUtil.deleteDocument(
157 getSearchEngineId(), companyId, document.get(Field.UID));
158
159 }
160 else if (obj instanceof WikiNode) {
161 WikiNode node = (WikiNode)obj;
162
163 BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create(
164 searchContext);
165
166 booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
167
168 booleanQuery.addRequiredTerm("nodeId", node.getNodeId());
169
170 Hits hits = SearchEngineUtil.search(
171 getSearchEngineId(), node.getCompanyId(), booleanQuery,
172 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
173
174 for (int i = 0; i < hits.getLength(); i++) {
175 Document document = hits.doc(i);
176
177 SearchEngineUtil.deleteDocument(
178 getSearchEngineId(), node.getCompanyId(),
179 document.get(Field.UID));
180 }
181 }
182 else if (obj instanceof WikiPage) {
183 WikiPage page = (WikiPage)obj;
184
185 Document document = new DocumentImpl();
186
187 document.addUID(PORTLET_ID, page.getNodeId(), page.getTitle());
188
189 SearchEngineUtil.deleteDocument(
190 getSearchEngineId(), page.getCompanyId(),
191 document.get(Field.UID));
192 }
193 }
194
195 @Override
196 protected Document doGetDocument(Object obj) throws Exception {
197 WikiPage page = (WikiPage)obj;
198
199 Document document = getBaseModelDocument(PORTLET_ID, page);
200
201 document.addUID(PORTLET_ID, page.getNodeId(), page.getTitle());
202
203 String content = HtmlUtil.extractText(
204 WikiUtil.convert(page, null, null, null));
205
206 document.addText(Field.CONTENT, content);
207
208 document.addKeyword(Field.NODE_ID, page.getNodeId());
209 document.addText(Field.TITLE, page.getTitle());
210
211 return document;
212 }
213
214 @Override
215 protected Summary doGetSummary(
216 Document document, Locale locale, String snippet,
217 PortletURL portletURL) {
218
219 String title = document.get(Field.TITLE);
220
221 String content = snippet;
222
223 if (Validator.isNull(snippet)) {
224 content = StringUtil.shorten(document.get(Field.CONTENT), 200);
225 }
226
227 String nodeId = document.get("nodeId");
228
229 portletURL.setParameter("struts_action", "/wiki/view");
230 portletURL.setParameter("nodeId", nodeId);
231 portletURL.setParameter("title", title);
232
233 return new Summary(title, content, portletURL);
234 }
235
236 @Override
237 protected void doReindex(Object obj) throws Exception {
238 WikiPage page = (WikiPage)obj;
239
240 if (Validator.isNotNull(page.getRedirectTitle())) {
241 return;
242 }
243
244 Document document = getDocument(page);
245
246 SearchEngineUtil.updateDocument(
247 getSearchEngineId(), page.getCompanyId(), document);
248 }
249
250 @Override
251 protected void doReindex(String className, long classPK) throws Exception {
252 WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
253
254 doReindex(page);
255 }
256
257 @Override
258 protected void doReindex(String[] ids) throws Exception {
259 long companyId = GetterUtil.getLong(ids[0]);
260
261 reindexNodes(companyId);
262 }
263
264 @Override
265 protected String getPortletId(SearchContext searchContext) {
266 return PORTLET_ID;
267 }
268
269 protected void reindexNodes(long companyId) throws Exception {
270 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
271 WikiNode.class, PACLClassLoaderUtil.getPortalClassLoader());
272
273 Projection minNodeIdProjection = ProjectionFactoryUtil.min("nodeId");
274 Projection maxNodeIdProjection = ProjectionFactoryUtil.max("nodeId");
275
276 ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
277
278 projectionList.add(minNodeIdProjection);
279 projectionList.add(maxNodeIdProjection);
280
281 dynamicQuery.setProjection(projectionList);
282
283 addReindexCriteria(dynamicQuery, companyId);
284
285 List<Object[]> results = WikiNodeLocalServiceUtil.dynamicQuery(
286 dynamicQuery);
287
288 Object[] minAndMaxNodeIds = results.get(0);
289
290 if ((minAndMaxNodeIds[0] == null) || (minAndMaxNodeIds[1] == null)) {
291 return;
292 }
293
294 long minNodeId = (Long)minAndMaxNodeIds[0];
295 long maxNodeId = (Long)minAndMaxNodeIds[1];
296
297 long startNodeId = minNodeId;
298 long endNodeId = startNodeId + DEFAULT_INTERVAL;
299
300 while (startNodeId <= maxNodeId) {
301 reindexNodes(companyId, startNodeId, endNodeId);
302
303 startNodeId = endNodeId;
304 endNodeId += DEFAULT_INTERVAL;
305 }
306 }
307
308 protected void reindexNodes(
309 long companyId, long startNodeId, long endNodeId)
310 throws Exception {
311
312 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
313 WikiNode.class, PACLClassLoaderUtil.getPortalClassLoader());
314
315 Property property = PropertyFactoryUtil.forName("nodeId");
316
317 dynamicQuery.add(property.ge(startNodeId));
318 dynamicQuery.add(property.lt(endNodeId));
319
320 addReindexCriteria(dynamicQuery, companyId);
321
322 List<WikiNode> nodes = WikiNodeLocalServiceUtil.dynamicQuery(
323 dynamicQuery);
324
325 for (WikiNode node : nodes) {
326 long groupId = node.getGroupId();
327 long nodeId = node.getNodeId();
328
329 reindexPages(companyId, groupId, nodeId);
330 }
331 }
332
333 protected void reindexPages(long companyId, long groupId, long nodeId)
334 throws Exception {
335
336 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
337 WikiPage.class, PACLClassLoaderUtil.getPortalClassLoader());
338
339 Projection minPageIdProjection = ProjectionFactoryUtil.min("pageId");
340 Projection maxPageIdProjection = ProjectionFactoryUtil.max("pageId");
341
342 ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
343
344 projectionList.add(minPageIdProjection);
345 projectionList.add(maxPageIdProjection);
346
347 dynamicQuery.setProjection(projectionList);
348
349 addReindexCriteria(dynamicQuery, groupId, nodeId);
350
351 List<Object[]> results = WikiPageLocalServiceUtil.dynamicQuery(
352 dynamicQuery);
353
354 Object[] minAndMaxPageIds = results.get(0);
355
356 if ((minAndMaxPageIds[0] == null) || (minAndMaxPageIds[1] == null)) {
357 return;
358 }
359
360 long minPageId = (Long)minAndMaxPageIds[0];
361 long maxPageId = (Long)minAndMaxPageIds[1];
362
363 long startPageId = minPageId;
364 long endPageId = startPageId + DEFAULT_INTERVAL;
365
366 while (startPageId <= maxPageId) {
367 reindexPages(companyId, groupId, nodeId, startPageId, endPageId);
368
369 startPageId = endPageId;
370 endPageId += DEFAULT_INTERVAL;
371 }
372 }
373
374 protected void reindexPages(
375 long companyId, long groupId, long nodeId, long startPageId,
376 long endPageId)
377 throws Exception {
378
379 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
380 WikiPage.class, PACLClassLoaderUtil.getPortalClassLoader());
381
382 Property property = PropertyFactoryUtil.forName("pageId");
383
384 dynamicQuery.add(property.ge(startPageId));
385 dynamicQuery.add(property.lt(endPageId));
386
387 addReindexCriteria(dynamicQuery, groupId, nodeId);
388
389 List<WikiPage> pages = WikiPageLocalServiceUtil.dynamicQuery(
390 dynamicQuery);
391
392 if (pages.isEmpty()) {
393 return;
394 }
395
396 Collection<Document> documents = new ArrayList<Document>(pages.size());
397
398 for (WikiPage page : pages) {
399 Document document = getDocument(page);
400
401 documents.add(document);
402 }
403
404 SearchEngineUtil.updateDocuments(
405 getSearchEngineId(), companyId, documents);
406 }
407
408 private static final boolean _PERMISSION_AWARE = true;
409
410 }