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