001
014
015 package com.liferay.portlet.wiki.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
021 import com.liferay.portal.kernel.language.LanguageUtil;
022 import com.liferay.portal.kernel.util.Diff;
023 import com.liferay.portal.kernel.util.DiffResult;
024 import com.liferay.portal.kernel.util.DiffUtil;
025 import com.liferay.portal.kernel.util.HtmlUtil;
026 import com.liferay.portal.kernel.util.HttpUtil;
027 import com.liferay.portal.kernel.util.ObjectValuePair;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.velocity.VelocityContext;
032 import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
033 import com.liferay.portal.security.permission.ActionKeys;
034 import com.liferay.portal.service.ServiceContext;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portal.util.PortletKeys;
037 import com.liferay.portal.util.PropsValues;
038 import com.liferay.portlet.wiki.model.WikiNode;
039 import com.liferay.portlet.wiki.model.WikiPage;
040 import com.liferay.portlet.wiki.model.WikiPageConstants;
041 import com.liferay.portlet.wiki.service.base.WikiPageServiceBaseImpl;
042 import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
043 import com.liferay.portlet.wiki.service.permission.WikiPagePermission;
044 import com.liferay.portlet.wiki.util.WikiUtil;
045 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
046 import com.liferay.util.ContentUtil;
047 import com.liferay.util.RSSUtil;
048
049 import com.sun.syndication.feed.synd.SyndContent;
050 import com.sun.syndication.feed.synd.SyndContentImpl;
051 import com.sun.syndication.feed.synd.SyndEntry;
052 import com.sun.syndication.feed.synd.SyndEntryImpl;
053 import com.sun.syndication.feed.synd.SyndFeed;
054 import com.sun.syndication.feed.synd.SyndFeedImpl;
055 import com.sun.syndication.io.FeedException;
056
057 import java.io.File;
058 import java.io.InputStream;
059
060 import java.util.ArrayList;
061 import java.util.Iterator;
062 import java.util.List;
063 import java.util.Locale;
064
065
070 public class WikiPageServiceImpl extends WikiPageServiceBaseImpl {
071
072 public WikiPage addPage(
073 long nodeId, String title, String content, String summary,
074 boolean minorEdit, ServiceContext serviceContext)
075 throws PortalException, SystemException {
076
077 WikiNodePermission.check(
078 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
079
080 return wikiPageLocalService.addPage(
081 getUserId(), nodeId, title, content, summary, minorEdit,
082 serviceContext);
083 }
084
085 public WikiPage addPage(
086 long nodeId, String title, String content, String summary,
087 boolean minorEdit, String format, String parentTitle,
088 String redirectTitle, ServiceContext serviceContext)
089 throws PortalException, SystemException {
090
091 WikiNodePermission.check(
092 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
093
094 return wikiPageLocalService.addPage(
095 getUserId(), nodeId, title, WikiPageConstants.VERSION_DEFAULT,
096 content, summary, minorEdit, format, true, parentTitle,
097 redirectTitle, serviceContext);
098 }
099
100 public void addPageAttachment(
101 long nodeId, String title, String fileName, File file)
102 throws PortalException, SystemException {
103
104 WikiNodePermission.check(
105 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
106
107 wikiPageLocalService.addPageAttachment(
108 getUserId(), nodeId, title, fileName, file);
109 }
110
111 public void addPageAttachment(
112 long nodeId, String title, String fileName, InputStream inputStream)
113 throws PortalException, SystemException {
114
115 WikiNodePermission.check(
116 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
117
118 wikiPageLocalService.addPageAttachment(
119 getUserId(), nodeId, title, fileName, inputStream);
120 }
121
122 public void addPageAttachments(
123 long nodeId, String title,
124 List<ObjectValuePair<String, InputStream>> inputStream)
125 throws PortalException, SystemException {
126
127 WikiNodePermission.check(
128 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
129
130 wikiPageLocalService.addPageAttachments(
131 getUserId(), nodeId, title, inputStream);
132 }
133
134 public String addTempPageAttachment(
135 long nodeId, String fileName, String tempFolderName,
136 InputStream inputStream)
137 throws PortalException, SystemException {
138
139 WikiNodePermission.check(
140 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
141
142 return wikiPageLocalService.addTempPageAttachment(
143 getUserId(), fileName, tempFolderName, inputStream);
144 }
145
146 public void changeParent(
147 long nodeId, String title, String newParentTitle,
148 ServiceContext serviceContext)
149 throws PortalException, SystemException {
150
151 WikiPagePermission.check(
152 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
153
154 WikiNodePermission.check(
155 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
156
157 wikiPageLocalService.changeParent(
158 getUserId(), nodeId, title, newParentTitle, serviceContext);
159 }
160
161 public void deletePage(long nodeId, String title)
162 throws PortalException, SystemException {
163
164 WikiPagePermission.check(
165 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
166
167 wikiPageLocalService.deletePage(nodeId, title);
168 }
169
170 public void deletePage(long nodeId, String title, double version)
171 throws PortalException, SystemException {
172
173 WikiPagePermission.check(
174 getPermissionChecker(), nodeId, title, version, ActionKeys.DELETE);
175
176 wikiPageLocalService.deletePage(nodeId, title, version);
177 }
178
179 public void deletePageAttachment(long nodeId, String title, String fileName)
180 throws PortalException, SystemException {
181
182 WikiPagePermission.check(
183 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
184
185 wikiPageLocalService.deletePageAttachment(nodeId, title, fileName);
186 }
187
188 public void deleteTempPageAttachment(
189 long nodeId, String fileName, String tempFolderName)
190 throws PortalException, SystemException {
191
192 WikiNodePermission.check(
193 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
194
195 wikiPageLocalService.deleteTempPageAttachment(
196 getUserId(), fileName, tempFolderName);
197 }
198
199 public WikiPage getDraftPage(long nodeId, String title)
200 throws PortalException, SystemException {
201
202 WikiPagePermission.check(
203 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
204
205 return wikiPageLocalService.getDraftPage(nodeId, title);
206 }
207
208 public List<WikiPage> getNodePages(long nodeId, int max)
209 throws PortalException, SystemException {
210
211 List<WikiPage> pages = new ArrayList<WikiPage>();
212
213 int lastIntervalStart = 0;
214 boolean listNotExhausted = true;
215
216 while ((pages.size() < max) && listNotExhausted) {
217 List<WikiPage> pageList = wikiPageLocalService.getPages(
218 nodeId, true, lastIntervalStart, lastIntervalStart + max);
219
220 Iterator<WikiPage> itr = pageList.iterator();
221
222 lastIntervalStart += max;
223 listNotExhausted = (pageList.size() == max);
224
225 while (itr.hasNext() && (pages.size() < max)) {
226 WikiPage page = itr.next();
227
228 if (WikiPagePermission.contains(
229 getPermissionChecker(), page, ActionKeys.VIEW)) {
230
231 pages.add(page);
232 }
233 }
234 }
235
236 return pages;
237 }
238
239 public String getNodePagesRSS(
240 long nodeId, int max, String type, double version,
241 String displayStyle, String feedURL, String entryURL)
242 throws PortalException, SystemException {
243
244 WikiNodePermission.check(
245 getPermissionChecker(), nodeId, ActionKeys.VIEW);
246
247 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
248
249 long companyId = node.getCompanyId();
250 String name = node.getName();
251 String description = node.getDescription();
252 List<WikiPage> pages = getNodePages(nodeId, max);
253 boolean diff = false;
254 Locale locale = null;
255
256 return exportToRSS(
257 companyId, name, description, type, version, displayStyle, feedURL,
258 entryURL, pages, diff, locale);
259 }
260
261 public WikiPage getPage(long nodeId, String title)
262 throws PortalException, SystemException {
263
264 WikiPagePermission.check(
265 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
266
267 return wikiPageLocalService.getPage(nodeId, title);
268 }
269
270 public WikiPage getPage(long nodeId, String title, Boolean head)
271 throws PortalException, SystemException {
272
273 WikiPagePermission.check(
274 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
275
276 return wikiPageLocalService.getPage(nodeId, title, head);
277 }
278
279 public WikiPage getPage(long nodeId, String title, double version)
280 throws PortalException, SystemException {
281
282 WikiPagePermission.check(
283 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
284
285 return wikiPageLocalService.getPage(nodeId, title, version);
286 }
287
288 public String getPagesRSS(
289 long companyId, long nodeId, String title, int max, String type,
290 double version, String displayStyle, String feedURL,
291 String entryURL, Locale locale)
292 throws PortalException, SystemException {
293
294 WikiPagePermission.check(
295 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
296
297 String description = title;
298 List<WikiPage> pages = wikiPageLocalService.getPages(
299 nodeId, title, 0, max, new PageCreateDateComparator(true));
300 boolean diff = true;
301
302 return exportToRSS(
303 companyId, title, description, type, version, displayStyle, feedURL,
304 entryURL, pages, diff, locale);
305 }
306
307 public String[] getTempPageAttachmentNames(
308 long nodeId, String tempFolderName)
309 throws PortalException, SystemException {
310
311 WikiNodePermission.check(
312 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
313
314 return wikiPageLocalService.getTempPageAttachmentNames(
315 getUserId(), tempFolderName);
316 }
317
318 public void movePage(
319 long nodeId, String title, String newTitle,
320 ServiceContext serviceContext)
321 throws PortalException, SystemException {
322
323 WikiPagePermission.check(
324 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
325
326 WikiNodePermission.check(
327 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
328
329 wikiPageLocalService.movePage(
330 getUserId(), nodeId, title, newTitle, serviceContext);
331 }
332
333 public WikiPage revertPage(
334 long nodeId, String title, double version,
335 ServiceContext serviceContext)
336 throws PortalException, SystemException {
337
338 WikiPagePermission.check(
339 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
340
341 return wikiPageLocalService.revertPage(
342 getUserId(), nodeId, title, version, serviceContext);
343 }
344
345 public void subscribePage(long nodeId, String title)
346 throws PortalException, SystemException {
347
348 WikiPagePermission.check(
349 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
350
351 wikiPageLocalService.subscribePage(getUserId(), nodeId, title);
352 }
353
354 public void unsubscribePage(long nodeId, String title)
355 throws PortalException, SystemException {
356
357 WikiPagePermission.check(
358 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
359
360 wikiPageLocalService.unsubscribePage(getUserId(), nodeId, title);
361 }
362
363 public WikiPage updatePage(
364 long nodeId, String title, double version, String content,
365 String summary, boolean minorEdit, String format,
366 String parentTitle, String redirectTitle,
367 ServiceContext serviceContext)
368 throws PortalException, SystemException {
369
370 WikiPagePermission.check(
371 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
372
373 return wikiPageLocalService.updatePage(
374 getUserId(), nodeId, title, version, content, summary, minorEdit,
375 format, parentTitle, redirectTitle, serviceContext);
376 }
377
378 protected String exportToRSS(
379 long companyId, String name, String description, String type,
380 double version, String displayStyle, String feedURL,
381 String entryURL, List<WikiPage> pages, boolean diff, Locale locale)
382 throws SystemException {
383
384 SyndFeed syndFeed = new SyndFeedImpl();
385
386 syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
387 syndFeed.setTitle(name);
388 syndFeed.setLink(feedURL);
389 syndFeed.setDescription(description);
390
391 List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
392
393 syndFeed.setEntries(syndEntries);
394
395 WikiPage latestPage = null;
396
397 StringBundler link = new StringBundler(7);
398
399 for (WikiPage page : pages) {
400 String author = HtmlUtil.escape(
401 PortalUtil.getUserName(page.getUserId(), page.getUserName()));
402
403 String title =
404 page.getTitle() + StringPool.SPACE + page.getVersion();
405
406 if (page.isMinorEdit()) {
407 title +=
408 StringPool.SPACE + StringPool.OPEN_PARENTHESIS +
409 LanguageUtil.get(locale, "minor-edit") +
410 StringPool.CLOSE_PARENTHESIS;
411 }
412
413 link.setIndex(0);
414
415 link.append(entryURL);
416 link.append(StringPool.AMPERSAND);
417 link.append(HttpUtil.encodeURL(page.getTitle()));
418
419 SyndEntry syndEntry = new SyndEntryImpl();
420
421 syndEntry.setAuthor(author);
422 syndEntry.setTitle(title);
423 syndEntry.setPublishedDate(page.getCreateDate());
424 syndEntry.setUpdatedDate(page.getModifiedDate());
425
426 SyndContent syndContent = new SyndContentImpl();
427
428 syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
429
430 if (diff) {
431 if (latestPage != null) {
432 link.append(StringPool.QUESTION);
433 link.append(
434 PortalUtil.getPortletNamespace(PortletKeys.WIKI));
435 link.append("version=");
436 link.append(page.getVersion());
437
438 String value = getPageDiff(
439 companyId, latestPage, page, locale);
440
441 syndContent.setValue(value);
442
443 syndEntry.setDescription(syndContent);
444
445 syndEntries.add(syndEntry);
446 }
447 }
448 else {
449 String value = null;
450
451 if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
452 value = StringUtil.shorten(
453 HtmlUtil.extractText(page.getContent()),
454 PropsValues.WIKI_RSS_ABSTRACT_LENGTH, StringPool.BLANK);
455 }
456 else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
457 value = StringPool.BLANK;
458 }
459 else {
460 value = page.getContent();
461 }
462
463 syndContent.setValue(value);
464
465 syndEntry.setDescription(syndContent);
466
467 syndEntries.add(syndEntry);
468 }
469
470 syndEntry.setLink(link.toString());
471 syndEntry.setUri(syndEntry.getLink());
472
473 latestPage = page;
474 }
475
476 try {
477 return RSSUtil.export(syndFeed);
478 }
479 catch (FeedException fe) {
480 throw new SystemException(fe);
481 }
482 }
483
484 protected String getPageDiff(
485 long companyId, WikiPage latestPage, WikiPage page, Locale locale)
486 throws SystemException {
487
488 String sourceContent = WikiUtil.processContent(latestPage.getContent());
489 String targetContent = WikiUtil.processContent(page.getContent());
490
491 sourceContent = HtmlUtil.escape(sourceContent);
492 targetContent = HtmlUtil.escape(targetContent);
493
494 List<DiffResult>[] diffResults = DiffUtil.diff(
495 new UnsyncStringReader(sourceContent),
496 new UnsyncStringReader(targetContent));
497
498 String velocityTemplateId =
499 "com/liferay/portlet/wiki/dependencies/rss.vm";
500 String velocityTemplateContent = ContentUtil.get(velocityTemplateId);
501
502 VelocityContext velocityContext =
503 VelocityEngineUtil.getWrappedStandardToolsContext();
504
505 velocityContext.put("companyId", companyId);
506 velocityContext.put("contextLine", Diff.CONTEXT_LINE);
507 velocityContext.put("diffUtil", new DiffUtil());
508 velocityContext.put("languageUtil", LanguageUtil.getLanguage());
509 velocityContext.put("locale", locale);
510 velocityContext.put("sourceResults", diffResults[0]);
511 velocityContext.put("targetResults", diffResults[1]);
512
513 try {
514 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
515
516 VelocityEngineUtil.mergeTemplate(
517 velocityTemplateId, velocityTemplateContent, velocityContext,
518 unsyncStringWriter);
519
520 return unsyncStringWriter.toString();
521 }
522 catch (Exception e) {
523 throw new SystemException(e);
524 }
525 }
526
527 }