blob: cf10241fd226df5e6430d671f2f568d400915dfd [file] [log] [blame]
Stefan Beller6307b3d2014-11-13 17:53:03 -08001// Copyright 2014 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles;
16
17import static com.google.common.base.Preconditions.checkNotNull;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.Lists;
22
23import java.util.List;
24import java.util.Map;
25import java.util.regex.Matcher;
26import java.util.regex.Pattern;
27
28/**
29 * Converts commit message text to soy data in accordance with
30 * a commentlink rule.
31 * <p>
32 * Example:
33 * <pre>
34 * new CommentLinkInfo(
Nodir Turakulov5270eab2015-08-28 11:00:44 -070035 * Pattern.compile("bug (\d+)"),
Stefan Beller6307b3d2014-11-13 17:53:03 -080036 * "http://bugs/$1")
37 * .linkify("do something nice\n\nbug 5")
38 * </pre>
39 * <p>
40 * returns a list of soy data objects:
41 * <pre>
42 * ImmutableList.of(
43 * ImmutableMap.of("text", "do something nice\n\n"),
44 * ImmutableMap.of("text", "bug 5", "url", "http://bugs/5")
45 * )
46 * </pre>
47 */
48public class CommentLinkInfo {
49 private final Pattern pattern;
50 private final String link;
51
52 public CommentLinkInfo(Pattern pattern, String link) {
53 this.pattern = checkNotNull(pattern);
54 this.link = checkNotNull(link);
55 }
56
57 public List<Map<String, String>> linkify(String input) {
58 List<Map<String, String>> parsed = Lists.newArrayList();
59 Matcher m = pattern.matcher(input);
60 int last = 0;
61 while (m.find()) {
62 addText(parsed, input.substring(last, m.start()));
63 String text = m.group(0);
64 addLink(parsed, text, pattern.matcher(text).replaceAll(link));
65 last = m.end();
66 }
67 addText(parsed, input.substring(last));
68 return ImmutableList.copyOf(parsed);
69 }
70
71 private static void addLink(List<Map<String, String>> parts, String text, String url) {
72 parts.add(ImmutableMap.of("text", text, "url", url));
73 }
74
75 private static void addText(List<Map<String, String>> parts, String text) {
76 if (text.isEmpty()) {
77 return;
78 }
79 if (parts.isEmpty()) {
80 parts.add(ImmutableMap.of("text", text));
81 } else {
82 Map<String, String> old = parts.get(parts.size() - 1);
83 if (!old.containsKey("url")) {
84 parts.set(parts.size() - 1, ImmutableMap.of("text", old.get("text") + text));
85 } else {
86 parts.add(ImmutableMap.of("text", text));
87 }
88 }
89 }
90}