Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
notify users when they are automatically assigned to issues - SONAR-6106
- Loading branch information
Showing
24 changed files
with
962 additions
and
315 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
188 changes: 188 additions & 0 deletions
188
...ver/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,188 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
|
|||
package org.sonar.server.issue.notification; | |||
|
|||
import com.google.common.collect.Lists; | |||
import org.sonar.api.config.EmailSettings; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.notifications.Notification; | |||
import org.sonar.api.rule.Severity; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.plugins.emailnotifications.api.EmailMessage; | |||
import org.sonar.plugins.emailnotifications.api.EmailTemplate; | |||
import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC; | |||
|
|||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.util.Date; | |||
import java.util.Iterator; | |||
import java.util.Locale; | |||
|
|||
import static com.google.common.base.Preconditions.checkNotNull; | |||
|
|||
/** | |||
* Base class to create emails for new issues | |||
*/ | |||
public abstract class AbstractNewIssuesEmailTemplate extends EmailTemplate { | |||
|
|||
protected static final char NEW_LINE = '\n'; | |||
protected static final String TAB = " "; | |||
protected static final String DOT = "."; | |||
protected static final String COUNT = DOT + "count"; | |||
protected static final String LABEL = DOT + "label"; | |||
|
|||
static final String FIELD_PROJECT_NAME = "projectName"; | |||
static final String FIELD_PROJECT_KEY = "projectKey"; | |||
static final String FIELD_PROJECT_DATE = "projectDate"; | |||
static final String FIELD_PROJECT_UUID = "projectUuid"; | |||
static final String FIELD_ASSIGNEE = "assignee"; | |||
|
|||
protected final EmailSettings settings; | |||
protected final I18n i18n; | |||
|
|||
public AbstractNewIssuesEmailTemplate(EmailSettings settings, I18n i18n) { | |||
this.settings = settings; | |||
this.i18n = i18n; | |||
} | |||
|
|||
public static String encode(String toEncode) { | |||
try { | |||
return URLEncoder.encode(toEncode, "UTF-8"); | |||
} catch (UnsupportedEncodingException e) { | |||
throw new IllegalStateException("Encoding not supported", e); | |||
} | |||
} | |||
|
|||
@Override | |||
public EmailMessage format(Notification notification) { | |||
if (shouldNotFormat(notification)) { | |||
return null; | |||
} | |||
String projectName = checkNotNull(notification.getFieldValue(FIELD_PROJECT_NAME)); | |||
|
|||
StringBuilder message = new StringBuilder(); | |||
message.append("Project: ").append(projectName).append(NEW_LINE).append(NEW_LINE); | |||
appendSeverity(message, notification); | |||
appendAssignees(message, notification); | |||
appendTags(message, notification); | |||
appendComponents(message, notification); | |||
appendFooter(message, notification); | |||
|
|||
return new EmailMessage() | |||
.setMessageId(notification.getType() + "/" + notification.getFieldValue(FIELD_PROJECT_KEY)) | |||
.setSubject(subject(notification, projectName)) | |||
.setMessage(message.toString()); | |||
} | |||
|
|||
protected abstract boolean shouldNotFormat(Notification notification); | |||
|
|||
protected String subject(Notification notification, String projectName) { | |||
return String.format("%s: %s new issues (new debt: %s)", | |||
projectName, | |||
notification.getFieldValue(METRIC.SEVERITY + COUNT), | |||
notification.getFieldValue(METRIC.DEBT + COUNT)); | |||
} | |||
|
|||
private boolean doNotHaveValue(Notification notification, METRIC metric) { | |||
return notification.getFieldValue(metric + DOT + "1" + LABEL) == null; | |||
} | |||
|
|||
private void genericAppendOfMetric(METRIC metric, String label, StringBuilder message, Notification notification) { | |||
if (doNotHaveValue(notification, metric)) { | |||
return; | |||
} | |||
|
|||
message | |||
.append(TAB) | |||
.append(label) | |||
.append(NEW_LINE); | |||
int i = 1; | |||
while (notification.getFieldValue(metric + DOT + i + LABEL) != null && i <= 5) { | |||
String name = notification.getFieldValue(metric + DOT + i + LABEL); | |||
message | |||
.append(TAB).append(TAB) | |||
.append(name) | |||
.append(": ") | |||
.append(notification.getFieldValue(metric + DOT + i + COUNT)) | |||
.append(NEW_LINE); | |||
i += 1; | |||
} | |||
|
|||
message.append(NEW_LINE); | |||
} | |||
|
|||
protected void appendAssignees(StringBuilder message, Notification notification) { | |||
genericAppendOfMetric(METRIC.ASSIGNEE, "Assignees", message, notification); | |||
} | |||
|
|||
protected void appendComponents(StringBuilder message, Notification notification) { | |||
genericAppendOfMetric(METRIC.COMPONENT, "Most impacted files", message, notification); | |||
} | |||
|
|||
protected void appendTags(StringBuilder message, Notification notification) { | |||
genericAppendOfMetric(METRIC.TAGS, "Tags", message, notification); | |||
} | |||
|
|||
protected void appendSeverity(StringBuilder message, Notification notification) { | |||
message | |||
.append(String.format("%s new issues (new debt: %s)", | |||
notification.getFieldValue(METRIC.SEVERITY + COUNT), | |||
notification.getFieldValue(METRIC.DEBT + COUNT))) | |||
.append(NEW_LINE).append(NEW_LINE) | |||
.append(TAB) | |||
.append("Severity") | |||
.append(NEW_LINE) | |||
.append(TAB) | |||
.append(TAB); | |||
|
|||
for (Iterator<String> severityIterator = Lists.reverse(Severity.ALL).iterator(); severityIterator.hasNext();) { | |||
String severity = severityIterator.next(); | |||
String severityLabel = i18n.message(getLocale(), "severity." + severity, severity); | |||
message.append(severityLabel).append(": ").append(notification.getFieldValue(METRIC.SEVERITY + DOT + severity + COUNT)); | |||
if (severityIterator.hasNext()) { | |||
message.append(TAB); | |||
} | |||
} | |||
|
|||
message | |||
.append(NEW_LINE) | |||
.append(NEW_LINE); | |||
} | |||
|
|||
protected void appendFooter(StringBuilder message, Notification notification) { | |||
String projectUuid = notification.getFieldValue(FIELD_PROJECT_UUID); | |||
String dateString = notification.getFieldValue(FIELD_PROJECT_DATE); | |||
if (projectUuid != null && dateString != null) { | |||
Date date = DateUtils.parseDateTime(dateString); | |||
String url = String.format("%s/issues/search#projectUuids=%s|createdAt=%s", | |||
settings.getServerBaseURL(), encode(projectUuid), encode(DateUtils.formatDateTime(date))); | |||
message | |||
.append("See it in SonarQube: ") | |||
.append(url) | |||
.append(NEW_LINE); | |||
} | |||
} | |||
|
|||
private Locale getLocale() { | |||
return Locale.ENGLISH; | |||
} | |||
|
|||
} |
72 changes: 72 additions & 0 deletions
72
...ar-server/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,72 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
|
|||
package org.sonar.server.issue.notification; | |||
|
|||
import org.sonar.api.config.EmailSettings; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.notifications.Notification; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC; | |||
|
|||
import java.util.Date; | |||
|
|||
/** | |||
* Creates email message for notification "my-new-issues". | |||
*/ | |||
public class MyNewIssuesEmailTemplate extends AbstractNewIssuesEmailTemplate { | |||
|
|||
public MyNewIssuesEmailTemplate(EmailSettings settings, I18n i18n) { | |||
super(settings, i18n); | |||
} | |||
|
|||
@Override | |||
protected boolean shouldNotFormat(Notification notification) { | |||
return !MyNewIssuesNotification.TYPE.equals(notification.getType()); | |||
} | |||
|
|||
@Override | |||
protected void appendAssignees(StringBuilder message, Notification notification) { | |||
// do nothing as we don't want to print assignees, it's a personalized email for one person | |||
} | |||
|
|||
@Override | |||
protected String subject(Notification notification, String projectName) { | |||
return String.format("You have %s new issues on project %s", | |||
notification.getFieldValue(METRIC.SEVERITY + COUNT), | |||
projectName); | |||
} | |||
|
|||
@Override | |||
protected void appendFooter(StringBuilder message, Notification notification) { | |||
String projectUuid = notification.getFieldValue(FIELD_PROJECT_UUID); | |||
String dateString = notification.getFieldValue(FIELD_PROJECT_DATE); | |||
String assignee = notification.getFieldValue(FIELD_ASSIGNEE); | |||
if (projectUuid != null && dateString != null && assignee != null) { | |||
Date date = DateUtils.parseDateTime(dateString); | |||
String url = String.format("%s/issues/search#projectUuids=%s|assignees=%s|createdAt=%s", | |||
settings.getServerBaseURL(), | |||
encode(projectUuid), | |||
encode(assignee), | |||
encode(DateUtils.formatDateTime(date))); | |||
message.append("See it in SonarQube: ").append(url).append(NEW_LINE); | |||
} | |||
} | |||
} |
42 changes: 42 additions & 0 deletions
42
...nar-server/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotification.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,42 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
|
|||
package org.sonar.server.issue.notification; | |||
|
|||
import org.sonar.api.utils.Durations; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.user.index.UserIndex; | |||
|
|||
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_ASSIGNEE; | |||
|
|||
public class MyNewIssuesNotification extends NewIssuesNotification { | |||
|
|||
public static final String TYPE = "my-new-issues"; | |||
|
|||
MyNewIssuesNotification(UserIndex userIndex, DbClient dbClient, Durations durations) { | |||
super(TYPE, userIndex, dbClient, durations); | |||
} | |||
|
|||
public MyNewIssuesNotification setAssignee(String assignee) { | |||
setFieldValue(FIELD_ASSIGNEE, assignee); | |||
|
|||
return this; | |||
} | |||
} |
Oops, something went wrong.