]> source.dussan.org Git - sonarqube.git/blob
09c6611dcfe72d098362f97949b095cf1b7f4916
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.issue.notification;
21
22 import com.google.common.collect.Lists;
23 import java.io.UnsupportedEncodingException;
24 import java.net.URLEncoder;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.Locale;
28 import org.sonar.api.config.EmailSettings;
29 import org.sonar.api.i18n.I18n;
30 import org.sonar.api.notifications.Notification;
31 import org.sonar.api.rule.Severity;
32 import org.sonar.api.utils.DateUtils;
33 import org.sonar.plugins.emailnotifications.api.EmailMessage;
34 import org.sonar.plugins.emailnotifications.api.EmailTemplate;
35 import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
36
37 import static com.google.common.base.Preconditions.checkNotNull;
38
39 /**
40  * Base class to create emails for new issues
41  */
42 public abstract class AbstractNewIssuesEmailTemplate extends EmailTemplate {
43
44   protected static final char NEW_LINE = '\n';
45   protected static final String TAB = "    ";
46   protected static final String DOT = ".";
47   protected static final String COUNT = DOT + "count";
48   protected static final String LABEL = DOT + "label";
49
50   static final String FIELD_PROJECT_NAME = "projectName";
51   static final String FIELD_PROJECT_KEY = "projectKey";
52   static final String FIELD_PROJECT_DATE = "projectDate";
53   static final String FIELD_PROJECT_UUID = "projectUuid";
54   static final String FIELD_ASSIGNEE = "assignee";
55
56   protected final EmailSettings settings;
57   protected final I18n i18n;
58
59   public AbstractNewIssuesEmailTemplate(EmailSettings settings, I18n i18n) {
60     this.settings = settings;
61     this.i18n = i18n;
62   }
63
64   public static String encode(String toEncode) {
65     try {
66       return URLEncoder.encode(toEncode, "UTF-8");
67     } catch (UnsupportedEncodingException e) {
68       throw new IllegalStateException("Encoding not supported", e);
69     }
70   }
71
72   @Override
73   public EmailMessage format(Notification notification) {
74     if (shouldNotFormat(notification)) {
75       return null;
76     }
77     String projectName = checkNotNull(notification.getFieldValue(FIELD_PROJECT_NAME));
78
79     StringBuilder message = new StringBuilder();
80     message.append("Project: ").append(projectName).append(NEW_LINE).append(NEW_LINE);
81     appendSeverity(message, notification);
82     appendAssignees(message, notification);
83     appendRules(message, notification);
84     appendTags(message, notification);
85     appendComponents(message, notification);
86     appendFooter(message, notification);
87
88     return new EmailMessage()
89       .setMessageId(notification.getType() + "/" + notification.getFieldValue(FIELD_PROJECT_KEY))
90       .setSubject(subject(notification, projectName))
91       .setMessage(message.toString());
92   }
93
94   protected abstract boolean shouldNotFormat(Notification notification);
95
96   protected String subject(Notification notification, String projectName) {
97     return String.format("%s: %s new issues (new debt: %s)",
98       projectName,
99       notification.getFieldValue(Metric.SEVERITY + COUNT),
100       notification.getFieldValue(Metric.DEBT + COUNT));
101   }
102
103   private static boolean doNotHaveValue(Notification notification, Metric metric) {
104     return notification.getFieldValue(metric + DOT + "1" + LABEL) == null;
105   }
106
107   private static void genericAppendOfMetric(Metric metric, String label, StringBuilder message, Notification notification) {
108     if (doNotHaveValue(notification, metric)) {
109       return;
110     }
111
112     message
113       .append(TAB)
114       .append(label)
115       .append(NEW_LINE);
116     int i = 1;
117     while (notification.getFieldValue(metric + DOT + i + LABEL) != null && i <= 5) {
118       String name = notification.getFieldValue(metric + DOT + i + LABEL);
119       message
120         .append(TAB).append(TAB)
121         .append(name)
122         .append(": ")
123         .append(notification.getFieldValue(metric + DOT + i + COUNT))
124         .append(NEW_LINE);
125       i += 1;
126     }
127
128     message.append(NEW_LINE);
129   }
130
131   protected void appendAssignees(StringBuilder message, Notification notification) {
132     genericAppendOfMetric(Metric.ASSIGNEE, "Assignees", message, notification);
133   }
134
135   protected void appendComponents(StringBuilder message, Notification notification) {
136     genericAppendOfMetric(Metric.COMPONENT, "Most impacted files", message, notification);
137   }
138
139   protected void appendTags(StringBuilder message, Notification notification) {
140     genericAppendOfMetric(Metric.TAG, "Tags", message, notification);
141   }
142
143   protected void appendRules(StringBuilder message, Notification notification) {
144     genericAppendOfMetric(Metric.RULE, "Rules", message, notification);
145   }
146
147   protected void appendSeverity(StringBuilder message, Notification notification) {
148     message
149       .append(String.format("%s new issues (new debt: %s)",
150         notification.getFieldValue(Metric.SEVERITY + COUNT),
151         notification.getFieldValue(Metric.DEBT + COUNT)))
152       .append(NEW_LINE).append(NEW_LINE)
153       .append(TAB)
154       .append("Severity")
155       .append(NEW_LINE)
156       .append(TAB)
157       .append(TAB);
158
159     for (Iterator<String> severityIterator = Lists.reverse(Severity.ALL).iterator(); severityIterator.hasNext();) {
160       String severity = severityIterator.next();
161       String severityLabel = i18n.message(getLocale(), "severity." + severity, severity);
162       message.append(severityLabel).append(": ").append(notification.getFieldValue(Metric.SEVERITY + DOT + severity + COUNT));
163       if (severityIterator.hasNext()) {
164         message.append(TAB);
165       }
166     }
167
168     message
169       .append(NEW_LINE)
170       .append(NEW_LINE);
171   }
172
173   protected void appendFooter(StringBuilder message, Notification notification) {
174     String projectKey = notification.getFieldValue(FIELD_PROJECT_KEY);
175     String dateString = notification.getFieldValue(FIELD_PROJECT_DATE);
176     if (projectKey != null && dateString != null) {
177       Date date = DateUtils.parseDateTime(dateString);
178       String url = String.format("%s/project/issues?id=%s&createdAt=%s",
179         settings.getServerBaseURL(), encode(projectKey), encode(DateUtils.formatDateTime(date)));
180       message
181         .append("See it in SonarQube: ")
182         .append(url)
183         .append(NEW_LINE);
184     }
185   }
186
187   private static Locale getLocale() {
188     return Locale.ENGLISH;
189   }
190
191 }