You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BugtraqProcessor.java 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright 2013 gitblit.com.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.gitblit.utils;
  17. import java.io.IOException;
  18. import java.text.MessageFormat;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.Map.Entry;
  23. import org.eclipse.jgit.errors.ConfigInvalidException;
  24. import org.eclipse.jgit.lib.Repository;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. import com.gitblit.IStoredSettings;
  28. import com.gitblit.Keys;
  29. import com.gitblit.models.RepositoryModel;
  30. import com.syntevo.bugtraq.BugtraqConfig;
  31. import com.syntevo.bugtraq.BugtraqFormatter;
  32. import com.syntevo.bugtraq.BugtraqFormatter.OutputHandler;
  33. public class BugtraqProcessor {
  34. private final Logger logger = LoggerFactory.getLogger(getClass());
  35. private final IStoredSettings settings;
  36. public BugtraqProcessor(IStoredSettings settings) {
  37. this.settings = settings;
  38. }
  39. /**
  40. * Returns an html version of the commit message with any global or
  41. * repository-specific regular expression substitution applied.
  42. *
  43. * This method uses the preferred renderer to transform the commit message.
  44. *
  45. * @param repository
  46. * @param model
  47. * @param text
  48. * @return html version of the commit message
  49. */
  50. public String processCommitMessage(Repository repository, RepositoryModel model, String text) {
  51. switch (model.commitMessageRenderer) {
  52. case MARKDOWN:
  53. try {
  54. String prepared = processTextRegex(repository, model.name, text);
  55. return MarkdownUtils.transformMarkdown(prepared);
  56. } catch (Exception e) {
  57. logger.error("Failed to render commit message as markdown", e);
  58. }
  59. break;
  60. default:
  61. // noop
  62. break;
  63. }
  64. return processPlainCommitMessage(repository, model.name, text);
  65. }
  66. /**
  67. * Returns an html version of the commit message with any global or
  68. * repository-specific regular expression substitution applied.
  69. *
  70. * This method assumes the commit message is plain text.
  71. *
  72. * @param repository
  73. * @param repositoryName
  74. * @param text
  75. * @return html version of the commit message
  76. */
  77. public String processPlainCommitMessage(Repository repository, String repositoryName, String text) {
  78. String html = StringUtils.escapeForHtml(text, false);
  79. html = processTextRegex(repository, repositoryName, html);
  80. return StringUtils.breakLinesForHtml(html);
  81. }
  82. /**
  83. * Returns an processed version of the text with any global or
  84. * repository-specific regular expression substitution applied.
  85. *
  86. * @param repository
  87. * @param repositoryName
  88. * @param text
  89. * @return processed version of the text
  90. */
  91. public String processText(Repository repository, String repositoryName, String text) {
  92. String html = processTextRegex(repository, repositoryName, text);
  93. return html;
  94. }
  95. /**
  96. * Apply globally or per-repository specified regex substitutions to the
  97. * text.
  98. *
  99. * @param repository
  100. * @param repositoryName
  101. * @param text
  102. * @return the processed text
  103. */
  104. protected String processTextRegex(Repository repository, String repositoryName, String text) {
  105. Map<String, String> map = new HashMap<String, String>();
  106. // global regex keys
  107. if (settings.getBoolean(Keys.regex.global, false)) {
  108. for (String key : settings.getAllKeys(Keys.regex.global)) {
  109. if (!key.equals(Keys.regex.global)) {
  110. String subKey = key.substring(key.lastIndexOf('.') + 1);
  111. map.put(subKey, settings.getString(key, ""));
  112. }
  113. }
  114. }
  115. // repository-specific regex keys
  116. List<String> keys = settings.getAllKeys(Keys.regex._ROOT + "."
  117. + repositoryName.toLowerCase());
  118. for (String key : keys) {
  119. String subKey = key.substring(key.lastIndexOf('.') + 1);
  120. map.put(subKey, settings.getString(key, ""));
  121. }
  122. for (Entry<String, String> entry : map.entrySet()) {
  123. String definition = entry.getValue().trim();
  124. String[] chunks = definition.split("!!!");
  125. if (chunks.length == 2) {
  126. text = text.replaceAll(chunks[0], chunks[1]);
  127. } else {
  128. logger.warn(entry.getKey()
  129. + " improperly formatted. Use !!! to separate match from replacement: "
  130. + definition);
  131. }
  132. }
  133. try {
  134. // parse bugtraq repo config
  135. BugtraqConfig config = BugtraqConfig.read(repository);
  136. if (config != null) {
  137. BugtraqFormatter formatter = new BugtraqFormatter(config);
  138. StringBuilder sb = new StringBuilder();
  139. formatter.formatLogMessage(text, new BugtraqOutputHandler(sb));
  140. text = sb.toString();
  141. }
  142. } catch (ConfigInvalidException e) {
  143. logger.warn("Bugtraq config for {} is invalid!", repositoryName, e);
  144. } catch (Exception e) {
  145. logger.warn("Failed to parse message through Bugtraq.", e);
  146. }
  147. return text;
  148. }
  149. private class BugtraqOutputHandler implements OutputHandler {
  150. final StringBuilder sb;
  151. BugtraqOutputHandler(StringBuilder sb) {
  152. this.sb = sb;
  153. }
  154. @Override
  155. public void appendText(String text) {
  156. sb.append(text);
  157. }
  158. @Override
  159. public void appendLink(String name, String target) {
  160. sb.append(MessageFormat.format("<a class=\"bugtraq\" href=\"{1}\" target=\"_blank\">{0}</a>", name, target));
  161. }
  162. }
  163. }