import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.profiles.XMLProfileParser;
@Test
public void shouldCreateProfile() {
- ProfileDefinition sonarWay = new SonarWayProfile(new XMLProfileParser(newRuleFinder()));
+ ProfileDefinition sonarWay = new SonarWayProfile(new XMLProfileParser(newRuleFinder(), mock(MetricFinder.class)));
ValidationMessages validation = ValidationMessages.create();
RulesProfile profile = sonarWay.createProfile(validation);
assertThat(profile.getActiveRulesByRepository(CheckstyleConstants.REPOSITORY_KEY).size(), greaterThan(1));
private RuleFinder newRuleFinder() {
RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer<Rule>(){
+ when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer<Rule>() {
public Rule answer(InvocationOnMock iom) throws Throwable {
return Rule.create((String) iom.getArguments()[0], (String) iom.getArguments()[1], (String) iom.getArguments()[1]);
}
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.profiles.XMLProfileParser;
import org.sonar.api.rules.Rule;
@Test
public void shouldBeSameAsSonarWay() {
RuleFinder ruleFinder = newRuleFinder();
- SonarWayProfile sonarWay = new SonarWayProfile(new XMLProfileParser(ruleFinder));
+ SonarWayProfile sonarWay = new SonarWayProfile(new XMLProfileParser(ruleFinder, mock(MetricFinder.class)));
RulesProfile withoutFindbugs = sonarWay.createProfile(ValidationMessages.create());
RulesProfile withFindbugs = new SonarWayWithFindbugsProfile(sonarWay).createProfile(ValidationMessages.create());
assertThat(withFindbugs.getActiveRules().size(), is(withoutFindbugs.getActiveRules().size()));
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.profiles.XMLProfileParser;
public class SunConventionsProfileTest {
@Test
public void shouldCreateProfile() {
- ProfileDefinition definition = new SunConventionsProfile(new XMLProfileParser(newRuleFinder()));
+ ProfileDefinition definition = new SunConventionsProfile(new XMLProfileParser(newRuleFinder(), mock(MetricFinder.class)));
ValidationMessages validation = ValidationMessages.create();
RulesProfile sunProfile = definition.createProfile(validation);
assertThat(sunProfile.getActiveRulesByRepository(CheckstyleConstants.REPOSITORY_KEY).size(), greaterThan(1));
import org.codehaus.staxmate.in.SMHierarchicCursor;
import org.codehaus.staxmate.in.SMInputCursor;
import org.sonar.api.ServerComponent;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.utils.ValidationMessages;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+
/**
* @since 2.3
*/
public final class XMLProfileParser implements ServerComponent {
private RuleFinder ruleFinder;
+ private MetricFinder metricFinder;
- public XMLProfileParser(RuleFinder ruleFinder) {
+ public XMLProfileParser(RuleFinder ruleFinder, MetricFinder metricFinder) {
this.ruleFinder = ruleFinder;
+ this.metricFinder = metricFinder;
}
public RulesProfile parseResource(ClassLoader classloader, String xmlClassPath, ValidationMessages messages) {
SMInputCursor rulesCursor = cursor.childElementCursor("rule");
processRules(rulesCursor, profile, messages);
+ } else if (StringUtils.equals("alerts", nodeName)) {
+ SMInputCursor alertsCursor = cursor.childElementCursor("alert");
+ processAlerts(alertsCursor, profile, messages);
+
} else if (StringUtils.equals("name", nodeName)) {
profile.setName(StringUtils.trim(cursor.collectDescendantText(false)));
// just so it won't try to load DTD in if there's DOCTYPE
xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
- SMInputFactory inputFactory = new SMInputFactory(xmlFactory);
- return inputFactory;
+ return new SMInputFactory(xmlFactory);
}
private void processRules(SMInputCursor rulesCursor, RulesProfile profile, ValidationMessages messages) throws XMLStreamException {
ActiveRule activeRule = profile.activateRule(rule, priority);
for (Map.Entry<String, String> entry : parameters.entrySet()) {
if (rule.getParam(entry.getKey()) == null) {
- messages.addWarningText("The parameter '" + entry.getKey() + "' does not exist in the rule: [repository=" + repositoryKey + ", key=" + key + "]");
+ messages.addWarningText("The parameter '" + entry.getKey() + "' does not exist in the rule: [repository=" + repositoryKey
+ + ", key=" + key + "]");
} else {
activeRule.setParameter(entry.getKey(), entry.getValue());
}
}
}
+ private void processAlerts(SMInputCursor alertsCursor, RulesProfile profile, ValidationMessages messages) throws XMLStreamException {
+ while (alertsCursor.getNext() != null) {
+ SMInputCursor alertCursor = alertsCursor.childElementCursor();
+
+ String metricKey = null, operator = "", valueError = "", valueWarning = "";
+
+ while (alertCursor.getNext() != null) {
+ String nodeName = alertCursor.getLocalName();
+
+ if (StringUtils.equals("metric", nodeName)) {
+ metricKey = StringUtils.trim(alertCursor.collectDescendantText(false));
+
+ } else if (StringUtils.equals("operator", nodeName)) {
+ operator = StringUtils.trim(alertCursor.collectDescendantText(false));
+
+ } else if (StringUtils.equals("warning", nodeName)) {
+ valueWarning = StringUtils.trim(alertCursor.collectDescendantText(false));
+
+ } else if (StringUtils.equals("error", nodeName)) {
+ valueError = StringUtils.trim(alertCursor.collectDescendantText(false));
+ }
+ }
+
+ Metric metric = metricFinder.findByKey(metricKey);
+ if (metric == null) {
+ messages.addWarningText("Metric '" + metricKey + "' does not exist");
+ } else {
+ Alert alert = new Alert();
+ alert.setMetric(metric);
+ alert.setOperator(operator);
+ alert.setValueError(valueError);
+ alert.setValueWarning(valueWarning);
+ profile.getAlerts().add(alert);
+ }
+ }
+ }
}
try {
appendHeader(profile, writer);
appendRules(profile, writer);
+ appendAlerts(profile, writer);
appendFooter(writer);
} catch (IOException e) {
}
}
+ private void appendAlerts(RulesProfile profile, Writer writer) throws IOException {
+ if (!profile.getAlerts().isEmpty()) {
+ writer.append("<alerts>");
+ for (Alert alert : profile.getAlerts()) {
+ appendAlert(alert, writer);
+ }
+ writer.append("</alerts>");
+ }
+ }
+
+ private void appendAlert(Alert alert, Writer writer) throws IOException {
+ writer.append("<alert><metric>");
+ StringEscapeUtils.escapeXml(writer, alert.getMetric().getKey());
+ writer.append("</metric><operator>");
+ StringEscapeUtils.escapeXml(writer, alert.getOperator());
+ writer.append("</operator><warning>");
+ StringEscapeUtils.escapeXml(writer, alert.getValueWarning());
+ writer.append("</warning><error>");
+ StringEscapeUtils.escapeXml(writer, alert.getValueError());
+ writer.append("</error></alert>");
+ }
+
private void appendFooter(Writer writer) throws IOException {
writer.append("</profile>");
}
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
@Test
public void importProfile() throws UnsupportedEncodingException {
ValidationMessages validation = ValidationMessages.create();
- RuleFinder ruleFinder = newRuleFinder();
- RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfile.xml", validation);
+ RulesProfile profile = parse("importProfile.xml", validation);
assertThat(profile.getLanguage(), is("java"));
assertThat(profile.getName(), is("sonar way"));
@Test
public void nameAndLanguageShouldBeMandatory() throws UnsupportedEncodingException {
ValidationMessages validation = ValidationMessages.create();
- RuleFinder ruleFinder = newRuleFinder();
- RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/nameAndLanguageShouldBeMandatory.xml", validation);
+ parse("nameAndLanguageShouldBeMandatory.xml", validation);
assertThat(validation.getErrors().size(), is(2));
assertThat(validation.getErrors().get(0), containsString(""));
@Test
public void importProfileWithRuleParameters() throws UnsupportedEncodingException {
ValidationMessages validation = ValidationMessages.create();
- RuleFinder ruleFinder = newRuleFinder();
- RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfileWithRuleParameters.xml", validation);
+ RulesProfile profile = parse("importProfileWithRuleParameters.xml", validation);
assertThat(validation.hasErrors(), is(false));
assertThat(validation.hasWarnings(), is(false));
@Test
public void importProfileWithUnknownRuleParameter() throws UnsupportedEncodingException {
ValidationMessages validation = ValidationMessages.create();
- RuleFinder ruleFinder = newRuleFinder();
- RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfileWithUnknownRuleParameter.xml", validation);
+ RulesProfile profile = parse("importProfileWithUnknownRuleParameter.xml", validation);
assertThat(validation.getWarnings().size(), is(1));
ActiveRule rule = profile.getActiveRule("checkstyle", "IllegalRegexp");
assertThat(rule.getParameter("unknown"), nullValue());
}
+ @Test
+ public void importProfileWithAlerts() {
+ ValidationMessages validation = ValidationMessages.create();
+ RulesProfile profile = parse("importProfileWithAlerts.xml", validation);
+
+ assertThat(profile.getAlerts().size(), is(1));
+ Alert alert = profile.getAlerts().get(0);
+ assertThat(alert.getMetric().getKey(), is("complexity"));
+ assertThat(alert.getOperator(), is(Alert.OPERATOR_GREATER));
+ assertThat(alert.getValueWarning(), is("10"));
+ assertThat(alert.getValueError(), is("12"));
+ }
+
+ private RulesProfile parse(String resource, ValidationMessages validation) {
+ return new XMLProfileParser(newRuleFinder(), newMetricFinder())
+ .parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/" + resource, validation);
+ }
+
+ private MetricFinder newMetricFinder() {
+ MetricFinder metricFinder = mock(MetricFinder.class);
+ when(metricFinder.findByKey(anyString())).thenAnswer(new Answer<Metric>() {
+ public Metric answer(InvocationOnMock iom) throws Throwable {
+ return new Metric((String) iom.getArguments()[0]);
+ }
+ });
+ return metricFinder;
+ }
+
private RuleFinder newRuleFinder() {
RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer<Rule>() {
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Test;
+import org.sonar.api.measures.Metric;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
assertSimilarXml("/org/sonar/api/profiles/XMLProfileSerializerTest/exportRuleParameters.xml", writer.toString());
}
+ @Test
+ public void exportAlerts() throws Exception {
+ Writer writer = new StringWriter();
+ RulesProfile profile = RulesProfile.create("sonar way", "java");
+ Alert alert = new Alert();
+ alert.setMetric(new Metric("coverage"));
+ alert.setOperator(Alert.OPERATOR_SMALLER);
+ alert.setValueError("60");
+ alert.setValueWarning("80");
+ profile.getAlerts().add(alert);
+ new XMLProfileSerializer().write(profile, writer);
+
+ assertSimilarXml("/org/sonar/api/profiles/XMLProfileSerializerTest/exportAlerts.xml", writer.toString());
+ }
+
public static void assertSimilarXml(String pathToExpectedXml, String xml) throws IOException, SAXException {
InputStream stream = XMLProfileSerializerTest.class.getResourceAsStream(pathToExpectedXml);
try {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated by Sonar -->
+<profile>
+ <name>sonar way</name>
+ <language>java</language>
+ <rules>
+ <rule>
+ <repositoryKey>checkstyle</repositoryKey>
+ <key>IllegalRegexp</key>
+ <priority>CRITICAL</priority>
+ </rule>
+ </rules>
+ <alerts>
+ <alert>
+ <metric>complexity</metric>
+ <operator>></operator>
+ <error>12</error>
+ <warning>10</warning>
+ </alert>
+ </alerts>
+</profile>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated by Sonar -->
+<profile>
+ <name>sonar way</name>
+ <language>java</language>
+ <alerts>
+ <alert>
+ <metric>coverage</metric>
+ <operator><</operator>
+ <error>60</error>
+ <warning>80</warning>
+ </alert>
+ </alerts>
+</profile>
\ No newline at end of file