]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4831 Fix NPE when a requirement is attached on a root characteristic
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 28 Nov 2013 18:55:49 +0000 (19:55 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 28 Nov 2013 18:55:49 +0000 (19:55 +0100)
sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporter.java
sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporterTest.java
sonar-core/src/test/resources/org/sonar/core/technicaldebt/TechnicalDebtXMLImporterTest/ignore_requirement_on_root_characteristics.xml [new file with mode: 0644]

index 7482db5dd5ebcfb54c4875bdce0106ae3b70261b..23589dce0d0e1e068811a013b5dffd0588d56f70 100644 (file)
@@ -106,13 +106,13 @@ public class TechnicalDebtXMLImporter implements ServerExtension {
   private DefaultCharacteristic processCharacteristic(DefaultTechnicalDebtModel model, DefaultCharacteristic parent, SMInputCursor chcCursor, ValidationMessages messages,
                                                       TechnicalDebtRuleCache technicalDebtRuleCache) throws XMLStreamException {
     DefaultCharacteristic characteristic = new DefaultCharacteristic();
-    characteristic.setParent(parent);
-
     SMInputCursor cursor = chcCursor.childElementCursor();
     while (cursor.getNext() != null) {
       String node = cursor.getLocalName();
       if (StringUtils.equals(node, CHARACTERISTIC_KEY)) {
         characteristic.setKey(cursor.collectDescendantText().trim());
+        // Attached to parent only if a key is existing, otherwise characteristic with empty key can be added.
+        characteristic.setParent(parent);
 
       } else if (StringUtils.equals(node, CHARACTERISTIC_NAME)) {
         characteristic.setName(cursor.collectDescendantText().trim(), false);
@@ -124,7 +124,12 @@ public class TechnicalDebtXMLImporter implements ServerExtension {
       } else if (StringUtils.equals(node, REPOSITORY_KEY)) {
         DefaultRequirement requirement = processRequirement(model, cursor, messages, technicalDebtRuleCache);
         if (requirement != null) {
-          requirement.setCharacteristic(parent);
+          if (parent.parent() == null) {
+            messages.addWarningText("Requirement '" + requirement.ruleKey()  + "' is ignored because it's defined directly under a root characteristic.");
+          } else {
+            requirement.setCharacteristic(parent);
+            requirement.setRootCharacteristic(parent.parent());
+          }
         }
       }
     }
index 6b1e85d1a7c20be771427867ff8062bdbb1a17a5..2a606c82757460de0bfef968b0dc554ecd8600b7 100644 (file)
@@ -122,6 +122,23 @@ public class TechnicalDebtXMLImporterTest {
     assertThat(efficiency.requirements()).isEmpty();
   }
 
+  @Test
+  public void ignore_requirement_on_root_characteristics() {
+    TechnicalDebtRuleCache technicalDebtRuleCache = mockRuleCache();
+
+    String xml = getFileContent("ignore_requirement_on_root_characteristics.xml");
+
+    ValidationMessages messages = ValidationMessages.create();
+    DefaultTechnicalDebtModel sqale = new TechnicalDebtXMLImporter().importXML(xml, messages, technicalDebtRuleCache);
+
+    assertThat(messages.getWarnings()).hasSize(1);
+
+    assertThat(sqale.characteristics()).hasSize(1);
+    DefaultCharacteristic efficiency = sqale.characteristicByKey("EFFICIENCY");
+    assertThat(efficiency.requirements()).isEmpty();
+    assertThat(messages.getWarnings().get(0)).contains("checkstyle");
+  }
+
   @Test
   public void shouldBadlyFormattedImportXML() {
     TechnicalDebtRuleCache technicalDebtRuleCache = mockRuleCache();
@@ -196,6 +213,8 @@ public class TechnicalDebtXMLImporterTest {
     assertThat(requirement.function()).isEqualTo("linear");
     assertThat(requirement.factor()).isEqualTo(WorkUnit.create(3.2, "h"));
     assertThat(requirement.offset()).isEqualTo(offset);
+    assertThat(requirement.characteristic().key()).isEqualTo("MEMORY_EFFICIENCY");
+    assertThat(requirement.rootCharacteristic().key()).isEqualTo("EFFICIENCY");
   }
 
   private String getFileContent(String file) {
diff --git a/sonar-core/src/test/resources/org/sonar/core/technicaldebt/TechnicalDebtXMLImporterTest/ignore_requirement_on_root_characteristics.xml b/sonar-core/src/test/resources/org/sonar/core/technicaldebt/TechnicalDebtXMLImporterTest/ignore_requirement_on_root_characteristics.xml
new file mode 100644 (file)
index 0000000..af9e9f4
--- /dev/null
@@ -0,0 +1,19 @@
+<sqale>
+  <chc>
+    <key>EFFICIENCY</key>
+    <name>Efficiency</name>
+    <chc>
+      <rule-repo>checkstyle</rule-repo>
+      <rule-key>Regexp</rule-key>
+      <prop>
+        <key>remediationFactor</key>
+        <val>3.2</val>
+        <txt>h</txt>
+      </prop>
+      <prop>
+        <key>remediationFunction</key>
+        <txt>linear</txt>
+      </prop>
+    </chc>
+  </chc>
+</sqale>