]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19050 update RuleDto to add characteristics
authorBenjamin Campomenosi <benjamin.campomenosi@sonarsource.com>
Fri, 14 Apr 2023 10:11:57 +0000 (12:11 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 24 Apr 2023 20:04:24 +0000 (20:04 +0000)
16 files changed:
build.gradle
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverter.java [new file with mode: 0644]
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml
server/sonar-db-dao/src/schema/schema-sq.ddl
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverterTest.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRules.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest/schema.sql [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java
sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java
sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRuleTest.java

index 467cd1a993560705fd9538903e3a46e2a98ad28a..a2ecef603ccb995eca2c50833e5b6dce75377a9d 100644 (file)
@@ -215,8 +215,8 @@ subprojects {
       dependency 'org.sonarsource.kotlin:sonar-kotlin-plugin:2.13.0.2116'
       dependency 'org.sonarsource.slang:sonar-ruby-plugin:1.12.0.4259'
       dependency 'org.sonarsource.slang:sonar-scala-plugin:1.12.0.4259'
-      dependency "org.sonarsource.api.plugin:sonar-plugin-api:$pluginApiVersion"
-      dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:$pluginApiVersion"
+      dependency "org.sonarsource.api.plugin:sonar-plugin-api:9.16.0.500"
+      dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:9.16.0.500"
       dependency 'org.sonarsource.xml:sonar-xml-plugin:2.7.0.3820'
       dependency 'org.sonarsource.iac:sonar-iac-plugin:1.15.0.3752'
       dependency 'org.sonarsource.text:sonar-text-plugin:2.0.2.1090'
index d88245d7486615b9d81ada79d7e898d55af77bb7..5afe149cc34fb6b9c1a2c0c2ded6c970df5ce159 100644 (file)
@@ -33,6 +33,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -40,6 +41,7 @@ import static java.util.Arrays.asList;
 import static java.util.Collections.emptySet;
 import static java.util.Optional.ofNullable;
 import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
+import static org.sonar.db.rule.RuleTypeToRuleCharacteristicConverter.convertToRuleCharacteristic;
 
 public class RuleDto {
 
@@ -98,6 +100,7 @@ public class RuleDto {
   private String systemTagsField = null;
   private String securityStandardsField = null;
   private int type = 0;
+  private RuleCharacteristic characteristic = null;
   private Scope scope = null;
 
   private RuleKey key = null;
@@ -241,7 +244,7 @@ public class RuleDto {
     return deserializeStringSet(educationPrinciplesField);
   }
 
-  public RuleDto setEducationPrinciples(Set<String> educationPrinciples){
+  public RuleDto setEducationPrinciples(Set<String> educationPrinciples) {
     this.educationPrinciplesField = serializeStringSet(educationPrinciples);
     return this;
   }
@@ -395,6 +398,26 @@ public class RuleDto {
     return this;
   }
 
+  @CheckForNull
+  public RuleCharacteristic getCharacteristic() {
+    return this.characteristic;
+  }
+
+  @CheckForNull
+  public RuleCharacteristic getEffectiveCharacteristic() {
+    return characteristic != null ? characteristic : convertTypeToCharacteristic(type);
+  }
+
+  private static RuleCharacteristic convertTypeToCharacteristic(int type) {
+    RuleType ruleType = RuleType.valueOf(type);
+    return convertToRuleCharacteristic(ruleType);
+  }
+
+  public RuleDto setCharacteristic(RuleCharacteristic characteristic) {
+    this.characteristic = characteristic;
+    return this;
+  }
+
   public long getCreatedAt() {
     return createdAt;
   }
@@ -413,7 +436,6 @@ public class RuleDto {
     return this;
   }
 
-
   @CheckForNull
   public String getDefRemediationFunction() {
     return defRemediationFunction;
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverter.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverter.java
new file mode 100644 (file)
index 0000000..bd7cb27
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.rule;
+
+import org.sonar.api.rules.RuleCharacteristic;
+import org.sonar.api.rules.RuleType;
+
+public class RuleTypeToRuleCharacteristicConverter {
+
+  private RuleTypeToRuleCharacteristicConverter() {
+  }
+
+  public static RuleCharacteristic convertToRuleCharacteristic(RuleType ruleType) {
+    return switch (ruleType) {
+      case BUG -> RuleCharacteristic.ROBUST;
+      case CODE_SMELL -> RuleCharacteristic.CLEAR;
+      case SECURITY_HOTSPOT, VULNERABILITY -> RuleCharacteristic.SECURE;
+    };
+  }
+
+}
index fcd120cd8b5269384c7d28947c4fc6380a6cdbbe..ca8352d9cd809ddf41b8e2362289b2f8e09fe726 100644 (file)
@@ -39,7 +39,8 @@
     r.ad_hoc_description as "adHocDescription",
     r.ad_hoc_severity as "adHocSeverity",
     r.ad_hoc_type as "adHocType",
-    r.education_principles as "educationPrinciplesField"
+    r.education_principles as "educationPrinciplesField",
+    r.characteristic as "characteristic"
   </sql>
 
   <sql id="leftOuterJoinRulesDescriptionSections">
index 08a75b195bee4e547d856471752bb86778e25e8d..eee610da133b8304effe2bcbed7df6f95808c593 100644 (file)
@@ -873,7 +873,8 @@ CREATE TABLE "RULES"(
     "AD_HOC_DESCRIPTION" CHARACTER LARGE OBJECT,
     "AD_HOC_SEVERITY" CHARACTER VARYING(10),
     "AD_HOC_TYPE" TINYINT,
-    "EDUCATION_PRINCIPLES" CHARACTER VARYING(255)
+    "EDUCATION_PRINCIPLES" CHARACTER VARYING(255),
+    "CHARACTERISTIC" CHARACTER VARYING(20)
 );
 ALTER TABLE "RULES" ADD CONSTRAINT "PK_RULES" PRIMARY KEY("UUID");
 CREATE UNIQUE INDEX "RULES_REPO_KEY" ON "RULES"("PLUGIN_RULE_KEY" NULLS FIRST, "PLUGIN_NAME" NULLS FIRST);
index a6aec187b52811a38574bc2bc3f9413405b207f5..ce4e485ece33c75795f05498869e9113e98fcbb1 100644 (file)
 package org.sonar.db.rule;
 
 import com.google.common.collect.ImmutableSet;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.Collections;
 import java.util.Set;
 import java.util.TreeSet;
 import org.jetbrains.annotations.NotNull;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.sonar.api.rules.RuleCharacteristic;
+import org.sonar.api.rules.RuleType;
 import org.sonar.core.util.Uuids;
 
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
@@ -34,10 +41,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.sonar.db.rule.RuleDto.ERROR_MESSAGE_SECTION_ALREADY_EXISTS;
 import static org.sonar.db.rule.RuleTesting.newRule;
 
+@RunWith(DataProviderRunner.class)
 public class RuleDtoTest {
 
-
   public static final String SECTION_KEY = "section key";
+
   @Test
   public void fail_if_key_is_too_long() {
     assertThatThrownBy(() -> new RuleDto().setRuleKey(repeat("x", 250)))
@@ -178,4 +186,27 @@ public class RuleDtoTest {
       .key(section_key)
       .build();
   }
+
+  @Test
+  public void getEffectiveCharacteristic_when_noCharacteristicInitialized_should_return_dbConstantValueFromConverter() {
+    RuleDto rule = new RuleDto().setType(RuleType.BUG);
+
+    RuleCharacteristic characteristic = rule.getCharacteristic();
+    assertThat(characteristic).isNull();
+
+    RuleCharacteristic effectiveCharacteristic = rule.getEffectiveCharacteristic();
+    RuleCharacteristic expected = RuleTypeToRuleCharacteristicConverter.convertToRuleCharacteristic(RuleType.BUG);
+    assertThat(effectiveCharacteristic).isEqualTo(expected);
+  }
+
+  @Test
+  public void getEffectiveCharacteristic_when_characteristicInitialized_should_return_characteristicDbConstantValue() {
+    RuleDto rule = new RuleDto().setType(RuleType.BUG).setCharacteristic(RuleCharacteristic.COMPLIANT);
+
+    RuleCharacteristic effectiveCharacteristic = rule.getEffectiveCharacteristic();
+    RuleCharacteristic characteristic = rule.getCharacteristic();
+
+    assertThat(effectiveCharacteristic).isEqualTo(characteristic).isEqualTo(RuleCharacteristic.COMPLIANT);
+  }
+
 }
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTypeToRuleCharacteristicConverterTest.java
new file mode 100644 (file)
index 0000000..8bf53ac
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.rule;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.sonar.api.rules.RuleCharacteristic;
+import org.sonar.api.rules.RuleType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.rule.RuleTypeToRuleCharacteristicConverter.convertToRuleCharacteristic;
+
+@RunWith(DataProviderRunner.class)
+public class RuleTypeToRuleCharacteristicConverterTest {
+
+  @Test
+  @UseDataProvider("ruleTypeToRulCharacteristicData")
+  public void convertToRuleCharacteristic_when_receivedNonNullRuleType_should_convertToCorrespondingDefaultCharacteristic(RuleType type,
+    RuleCharacteristic expectedCharacteristic) {
+    assertThat(convertToRuleCharacteristic(type)).isEqualTo(expectedCharacteristic);
+  }
+
+  @DataProvider
+  public static Object[][] ruleTypeToRulCharacteristicData() {
+    return new Object[][] {
+      {RuleType.CODE_SMELL, RuleCharacteristic.CLEAR},
+      {RuleType.BUG, RuleCharacteristic.ROBUST},
+      {RuleType.VULNERABILITY, RuleCharacteristic.SECURE},
+      {RuleType.SECURITY_HOTSPOT, RuleCharacteristic.SECURE}
+    };
+  }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRules.java
new file mode 100644 (file)
index 0000000..0faddfe
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.platform.db.migration.version.v101;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class AddCharacteristicInRules extends DdlChange {
+
+  private static final String TABLE_NAME = "rules";
+  private static final String COLUMN_NAME = "characteristic";
+
+  public AddCharacteristicInRules(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    try (Connection c = getDatabase().getDataSource().getConnection()) {
+      if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, COLUMN_NAME)) {
+
+        ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder()
+          .setColumnName(COLUMN_NAME)
+          .setLimit(20)
+          .setIsNullable(true)
+          .build();
+        context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build());
+      }
+    }
+
+  }
+}
index 7434d7b35dee32489fffe1b877cfba3f0723a18e..29da7ba869840a35ceadb9c28b5c59d790fdc55d 100644 (file)
@@ -53,6 +53,6 @@ public class DbVersion101 implements DbVersion {
       .add(10_1_006, "Update value of 'is_main' in 'project_branches' table", UpdateIsMainColumnInProjectBranches.class)
       .add(10_1_007, "Alter column 'is_main' in 'project_branches' table - make it not nullable", AlterIsMainColumnInProjectBranches.class)
       .add(10_1_008, "Increase size of 'internal_properties.kee' from 20 to 40 characters", IncreaseKeeColumnSizeInInternalProperties.class)
-    ;
+      .add(10_1_009, "Add column 'characteristic' to 'rules' table", AddCharacteristicInRules.class);
   }
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest.java
new file mode 100644 (file)
index 0000000..7990ef4
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.platform.db.migration.version.v101;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class AddCharacteristicInRulesTest {
+
+  private static final String TABLE_NAME = "rules";
+  private static final String COLUMN_NAME = "characteristic";
+
+  @Rule
+  public final CoreDbTester db = CoreDbTester.createForSchema(AddCharacteristicInRulesTest.class, "schema.sql");
+
+  private final AddCharacteristicInRules underTest = new AddCharacteristicInRules(db.database());
+
+  @Test
+  public void characteristic_column_exists_with_null_value() throws SQLException {
+    db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+    underTest.execute();
+    db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 20, true);
+  }
+
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+    underTest.execute();
+    underTest.execute();
+    db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 20, true);
+  }
+
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v101/AddCharacteristicInRulesTest/schema.sql
new file mode 100644 (file)
index 0000000..06e99d2
--- /dev/null
@@ -0,0 +1,41 @@
+CREATE TABLE "RULES"(
+                        "UUID" CHARACTER VARYING(40) NOT NULL,
+                        "NAME" CHARACTER VARYING(200),
+                        "PLUGIN_RULE_KEY" CHARACTER VARYING(200) NOT NULL,
+                        "PLUGIN_KEY" CHARACTER VARYING(200),
+                        "PLUGIN_CONFIG_KEY" CHARACTER VARYING(200),
+                        "PLUGIN_NAME" CHARACTER VARYING(255) NOT NULL,
+                        "SCOPE" CHARACTER VARYING(20) NOT NULL,
+                        "PRIORITY" INTEGER,
+                        "STATUS" CHARACTER VARYING(40),
+                        "LANGUAGE" CHARACTER VARYING(20),
+                        "DEF_REMEDIATION_FUNCTION" CHARACTER VARYING(20),
+                        "DEF_REMEDIATION_GAP_MULT" CHARACTER VARYING(20),
+                        "DEF_REMEDIATION_BASE_EFFORT" CHARACTER VARYING(20),
+                        "GAP_DESCRIPTION" CHARACTER VARYING(4000),
+                        "SYSTEM_TAGS" CHARACTER VARYING(4000),
+                        "IS_TEMPLATE" BOOLEAN DEFAULT FALSE NOT NULL,
+                        "DESCRIPTION_FORMAT" CHARACTER VARYING(20),
+                        "RULE_TYPE" TINYINT,
+                        "SECURITY_STANDARDS" CHARACTER VARYING(4000),
+                        "IS_AD_HOC" BOOLEAN NOT NULL,
+                        "IS_EXTERNAL" BOOLEAN NOT NULL,
+                        "CREATED_AT" BIGINT,
+                        "UPDATED_AT" BIGINT,
+                        "TEMPLATE_UUID" CHARACTER VARYING(40),
+                        "NOTE_DATA" CHARACTER LARGE OBJECT,
+                        "NOTE_USER_UUID" CHARACTER VARYING(255),
+                        "NOTE_CREATED_AT" BIGINT,
+                        "NOTE_UPDATED_AT" BIGINT,
+                        "REMEDIATION_FUNCTION" CHARACTER VARYING(20),
+                        "REMEDIATION_GAP_MULT" CHARACTER VARYING(20),
+                        "REMEDIATION_BASE_EFFORT" CHARACTER VARYING(20),
+                        "TAGS" CHARACTER VARYING(4000),
+                        "AD_HOC_NAME" CHARACTER VARYING(200),
+                        "AD_HOC_DESCRIPTION" CHARACTER LARGE OBJECT,
+                        "AD_HOC_SEVERITY" CHARACTER VARYING(10),
+                        "AD_HOC_TYPE" TINYINT,
+                        "EDUCATION_PRINCIPLES" CHARACTER VARYING(255)
+);
+ALTER TABLE "RULES" ADD CONSTRAINT "PK_RULES" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "RULES_REPO_KEY" ON "RULES"("PLUGIN_RULE_KEY" NULLS FIRST, "PLUGIN_NAME" NULLS FIRST);
index 324097ee15d5cb725241bb8745ea540b01ec59f2..c00af6fddbb3c91da647e67a00932541cb3a7051 100644 (file)
@@ -45,6 +45,7 @@ import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.IssueComment;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.utils.Duration;
 import org.sonar.core.issue.tracking.Trackable;
@@ -55,6 +56,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
 
   private String key = null;
   private RuleType type = null;
+  private RuleCharacteristic characteristic = null;
   private String componentUuid = null;
   private String componentKey = null;
 
@@ -156,6 +158,17 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
     return this;
   }
 
+  @CheckForNull
+  @Override
+  public RuleCharacteristic characteristic() {
+    return characteristic;
+  }
+
+  public DefaultIssue setCharacteristic(RuleCharacteristic characteristic) {
+    this.characteristic = characteristic;
+    return this;
+  }
+
   /**
    * Can be null on Views or Devs
    */
index 42418950a25bf99f9823e81fd5a72270bf3c799b..d2e606bee1a6616ebe4cc5783f27ec80cdccde6b 100644 (file)
@@ -26,8 +26,8 @@ import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.NewExternalIssue;
-import org.sonar.api.code.CodeCharacteristic;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static java.lang.String.format;
@@ -39,6 +39,7 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
   private Long effort;
   private Severity severity;
   private RuleType type;
+  private RuleCharacteristic characteristic;
   private String engineId;
   private String ruleId;
 
@@ -100,9 +101,8 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
   }
 
   @CheckForNull
-  @Override
-  public CodeCharacteristic characteristic() {
-    throw new IllegalStateException("Not implemented yet");
+  public RuleCharacteristic characteristic() {
+    return characteristic;
   }
 
   @Override
@@ -133,14 +133,15 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
   }
 
   @Override
-  public DefaultExternalIssue type(RuleType type) {
-    this.type = type;
+  public DefaultExternalIssue characteristic(RuleCharacteristic characteristic) {
+    this.characteristic = characteristic;
     return this;
   }
 
   @Override
-  public NewExternalIssue characteristic(CodeCharacteristic characteristic) {
-    throw new IllegalStateException("Not implemented yet");
+  public DefaultExternalIssue type(RuleType type) {
+    this.type = type;
+    return this;
   }
 
 }
index 52a243b8fca73e4f2e610973f9e6b7923daa32fc..aefa37f67e7ab5337a6a73b5bc8ef47b2d84c5d2 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.api.batch.sensor.internal.DefaultStorable;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.rule.AdHocRule;
 import org.sonar.api.batch.sensor.rule.NewAdHocRule;
-import org.sonar.api.code.CodeCharacteristic;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static org.apache.commons.lang.StringUtils.isNotBlank;
@@ -35,6 +35,8 @@ import static org.sonar.api.utils.Preconditions.checkState;
 public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewAdHocRule {
   private Severity severity;
   private RuleType type;
+
+  private RuleCharacteristic characteristic;
   private String name;
   private String description;
   private String engineId;
@@ -97,8 +99,8 @@ public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewA
 
   @CheckForNull
   @Override
-  public CodeCharacteristic characteristic() {
-    throw new IllegalStateException("Not implemented yet");
+  public RuleCharacteristic characteristic() {
+    return characteristic;
   }
 
   @Override
@@ -132,8 +134,8 @@ public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewA
   }
 
   @Override
-  public NewAdHocRule characteristic(CodeCharacteristic characteristic) {
-    throw new IllegalStateException("Not implemented yet");
+  public DefaultAdHocRule characteristic(RuleCharacteristic characteristic) {
+    this.characteristic = characteristic;
+    return this;
   }
-
 }
index 25cb562857dcb7cf02d78e03526ebc215557fc41..46a9b8e8e466acbde6a5a60528acef17b6094174 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -69,7 +70,8 @@ public class DefaultExternalIssueTest {
       .forRule(RuleKey.of("repo", "rule"))
       .remediationEffortMinutes(10L)
       .type(RuleType.BUG)
-      .severity(Severity.BLOCKER);
+      .severity(Severity.BLOCKER)
+      .characteristic(RuleCharacteristic.SECURE);
 
     assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile);
     assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_repo", "rule"));
@@ -79,6 +81,7 @@ public class DefaultExternalIssueTest {
     assertThat(issue.remediationEffort()).isEqualTo(10L);
     assertThat(issue.type()).isEqualTo(RuleType.BUG);
     assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
+    assertThat(issue.characteristic()).isEqualTo(RuleCharacteristic.SECURE);
     assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!");
 
     issue.save();
index 945b145fedf0dd0a166347bb932a78875700e309..6ba0c8dde7b3f00efd15d5b600819f8ec8b16725 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Test;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.rule.NewAdHocRule;
+import org.sonar.api.rules.RuleCharacteristic;
 import org.sonar.api.rules.RuleType;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -42,8 +43,9 @@ public class DefaultAdHocRuleTest {
       .name("name")
       .description("desc")
       .severity(Severity.BLOCKER)
-      .type(RuleType.CODE_SMELL);
-      rule.save();
+      .type(RuleType.CODE_SMELL)
+      .characteristic(RuleCharacteristic.COMPLIANT);
+    rule.save();
 
     assertThat(rule.engineId()).isEqualTo("engine");
     assertThat(rule.ruleId()).isEqualTo("ruleId");
@@ -51,11 +53,10 @@ public class DefaultAdHocRuleTest {
     assertThat(rule.description()).isEqualTo("desc");
     assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
     assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL);
-
+    assertThat(rule.characteristic()).isEqualTo(RuleCharacteristic.COMPLIANT);
     verify(storage).store(any(DefaultAdHocRule.class));
   }
 
-
   @Test
   public void description_is_optional() {
     SensorStorage storage = mock(SensorStorage.class);
@@ -118,7 +119,6 @@ public class DefaultAdHocRuleTest {
       .hasMessageContaining("Name is mandatory");
   }
 
-
   @Test
   public void fail_to_store_if_no_severity() {
     SensorStorage storage = mock(SensorStorage.class);