/*************************GO-LICENSE-START********************************* * Copyright 2014 ThoughtWorks, Inc. * * 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. *************************GO-LICENSE-END***********************************/ package com.thoughtworks.go.domain; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class DefaultCommentRenderer implements CommentRenderer { private static final Log LOGGER = LogFactory.getLog(DefaultCommentRenderer.class); private final String link; private final String regex; public DefaultCommentRenderer(String link, String regex) { this.link = link; this.regex = regex; } public String render(String text) { if (StringUtils.isBlank(text)) { return ""; } if (regex.isEmpty() || link.isEmpty()) { Comment comment = new Comment(); comment.escapeAndAdd(text); return comment.render(); } try { java.util.regex.Matcher matcher = Pattern.compile(regex).matcher(text); int start = 0; Comment comment = new Comment(); while (hasMatch(matcher)) { comment.escapeAndAdd(text.substring(start, matcher.start())); comment.add(dynamicLink(matcher)); start = matcher.end(); } comment.escapeAndAdd(text.substring(start)); return comment.render(); } catch (PatternSyntaxException e) { LOGGER.warn(String.format("Illegal regular expression: %s - %s", regex, e.getMessage())); } return text; } private boolean hasMatch(Matcher matcher) { return matcher.find() && id(matcher) != null; } private String dynamicLink(Matcher matcher) { String linkWithRealId = StringEscapeUtils.escapeHtml(link.replace("${ID}", id(matcher))); return String.format("<a href=\"%s\" target=\"story_tracker\">%s</a>", linkWithRealId, textOnLink(matcher)); } private String textOnLink(Matcher matcher) { return StringEscapeUtils.escapeHtml(matcher.group()); } private String contentsOfFirstGroupThatMatched(Matcher matcher) { for(int i = 1; i <= matcher.groupCount(); i++) { String groupContent = matcher.group(i); if (groupContent != null) { return groupContent; } } return null; } private String id(Matcher matcher) { return matcher.groupCount() > 0 ? contentsOfFirstGroupThatMatched(matcher) : matcher.group(); } private static class Comment { private final StringBuilder buffer = new StringBuilder(); public String render() { return buffer.toString(); } public void escapeAndAdd(String text) { buffer.append(StringEscapeUtils.escapeHtml(text)); } public void add(String text) { buffer.append(text); } } }