import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.Logs;
import java.util.Date;
}
/**
- * @see #setLineId(Integer)
+ * @return line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line
+ * @see #hasLineId()
*/
public Integer getLineId() {
return lineId;
}
/**
- * Sets the violation line. Note that numbering starts from 1.
+ * Sets the violation line.
*
+ * @param lineId line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line
* @return the current object
*/
public Violation setLineId(Integer lineId) {
- this.lineId = lineId;
+ if (lineId != null && lineId < 1) {
+ // TODO this normalization was added in 2.8, throw exception in future versions - see http://jira.codehaus.org/browse/SONAR-2386
+ Logs.INFO.warn("line must not be less than 1 - in future versions this will cause IllegalArgumentException");
+ this.lineId = null;
+ } else {
+ this.lineId = lineId;
+ }
return this;
}
+ /**
+ * @return <code>true<code> if violation belongs to concrete line
+ * @since 2.8
+ */
+ public boolean hasLineId() {
+ return lineId != null;
+ }
+
/**
* @since 2.5
*/
@Override
public boolean equals(Object obj) {
- if ( !(obj instanceof Violation)) {
+ if (!(obj instanceof Violation)) {
return false;
}
if (this == obj) {
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.rules;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class ViolationTest {
+ /**
+ * See http://jira.codehaus.org/browse/SONAR-2386
+ */
+ @Test
+ public void testLineIdContract() {
+ Violation violation = Violation.create((Rule) null, null);
+
+ violation.setLineId(null);
+ assertThat(violation.hasLineId(), is(false));
+ assertThat(violation.getLineId(), nullValue());
+
+ violation.setLineId(0);
+ assertThat(violation.hasLineId(), is(false));
+ assertThat(violation.getLineId(), nullValue());
+
+ violation.setLineId(1);
+ assertThat(violation.hasLineId(), is(true));
+ assertThat(violation.getLineId(), is(1));
+ }
+}
this.severity = priority;
}
+ /**
+ * @return line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line
+ * @see #hasLine()
+ */
public Integer getLine() {
return line;
}
public void setLine(Integer line) {
- this.line = line;
+ if (line != null && line < 1) {
+ /*
+ * This shouldn't happen, however line would be normalized to null if web service returns incorrect value (less than 1)
+ * in compliance with a contract for getLine method. Normalization added in 2.8 - see http://jira.codehaus.org/browse/SONAR-2386
+ */
+ this.line = null;
+ } else {
+ this.line = line;
+ }
+ }
+
+ /**
+ * @return <code>true<code> if violation belongs to concrete line
+ * @since 2.8
+ */
+ public boolean hasLine() {
+ return line != null;
}
public String getResourceKey() {
violation = violations.get(0);
assertThat(violation.getMessage(), is("throw java.lang.Exception"));
+ assertThat(violation.hasLine(), is(true));
assertThat(violation.getLine(), is(97));
assertThat(violation.getCreatedAt(), notNullValue());
assertThat(violation.getSeverity(), is("MAJOR"));
public void testViolationWithoutLineNumber() {
Violation violation = new ViolationUnmarshaller().toModel(loadFile("/violations/violation-without-optional-fields.json"));
assertThat(violation.getMessage(), not(nullValue()));
+ assertThat(violation.hasLine(), is(false));
assertThat(violation.getLine(), nullValue());
assertThat(violation.getCreatedAt(), nullValue());
}
assertThat(violation.isFalsePositive(), is(true));
assertThat(violation.getReviewId(), is(123L));
}
+
+ /**
+ * See http://jira.codehaus.org/browse/SONAR-2386
+ */
+ @Test
+ public void testIncorrectLine() {
+ Violation violation = new ViolationUnmarshaller().toModel(loadFile("/violations/violation-with-incorrect-line.json"));
+ assertThat(violation.hasLine(), is(false));
+ assertThat(violation.getLine(), nullValue());
+ }
}
--- /dev/null
+[
+ {
+ "message":"1 branches need to be covered by unit tests to reach the minimum threshold of 65.0% branch coverage.",
+ "line":0,
+ "priority":"MAJOR",
+ "createdAt":"2011-03-07T16:21:39+0000",
+ "rule":{
+ "key":"sqale-java:BranchCoverageCheck",
+ "name":"Insufficient branch coverage by unit tests"
+ },
+ "resource":{
+ "key":"org.codehaus.sonar.plugins:sonar-pmd-plugin:org.sonar.plugins.pmd.PmdRuleRepository",
+ "name":"PmdRuleRepository",
+ "scope":"FIL",
+ "qualifier":"CLA",
+ "language":"java"
+ }
+ }
+]