PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/portal-impl/src/com/liferay/portlet/wiki/util/WikiUtil.java

https://github.com/viktorkovacs/liferay-portal-trunk
Java | 610 lines | 448 code | 145 blank | 17 comment | 58 complexity | 5030636235d490abde9a5526d3dc70c3 MD5 | raw file
  1. /**
  2. * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. package com.liferay.portlet.wiki.util;
  15. import com.liferay.portal.kernel.configuration.Filter;
  16. import com.liferay.portal.kernel.exception.PortalException;
  17. import com.liferay.portal.kernel.exception.SystemException;
  18. import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
  19. import com.liferay.portal.kernel.portlet.LiferayPortletURL;
  20. import com.liferay.portal.kernel.util.CharPool;
  21. import com.liferay.portal.kernel.util.DiffHtmlUtil;
  22. import com.liferay.portal.kernel.util.GetterUtil;
  23. import com.liferay.portal.kernel.util.HtmlUtil;
  24. import com.liferay.portal.kernel.util.HttpUtil;
  25. import com.liferay.portal.kernel.util.InstancePool;
  26. import com.liferay.portal.kernel.util.ListUtil;
  27. import com.liferay.portal.kernel.util.OrderByComparator;
  28. import com.liferay.portal.kernel.util.PropsKeys;
  29. import com.liferay.portal.kernel.util.StringPool;
  30. import com.liferay.portal.kernel.util.StringUtil;
  31. import com.liferay.portal.kernel.util.Validator;
  32. import com.liferay.portal.security.permission.ActionKeys;
  33. import com.liferay.portal.security.permission.PermissionChecker;
  34. import com.liferay.portal.theme.ThemeDisplay;
  35. import com.liferay.portal.util.PropsUtil;
  36. import com.liferay.portal.util.WebKeys;
  37. import com.liferay.portlet.wiki.PageContentException;
  38. import com.liferay.portlet.wiki.WikiFormatException;
  39. import com.liferay.portlet.wiki.engines.WikiEngine;
  40. import com.liferay.portlet.wiki.model.WikiNode;
  41. import com.liferay.portlet.wiki.model.WikiPage;
  42. import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
  43. import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
  44. import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
  45. import com.liferay.portlet.wiki.util.comparator.PageTitleComparator;
  46. import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
  47. import com.liferay.util.ContentUtil;
  48. import java.io.IOException;
  49. import java.util.ArrayList;
  50. import java.util.Arrays;
  51. import java.util.Collections;
  52. import java.util.Iterator;
  53. import java.util.List;
  54. import java.util.Map;
  55. import java.util.concurrent.ConcurrentHashMap;
  56. import java.util.regex.Matcher;
  57. import java.util.regex.Pattern;
  58. import javax.portlet.PortletPreferences;
  59. import javax.portlet.PortletRequest;
  60. import javax.portlet.PortletURL;
  61. /**
  62. * @author Brian Wing Shun Chan
  63. * @author Jorge Ferrer
  64. */
  65. public class WikiUtil {
  66. public static String convert(
  67. WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
  68. String attachmentURLPrefix)
  69. throws PageContentException, WikiFormatException {
  70. return _instance._convert(
  71. page, viewPageURL, editPageURL, attachmentURLPrefix);
  72. }
  73. public static String diffHtml (
  74. WikiPage sourcePage, WikiPage targetPage, PortletURL viewPageURL,
  75. PortletURL editPageURL, String attachmentURLPrefix)
  76. throws Exception {
  77. String sourceContent = StringPool.BLANK;
  78. String targetContent = StringPool.BLANK;
  79. if (sourcePage != null) {
  80. sourceContent = WikiUtil.convert(
  81. sourcePage, viewPageURL, editPageURL,attachmentURLPrefix);
  82. }
  83. if (targetPage != null) {
  84. targetContent = WikiUtil.convert(
  85. targetPage, viewPageURL, editPageURL, attachmentURLPrefix);
  86. }
  87. return DiffHtmlUtil.diff(
  88. new UnsyncStringReader(sourceContent),
  89. new UnsyncStringReader(targetContent));
  90. }
  91. public static String getEditPage(String format) {
  92. return _instance._getEditPage(format);
  93. }
  94. public static String getEmailFromAddress(PortletPreferences preferences) {
  95. String emailFromAddress = PropsUtil.get(
  96. PropsKeys.WIKI_EMAIL_FROM_ADDRESS);
  97. return preferences.getValue("emailFromAddress", emailFromAddress);
  98. }
  99. public static String getEmailFromName(PortletPreferences preferences) {
  100. String emailFromName = PropsUtil.get(PropsKeys.WIKI_EMAIL_FROM_NAME);
  101. return preferences.getValue("emailFromName", emailFromName);
  102. }
  103. public static String getEmailPageAddedBody(PortletPreferences preferences) {
  104. String emailPageAddedBody = preferences.getValue(
  105. "emailPageAddedBody", StringPool.BLANK);
  106. if (Validator.isNotNull(emailPageAddedBody)) {
  107. return emailPageAddedBody;
  108. }
  109. else {
  110. return ContentUtil.get(PropsUtil.get(
  111. PropsKeys.WIKI_EMAIL_PAGE_ADDED_BODY));
  112. }
  113. }
  114. public static boolean getEmailPageAddedEnabled(
  115. PortletPreferences preferences) {
  116. String emailPageAddedEnabled = preferences.getValue(
  117. "emailPageAddedEnabled", StringPool.BLANK);
  118. if (Validator.isNotNull(emailPageAddedEnabled)) {
  119. return GetterUtil.getBoolean(emailPageAddedEnabled);
  120. }
  121. else {
  122. return GetterUtil.getBoolean(PropsUtil.get(
  123. PropsKeys.WIKI_EMAIL_PAGE_ADDED_ENABLED));
  124. }
  125. }
  126. public static String getEmailPageAddedSignature(
  127. PortletPreferences preferences) {
  128. String emailPageAddedSignature = preferences.getValue(
  129. "emailPageAddedSignature", StringPool.BLANK);
  130. if (Validator.isNotNull(emailPageAddedSignature)) {
  131. return emailPageAddedSignature;
  132. }
  133. else {
  134. return ContentUtil.get(PropsUtil.get(
  135. PropsKeys.WIKI_EMAIL_PAGE_ADDED_SIGNATURE));
  136. }
  137. }
  138. public static String getEmailPageAddedSubjectPrefix(
  139. PortletPreferences preferences) {
  140. String emailPageAddedSubjectPrefix = preferences.getValue(
  141. "emailPageAddedSubjectPrefix", StringPool.BLANK);
  142. if (Validator.isNotNull(emailPageAddedSubjectPrefix)) {
  143. return emailPageAddedSubjectPrefix;
  144. }
  145. else {
  146. return ContentUtil.get(PropsUtil.get(
  147. PropsKeys.WIKI_EMAIL_PAGE_ADDED_SUBJECT_PREFIX));
  148. }
  149. }
  150. public static String getEmailPageUpdatedBody(
  151. PortletPreferences preferences) {
  152. String emailPageUpdatedBody = preferences.getValue(
  153. "emailPageUpdatedBody", StringPool.BLANK);
  154. if (Validator.isNotNull(emailPageUpdatedBody)) {
  155. return emailPageUpdatedBody;
  156. }
  157. else {
  158. return ContentUtil.get(PropsUtil.get(
  159. PropsKeys.WIKI_EMAIL_PAGE_UPDATED_BODY));
  160. }
  161. }
  162. public static boolean getEmailPageUpdatedEnabled(
  163. PortletPreferences preferences) {
  164. String emailPageUpdatedEnabled = preferences.getValue(
  165. "emailPageUpdatedEnabled", StringPool.BLANK);
  166. if (Validator.isNotNull(emailPageUpdatedEnabled)) {
  167. return GetterUtil.getBoolean(emailPageUpdatedEnabled);
  168. }
  169. else {
  170. return GetterUtil.getBoolean(PropsUtil.get(
  171. PropsKeys.WIKI_EMAIL_PAGE_UPDATED_ENABLED));
  172. }
  173. }
  174. public static String getEmailPageUpdatedSignature(
  175. PortletPreferences preferences) {
  176. String emailPageUpdatedSignature = preferences.getValue(
  177. "emailPageUpdatedSignature", StringPool.BLANK);
  178. if (Validator.isNotNull(emailPageUpdatedSignature)) {
  179. return emailPageUpdatedSignature;
  180. }
  181. else {
  182. return ContentUtil.get(PropsUtil.get(
  183. PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SIGNATURE));
  184. }
  185. }
  186. public static String getEmailPageUpdatedSubjectPrefix(
  187. PortletPreferences preferences) {
  188. String emailPageUpdatedSubject = preferences.getValue(
  189. "emailPageUpdatedSubjectPrefix", StringPool.BLANK);
  190. if (Validator.isNotNull(emailPageUpdatedSubject)) {
  191. return emailPageUpdatedSubject;
  192. }
  193. else {
  194. return ContentUtil.get(PropsUtil.get(
  195. PropsKeys.WIKI_EMAIL_PAGE_UPDATED_SUBJECT_PREFIX));
  196. }
  197. }
  198. public static WikiNode getFirstNode(PortletRequest portletRequest)
  199. throws PortalException, SystemException {
  200. ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
  201. WebKeys.THEME_DISPLAY);
  202. long groupId = themeDisplay.getScopeGroupId();
  203. PermissionChecker permissionChecker =
  204. themeDisplay.getPermissionChecker();
  205. List<WikiNode> nodes = WikiNodeLocalServiceUtil.getNodes(groupId);
  206. PortletPreferences preferences = portletRequest.getPreferences();
  207. String[] visibleNodeNames =
  208. StringUtil.split(preferences.getValue("visibleNodes", null));
  209. nodes = orderNodes(nodes, visibleNodeNames);
  210. String[] hiddenNodes = StringUtil.split(
  211. preferences.getValue("hiddenNodes", StringPool.BLANK));
  212. Arrays.sort(hiddenNodes);
  213. for (WikiNode node : nodes) {
  214. if ((Arrays.binarySearch(hiddenNodes, node.getName()) < 0) &&
  215. (WikiNodePermission.contains(permissionChecker, node,
  216. ActionKeys.VIEW))) {
  217. return node;
  218. }
  219. }
  220. return null;
  221. }
  222. public static String getHelpPage(String format) {
  223. return _instance._getHelpPage(format);
  224. }
  225. public static String getHelpURL(String format) {
  226. return _instance._getHelpURL(format);
  227. }
  228. public static Map<String, Boolean> getLinks(WikiPage page)
  229. throws PageContentException {
  230. return _instance._getLinks(page);
  231. }
  232. public static long getNodeIdFromUri(String uri) {
  233. if ((uri == null) || !uri.contains(_WIKI_FRIENDLY_URL_MAPPING)) {
  234. return 0;
  235. }
  236. int x =
  237. uri.indexOf(_WIKI_FRIENDLY_URL_MAPPING) +
  238. _WIKI_FRIENDLY_URL_MAPPING.length();
  239. int y = x + uri.substring(x).indexOf(CharPool.SLASH);
  240. return GetterUtil.getLong(uri.substring(x, y));
  241. }
  242. public static List<String> getNodeNames(List<WikiNode> nodes) {
  243. List<String> nodeNames = new ArrayList<String>(nodes.size());
  244. for (WikiNode node : nodes) {
  245. nodeNames.add(node.getName());
  246. }
  247. return nodeNames;
  248. }
  249. public static List<WikiNode> getNodes(
  250. List<WikiNode> nodes, String[] hiddenNodes,
  251. PermissionChecker permissionChecker) {
  252. nodes = ListUtil.copy(nodes);
  253. Arrays.sort(hiddenNodes);
  254. Iterator<WikiNode> itr = nodes.iterator();
  255. while (itr.hasNext()) {
  256. WikiNode node = itr.next();
  257. if (!(Arrays.binarySearch(hiddenNodes, node.getName()) < 0) ||
  258. !WikiNodePermission.contains(
  259. permissionChecker, node, ActionKeys.VIEW)) {
  260. itr.remove();
  261. }
  262. }
  263. return nodes;
  264. }
  265. public static OrderByComparator getPageOrderByComparator(
  266. String orderByCol, String orderByType) {
  267. boolean orderByAsc = false;
  268. if (orderByType.equals("asc")) {
  269. orderByAsc = true;
  270. }
  271. OrderByComparator orderByComparator = null;
  272. if (orderByCol.equals("modifiedDate")) {
  273. orderByComparator = new PageCreateDateComparator(orderByAsc);
  274. }
  275. else if (orderByCol.equals("title")) {
  276. orderByComparator = new PageTitleComparator(orderByAsc);
  277. }
  278. else if (orderByCol.equals("version")) {
  279. orderByComparator = new PageVersionComparator(orderByAsc);
  280. }
  281. return orderByComparator;
  282. }
  283. public static String getSummary(WikiPage page) throws WikiFormatException {
  284. return _instance._getSummary(page);
  285. }
  286. public static List<WikiNode> orderNodes(
  287. List<WikiNode> nodes, String[] visibleNodeNames) {
  288. if ((visibleNodeNames == null) || (visibleNodeNames.length == 0)) {
  289. return nodes;
  290. }
  291. nodes = ListUtil.copy(nodes);
  292. List<WikiNode> orderedNodes = new ArrayList<WikiNode>(nodes.size());
  293. for (String visibleNodeName : visibleNodeNames) {
  294. for (WikiNode node : nodes) {
  295. if (node.getName().equals(visibleNodeName)) {
  296. orderedNodes.add(node);
  297. nodes.remove(node);
  298. break;
  299. }
  300. }
  301. }
  302. orderedNodes.addAll(nodes);
  303. return orderedNodes;
  304. }
  305. public static String processContent(String content) {
  306. content = content.replaceAll("</p>", "</p>\n");
  307. content = content.replaceAll("</br>", "</br>\n");
  308. content = content.replaceAll("</div>", "</div>\n");
  309. return content;
  310. }
  311. public static boolean validate(
  312. long nodeId, String content, String format)
  313. throws WikiFormatException {
  314. return _instance._validate(nodeId, content, format);
  315. }
  316. private String _convert(
  317. WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
  318. String attachmentURLPrefix)
  319. throws PageContentException, WikiFormatException {
  320. LiferayPortletURL liferayViewPageURL = (LiferayPortletURL)viewPageURL;
  321. LiferayPortletURL liferayEditPageURL = (LiferayPortletURL)editPageURL;
  322. WikiEngine engine = _getEngine(page.getFormat());
  323. String content = engine.convert(
  324. page, viewPageURL, editPageURL, attachmentURLPrefix);
  325. String editPageURLString = StringPool.BLANK;
  326. if (editPageURL != null) {
  327. liferayEditPageURL.setParameter("title", "__REPLACEMENT__", false);
  328. editPageURLString = editPageURL.toString();
  329. editPageURLString = StringUtil.replace(
  330. editPageURLString, "__REPLACEMENT__", "$1");
  331. }
  332. Matcher matcher = _editPageURLPattern.matcher(content);
  333. content = _convertURLs(editPageURLString, matcher);
  334. String viewPageURLString = StringPool.BLANK;
  335. if (viewPageURL != null) {
  336. liferayViewPageURL.setParameter("title", "__REPLACEMENT__", false);
  337. viewPageURLString = viewPageURL.toString();
  338. viewPageURLString = StringUtil.replace(
  339. viewPageURLString, "__REPLACEMENT__", "$1");
  340. }
  341. matcher = _viewPageURLPattern.matcher(content);
  342. content = _convertURLs(viewPageURLString, matcher);
  343. content = _replaceAttachments(
  344. content, page.getTitle(), attachmentURLPrefix);
  345. return content;
  346. }
  347. private String _convertURLs(String url, Matcher matcher) {
  348. StringBuffer sb = new StringBuffer();
  349. while (matcher.find()) {
  350. String replacement = null;
  351. if (matcher.groupCount() >= 1) {
  352. String encodedTitle = HttpUtil.encodeURL(matcher.group(1));
  353. replacement = url.replace("$1", encodedTitle);
  354. }
  355. else {
  356. replacement = url;
  357. }
  358. matcher.appendReplacement(sb, replacement);
  359. }
  360. return matcher.appendTail(sb).toString();
  361. }
  362. private String _getEditPage(String format) {
  363. return PropsUtil.get(
  364. PropsKeys.WIKI_FORMATS_EDIT_PAGE, new Filter(format));
  365. }
  366. private WikiEngine _getEngine(String format) throws WikiFormatException {
  367. WikiEngine engine = _engines.get(format);
  368. if (engine != null) {
  369. return engine;
  370. }
  371. synchronized (_engines) {
  372. engine = _engines.get(format);
  373. if (engine != null) {
  374. return engine;
  375. }
  376. try {
  377. String engineClass = PropsUtil.get(
  378. PropsKeys.WIKI_FORMATS_ENGINE, new Filter(format));
  379. if (engineClass == null) {
  380. throw new WikiFormatException(format);
  381. }
  382. if (!InstancePool.contains(engineClass)) {
  383. engine = (WikiEngine)InstancePool.get(engineClass);
  384. engine.setMainConfiguration(
  385. _readConfigurationFile(
  386. PropsKeys.WIKI_FORMATS_CONFIGURATION_MAIN, format));
  387. engine.setInterWikiConfiguration(
  388. _readConfigurationFile(
  389. PropsKeys.WIKI_FORMATS_CONFIGURATION_INTERWIKI,
  390. format));
  391. }
  392. else {
  393. engine = (WikiEngine)InstancePool.get(engineClass);
  394. }
  395. _engines.put(format, engine);
  396. return engine;
  397. }
  398. catch (Exception e) {
  399. throw new WikiFormatException(e);
  400. }
  401. }
  402. }
  403. private String _getHelpPage(String format) {
  404. return PropsUtil.get(
  405. PropsKeys.WIKI_FORMATS_HELP_PAGE, new Filter(format));
  406. }
  407. private String _getHelpURL(String format) {
  408. return PropsUtil.get(
  409. PropsKeys.WIKI_FORMATS_HELP_URL, new Filter(format));
  410. }
  411. private Map<String, Boolean> _getLinks(WikiPage page)
  412. throws PageContentException {
  413. try {
  414. return _getEngine(page.getFormat()).getOutgoingLinks(page);
  415. }
  416. catch (WikiFormatException wfe) {
  417. return Collections.emptyMap();
  418. }
  419. }
  420. private String _getSummary(WikiPage page) throws WikiFormatException {
  421. WikiEngine engine = _getEngine(page.getFormat());
  422. String content = null;
  423. try {
  424. content = engine.convert(page, null, null, null);
  425. content = HtmlUtil.stripHtml(content);
  426. }
  427. catch (Exception e) {
  428. content = null;
  429. }
  430. return content;
  431. }
  432. private String _readConfigurationFile(String propertyName, String format)
  433. throws IOException {
  434. ClassLoader classLoader = getClass().getClassLoader();
  435. String configurationFile = PropsUtil.get(
  436. propertyName, new Filter(format));
  437. if (Validator.isNotNull(configurationFile)) {
  438. return HttpUtil.URLtoString(
  439. classLoader.getResource(configurationFile));
  440. }
  441. else {
  442. return StringPool.BLANK;
  443. }
  444. }
  445. private String _replaceAttachments(
  446. String content, String title, String attachmentURLPrefix) {
  447. content = StringUtil.replace(content, "[$WIKI_PAGE_NAME$]", title);
  448. content = StringUtil.replace(
  449. content, "[$ATTACHMENT_URL_PREFIX$]", attachmentURLPrefix);
  450. return content;
  451. }
  452. private boolean _validate(long nodeId, String content, String format)
  453. throws WikiFormatException {
  454. return _getEngine(format).validate(nodeId, content);
  455. }
  456. private static final String _WIKI_FRIENDLY_URL_MAPPING = "-/wiki/";
  457. private static WikiUtil _instance = new WikiUtil();
  458. private static Pattern _editPageURLPattern = Pattern.compile(
  459. "\\[\\$BEGIN_PAGE_TITLE_EDIT\\$\\](.*?)" +
  460. "\\[\\$END_PAGE_TITLE_EDIT\\$\\]");
  461. private static Pattern _viewPageURLPattern = Pattern.compile(
  462. "\\[\\$BEGIN_PAGE_TITLE\\$\\](.*?)\\[\\$END_PAGE_TITLE\\$\\]");
  463. private Map<String, WikiEngine> _engines =
  464. new ConcurrentHashMap<String, WikiEngine>();
  465. }