001    /**
002     * Copyright (c) 2000-2010 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.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[] assetCategoryNames =
178                            AssetCategoryLocalServiceUtil.getCategoryNames(
179                                    WikiPage.class.getName(), resourcePrimKey);
180                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
181                            WikiPage.class.getName(), resourcePrimKey);
182    
183                    ExpandoBridge expandoBridge = page.getExpandoBridge();
184    
185                    Document document = new DocumentImpl();
186    
187                    document.addUID(PORTLET_ID, nodeId, title);
188    
189                    document.addModifiedDate(modifiedDate);
190    
191                    document.addKeyword(Field.COMPANY_ID, companyId);
192                    document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
193                    document.addKeyword(Field.GROUP_ID, groupId);
194                    document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
195                    document.addKeyword(Field.USER_ID, userId);
196    
197                    document.addText(Field.TITLE, title);
198                    document.addText(Field.CONTENT, content);
199                    document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
200                    document.addKeyword(Field.ASSET_CATEGORY_NAMES, assetCategoryNames);
201                    document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
202    
203                    document.addKeyword(Field.NODE_ID, nodeId);
204                    document.addKeyword(Field.ENTRY_CLASS_NAME, WikiPage.class.getName());
205                    document.addKeyword(Field.ENTRY_CLASS_PK, resourcePrimKey);
206    
207                    ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
208    
209                    return document;
210            }
211    
212            protected void checkSearchNodeId(
213                            long nodeId, SearchContext searchContext)
214                    throws Exception {
215    
216                    WikiNodeServiceUtil.getNode(nodeId);
217            }
218    
219            protected void reindexNodes(long companyId) throws Exception {
220                    int nodeCount = WikiNodeLocalServiceUtil.getCompanyNodesCount(
221                            companyId);
222    
223                    int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
224    
225                    for (int i = 0; i <= nodePages; i++) {
226                            int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
227                            int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
228    
229                            reindexNodes(companyId, nodeStart, nodeEnd);
230                    }
231            }
232    
233            protected void reindexNodes(long companyId, int nodeStart, int nodeEnd)
234                    throws Exception {
235    
236                    List<WikiNode> nodes = WikiNodeLocalServiceUtil.getCompanyNodes(
237                            companyId, nodeStart, nodeEnd);
238    
239                    for (WikiNode node : nodes) {
240                            long nodeId = node.getNodeId();
241    
242                            int pageCount = WikiPageLocalServiceUtil.getPagesCount(
243                                    nodeId, true);
244    
245                            int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
246    
247                            for (int i = 0; i <= pagePages; i++) {
248                                    int pageStart = (i * Indexer.DEFAULT_INTERVAL);
249                                    int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
250    
251                                    reindexPages(companyId, nodeId, pageStart, pageEnd);
252                            }
253                    }
254            }
255    
256            protected void reindexPages(
257                            long companyId, long nodeId, int pageStart, int pageEnd)
258                    throws Exception {
259    
260                    List<WikiPage> pages = WikiPageLocalServiceUtil.getPages(
261                            nodeId, true, pageStart, pageEnd);
262    
263                    if (pages.isEmpty()) {
264                            return;
265                    }
266    
267                    Collection<Document> documents = new ArrayList<Document>();
268    
269                    for (WikiPage page : pages) {
270                            Document document = getDocument(page);
271    
272                            documents.add(document);
273                    }
274    
275                    SearchEngineUtil.updateDocuments(companyId, documents);
276            }
277    
278    }