1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.journal.util;
24  
25  import com.liferay.portal.kernel.search.Document;
26  import com.liferay.portal.kernel.search.DocumentImpl;
27  import com.liferay.portal.kernel.search.DocumentSummary;
28  import com.liferay.portal.kernel.search.Field;
29  import com.liferay.portal.kernel.search.SearchEngineUtil;
30  import com.liferay.portal.kernel.search.SearchException;
31  import com.liferay.portal.kernel.util.HtmlUtil;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.StringUtil;
34  import com.liferay.portal.kernel.xml.Element;
35  import com.liferay.portal.kernel.xml.SAXReaderUtil;
36  import com.liferay.portal.util.PortletKeys;
37  import com.liferay.portlet.expando.model.ExpandoBridge;
38  import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
39  import com.liferay.portlet.journal.model.JournalArticle;
40  import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
41  
42  import java.util.Date;
43  
44  import javax.portlet.PortletURL;
45  
46  /**
47   * <a href="Indexer.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Brian Wing Shun Chan
50   * @author Harry Mark
51   * @author Bruno Farache
52   * @author Raymond Augé
53   *
54   */
55  public class Indexer implements com.liferay.portal.kernel.search.Indexer {
56  
57      public static final String PORTLET_ID = PortletKeys.JOURNAL;
58  
59      public static void addArticle(
60              long companyId, long groupId, String articleId, double version,
61              String title, String description, String content, String type,
62              Date displayDate, String[] tagsCategories, String[] tagsEntries,
63              ExpandoBridge expandoBridge)
64          throws SearchException {
65  
66          Document doc = getArticleDocument(
67              companyId, groupId, articleId, version, title, description, content,
68              type, displayDate, tagsCategories, tagsEntries, expandoBridge);
69  
70          SearchEngineUtil.addDocument(companyId, doc);
71      }
72  
73      public static void deleteArticle(long companyId, String articleId)
74          throws SearchException {
75  
76          SearchEngineUtil.deleteDocument(companyId, getArticleUID(articleId));
77      }
78  
79      public static Document getArticleDocument(
80          long companyId, long groupId, String articleId, double version,
81          String title, String description, String content, String type,
82          Date displayDate, String[] tagsCategories, String[] tagsEntries,
83          ExpandoBridge expandoBridge) {
84  
85          if ((content != null) &&
86              ((content.indexOf("<dynamic-content") != -1) ||
87               (content.indexOf("<static-content") != -1))) {
88  
89              content = _getIndexableContent(content);
90  
91              content = StringUtil.replace(
92                  content, "<![CDATA[", StringPool.BLANK);
93              content = StringUtil.replace(content, "]]>", StringPool.BLANK);
94          }
95  
96          content = StringUtil.replace(content, "&amp;", "&");
97          content = StringUtil.replace(content, "&lt;", "<");
98          content = StringUtil.replace(content, "&gt;", ">");
99  
100         content = HtmlUtil.extractText(content);
101 
102         Document doc = new DocumentImpl();
103 
104         doc.addUID(PORTLET_ID, articleId);
105 
106         doc.addModifiedDate(displayDate);
107 
108         doc.addKeyword(Field.COMPANY_ID, companyId);
109         doc.addKeyword(Field.PORTLET_ID, PORTLET_ID);
110         doc.addKeyword(Field.GROUP_ID, groupId);
111 
112         doc.addText(Field.TITLE, title);
113         doc.addText(Field.CONTENT, content);
114         doc.addText(Field.DESCRIPTION, description);
115         doc.addKeyword(Field.TAGS_CATEGORIES, tagsCategories);
116         doc.addKeyword(Field.TAGS_ENTRIES, tagsEntries);
117 
118         doc.addKeyword(Field.ENTRY_CLASS_NAME, JournalArticle.class.getName());
119         doc.addKeyword(Field.ENTRY_CLASS_PK, articleId);
120         doc.addKeyword(Field.VERSION, version);
121         doc.addKeyword(Field.TYPE, type);
122 
123         ExpandoBridgeIndexerUtil.addAttributes(doc, expandoBridge);
124 
125         return doc;
126     }
127 
128     public static String getArticleUID(String articleId) {
129         Document doc = new DocumentImpl();
130 
131         doc.addUID(PORTLET_ID, articleId);
132 
133         return doc.get(Field.UID);
134     }
135 
136     public static void updateArticle(
137             long companyId, long groupId, String articleId, double version,
138             String title, String description, String content, String type,
139             Date displayDate, String[] tagsCategories, String[] tagsEntries,
140             ExpandoBridge expandoBridge)
141         throws SearchException {
142 
143         Document doc = getArticleDocument(
144             companyId, groupId, articleId, version, title, description, content,
145             type, displayDate, tagsCategories, tagsEntries, expandoBridge);
146 
147         SearchEngineUtil.updateDocument(companyId, doc.get(Field.UID), doc);
148     }
149 
150     public String[] getClassNames() {
151         return _CLASS_NAMES;
152     }
153 
154     public DocumentSummary getDocumentSummary(
155         com.liferay.portal.kernel.search.Document doc, PortletURL portletURL) {
156 
157         // Title
158 
159         String title = doc.get(Field.TITLE);
160 
161         // Content
162 
163         String content = doc.get(Field.CONTENT);
164 
165         content = StringUtil.shorten(content, 200);
166 
167         // Portlet URL
168 
169         String groupId = doc.get("groupId");
170         String articleId = doc.get(Field.ENTRY_CLASS_PK);
171         String version = doc.get("version");
172 
173         portletURL.setParameter("struts_action", "/journal/edit_article");
174         portletURL.setParameter("groupId", groupId);
175         portletURL.setParameter("articleId", articleId);
176         portletURL.setParameter("version", version);
177 
178         return new DocumentSummary(title, content, portletURL);
179     }
180 
181     public void reIndex(String className, long classPK) throws SearchException {
182         try {
183             JournalArticleLocalServiceUtil.reIndex(classPK);
184         }
185         catch (Exception e) {
186             throw new SearchException(e);
187         }
188     }
189 
190     public void reIndex(String[] ids) throws SearchException {
191         try {
192             JournalArticleLocalServiceUtil.reIndex(ids);
193         }
194         catch (Exception e) {
195             throw new SearchException(e);
196         }
197     }
198 
199     private static String _getIndexableContent(String content) {
200         try {
201             StringBuilder sb = new StringBuilder();
202 
203             com.liferay.portal.kernel.xml.Document doc = SAXReaderUtil.read(
204                 content);
205 
206             Element root = doc.getRootElement();
207 
208             _getIndexableContent(sb, root);
209 
210             return sb.toString();
211         }
212         catch (Exception e) {
213             e.printStackTrace();
214 
215             return content;
216         }
217     }
218 
219     private static void _getIndexableContent(StringBuilder sb, Element root)
220         throws Exception {
221 
222         for (Element el : root.elements()) {
223             String elType = el.attributeValue("type", StringPool.BLANK);
224 
225             if (elType.equals("text") || elType.equals("text_box") ||
226                 elType.equals("text_area")) {
227 
228                 for (Element dynamicContent : el.elements("dynamic-content")) {
229                     String text = dynamicContent.getText();
230 
231                     sb.append(text);
232                     sb.append(StringPool.SPACE);
233                 }
234             }
235             else if (el.getName().equals("static-content")) {
236                 String text = el.getText();
237 
238                 sb.append(text);
239                 sb.append(StringPool.SPACE);
240             }
241 
242             _getIndexableContent(sb, el);
243         }
244     }
245 
246     private static final String[] _CLASS_NAMES = new String[] {
247         JournalArticle.class.getName()
248     };
249 
250 }