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