@@ -24,6 +24,7 @@ import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.sensor.Sensor; | |||
import org.sonar.api.batch.sensor.SensorContext; | |||
import org.sonar.api.batch.sensor.SensorDescriptor; | |||
import org.sonar.api.batch.sensor.issue.IssueBuilder; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.rule.RuleKey; | |||
@@ -58,8 +59,9 @@ public class OneIssuePerLineSensor implements Sensor { | |||
if (linesMeasure == null) { | |||
LoggerFactory.getLogger(getClass()).warn("Missing measure " + CoreMetrics.LINES_KEY + " on " + file); | |||
} else { | |||
IssueBuilder issueBuilder = context.issueBuilder(); | |||
for (int line = 1; line <= (Integer) linesMeasure.value(); line++) { | |||
context.addIssue(context.issueBuilder() | |||
context.addIssue(issueBuilder | |||
.ruleKey(ruleKey) | |||
.onFile(file) | |||
.atLine(line) |
@@ -19,16 +19,15 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor; | |||
import org.sonar.api.batch.sensor.issue.Issue; | |||
import org.sonar.api.batch.sensor.issue.IssueBuilder; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import org.sonar.api.batch.sensor.measure.MeasureBuilder; | |||
import com.google.common.annotations.Beta; | |||
import org.sonar.api.batch.fs.FileSystem; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.measure.Metric; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.batch.sensor.issue.Issue; | |||
import org.sonar.api.batch.sensor.issue.IssueBuilder; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import org.sonar.api.batch.sensor.measure.MeasureBuilder; | |||
import org.sonar.api.config.Settings; | |||
import javax.annotation.CheckForNull; | |||
@@ -101,7 +100,11 @@ public interface SensorContext { | |||
/** | |||
* Add an issue. Use {@link #issueBuilder()} to create the new issue. | |||
* @return true if the new issue is registered, false if the related rule does not exist or is disabled in the Quality profile. | |||
* @return <code>true</code> if the new issue is registered, <code>false</code> if: | |||
* <ul> | |||
* <li>the rule does not exist</li> | |||
* <li>the rule is disabled in the Quality profile</li> | |||
* </ul> | |||
*/ | |||
boolean addIssue(Issue issue); | |||
@@ -48,6 +48,7 @@ public interface Issue { | |||
/** | |||
* Message of the issue. | |||
*/ | |||
@CheckForNull | |||
String message(); | |||
/** | |||
@@ -65,7 +66,7 @@ public interface Issue { | |||
/** | |||
* See constants in {@link org.sonar.api.rule.Severity}. | |||
* Can be null before issue is saved to tell to use severity configured in quality profile. | |||
* Can be null before issue is saved. Means to use severity configured in quality profile. | |||
*/ | |||
@CheckForNull | |||
String severity(); |
@@ -56,7 +56,8 @@ public interface IssueBuilder { | |||
IssueBuilder onProject(); | |||
/** | |||
* Line of the issue. Only available for {@link #onFile(InputFile)} issues. If no line is specified then issue is supposed to be global to the file. | |||
* Line of the issue. Only available for {@link #onFile(InputFile)} issues. | |||
* If no line is specified it means that issue is global to the file. | |||
*/ | |||
IssueBuilder atLine(int line); | |||
@@ -77,7 +78,7 @@ public interface IssueBuilder { | |||
IssueBuilder severity(@Nullable String severity); | |||
/** | |||
* Build the issue. | |||
* Build the issue. After call of this method the builder is cleaned and can be used to build another issue. | |||
*/ | |||
Issue build(); | |||
@@ -70,6 +70,7 @@ public class DefaultIssue implements Issue, Serializable { | |||
return ruleKey; | |||
} | |||
@CheckForNull | |||
@Override | |||
public String message() { | |||
return message; |
@@ -23,7 +23,6 @@ import com.google.common.base.Preconditions; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputPath; | |||
import org.sonar.api.batch.sensor.issue.Issue; | |||
import org.sonar.api.batch.sensor.issue.IssueBuilder; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rule.Severity; | |||
@@ -108,8 +107,21 @@ public class DefaultIssueBuilder implements IssueBuilder { | |||
} | |||
@Override | |||
public Issue build() { | |||
return new DefaultIssue(this); | |||
public DefaultIssue build() { | |||
DefaultIssue result = new DefaultIssue(this); | |||
reset(); | |||
return result; | |||
} | |||
private void reset() { | |||
key = null; | |||
onProject = false; | |||
path = null; | |||
ruleKey = null; | |||
message = null; | |||
line = null; | |||
effortToFix = null; | |||
severity = null; | |||
} | |||
} |
@@ -19,13 +19,12 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.measure; | |||
import org.sonar.api.batch.sensor.Sensor; | |||
import com.google.common.annotations.Beta; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.measure.Metric; | |||
import org.sonar.api.batch.sensor.Sensor; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.CheckForNull; | |||
import java.io.Serializable; | |||
@@ -39,7 +38,7 @@ public interface Measure<G extends Serializable> { | |||
/** | |||
* The {@link InputFile} this measure belongs to. Returns null if measure is global to the project. | |||
*/ | |||
@Nullable | |||
@CheckForNull | |||
InputFile inputFile(); | |||
Metric<G> metric(); |
@@ -19,10 +19,9 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.measure; | |||
import org.sonar.api.batch.measure.Metric; | |||
import com.google.common.annotations.Beta; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.measure.Metric; | |||
import java.io.Serializable; | |||
@@ -54,7 +53,7 @@ public interface MeasureBuilder<G extends Serializable> { | |||
MeasureBuilder<G> withValue(G value); | |||
/** | |||
* Build the measure. | |||
* Build the measure. After call of this method the builder is cleaned and can be used to build another measure. | |||
*/ | |||
Measure<G> build(); | |||
} |
@@ -19,8 +19,6 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.measure.internal; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import com.google.common.base.Preconditions; | |||
import org.apache.commons.lang.builder.EqualsBuilder; | |||
import org.apache.commons.lang.builder.HashCodeBuilder; | |||
@@ -28,8 +26,9 @@ import org.apache.commons.lang.builder.ToStringBuilder; | |||
import org.apache.commons.lang.builder.ToStringStyle; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.measure.Metric; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.CheckForNull; | |||
import java.io.Serializable; | |||
@@ -48,7 +47,7 @@ public class DefaultMeasure<G extends Serializable> implements Measure<G>, Seria | |||
this.value = builder.value; | |||
} | |||
@Nullable | |||
@CheckForNull | |||
@Override | |||
public InputFile inputFile() { | |||
return inputFile; |
@@ -19,41 +19,37 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.measure.internal; | |||
import org.sonar.api.batch.sensor.measure.MeasureBuilder; | |||
import com.google.common.base.Preconditions; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.measure.Metric; | |||
import org.sonar.api.batch.sensor.measure.MeasureBuilder; | |||
import java.io.Serializable; | |||
public class DefaultMeasureBuilder<G extends Serializable> implements MeasureBuilder<G> { | |||
Boolean onProject = null; | |||
boolean onProject = false; | |||
InputFile file; | |||
Metric<G> metric; | |||
G value; | |||
@Override | |||
public DefaultMeasureBuilder<G> onFile(InputFile inputFile) { | |||
onProject(false); | |||
Preconditions.checkNotNull(inputFile, "inputFile should be non null"); | |||
Preconditions.checkState(!this.onProject, "onProject already called"); | |||
Preconditions.checkState(this.file == null, "onFile already called"); | |||
Preconditions.checkNotNull(inputFile, "InputFile should be non null"); | |||
this.file = inputFile; | |||
return this; | |||
} | |||
@Override | |||
public DefaultMeasureBuilder<G> onProject() { | |||
onProject(true); | |||
this.file = null; | |||
Preconditions.checkState(!this.onProject, "onProject already called"); | |||
Preconditions.checkState(this.file == null, "onFile already called"); | |||
this.onProject = true; | |||
return this; | |||
} | |||
private void onProject(boolean isOnProject) { | |||
Preconditions.checkState(this.onProject == null, "onFile or onProject can be called only once"); | |||
this.onProject = isOnProject; | |||
} | |||
@Override | |||
public DefaultMeasureBuilder<G> forMetric(Metric<G> metric) { | |||
Preconditions.checkState(metric != null, "Metric already defined"); | |||
@@ -72,6 +68,15 @@ public class DefaultMeasureBuilder<G extends Serializable> implements MeasureBui | |||
@Override | |||
public DefaultMeasure<G> build() { | |||
return new DefaultMeasure<G>(this); | |||
DefaultMeasure<G> result = new DefaultMeasure<G>(this); | |||
reset(); | |||
return result; | |||
} | |||
private void reset() { | |||
onProject = false; | |||
file = null; | |||
metric = null; | |||
value = null; | |||
} | |||
} |
@@ -19,14 +19,13 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.measure.internal; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.sensor.measure.Measure; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class DefaultMeasureTest { | |||
@@ -63,7 +62,7 @@ public class DefaultMeasureTest { | |||
@Test | |||
public void not_allowed_to_call_onFile_and_onProject() { | |||
thrown.expect(IllegalStateException.class); | |||
thrown.expectMessage("onFile or onProject can be called only once"); | |||
thrown.expectMessage("onProject already called"); | |||
new DefaultMeasureBuilder<Integer>() | |||
.onProject() | |||
.onFile(new DefaultInputFile("src/Foo.php")) |