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