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