From f462e365e2fb13c79c3b077455522e5391cedda9 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Thu, 31 Jul 2014 15:47:08 +0200 Subject: [PATCH] SONAR-5513 Deprecate measure duplication_data and provide alternative to dev cockpit --- .../sonar/plugins/cpd/DefaultCpdEngine.java | 12 ++++++--- .../org/sonar/plugins/cpd/JavaCpdEngine.java | 20 ++++++++++---- .../org/sonar/plugins/cpd/CpdSensorTest.java | 4 +-- .../plugins/cpd/DefaultCpdEngineTest.java | 2 +- .../sonar/plugins/cpd/JavaCpdEngineTest.java | 26 ++++++++++++++----- .../plugins/cpd/medium/CpdMediumTest.java | 2 +- .../org/sonar/api/measures/CoreMetrics.java | 25 ++++++++++++++++++ .../sonar/api/resources/CoreMetricsTest.java | 2 +- 8 files changed, 73 insertions(+), 20 deletions(-) diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java index 33558ec898a..887c886ac1e 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java @@ -33,6 +33,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.config.Settings; +import org.sonar.api.measures.FileLinesContextFactory; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; import org.sonar.batch.duplication.BlockCache; @@ -69,18 +70,21 @@ public class DefaultCpdEngine extends CpdEngine { private final Settings settings; private final BlockCache duplicationCache; private final Project project; + private final FileLinesContextFactory contextFactory; - public DefaultCpdEngine(@Nullable Project project, IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache) { + public DefaultCpdEngine(@Nullable Project project, IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache, + FileLinesContextFactory contextFactory) { this.project = project; this.indexFactory = indexFactory; this.mappings = mappings; this.fs = fs; this.settings = settings; this.duplicationCache = duplicationCache; + this.contextFactory = contextFactory; } - public DefaultCpdEngine(IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache) { - this(null, indexFactory, mappings, fs, settings, duplicationCache); + public DefaultCpdEngine(IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache, FileLinesContextFactory contextFactory) { + this(null, indexFactory, mappings, fs, settings, duplicationCache, contextFactory); } @Override @@ -146,7 +150,7 @@ public class DefaultCpdEngine extends CpdEngine { throw new SonarException("Fail during detection of duplication for " + inputFile, e); } - JavaCpdEngine.save(context, inputFile, filtered); + JavaCpdEngine.save(context, inputFile, filtered, contextFactory); } } finally { executorService.shutdown(); diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java index 2ea908dbb27..c74f41bccc9 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java @@ -34,6 +34,8 @@ import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.duplication.DuplicationBuilder; import org.sonar.api.config.Settings; import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.FileLinesContext; +import org.sonar.api.measures.FileLinesContextFactory; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; import org.sonar.batch.duplication.DefaultDuplicationBuilder; @@ -83,16 +85,18 @@ public class JavaCpdEngine extends CpdEngine { private final FileSystem fs; private final Settings settings; private final Project project; + private final FileLinesContextFactory contextFactory; - public JavaCpdEngine(@Nullable Project project, IndexFactory indexFactory, FileSystem fs, Settings settings) { + public JavaCpdEngine(@Nullable Project project, IndexFactory indexFactory, FileSystem fs, Settings settings, FileLinesContextFactory contextFactory) { this.project = project; this.indexFactory = indexFactory; this.fs = fs; this.settings = settings; + this.contextFactory = contextFactory; } - public JavaCpdEngine(IndexFactory indexFactory, FileSystem fs, Settings settings) { - this(null, indexFactory, fs, settings); + public JavaCpdEngine(IndexFactory indexFactory, FileSystem fs, Settings settings, FileLinesContextFactory contextFactory) { + this(null, indexFactory, fs, settings, contextFactory); } @Override @@ -168,7 +172,7 @@ public class JavaCpdEngine extends CpdEngine { throw new SonarException("Fail during detection of duplication for " + inputFile, e); } - save(context, inputFile, clones); + save(context, inputFile, clones, contextFactory); } } finally { executorService.shutdown(); @@ -189,7 +193,8 @@ public class JavaCpdEngine extends CpdEngine { } } - static void save(org.sonar.api.batch.sensor.SensorContext context, InputFile inputFile, @Nullable Iterable duplications) { + static void save(org.sonar.api.batch.sensor.SensorContext context, InputFile inputFile, @Nullable Iterable duplications, + FileLinesContextFactory contextFactory) { if (duplications == null || Iterables.isEmpty(duplications)) { return; } @@ -207,6 +212,11 @@ public class JavaCpdEngine extends CpdEngine { } } } + FileLinesContext linesContext = contextFactory.createFor(inputFile); + for (int i = 1; i <= inputFile.lines(); i++) { + linesContext.setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, i, duplicatedLines.contains(i) ? 1 : 0); + } + linesContext.save(); // Save context.addMeasure(context.measureBuilder() .forMetric(CoreMetrics.DUPLICATED_FILES) diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java index 7724fa6f725..a307f859edf 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java @@ -41,8 +41,8 @@ public class CpdSensorTest { @Before public void setUp() { IndexFactory indexFactory = mock(IndexFactory.class); - sonarEngine = new JavaCpdEngine(indexFactory, null, null); - sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class)); + sonarEngine = new JavaCpdEngine(indexFactory, null, null, null); + sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class), null); settings = new Settings(new PropertyDefinitions(CpdPlugin.class)); DefaultFileSystem fs = new DefaultFileSystem(); diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java index 924aa9193c8..6410d5ddcf0 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java @@ -42,7 +42,7 @@ public class DefaultCpdEngineTest { @Before public void init() { settings = new Settings(); - engine = new DefaultCpdEngine(null, null, null, settings, mock(BlockCache.class)); + engine = new DefaultCpdEngine(null, null, null, settings, mock(BlockCache.class), null); } @Test diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java index 770688d24a9..5a0e6f65815 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java @@ -30,6 +30,8 @@ import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder; import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.FileLinesContext; +import org.sonar.api.measures.FileLinesContextFactory; import org.sonar.batch.duplication.DefaultDuplicationBuilder; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.duplications.index.CloneGroup; @@ -55,6 +57,8 @@ public class JavaCpdEngineTest { SensorContext context = mock(SensorContext.class); DeprecatedDefaultInputFile inputFile; private DefaultDuplicationBuilder duplicationBuilder; + private FileLinesContextFactory contextFactory; + private FileLinesContext linesContext; @Before public void before() throws IOException { @@ -64,21 +68,25 @@ public class JavaCpdEngineTest { duplicationBuilder = spy(new DefaultDuplicationBuilder(inputFile, duplicationCache)); when(context.duplicationBuilder(any(InputFile.class))).thenReturn(duplicationBuilder); inputFile.setFile(temp.newFile("Foo.java")); + contextFactory = mock(FileLinesContextFactory.class); + linesContext = mock(FileLinesContext.class); + when(contextFactory.createFor(inputFile)).thenReturn(linesContext); } @SuppressWarnings("unchecked") @Test public void testNothingToSave() { - JavaCpdEngine.save(context, inputFile, null); - JavaCpdEngine.save(context, inputFile, Collections.EMPTY_LIST); + JavaCpdEngine.save(context, inputFile, null, contextFactory); + JavaCpdEngine.save(context, inputFile, Collections.EMPTY_LIST, contextFactory); verifyZeroInteractions(context); } @Test public void testOneSimpleDuplicationBetweenTwoFiles() { + inputFile.setLines(300); List groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214))); - JavaCpdEngine.save(context, inputFile, groups); + JavaCpdEngine.save(context, inputFile, groups, contextFactory); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1).build()); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1).build()); @@ -88,12 +96,18 @@ public class JavaCpdEngineTest { inOrder.verify(duplicationBuilder).originBlock(5, 204); inOrder.verify(duplicationBuilder).isDuplicatedBy("key2", 15, 214); inOrder.verify(duplicationBuilder).done(); + + verify(linesContext).setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, 1, 0); + verify(linesContext).setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, 4, 0); + verify(linesContext).setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, 5, 1); + verify(linesContext).setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, 204, 1); + verify(linesContext).setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, 205, 0); } @Test public void testDuplicationOnSameFile() throws Exception { List groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key1", 0, 215, 414))); - JavaCpdEngine.save(context, inputFile, groups); + JavaCpdEngine.save(context, inputFile, groups, contextFactory); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1).build()); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2).build()); @@ -108,7 +122,7 @@ public class JavaCpdEngineTest { @Test public void testOneDuplicatedGroupInvolvingMoreThanTwoFiles() throws Exception { List groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214), new ClonePart("key3", 0, 25, 224))); - JavaCpdEngine.save(context, inputFile, groups); + JavaCpdEngine.save(context, inputFile, groups, contextFactory); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1).build()); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1).build()); @@ -126,7 +140,7 @@ public class JavaCpdEngineTest { List groups = Arrays.asList( newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214)), newCloneGroup(new ClonePart("key1", 0, 15, 214), new ClonePart("key3", 0, 15, 214))); - JavaCpdEngine.save(context, inputFile, groups); + JavaCpdEngine.save(context, inputFile, groups, contextFactory); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1).build()); verify(context).addMeasure(new DefaultMeasureBuilder().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2).build()); diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java index 21876b8f3d5..71b5288c6b3 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java @@ -103,7 +103,7 @@ public class CpdMediumTest { assertThat(result.inputFiles()).hasSize(2); // 4 measures per file - assertThat(result.measures()).hasSize(6); + assertThat(result.measures()).hasSize(8); InputFile inputFile = result.inputFiles().get(0); // One clone group diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java index dc72077af41..c88a2c18974 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java @@ -1318,6 +1318,10 @@ public final class CoreMetrics { .setOptimizedBestValue(true) .create(); + /** + * @deprecated since 4.5. Internal storage of duplication is not an API. No more available on batch side. + */ + @Deprecated public static final String DUPLICATIONS_DATA_KEY = "duplications_data"; /** @@ -1336,7 +1340,9 @@ public final class CoreMetrics { * * *

+ * @deprecated since 4.5. Internal storage of duplication is not an API. No more available on batch side. */ + @Deprecated public static final Metric DUPLICATIONS_DATA = new Metric.Builder(DUPLICATIONS_DATA_KEY, "Duplications details", Metric.ValueType.DATA) .setDescription("Duplications details") .setDirection(Metric.DIRECTION_NONE) @@ -1345,6 +1351,25 @@ public final class CoreMetrics { .setDeleteHistoricalData(true) .create(); + /** + * @since 4.5 used by dev cockpit. + */ + @Beta + public static final String DUPLICATION_LINES_DATA_KEY = "comment_lines_data"; + + /** + * Information about duplication in file. + * Key-value pairs, where key - is a number of line, and value - is an indicator of whether line is duplicated somewhere (1) or not (0). + * + * @see org.sonar.api.measures.FileLinesContext + * @since 4.5 used by dev cockpit + */ + @Beta + public static final Metric DUPLICATION_LINES_DATA = new Metric.Builder(DUPLICATION_LINES_DATA_KEY, "duplication_lines_data", Metric.ValueType.DATA) + .setHidden(true) + .setDomain(DOMAIN_DUPLICATION) + .create(); + // -------------------------------------------------------------------------------------------------------------------- // // CODING RULES diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java index 6d4156dc668..204fcfc71e6 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java @@ -32,7 +32,7 @@ public class CoreMetricsTest { @Test public void read_metrics_from_class_reflection() { List metrics = CoreMetrics.getMetrics(); - assertThat(metrics).hasSize(153); + assertThat(metrics).hasSize(154); assertThat(metrics).contains(CoreMetrics.NCLOC, CoreMetrics.DIRECTORIES); } -- 2.39.5