001
014
015 package com.liferay.portlet.wiki.util;
016
017 import com.liferay.portal.kernel.configuration.Filter;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
021 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
022 import com.liferay.portal.kernel.util.DiffHtmlUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.InstancePool;
026 import com.liferay.portal.kernel.util.ListUtil;
027 import com.liferay.portal.kernel.util.OrderByComparator;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.StringUtil;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.security.permission.ActionKeys;
034 import com.liferay.portal.security.permission.PermissionChecker;
035 import com.liferay.portal.theme.ThemeDisplay;
036 import com.liferay.portal.util.ContentUtil;
037 import com.liferay.portal.util.PropsUtil;
038 import com.liferay.portal.util.PropsValues;
039 import com.liferay.portal.util.WebKeys;
040 import com.liferay.portlet.wiki.PageContentException;
041 import com.liferay.portlet.wiki.WikiFormatException;
042 import com.liferay.portlet.wiki.engines.WikiEngine;
043 import com.liferay.portlet.wiki.model.WikiNode;
044 import com.liferay.portlet.wiki.model.WikiPage;
045 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
046 import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
047 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
048 import com.liferay.portlet.wiki.util.comparator.PageTitleComparator;
049 import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
050
051 import java.io.IOException;
052
053 import java.util.ArrayList;
054 import java.util.Arrays;
055 import java.util.Collections;
056 import java.util.HashMap;
057 import java.util.Iterator;
058 import java.util.List;
059 import java.util.Map;
060 import java.util.regex.Matcher;
061 import java.util.regex.Pattern;
062
063 import javax.portlet.PortletPreferences;
064 import javax.portlet.PortletRequest;
065 import javax.portlet.PortletURL;
066
067
071 public class WikiUtil {
072
073 public static final String POP_PORTLET_PREFIX = "wiki.";
074
075 public static String convert(
076 WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
077 String attachmentURLPrefix)
078 throws PageContentException, WikiFormatException {
079
080 return _instance._convert(
081 page, viewPageURL, editPageURL, attachmentURLPrefix);
082 }
083
084 public static String diffHtml (
085 WikiPage sourcePage, WikiPage targetPage, PortletURL viewPageURL,
086 PortletURL editPageURL, String attachmentURLPrefix)
087 throws Exception {
088
089 String sourceContent = StringPool.BLANK;
090 String targetContent = StringPool.BLANK;
091
092 if (sourcePage != null) {
093 sourceContent = WikiUtil.convert(
094 sourcePage, viewPageURL, editPageURL,attachmentURLPrefix);
095 }
096
097 if (targetPage != null) {
098 targetContent = WikiUtil.convert(
099 targetPage, viewPageURL, editPageURL, attachmentURLPrefix);
100 }
101
102 return DiffHtmlUtil.diff(
103 new UnsyncStringReader(sourceContent),
104 new UnsyncStringReader(targetContent));
105 }
106
107 public static String getEditPage(String format) {
108 return _instance._getEditPage(format);
109 }
110
111 public static String getEmailFromAddress(PortletPreferences preferences) {
112 String emailFromAddress = PropsUtil.get(
113 PropsKeys.WIKI_EMAIL_FROM_ADDRESS);
114
115 return preferences.getValue("email-from-address", emailFromAddress);
116 }
117
118 public static String getEmailFromName(PortletPreferences preferences) {
119 String emailFromName = PropsUtil.get(PropsKeys.WIKI_EMAIL_FROM_NAME);
120
121 return preferences.getValue("email-from-name", emailFromName);
122 }
123
124 public static boolean getEmailPageAddedEnabled(
125 PortletPreferences preferences) {
126
127 String emailPageAddedEnabled = preferences.getValue(
128 "email-page-added-enabled", StringPool.BLANK);
129
130 if (Validator.isNotNull(emailPageAddedEnabled)) {
131 return GetterUtil.getBoolean(emailPageAddedEnabled);
132 }
133 else {
134 return GetterUtil.getBoolean(PropsUtil.get(
135 PropsKeys.WIKI_EMAIL_PAGE_ADDED_ENABLED));
136 }
137 }
138
139 public static String getEmailPageAddedBody(PortletPreferences preferences) {
140 String emailPageAddedBody = preferences.getValue(
141 "email-page-added-body", StringPool.BLANK);
142
143 if (Validator.isNotNull(emailPageAddedBody)) {
144 return emailPageAddedBody;
145 }
146 else {
147 return ContentUtil.get(PropsUtil.get(
148 PropsKeys.WIKI_EMAIL_PAGE_ADDED_BODY));
149 }
150 }
151
152 public static String getEmailPageAddedSignature(
153 PortletPreferences preferences) {
154
155 String emailPageAddedSignature = preferences.getValue(
156 "email-page-added-signature", StringPool.BLANK);
157
158 if (Validator.isNotNull(emailPageAddedSignature)) {
159 return emailPageAddedSignature;
160 }
161 else {
162 return ContentUtil.get(PropsUtil.get(
163 PropsKeys.WIKI_EMAIL_PAGE_ADDED_SIGNATURE));
164 }
165 }
166
167 public static String getEmailPageAddedSubjectPrefix(
168 PortletPreferences preferences) {
169
170 String emailPageAddedSubjectPrefix = preferences.getValue(
171 "email-page-added-subject-prefix", StringPool.BLANK);
172
173 if (Validator.isNotNull(emailPageAddedSubjectPrefix)) {
174 return emailPageAddedSubjectPrefix;
175 }
176 else {
177 return ContentUtil.get(PropsUtil.get(
178 PropsKeys.WIKI_EMAIL_PAGE_ADDED_SUBJECT_PREFIX));
179 }
180 }
181
182 public static boolean getEmailPageUpdatedEnabled(
183 PortletPreferences preferences) {
184
185 String emailPageUpdatedEnabled = preferences.getValue(
186 "email-page-updated-enabled", StringPool.BLANK);
187
188 if (Validator.isNotNull(emailPageUpdatedEnabled)) {
189 return GetterUtil.getBoolean(emailPageUpdatedEnabled);
190 }
191 else {
192 return GetterUtil.getBoolean(PropsUtil.get(
193 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_ENABLED));
194 }
195 }
196
197 public static String getEmailPageUpdatedBody(
198 PortletPreferences preferences) {
199
200 String emailPageUpdatedBody = preferences.getValue(
201 "email-page-updated-body", StringPool.BLANK);
202
203 if (Validator.isNotNull(emailPageUpdatedBody)) {
204 return emailPageUpdatedBody;
205 }
206 else {
207 return ContentUtil.get(PropsUtil.get(
208 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_BODY));
209 }
210 }
211
212 public static String getEmailPageUpdatedSignature(
213 PortletPreferences preferences) {
214
215 String emailPageUpdatedSignature = preferences.getValue(
216 "email-page-updated-signature", StringPool.BLANK);
217
218 if (Validator.isNotNull(emailPageUpdatedSignature)) {
219 return emailPageUpdatedSignature;
220 }
221 else {
222 return ContentUtil.get(PropsUtil.get(
223 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SIGNATURE));
224 }
225 }
226
227 public static String getEmailPageUpdatedSubjectPrefix(
228 PortletPreferences preferences) {
229
230 String emailPageUpdatedSubject = preferences.getValue(
231 "email-page-updated-subject-prefix", StringPool.BLANK);
232
233 if (Validator.isNotNull(emailPageUpdatedSubject)) {
234 return emailPageUpdatedSubject;
235 }
236 else {
237 return ContentUtil.get(PropsUtil.get(
238 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SUBJECT_PREFIX));
239 }
240 }
241
242 public static WikiNode getFirstNode(PortletRequest portletRequest)
243 throws PortalException, SystemException {
244
245 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
246 WebKeys.THEME_DISPLAY);
247 long groupId = themeDisplay.getScopeGroupId();
248 PermissionChecker permissionChecker =
249 themeDisplay.getPermissionChecker();
250
251 List<WikiNode> nodes = WikiNodeLocalServiceUtil.getNodes(groupId);
252
253 PortletPreferences preferences = portletRequest.getPreferences();
254 String[] visibleNodeNames =
255 StringUtil.split(preferences.getValue("visible-nodes", null));
256 nodes = orderNodes(nodes, visibleNodeNames);
257
258 String[] hiddenNodes = StringUtil.split(
259 preferences.getValue("hidden-nodes", StringPool.BLANK));
260 Arrays.sort(hiddenNodes);
261
262 for(WikiNode node : nodes) {
263 if ((Arrays.binarySearch(hiddenNodes, node.getName()) < 0) &&
264 (WikiNodePermission.contains(permissionChecker, node,
265 ActionKeys.VIEW))) {
266 return node;
267 }
268 }
269 return null;
270 }
271
272 public static String getHelpPage(String format) {
273 return _instance._getHelpPage(format);
274 }
275
276 public static String getHelpURL(String format) {
277 return _instance._getHelpURL(format);
278 }
279
280 public static Map<String, Boolean> getLinks(WikiPage page)
281 throws PageContentException {
282
283 return _instance._getLinks(page);
284 }
285
286 public static String getMailId(String mx, long nodeId, long pageId) {
287 StringBundler sb = new StringBundler(10);
288
289 sb.append(StringPool.LESS_THAN);
290 sb.append(POP_PORTLET_PREFIX);
291 sb.append(nodeId);
292 sb.append(StringPool.PERIOD);
293 sb.append(pageId);
294 sb.append(StringPool.AT);
295 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
296 sb.append(StringPool.PERIOD);
297 sb.append(mx);
298 sb.append(StringPool.GREATER_THAN);
299
300 return sb.toString();
301 }
302
303 public static List<String> getNodeNames(List<WikiNode> nodes) {
304 List<String> nodeNames = new ArrayList<String>(nodes.size());
305
306 for (WikiNode node : nodes) {
307 nodeNames.add(node.getName());
308 }
309
310 return nodeNames;
311 }
312
313 public static List<WikiNode> getNodes(
314 List<WikiNode> nodes, String[] hiddenNodes,
315 PermissionChecker permissionChecker) {
316
317 nodes = ListUtil.copy(nodes);
318
319 Arrays.sort(hiddenNodes);
320
321 Iterator<WikiNode> itr = nodes.iterator();
322
323 while (itr.hasNext()) {
324 WikiNode node = itr.next();
325
326 if (!(Arrays.binarySearch(hiddenNodes, node.getName()) < 0) ||
327 !WikiNodePermission.contains(
328 permissionChecker, node, ActionKeys.VIEW)) {
329
330 itr.remove();
331 }
332 }
333
334 return nodes;
335 }
336
337 public static OrderByComparator getPageOrderByComparator(
338 String orderByCol, String orderByType) {
339
340 boolean orderByAsc = false;
341
342 if (orderByType.equals("asc")) {
343 orderByAsc = true;
344 }
345
346 OrderByComparator orderByComparator = null;
347
348 if (orderByCol.equals("modifiedDate")) {
349 orderByComparator = new PageCreateDateComparator(orderByAsc);
350 }
351 else if (orderByCol.equals("title")) {
352 orderByComparator = new PageTitleComparator(orderByAsc);
353 }
354 else if (orderByCol.equals("version")) {
355 orderByComparator = new PageVersionComparator(orderByAsc);
356 }
357
358 return orderByComparator;
359 }
360
361 public static List<WikiNode> orderNodes(
362 List<WikiNode> nodes, String[] visibleNodeNames) {
363
364 if ((visibleNodeNames == null) || (visibleNodeNames.length == 0)) {
365 return nodes;
366 }
367
368 nodes = ListUtil.copy(nodes);
369
370 List<WikiNode> orderedNodes = new ArrayList<WikiNode>(nodes.size());
371
372 for (String visibleNodeName : visibleNodeNames) {
373 for (WikiNode node : nodes) {
374 if (node.getName().equals(visibleNodeName)) {
375 orderedNodes.add(node);
376
377 nodes.remove(node);
378
379 break;
380 }
381 }
382 }
383
384 orderedNodes.addAll(nodes);
385
386 return orderedNodes;
387 }
388
389 public static String processContent(String content) {
390 content = content.replaceAll("</p>", "</p>\n");
391 content = content.replaceAll("</br>", "</br>\n");
392 content = content.replaceAll("</div>", "</div>\n");
393
394 return content;
395 }
396
397 public static boolean validate(
398 long nodeId, String content, String format)
399 throws WikiFormatException {
400
401 return _instance._validate(nodeId, content, format);
402 }
403
404 private String _convert(
405 WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
406 String attachmentURLPrefix)
407 throws PageContentException, WikiFormatException {
408
409 LiferayPortletURL liferayViewPageURL = (LiferayPortletURL)viewPageURL;
410 LiferayPortletURL liferayEditPageURL = (LiferayPortletURL)editPageURL;
411
412 WikiEngine engine = _getEngine(page.getFormat());
413
414 String content = engine.convert(page, editPageURL);
415
416 String editPageURLString = StringPool.BLANK;
417
418 if (editPageURL != null) {
419 liferayEditPageURL.setParameter("title", "__REPLACEMENT__", false);
420
421 editPageURLString = editPageURL.toString();
422
423 editPageURLString = StringUtil.replace(
424 editPageURLString, "__REPLACEMENT__", "$1");
425 }
426
427 Matcher matcher = _editPageURLPattern.matcher(content);
428
429 content = matcher.replaceAll(editPageURLString);
430
431 String viewPageURLString = StringPool.BLANK;
432
433 if (viewPageURL != null) {
434 liferayViewPageURL.setParameter("title", "__REPLACEMENT__", false);
435
436 viewPageURLString = viewPageURL.toString();
437
438 viewPageURLString = StringUtil.replace(
439 viewPageURLString, "__REPLACEMENT__", "$1");
440 }
441
442 matcher = _viewPageURLPattern.matcher(content);
443
444 content = matcher.replaceAll(viewPageURLString);
445
446 content = _replaceAttachments(
447 content, page.getTitle(), attachmentURLPrefix);
448
449 return content;
450 }
451
452 private String _getEditPage(String format) {
453 return PropsUtil.get(
454 PropsKeys.WIKI_FORMATS_EDIT_PAGE, new Filter(format));
455 }
456
457 private WikiEngine _getEngine(String format) throws WikiFormatException {
458 WikiEngine engine = _engines.get(format);
459
460 if (engine == null) {
461 try {
462 String engineClass = PropsUtil.get(
463 PropsKeys.WIKI_FORMATS_ENGINE, new Filter(format));
464
465 if (engineClass != null) {
466 if (!InstancePool.contains(engineClass)) {
467 engine = (WikiEngine)InstancePool.get(engineClass);
468
469 engine.setMainConfiguration(
470 _readConfigurationFile(
471 PropsKeys.WIKI_FORMATS_CONFIGURATION_MAIN,
472 format));
473
474 engine.setInterWikiConfiguration(
475 _readConfigurationFile(
476 PropsKeys.WIKI_FORMATS_CONFIGURATION_INTERWIKI,
477 format));
478 }
479 else {
480 engine = (WikiEngine)InstancePool.get(engineClass);
481 }
482
483 _engines.put(format, engine);
484 }
485 }
486 catch (Exception e) {
487 throw new WikiFormatException(e);
488 }
489
490 if (engine == null) {
491 throw new WikiFormatException(format);
492 }
493 }
494
495 return engine;
496 }
497
498 private String _getHelpPage(String format) {
499 return PropsUtil.get(
500 PropsKeys.WIKI_FORMATS_HELP_PAGE, new Filter(format));
501 }
502
503 private String _getHelpURL(String format) {
504 return PropsUtil.get(
505 PropsKeys.WIKI_FORMATS_HELP_URL, new Filter(format));
506 }
507
508 private Map<String, Boolean> _getLinks(WikiPage page)
509 throws PageContentException {
510
511 try {
512 return _getEngine(page.getFormat()).getOutgoingLinks(page);
513 }
514 catch (WikiFormatException wfe) {
515 return Collections.EMPTY_MAP;
516 }
517 }
518
519 private String _readConfigurationFile(String propertyName, String format)
520 throws IOException {
521
522 ClassLoader classLoader = getClass().getClassLoader();
523
524 String configurationFile = PropsUtil.get(
525 propertyName, new Filter(format));
526
527 if (Validator.isNotNull(configurationFile)) {
528 return HttpUtil.URLtoString(
529 classLoader.getResource(configurationFile));
530 }
531 else {
532 return StringPool.BLANK;
533 }
534 }
535
536 private String _replaceAttachments(
537 String content, String title, String attachmentURLPrefix) {
538
539 content = StringUtil.replace(content, "[$WIKI_PAGE_NAME$]", title);
540
541 content = StringUtil.replace(
542 content, "[$ATTACHMENT_URL_PREFIX$]", attachmentURLPrefix);
543
544 return content;
545 }
546
547 private boolean _validate(long nodeId, String content, String format)
548 throws WikiFormatException {
549
550 return _getEngine(format).validate(nodeId, content);
551 }
552
553 private static WikiUtil _instance = new WikiUtil();
554
555 private static Pattern _editPageURLPattern = Pattern.compile(
556 "\\[\\$BEGIN_PAGE_TITLE_EDIT\\$\\](.*?)\\[\\$END_PAGE_TITLE_EDIT\\$\\]");
557 private static Pattern _viewPageURLPattern = Pattern.compile(
558 "\\[\\$BEGIN_PAGE_TITLE\\$\\](.*?)\\[\\$END_PAGE_TITLE\\$\\]");
559
560 private Map<String, WikiEngine> _engines =
561 new HashMap<String, WikiEngine>();
562
563 }