]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4908 refactor RulesDefinition API (debt functions, XML)
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 25 Mar 2014 14:50:29 +0000 (15:50 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 25 Mar 2014 15:45:32 +0000 (16:45 +0100)
28 files changed:
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java
sonar-deprecated/src/main/java/org/sonar/api/i18n/RuleI18n.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/i18n/RuleI18n.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/server/debt/DebtRemediationFunction.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunction.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunctions.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DefaultDebtRemediationFunction.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DefaultDebtRemediationFunctions.java
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleTagFormat.java
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionI18nLoader.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java
sonar-plugin-api/src/test/java/org/sonar/api/server/debt/DefaultDebtRemediationFunctionTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/DefaultDebtRemediationFunctionTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagFormatTest.java
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionI18nLoaderTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionTest.java
sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsTest/sample.html [deleted file]
sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionTest/sample.html [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java
sonar-server/src/main/java/org/sonar/server/debt/DebtModelXMLExporter.java
sonar-server/src/main/java/org/sonar/server/debt/DebtRulesXMLImporter.java
sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java
sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java
sonar-server/src/test/java/org/sonar/server/debt/DebtModelXMLExporterTest.java
sonar-server/src/test/java/org/sonar/server/debt/DebtRulesXMLImporterTest.java
sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionTest.java

index f6e8173e4447c6496b4a37df3747d9a633b9f1d1..229e07ca1471086cfb1df7a3226caa9a57041cc5 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.xoo.rule;
 
 import org.junit.Test;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.rule.RulesDefinition;
 
 import static org.fest.assertions.Assertions.assertThat;
diff --git a/sonar-deprecated/src/main/java/org/sonar/api/i18n/RuleI18n.java b/sonar-deprecated/src/main/java/org/sonar/api/i18n/RuleI18n.java
deleted file mode 100644 (file)
index 0dbcee2..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.api.i18n;
-
-import org.sonar.api.BatchComponent;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.rules.Rule;
-
-import javax.annotation.CheckForNull;
-
-import java.util.Locale;
-
-/**
- * {@link I18n}-companion component that provides translation facilities for rule names, descriptions and parameter names.
- * 
- * @since 3.2
- * @deprecated in 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
- */
-@Deprecated
-public interface RuleI18n extends ServerComponent, BatchComponent {
-
-  /**
-   * Returns the localized name of the rule identified by its repository key and rule key.
-   * <br>
-   * If the name is not found in the given locale, then the default name is returned (the English one).
-   * This method could return null if no default name found. This is the cause for instance the copies rules.
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @param locale not used
-   * @return the translated name of the rule, or the default English one if the given locale is not supported, or null
-   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
-   */
-  @Deprecated
-  @CheckForNull
-  String getName(String repositoryKey, String ruleKey, Locale locale);
-
-  /**
-   * Returns the name of the rule identified by its repository key and rule key.
-   * <br>
-   * This method could return null if no default name found. This is the cause for instance the copies rules.
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @return the nullable name of the rule
-   * @since 4.1
-   */
-  @CheckForNull
-  String getName(String repositoryKey, String ruleKey);
-
-  /**
-   * Returns the localized name or the name of the rule.
-   * <br>
-   * If the name is not found in the given locale, then the default name is returned (the English one).
-   * It the default name is not found, then the rule name is returned.
-   *
-   * @param rule the rule
-   * @param locale the locale to translate into
-   * @return the translated name of the rule, or the default English one if the given locale is not supported, or the rule name.
-   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
-   */
-  @Deprecated
-  @CheckForNull
-  String getName(Rule rule, Locale locale);
-
-  /**
-   * Returns the name of the rule.
-   * <br>
-   * It the default name is not found, then the rule name is returned.
-   *
-   * @param rule the rule
-   * @return the nullable name of the rule
-   * @since 4.1
-   */
-  @CheckForNull
-  String getName(Rule rule);
-
-  /**
-   * Returns the localized description of the rule identified by its repository key and rule key.
-   * <br>
-   * If the description is not found in the given locale, then the default description is returned (the English one).
-   * As a rule must have a description (this is a constraint in Sonar), this method never returns null.
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @param locale  the locale to translate into
-   * @return the translated description of the rule, or the default English one if the given locale is not supported
-   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
-   */
-  @Deprecated
-  String getDescription(String repositoryKey, String ruleKey, Locale locale);
-
-  /**
-   * Returns the description of the rule identified by its repository key and rule key.
-   * <br>
-   * As a rule must have a description (this is a constraint in SonarQube), this method never returns null.
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @return the description of the rule
-   * @since 4.1
-   */
-  String getDescription(String repositoryKey, String ruleKey);
-
-  /**
-   * Returns the localized name of the rule parameter identified by the rules's key and repository key, and by the parameter key.
-   * <br>
-   * If the name is not found in the given locale, then the English translation is searched and return if found. Otherwise,
-   * this method returns null (= if no translation can be found).
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @param paramKey the parameter key
-   * @param locale the locale to translate into
-   * @return the translated name of the rule parameter, or the default English one if the given locale is not supported, or null if
-   *         no translation can be found.
-   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
-   */
-  @Deprecated
-  @CheckForNull
-  String getParamDescription(String repositoryKey, String ruleKey, String paramKey, Locale locale);
-
-  /**
-   * Returns the name of the rule parameter identified by the rules's key and repository key, and by the parameter key.
-   *
-   * @param repositoryKey the repository key
-   * @param ruleKey the rule key
-   * @param paramKey the parameter key
-   * @return the nullable name of the rule parameter
-   * @since 4.1
-   */
-  @CheckForNull
-  String getParamDescription(String repositoryKey, String ruleKey, String paramKey);
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/i18n/RuleI18n.java b/sonar-plugin-api/src/main/java/org/sonar/api/i18n/RuleI18n.java
new file mode 100644 (file)
index 0000000..0dbcee2
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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.api.i18n;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.rules.Rule;
+
+import javax.annotation.CheckForNull;
+
+import java.util.Locale;
+
+/**
+ * {@link I18n}-companion component that provides translation facilities for rule names, descriptions and parameter names.
+ * 
+ * @since 3.2
+ * @deprecated in 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
+ */
+@Deprecated
+public interface RuleI18n extends ServerComponent, BatchComponent {
+
+  /**
+   * Returns the localized name of the rule identified by its repository key and rule key.
+   * <br>
+   * If the name is not found in the given locale, then the default name is returned (the English one).
+   * This method could return null if no default name found. This is the cause for instance the copies rules.
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @param locale not used
+   * @return the translated name of the rule, or the default English one if the given locale is not supported, or null
+   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
+   */
+  @Deprecated
+  @CheckForNull
+  String getName(String repositoryKey, String ruleKey, Locale locale);
+
+  /**
+   * Returns the name of the rule identified by its repository key and rule key.
+   * <br>
+   * This method could return null if no default name found. This is the cause for instance the copies rules.
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @return the nullable name of the rule
+   * @since 4.1
+   */
+  @CheckForNull
+  String getName(String repositoryKey, String ruleKey);
+
+  /**
+   * Returns the localized name or the name of the rule.
+   * <br>
+   * If the name is not found in the given locale, then the default name is returned (the English one).
+   * It the default name is not found, then the rule name is returned.
+   *
+   * @param rule the rule
+   * @param locale the locale to translate into
+   * @return the translated name of the rule, or the default English one if the given locale is not supported, or the rule name.
+   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
+   */
+  @Deprecated
+  @CheckForNull
+  String getName(Rule rule, Locale locale);
+
+  /**
+   * Returns the name of the rule.
+   * <br>
+   * It the default name is not found, then the rule name is returned.
+   *
+   * @param rule the rule
+   * @return the nullable name of the rule
+   * @since 4.1
+   */
+  @CheckForNull
+  String getName(Rule rule);
+
+  /**
+   * Returns the localized description of the rule identified by its repository key and rule key.
+   * <br>
+   * If the description is not found in the given locale, then the default description is returned (the English one).
+   * As a rule must have a description (this is a constraint in Sonar), this method never returns null.
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @param locale  the locale to translate into
+   * @return the translated description of the rule, or the default English one if the given locale is not supported
+   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
+   */
+  @Deprecated
+  String getDescription(String repositoryKey, String ruleKey, Locale locale);
+
+  /**
+   * Returns the description of the rule identified by its repository key and rule key.
+   * <br>
+   * As a rule must have a description (this is a constraint in SonarQube), this method never returns null.
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @return the description of the rule
+   * @since 4.1
+   */
+  String getDescription(String repositoryKey, String ruleKey);
+
+  /**
+   * Returns the localized name of the rule parameter identified by the rules's key and repository key, and by the parameter key.
+   * <br>
+   * If the name is not found in the given locale, then the English translation is searched and return if found. Otherwise,
+   * this method returns null (= if no translation can be found).
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @param paramKey the parameter key
+   * @param locale the locale to translate into
+   * @return the translated name of the rule parameter, or the default English one if the given locale is not supported, or null if
+   *         no translation can be found.
+   * @deprecated since 4.1. Rules are not localized anymore. See http://jira.codehaus.org/browse/SONAR-4885
+   */
+  @Deprecated
+  @CheckForNull
+  String getParamDescription(String repositoryKey, String ruleKey, String paramKey, Locale locale);
+
+  /**
+   * Returns the name of the rule parameter identified by the rules's key and repository key, and by the parameter key.
+   *
+   * @param repositoryKey the repository key
+   * @param ruleKey the rule key
+   * @param paramKey the parameter key
+   * @return the nullable name of the rule parameter
+   * @since 4.1
+   */
+  @CheckForNull
+  String getParamDescription(String repositoryKey, String ruleKey, String paramKey);
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/DebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/DebtRemediationFunction.java
new file mode 100644 (file)
index 0000000..3c8e997
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.api.server.debt;
+
+import javax.annotation.CheckForNull;
+
+/**
+ * Function used to calculate the remediation cost of an issue. There are three types :
+ * <ul>
+ * <li>
+ * <b>Linear</b> - Each issue of the rule costs the same amount of time (factor) to fix.
+ * </li>
+ * <li>
+ * <b>Linear with offset</b> - It takes a certain amount of time to analyze the issues of such kind on the file (offset).
+ * Then, each issue of the rule costs the same amount of time (factor) to fix. Total remediation cost
+ * by file = offset + (number of issues x factor)
+ * </li>
+ * <li><b>Constant/issue</b> - The cost to fix all the issues of the rule is the same whatever the number of issues
+ * of this rule in the file. Total remediation cost by file = constant
+ * </li>
+ * </ul>
+ *
+ * @since 4.3
+ */
+public interface DebtRemediationFunction {
+
+  static enum Type {
+    LINEAR, LINEAR_OFFSET, CONSTANT_ISSUE
+  }
+
+  Type type();
+
+  /**
+   * Factor is set on types {@link Type#LINEAR} and {@link Type#LINEAR_OFFSET}, else it's null.
+   */
+  @CheckForNull
+  String factor();
+
+  /**
+   * Offset is set on types {@link Type#LINEAR_OFFSET} and {@link Type#CONSTANT_ISSUE}, else it's null.
+   */
+  @CheckForNull
+  String offset();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java
new file mode 100644 (file)
index 0000000..759aef8
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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.api.server.debt.internal;
+
+import com.google.common.base.Objects;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.api.utils.Duration;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class DefaultDebtRemediationFunction implements DebtRemediationFunction {
+
+  private static final int HOURS_IN_DAY = 24;
+
+  private final Type type;
+  private final String factor;
+  private final String offset;
+
+  public DefaultDebtRemediationFunction(Type type, @Nullable String factor, @Nullable String offset) {
+    this.type = type;
+    // TODO validate factor and offset format
+    this.factor = sanitizeValue("factor", factor);
+    this.offset = sanitizeValue("offset", offset);
+    validate();
+  }
+
+  @CheckForNull
+  private String sanitizeValue(String label, @Nullable String s) {
+    if (StringUtils.isNotBlank(s)) {
+      try {
+        Duration duration = Duration.decode(s, HOURS_IN_DAY);
+        return duration.encode(HOURS_IN_DAY);
+      } catch (Exception e) {
+        throw new IllegalArgumentException(String.format("Invalid %s: %s", label, s), e);
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public Type type() {
+    return type;
+  }
+
+  @Override
+  @CheckForNull
+  public String factor() {
+    return factor;
+  }
+
+  @Override
+  @CheckForNull
+  public String offset() {
+    return offset;
+  }
+
+  private void validate() {
+    switch (type) {
+      case LINEAR:
+        if (this.factor == null || this.offset != null) {
+          throw new IllegalArgumentException(String.format("Only factor must be set on %s", this));
+        }
+        break;
+      case LINEAR_OFFSET:
+        if (this.factor == null || this.offset == null) {
+          throw new IllegalArgumentException(String.format("Both factor and offset are required on %s", this));
+        }
+        break;
+      case CONSTANT_ISSUE:
+        if (this.factor != null || this.offset == null) {
+          throw new IllegalArgumentException(String.format("Only offset must be set on %s", this));
+        }
+        break;
+      default:
+        throw new IllegalArgumentException(String.format("Unknown type on %s", this));
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    DefaultDebtRemediationFunction that = (DefaultDebtRemediationFunction) o;
+    if (factor != null ? !factor.equals(that.factor) : that.factor != null) {
+      return false;
+    }
+    if (offset != null ? !offset.equals(that.offset) : that.offset != null) {
+      return false;
+    }
+    return type == that.type;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = type.hashCode();
+    result = 31 * result + (factor != null ? factor.hashCode() : 0);
+    result = 31 * result + (offset != null ? offset.hashCode() : 0);
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return Objects.toStringHelper(DebtRemediationFunction.class)
+      .add("type", type)
+      .add("factor", factor)
+      .add("offset", offset)
+      .toString();
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunction.java
deleted file mode 100644 (file)
index d1ae702..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.api.server.rule;
-
-import javax.annotation.CheckForNull;
-
-/**
- * @since 4.3
- */
-public interface DebtRemediationFunction {
-
-  static class ValidationException extends RuntimeException {
-    public ValidationException(String message) {
-      super(message);
-    }
-  }
-
-  static enum Type {
-    LINEAR, LINEAR_OFFSET, CONSTANT_ISSUE
-  }
-
-  Type type();
-
-  @CheckForNull
-  String factor();
-
-  @CheckForNull
-  String offset();
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunctions.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DebtRemediationFunctions.java
deleted file mode 100644 (file)
index ace4b88..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.api.server.rule;
-
-/**
- * Factory of {@link org.sonar.api.server.rule.DebtRemediationFunction}
- *
- * @since 4.3
- */
-public interface DebtRemediationFunctions {
-
-  DebtRemediationFunction linear(String factor);
-
-  DebtRemediationFunction linearWithOffset(String factor, String offset);
-
-  DebtRemediationFunction constantPerIssue(String offset);
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DefaultDebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/DefaultDebtRemediationFunction.java
deleted file mode 100644 (file)
index dedf5a3..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.api.server.rule;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-class DefaultDebtRemediationFunction implements DebtRemediationFunction {
-
-  private Type type;
-  private String factor;
-  private String offset;
-
-  public DefaultDebtRemediationFunction(Type type, @Nullable String factor, @Nullable String offset) {
-    this.type = type;
-    // TODO validate factor and offset format
-    this.factor = StringUtils.deleteWhitespace(factor);
-    this.offset = StringUtils.deleteWhitespace(offset);
-    validate();
-  }
-
-  @Override
-  public Type type() {
-    return type;
-  }
-
-  @Override
-  @CheckForNull
-  public String factor() {
-    return factor;
-  }
-
-  @Override
-  @CheckForNull
-  public String offset() {
-    return offset;
-  }
-
-  private void validate() {
-    switch (type) {
-      case LINEAR:
-        if (this.factor == null || this.offset != null) {
-          throw new ValidationException(String.format("%s is invalid, Linear remediation function should only define a factor", this));
-        }
-        break;
-      case LINEAR_OFFSET:
-        if (this.factor == null || this.offset == null) {
-          throw new ValidationException(String.format("%s is invalid,  Linear with offset remediation function should define both factor and offset", this));
-        }
-        break;
-      case CONSTANT_ISSUE:
-        if (this.factor != null || this.offset == null) {
-          throw new ValidationException(String.format("%s is invalid, Constant/issue remediation function should only define an offset", this));
-        }
-        break;
-      default:
-        throw new IllegalStateException(String.format("Remediation function of %s is unknown", this));
-    }
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-
-    DebtRemediationFunction that = (DebtRemediationFunction) o;
-    return new EqualsBuilder()
-      .append(type, that.type())
-      .append(factor, that.factor())
-      .append(offset, that.offset())
-      .isEquals();
-  }
-
-  @Override
-  public int hashCode() {
-    return new HashCodeBuilder(15, 33)
-      .append(type)
-      .append(factor)
-      .append(offset)
-      .toHashCode();
-  }
-
-  @Override
-  public String toString() {
-    return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
-  }
-}
index befa7907095172d4f27957c7eb02e6b02c3277cf..a2fa542e6ddc90ece0df5c1907aff6d26a30cf38 100644 (file)
  * 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.api.server.rule;
 
+import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
 import org.sonar.api.utils.MessageException;
 
 import javax.annotation.Nullable;
 
-class DefaultDebtRemediationFunctions implements DebtRemediationFunctions {
+/**
+ * Factory of {@link org.sonar.api.server.debt.DebtRemediationFunction} that keeps
+ * a context of rule for better error messages. Used only when declaring rules.
+ *
+ * @see org.sonar.api.server.rule.RulesDefinition
+ */
+class DefaultDebtRemediationFunctions implements RulesDefinition.DebtRemediationFunctions {
 
   private final String repoKey, key;
 
@@ -51,7 +58,7 @@ class DefaultDebtRemediationFunctions implements DebtRemediationFunctions {
   private DebtRemediationFunction create(DefaultDebtRemediationFunction.Type type, @Nullable String factor, @Nullable String offset) {
     try {
       return new DefaultDebtRemediationFunction(type, factor, offset);
-    } catch (DefaultDebtRemediationFunction.ValidationException e) {
+    } catch (Exception e) {
       throw MessageException.of(String.format("The rule '%s:%s' is invalid : %s ", this.repoKey, this.key, e.getMessage()));
     }
   }
index bd2326407c4e370ba3e84222258eb54342cfc039..3885bede9126fecc74934fc8526b026611ecd330 100644 (file)
@@ -40,7 +40,7 @@ public class RuleTagFormat {
 
   public static void validate(String tag) {
     if (!isValid(tag)) {
-      throw new IllegalArgumentException(String.format("Tag '%s' is invalid. Rule tags accept only the following characters: a-z, 0-9, '+', '-', '#', '.'", tag));
+      throw new IllegalArgumentException(String.format("Tag '%s' is invalid. Rule tags accept only the characters: a-z, 0-9, '+', '-', '#', '.'", tag));
     }
   }
 }
index 2bab880020aec650d45b5b7f0152ee88db70bff1..79d08f46588c78c41a8b4c7320b69a79f3da9c4e 100644 (file)
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
 import org.sonar.api.ServerExtension;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -49,6 +50,89 @@ import java.util.Set;
  * this extension point in order to define the rules that it supports.
  * <p/>
  * This interface replaces the deprecated class org.sonar.api.rules.RuleRepository.
+ * <p/>
+ * <h3>How to use</h3>
+ * <pre>
+ * public class JsSquidRulesDefinition implements RulesDefinition {
+ *
+ *   {@literal @}Override
+ *   public void define(Context context) {
+ *     NewRepository repository = context.createRepository("js_squid", "js").setName("Javascript Squid");
+ *
+ *     // define a rule programmatically. Note that rules
+ *     // could be loaded from files (JSON, XML, ...)
+ *     NewRule x1Rule = repository.createRule("x1")
+ *      .setName("No empty line")
+ *      .setHtmlDescription("Generate an issue on empty lines")
+ *
+ *      // optional tags
+ *      .setTags("style", "stupid")
+ *
+ *     // optional status. Default value is READY.
+ *     .setStatus(RuleStatus.BETA)
+ *
+ *     // default severity when the rule is activated on a Quality profile. Default value is MAJOR.
+ *     .setSeverity(Severity.MINOR);
+ *
+ *     x1Rule
+ *       .setDebtCharacteristic("INTEGRATION_TESTABILITY")
+ *       .setDebtRemediationFunction(x1Rule.debtRemediationFunctions().linearWithOffset("1h", "30min"));
+ *
+ *     x1Rule.createParam("acceptWhitespace")
+ *       .setDefaultValue("false")
+ *       .setType(RuleParamType.BOOLEAN)
+ *       .setDescription("Accept whitespaces on the line");
+ *
+ *     // don't forget to call done() to finalize the definition
+ *     repository.done();
+ *   }
+ * }
+ * </pre>
+ * <p/>
+ * If rules are declared in a XML file with the standard SonarQube format, then it can be loaded by using :
+ *
+ * <pre>
+ * public class JsSquidRulesDefinition implements RulesDefinition {
+ *
+ *   private final RulesDefinitionXmlLoader xmlLoader;
+ *
+ *   public JsSquidRulesDefinition(RulesDefinitionXmlLoader xmlLoader) {
+ *     this.xmlLoader = xmlLoader;
+ *   }
+ *
+ *   {@literal @}Override
+ *   public void define(Context context) {
+ *     NewRepository repository = context.createRepository("js_squid", "js").setName("Javascript Squid");
+ *     // see javadoc of RulesDefinitionXmlLoader for the format
+ *     xmlLoader.load(repository, getClass().getResourceAsStream("/path/to/rules.xml"));
+ *     repository.done();
+ *   }
+ * }
+ * </pre>
+ *
+ * In the above example, XML file must contain name and description of each rule. If it's not the case, then the
+ * (deprecated) English bundles can be used :
+ *
+ * <pre>
+ * public class JsSquidRulesDefinition implements RulesDefinition {
+ *
+ *   private final RulesDefinitionXmlLoader xmlLoader;
+ *   private final RulesDefinitionI18nLoader i18nLoader;
+ *
+ *   public JsSquidRulesDefinition(RulesDefinitionXmlLoader xmlLoader, RulesDefinitionI18nLoader i18nLoader) {
+ *     this.xmlLoader = xmlLoader;
+ *     this.i18nLoader = i18nLoader;
+ *   }
+ *
+ *   {@literal @}Override
+ *   public void define(Context context) {
+ *     NewRepository repository = context.createRepository("js_squid", "js").setName("Javascript Squid");
+ *     xmlLoader.load(repository, getClass().getResourceAsStream("/path/to/rules.xml"));
+ *     i18nLoader.load(repository);
+ *     repository.done();
+ *   }
+ * }
+ * </pre>
  *
  * @since 4.3
  */
@@ -278,6 +362,15 @@ public interface RulesDefinition extends ServerExtension {
     }
   }
 
+  interface DebtRemediationFunctions {
+    DebtRemediationFunction linear(String factor);
+
+    DebtRemediationFunction linearWithOffset(String factor, String offset);
+
+    DebtRemediationFunction constantPerIssue(String offset);
+  }
+
+
   class NewRule {
     private final String repoKey, key;
     private String name, htmlDescription, internalKey, severity = Severity.MAJOR;
@@ -288,7 +381,7 @@ public interface RulesDefinition extends ServerExtension {
     private String effortToFixDescription;
     private final Set<String> tags = Sets.newTreeSet();
     private final Map<String, NewParam> paramsByKey = Maps.newHashMap();
-    private final DefaultDebtRemediationFunctions functions;
+    private final DebtRemediationFunctions functions;
 
     private NewRule(String repoKey, String key) {
       this.repoKey = repoKey;
@@ -356,13 +449,16 @@ public interface RulesDefinition extends ServerExtension {
       return functions;
     }
 
-    public NewRule setDebtRemediationFunction(@Nullable DebtRemediationFunction debtRemediationFunction) {
-      this.debtRemediationFunction = debtRemediationFunction;
+    /**
+     * @see #debtRemediationFunctions()
+     */
+    public NewRule setDebtRemediationFunction(@Nullable DebtRemediationFunction fn) {
+      this.debtRemediationFunction = fn;
       return this;
     }
 
-    public NewRule setEffortToFixDescription(@Nullable String effortToFixDescription) {
-      this.effortToFixDescription = effortToFixDescription;
+    public NewRule setEffortToFixDescription(@Nullable String s) {
+      this.effortToFixDescription = s;
       return this;
     }
 
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionI18nLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionI18nLoader.java
new file mode 100644 (file)
index 0000000..70973c5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.api.server.rule;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.i18n.RuleI18n;
+
+/**
+ * Loads the English bundles of rules (name, description and parameters) that are
+ * deprecated since 4.2. It can be useful when loading existing XML files that
+ * do not contain rule names and descriptions.
+ * <p/>
+ * This class must be executed after declaring rules on {@link RulesDefinition.NewRepository}.
+ * <p/>
+ * Note that localization of rules was dropped in version 4.2. All texts are English.
+ *
+ * @see org.sonar.api.server.rule.RulesDefinition for an example
+ * @since 4.3
+ */
+public class RulesDefinitionI18nLoader implements ServerComponent {
+
+  private final RuleI18n i18n;
+
+  public RulesDefinitionI18nLoader(RuleI18n i18n) {
+    this.i18n = i18n;
+  }
+
+  /**
+   * Loads descriptions of rules and related rule parameters. Existing descriptions
+   * are overridden if English labels exist in bundles.
+   */
+  public void load(RulesDefinition.NewRepository repo) {
+    for (RulesDefinition.NewRule rule : repo.rules()) {
+      String name = i18n.getName(repo.key(), rule.key());
+      if (StringUtils.isNotBlank(name)) {
+        rule.setName(name);
+      }
+
+      String desc = i18n.getDescription(repo.key(), rule.key());
+      if (StringUtils.isNotBlank(desc)) {
+        rule.setHtmlDescription(desc);
+      }
+
+      for (RulesDefinition.NewParam param : rule.params()) {
+        String paramDesc = i18n.getParamDescription(repo.key(), rule.key(), param.key());
+        if (StringUtils.isNotBlank(paramDesc)) {
+          param.setDescription(paramDesc);
+        }
+      }
+    }
+  }
+}
index 83e53ee72d274d429c8fadf5b152ebfbed405e54..a4725146bdd745fb318edae7a192767d3c270111 100644 (file)
@@ -39,7 +39,7 @@ import java.util.Map;
  * <p/>
  * The classes implementing this extension point must be declared in {@link org.sonar.api.SonarPlugin#getExtensions()}.
  *
- * <h2>How to use</h2>
+ * <h3>How to use</h3>
  * <pre>
  * public class HelloWs implements WebService {
  *   {@literal @}Override
@@ -66,7 +66,7 @@ import java.util.Map;
  *   }
  * }
  * </pre>
- * <h2>How to unit test</h2>
+ * <h3>How to test</h3>
  * <pre>
  * public class HelloWsTest {
  *   WebService ws = new HelloWs();
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/debt/DefaultDebtRemediationFunctionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/debt/DefaultDebtRemediationFunctionTest.java
new file mode 100644 (file)
index 0000000..6223fc8
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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.api.server.debt;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
+public class DefaultDebtRemediationFunctionTest {
+
+  @Test
+  public void create_linear() {
+    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "10h", null);
+    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR);
+    assertThat(function.factor()).isEqualTo("10h");
+    assertThat(function.offset()).isNull();
+  }
+
+  @Test
+  public void create_linear_with_offset() {
+    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
+    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR_OFFSET);
+    assertThat(function.factor()).isEqualTo("10h");
+    assertThat(function.offset()).isEqualTo("5min");
+  }
+
+  @Test
+  public void create_constant_per_issue() {
+    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10h");
+    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.CONSTANT_ISSUE);
+    assertThat(function.factor()).isNull();
+    assertThat(function.offset()).isEqualTo("10h");
+  }
+
+  @Test
+  public void sanitize_remediation_factor_and_offset() {
+    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "  1  h   ", "  10   min");
+
+    assertThat(function.factor()).isEqualTo("1h");
+    assertThat(function.offset()).isEqualTo("10min");
+  }
+
+  @Test
+  public void fail_to_create_linear_when_no_factor() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, null, "10h");
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Only factor must be set on DebtRemediationFunction{type=LINEAR, factor=null, offset=10h}");
+    }
+  }
+
+  @Test
+  public void fail_to_create_linear_when_offset() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "5min", "10h");
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Only factor must be set on DebtRemediationFunction{type=LINEAR, factor=5min, offset=10h}");
+    }
+  }
+
+  @Test
+  public void fail_to_create_constant_per_issue_when_no_offset() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "10h", null);
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Only offset must be set on DebtRemediationFunction{type=CONSTANT_ISSUE, factor=10h, offset=null}");
+    }
+  }
+
+  @Test
+  public void fail_to_create_constant_per_issue_when_factor() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "5min", "10h");
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Only offset must be set on DebtRemediationFunction{type=CONSTANT_ISSUE, factor=5min, offset=10h}");
+    }
+  }
+
+  @Test
+  public void fail_to_create_linear_with_offset_when_no_factor() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "", "10h");
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Both factor and offset are required on DebtRemediationFunction{type=LINEAR_OFFSET, factor=null, offset=10h}");
+    }
+  }
+
+  @Test
+  public void fail_to_create_linear_with_offset_when_no_offset() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "5min", "");
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Both factor and offset are required on DebtRemediationFunction{type=LINEAR_OFFSET, factor=5min, offset=null}");
+    }
+  }
+
+  @Test
+  public void test_equals_and_hashcode() {
+    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
+    DebtRemediationFunction functionWithSameValue = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
+    DebtRemediationFunction functionWithDifferentType = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "5min");
+
+    assertThat(function).isEqualTo(function);
+    assertThat(function).isEqualTo(functionWithSameValue);
+    assertThat(function).isNotEqualTo(functionWithDifferentType);
+
+    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "11h", "5min"));
+    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "6min"));
+    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "10h", null));
+    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "6min"));
+
+    assertThat(function.hashCode()).isEqualTo(function.hashCode());
+    assertThat(function.hashCode()).isEqualTo(functionWithSameValue.hashCode());
+    assertThat(function.hashCode()).isNotEqualTo(functionWithDifferentType.hashCode());
+  }
+
+  @Test
+  public void test_to_string() {
+    assertThat(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min").toString())
+      .isEqualTo("DebtRemediationFunction{type=LINEAR_OFFSET, factor=10h, offset=5min}");
+  }
+
+  @Ignore
+  @Test
+  public void fail_if_bad_factor_format() {
+    try {
+      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "foo", null);
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("TODO");
+    }
+
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/DefaultDebtRemediationFunctionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/DefaultDebtRemediationFunctionTest.java
deleted file mode 100644 (file)
index 5f1b5ae..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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.api.server.rule;
-
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-
-public class DefaultDebtRemediationFunctionTest {
-
-  @Test
-  public void create_linear() throws Exception {
-    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "10h", null);
-    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR);
-    assertThat(function.factor()).isEqualTo("10h");
-    assertThat(function.offset()).isNull();
-  }
-
-  @Test
-  public void create_linear_with_offset() throws Exception {
-    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
-    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR_OFFSET);
-    assertThat(function.factor()).isEqualTo("10h");
-    assertThat(function.offset()).isEqualTo("5min");
-  }
-
-  @Test
-  public void create_constant_per_issue() throws Exception {
-    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10h");
-    assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.CONSTANT_ISSUE);
-    assertThat(function.factor()).isNull();
-    assertThat(function.offset()).isEqualTo("10h");
-  }
-
-  @Test
-  public void sanitize_remediation_factor_and_offset() {
-    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "  1  h   ", "  10   mi n");
-
-    assertThat(function.factor()).isEqualTo("1h");
-    assertThat(function.offset()).isEqualTo("10min");
-  }
-
-  @Test
-  public void fail_to_create_linear_when_no_factor() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, null, "10h");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void fail_to_create_linear_when_offset() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "5min", "10h");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void fail_to_create_constant_per_issue_when_no_offset() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "10h", null);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void fail_to_create_constant_per_issue_when_factor() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "5min", "10h");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void fail_to_create_linear_with_offset_when_no_factor() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, null, "10h");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void fail_to_create_linear_with_offset_when_no_offset() throws Exception {
-    try {
-      new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "5min", null);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(DefaultDebtRemediationFunction.ValidationException.class);
-    }
-  }
-
-  @Test
-  public void test_equals_and_hashcode() throws Exception {
-    DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
-    DebtRemediationFunction functionWithSameValue = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
-    DebtRemediationFunction functionWithDifferentType = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "5min");
-
-    assertThat(function).isEqualTo(function);
-    assertThat(function).isEqualTo(functionWithSameValue);
-    assertThat(function).isNotEqualTo(functionWithDifferentType);
-
-    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "11h", "5min"));
-    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "6min"));
-    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "10h", null));
-    assertThat(function).isNotEqualTo(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "6min"));
-
-    assertThat(function.hashCode()).isEqualTo(function.hashCode());
-    assertThat(function.hashCode()).isEqualTo(functionWithSameValue.hashCode());
-    assertThat(function.hashCode()).isNotEqualTo(functionWithDifferentType.hashCode());
-  }
-
-  @Test
-  public void test_to_string() throws Exception {
-    assertThat(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min").toString()).isNotNull();
-  }
-
-}
index e5a832178b4c903e660bdce5fef97d9948945da1..fcc82e7ec7c65579af98cb355ab1768767fb0a1e 100644 (file)
@@ -53,7 +53,7 @@ public class RuleTagFormatTest {
       RuleTagFormat.validate("  ");
       fail();
     } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Tag '  ' is invalid. Rule tags accept only the following characters: a-z, 0-9, '+', '-', '#', '.'");
+      assertThat(e).hasMessage("Tag '  ' is invalid. Rule tags accept only the characters: a-z, 0-9, '+', '-', '#', '.'");
     }
   }
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionI18nLoaderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionI18nLoaderTest.java
new file mode 100644 (file)
index 0000000..5bea527
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.api.server.rule;
+
+import org.junit.Test;
+import org.sonar.api.i18n.RuleI18n;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RulesDefinitionI18nLoaderTest {
+
+  RuleI18n i18n = mock(RuleI18n.class);
+  RulesDefinitionI18nLoader loader = new RulesDefinitionI18nLoader(i18n);
+
+  @Test
+  public void complete_rule_name_and_description() throws Exception {
+    when(i18n.getName("squid", "S0001")).thenReturn("SOne");
+    when(i18n.getDescription("squid", "S0001")).thenReturn("S One");
+
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java");
+    // rule without description
+    repo.createRule("S0001");
+
+    loader.load(repo);
+    repo.done();
+
+    RulesDefinition.Rule rule = context.repository("squid").rule("S0001");
+    assertThat(rule.name()).isEqualTo("SOne");
+    assertThat(rule.htmlDescription()).isEqualTo("S One");
+  }
+
+  @Test
+  public void do_not_override_if_no_bundle() throws Exception {
+    // i18n returns null values
+
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java");
+    repo.createRule("S0001").setName("SOne").setHtmlDescription("S One");
+
+    loader.load(repo);
+    repo.done();
+
+    RulesDefinition.Rule rule = context.repository("squid").rule("S0001");
+    assertThat(rule.name()).isEqualTo("SOne");
+    assertThat(rule.htmlDescription()).isEqualTo("S One");
+  }
+
+  @Test
+  public void override_existing() throws Exception {
+    when(i18n.getName("squid", "S0001")).thenReturn("SOne");
+    when(i18n.getDescription("squid", "S0001")).thenReturn("S One");
+
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java");
+    repo.createRule("S0001").setName("Bad").setHtmlDescription("Bad");
+
+    loader.load(repo);
+    repo.done();
+
+    RulesDefinition.Rule rule = context.repository("squid").rule("S0001");
+    assertThat(rule.name()).isEqualTo("SOne");
+    assertThat(rule.htmlDescription()).isEqualTo("S One");
+  }
+
+  @Test
+  public void complete_param_description() throws Exception {
+    when(i18n.getParamDescription("squid", "S0001", "max")).thenReturn("Maximum");
+
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java");
+    repo.createRule("S0001").setName("SOne").setHtmlDescription("S One").createParam("max");
+
+    loader.load(repo);
+    repo.done();
+
+    RulesDefinition.Rule rule = context.repository("squid").rule("S0001");
+    assertThat(rule.param("max").description()).isEqualTo("Maximum");
+  }
+}
index 5a9f2511c126e92f1fa484638eebe494642f863c..96351855f531a878ed39b9beab039baf8bff5fd8 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.api.server.rule;
 import org.junit.Test;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 
 import java.net.URL;
 
@@ -63,8 +64,8 @@ public class RulesDefinitionTest {
 
   @Test
   public void define_rules() {
-    RulesDefinition.NewRepository newFindbugs = context.createRepository("findbugs", "java");
-    RulesDefinition.NewRule newFindbug = newFindbugs.createRule("NPE")
+    RulesDefinition.NewRepository newRepo = context.createRepository("findbugs", "java");
+    RulesDefinition.NewRule newRule = newRepo.createRule("NPE")
       .setName("Detect NPE")
       .setHtmlDescription("Detect <code>java.lang.NullPointerException</code>")
       .setSeverity(Severity.BLOCKER)
@@ -74,36 +75,36 @@ public class RulesDefinitionTest {
       .setEffortToFixDescription("squid.S115.effortToFix")
       .setTags("one", "two")
       .addTags("two", "three", "four");
-    newFindbug.setDebtRemediationFunction(newFindbug.debtRemediationFunctions().linearWithOffset("1h", "10min"));
+    newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().linearWithOffset("1h", "10min"));
 
-    newFindbugs.createRule("ABC").setName("ABC").setHtmlDescription("ABC");
-    newFindbugs.done();
+    newRepo.createRule("ABC").setName("ABC").setHtmlDescription("ABC");
+    newRepo.done();
 
-    RulesDefinition.Repository findbugs = context.repository("findbugs");
-    assertThat(findbugs.rules()).hasSize(2);
-
-    RulesDefinition.Rule npeRule = findbugs.rule("NPE");
-    assertThat(npeRule.key()).isEqualTo("NPE");
-    assertThat(npeRule.name()).isEqualTo("Detect NPE");
-    assertThat(npeRule.severity()).isEqualTo(Severity.BLOCKER);
-    assertThat(npeRule.htmlDescription()).isEqualTo("Detect <code>java.lang.NullPointerException</code>");
-    assertThat(npeRule.tags()).containsOnly("one", "two", "three", "four");
-    assertThat(npeRule.params()).isEmpty();
-    assertThat(npeRule.internalKey()).isEqualTo("/something");
-    assertThat(npeRule.template()).isFalse();
-    assertThat(npeRule.status()).isEqualTo(RuleStatus.BETA);
-    assertThat(npeRule.debtCharacteristic()).isEqualTo("COMPILER");
-    assertThat(npeRule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
-    assertThat(npeRule.debtRemediationFunction().factor()).isEqualTo("1h");
-    assertThat(npeRule.debtRemediationFunction().offset()).isEqualTo("10min");
-    assertThat(npeRule.effortToFixDescription()).isEqualTo("squid.S115.effortToFix");
-    assertThat(npeRule.toString()).isEqualTo("[repository=findbugs, key=NPE]");
-    assertThat(npeRule.repository()).isSameAs(findbugs);
+    RulesDefinition.Repository repo = context.repository("findbugs");
+    assertThat(repo.rules()).hasSize(2);
+
+    RulesDefinition.Rule rule = repo.rule("NPE");
+    assertThat(rule.key()).isEqualTo("NPE");
+    assertThat(rule.name()).isEqualTo("Detect NPE");
+    assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
+    assertThat(rule.htmlDescription()).isEqualTo("Detect <code>java.lang.NullPointerException</code>");
+    assertThat(rule.tags()).containsOnly("one", "two", "three", "four");
+    assertThat(rule.params()).isEmpty();
+    assertThat(rule.internalKey()).isEqualTo("/something");
+    assertThat(rule.template()).isFalse();
+    assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
+    assertThat(rule.debtCharacteristic()).isEqualTo("COMPILER");
+    assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
+    assertThat(rule.debtRemediationFunction().factor()).isEqualTo("1h");
+    assertThat(rule.debtRemediationFunction().offset()).isEqualTo("10min");
+    assertThat(rule.effortToFixDescription()).isEqualTo("squid.S115.effortToFix");
+    assertThat(rule.toString()).isEqualTo("[repository=findbugs, key=NPE]");
+    assertThat(rule.repository()).isSameAs(repo);
 
     // test equals() and hashCode()
-    RulesDefinition.Rule otherRule = findbugs.rule("ABC");
-    assertThat(npeRule).isEqualTo(npeRule).isNotEqualTo(otherRule).isNotEqualTo("NPE").isNotEqualTo(null);
-    assertThat(npeRule.hashCode()).isEqualTo(npeRule.hashCode());
+    RulesDefinition.Rule otherRule = repo.rule("ABC");
+    assertThat(rule).isEqualTo(rule).isNotEqualTo(otherRule).isNotEqualTo("NPE").isNotEqualTo(null);
+    assertThat(rule.hashCode()).isEqualTo(rule.hashCode());
   }
 
   @Test
@@ -239,14 +240,14 @@ public class RulesDefinitionTest {
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("Tag 'coding style' is invalid. Rule tags accept only the following characters: a-z, 0-9, '+', '-', '#', '.'");
+        .hasMessage("Tag 'coding style' is invalid. Rule tags accept only the characters: a-z, 0-9, '+', '-', '#', '.'");
     }
   }
 
   @Test
   public void load_rule_description_from_file() {
     RulesDefinition.NewRepository newRepository = context.createRepository("findbugs", "java");
-    newRepository.createRule("NPE").setName("NPE").setHtmlDescription(getClass().getResource("/org/sonar/api/server/rule/RuleDefinitionsTest/sample.html"));
+    newRepository.createRule("NPE").setName("NPE").setHtmlDescription(getClass().getResource("/org/sonar/api/server/rule/RulesDefinitionTest/sample.html"));
     newRepository.done();
 
     RulesDefinition.Rule rule = context.repository("findbugs").rule("NPE");
diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsTest/sample.html b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsTest/sample.html
deleted file mode 100644 (file)
index 86c3693..0000000
+++ /dev/null
@@ -1 +0,0 @@
-description of rule loaded from file
diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionTest/sample.html b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionTest/sample.html
new file mode 100644 (file)
index 0000000..86c3693
--- /dev/null
@@ -0,0 +1 @@
+description of rule loaded from file
index ec9ac28c22f5f6dbebd08c3b32db5b01e1e6f0ad..b66e8bceb330052bc18a81151206db73015df7f1 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.debt.DebtCharacteristic;
 import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.ValidationMessages;
 import org.sonar.core.permission.GlobalPermissions;
index feefe213d77a01dfc611b46dbd26011499e36daa..37cb409e4118e99587916f1978576ba07799a8ba 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.debt.DebtCharacteristic;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.xml.sax.InputSource;
 
 import javax.annotation.CheckForNull;
index 32cc6ae4b8fd22de3c0f7ba1dab043007dd69605..dd784b0863d2c7b7462bdc47d5d2f878d4a29afe 100644 (file)
@@ -31,7 +31,7 @@ import org.codehaus.staxmate.in.SMHierarchicCursor;
 import org.codehaus.staxmate.in.SMInputCursor;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.utils.Duration;
 import org.sonar.api.utils.ValidationMessages;
 
index 775cb4f03b9c88d2024f0c5df216cc7ab8fe6d9d..9155a6e9edf60970186b08bc8206151459f464b2 100644 (file)
@@ -31,7 +31,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.Rule;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.System2;
index 2127ac817bb254bdffdd2c1948de48a17efa821d..dbad6dea2ecbd8bd7254a53c25510b6dc2380736 100644 (file)
@@ -32,7 +32,7 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.ValidationMessages;
index a40df68a64fdc15f4122ed806316af3b6579ddbd..36e4b5e044131098524942424d9e00f3fb8e6c69 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.test.TestUtils;
 
 import java.io.IOException;
index 390636ac0f658e656152d2d7e627fd0befa61292..7c7d18bbd6d6811bbc94202a0276c766e320b0e5 100644 (file)
@@ -24,7 +24,7 @@ import com.google.common.base.Charsets;
 import com.google.common.io.Resources;
 import org.junit.Test;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.utils.ValidationMessages;
 
 import java.io.IOException;
@@ -211,7 +211,7 @@ public class DebtRulesXMLImporterTest {
     RuleDebt ruleDebt = results.get(0);
     assertThat(ruleDebt.characteristicKey()).isEqualTo("MEMORY_EFFICIENCY");
     assertThat(ruleDebt.ruleKey()).isEqualTo(RuleKey.of("checkstyle", "Regexp"));
-    assertThat(ruleDebt.function()).isEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.Type.LINEAR);
+    assertThat(ruleDebt.function()).isEqualTo(DebtRemediationFunction.Type.LINEAR);
     assertThat(ruleDebt.factor()).isEqualTo("3h");
     assertThat(ruleDebt.offset()).isNull();
   }
index 78d35bf975dd37ad8db35abbc925043de7db4588..cc48bef99aa233815f8297f6e71f9a585323d9f7 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.api.rules.RuleRepository;
-import org.sonar.api.server.rule.DebtRemediationFunction;
+import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.utils.ValidationMessages;
 import org.sonar.core.i18n.RuleI18nManager;