1
22
23 package com.liferay.portlet.wiki.util;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.configuration.Filter;
28 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
29 import com.liferay.portal.kernel.util.ArrayUtil;
30 import com.liferay.portal.kernel.util.DiffHtmlUtil;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.HttpUtil;
33 import com.liferay.portal.kernel.util.InstancePool;
34 import com.liferay.portal.kernel.util.ListUtil;
35 import com.liferay.portal.kernel.util.PropsKeys;
36 import com.liferay.portal.kernel.util.StringPool;
37 import com.liferay.portal.kernel.util.StringUtil;
38 import com.liferay.portal.kernel.util.Validator;
39 import com.liferay.portal.security.permission.ActionKeys;
40 import com.liferay.portal.security.permission.PermissionChecker;
41 import com.liferay.portal.theme.ThemeDisplay;
42 import com.liferay.portal.util.ContentUtil;
43 import com.liferay.portal.util.PropsUtil;
44 import com.liferay.portal.util.PropsValues;
45 import com.liferay.portal.util.WebKeys;
46 import com.liferay.portlet.wiki.PageContentException;
47 import com.liferay.portlet.wiki.WikiFormatException;
48 import com.liferay.portlet.wiki.engines.WikiEngine;
49 import com.liferay.portlet.wiki.model.WikiNode;
50 import com.liferay.portlet.wiki.model.WikiPage;
51 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
52 import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
53 import com.liferay.portlet.wiki.util.comparator.VisibleNodesComparator;
54
55 import java.io.IOException;
56 import java.io.StringReader;
57
58 import java.util.Collections;
59 import java.util.HashMap;
60 import java.util.Iterator;
61 import java.util.List;
62 import java.util.Map;
63 import java.util.regex.Matcher;
64 import java.util.regex.Pattern;
65
66 import javax.portlet.PortletPreferences;
67 import javax.portlet.PortletURL;
68 import javax.portlet.RenderRequest;
69
70
76 public class WikiUtil {
77
78 public static final String POP_PORTLET_PREFIX = "wiki.";
79
80 public static String convert(
81 WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
82 String attachmentURLPrefix)
83 throws PageContentException, WikiFormatException {
84
85 return _instance._convert(
86 page, viewPageURL, editPageURL, attachmentURLPrefix);
87 }
88
89 public static String diffHtml (
90 WikiPage sourcePage, WikiPage targetPage, PortletURL viewPageURL,
91 PortletURL editPageURL, String attachmentURLPrefix)
92 throws Exception {
93
94 String sourceContent = StringPool.BLANK;
95 String targetContent = StringPool.BLANK;
96
97 if (sourcePage != null) {
98 sourceContent = WikiUtil.convert(
99 sourcePage, viewPageURL, editPageURL,attachmentURLPrefix);
100 }
101
102 if (targetPage != null) {
103 targetContent = WikiUtil.convert(
104 targetPage, viewPageURL, editPageURL, attachmentURLPrefix);
105 }
106
107 return DiffHtmlUtil.diff(
108 new StringReader(sourceContent),new StringReader(targetContent));
109 }
110
111 public static String getEditPage(String format) {
112 return _instance._getEditPage(format);
113 }
114
115 public static String getEmailFromAddress(PortletPreferences preferences) {
116 String emailFromAddress = PropsUtil.get(
117 PropsKeys.WIKI_EMAIL_FROM_ADDRESS);
118
119 return preferences.getValue("email-from-address", emailFromAddress);
120 }
121
122 public static String getEmailFromName(PortletPreferences preferences) {
123 String emailFromName = PropsUtil.get(PropsKeys.WIKI_EMAIL_FROM_NAME);
124
125 return preferences.getValue("email-from-name", emailFromName);
126 }
127
128 public static boolean getEmailPageAddedEnabled(
129 PortletPreferences preferences) {
130
131 String emailPageAddedEnabled = preferences.getValue(
132 "email-page-added-enabled", StringPool.BLANK);
133
134 if (Validator.isNotNull(emailPageAddedEnabled)) {
135 return GetterUtil.getBoolean(emailPageAddedEnabled);
136 }
137 else {
138 return GetterUtil.getBoolean(PropsUtil.get(
139 PropsKeys.WIKI_EMAIL_PAGE_ADDED_ENABLED));
140 }
141 }
142
143 public static String getEmailPageAddedBody(PortletPreferences preferences) {
144 String emailPageAddedBody = preferences.getValue(
145 "email-page-added-body", StringPool.BLANK);
146
147 if (Validator.isNotNull(emailPageAddedBody)) {
148 return emailPageAddedBody;
149 }
150 else {
151 return ContentUtil.get(PropsUtil.get(
152 PropsKeys.WIKI_EMAIL_PAGE_ADDED_BODY));
153 }
154 }
155
156 public static String getEmailPageAddedSignature(
157 PortletPreferences preferences) {
158
159 String emailPageAddedSignature = preferences.getValue(
160 "email-page-added-signature", StringPool.BLANK);
161
162 if (Validator.isNotNull(emailPageAddedSignature)) {
163 return emailPageAddedSignature;
164 }
165 else {
166 return ContentUtil.get(PropsUtil.get(
167 PropsKeys.WIKI_EMAIL_PAGE_ADDED_SIGNATURE));
168 }
169 }
170
171 public static String getEmailPageAddedSubjectPrefix(
172 PortletPreferences preferences) {
173
174 String emailPageAddedSubjectPrefix = preferences.getValue(
175 "email-page-added-subject-prefix", StringPool.BLANK);
176
177 if (Validator.isNotNull(emailPageAddedSubjectPrefix)) {
178 return emailPageAddedSubjectPrefix;
179 }
180 else {
181 return ContentUtil.get(PropsUtil.get(
182 PropsKeys.WIKI_EMAIL_PAGE_ADDED_SUBJECT_PREFIX));
183 }
184 }
185
186 public static boolean getEmailPageUpdatedEnabled(
187 PortletPreferences preferences) {
188
189 String emailPageUpdatedEnabled = preferences.getValue(
190 "email-page-updated-enabled", StringPool.BLANK);
191
192 if (Validator.isNotNull(emailPageUpdatedEnabled)) {
193 return GetterUtil.getBoolean(emailPageUpdatedEnabled);
194 }
195 else {
196 return GetterUtil.getBoolean(PropsUtil.get(
197 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_ENABLED));
198 }
199 }
200
201 public static String getEmailPageUpdatedBody(
202 PortletPreferences preferences) {
203
204 String emailPageUpdatedBody = preferences.getValue(
205 "email-page-updated-body", StringPool.BLANK);
206
207 if (Validator.isNotNull(emailPageUpdatedBody)) {
208 return emailPageUpdatedBody;
209 }
210 else {
211 return ContentUtil.get(PropsUtil.get(
212 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_BODY));
213 }
214 }
215
216 public static String getEmailPageUpdatedSignature(
217 PortletPreferences preferences) {
218
219 String emailPageUpdatedSignature = preferences.getValue(
220 "email-page-updated-signature", StringPool.BLANK);
221
222 if (Validator.isNotNull(emailPageUpdatedSignature)) {
223 return emailPageUpdatedSignature;
224 }
225 else {
226 return ContentUtil.get(PropsUtil.get(
227 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SIGNATURE));
228 }
229 }
230
231 public static String getEmailPageUpdatedSubjectPrefix(
232 PortletPreferences preferences) {
233
234 String emailPageUpdatedSubject = preferences.getValue(
235 "email-page-updated-subject-prefix", StringPool.BLANK);
236
237 if (Validator.isNotNull(emailPageUpdatedSubject)) {
238 return emailPageUpdatedSubject;
239 }
240 else {
241 return ContentUtil.get(PropsUtil.get(
242 PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SUBJECT_PREFIX));
243 }
244 }
245
246 public static String getHelpPage(String format) {
247 return _instance._getHelpPage(format);
248 }
249
250 public static String getHelpURL(String format) {
251 return _instance._getHelpURL(format);
252 }
253
254 public static Map<String, Boolean> getLinks(WikiPage page)
255 throws PageContentException {
256
257 return _instance._getLinks(page);
258 }
259
260 public static String getMailId(String mx, long nodeId, long pageId) {
261 StringBuilder sb = new StringBuilder();
262
263 sb.append(StringPool.LESS_THAN);
264 sb.append(POP_PORTLET_PREFIX);
265 sb.append(nodeId);
266 sb.append(StringPool.PERIOD);
267 sb.append(pageId);
268 sb.append(StringPool.AT);
269 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
270 sb.append(StringPool.PERIOD);
271 sb.append(mx);
272 sb.append(StringPool.GREATER_THAN);
273
274 return sb.toString();
275 }
276
277 public static List<WikiNode> getNodes(RenderRequest renderRequest)
278 throws PortalException, SystemException {
279
280 ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
281 WebKeys.THEME_DISPLAY);
282
283 long groupId = themeDisplay.getScopeGroupId();
284
285 String allNodes = ListUtil.toString(
286 WikiNodeLocalServiceUtil.getNodes(groupId), "name");
287
288 String[] visibleNodes = StringUtil.split(
289 renderRequest.getPreferences().getValue("visible-nodes", allNodes));
290 String[] hiddenNodes = StringUtil.split(
291 renderRequest.getPreferences().getValue(
292 "hidden-nodes", StringPool.BLANK));
293
294 return getNodes(
295 groupId, visibleNodes, hiddenNodes,
296 themeDisplay.getPermissionChecker());
297 }
298
299 public static List<WikiNode> getNodes(
300 long groupId, String[] visibleNodes, String[] hiddenNodes,
301 PermissionChecker permissionChecker)
302 throws PortalException, SystemException {
303
304 List<WikiNode> nodes = WikiNodeLocalServiceUtil.getNodes(groupId);
305
306 nodes = ListUtil.sort(nodes, new VisibleNodesComparator(visibleNodes));
307
308 Iterator<WikiNode> itr = nodes.iterator();
309
310 while (itr.hasNext()) {
311 WikiNode node = itr.next();
312
313 if (ArrayUtil.contains(hiddenNodes, node.getName()) ||
314 !WikiNodePermission.contains(
315 permissionChecker, node.getNodeId(), ActionKeys.VIEW)) {
316
317 itr.remove();
318 }
319 }
320
321 return nodes;
322 }
323
324 public static String processContent(String content) {
325 content = content.replaceAll("</p>", "</p>\n");
326 content = content.replaceAll("</br>", "</br>\n");
327 content = content.replaceAll("</div>", "</div>\n");
328
329 return content;
330 }
331
332 public static boolean validate(
333 long nodeId, String content, String format)
334 throws WikiFormatException {
335
336 return _instance._validate(nodeId, content, format);
337 }
338
339 private String _convert(
340 WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
341 String attachmentURLPrefix)
342 throws PageContentException, WikiFormatException {
343
344 LiferayPortletURL liferayViewPageURL = (LiferayPortletURL)viewPageURL;
345 LiferayPortletURL liferayEditPageURL = (LiferayPortletURL)editPageURL;
346
347 WikiEngine engine = _getEngine(page.getFormat());
348
349 String content = engine.convert(page, editPageURL);
350
351 String editPageURLString = StringPool.BLANK;
352
353 if (editPageURL != null) {
354 liferayEditPageURL.setParameter("title", "__REPLACEMENT__", false);
355
356 editPageURLString = editPageURL.toString();
357
358 editPageURLString = StringUtil.replace(
359 editPageURLString, "__REPLACEMENT__", "$1");
360 }
361
362 Matcher matcher = _editPageURLPattern.matcher(content);
363
364 content = matcher.replaceAll(editPageURLString);
365
366 String viewPageURLString = StringPool.BLANK;
367
368 if (viewPageURL != null) {
369 liferayViewPageURL.setParameter("title", "__REPLACEMENT__", false);
370
371 viewPageURLString = viewPageURL.toString();
372
373 viewPageURLString = StringUtil.replace(
374 viewPageURLString, "__REPLACEMENT__", "$1");
375 }
376
377 matcher = _viewPageURLPattern.matcher(content);
378
379 content = matcher.replaceAll(viewPageURLString);
380
381 content = _replaceAttachments(
382 content, page.getTitle(), attachmentURLPrefix);
383
384 return content;
385 }
386
387 private String _getEditPage(String format) {
388 return PropsUtil.get(
389 PropsKeys.WIKI_FORMATS_EDIT_PAGE, new Filter(format));
390 }
391
392 private WikiEngine _getEngine(String format) throws WikiFormatException {
393 WikiEngine engine = _engines.get(format);
394
395 if (engine == null) {
396 try {
397 String engineClass = PropsUtil.get(
398 PropsKeys.WIKI_FORMATS_ENGINE, new Filter(format));
399
400 if (engineClass != null) {
401 if (!InstancePool.contains(engineClass)) {
402 engine = (WikiEngine)InstancePool.get(engineClass);
403
404 engine.setMainConfiguration(
405 _readConfigurationFile(
406 PropsKeys.WIKI_FORMATS_CONFIGURATION_MAIN,
407 format));
408
409 engine.setInterWikiConfiguration(
410 _readConfigurationFile(
411 PropsKeys.WIKI_FORMATS_CONFIGURATION_INTERWIKI,
412 format));
413 }
414 else {
415 engine = (WikiEngine)InstancePool.get(engineClass);
416 }
417
418 _engines.put(format, engine);
419 }
420 }
421 catch (Exception e) {
422 throw new WikiFormatException(e);
423 }
424
425 if (engine == null) {
426 throw new WikiFormatException(format);
427 }
428 }
429
430 return engine;
431 }
432
433 private String _getHelpPage(String format) {
434 return PropsUtil.get(
435 PropsKeys.WIKI_FORMATS_HELP_PAGE, new Filter(format));
436 }
437
438 private String _getHelpURL(String format) {
439 return PropsUtil.get(
440 PropsKeys.WIKI_FORMATS_HELP_URL, new Filter(format));
441 }
442
443 private Map<String, Boolean> _getLinks(WikiPage page)
444 throws PageContentException {
445
446 try {
447 return _getEngine(page.getFormat()).getOutgoingLinks(page);
448 }
449 catch (WikiFormatException wfe) {
450 return Collections.EMPTY_MAP;
451 }
452 }
453
454 private String _readConfigurationFile(String propertyName, String format)
455 throws IOException {
456
457 ClassLoader classLoader = getClass().getClassLoader();
458
459 String configurationFile = PropsUtil.get(
460 propertyName, new Filter(format));
461
462 if (Validator.isNotNull(configurationFile)) {
463 return HttpUtil.URLtoString(
464 classLoader.getResource(configurationFile));
465 }
466 else {
467 return StringPool.BLANK;
468 }
469 }
470
471 private String _replaceAttachments(
472 String content, String title, String attachmentURLPrefix) {
473
474 content = StringUtil.replace(content, "[$WIKI_PAGE_NAME$]", title);
475
476 content = StringUtil.replace(
477 content, "[$ATTACHMENT_URL_PREFIX$]", attachmentURLPrefix);
478
479 return content;
480 }
481
482 private boolean _validate(long nodeId, String content, String format)
483 throws WikiFormatException {
484
485 return _getEngine(format).validate(nodeId, content);
486 }
487
488 private static WikiUtil _instance = new WikiUtil();
489
490 private static Pattern _editPageURLPattern = Pattern.compile(
491 "\\[\\$BEGIN_PAGE_TITLE_EDIT\\$\\](.*?)\\[\\$END_PAGE_TITLE_EDIT\\$\\]");
492 private static Pattern _viewPageURLPattern = Pattern.compile(
493 "\\[\\$BEGIN_PAGE_TITLE\\$\\](.*?)\\[\\$END_PAGE_TITLE\\$\\]");
494
495 private Map<String, WikiEngine> _engines =
496 new HashMap<String, WikiEngine>();
497
498 }