1
22
23 package com.liferay.portlet.wiki.service.impl;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.language.LanguageUtil;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.HtmlUtil;
30 import com.liferay.portal.kernel.util.ObjectValuePair;
31 import com.liferay.portal.kernel.util.StringPool;
32 import com.liferay.portal.kernel.util.StringUtil;
33 import com.liferay.portal.security.permission.ActionKeys;
34 import com.liferay.portal.theme.ThemeDisplay;
35 import com.liferay.portal.util.ContentUtil;
36 import com.liferay.portal.util.PortalUtil;
37 import com.liferay.portal.util.PortletKeys;
38 import com.liferay.portal.util.PropsKeys;
39 import com.liferay.portal.util.PropsUtil;
40 import com.liferay.portal.velocity.VelocityUtil;
41 import com.liferay.portlet.wiki.model.WikiNode;
42 import com.liferay.portlet.wiki.model.WikiPage;
43 import com.liferay.portlet.wiki.service.base.WikiPageServiceBaseImpl;
44 import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
45 import com.liferay.portlet.wiki.service.permission.WikiPagePermission;
46 import com.liferay.portlet.wiki.util.WikiUtil;
47 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
48 import com.liferay.util.RSSUtil;
49 import com.liferay.util.diff.DiffResult;
50 import com.liferay.util.diff.DiffUtil;
51
52 import com.sun.syndication.feed.synd.SyndContent;
53 import com.sun.syndication.feed.synd.SyndContentImpl;
54 import com.sun.syndication.feed.synd.SyndEntry;
55 import com.sun.syndication.feed.synd.SyndEntryImpl;
56 import com.sun.syndication.feed.synd.SyndFeed;
57 import com.sun.syndication.feed.synd.SyndFeedImpl;
58 import com.sun.syndication.io.FeedException;
59
60 import java.io.IOException;
61 import java.io.StringReader;
62
63 import java.util.ArrayList;
64 import java.util.HashMap;
65 import java.util.Iterator;
66 import java.util.List;
67 import java.util.Locale;
68 import java.util.Map;
69
70 import javax.portlet.PortletPreferences;
71
72
79 public class WikiPageServiceImpl extends WikiPageServiceBaseImpl {
80
81 public WikiPage addPage(
82 long nodeId, String title, String content, String summary,
83 boolean minorEdit, PortletPreferences prefs,
84 ThemeDisplay themeDisplay)
85 throws PortalException, SystemException {
86
87 WikiNodePermission.check(
88 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
89
90 return wikiPageLocalService.addPage(
91 getUserId(), nodeId, title, content, summary, minorEdit, prefs,
92 themeDisplay);
93 }
94
95 public void addPageAttachments(
96 long nodeId, String title,
97 List<ObjectValuePair<String, byte[]>> files)
98 throws PortalException, SystemException {
99
100 WikiNodePermission.check(
101 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
102
103 wikiPageLocalService.addPageAttachments(nodeId, title, files);
104 }
105
106 public void changeParent(
107 long nodeId, String title, String newParentTitle,
108 PortletPreferences prefs, ThemeDisplay themeDisplay)
109 throws PortalException, SystemException {
110
111 WikiNodePermission.check(
112 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
113
114 WikiPagePermission.check(
115 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
116
117 wikiPageLocalService.changeParent(
118 getUserId(), nodeId, title, newParentTitle, prefs, themeDisplay);
119 }
120
121 public void deletePage(long nodeId, String title)
122 throws PortalException, SystemException {
123
124 WikiPagePermission.check(
125 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
126
127 wikiPageLocalService.deletePage(nodeId, title);
128 }
129
130 public void deletePageAttachment(long nodeId, String title, String fileName)
131 throws PortalException, SystemException {
132
133 WikiPagePermission.check(
134 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
135
136 wikiPageLocalService.deletePageAttachment(nodeId, title, fileName);
137 }
138
139 public List<WikiPage> getNodePages(long nodeId, int max)
140 throws PortalException, SystemException {
141
142 List<WikiPage> pages = new ArrayList<WikiPage>();
143
144 Iterator<WikiPage> itr = wikiPageLocalService.getPages(nodeId, true, 0,
145 _MAX_END).iterator();
146
147 while (itr.hasNext() && (pages.size() < max)) {
148 WikiPage page = itr.next();
149
150 if (WikiPagePermission.contains(getPermissionChecker(), page,
151 ActionKeys.VIEW)) {
152
153 pages.add(page);
154 }
155 }
156
157 return pages;
158 }
159
160 public String getNodePagesRSS(
161 long nodeId, int max, String type, double version,
162 String displayStyle, String feedURL, String entryURL)
163 throws PortalException, SystemException {
164
165 WikiNodePermission.check(
166 getPermissionChecker(), nodeId, ActionKeys.VIEW);
167
168 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
169
170 long companyId = node.getCompanyId();
171 String name = node.getName();
172 String description = node.getDescription();
173 List<WikiPage> pages = getNodePages(nodeId, max);
174 boolean diff = false;
175 Locale locale = null;
176
177 return exportToRSS(
178 companyId, name, description, type, version, displayStyle,
179 feedURL, entryURL, pages, diff, locale);
180 }
181
182 public WikiPage getPage(long nodeId, String title)
183 throws PortalException, SystemException {
184
185 WikiPagePermission.check(
186 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
187
188 return wikiPageLocalService.getPage(nodeId, title);
189 }
190
191 public WikiPage getPage(long nodeId, String title, double version)
192 throws PortalException, SystemException {
193
194 WikiPagePermission.check(
195 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
196
197 return wikiPageLocalService.getPage(nodeId, title, version);
198 }
199
200 public String getPagesRSS(
201 long companyId, long nodeId, String title, int max, String type,
202 double version, String displayStyle, String feedURL,
203 String entryURL, Locale locale)
204 throws PortalException, SystemException {
205
206 WikiPagePermission.check(
207 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
208
209 String description = title;
210 List<WikiPage> pages = wikiPageLocalService.getPages(
211 nodeId, title, 0, _MAX_END, new PageCreateDateComparator(true));
212 boolean diff = true;
213
214 return exportToRSS(
215 companyId, title, description, type, version, displayStyle, feedURL,
216 entryURL, pages, diff, locale);
217 }
218
219 public void movePage(
220 long nodeId, String title, String newTitle,
221 PortletPreferences prefs, ThemeDisplay themeDisplay)
222 throws PortalException, SystemException {
223
224 WikiNodePermission.check(
225 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
226
227 WikiPagePermission.check(
228 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
229
230 wikiPageLocalService.movePage(
231 getUserId(), nodeId, title, newTitle, prefs, themeDisplay);
232 }
233
234 public WikiPage revertPage(
235 long nodeId, String title, double version, PortletPreferences prefs,
236 ThemeDisplay themeDisplay)
237 throws PortalException, SystemException {
238
239 WikiPagePermission.check(
240 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
241
242 return wikiPageLocalService.revertPage(
243 getUserId(), nodeId, title, version, prefs, themeDisplay);
244 }
245
246 public void subscribePage(long nodeId, String title)
247 throws PortalException, SystemException {
248
249 WikiPagePermission.check(
250 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
251
252 wikiPageLocalService.subscribePage(getUserId(), nodeId, title);
253 }
254
255 public void unsubscribePage(long nodeId, String title)
256 throws PortalException, SystemException {
257
258 WikiPagePermission.check(
259 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
260
261 wikiPageLocalService.unsubscribePage(getUserId(), nodeId, title);
262 }
263
264 public WikiPage updatePage(
265 long nodeId, String title, double version, String content,
266 String summary, boolean minorEdit, String format,
267 String parentTitle, String redirectTitle, String[] tagsEntries,
268 PortletPreferences prefs, ThemeDisplay themeDisplay)
269 throws PortalException, SystemException {
270
271 WikiPagePermission.check(
272 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
273
274 return wikiPageLocalService.updatePage(
275 getUserId(), nodeId, title, version, content, summary, minorEdit,
276 format, parentTitle, redirectTitle, tagsEntries, prefs,
277 themeDisplay);
278 }
279
280 protected String exportToRSS(
281 long companyId, String name, String description, String type,
282 double version, String displayStyle, String feedURL,
283 String entryURL, List<WikiPage> pages, boolean diff, Locale locale)
284 throws SystemException {
285
286 SyndFeed syndFeed = new SyndFeedImpl();
287
288 syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
289 syndFeed.setTitle(name);
290 syndFeed.setLink(feedURL);
291 syndFeed.setDescription(description);
292
293 List<SyndEntry> entries = new ArrayList<SyndEntry>();
294
295 syndFeed.setEntries(entries);
296
297 WikiPage latestPage = null;
298
299 for (WikiPage page : pages) {
300 String author = PortalUtil.getUserName(
301 page.getUserId(), page.getUserName());
302
303 String link = entryURL;
304
305 SyndEntry syndEntry = new SyndEntryImpl();
306
307 syndEntry.setAuthor(author);
308 syndEntry.setTitle(
309 page.getTitle() + StringPool.SPACE + page.getVersion());
310 syndEntry.setPublishedDate(page.getCreateDate());
311
312 SyndContent syndContent = new SyndContentImpl();
313
314 syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
315
316 if (diff) {
317 if (latestPage != null) {
318 link +=
319 "?" + PortalUtil.getPortletNamespace(PortletKeys.WIKI) +
320 "version=" + page.getVersion();
321
322 String value = getPageDiff(
323 companyId, latestPage, page, locale);
324
325 syndContent.setValue(value);
326
327 syndEntry.setDescription(syndContent);
328
329 entries.add(syndEntry);
330 }
331 }
332 else {
333 String value = null;
334
335 if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
336 value = StringUtil.shorten(
337 HtmlUtil.extractText(page.getContent()),
338 _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
339 }
340 else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
341 value = StringPool.BLANK;
342 }
343 else {
344 value = page.getContent();
345 }
346
347 syndContent.setValue(value);
348
349 syndEntry.setDescription(syndContent);
350
351 entries.add(syndEntry);
352 }
353
354 syndEntry.setLink(link);
355
356 latestPage = page;
357 }
358
359 try {
360 return RSSUtil.export(syndFeed);
361 }
362 catch (FeedException fe) {
363 throw new SystemException(fe);
364 }
365 catch (IOException ioe) {
366 throw new SystemException(ioe);
367 }
368 }
369
370 protected String getPageDiff(
371 long companyId, WikiPage latestPage, WikiPage page,
372 Locale locale)
373 throws SystemException {
374
375 String sourceContent = WikiUtil.processContent(latestPage.getContent());
376 String targetContent = WikiUtil.processContent(page.getContent());
377
378 sourceContent = HtmlUtil.escape(sourceContent);
379 targetContent = HtmlUtil.escape(targetContent);
380
381 List<DiffResult>[] diffResults = DiffUtil.diff(
382 new StringReader(sourceContent), new StringReader(targetContent));
383
384 String template = ContentUtil.get(
385 "com/liferay/portlet/wiki/dependencies/rss.vm");
386
387 Map<String, Object> variables = new HashMap<String, Object>();
388
389 variables.put("companyId", companyId);
390 variables.put("contextLine", DiffUtil.CONTEXT_LINE);
391 variables.put("diffUtil", new DiffUtil());
392 variables.put("languageUtil", LanguageUtil.getLanguage());
393 variables.put("locale", locale);
394 variables.put("sourceResults", diffResults[0]);
395 variables.put("targetResults", diffResults[1]);
396
397 try {
398 return VelocityUtil.evaluate(template, variables);
399 }
400 catch (Exception e) {
401 throw new SystemException(e);
402 }
403 }
404
405 private static final int _MAX_END = 200;
406
407 private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
408 PropsUtil.get(PropsKeys.WIKI_RSS_ABSTRACT_LENGTH));
409
410 }