1
14
15 package com.liferay.portlet.journal.util;
16
17 import com.liferay.portal.kernel.log.Log;
18 import com.liferay.portal.kernel.log.LogFactoryUtil;
19 import com.liferay.portal.kernel.search.Document;
20 import com.liferay.portal.kernel.search.DocumentImpl;
21 import com.liferay.portal.kernel.search.Field;
22 import com.liferay.portal.kernel.search.Indexer;
23 import com.liferay.portal.kernel.search.SearchContext;
24 import com.liferay.portal.kernel.search.SearchEngineUtil;
25 import com.liferay.portal.kernel.search.Summary;
26 import com.liferay.portal.kernel.util.GetterUtil;
27 import com.liferay.portal.kernel.util.HtmlUtil;
28 import com.liferay.portal.kernel.util.StringBundler;
29 import com.liferay.portal.kernel.util.StringPool;
30 import com.liferay.portal.kernel.util.StringUtil;
31 import com.liferay.portal.kernel.util.Validator;
32 import com.liferay.portal.kernel.workflow.StatusConstants;
33 import com.liferay.portal.kernel.xml.Element;
34 import com.liferay.portal.kernel.xml.SAXReaderUtil;
35 import com.liferay.portal.search.BaseIndexer;
36 import com.liferay.portal.util.PortletKeys;
37 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
38 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
39 import com.liferay.portlet.expando.model.ExpandoBridge;
40 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
41 import com.liferay.portlet.journal.model.JournalArticle;
42 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
43
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Date;
47 import java.util.LinkedList;
48 import java.util.List;
49
50 import javax.portlet.PortletURL;
51
52
60 public class JournalIndexer extends BaseIndexer {
61
62 public static final String[] CLASS_NAMES = {JournalArticle.class.getName()};
63
64 public static final String PORTLET_ID = PortletKeys.JOURNAL;
65
66 public String[] getClassNames() {
67 return CLASS_NAMES;
68 }
69
70 public Summary getSummary(
71 Document document, String snippet, PortletURL portletURL) {
72
73 String title = document.get(Field.TITLE);
74
75 String content = snippet;
76
77 if (Validator.isNull(snippet)) {
78 content = StringUtil.shorten(document.get(Field.CONTENT), 200);
79 }
80
81 String groupId = document.get("groupId");
82 String articleId = document.get(Field.ENTRY_CLASS_PK);
83 String version = document.get("version");
84
85 portletURL.setParameter("struts_action", "/journal/edit_article");
86 portletURL.setParameter("groupId", groupId);
87 portletURL.setParameter("articleId", articleId);
88 portletURL.setParameter("version", version);
89
90 return new Summary(title, content, portletURL);
91 }
92
93 protected void doDelete(Object obj) throws Exception {
94 JournalArticle article = (JournalArticle)obj;
95
96 Document document = new DocumentImpl();
97
98 document.addUID(
99 PORTLET_ID, article.getGroupId(), article.getArticleId());
100
101 SearchEngineUtil.deleteDocument(
102 article.getCompanyId(), document.get(Field.UID));
103 }
104
105 protected Document doGetDocument(Object obj) throws Exception {
106 JournalArticle article = (JournalArticle)obj;
107
108 long companyId = article.getCompanyId();
109 long groupId = getParentGroupId(article.getGroupId());
110 long scopeGroupId = article.getGroupId();
111 long userId = article.getUserId();
112 long resourcePrimKey = article.getResourcePrimKey();
113 String articleId = article.getArticleId();
114 double version = article.getVersion();
115 String title = article.getTitle();
116 String description = article.getDescription();
117 String content = article.getContent();
118 String type = article.getType();
119 Date displayDate = article.getDisplayDate();
120
121 long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
122 JournalArticle.class.getName(), resourcePrimKey);
123 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
124 JournalArticle.class.getName(), resourcePrimKey);
125
126 ExpandoBridge expandoBridge = article.getExpandoBridge();
127
128 Document document = new DocumentImpl();
129
130 document.addUID(PORTLET_ID, groupId, articleId);
131
132 document.addModifiedDate(displayDate);
133
134 document.addKeyword(Field.COMPANY_ID, companyId);
135 document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
136 document.addKeyword(Field.GROUP_ID, groupId);
137 document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
138 document.addKeyword(Field.USER_ID, userId);
139
140 document.addText(Field.TITLE, title);
141 document.addText(Field.CONTENT, processContent(document, content));
142 document.addText(Field.DESCRIPTION, description);
143 document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
144 document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
145
146 document.addKeyword(
147 Field.ENTRY_CLASS_NAME, JournalArticle.class.getName());
148 document.addKeyword(Field.ENTRY_CLASS_PK, articleId);
149 document.addKeyword(Field.ROOT_ENTRY_CLASS_PK, resourcePrimKey);
150 document.addKeyword(Field.VERSION, version);
151 document.addKeyword(Field.TYPE, type);
152
153 ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
154
155 return document;
156 }
157
158 protected void doReindex(Object obj) throws Exception {
159 JournalArticle article = (JournalArticle)obj;
160
161 if (!article.isApproved() || !article.isIndexable()) {
162 return;
163 }
164
165 Document document = getDocument(article);
166
167 SearchEngineUtil.updateDocument(article.getCompanyId(), document);
168 }
169
170 protected void doReindex(String className, long classPK) throws Exception {
171 JournalArticle article =
172 JournalArticleLocalServiceUtil.getLatestArticle(
173 classPK, StatusConstants.APPROVED);
174
175 doReindex(article);
176 }
177
178 protected void doReindex(String[] ids) throws Exception {
179 long companyId = GetterUtil.getLong(ids[0]);
180
181 reindexArticles(companyId);
182 }
183
184 protected String getIndexableContent(Document document, Element rootElement)
185 throws Exception {
186
187 StringBundler sb = new StringBundler();
188
189 LinkedList<Element> queue = new LinkedList<Element>(
190 rootElement.elements());
191
192 Element element = null;
193
194 while ((element = queue.poll()) != null) {
195 String elType = element.attributeValue("type", StringPool.BLANK);
196 String elIndexType = element.attributeValue(
197 "index-type", StringPool.BLANK);
198
199 indexField(document, element, elType, elIndexType);
200
201 if (elType.equals("text") || elType.equals("text_box") ||
202 elType.equals("text_area")) {
203
204 for (Element dynamicContentElement :
205 element.elements("dynamic-content")) {
206
207 String text = dynamicContentElement.getText();
208
209 sb.append(text);
210 sb.append(StringPool.SPACE);
211 }
212 }
213 else if (element.getName().equals("static-content")) {
214 String text = element.getText();
215
216 sb.append(text);
217 sb.append(StringPool.SPACE);
218 }
219
220 queue.addAll(element.elements());
221 }
222
223 return sb.toString();
224 }
225
226 protected String getIndexableContent(Document document, String content) {
227 try {
228 com.liferay.portal.kernel.xml.Document contentDocument =
229 SAXReaderUtil.read(content);
230
231 Element rootElement = contentDocument.getRootElement();
232
233 return getIndexableContent(document, rootElement);
234 }
235 catch (Exception e) {
236 _log.error(e, e);
237
238 return content;
239 }
240 }
241
242 protected String getPortletId(SearchContext searchContext) {
243 return PORTLET_ID;
244 }
245
246 protected void indexField(
247 Document document, Element element, String elType, String elIndexType) {
248
249 if (Validator.isNull(elIndexType)) {
250 return;
251 }
252
253 Element dynamicContentElement = element.element("dynamic-content");
254
255 String name = element.attributeValue("name", StringPool.BLANK);
256 String[] value = new String[] {dynamicContentElement.getText()};
257
258 if (elType.equals("multi-list")) {
259 List<Element> optionElements = dynamicContentElement.elements();
260
261 value = new String[optionElements.size()];
262
263 for (int i = 0; i < optionElements.size(); i++) {
264 value[i] = optionElements.get(i).getText();
265 }
266 }
267
268 if (elIndexType.equals("keyword")) {
269 document.addKeyword(name, value);
270 }
271 else if (elIndexType.equals("text")) {
272 document.addText(name, StringUtil.merge(value, StringPool.SPACE));
273 }
274 }
275
276 protected String processContent(Document document, String content) {
277 if ((content != null) &&
278 ((content.indexOf("<dynamic-content") != -1) ||
279 (content.indexOf("<static-content") != -1))) {
280
281 content = getIndexableContent(document, content);
282
283 content = StringUtil.replace(
284 content, "<![CDATA[", StringPool.BLANK);
285 content = StringUtil.replace(content, "]]>", StringPool.BLANK);
286 }
287
288 content = StringUtil.replace(content, "&", "&");
289 content = StringUtil.replace(content, "<", "<");
290 content = StringUtil.replace(content, ">", ">");
291
292 content = HtmlUtil.extractText(content);
293
294 return content;
295 }
296
297 protected void reindexArticles(long companyId) throws Exception {
298 int count = JournalArticleLocalServiceUtil.getCompanyArticlesCount(
299 companyId, StatusConstants.APPROVED);
300
301 int pages = count / Indexer.DEFAULT_INTERVAL;
302
303 for (int i = 0; i <= pages; i++) {
304 int start = (i * Indexer.DEFAULT_INTERVAL);
305 int end = start + Indexer.DEFAULT_INTERVAL;
306
307 reindexArticles(companyId, start, end);
308 }
309 }
310
311 protected void reindexArticles(long companyId, int start, int end)
312 throws Exception {
313
314 List<JournalArticle> articles =
315 JournalArticleLocalServiceUtil.getCompanyArticles(
316 companyId, StatusConstants.APPROVED, start, end);
317
318 if (articles.isEmpty()) {
319 return;
320 }
321
322 Collection<Document> documents = new ArrayList<Document>();
323
324 for (JournalArticle article : articles) {
325 Document document = getDocument(article);
326
327 documents.add(document);
328 }
329
330 SearchEngineUtil.updateDocuments(companyId, documents);
331 }
332
333 private static Log _log = LogFactoryUtil.getLog(JournalIndexer.class);
334
335 }