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.BooleanQuery;
19  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
20  import com.liferay.portal.kernel.search.Document;
21  import com.liferay.portal.kernel.search.DocumentImpl;
22  import com.liferay.portal.kernel.search.Field;
23  import com.liferay.portal.kernel.search.Hits;
24  import com.liferay.portal.kernel.search.Indexer;
25  import com.liferay.portal.kernel.search.SearchContext;
26  import com.liferay.portal.kernel.search.SearchEngineUtil;
27  import com.liferay.portal.kernel.search.Summary;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.kernel.util.HtmlUtil;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.search.BaseIndexer;
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.Date;
45  import java.util.List;
46  
47  import javax.portlet.PortletURL;
48  
49  /**
50   * <a href="WikiIndexer.java.html"><b><i>View Source</i></b></a>
51   *
52   * @author Brian Wing Shun Chan
53   * @author Harry Mark
54   * @author Bruno Farache
55   * @author Raymond Augé
56   */
57  public class WikiIndexer extends BaseIndexer {
58  
59      public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
60  
61      public static final String PORTLET_ID = PortletKeys.WIKI;
62  
63      public String[] getClassNames() {
64          return CLASS_NAMES;
65      }
66  
67      protected String getPortletId(SearchContext searchContext) {
68          return PORTLET_ID;
69      }
70  
71      public Summary getSummary(
72          Document document, String snippet, PortletURL portletURL) {
73  
74          String title = document.get(Field.TITLE);
75  
76          String content = snippet;
77  
78          if (Validator.isNull(snippet)) {
79              content = StringUtil.shorten(document.get(Field.CONTENT), 200);
80          }
81  
82          String nodeId = document.get("nodeId");
83  
84          portletURL.setParameter("struts_action", "/wiki/view");
85          portletURL.setParameter("nodeId", nodeId);
86          portletURL.setParameter("title", title);
87  
88          return new Summary(title, content, portletURL);
89      }
90  
91      protected void doDelete(Object obj) throws Exception {
92          if (obj instanceof Object[]) {
93              Object[] array = (Object[])obj;
94  
95              long companyId = (Long)array[0];
96              String nodeId = (String)array[0];
97              String title = (String)array[0];
98  
99              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(
148             page.getCompanyId(), document.get(Field.UID), document);
149     }
150 
151     protected void doReindex(String className, long classPK) throws Exception {
152         WikiPage page = WikiPageLocalServiceUtil.getPage(classPK);
153 
154         doReindex(page);
155     }
156 
157     protected void doReindex(String[] ids) throws Exception {
158         long companyId = GetterUtil.getLong(ids[0]);
159 
160         reindexNodes(companyId);
161     }
162 
163     protected Document doGetDocument(Object obj) throws Exception {
164         WikiPage page = (WikiPage)obj;
165 
166         long companyId = page.getCompanyId();
167         long groupId = getParentGroupId(page.getGroupId());
168         long scopeGroupId = page.getGroupId();
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 
193         document.addText(Field.TITLE, title);
194         document.addText(Field.CONTENT, content);
195         document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
196         document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
197 
198         document.addKeyword(Field.NODE_ID, nodeId);
199         document.addKeyword(Field.ENTRY_CLASS_NAME, WikiPage.class.getName());
200         document.addKeyword(Field.ENTRY_CLASS_PK, resourcePrimKey);
201 
202         ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
203 
204         return document;
205     }
206 
207     protected void checkSearchNodeId(
208             long nodeId, SearchContext searchContext)
209         throws Exception {
210 
211         WikiNodeServiceUtil.getNode(nodeId);
212     }
213 
214     protected void reindexNodes(long companyId) throws Exception {
215         int nodeCount = WikiNodeLocalServiceUtil.getCompanyNodesCount(
216             companyId);
217 
218         int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
219 
220         for (int i = 0; i <= nodePages; i++) {
221             int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
222             int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
223 
224             reindexNodes(companyId, nodeStart, nodeEnd);
225         }
226     }
227 
228     protected void reindexNodes(long companyId, int nodeStart, int nodeEnd)
229         throws Exception {
230 
231         List<WikiNode> nodes = WikiNodeLocalServiceUtil.getCompanyNodes(
232             companyId, nodeStart, nodeEnd);
233 
234         for (WikiNode node : nodes) {
235             long nodeId = node.getNodeId();
236 
237             int pageCount = WikiPageLocalServiceUtil.getPagesCount(
238                 nodeId, true);
239 
240             int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
241 
242             for (int i = 0; i <= pagePages; i++) {
243                 int pageStart = (i * Indexer.DEFAULT_INTERVAL);
244                 int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
245 
246                 reindexPages(nodeId, pageStart, pageEnd);
247             }
248         }
249     }
250 
251     protected void reindexPages(long nodeId, int pageStart, int pageEnd)
252         throws Exception {
253 
254         List<WikiPage> pages = WikiPageLocalServiceUtil.getPages(
255             nodeId, true, pageStart, pageEnd);
256 
257         for (WikiPage page : pages) {
258             reindex(page);
259         }
260     }
261 
262 }