aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/sonar-xoo-plugin/src
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2014-07-25 16:31:45 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2014-07-30 18:03:36 +0200
commit6074164392edd3db2dfdfd21d05cd56c19e2b0e6 (patch)
treeb9314796d68c4c396dcf45a1ab689b06490fd4a2 /plugins/sonar-xoo-plugin/src
parent12f243728f42a5eb1e714ff15f0240109193f1d8 (diff)
downloadsonarqube-6074164392edd3db2dfdfd21d05cd56c19e2b0e6.tar.gz
sonarqube-6074164392edd3db2dfdfd21d05cd56c19e2b0e6.zip
SONAR-5389 New duplication API
Diffstat (limited to 'plugins/sonar-xoo-plugin/src')
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java36
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java22
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java119
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/ScmActivitySensor.java112
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java98
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java95
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooTokenizerSensor.java84
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java61
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java62
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java76
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java2
11 files changed, 765 insertions, 2 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java
new file mode 100644
index 00000000000..62f7d2ba782
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java
@@ -0,0 +1,36 @@
+/*
+ * 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.xoo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public interface XooConstants {
+
+ String PLUGIN_KEY = "xoo";
+ String PLUGIN_NAME = "Xoo";
+
+ String REPOSITORY_KEY = PLUGIN_KEY;
+ String REPOSITORY_NAME = PLUGIN_NAME;
+
+ String[] FILE_SUFFIXES = {"xoo"};
+
+ Logger LOG = LoggerFactory.getLogger("xoo");
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
index 95b65dd31a3..3477fab825c 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
@@ -20,6 +20,14 @@
package org.sonar.xoo;
import org.sonar.api.SonarPlugin;
+import org.sonar.xoo.lang.MeasureSensor;
+import org.sonar.xoo.lang.ScmActivitySensor;
+import org.sonar.xoo.lang.SymbolReferencesSensor;
+import org.sonar.xoo.lang.SyntaxHighlightingSensor;
+import org.sonar.xoo.lang.XooTokenizerSensor;
+import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
+import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor;
+import org.sonar.xoo.rule.OneIssuePerLineSensor;
import org.sonar.xoo.rule.XooQualityProfile;
import org.sonar.xoo.rule.XooRulesDefinition;
@@ -39,7 +47,19 @@ public class XooPlugin extends SonarPlugin {
return Arrays.asList(
Xoo.class,
XooRulesDefinition.class,
- XooQualityProfile.class);
+ XooQualityProfile.class,
+
+ // sensors
+ MeasureSensor.class,
+ ScmActivitySensor.class,
+ SyntaxHighlightingSensor.class,
+ SymbolReferencesSensor.class,
+ XooTokenizerSensor.class,
+
+ OneIssuePerLineSensor.class,
+ OneIssueOnDirPerFileSensor.class,
+ CreateIssueByInternalKeySensor.class
+ );
}
}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java
new file mode 100644
index 00000000000..56e013b3716
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java
@@ -0,0 +1,119 @@
+/*
+ * 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.xoo.lang;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measure.MetricFinder;
+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.measure.Measure;
+import org.sonar.api.batch.sensor.measure.MeasureBuilder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.measures
+ */
+public class MeasureSensor implements Sensor {
+
+ private static final String MEASURES_EXTENSION = ".measures";
+
+ private MetricFinder metricFinder;
+
+ public MeasureSensor(MetricFinder metricFinder) {
+ this.metricFinder = metricFinder;
+ }
+
+ private void processFileMeasures(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File measureFile = new File(ioFile.getParentFile(), ioFile.getName() + MEASURES_EXTENSION);
+ if (measureFile.exists()) {
+ XooConstants.LOG.debug("Processing " + measureFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(measureFile, context.fileSystem().encoding().name());
+ int lineNumber = 0;
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ String metricKey = StringUtils.substringBefore(line, ":");
+ String value = line.substring(metricKey.length() + 1);
+ context.addMeasure(createMeasure(context, inputFile, metricKey, value));
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + measureFile.getAbsolutePath(), e);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private Measure<?> createMeasure(SensorContext context, InputFile xooFile, String metricKey, String value) {
+ org.sonar.api.batch.measure.Metric<Serializable> metric = metricFinder.findByKey(metricKey);
+ MeasureBuilder<Serializable> builder = context.measureBuilder()
+ .forMetric(metric)
+ .onFile(xooFile);
+ if (Boolean.class.equals(metric.valueType())) {
+ builder.withValue(Boolean.parseBoolean(value));
+ } else if (Integer.class.equals(metric.valueType())) {
+ builder.withValue(Integer.valueOf(value));
+ } else if (Double.class.equals(metric.valueType())) {
+ builder.withValue(Double.valueOf(value));
+ } else if (String.class.equals(metric.valueType())) {
+ builder.withValue(value);
+ } else if (Long.class.equals(metric.valueType())) {
+ builder.withValue(Long.valueOf(value));
+ } else {
+ throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
+ }
+ return builder.build();
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Measure Sensor")
+ .provides(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ processFileMeasures(file, context);
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/ScmActivitySensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/ScmActivitySensor.java
new file mode 100644
index 00000000000..12663b0b697
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/ScmActivitySensor.java
@@ -0,0 +1,112 @@
+/*
+ * 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.xoo.lang;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.FileSystem;
+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.measures.CoreMetrics;
+import org.sonar.api.measures.FileLinesContext;
+import org.sonar.api.measures.FileLinesContextFactory;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.xoo.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+public class ScmActivitySensor implements Sensor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ScmActivitySensor.class);
+
+ private static final String SCM_EXTENSION = ".scm";
+
+ private final FileSystem fs;
+ private final FileLinesContextFactory fileLinesContextFactory;
+
+ public ScmActivitySensor(FileLinesContextFactory fileLinesContextFactory, FileSystem fileSystem) {
+ this.fs = fileSystem;
+ this.fileLinesContextFactory = fileLinesContextFactory;
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name(this.getClass().getSimpleName())
+ .provides(CoreMetrics.SCM_AUTHORS_BY_LINE,
+ CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE,
+ CoreMetrics.SCM_REVISIONS_BY_LINE)
+ .workOnLanguages(Xoo.KEY);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile inputFile : fs.inputFiles(fs.predicates().hasLanguage(Xoo.KEY))) {
+ processFile(inputFile);
+ }
+
+ }
+
+ @VisibleForTesting
+ protected void processFile(InputFile inputFile) {
+ File ioFile = inputFile.file();
+ File scmDataFile = new java.io.File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
+ if (!scmDataFile.exists()) {
+ LOG.debug("Skipping SCM data injection for " + inputFile.relativePath());
+ return;
+ }
+
+ FileLinesContext fileLinesContext = fileLinesContextFactory.createFor(inputFile);
+ try {
+ List<String> lines = FileUtils.readLines(scmDataFile, Charsets.UTF_8.name());
+ int lineNumber = 0;
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isNotBlank(line)) {
+ // revision,author,dateTime
+ String[] fields = StringUtils.split(line, ',');
+ if (fields.length < 3) {
+ throw new IllegalStateException("Not enough fields on line " + lineNumber);
+ }
+ String revision = fields[0];
+ String author = fields[1];
+ // Will throw an exception, when date is not in format "yyyy-MM-dd"
+ Date date = DateUtils.parseDate(fields[2]);
+
+ fileLinesContext.setStringValue(CoreMetrics.SCM_REVISIONS_BY_LINE_KEY, lineNumber, revision);
+ fileLinesContext.setStringValue(CoreMetrics.SCM_AUTHORS_BY_LINE_KEY, lineNumber, author);
+ fileLinesContext.setStringValue(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY, lineNumber, DateUtils.formatDateTime(date));
+ }
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ fileLinesContext.save();
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java
new file mode 100644
index 00000000000..c8cafc2d705
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java
@@ -0,0 +1,98 @@
+/*
+ * 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.xoo.lang;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+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.symbol.Symbol;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.symbol
+ */
+public class SymbolReferencesSensor implements Sensor {
+
+ private static final String SYMBOL_EXTENSION = ".symbol";
+
+ private void processFileHighlighting(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File symbolFile = new File(ioFile.getParentFile(), ioFile.getName() + SYMBOL_EXTENSION);
+ if (symbolFile.exists()) {
+ XooConstants.LOG.debug("Processing " + symbolFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(symbolFile, context.fileSystem().encoding().name());
+ int lineNumber = 0;
+ SymbolTableBuilder symbolTableBuilder = context.symbolTableBuilder(inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(",").split(line).iterator();
+ int startOffset = Integer.parseInt(split.next());
+ int endOffset = Integer.parseInt(split.next());
+ Symbol s = symbolTableBuilder.newSymbol(startOffset, endOffset);
+ while (split.hasNext()) {
+ symbolTableBuilder.newReference(s, Integer.parseInt(split.next()));
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + symbolFile.getAbsolutePath(), e);
+ }
+ }
+ symbolTableBuilder.done();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Symbol Reference Sensor")
+ .provides(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ processFileHighlighting(file, context);
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java
new file mode 100644
index 00000000000..0ae23954442
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java
@@ -0,0 +1,95 @@
+/*
+ * 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.xoo.lang;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+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.highlighting.HighlightingBuilder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.highlighting
+ */
+public class SyntaxHighlightingSensor implements Sensor {
+
+ private static final String HIGHLIGHTING_EXTENSION = ".highlighting";
+
+ private void processFileHighlighting(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File highlightingFile = new File(ioFile.getParentFile(), ioFile.getName() + HIGHLIGHTING_EXTENSION);
+ if (highlightingFile.exists()) {
+ XooConstants.LOG.debug("Processing " + highlightingFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(highlightingFile, context.fileSystem().encoding().name());
+ int lineNumber = 0;
+ HighlightingBuilder highlightingBuilder = context.highlightingBuilder(inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(":").split(line).iterator();
+ int startOffset = Integer.parseInt(split.next());
+ int endOffset = Integer.parseInt(split.next());
+ HighlightingBuilder.TypeOfText type = HighlightingBuilder.TypeOfText.forCssClass(split.next());
+ highlightingBuilder.highlight(startOffset, endOffset, type);
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + highlightingFile.getAbsolutePath(), e);
+ }
+ }
+ highlightingBuilder.done();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Highlighting Sensor")
+ .provides(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ processFileHighlighting(file, context);
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooTokenizerSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooTokenizerSensor.java
new file mode 100644
index 00000000000..1ee33e560ef
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooTokenizerSensor.java
@@ -0,0 +1,84 @@
+/*
+ * 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.xoo.lang;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.apache.commons.io.FileUtils;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.FilePredicates;
+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.duplication.TokenBuilder;
+import org.sonar.xoo.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.highlighting
+ */
+public class XooTokenizerSensor implements Sensor {
+
+ private void computeTokens(InputFile inputFile, SensorContext context) {
+ TokenBuilder tokenBuilder = context.tokenBuilder(inputFile);
+ File ioFile = inputFile.file();
+ int lineId = 0;
+ try {
+ for (String line : FileUtils.readLines(ioFile)) {
+ lineId++;
+ for (String token : Splitter.on(" ").split(line)) {
+ tokenBuilder.addToken(lineId, token);
+ }
+ }
+ tokenBuilder.done();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to read file " + ioFile, e);
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Tokenizer Sensor")
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ String[] cpdExclusions = context.settings().getStringArray(CoreProperties.CPD_EXCLUSIONS);
+ FilePredicates p = context.fileSystem().predicates();
+ List<InputFile> sourceFiles = Lists.newArrayList(context.fileSystem().inputFiles(p.and(
+ p.hasType(InputFile.Type.MAIN),
+ p.hasLanguage(Xoo.KEY),
+ p.doesNotMatchPathPatterns(cpdExclusions)
+ )));
+ if (sourceFiles.isEmpty()) {
+ return;
+ }
+ for (InputFile file : sourceFiles) {
+ computeTokens(file, context);
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
new file mode 100644
index 00000000000..c3e7d2641e6
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
@@ -0,0 +1,61 @@
+/*
+ * 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.xoo.rule;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.rule.ActiveRule;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+public class CreateIssueByInternalKeySensor implements Sensor {
+
+ private static final String INTERNAL_KEY_PROPERTY = "sonar.xoo.internalKey";
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("CreateIssueByInternalKeySensor")
+ .workOnLanguages(Xoo.KEY)
+ .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ createIssues(file, context);
+ }
+ }
+
+ private void createIssues(InputFile file, SensorContext context) {
+ ActiveRule rule = context.activeRules().findByInternalKey(XooConstants.REPOSITORY_KEY,
+ context.settings().getString(INTERNAL_KEY_PROPERTY));
+ if (rule != null) {
+ context.addIssue(context.issueBuilder()
+ .ruleKey(rule.ruleKey())
+ .onFile(file)
+ .message("This issue is generated on each file")
+ .build());
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
new file mode 100644
index 00000000000..c2478830975
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.xoo.rule;
+
+import org.sonar.api.batch.fs.InputDir;
+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.rule.RuleKey;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+public class OneIssueOnDirPerFileSensor implements Sensor {
+
+ public static final String RULE_KEY = "OneIssueOnDirPerFile";
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("One Issue On Dir Per File")
+ .workOnLanguages(Xoo.KEY)
+ .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ createIssues(file, context);
+ }
+ }
+
+ private void createIssues(InputFile file, SensorContext context) {
+ RuleKey ruleKey = RuleKey.of(XooConstants.REPOSITORY_KEY, RULE_KEY);
+ InputDir inputDir = context.fileSystem().inputDir(file.file().getParentFile());
+ if (inputDir != null) {
+ context.addIssue(context.issueBuilder()
+ .ruleKey(ruleKey)
+ .onDir(inputDir)
+ .message("This issue is generated for file " + file.relativePath())
+ .build());
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
new file mode 100644
index 00000000000..bc0697b64b4
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.xoo.rule;
+
+import org.slf4j.LoggerFactory;
+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;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooConstants;
+
+public class OneIssuePerLineSensor implements Sensor {
+
+ public static final String RULE_KEY = "OneIssuePerLine";
+ private static final String EFFORT_TO_FIX_PROPERTY = "sonar.oneIssuePerLine.effortToFix";
+ private static final String FORCE_SEVERITY_PROPERTY = "sonar.oneIssuePerLine.forceSeverity";
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("One Issue Per Line")
+ .dependsOn(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ createIssues(file, context);
+ }
+ }
+
+ private void createIssues(InputFile file, SensorContext context) {
+ RuleKey ruleKey = RuleKey.of(XooConstants.REPOSITORY_KEY, RULE_KEY);
+ Measure<Integer> linesMeasure = context.getMeasure(file, CoreMetrics.LINES);
+ 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(issueBuilder
+ .ruleKey(ruleKey)
+ .onFile(file)
+ .atLine(line)
+ .effortToFix(context.settings().getDouble(EFFORT_TO_FIX_PROPERTY))
+ .severity(context.settings().getString(FORCE_SEVERITY_PROPERTY))
+ .message("This issue is generated on each line")
+ .build());
+ }
+ }
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
index b65ad573daa..bfe1fd99afa 100644
--- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
+++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
@@ -27,6 +27,6 @@ public class XooPluginTest {
@Test
public void provide_extensions() {
- assertThat(new XooPlugin().getExtensions()).hasSize(3);
+ assertThat(new XooPlugin().getExtensions()).hasSize(11);
}
}