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