1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.wiki.util;
16  
17  import com.liferay.portal.kernel.dao.orm.QueryUtil;
18  import com.liferay.portal.kernel.search.BaseIndexer;
19  import com.liferay.portal.kernel.search.BooleanQuery;
20  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
21  import com.liferay.portal.kernel.search.Document;
22  import com.liferay.portal.kernel.search.DocumentImpl;
23  import com.liferay.portal.kernel.search.Field;
24  import com.liferay.portal.kernel.search.Hits;
25  import com.liferay.portal.kernel.search.Indexer;
26  import com.liferay.portal.kernel.search.SearchContext;
27  import com.liferay.portal.kernel.search.SearchEngineUtil;
28  import com.liferay.portal.kernel.search.Summary;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.HtmlUtil;
31  import com.liferay.portal.kernel.util.StringUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.util.PortletKeys;
34  import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
35  import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
36  import com.liferay.portlet.expando.model.ExpandoBridge;
37  import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
38  import com.liferay.portlet.wiki.model.WikiNode;
39  import com.liferay.portlet.wiki.model.WikiPage;
40  import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
41  import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
42  import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
43  
44  import java.util.ArrayList;
45  import java.util.Collection;
46  import java.util.Date;
47  import java.util.List;
48  
49  import javax.portlet.PortletURL;
50  
51  /**
52   * <a href="WikiIndexer.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Brian Wing Shun Chan
55   * @author Harry Mark
56   * @author Bruno Farache
57   * @author Raymond Augé
58   */
59  public class WikiIndexer extends BaseIndexer {
60  
61      public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
62  
63      public static final String PORTLET_ID = PortletKeys.WIKI;
64  
65      public String[] getClassNames() {
66          return CLASS_NAMES;
67      }
68  
69      protected String getPortletId(SearchContext searchContext) {
70          return PORTLET_ID;
71      }
72  
73      public Summary getSummary(
74          Document document, String snippet, PortletURL portletURL) {
75  
76          String title = document.get(Field.TITLE);
77  
78          String content = snippet;
79  
80          if (Validator.isNull(snippet)) {
81              content = StringUtil.shorten(document.get(Field.CONTENT), 200);
82          }
83  
84          String nodeId = document.get("nodeId");
85  
86          portletURL.setParameter("struts_action", "/wiki/view");
87          portletURL.setParameter("nodeId", nodeId);
88          portletURL.setParameter("title", title);
89  
90          return new Summary(title, content, portletURL);
91      }
92  
93      protected void doDelete(Object obj) throws Exception {
94          if (obj instanceof Object[]) {
95              Object[] array = (Object[])obj;
96  
97              long companyId = (Long)array[0];
98              long nodeId = (Long)array[1];
99              String title = (String)array[2];
100 
101             Document document = new DocumentImpl();
102 
103             document.addUID(PORTLET_ID, nodeId, title);
104 
105             SearchEngineUtil.deleteDocument(companyId, document.get(Field.UID));
106 
107         }
108         else if (obj instanceof WikiNode) {
109             WikiNode node = (WikiNode)obj;
110 
111             BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
112 
113             booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
114 
115             booleanQuery.addRequiredTerm("nodeId", node.getNodeId());
116 
117             Hits hits = SearchEngineUtil.search(
118                 node.getCompanyId(), booleanQuery, QueryUtil.ALL_POS,
119                 QueryUtil.ALL_POS);
120 
121             for (int i = 0; i < hits.getLength(); i++) {
122                 Document document = hits.doc(i);
123 
124                 SearchEngineUtil.deleteDocument(
125                     node.getCompanyId(), document.get(Field.UID));
126             }
127         }
128         else if (obj instanceof WikiPage) {
129             WikiPage page = (WikiPage)obj;
130 
131             Document document = new DocumentImpl();
132 
133             document.addUID(PORTLET_ID, page.getNodeId(), page.getTitle());
134 
135             SearchEngineUtil.deleteDocument(
136                 page.getCompanyId(), document.get(Field.UID));
137         }
138     }
139 
140     protected void doReindex(Object obj) throws Exception {
141         WikiPage page = (WikiPage)obj;
142 
143         if (Validator.isNotNull(page.getRedirectTitle())) {
144             return;
145         }
146 
147         Document document = getDocument(page);
148 
149         SearchEngineUtil.updateDocument(page.getCompanyId(), document);
150     }
151 
152     protected void doReindex(String className, long classPK) throws Exception {
153         WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
154 
155         doReindex(page);
156     }
157 
158     protected void doReindex(String[] ids) throws Exception {
159         long companyId = GetterUtil.getLong(ids[0]);
160 
161         reindexNodes(companyId);
162     }
163 
164     protected Document doGetDocument(Object obj) throws Exception {
165         WikiPage page = (WikiPage)obj;
166 
167         long companyId = page.getCompanyId();
168         long groupId = getParentGroupId(page.getGroupId());
169         long scopeGroupId = page.getGroupId();
170         long userId = page.getUserId();
171         long resourcePrimKey = page.getResourcePrimKey();
172         long nodeId = page.getNodeId();
173         String title = page.getTitle();
174         String content = HtmlUtil.extractText(page.getContent());
175         Date modifiedDate = page.getModifiedDate();
176 
177         long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
178             WikiPage.class.getName(), resourcePrimKey);
179         String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
180             WikiPage.class.getName(), resourcePrimKey);
181 
182         ExpandoBridge expandoBridge = page.getExpandoBridge();
183 
184         Document document = new DocumentImpl();
185 
186         document.addUID(PORTLET_ID, nodeId, title);
187 
188         document.addModifiedDate(modifiedDate);
189 
190         document.addKeyword(Field.COMPANY_ID, companyId);
191         document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
192         document.addKeyword(Field.GROUP_ID, groupId);
193         document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
194         document.addKeyword(Field.USER_ID, userId);
195 
196         document.addText(Field.TITLE, title);
197         document.addText(Field.CONTENT, content);
198         document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
199         document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
200 
201         document.addKeyword(Field.NODE_ID, nodeId);
202         document.addKeyword(Field.ENTRY_CLASS_NAME, WikiPage.class.getName());
203         document.addKeyword(Field.ENTRY_CLASS_PK, resourcePrimKey);
204 
205         ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
206 
207         return document;
208     }
209 
210     protected void checkSearchNodeId(
211             long nodeId, SearchContext searchContext)
212         throws Exception {
213 
214         WikiNodeServiceUtil.getNode(nodeId);
215     }
216 
217     protected void reindexNodes(long companyId) throws Exception {
218         int nodeCount = WikiNodeLocalServiceUtil.getCompanyNodesCount(
219             companyId);
220 
221         int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
222 
223         for (int i = 0; i <= nodePages; i++) {
224             int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
225             int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
226 
227             reindexNodes(companyId, nodeStart, nodeEnd);
228         }
229     }
230 
231     protected void reindexNodes(long companyId, int nodeStart, int nodeEnd)
232         throws Exception {
233 
234         List<WikiNode> nodes = WikiNodeLocalServiceUtil.getCompanyNodes(
235             companyId, nodeStart, nodeEnd);
236 
237         for (WikiNode node : nodes) {
238             long nodeId = node.getNodeId();
239 
240             int pageCount = WikiPageLocalServiceUtil.getPagesCount(
241                 nodeId, true);
242 
243             int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
244 
245             for (int i = 0; i <= pagePages; i++) {
246                 int pageStart = (i * Indexer.DEFAULT_INTERVAL);
247                 int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
248 
249                 reindexPages(companyId, nodeId, pageStart, pageEnd);
250             }
251         }
252     }
253 
254     protected void reindexPages(
255             long companyId, long nodeId, int pageStart, int pageEnd)
256         throws Exception {
257 
258         List<WikiPage> pages = WikiPageLocalServiceUtil.getPages(
259             nodeId, true, pageStart, pageEnd);
260 
261         if (pages.isEmpty()) {
262             return;
263         }
264 
265         Collection<Document> documents = new ArrayList<Document>();
266 
267         for (WikiPage page : pages) {
268             Document document = getDocument(page);
269 
270             documents.add(document);
271         }
272 
273         SearchEngineUtil.updateDocuments(companyId, documents);
274     }
275 
276 }