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