001
014
015 package com.liferay.portlet.wiki.util;
016
017 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.Property;
020 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.repository.model.FileEntry;
026 import com.liferay.portal.kernel.search.BaseIndexer;
027 import com.liferay.portal.kernel.search.BooleanClauseOccur;
028 import com.liferay.portal.kernel.search.BooleanQuery;
029 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
030 import com.liferay.portal.kernel.search.Document;
031 import com.liferay.portal.kernel.search.DocumentImpl;
032 import com.liferay.portal.kernel.search.Field;
033 import com.liferay.portal.kernel.search.Indexer;
034 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
035 import com.liferay.portal.kernel.search.SearchContext;
036 import com.liferay.portal.kernel.search.SearchEngineUtil;
037 import com.liferay.portal.kernel.search.Summary;
038 import com.liferay.portal.kernel.util.ArrayUtil;
039 import com.liferay.portal.kernel.util.GetterUtil;
040 import com.liferay.portal.kernel.util.HtmlUtil;
041 import com.liferay.portal.kernel.util.Validator;
042 import com.liferay.portal.security.permission.ActionKeys;
043 import com.liferay.portal.security.permission.PermissionChecker;
044 import com.liferay.portal.util.PortalUtil;
045 import com.liferay.portal.util.PortletKeys;
046 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
047 import com.liferay.portlet.messageboards.model.MBMessage;
048 import com.liferay.portlet.trash.util.TrashUtil;
049 import com.liferay.portlet.wiki.model.WikiNode;
050 import com.liferay.portlet.wiki.model.WikiPage;
051 import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
052 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
053 import com.liferay.portlet.wiki.service.permission.WikiPagePermission;
054 import com.liferay.portlet.wiki.service.persistence.WikiNodeActionableDynamicQuery;
055 import com.liferay.portlet.wiki.service.persistence.WikiPageActionableDynamicQuery;
056
057 import java.util.Locale;
058
059 import javax.portlet.PortletURL;
060
061
067 public class WikiPageIndexer extends BaseIndexer {
068
069 public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
070
071 public static final String PORTLET_ID = PortletKeys.WIKI;
072
073 public WikiPageIndexer() {
074 setFilterSearch(true);
075 setPermissionAware(true);
076 }
077
078 @Override
079 public void addRelatedEntryFields(Document document, Object obj)
080 throws Exception {
081
082 WikiPage page = null;
083
084 try {
085 if (obj instanceof DLFileEntry) {
086 DLFileEntry dlFileEntry = (DLFileEntry)obj;
087
088 page = WikiPageAttachmentsUtil.getPage(
089 dlFileEntry.getFileEntryId());
090
091 document.addKeyword(
092 Field.CLASS_NAME_ID,
093 PortalUtil.getClassNameId(WikiPage.class.getName()));
094 document.addKeyword(Field.CLASS_PK, page.getResourcePrimKey());
095 }
096 else if (obj instanceof MBMessage) {
097 MBMessage message = (MBMessage)obj;
098
099 page = WikiPageLocalServiceUtil.getPage(message.getClassPK());
100 }
101 }
102 catch (Exception e) {
103 return;
104 }
105
106 document.addKeyword(Field.NODE_ID, page.getNodeId());
107 document.addKeyword(Field.RELATED_ENTRY, true);
108 }
109
110 @Override
111 public String[] getClassNames() {
112 return CLASS_NAMES;
113 }
114
115 @Override
116 public String getPortletId() {
117 return PORTLET_ID;
118 }
119
120 @Override
121 public boolean hasPermission(
122 PermissionChecker permissionChecker, String entryClassName,
123 long entryClassPK, String actionId)
124 throws Exception {
125
126 WikiPage page = WikiPageLocalServiceUtil.getPage(entryClassPK);
127
128 return WikiPagePermission.contains(
129 permissionChecker, page, ActionKeys.VIEW);
130 }
131
132 @Override
133 public boolean isVisible(long classPK, int status) throws Exception {
134 WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
135
136 return isVisible(page.getStatus(), status);
137 }
138
139 @Override
140 public void postProcessContextQuery(
141 BooleanQuery contextQuery, SearchContext searchContext)
142 throws Exception {
143
144 addStatus(contextQuery, searchContext);
145
146 long[] nodeIds = searchContext.getNodeIds();
147
148 if (ArrayUtil.isNotEmpty(nodeIds)) {
149 BooleanQuery nodeIdsQuery = BooleanQueryFactoryUtil.create(
150 searchContext);
151
152 for (long nodeId : nodeIds) {
153 try {
154 WikiNodeServiceUtil.getNode(nodeId);
155 }
156 catch (Exception e) {
157 if (_log.isDebugEnabled()) {
158 _log.debug("Unable to get wiki node " + nodeId, e);
159 }
160
161 continue;
162 }
163
164 nodeIdsQuery.addTerm(Field.NODE_ID, nodeId);
165 }
166
167 contextQuery.add(nodeIdsQuery, BooleanClauseOccur.MUST);
168 }
169 }
170
171 @Override
172 protected void doDelete(Object obj) throws Exception {
173 SearchContext searchContext = new SearchContext();
174
175 searchContext.setSearchEngineId(getSearchEngineId());
176
177 if (obj instanceof Object[]) {
178 Object[] array = (Object[])obj;
179
180 long companyId = (Long)array[0];
181 long nodeId = (Long)array[1];
182 String title = (String)array[2];
183
184 Document document = new DocumentImpl();
185
186 document.addUID(PORTLET_ID, nodeId, title);
187
188 SearchEngineUtil.deleteDocument(
189 getSearchEngineId(), companyId, document.get(Field.UID));
190 }
191 else if (obj instanceof WikiPage) {
192 WikiPage page = (WikiPage)obj;
193
194 deleteDocument(page.getCompanyId(), page.getResourcePrimKey());
195 }
196 }
197
198 @Override
199 protected Document doGetDocument(Object obj) throws Exception {
200 WikiPage page = (WikiPage)obj;
201
202 Document document = getBaseModelDocument(PORTLET_ID, page);
203
204 String content = HtmlUtil.extractText(
205 WikiUtil.convert(page, null, null, null));
206
207 document.addText(Field.CONTENT, content);
208
209 document.addKeyword(Field.NODE_ID, page.getNodeId());
210
211 String title = page.getTitle();
212
213 if (page.isInTrash()) {
214 title = TrashUtil.getOriginalTitle(title);
215 }
216
217 document.addText(Field.TITLE, title);
218
219 return document;
220 }
221
222 @Override
223 protected Summary doGetSummary(
224 Document document, Locale locale, String snippet,
225 PortletURL portletURL) {
226
227 Summary summary = createSummary(document, Field.TITLE, Field.CONTENT);
228
229 summary.setMaxContentLength(200);
230
231 String nodeId = document.get("nodeId");
232
233 portletURL.setParameter("struts_action", "/wiki/view");
234 portletURL.setParameter("nodeId", nodeId);
235 portletURL.setParameter("title", summary.getTitle());
236
237 summary.setPortletURL(portletURL);
238
239 return summary;
240 }
241
242 @Override
243 protected void doReindex(Object obj) throws Exception {
244 WikiPage page = (WikiPage)obj;
245
246 if (!page.isHead() || (!page.isApproved() && !page.isInTrash())) {
247 return;
248 }
249
250 if (Validator.isNotNull(page.getRedirectTitle())) {
251 return;
252 }
253
254 Document document = getDocument(page);
255
256 SearchEngineUtil.updateDocument(
257 getSearchEngineId(), page.getCompanyId(), document);
258
259 reindexAttachments(page);
260 }
261
262 @Override
263 protected void doReindex(String className, long classPK) throws Exception {
264 WikiPage page = WikiPageLocalServiceUtil.fetchWikiPage(classPK);
265
266 if (page == null) {
267 page = WikiPageLocalServiceUtil.getPage(classPK, (Boolean)null);
268 }
269
270 doReindex(page);
271 }
272
273 @Override
274 protected void doReindex(String[] ids) throws Exception {
275 long companyId = GetterUtil.getLong(ids[0]);
276
277 reindexNodes(companyId);
278 }
279
280 @Override
281 protected String getPortletId(SearchContext searchContext) {
282 return PORTLET_ID;
283 }
284
285 protected void reindexAttachments(WikiPage page)
286 throws PortalException, SystemException {
287
288 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
289 DLFileEntry.class);
290
291 for (FileEntry attachmentsFileEntry :
292 page.getAttachmentsFileEntries()) {
293
294 indexer.reindex((DLFileEntry)attachmentsFileEntry.getModel());
295 }
296 }
297
298 protected void reindexNodes(final long companyId)
299 throws PortalException, SystemException {
300
301 ActionableDynamicQuery actionableDynamicQuery =
302 new WikiNodeActionableDynamicQuery() {
303
304 @Override
305 protected void performAction(Object object)
306 throws PortalException, SystemException {
307
308 WikiNode node = (WikiNode)object;
309
310 reindexPages(companyId, node.getGroupId(), node.getNodeId());
311 }
312
313 };
314
315 actionableDynamicQuery.setCompanyId(companyId);
316
317 actionableDynamicQuery.performActions();
318 }
319
320 protected void reindexPages(long companyId, long groupId, final long nodeId)
321 throws PortalException, SystemException {
322
323 ActionableDynamicQuery actionableDynamicQuery =
324 new WikiPageActionableDynamicQuery() {
325
326 @Override
327 protected void addCriteria(DynamicQuery dynamicQuery) {
328 Property nodeIdProperty = PropertyFactoryUtil.forName("nodeId");
329
330 dynamicQuery.add(nodeIdProperty.eq(nodeId));
331
332 Property headProperty = PropertyFactoryUtil.forName("head");
333
334 dynamicQuery.add(headProperty.eq(true));
335 }
336
337 @Override
338 protected void performAction(Object object) {
339 WikiPage page = (WikiPage)object;
340
341 try {
342 Document document = getDocument(page);
343
344 addDocument(document);
345 }
346 catch (PortalException pe) {
347 if (_log.isWarnEnabled()) {
348 _log.warn(
349 "Unable to index wiki page " + page.getPageId(),
350 pe);
351 }
352 }
353 }
354
355 };
356
357 actionableDynamicQuery.setCompanyId(companyId);
358 actionableDynamicQuery.setGroupId(groupId);
359 actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
360
361 actionableDynamicQuery.performActions();
362 }
363
364 private static Log _log = LogFactoryUtil.getLog(WikiPageIndexer.class);
365
366 }