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