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[] tagsEntries, ExpandoBridge expandoBridge)
63          throws SearchException {
64  
65          Document doc = getArticleDocument(
66              companyId, groupId, articleId, version, title, description, content,
67              type, displayDate, tagsEntries, expandoBridge);
68  
69          SearchEngineUtil.addDocument(companyId, doc);
70      }
71  
72      public static void deleteArticle(long companyId, String articleId)
73          throws SearchException {
74  
75          SearchEngineUtil.deleteDocument(companyId, getArticleUID(articleId));
76      }
77  
78      public static Document getArticleDocument(
79          long companyId, long groupId, String articleId, double version,
80          String title, String description, String content, String type,
81          Date displayDate, String[] tagsEntries, ExpandoBridge expandoBridge) {
82  
83          if ((content != null) &&
84              ((content.indexOf("<dynamic-content>") != -1) ||
85               (content.indexOf("<static-content") != -1))) {
86  
87              content = _getIndexableContent(content);
88  
89              content = StringUtil.replace(
90                  content, "<![CDATA[", StringPool.BLANK);
91              content = StringUtil.replace(content, "]]>", StringPool.BLANK);
92          }
93  
94          content = StringUtil.replace(content, "&amp;", "&");
95          content = StringUtil.replace(content, "&lt;", "<");
96          content = StringUtil.replace(content, "&gt;", ">");
97  
98          content = HtmlUtil.extractText(content);
99  
100         Document doc = new DocumentImpl();
101 
102         doc.addUID(PORTLET_ID, articleId);
103 
104         doc.addModifiedDate(displayDate);
105 
106         doc.addKeyword(Field.COMPANY_ID, companyId);
107         doc.addKeyword(Field.PORTLET_ID, PORTLET_ID);
108         doc.addKeyword(Field.GROUP_ID, groupId);
109 
110         doc.addText(Field.TITLE, title);
111         doc.addText(Field.CONTENT, content);
112         doc.addText(Field.DESCRIPTION, description);
113         doc.addKeyword(Field.TAGS_ENTRIES, tagsEntries);
114 
115         doc.addKeyword(Field.ENTRY_CLASS_NAME, JournalArticle.class.getName());
116         doc.addKeyword(Field.ENTRY_CLASS_PK, articleId);
117         doc.addKeyword(Field.VERSION, version);
118         doc.addKeyword(Field.TYPE, type);
119 
120         ExpandoBridgeIndexerUtil.addAttributes(doc, expandoBridge);
121 
122         return doc;
123     }
124 
125     public static String getArticleUID(String articleId) {
126         Document doc = new DocumentImpl();
127 
128         doc.addUID(PORTLET_ID, articleId);
129 
130         return doc.get(Field.UID);
131     }
132 
133     public static void updateArticle(
134             long companyId, long groupId, String articleId, double version,
135             String title, String description, String content, String type,
136             Date displayDate, String[] tagsEntries, ExpandoBridge expandoBridge)
137         throws SearchException {
138 
139         Document doc = getArticleDocument(
140             companyId, groupId, articleId, version, title, description, content,
141             type, displayDate, tagsEntries, expandoBridge);
142 
143         SearchEngineUtil.updateDocument(companyId, doc.get(Field.UID), doc);
144     }
145 
146     public String[] getClassNames() {
147         return _CLASS_NAMES;
148     }
149 
150     public DocumentSummary getDocumentSummary(
151         com.liferay.portal.kernel.search.Document doc, PortletURL portletURL) {
152 
153         // Title
154 
155         String title = doc.get(Field.TITLE);
156 
157         // Content
158 
159         String content = doc.get(Field.CONTENT);
160 
161         content = StringUtil.shorten(content, 200);
162 
163         // Portlet URL
164 
165         String groupId = doc.get("groupId");
166         String articleId = doc.get(Field.ENTRY_CLASS_PK);
167         String version = doc.get("version");
168 
169         portletURL.setParameter("struts_action", "/journal/edit_article");
170         portletURL.setParameter("groupId", groupId);
171         portletURL.setParameter("articleId", articleId);
172         portletURL.setParameter("version", version);
173 
174         return new DocumentSummary(title, content, portletURL);
175     }
176 
177     public void reIndex(String className, long classPK) throws SearchException {
178         try {
179             JournalArticleLocalServiceUtil.reIndex(classPK);
180         }
181         catch (Exception e) {
182             throw new SearchException(e);
183         }
184     }
185 
186     public void reIndex(String[] ids) throws SearchException {
187         try {
188             JournalArticleLocalServiceUtil.reIndex(ids);
189         }
190         catch (Exception e) {
191             throw new SearchException(e);
192         }
193     }
194 
195     private static String _getIndexableContent(String content) {
196         try {
197             StringBuilder sb = new StringBuilder();
198 
199             com.liferay.portal.kernel.xml.Document doc = SAXReaderUtil.read(
200                 content);
201 
202             Element root = doc.getRootElement();
203 
204             _getIndexableContent(sb, root);
205 
206             return sb.toString();
207         }
208         catch (Exception e) {
209             e.printStackTrace();
210 
211             return content;
212         }
213     }
214 
215     private static void _getIndexableContent(StringBuilder sb, Element root)
216         throws Exception {
217 
218         for (Element el : root.elements()) {
219             String elType = el.attributeValue("type", StringPool.BLANK);
220 
221             if (elType.equals("text") || elType.equals("text_box") ||
222                 elType.equals("text_area")) {
223 
224                 Element dynamicContent = el.element("dynamic-content");
225 
226                 String text = dynamicContent.getText();
227 
228                 sb.append(text);
229                 sb.append(StringPool.SPACE);
230             }
231             else if (el.getName().equals("static-content")) {
232                 String text = el.getText();
233 
234                 sb.append(text);
235                 sb.append(StringPool.SPACE);
236             }
237 
238             _getIndexableContent(sb, el);
239         }
240     }
241 
242     private static final String[] _CLASS_NAMES = new String[] {
243         JournalArticle.class.getName()
244     };
245 
246 }