001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
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.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.SearchContext;
033    import com.liferay.portal.kernel.search.SearchEngineUtil;
034    import com.liferay.portal.kernel.search.Summary;
035    import com.liferay.portal.kernel.util.ArrayUtil;
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.security.permission.ActionKeys;
040    import com.liferay.portal.security.permission.PermissionChecker;
041    import com.liferay.portal.util.PortalUtil;
042    import com.liferay.portal.util.PortletKeys;
043    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
044    import com.liferay.portlet.messageboards.model.MBMessage;
045    import com.liferay.portlet.trash.util.TrashUtil;
046    import com.liferay.portlet.wiki.model.WikiNode;
047    import com.liferay.portlet.wiki.model.WikiPage;
048    import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
049    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
050    import com.liferay.portlet.wiki.service.permission.WikiPagePermission;
051    import com.liferay.portlet.wiki.service.persistence.WikiNodeActionableDynamicQuery;
052    import com.liferay.portlet.wiki.service.persistence.WikiPageActionableDynamicQuery;
053    
054    import java.util.Locale;
055    
056    import javax.portlet.PortletURL;
057    
058    /**
059     * @author Brian Wing Shun Chan
060     * @author Harry Mark
061     * @author Bruno Farache
062     * @author Raymond Aug??
063     */
064    public class WikiPageIndexer extends BaseIndexer {
065    
066            public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
067    
068            public static final String PORTLET_ID = PortletKeys.WIKI;
069    
070            public WikiPageIndexer() {
071                    setFilterSearch(true);
072                    setPermissionAware(true);
073            }
074    
075            @Override
076            public void addRelatedEntryFields(Document document, Object obj)
077                    throws Exception {
078    
079                    WikiPage page = null;
080    
081                    try {
082                            if (obj instanceof DLFileEntry) {
083                                    DLFileEntry dlFileEntry = (DLFileEntry)obj;
084    
085                                    page = WikiPageAttachmentsUtil.getPage(
086                                            dlFileEntry.getFileEntryId());
087    
088                                    document.addKeyword(
089                                            Field.CLASS_NAME_ID,
090                                            PortalUtil.getClassNameId(WikiPage.class.getName()));
091                                    document.addKeyword(Field.CLASS_PK, page.getResourcePrimKey());
092                            }
093                            else if (obj instanceof MBMessage) {
094                                    MBMessage message = (MBMessage)obj;
095    
096                                    page = WikiPageLocalServiceUtil.getPage(message.getClassPK());
097                            }
098                    }
099                    catch (Exception e) {
100                            return;
101                    }
102    
103                    document.addKeyword(Field.NODE_ID, page.getNodeId());
104                    document.addKeyword(Field.RELATED_ENTRY, true);
105            }
106    
107            @Override
108            public String[] getClassNames() {
109                    return CLASS_NAMES;
110            }
111    
112            @Override
113            public String getPortletId() {
114                    return PORTLET_ID;
115            }
116    
117            @Override
118            public boolean hasPermission(
119                            PermissionChecker permissionChecker, String entryClassName,
120                            long entryClassPK, String actionId)
121                    throws Exception {
122    
123                    WikiPage page = WikiPageLocalServiceUtil.getPage(entryClassPK);
124    
125                    return WikiPagePermission.contains(
126                            permissionChecker, page, ActionKeys.VIEW);
127            }
128    
129            @Override
130            public boolean isVisible(long classPK, int status) throws Exception {
131                    WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
132    
133                    return isVisible(page.getStatus(), status);
134            }
135    
136            @Override
137            public void postProcessContextQuery(
138                            BooleanQuery contextQuery, SearchContext searchContext)
139                    throws Exception {
140    
141                    addStatus(contextQuery, searchContext);
142    
143                    long[] nodeIds = searchContext.getNodeIds();
144    
145                    if (ArrayUtil.isNotEmpty(nodeIds)) {
146                            BooleanQuery nodeIdsQuery = BooleanQueryFactoryUtil.create(
147                                    searchContext);
148    
149                            for (long nodeId : nodeIds) {
150                                    try {
151                                            WikiNodeServiceUtil.getNode(nodeId);
152                                    }
153                                    catch (Exception e) {
154                                            if (_log.isDebugEnabled()) {
155                                                    _log.debug("Unable to get wiki node " + nodeId, e);
156                                            }
157    
158                                            continue;
159                                    }
160    
161                                    nodeIdsQuery.addTerm(Field.NODE_ID, nodeId);
162                            }
163    
164                            contextQuery.add(nodeIdsQuery, BooleanClauseOccur.MUST);
165                    }
166            }
167    
168            @Override
169            protected void doDelete(Object obj) throws Exception {
170                    SearchContext searchContext = new SearchContext();
171    
172                    searchContext.setSearchEngineId(getSearchEngineId());
173    
174                    if (obj instanceof Object[]) {
175                            Object[] array = (Object[])obj;
176    
177                            long companyId = (Long)array[0];
178                            long nodeId = (Long)array[1];
179                            String title = (String)array[2];
180    
181                            Document document = new DocumentImpl();
182    
183                            document.addUID(PORTLET_ID, nodeId, title);
184    
185                            SearchEngineUtil.deleteDocument(
186                                    getSearchEngineId(), companyId, document.get(Field.UID));
187                    }
188                    else if (obj instanceof WikiPage) {
189                            WikiPage page = (WikiPage)obj;
190    
191                            deleteDocument(page.getCompanyId(), page.getResourcePrimKey());
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                    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    
208                    String title = page.getTitle();
209    
210                    if (page.isInTrash()) {
211                            title = TrashUtil.getOriginalTitle(title);
212                    }
213    
214                    document.addText(Field.TITLE, title);
215    
216                    return document;
217            }
218    
219            @Override
220            protected Summary doGetSummary(
221                    Document document, Locale locale, String snippet,
222                    PortletURL portletURL) {
223    
224                    Summary summary = createSummary(document, Field.TITLE, Field.CONTENT);
225    
226                    summary.setMaxContentLength(200);
227    
228                    String nodeId = document.get("nodeId");
229    
230                    portletURL.setParameter("struts_action", "/wiki/view");
231                    portletURL.setParameter("nodeId", nodeId);
232                    portletURL.setParameter("title", summary.getTitle());
233    
234                    summary.setPortletURL(portletURL);
235    
236                    return summary;
237            }
238    
239            @Override
240            protected void doReindex(Object obj) throws Exception {
241                    WikiPage page = (WikiPage)obj;
242    
243                    if (!page.isHead() || (!page.isApproved() && !page.isInTrash())) {
244                            return;
245                    }
246    
247                    if (Validator.isNotNull(page.getRedirectTitle())) {
248                            return;
249                    }
250    
251                    Document document = getDocument(page);
252    
253                    SearchEngineUtil.updateDocument(
254                            getSearchEngineId(), page.getCompanyId(), document);
255            }
256    
257            @Override
258            protected void doReindex(String className, long classPK) throws Exception {
259                    WikiPage page = WikiPageLocalServiceUtil.fetchWikiPage(classPK);
260    
261                    if (page == null) {
262                            page = WikiPageLocalServiceUtil.getPage(classPK, (Boolean)null);
263                    }
264    
265                    doReindex(page);
266            }
267    
268            @Override
269            protected void doReindex(String[] ids) throws Exception {
270                    long companyId = GetterUtil.getLong(ids[0]);
271    
272                    reindexNodes(companyId);
273            }
274    
275            @Override
276            protected String getPortletId(SearchContext searchContext) {
277                    return PORTLET_ID;
278            }
279    
280            protected void reindexNodes(final long companyId)
281                    throws PortalException, SystemException {
282    
283                    ActionableDynamicQuery actionableDynamicQuery =
284                            new WikiNodeActionableDynamicQuery() {
285    
286                            @Override
287                            protected void performAction(Object object)
288                                    throws PortalException, SystemException {
289    
290                                    WikiNode node = (WikiNode)object;
291    
292                                    reindexPages(companyId, node.getGroupId(), node.getNodeId());
293                            }
294    
295                    };
296    
297                    actionableDynamicQuery.setCompanyId(companyId);
298    
299                    actionableDynamicQuery.performActions();
300            }
301    
302            protected void reindexPages(long companyId, long groupId, final long nodeId)
303                    throws PortalException, SystemException {
304    
305                    ActionableDynamicQuery actionableDynamicQuery =
306                            new WikiPageActionableDynamicQuery() {
307    
308                            @Override
309                            protected void addCriteria(DynamicQuery dynamicQuery) {
310                                    Property nodeIdProperty = PropertyFactoryUtil.forName("nodeId");
311    
312                                    dynamicQuery.add(nodeIdProperty.eq(nodeId));
313    
314                                    Property headProperty = PropertyFactoryUtil.forName("head");
315    
316                                    dynamicQuery.add(headProperty.eq(true));
317                            }
318    
319                            @Override
320                            protected void performAction(Object object) {
321                                    WikiPage page = (WikiPage)object;
322    
323                                    try {
324                                            Document document = getDocument(page);
325    
326                                            addDocument(document);
327                                    }
328                                    catch (PortalException pe) {
329                                            if (_log.isWarnEnabled()) {
330                                                    _log.warn(
331                                                            "Unable to index wiki page " + page.getPageId(),
332                                                            pe);
333                                            }
334                                    }
335                            }
336    
337                    };
338    
339                    actionableDynamicQuery.setCompanyId(companyId);
340                    actionableDynamicQuery.setGroupId(groupId);
341                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
342    
343                    actionableDynamicQuery.performActions();
344            }
345    
346            private static Log _log = LogFactoryUtil.getLog(WikiPageIndexer.class);
347    
348    }