From 1c56d9b8abc3c2a6dc2fdb93221b0dbc36c2c850 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Mon, 1 Dec 2014 17:48:01 +0100 Subject: [PATCH] SONAR-5871 Add duplication data to lines WS --- .../sonar/server/source/index/SourceLineDoc.java | 10 ++++++++++ .../source/index/SourceLineIndexDefinition.java | 2 ++ .../source/index/SourceLineResultSetIterator.java | 14 ++++++++++++++ .../org/sonar/server/source/ws/LinesAction.java | 7 +++++-- .../server/source/index/SourceLineIndexerTest.java | 9 +++++++-- .../index/SourceLineResultSetIteratorTest.java | 8 ++++---- .../sonar/server/source/ws/LinesActionTest.java | 5 +++++ .../source/index/SourceLineIndexerTest/db.xml | 2 +- .../source/ws/LinesActionTest/show_source.json | 3 ++- 9 files changed, 50 insertions(+), 10 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineDoc.java b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineDoc.java index e845c1926fc..f7235215a53 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineDoc.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineDoc.java @@ -19,6 +19,7 @@ */ package org.sonar.server.source.index; +import com.google.common.collect.ImmutableList; import org.sonar.server.search.BaseDoc; import org.sonar.server.search.BaseNormalizer; import org.sonar.server.search.IndexUtils; @@ -26,6 +27,7 @@ import org.sonar.server.search.IndexUtils; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import java.util.Collection; import java.util.Date; import java.util.Map; @@ -214,4 +216,12 @@ public class SourceLineDoc extends BaseDoc { setField(SourceLineIndexDefinition.FIELD_SYMBOLS, s); } + public Collection duplications() { + Collection duplications = getNullableField(SourceLineIndexDefinition.FIELD_DUPLICATIONS); + return duplications == null ? ImmutableList.of() : duplications; + } + + public void setDuplications(@Nullable Collection dups) { + setField(SourceLineIndexDefinition.FIELD_DUPLICATIONS, dups == null ? ImmutableList.of() : dups); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndexDefinition.java index ce10ac551bc..7bc5a70e887 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndexDefinition.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndexDefinition.java @@ -46,6 +46,7 @@ public class SourceLineIndexDefinition implements IndexDefinition { public static final String FIELD_OVERALL_CONDITIONS = "overallConditions"; public static final String FIELD_OVERALL_COVERED_CONDITIONS = "overallCoveredConditions"; public static final String FIELD_SYMBOLS = "symbols"; + public static final String FIELD_DUPLICATIONS = "duplications"; public static final String INDEX = "sourcelines"; @@ -90,6 +91,7 @@ public class SourceLineIndexDefinition implements IndexDefinition { sourceLineMapping.createShortField(FIELD_OVERALL_CONDITIONS); sourceLineMapping.createShortField(FIELD_OVERALL_COVERED_CONDITIONS); sourceLineMapping.stringFieldBuilder(FIELD_SYMBOLS).build(); + sourceLineMapping.createShortField(FIELD_DUPLICATIONS); sourceLineMapping.createDateTimeField(BaseNormalizer.UPDATED_AT_FIELD); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java index f2cd6030096..ac0c80311a4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java @@ -32,6 +32,8 @@ import org.sonar.server.db.DbClient; import org.sonar.server.db.ResultSetIterator; import org.sonar.server.db.migrations.SqlUtil; +import javax.annotation.Nullable; + import java.io.IOException; import java.io.StringReader; import java.sql.Connection; @@ -146,6 +148,7 @@ public class SourceLineResultSetIterator extends ResultSetIterator parseDuplications(@Nullable String duplications) { + List dups = Lists.newArrayList(); + if (duplications != null && !duplications.isEmpty()) { + String[] dupsStrings = duplications.split(","); + for (String dup: dupsStrings) { + dups.add(NumberUtils.toInt(dup, -1)); + } + } + return dups; + } + private Integer parseIntegerFromRecord(CSVRecord record, int column) { String cellValue = record.get(column); if (cellValue == null || cellValue.isEmpty()) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java b/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java index 1b7e12ed408..3d780801976 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java @@ -108,8 +108,11 @@ public class LinesAction implements RequestHandler { json.prop("scmDate", scmDate == null ? null : DateUtils.formatDateTime(scmDate)); json.prop("lineHits", line.overallLineHits()) .prop("conditions", line.overallConditions()) - .prop("coveredConditions", line.overallCoveredConditions()) - .endObject(); + .prop("coveredConditions", line.overallCoveredConditions()); + if (! line.duplications().isEmpty()) { + json.prop("duplicated", true); + } + json.endObject(); } json.endArray(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java index b4c16ec448c..db7f9b53701 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.source.index; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterators; import org.apache.commons.io.IOUtils; @@ -38,6 +39,7 @@ import org.sonar.test.TestUtils; import java.io.FileInputStream; import java.util.Date; +import java.util.List; import java.util.Map; import static org.fest.assertions.Assertions.assertThat; @@ -74,6 +76,7 @@ public class SourceLineIndexerTest { .setRefresh(true) .get(); + List duplications = ImmutableList.of(1, 2, 3); SourceLineDoc line1 = new SourceLineDoc(ImmutableMap.builder() .put(SourceLineIndexDefinition.FIELD_PROJECT_UUID, "abcd") .put(SourceLineIndexDefinition.FIELD_FILE_UUID, "efgh") @@ -82,6 +85,7 @@ public class SourceLineIndexerTest { .put(SourceLineIndexDefinition.FIELD_SCM_DATE, DateUtils.parseDateTime("2014-01-01T12:34:56+0100")) .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop") .put(SourceLineIndexDefinition.FIELD_SOURCE, "package org.sonar.server.source;") + .put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, duplications) .put(BaseNormalizer.UPDATED_AT_FIELD, new Date()) .build()); SourceLineResultSetIterator.SourceFile file = new SourceLineResultSetIterator.SourceFile("efgh", System.currentTimeMillis()); @@ -96,7 +100,7 @@ public class SourceLineIndexerTest { .get(); assertThat(fileSearch.getHits().getTotalHits()).isEqualTo(1L); Map fields = fileSearch.getHits().getHits()[0].sourceAsMap(); - assertThat(fields).hasSize(8); + assertThat(fields).hasSize(9); assertThat(fields).includes( MapAssert.entry(SourceLineIndexDefinition.FIELD_PROJECT_UUID, "abcd"), MapAssert.entry(SourceLineIndexDefinition.FIELD_FILE_UUID, "efgh"), @@ -104,7 +108,8 @@ public class SourceLineIndexerTest { MapAssert.entry(SourceLineIndexDefinition.FIELD_SCM_REVISION, "cafebabe"), MapAssert.entry(SourceLineIndexDefinition.FIELD_SCM_DATE, "2014-01-01T11:34:56.000Z"), MapAssert.entry(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop"), - MapAssert.entry(SourceLineIndexDefinition.FIELD_SOURCE, "package org.sonar.server.source;") + MapAssert.entry(SourceLineIndexDefinition.FIELD_SOURCE, "package org.sonar.server.source;"), + MapAssert.entry(SourceLineIndexDefinition.FIELD_DUPLICATIONS, duplications) ); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java index e86cc45328d..ccb2584b7d4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java @@ -56,10 +56,10 @@ public class SourceLineResultSetIteratorTest { public void should_generate_source_line_documents() throws Exception { db.prepareDbUnit(getClass(), "shared.xml"); PreparedStatement stmt = connection.prepareStatement("UPDATE file_sources SET data = ? WHERE id=1"); - stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,1,0,0,2,0,0,3,0,0,polop,palap,class Foo {\r\n" + - "abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,, // Empty\r\n" + - "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,}\r\n" + - "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,\r\n"); + stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,1,0,0,2,0,0,3,0,0,polop,palap,,class Foo {\r\n" + + "abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,, // Empty\r\n" + + "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,}\r\n" + + "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,\r\n"); stmt.executeUpdate(); SourceLineResultSetIterator iterator = SourceLineResultSetIterator.create(dbClient, connection, 0L); diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java index 94639b20884..9059a316e18 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.source.ws; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import org.apache.commons.lang.StringEscapeUtils; import org.elasticsearch.common.collect.Lists; @@ -100,6 +101,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3) .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2) .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1) + .put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, ImmutableList.of()) .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); SourceLineDoc line2 = new SourceLineDoc(ImmutableMap.builder() @@ -115,6 +117,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3) .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2) .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1) + .put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, ImmutableList.of(1)) .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); SourceLineDoc line3 = new SourceLineDoc(ImmutableMap.builder() @@ -130,6 +133,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3) .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2) .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1) + .put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, ImmutableList.of()) .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); when(sourceLineIndex.getLines(eq(componentUuid), anyInt(), anyInt())).thenReturn(newArrayList( @@ -173,6 +177,7 @@ public class LinesActionTest { fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, null); fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, null); fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, null); + fieldMap.put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, null); fieldMap.put(BaseNormalizer.UPDATED_AT_FIELD, new Date()); when(sourceLineIndex.getLines(fileKey, 3, 3)).thenReturn(newArrayList( new SourceLineDoc(fieldMap) diff --git a/server/sonar-server/src/test/resources/org/sonar/server/source/index/SourceLineIndexerTest/db.xml b/server/sonar-server/src/test/resources/org/sonar/server/source/index/SourceLineIndexerTest/db.xml index 9ce30d4f8e5..d8d7eed7662 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/source/index/SourceLineIndexerTest/db.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/source/index/SourceLineIndexerTest/db.xml @@ -1,6 +1,6 @@ + data="aef12a,alice,2014-04-25T12:34:56+0100,,,,,,,,,,polop,palap,1,class Foo { aef12a,alice,2014-04-25T12:34:56+0100,,,,,,,,,,polop,palap,"1,2",}" data_hash="THE_HASH" /> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json index 1ab70956af5..123ccde38e2 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json @@ -16,7 +16,8 @@ "scmRevision": "cafebabe", "lineHits": 3, "conditions": 2, - "coveredConditions": 1 + "coveredConditions": 1, + "duplicated": true }, { "code": "}", -- 2.39.5