@@ -107,15 +107,15 @@ public class ModuleIssues { | |||
if (issue.severity() == null) { | |||
issue.setSeverity(activeRule.severity()); | |||
} | |||
if (rule.debtCharacteristic() != null) { | |||
issue.setDebt(calculateDebt(rule, issue.effortToFix())); | |||
DebtRemediationFunction function = rule.debtRemediationFunction(); | |||
if (rule.debtCharacteristic() != null && function != null) { | |||
issue.setDebt(calculateDebt(function, issue.effortToFix(), rule.key())); | |||
} | |||
} | |||
private Duration calculateDebt(Rule rule, @Nullable Double effortToFix) { | |||
DebtRemediationFunction function = rule.debtRemediationFunction(); | |||
private Duration calculateDebt(DebtRemediationFunction function, @Nullable Double effortToFix, RuleKey ruleKey) { | |||
if (DebtRemediationFunction.Type.CONSTANT_ISSUE.equals(function.type()) && effortToFix != null) { | |||
throw new IllegalArgumentException("Rule '" + rule.key() + "' can not use 'Constant/issue' remediation function " + | |||
throw new IllegalArgumentException("Rule '" + ruleKey + "' can not use 'Constant/issue' remediation function " + | |||
"because this rule does not have a fixed remediation cost."); | |||
} | |||
Duration result = Duration.create(0); |
@@ -109,7 +109,7 @@ public class RulesProvider extends ProviderAdapter { | |||
if (function != null) { | |||
return createDebtRemediationFunction(function, ruleDto.getRemediationFactor(), ruleDto.getRemediationOffset(), durations); | |||
} else if (defaultFunction != null) { | |||
return createDebtRemediationFunction(ruleDto.getDefaultRemediationFunction(), ruleDto.getDefaultRemediationFactor(), ruleDto.getDefaultRemediationOffset(), durations); | |||
return createDebtRemediationFunction(defaultFunction, ruleDto.getDefaultRemediationFactor(), ruleDto.getDefaultRemediationOffset(), durations); | |||
} else { | |||
throw new IllegalStateException(String.format("Remediation function should not be null on rule '%s'", ruleKey)); | |||
} |
@@ -23,6 +23,7 @@ package org.sonar.core.technicaldebt; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import org.picocontainer.Startable; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.api.ServerExtension; | |||
import org.sonar.api.platform.PluginMetadata; | |||
import org.sonar.api.platform.PluginRepository; | |||
@@ -87,9 +88,12 @@ public class TechnicalDebtModelRepository implements ServerExtension, Startable | |||
contributingPluginKeyToClassLoader.put(DEFAULT_MODEL, getClass().getClassLoader()); | |||
for (PluginMetadata metadata : pluginRepository.getMetadata()) { | |||
String pluginKey = metadata.getKey(); | |||
ClassLoader classLoader = pluginRepository.getPlugin(pluginKey).getClass().getClassLoader(); | |||
if (classLoader.getResource(getXMLFilePath(pluginKey)) != null) { | |||
contributingPluginKeyToClassLoader.put(pluginKey, classLoader); | |||
Plugin plugin = pluginRepository.getPlugin(pluginKey); | |||
if (plugin != null) { | |||
ClassLoader classLoader = plugin.getClass().getClassLoader(); | |||
if (classLoader.getResource(getXMLFilePath(pluginKey)) != null) { | |||
contributingPluginKeyToClassLoader.put(pluginKey, classLoader); | |||
} | |||
} | |||
} | |||
} |
@@ -20,6 +20,8 @@ | |||
package org.sonar.api.batch.rule; | |||
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 org.sonar.api.utils.Duration; | |||
@@ -84,28 +86,21 @@ public class DebtRemediationFunction { | |||
if (o == null || getClass() != o.getClass()) { | |||
return false; | |||
} | |||
DebtRemediationFunction that = (DebtRemediationFunction) o; | |||
if (type != that.type) { | |||
return false; | |||
} | |||
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 true; | |||
return new EqualsBuilder() | |||
.append(type, that.type()) | |||
.append(factor, that.factor()) | |||
.append(offset, that.offset()) | |||
.isEquals(); | |||
} | |||
@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; | |||
return new HashCodeBuilder(15, 31) | |||
.append(type) | |||
.append(factor) | |||
.append(offset) | |||
.toHashCode(); | |||
} | |||
@Override |
@@ -61,7 +61,7 @@ public interface Rule { | |||
String debtCharacteristic(); | |||
/** | |||
* Remediation function : one of LINEAR (with a factor), LINEAR_OFFSET (with a factor and an offset) or CONSTANT_ISSUE (with an offset) | |||
* Remediation function : can by Linear (with a factor), Linear with offset (with a factor and an offset) or Constant per issue (with an offset) | |||
* | |||
* @since 4.3 | |||
*/ |
@@ -21,6 +21,8 @@ | |||
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; | |||
@@ -37,7 +39,6 @@ public class DebtRemediationFunction { | |||
} | |||
public static class ValidationException extends RuntimeException { | |||
public ValidationException(String message) { | |||
super(message); | |||
} | |||
@@ -117,26 +118,20 @@ public class DebtRemediationFunction { | |||
} | |||
DebtRemediationFunction that = (DebtRemediationFunction) o; | |||
if (type != that.type) { | |||
return false; | |||
} | |||
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 true; | |||
return new EqualsBuilder() | |||
.append(type, that.type()) | |||
.append(factor, that.factor()) | |||
.append(offset, that.offset()) | |||
.isEquals(); | |||
} | |||
@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; | |||
return new HashCodeBuilder(15, 33) | |||
.append(type) | |||
.append(factor) | |||
.append(offset) | |||
.toHashCode(); | |||
} | |||
@Override |
@@ -21,7 +21,7 @@ | |||
package org.sonar.api.batch.rule; | |||
import org.junit.Test; | |||
import org.sonar.api.server.rule.DebtRemediationFunction; | |||
import org.sonar.api.utils.Duration; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -29,41 +29,41 @@ public class DebtRemediationFunctionTest { | |||
@Test | |||
public void create_linear() throws Exception { | |||
org.sonar.api.server.rule.DebtRemediationFunction function = org.sonar.api.server.rule.DebtRemediationFunction.createLinear("10h"); | |||
assertThat(function.type()).isEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.Type.LINEAR); | |||
assertThat(function.factor()).isEqualTo("10h"); | |||
DebtRemediationFunction function = DebtRemediationFunction.createLinear(Duration.create(10)); | |||
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.LINEAR); | |||
assertThat(function.factor()).isEqualTo(Duration.create(10)); | |||
assertThat(function.offset()).isNull(); | |||
} | |||
@Test | |||
public void create_linear_with_offset() throws Exception { | |||
org.sonar.api.server.rule.DebtRemediationFunction function = org.sonar.api.server.rule.DebtRemediationFunction.createLinearWithOffset("10h", "5min"); | |||
assertThat(function.type()).isEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.Type.LINEAR_OFFSET); | |||
assertThat(function.factor()).isEqualTo("10h"); | |||
assertThat(function.offset()).isEqualTo("5min"); | |||
DebtRemediationFunction function = DebtRemediationFunction.createLinearWithOffset(Duration.create(10), Duration.create(5)); | |||
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET); | |||
assertThat(function.factor()).isEqualTo(Duration.create(10)); | |||
assertThat(function.offset()).isEqualTo(Duration.create(5)); | |||
} | |||
@Test | |||
public void create_constant_per_issue() throws Exception { | |||
org.sonar.api.server.rule.DebtRemediationFunction function = org.sonar.api.server.rule.DebtRemediationFunction.createConstantPerIssue("10h"); | |||
assertThat(function.type()).isEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.Type.CONSTANT_ISSUE); | |||
DebtRemediationFunction function = DebtRemediationFunction.createConstantPerIssue(Duration.create(10)); | |||
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE); | |||
assertThat(function.factor()).isNull(); | |||
assertThat(function.offset()).isEqualTo("10h"); | |||
assertThat(function.offset()).isEqualTo(Duration.create(10)); | |||
} | |||
@Test | |||
public void test_equals_and_hashcode() throws Exception { | |||
org.sonar.api.server.rule.DebtRemediationFunction function = org.sonar.api.server.rule.DebtRemediationFunction.createLinearWithOffset("10h", "5min"); | |||
org.sonar.api.server.rule.DebtRemediationFunction functionWithSameValue = org.sonar.api.server.rule.DebtRemediationFunction.createLinearWithOffset("10h", "5min"); | |||
org.sonar.api.server.rule.DebtRemediationFunction functionWithDifferentType = org.sonar.api.server.rule.DebtRemediationFunction.createConstantPerIssue("5min"); | |||
DebtRemediationFunction function = DebtRemediationFunction.createLinearWithOffset(Duration.create(10), Duration.create(5)); | |||
DebtRemediationFunction functionWithSameValue = DebtRemediationFunction.createLinearWithOffset(Duration.create(10), Duration.create(5)); | |||
DebtRemediationFunction functionWithDifferentType = DebtRemediationFunction.createConstantPerIssue(Duration.create(5)); | |||
assertThat(function).isEqualTo(function); | |||
assertThat(function).isEqualTo(functionWithSameValue); | |||
assertThat(function).isNotEqualTo(functionWithDifferentType); | |||
assertThat(function).isNotEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.createLinearWithOffset("11h", "5min")); | |||
assertThat(function).isNotEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.createLinearWithOffset("10h", "6min")); | |||
assertThat(function).isNotEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.createLinear("10h")); | |||
assertThat(function).isNotEqualTo(org.sonar.api.server.rule.DebtRemediationFunction.createConstantPerIssue("6min")); | |||
assertThat(function).isNotEqualTo(DebtRemediationFunction.createLinearWithOffset(Duration.create(11), Duration.create(5))); | |||
assertThat(function).isNotEqualTo(DebtRemediationFunction.createLinearWithOffset(Duration.create(10), Duration.create(6))); | |||
assertThat(function).isNotEqualTo(DebtRemediationFunction.createLinear(Duration.create(10))); | |||
assertThat(function).isNotEqualTo(DebtRemediationFunction.createConstantPerIssue(Duration.create(6))); | |||
assertThat(function.hashCode()).isEqualTo(function.hashCode()); | |||
assertThat(function.hashCode()).isEqualTo(functionWithSameValue.hashCode()); | |||
@@ -72,6 +72,6 @@ public class DebtRemediationFunctionTest { | |||
@Test | |||
public void test_to_string() throws Exception { | |||
assertThat(DebtRemediationFunction.createLinearWithOffset("10h", "5min").toString()).isNotNull(); | |||
assertThat(DebtRemediationFunction.createLinearWithOffset(Duration.create(10), Duration.create(5)).toString()).isNotNull(); | |||
} | |||
} |