001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.wiki.util;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.search.BaseIndexer;
019    import com.liferay.portal.kernel.search.BooleanQuery;
020    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
021    import com.liferay.portal.kernel.search.Document;
022    import com.liferay.portal.kernel.search.DocumentImpl;
023    import com.liferay.portal.kernel.search.Field;
024    import com.liferay.portal.kernel.search.Hits;
025    import com.liferay.portal.kernel.search.Indexer;
026    import com.liferay.portal.kernel.search.SearchContext;
027    import com.liferay.portal.kernel.search.SearchEngineUtil;
028    import com.liferay.portal.kernel.search.Summary;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.HtmlUtil;
031    import com.liferay.portal.kernel.util.StringUtil;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.util.PortletKeys;
034    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
035    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
036    import com.liferay.portlet.expando.model.ExpandoBridge;
037    import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
038    import com.liferay.portlet.wiki.model.WikiNode;
039    import com.liferay.portlet.wiki.model.WikiPage;
040    import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
041    import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
042    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
043    
044    import java.util.ArrayList;
045    import java.util.Collection;
046    import java.util.Date;
047    import java.util.List;
048    
049    import javax.portlet.PortletURL;
050    
051    /**
052     * @author Brian Wing Shun Chan
053     * @author Harry Mark
054     * @author Bruno Farache
055     * @author Raymond Augé
056     */
057    public class WikiIndexer extends BaseIndexer {
058    
059            public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
060    
061            public static final String PORTLET_ID = PortletKeys.WIKI;
062    
063            public String[] getClassNames() {
064                    return CLASS_NAMES;
065            }
066    
067            protected String getPortletId(SearchContext searchContext) {
068                    return PORTLET_ID;
069            }
070    
071            public Summary getSummary(
072                    Document document, String snippet, PortletURL portletURL) {
073    
074                    String title = document.get(Field.TITLE);
075    
076                    String content = snippet;
077    
078                    if (Validator.isNull(snippet)) {
079                            content = StringUtil.shorten(document.get(Field.CONTENT), 200);
080                    }
081    
082                    String nodeId = document.get("nodeId");
083    
084                    portletURL.setParameter("struts_action", "/wiki/view");
085                    portletURL.setParameter("nodeId", nodeId);
086                    portletURL.setParameter("title", title);
087    
088                    return new Summary(title, content, portletURL);
089            }
090    
091            protected void doDelete(Object obj) throws Exception {
092                    if (obj instanceof Object[]) {
093                            Object[] array = (Object[])obj;
094    
095                            long companyId = (Long)array[0];
096                            long nodeId = (Long)array[1];
097                            String title = (String)array[2];
098    
099                            Document document = new DocumentImpl();
100    
101                            document.addUID(PORTLET_ID, nodeId, title);
102    
103                            SearchEngineUtil.deleteDocument(companyId, document.get(Field.UID));
104    
105                    }
106                    else if (obj instanceof WikiNode) {
107                            WikiNode node = (WikiNode)obj;
108    
109                            BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
110    
111                            booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
112    
113                            booleanQuery.addRequiredTerm("nodeId", node.getNodeId());
114    
115                            Hits hits = SearchEngineUtil.search(
116                                    node.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
117                                    QueryUtil.ALL_POS);
118    
119                            for (int i = 0; i < hits.getLength(); i++) {
120                                    Document document = hits.doc(i);
121    
122                                    SearchEngineUtil.deleteDocument(
123                                            node.getCompanyId(), document.get(Field.UID));
124                            }
125                    }
126                    else if (obj instanceof WikiPage) {
127                            WikiPage page = (WikiPage)obj;
128    
129                            Document document = new DocumentImpl();
130    
131                            document.addUID(PORTLET_ID, page.getNodeId(), page.getTitle());
132    
133                            SearchEngineUtil.deleteDocument(
134                                    page.getCompanyId(), document.get(Field.UID));
135                    }
136            }
137    
138            protected void doReindex(Object obj) throws Exception {
139                    WikiPage page = (WikiPage)obj;
140    
141                    if (Validator.isNotNull(page.getRedirectTitle())) {
142                            return;
143                    }
144    
145                    Document document = getDocument(page);
146    
147                    SearchEngineUtil.updateDocument(page.getCompanyId(), document);
148            }
149    
150            protected void doReindex(String className, long classPK) throws Exception {
151                    WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
152    
153                    doReindex(page);
154            }
155    
156            protected void doReindex(String[] ids) throws Exception {
157                    long companyId = GetterUtil.getLong(ids[0]);
158    
159                    reindexNodes(companyId);
160            }
161    
162            protected Document doGetDocument(Object obj) throws Exception {
163                    WikiPage page = (WikiPage)obj;
164    
165                    long companyId = page.getCompanyId();
166                    long groupId = getParentGroupId(page.getGroupId());
167                    long scopeGroupId = page.getGroupId();
168                    long userId = page.getUserId();
169                    long resourcePrimKey = page.getResourcePrimKey();
170                    long nodeId = page.getNodeId();
171                    String title = page.getTitle();
172                    String content = HtmlUtil.extractText(page.getContent());
173                    Date modifiedDate = page.getModifiedDate();
174    
175                    long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
176                            WikiPage.class.getName(), resourcePrimKey);
177                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
178                            WikiPage.class.getName(), resourcePrimKey);
179    
180                    ExpandoBridge expandoBridge = page.getExpandoBridge();
181    
182                    Document document = new DocumentImpl();
183    
184                    document.addUID(PORTLET_ID, nodeId, title);
185    
186                    document.addModifiedDate(modifiedDate);
187    
188                    document.addKeyword(Field.COMPANY_ID, companyId);
189                    document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
190                    document.addKeyword(Field.GROUP_ID, groupId);
191                    document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
192                    document.addKeyword(Field.USER_ID, userId);
193    
194                    document.addText(Field.TITLE, title);
195                    document.addText(Field.CONTENT, content);
196                    document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
197                    document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
198    
199                    document.addKeyword(Field.NODE_ID, nodeId);
200                    document.addKeyword(Field.ENTRY_CLASS_NAME, WikiPage.class.getName());
201                    document.addKeyword(Field.ENTRY_CLASS_PK, resourcePrimKey);
202    
203                    ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
204    
205                    return document;
206            }
207    
208            protected void checkSearchNodeId(
209                            long nodeId, SearchContext searchContext)
210                    throws Exception {
211    
212                    WikiNodeServiceUtil.getNode(nodeId);
213            }
214    
215            protected void reindexNodes(long companyId) throws Exception {
216                    int nodeCount = WikiNodeLocalServiceUtil.getCompanyNodesCount(
217                            companyId);
218    
219                    int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
220    
221                    for (int i = 0; i <= nodePages; i++) {
222                            int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
223                            int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
224    
225                            reindexNodes(companyId, nodeStart, nodeEnd);
226                    }
227            }
228    
229            protected void reindexNodes(long companyId, int nodeStart, int nodeEnd)
230                    throws Exception {
231    
232                    List<WikiNode> nodes = WikiNodeLocalServiceUtil.getCompanyNodes(
233                            companyId, nodeStart, nodeEnd);
234    
235                    for (WikiNode node : nodes) {
236                            long nodeId = node.getNodeId();
237    
238                            int pageCount = WikiPageLocalServiceUtil.getPagesCount(
239                                    nodeId, true);
240    
241                            int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
242    
243                            for (int i = 0; i <= pagePages; i++) {
244                                    int pageStart = (i * Indexer.DEFAULT_INTERVAL);
245                                    int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
246    
247                                    reindexPages(companyId, nodeId, pageStart, pageEnd);
248                            }
249                    }
250            }
251    
252            protected void reindexPages(
253                            long companyId, long nodeId, int pageStart, int pageEnd)
254                    throws Exception {
255    
256                    List<WikiPage> pages = WikiPageLocalServiceUtil.getPages(
257                            nodeId, true, pageStart, pageEnd);
258    
259                    if (pages.isEmpty()) {
260                            return;
261                    }
262    
263                    Collection<Document> documents = new ArrayList<Document>();
264    
265                    for (WikiPage page : pages) {
266                            Document document = getDocument(page);
267    
268                            documents.add(document);
269                    }
270    
271                    SearchEngineUtil.updateDocuments(companyId, documents);
272            }
273    
274    }