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