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