| /* |
| * Copyright 2013 gitblit.com. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.gitblit.utils; |
| |
| import java.io.IOException; |
| import java.text.MessageFormat; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.Repository; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.gitblit.IStoredSettings; |
| import com.gitblit.Keys; |
| import com.gitblit.models.RepositoryModel; |
| import com.syntevo.bugtraq.BugtraqConfig; |
| import com.syntevo.bugtraq.BugtraqFormatter; |
| import com.syntevo.bugtraq.BugtraqFormatter.OutputHandler; |
| |
| public class BugtraqProcessor { |
| |
| private final Logger logger = LoggerFactory.getLogger(getClass()); |
| |
| private final IStoredSettings settings; |
| |
| public BugtraqProcessor(IStoredSettings settings) { |
| this.settings = settings; |
| } |
| |
| /** |
| * Returns an html version of the commit message with any global or |
| * repository-specific regular expression substitution applied. |
| * |
| * This method uses the preferred renderer to transform the commit message. |
| * |
| * @param repository |
| * @param model |
| * @param text |
| * @return html version of the commit message |
| */ |
| public String processCommitMessage(Repository repository, RepositoryModel model, String text) { |
| switch (model.commitMessageRenderer) { |
| case MARKDOWN: |
| try { |
| String prepared = processTextRegex(repository, model.name, text); |
| return MarkdownUtils.transformMarkdown(prepared); |
| } catch (Exception e) { |
| logger.error("Failed to render commit message as markdown", e); |
| } |
| break; |
| default: |
| // noop |
| break; |
| } |
| |
| return processPlainCommitMessage(repository, model.name, text); |
| } |
| |
| /** |
| * Returns an html version of the commit message with any global or |
| * repository-specific regular expression substitution applied. |
| * |
| * This method assumes the commit message is plain text. |
| * |
| * @param repository |
| * @param repositoryName |
| * @param text |
| * @return html version of the commit message |
| */ |
| public String processPlainCommitMessage(Repository repository, String repositoryName, String text) { |
| String html = StringUtils.escapeForHtml(text, false); |
| html = processTextRegex(repository, repositoryName, html); |
| return StringUtils.breakLinesForHtml(html); |
| |
| } |
| |
| /** |
| * Returns an processed version of the text with any global or |
| * repository-specific regular expression substitution applied. |
| * |
| * @param repository |
| * @param repositoryName |
| * @param text |
| * @return processed version of the text |
| */ |
| public String processText(Repository repository, String repositoryName, String text) { |
| String html = processTextRegex(repository, repositoryName, text); |
| return html; |
| } |
| |
| /** |
| * Apply globally or per-repository specified regex substitutions to the |
| * text. |
| * |
| * @param repository |
| * @param repositoryName |
| * @param text |
| * @return the processed text |
| */ |
| protected String processTextRegex(Repository repository, String repositoryName, String text) { |
| Map<String, String> map = new HashMap<String, String>(); |
| // global regex keys |
| if (settings.getBoolean(Keys.regex.global, false)) { |
| for (String key : settings.getAllKeys(Keys.regex.global)) { |
| if (!key.equals(Keys.regex.global)) { |
| String subKey = key.substring(key.lastIndexOf('.') + 1); |
| map.put(subKey, settings.getString(key, "")); |
| } |
| } |
| } |
| |
| // repository-specific regex keys |
| List<String> keys = settings.getAllKeys(Keys.regex._ROOT + "." |
| + repositoryName.toLowerCase()); |
| for (String key : keys) { |
| String subKey = key.substring(key.lastIndexOf('.') + 1); |
| map.put(subKey, settings.getString(key, "")); |
| } |
| |
| for (Entry<String, String> entry : map.entrySet()) { |
| String definition = entry.getValue().trim(); |
| String[] chunks = definition.split("!!!"); |
| if (chunks.length == 2) { |
| text = text.replaceAll(chunks[0], chunks[1]); |
| } else { |
| logger.warn(entry.getKey() |
| + " improperly formatted. Use !!! to separate match from replacement: " |
| + definition); |
| } |
| } |
| |
| try { |
| // parse bugtraq repo config |
| BugtraqConfig config = BugtraqConfig.read(repository); |
| if (config != null) { |
| BugtraqFormatter formatter = new BugtraqFormatter(config); |
| StringBuilder sb = new StringBuilder(); |
| formatter.formatLogMessage(text, new BugtraqOutputHandler(sb)); |
| text = sb.toString(); |
| } |
| } catch (IOException e) { |
| logger.error(MessageFormat.format("Bugtraq config for {0} is invalid!", repositoryName), e); |
| } catch (ConfigInvalidException e) { |
| logger.error(MessageFormat.format("Bugtraq config for {0} is invalid!", repositoryName), e); |
| } |
| |
| return text; |
| } |
| |
| private class BugtraqOutputHandler implements OutputHandler { |
| |
| final StringBuilder sb; |
| |
| BugtraqOutputHandler(StringBuilder sb) { |
| this.sb = sb; |
| } |
| |
| @Override |
| public void appendText(String text) { |
| sb.append(text); |
| } |
| |
| @Override |
| public void appendLink(String name, String target) { |
| sb.append(MessageFormat.format("<a class=\"bugtraq\" href=\"{1}\" target=\"_blank\">{0}</a>", name, target)); |
| } |
| } |
| } |