1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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(
74              long companyId, long groupId, String articleId)
75          throws SearchException {
76  
77          SearchEngineUtil.deleteDocument(
78              companyId, getArticleUID(groupId, articleId));
79      }
80  
81      public static Document getArticleDocument(
82          long companyId, long groupId, String articleId, double version,
83          String title, String description, String content, String type,
84          Date displayDate, String[] tagsCategories, String[] tagsEntries,
85          ExpandoBridge expandoBridge) {
86  
87          if ((content != null) &&
88              ((content.indexOf("<dynamic-content") != -1) ||
89               (content.indexOf("<static-content") != -1))) {
90  
91              content = _getIndexableContent(content);
92  
93              content = StringUtil.replace(
94                  content, "<![CDATA[", StringPool.BLANK);
95              content = StringUtil.replace(content, "]]>", StringPool.BLANK);
96          }
97  
98          content = StringUtil.replace(content, "&amp;", "&");
99          content = StringUtil.replace(content, "&lt;", "<");
100         content = StringUtil.replace(content, "&gt;", ">");
101 
102         content = HtmlUtil.extractText(content);
103 
104         Document doc = new DocumentImpl();
105 
106         doc.addUID(PORTLET_ID, groupId, articleId);
107 
108         doc.addModifiedDate(displayDate);
109 
110         doc.addKeyword(Field.COMPANY_ID, companyId);
111         doc.addKeyword(Field.PORTLET_ID, PORTLET_ID);
112         doc.addKeyword(Field.GROUP_ID, groupId);
113 
114         doc.addText(Field.TITLE, title);
115         doc.addText(Field.CONTENT, content);
116         doc.addText(Field.DESCRIPTION, description);
117         doc.addKeyword(Field.TAGS_CATEGORIES, tagsCategories);
118         doc.addKeyword(Field.TAGS_ENTRIES, tagsEntries);
119 
120         doc.addKeyword(Field.ENTRY_CLASS_NAME, JournalArticle.class.getName());
121         doc.addKeyword(Field.ENTRY_CLASS_PK, articleId);
122         doc.addKeyword(Field.VERSION, version);
123         doc.addKeyword(Field.TYPE, type);
124 
125         ExpandoBridgeIndexerUtil.addAttributes(doc, expandoBridge);
126 
127         return doc;
128     }
129 
130     public static String getArticleUID(long groupId, String articleId) {
131         Document doc = new DocumentImpl();
132 
133         doc.addUID(PORTLET_ID, groupId, articleId);
134 
135         return doc.get(Field.UID);
136     }
137 
138     public static void updateArticle(
139             long companyId, long groupId, String articleId, double version,
140             String title, String description, String content, String type,
141             Date displayDate, String[] tagsCategories, String[] tagsEntries,
142             ExpandoBridge expandoBridge)
143         throws SearchException {
144 
145         Document doc = getArticleDocument(
146             companyId, groupId, articleId, version, title, description, content,
147             type, displayDate, tagsCategories, tagsEntries, expandoBridge);
148 
149         SearchEngineUtil.updateDocument(companyId, doc.get(Field.UID), doc);
150     }
151 
152     public String[] getClassNames() {
153         return _CLASS_NAMES;
154     }
155 
156     public DocumentSummary getDocumentSummary(
157         com.liferay.portal.kernel.search.Document doc, PortletURL portletURL) {
158 
159         // Title
160 
161         String title = doc.get(Field.TITLE);
162 
163         // Content
164 
165         String content = doc.get(Field.CONTENT);
166 
167         content = StringUtil.shorten(content, 200);
168 
169         // Portlet URL
170 
171         String groupId = doc.get("groupId");
172         String articleId = doc.get(Field.ENTRY_CLASS_PK);
173         String version = doc.get("version");
174 
175         portletURL.setParameter("struts_action", "/journal/edit_article");
176         portletURL.setParameter("groupId", groupId);
177         portletURL.setParameter("articleId", articleId);
178         portletURL.setParameter("version", version);
179 
180         return new DocumentSummary(title, content, portletURL);
181     }
182 
183     public void reIndex(String className, long classPK) throws SearchException {
184         try {
185             JournalArticleLocalServiceUtil.reIndex(classPK);
186         }
187         catch (Exception e) {
188             throw new SearchException(e);
189         }
190     }
191 
192     public void reIndex(String[] ids) throws SearchException {
193         try {
194             JournalArticleLocalServiceUtil.reIndex(ids);
195         }
196         catch (Exception e) {
197             throw new SearchException(e);
198         }
199     }
200 
201     private static String _getIndexableContent(String content) {
202         try {
203             StringBuilder sb = new StringBuilder();
204 
205             com.liferay.portal.kernel.xml.Document doc = SAXReaderUtil.read(
206                 content);
207 
208             Element root = doc.getRootElement();
209 
210             _getIndexableContent(sb, root);
211 
212             return sb.toString();
213         }
214         catch (Exception e) {
215             e.printStackTrace();
216 
217             return content;
218         }
219     }
220 
221     private static void _getIndexableContent(StringBuilder sb, Element root)
222         throws Exception {
223 
224         for (Element el : root.elements()) {
225             String elType = el.attributeValue("type", StringPool.BLANK);
226 
227             if (elType.equals("text") || elType.equals("text_box") ||
228                 elType.equals("text_area")) {
229 
230                 for (Element dynamicContent : el.elements("dynamic-content")) {
231                     String text = dynamicContent.getText();
232 
233                     sb.append(text);
234                     sb.append(StringPool.SPACE);
235                 }
236             }
237             else if (el.getName().equals("static-content")) {
238                 String text = el.getText();
239 
240                 sb.append(text);
241                 sb.append(StringPool.SPACE);
242             }
243 
244             _getIndexableContent(sb, el);
245         }
246     }
247 
248     private static final String[] _CLASS_NAMES = new String[] {
249         JournalArticle.class.getName()
250     };
251 
252 }