From 36f47f4b53f8a5b8befecf89ce6e10c977ba874c Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 24 Nov 2011 17:15:31 +0100 Subject: [PATCH] SONAR-3029 API: allow to have different severities for violations related to the same rule --- .../core/sensors/ViolationsDecorator.java | 132 ++++++++++-------- .../sensors/WeightedViolationsDecorator.java | 68 +++++---- .../timemachine/NewViolationsDecorator.java | 113 ++++++++------- .../core/timemachine/VariationDecorator.java | 12 +- .../hotspot_most_violated_rules.html.erb | 4 +- .../sonar/plugins/core/widgets/rules.html.erb | 12 +- .../core/sensors/ViolationsDecoratorTest.java | 76 +++++----- .../WeightedViolationsDecoratorTest.java | 45 ++---- .../NewViolationsDecoratorTest.java | 24 ++-- .../timemachine/VariationDecoratorTest.java | 16 +-- .../resources/org/sonar/l10n/core.properties | 3 - .../batch/components/PastMeasuresLoader.java | 12 +- .../org/sonar/jpa/entity/SchemaMigration.java | 2 +- .../org/sonar/persistence/rows-derby.sql | 1 + .../sonar/api/measures/MeasuresFilters.java | 19 --- .../org/sonar/api/measures/RuleMeasure.java | 42 +++--- .../api/measures/MeasuresFiltersTest.java | 12 -- .../sonar/api/measures/RuleMeasureTest.java | 17 +-- .../org/sonar/api/test/IsRuleMeasure.java | 20 +-- .../app/controllers/drilldown_controller.rb | 27 +++- .../WEB-INF/app/models/project_measure.rb | 12 +- .../webapp/WEB-INF/app/models/snapshot.rb | 19 ++- .../{_rule_priority.erb => _severity.erb} | 9 +- .../app/views/drilldown/measures.html.erb | 15 +- .../app/views/drilldown/violations.html.erb | 65 +++------ .../app/views/resource/_rules_filter.html.erb | 48 ++++--- .../db/migrate/231_refactor_rule_measures.rb | 53 +++++++ 27 files changed, 441 insertions(+), 437 deletions(-) rename sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/{_rule_priority.erb => _severity.erb} (50%) create mode 100644 sonar-server/src/main/webapp/WEB-INF/db/migrate/231_refactor_rule_measures.rb diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java index ebe4f47397f..c349eac99ab 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java @@ -39,56 +39,98 @@ import java.util.Map; @DependsUpon(DecoratorBarriers.END_OF_VIOLATION_TRACKING) public class ViolationsDecorator implements Decorator { - // temporary data for current resource - private Multiset rules = HashMultiset.create(); - private Multiset severities = HashMultiset.create(); - private Map ruleToSeverity = Maps.newHashMap(); - private int total = 0; - public boolean shouldExecuteOnProject(Project project) { return true; } + private boolean shouldDecorateResource(Resource resource) { + return !ResourceUtils.isUnitTestClass(resource); + } + @DependedUpon public List generatesViolationsMetrics() { return Arrays.asList(CoreMetrics.VIOLATIONS, - CoreMetrics.BLOCKER_VIOLATIONS, CoreMetrics.CRITICAL_VIOLATIONS, CoreMetrics.MAJOR_VIOLATIONS, CoreMetrics.MINOR_VIOLATIONS, CoreMetrics.INFO_VIOLATIONS); + CoreMetrics.BLOCKER_VIOLATIONS, + CoreMetrics.CRITICAL_VIOLATIONS, + CoreMetrics.MAJOR_VIOLATIONS, + CoreMetrics.MINOR_VIOLATIONS, + CoreMetrics.INFO_VIOLATIONS); } public void decorate(Resource resource, DecoratorContext context) { if (shouldDecorateResource(resource)) { - resetCounters(); - countViolations(context); - saveTotalViolations(context); - saveViolationsBySeverity(context); - saveViolationsByRule(context); + computeTotalViolations(context); + computeViolationsPerSeverities(context); + computeViolationsPerRules(context); } } - private boolean shouldDecorateResource(Resource resource) { - return !ResourceUtils.isUnitTestClass(resource); + private void computeTotalViolations(DecoratorContext context) { + if (context.getMeasure(CoreMetrics.VIOLATIONS) == null) { + Collection childrenViolations = context.getChildrenMeasures(CoreMetrics.VIOLATIONS); + Double sum = MeasureUtils.sum(true, childrenViolations); + context.saveMeasure(CoreMetrics.VIOLATIONS, sum + context.getViolations().size()); + } } - private void resetCounters() { - rules.clear(); - severities.clear(); - ruleToSeverity.clear(); - total = 0; - } + private void computeViolationsPerSeverities(DecoratorContext context) { + Multiset severitiesBag = HashMultiset.create(); + for (Violation violation : context.getViolations()) { + severitiesBag.add(violation.getSeverity()); + } - private void saveViolationsBySeverity(DecoratorContext context) { for (RulePriority severity : RulePriority.values()) { - Metric metric = getMetricForSeverity(severity); + Metric metric = severityToMetric(severity); if (context.getMeasure(metric) == null) { Collection children = context.getChildrenMeasures(MeasuresFilters.metric(metric)); - double sum = MeasureUtils.sum(true, children) + severities.count(severity); - context.saveMeasure(new Measure(metric, sum)); + int sum = MeasureUtils.sum(true, children).intValue() + severitiesBag.count(severity); + context.saveMeasure(metric, (double) sum); + } + } + } + + private void computeViolationsPerRules(DecoratorContext context) { + Map> rulesPerSeverity = Maps.newHashMap(); + for (Violation violation : context.getViolations()) { + Multiset rulesBag = initRules(rulesPerSeverity, violation.getSeverity()); + rulesBag.add(violation.getRule()); + } + + for (RulePriority severity : RulePriority.values()) { + Metric metric = severityToMetric(severity); + + Collection children = context.getChildrenMeasures(MeasuresFilters.rules(metric)); + for (Measure child : children) { + RuleMeasure childRuleMeasure = (RuleMeasure) child; + Rule rule = childRuleMeasure.getRule(); + if (rule != null && MeasureUtils.hasValue(childRuleMeasure)) { + Multiset rulesBag = initRules(rulesPerSeverity, severity); + rulesBag.add(rule, childRuleMeasure.getIntValue()); + } + } + + Multiset rulesBag = rulesPerSeverity.get(severity); + if (rulesBag != null) { + for (Multiset.Entry entry : rulesBag.entrySet()) { + RuleMeasure measure = RuleMeasure.createForRule(metric, entry.getElement(), (double) entry.getCount()); + measure.setRulePriority(severity); + context.saveMeasure(measure); + } } } } - private Metric getMetricForSeverity(RulePriority severity) { - Metric metric = null; + private Multiset initRules(Map> rulesPerSeverity, RulePriority severity) { + Multiset rulesBag = rulesPerSeverity.get(severity); + if (rulesBag == null) { + rulesBag = HashMultiset.create(); + rulesPerSeverity.put(severity, rulesBag); + } + return rulesBag; + } + + static Metric severityToMetric(RulePriority severity) { + Metric metric; if (severity.equals(RulePriority.BLOCKER)) { metric = CoreMetrics.BLOCKER_VIOLATIONS; } else if (severity.equals(RulePriority.CRITICAL)) { @@ -99,46 +141,12 @@ public class ViolationsDecorator implements Decorator { metric = CoreMetrics.MINOR_VIOLATIONS; } else if (severity.equals(RulePriority.INFO)) { metric = CoreMetrics.INFO_VIOLATIONS; + } else { + throw new IllegalArgumentException("Unsupported severity: " + severity); } return metric; } - private void saveViolationsByRule(DecoratorContext context) { - Collection children = context.getChildrenMeasures(MeasuresFilters.rules(CoreMetrics.VIOLATIONS)); - for (Measure childMeasure : children) { - RuleMeasure childRuleMeasure = (RuleMeasure) childMeasure; - Rule rule = childRuleMeasure.getRule(); - if (rule != null && MeasureUtils.hasValue(childRuleMeasure)) { - rules.add(rule, childRuleMeasure.getValue().intValue()); - ruleToSeverity.put(childRuleMeasure.getRule(), childRuleMeasure.getRulePriority()); - } - } - for (Multiset.Entry entry : rules.entrySet()) { - Rule rule = entry.getElement(); - RuleMeasure measure = RuleMeasure.createForRule(CoreMetrics.VIOLATIONS, rule, (double) entry.getCount()); - measure.setRulePriority(ruleToSeverity.get(rule)); - context.saveMeasure(measure); - } - } - - private void saveTotalViolations(DecoratorContext context) { - if (context.getMeasure(CoreMetrics.VIOLATIONS) == null) { - Collection childrenViolations = context.getChildrenMeasures(CoreMetrics.VIOLATIONS); - Double sum = MeasureUtils.sum(true, childrenViolations) + total; - context.saveMeasure(new Measure(CoreMetrics.VIOLATIONS, sum)); - } - } - - private void countViolations(DecoratorContext context) { - List violations = context.getViolations(); - for (Violation violation : violations) { - rules.add(violation.getRule()); - severities.add(violation.getSeverity()); - ruleToSeverity.put(violation.getRule(), violation.getSeverity()); - } - total = violations.size(); - } - @Override public String toString() { return getClass().getSimpleName(); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java index 330cf8fe365..c25f6415a3e 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java @@ -25,23 +25,27 @@ import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.DependsUpon; -import org.sonar.api.measures.*; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.RuleUtils; +import org.sonar.api.rules.Violation; import org.sonar.api.utils.KeyValueFormat; +import java.util.Arrays; +import java.util.List; import java.util.Map; public class WeightedViolationsDecorator implements Decorator { - private Map weights; - - @DependsUpon - public Metric dependsUponViolations() { - return CoreMetrics.VIOLATIONS; + public List dependsUponViolations() { + return Arrays.asList(CoreMetrics.BLOCKER_VIOLATIONS, CoreMetrics.CRITICAL_VIOLATIONS, + CoreMetrics.MAJOR_VIOLATIONS, CoreMetrics.MINOR_VIOLATIONS, CoreMetrics.INFO_VIOLATIONS); } @DependedUpon @@ -49,44 +53,50 @@ public class WeightedViolationsDecorator implements Decorator { return CoreMetrics.WEIGHTED_VIOLATIONS; } - public WeightedViolationsDecorator() { - } - - /** - * for unit tests - */ - WeightedViolationsDecorator(Map weights) { - this.weights = weights; - } - - private void loadWeights(DecoratorContext context) { - if (weights == null && context != null) { - weights = RuleUtils.getPriorityWeights(context.getProject().getConfiguration()); - } - } - public boolean shouldExecuteOnProject(Project project) { return true; } public void decorate(Resource resource, DecoratorContext context) { - loadWeights(context); + decorate(context, RuleUtils.getPriorityWeights(context.getProject().getConfiguration())); + } + void decorate(DecoratorContext context, Map weights) { double debt = 0.0; - Multiset violationsByPriority = TreeMultiset.create(); + Multiset distribution = TreeMultiset.create(); - for (RuleMeasure violations : context.getMeasures(MeasuresFilters.rules(CoreMetrics.VIOLATIONS))) { - if (MeasureUtils.hasValue(violations)) { - violationsByPriority.add(violations.getRulePriority(), violations.getValue().intValue()); - double add = (int) weights.get(violations.getRulePriority()) * violations.getValue(); + for (RulePriority severity : RulePriority.values()) { + Measure measure = context.getMeasure(severityToMetric(severity)); + if (measure != null && MeasureUtils.hasValue(measure)) { + distribution.add(severity, measure.getIntValue()); + double add = weights.get(severity) * measure.getIntValue(); debt += add; } } - Measure debtMeasure = new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, debt, KeyValueFormat.format(violationsByPriority)); + Measure debtMeasure = new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, debt, KeyValueFormat.format(distribution)); saveMeasure(context, debtMeasure); } + static Metric severityToMetric(RulePriority severity) { + Metric metric; + if (severity.equals(RulePriority.BLOCKER)) { + metric = CoreMetrics.BLOCKER_VIOLATIONS; + } else if (severity.equals(RulePriority.CRITICAL)) { + metric = CoreMetrics.CRITICAL_VIOLATIONS; + } else if (severity.equals(RulePriority.MAJOR)) { + metric = CoreMetrics.MAJOR_VIOLATIONS; + } else if (severity.equals(RulePriority.MINOR)) { + metric = CoreMetrics.MINOR_VIOLATIONS; + } else if (severity.equals(RulePriority.INFO)) { + metric = CoreMetrics.INFO_VIOLATIONS; + } else { + throw new IllegalArgumentException("Unsupported severity: " + severity); + } + return metric; + } + + private void saveMeasure(DecoratorContext context, Measure debtMeasure) { if (debtMeasure.getValue() > 0.0) { context.saveMeasure(debtMeasure); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java index e603fb1f129..144f398978b 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java @@ -20,6 +20,7 @@ package org.sonar.plugins.core.timemachine; import com.google.common.collect.*; +import com.sun.xml.internal.bind.v2.util.QNameMap; import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.*; import org.sonar.api.measures.*; @@ -40,11 +41,6 @@ public class NewViolationsDecorator implements Decorator { private TimeMachineConfiguration timeMachineConfiguration; - // temporary data for current resource - private Map ruleToLevel = Maps.newHashMap(); - private Multimap violationsBySeverity = ArrayListMultimap.create(); - private Multimap violationsByRule = ArrayListMultimap.create(); - public NewViolationsDecorator(TimeMachineConfiguration timeMachineConfiguration) { this.timeMachineConfiguration = timeMachineConfiguration; } @@ -56,42 +52,30 @@ public class NewViolationsDecorator implements Decorator { @DependedUpon public List generatesMetric() { return Arrays.asList( - CoreMetrics.NEW_VIOLATIONS, CoreMetrics.NEW_BLOCKER_VIOLATIONS, CoreMetrics.NEW_CRITICAL_VIOLATIONS, - CoreMetrics.NEW_MAJOR_VIOLATIONS, CoreMetrics.NEW_MINOR_VIOLATIONS, CoreMetrics.NEW_INFO_VIOLATIONS); + CoreMetrics.NEW_VIOLATIONS, + CoreMetrics.NEW_BLOCKER_VIOLATIONS, + CoreMetrics.NEW_CRITICAL_VIOLATIONS, + CoreMetrics.NEW_MAJOR_VIOLATIONS, + CoreMetrics.NEW_MINOR_VIOLATIONS, + CoreMetrics.NEW_INFO_VIOLATIONS); } public void decorate(Resource resource, DecoratorContext context) { if (shouldDecorateResource(resource, context)) { - prepareCurrentResourceViolations(context); - saveNewViolations(context); - saveNewViolationsBySeverity(context); - saveNewViolationsByRule(context); - clearCache(); + computeNewViolations(context); + computeNewViolationsPerSeverity(context); + computeNewViolationsPerRule(context); } } private boolean shouldDecorateResource(Resource resource, DecoratorContext context) { return - (StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()) || StringUtils.equals(Scopes.FILE, resource.getScope())) - && !ResourceUtils.isUnitTestClass(resource) && context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null; + (StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()) || StringUtils.equals(Scopes.FILE, resource.getScope())) + && !ResourceUtils.isUnitTestClass(resource) + && context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null; } - - private void clearCache() { - ruleToLevel.clear(); - violationsBySeverity.clear(); - violationsByRule.clear(); - } - - private void prepareCurrentResourceViolations(DecoratorContext context) { - for (Violation violation : context.getViolations()) { - violationsBySeverity.put(violation.getSeverity(), violation); - violationsByRule.put(violation.getRule(), violation); - ruleToLevel.put(violation.getRule(), violation.getSeverity()); - } - } - - private void saveNewViolations(DecoratorContext context) { + private void computeNewViolations(DecoratorContext context) { Measure measure = new Measure(CoreMetrics.NEW_VIOLATIONS); for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) { int variationIndex = pastSnapshot.getIndex(); @@ -103,13 +87,18 @@ public class NewViolationsDecorator implements Decorator { context.saveMeasure(measure); } - private void saveNewViolationsBySeverity(DecoratorContext context) { - for (RulePriority priority : RulePriority.values()) { - Metric metric = getMetricForSeverity(priority); + private void computeNewViolationsPerSeverity(DecoratorContext context) { + ListMultimap violationsPerSeverities = ArrayListMultimap.create(); + for (Violation violation : context.getViolations()) { + violationsPerSeverities.put(violation.getSeverity(), violation); + } + + for (RulePriority severity : RulePriority.values()) { + Metric metric = severityToMetric(severity); Measure measure = new Measure(metric); for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) { int variationIndex = pastSnapshot.getIndex(); - int count = countViolations(violationsBySeverity.get(priority), pastSnapshot.getTargetDate()); + int count = countViolations(violationsPerSeverities.get(severity), pastSnapshot.getTargetDate()); Collection children = context.getChildrenMeasures(MeasuresFilters.metric(metric)); double sum = sumChildren(variationIndex, children) + count; measure.setVariation(variationIndex, sum); @@ -118,31 +107,41 @@ public class NewViolationsDecorator implements Decorator { } } - private void saveNewViolationsByRule(DecoratorContext context) { - ListMultimap childrenByRule = ArrayListMultimap.create(); - Collection children = context.getChildrenMeasures(MeasuresFilters.rules(CoreMetrics.NEW_VIOLATIONS)); - for (Measure childMeasure : children) { - RuleMeasure childRuleMeasure = (RuleMeasure) childMeasure; - Rule rule = childRuleMeasure.getRule(); - if (rule != null) { - childrenByRule.put(rule, childMeasure); - ruleToLevel.put(childRuleMeasure.getRule(), childRuleMeasure.getRulePriority()); + private void computeNewViolationsPerRule(DecoratorContext context) { + for (RulePriority severity : RulePriority.values()) { + Metric metric = severityToMetric(severity); + ListMultimap childMeasuresPerRule = ArrayListMultimap.create(); + ListMultimap violationsPerRule = ArrayListMultimap.create(); + Set rules = Sets.newHashSet(); + + Collection children = context.getChildrenMeasures(MeasuresFilters.rules(metric)); + for (Measure child : children) { + RuleMeasure childRuleMeasure = (RuleMeasure) child; + Rule rule = childRuleMeasure.getRule(); + if (rule != null) { + childMeasuresPerRule.put(rule, childRuleMeasure); + rules.add(rule); + } } - } - Set rules = Sets.newHashSet(violationsByRule.keys()); - rules.addAll(childrenByRule.keys()); + for (Violation violation : context.getViolations()) { + if (violation.getSeverity().equals(severity)) { + rules.add(violation.getRule()); + violationsPerRule.put(violation.getRule(), violation); + } + } - for (Rule rule : rules) { - RuleMeasure measure = RuleMeasure.createForRule(CoreMetrics.NEW_VIOLATIONS, rule, null); - measure.setRulePriority(ruleToLevel.get(rule)); - for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) { - int variationIndex = pastSnapshot.getIndex(); - int count = countViolations(violationsByRule.get(rule), pastSnapshot.getTargetDate()); - double sum = sumChildren(variationIndex, childrenByRule.get(rule)) + count; - measure.setVariation(variationIndex, sum); + for (Rule rule : rules) { + RuleMeasure measure = RuleMeasure.createForRule(metric, rule, null); + measure.setRulePriority(severity); + for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) { + int variationIndex = pastSnapshot.getIndex(); + int count = countViolations(violationsPerRule.get(rule), pastSnapshot.getTargetDate()); + double sum = sumChildren(variationIndex, childMeasuresPerRule.get(rule)) + count; + measure.setVariation(variationIndex, sum); + } + context.saveMeasure(measure); } - context.saveMeasure(measure); } } @@ -177,7 +176,7 @@ public class NewViolationsDecorator implements Decorator { return violation.getCreatedAt() != null && violation.getCreatedAt().after(date); } - private Metric getMetricForSeverity(RulePriority severity) { + private Metric severityToMetric(RulePriority severity) { Metric metric; if (severity.equals(RulePriority.BLOCKER)) { metric = CoreMetrics.NEW_BLOCKER_VIOLATIONS; @@ -190,7 +189,7 @@ public class NewViolationsDecorator implements Decorator { } else if (severity.equals(RulePriority.INFO)) { metric = CoreMetrics.NEW_INFO_VIOLATIONS; } else { - throw new IllegalArgumentException("Not supported severity: " + severity); + throw new IllegalArgumentException("Unsupported severity: " + severity); } return metric; } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index cb10c34d886..e78a3db9c14 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -99,9 +99,8 @@ public class VariationDecorator implements Decorator { Integer metricId = (measure.getMetric().getId() != null ? measure.getMetric().getId() : metricFinder.findByKey(measure.getMetric().getKey()).getId()); Integer characteristicId = (measure.getCharacteristic() != null ? measure.getCharacteristic().getId() : null); Integer ruleId = (measure instanceof RuleMeasure ? ((RuleMeasure)measure).getRule().getId() : null); - Integer severityId = (measure instanceof RuleMeasure ? ((RuleMeasure)measure).getRulePriority().ordinal() : null); - Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, ruleId, severityId)); + Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, ruleId)); if (updateVariation(measure, pastMeasure, index)) { context.saveMeasure(measure); } @@ -126,20 +125,17 @@ public class VariationDecorator implements Decorator { int metricId; Integer characteristicId; Integer ruleId; - Integer severityId; MeasureKey(Object[] pastFields) { metricId = PastMeasuresLoader.getMetricId(pastFields); characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields); ruleId = PastMeasuresLoader.getRuleId(pastFields); - severityId = PastMeasuresLoader.getSeverityId(pastFields); } - MeasureKey(int metricId, Integer characteristicId, Integer ruleId, Integer severityId) { + MeasureKey(int metricId, Integer characteristicId, Integer ruleId) { this.metricId = metricId; this.characteristicId = characteristicId; this.ruleId = ruleId; - this.severityId = severityId; } @Override @@ -160,9 +156,6 @@ public class VariationDecorator implements Decorator { if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) { return false; } - if (severityId != null ? !severityId.equals(that.severityId) : that.severityId != null) { - return false; - } return true; } @@ -171,7 +164,6 @@ public class VariationDecorator implements Decorator { int result = metricId; result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0); result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0); - result = 31 * result + (severityId != null ? severityId.hashCode() : 0); return result; } } diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/hotspot_most_violated_rules.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/hotspot_most_violated_rules.html.erb index 034d8b31021..0a646e060b5 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/hotspot_most_violated_rules.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/hotspot_most_violated_rules.html.erb @@ -91,12 +91,12 @@ %> - + <%= image_tag('priority/' + m.rule_priority.to_s + '.png') -%> - <%= rule.name -%> + <%= rule.name -%> <%= m.formatted_value -%> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb index 456fdafdf17..8db7c377ff8 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb @@ -21,7 +21,7 @@

<%= message('widget.rules.rules_compliance') -%>

- <%= format_measure(density, :url => url_for_drilldown(Metric::WEIGHTED_VIOLATIONS, {:highlight => Metric::WEIGHTED_VIOLATIONS})) -%> + <%= format_measure(density, :url => url_for_drilldown('weighted_violations', {:highlight => 'weighted_violations'})) -%> <%= dashboard_configuration.selected_period? ? format_variation(density) : trend_icon(density) -%>
@@ -40,7 +40,7 @@ - + @@ -60,7 +60,7 @@ - + @@ -80,7 +80,7 @@ - + @@ -100,7 +100,7 @@ - + @@ -120,7 +120,7 @@ - + diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java index 73173480748..a387627919a 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java @@ -27,6 +27,7 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.resources.Resource; +import org.sonar.api.resources.Scopes; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.Violation; @@ -38,6 +39,7 @@ import java.util.List; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; public class ViolationsDecoratorTest { @@ -61,14 +63,14 @@ public class ViolationsDecoratorTest { } @Test - public void countViolations() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + public void shouldCountViolations() { + when(resource.getScope()).thenReturn(Scopes.PROJECT); when(context.getViolations()).thenReturn(createViolations()); when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); decorator.decorate(resource, context); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 4.0))); + verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 4.0); } /** @@ -76,7 +78,7 @@ public class ViolationsDecoratorTest { */ @Test public void shouldNotCountViolationsIfMeasureAlreadyExists() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(resource.getScope()).thenReturn(Scopes.PROJECT); when(context.getViolations()).thenReturn(createViolations()); when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); when(context.getMeasure(CoreMetrics.VIOLATIONS)).thenReturn(new Measure(CoreMetrics.VIOLATIONS, 3000.0)); @@ -84,71 +86,75 @@ public class ViolationsDecoratorTest { decorator.decorate(resource, context); - verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 4.0)));// not changed - verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.MAJOR_VIOLATIONS)));// not changed - verify(context, times(1)).saveMeasure(argThat(new IsMeasure(CoreMetrics.CRITICAL_VIOLATIONS)));// did not exist + verify(context, never()).saveMeasure(eq(CoreMetrics.VIOLATIONS), anyDouble());// not changed + verify(context, never()).saveMeasure(eq(CoreMetrics.MAJOR_VIOLATIONS), anyDouble());// not changed + verify(context, times(1)).saveMeasure(eq(CoreMetrics.CRITICAL_VIOLATIONS), anyDouble());// did not exist } @Test - public void resetCountersAfterExecution() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SET); - when(context.getViolations()).thenReturn(createViolations()); + public void shouldSaveZeroOnProjects() { + when(resource.getScope()).thenReturn(Scopes.PROJECT); + when(context.getViolations()).thenReturn(Collections.emptyList()); when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); - decorator.decorate(resource, context); decorator.decorate(resource, context); - // we must not have 8 violations ! - verify(context, times(2)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 4.0))); - verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 8.0))); + verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0); } @Test - public void saveZeroOnProjects() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + public void shouldSaveZeroOnDirectories() { + when(resource.getScope()).thenReturn(Scopes.DIRECTORY); when(context.getViolations()).thenReturn(Collections.emptyList()); when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); decorator.decorate(resource, context); - verify(context, atLeast(1)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 0.0))); + verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0); } @Test - public void saveZeroOnDirectories() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SPACE); - when(context.getViolations()).thenReturn(Collections.emptyList()); + public void shouldCountViolationsBySeverity() { + when(resource.getScope()).thenReturn(Scopes.PROJECT); + when(context.getViolations()).thenReturn(createViolations()); when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); decorator.decorate(resource, context); - verify(context, atLeast(1)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 0.0))); + verify(context).saveMeasure(CoreMetrics.BLOCKER_VIOLATIONS, 0.0); + verify(context).saveMeasure(CoreMetrics.CRITICAL_VIOLATIONS, 2.0); + verify(context).saveMeasure(CoreMetrics.MAJOR_VIOLATIONS, 1.0); + verify(context).saveMeasure(CoreMetrics.MINOR_VIOLATIONS, 1.0); + verify(context).saveMeasure(CoreMetrics.INFO_VIOLATIONS, 0.0); } @Test - public void shouldCountViolationsBySeverity() { - when(resource.getScope()).thenReturn(Resource.SCOPE_SET); - when(context.getViolations()).thenReturn(createViolations()); - when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.emptyList()); + public void shouldCountViolationsPerRule() { + List violations = Lists.newArrayList(); + violations.add(Violation.create(ruleA1, resource).setSeverity(RulePriority.CRITICAL)); + violations.add(Violation.create(ruleA1, resource).setSeverity(RulePriority.CRITICAL)); + violations.add(Violation.create(ruleA2, resource).setSeverity(RulePriority.MAJOR)); + when(context.getViolations()).thenReturn(violations); decorator.decorate(resource, context); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.BLOCKER_VIOLATIONS, 0.0))); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.CRITICAL_VIOLATIONS, 2.0))); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.MAJOR_VIOLATIONS, 1.0))); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.MINOR_VIOLATIONS, 1.0))); - verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.INFO_VIOLATIONS, 0.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0))); + verify(context, never()).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA1, 0.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA2, 1.0))); } @Test - public void ruleViolations() { - when(context.getViolations()).thenReturn(createViolations()); + public void sameRuleShouldHaveDifferentSeverities() { + List violations = Lists.newArrayList(); + violations.add(Violation.create(ruleA1, resource).setSeverity(RulePriority.CRITICAL)); + violations.add(Violation.create(ruleA1, resource).setSeverity(RulePriority.CRITICAL)); + violations.add(Violation.create(ruleA1, resource).setSeverity(RulePriority.MINOR)); + when(context.getViolations()).thenReturn(violations); decorator.decorate(resource, context); - verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, ruleA1, RulePriority.CRITICAL, 2.0))); - verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, ruleA2, RulePriority.MAJOR, 1.0))); - verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, ruleB1, RulePriority.MINOR, 1.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MINOR_VIOLATIONS, ruleA1, 1.0))); } private List createViolations() { diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java index 54407f80223..60048f084f7 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java @@ -19,42 +19,26 @@ */ package org.sonar.plugins.core.sensors; +import com.google.common.collect.Maps; import org.junit.Test; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; -import org.sonar.api.measures.RuleMeasure; -import org.sonar.api.resources.Resource; -import org.sonar.api.rules.Rule; +import org.sonar.api.measures.Metric; import org.sonar.api.rules.RulePriority; import org.sonar.api.test.IsMeasure; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.Collections; import java.util.Map; import static org.mockito.Mockito.*; - public class WeightedViolationsDecoratorTest { - private List createViolationsMeasures() { - return Arrays.asList( - // categ 3 - new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.INFO, 3).setValue(40.0), - new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.CRITICAL, 3).setValue(80.0), - new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.BLOCKER, 3).setValue(90.0), - - // categ 4 - new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.INFO, 4).setValue(10.0), - new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.BLOCKER, 4).setValue(10.0) - ); - } - private Map createWeights() { - Map weights = new HashMap(); + Map weights = Maps.newHashMap(); weights.put(RulePriority.BLOCKER, 10); weights.put(RulePriority.CRITICAL, 5); weights.put(RulePriority.MAJOR, 2); @@ -66,13 +50,13 @@ public class WeightedViolationsDecoratorTest { @Test public void weightedViolations() { Map weights = createWeights(); - - WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(weights); + WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(); DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.INFO_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.INFO_VIOLATIONS, 50.0)); + when(context.getMeasure(CoreMetrics.CRITICAL_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.CRITICAL_VIOLATIONS, 80.0)); + when(context.getMeasure(CoreMetrics.BLOCKER_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.BLOCKER_VIOLATIONS, 100.0)); - when(context.getMeasures((MeasuresFilter) anyObject())).thenReturn(createViolationsMeasures()); - - decorator.decorate(mock(Resource.class), context); + decorator.decorate(context, weights); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, (double) (100 * 10 + 80 * 5 + 50 * 0)))); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, "INFO=50;CRITICAL=80;BLOCKER=100"))); @@ -81,15 +65,10 @@ public class WeightedViolationsDecoratorTest { @Test public void doNotSaveZero() { Map weights = createWeights(); - - WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(weights); + WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(); DecoratorContext context = mock(DecoratorContext.class); - - when(context.getMeasures((MeasuresFilter) anyObject())).thenReturn(Arrays.asList()); - - decorator.decorate(mock(Resource.class), context); + decorator.decorate(context, weights); verify(context, never()).saveMeasure((Measure) anyObject()); } - -} +} \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java index 22a239811b3..9bc7b8e15b9 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java @@ -140,7 +140,7 @@ public class NewViolationsDecoratorTest { } @Test - public void priorityViolations() { + public void severityViolations() { when(context.getViolations()).thenReturn(createViolations()); decorator.decorate(resource, context); @@ -160,9 +160,9 @@ public class NewViolationsDecoratorTest { decorator.decorate(resource, context); // remember : period1 is 5daysAgo, period2 is 10daysAgo - verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_VIOLATIONS, rule1, RulePriority.CRITICAL, 1.0, 1.0))); - verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_VIOLATIONS, rule2, RulePriority.MAJOR, 0.0, 1.0))); - verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_VIOLATIONS, rule3, RulePriority.MINOR, 0.0, 1.0))); + verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, rule1, 1.0, 1.0))); + verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS, rule2, 0.0, 1.0))); + verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS, rule3, 0.0, 1.0))); } private List createViolations() { @@ -179,14 +179,12 @@ public class NewViolationsDecoratorTest { private class IsVariationRuleMeasure extends BaseMatcher { private Metric metric = null; private Rule rule = null; - private RulePriority priority = null; private Double var1 = null; private Double var2 = null; - public IsVariationRuleMeasure(Metric metric, Rule rule, RulePriority priority, Double var1, Double var2) { + public IsVariationRuleMeasure(Metric metric, Rule rule, Double var1, Double var2) { this.metric = metric; this.rule = rule; - this.priority = priority; this.var1 = var1; this.var2 = var2; } @@ -197,10 +195,9 @@ public class NewViolationsDecoratorTest { } RuleMeasure m = (RuleMeasure) o; return ObjectUtils.equals(metric, m.getMetric()) && - ObjectUtils.equals(rule, m.getRule()) && - ObjectUtils.equals(priority, m.getRulePriority()) && - ObjectUtils.equals(var1, m.getVariation1()) && - ObjectUtils.equals(var2, m.getVariation2()); + ObjectUtils.equals(rule, m.getRule()) && + ObjectUtils.equals(var1, m.getVariation1()) && + ObjectUtils.equals(var2, m.getVariation2()); } public void describeTo(Description arg0) { @@ -224,8 +221,9 @@ public class NewViolationsDecoratorTest { } Measure m = (Measure) o; return ObjectUtils.equals(metric, m.getMetric()) && - ObjectUtils.equals(var1, m.getVariation1()) && - ObjectUtils.equals(var2, m.getVariation2()); + ObjectUtils.equals(var1, m.getVariation1()) && + ObjectUtils.equals(var2, m.getVariation2()) && + !(m instanceof RuleMeasure); } public void describeTo(Description o) { diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java index ba963a10f0a..c5c3645f31c 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java @@ -100,12 +100,12 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { // first past analysis when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList( - new Object[]{NCLOC_ID, null, null, null, 180.0}, - new Object[]{COVERAGE_ID, null, null, null, 75.0})); + new Object[]{NCLOC_ID, null, null, 180.0}, + new Object[]{COVERAGE_ID, null, null, 75.0})); // second past analysis when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot3)).thenReturn(Arrays.asList( - new Object[]{NCLOC_ID, null, null, null, 240.0})); + new Object[]{NCLOC_ID, null, null, 240.0})); // current analysis DecoratorContext context = mock(DecoratorContext.class); @@ -142,15 +142,15 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { // first past analysis when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList( - new Object[]{VIOLATIONS_ID, null, null, null, 180.0},//total - new Object[]{VIOLATIONS_ID, null, rule1.getId(), RulePriority.BLOCKER.ordinal(), 100.0},// rule 1 - new Object[]{VIOLATIONS_ID, null, rule2.getId(), RulePriority.MAJOR.ordinal(), 80.0})); // rule 2 + new Object[]{VIOLATIONS_ID, null, null, 180.0},//total + new Object[]{VIOLATIONS_ID, null, rule1.getId(), 100.0},// rule 1 + new Object[]{VIOLATIONS_ID, null, rule2.getId(), 80.0})); // rule 2 // current analysis DecoratorContext context = mock(DecoratorContext.class); Measure violations = newMeasure(VIOLATIONS, 200.0); - Measure violationsRule1 = new RuleMeasure(VIOLATIONS, rule1, RulePriority.BLOCKER, null).setValue(130.0); - Measure violationsRule2 = new RuleMeasure(VIOLATIONS, rule2, RulePriority.MAJOR, null).setValue(70.0); + Measure violationsRule1 = RuleMeasure.createForRule(VIOLATIONS, rule1, 130.0); + Measure violationsRule2 = RuleMeasure.createForRule(VIOLATIONS, rule2, 70.0); when(context.getMeasures(Matchers.anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2)); VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), false); diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties index 721ae89b67b..cbeef6f5475 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -595,9 +595,6 @@ drilldown.drilldown_on=Drilldown on violations_drilldown.click_for_more_on_x=Click for more on {0} : {1} violations_drilldown.col.severity=Severity violations_drilldown.col.rule=Rule -violations_drilldown.path=Path -violations_drilldown.any_severity=Any severity -violations_drilldown.any_rule=Any rule violations_drilldown.no_violations=No violations diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java index 5b21a07ba5c..3b835911d41 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java @@ -65,7 +65,7 @@ public class PastMeasuresLoader implements BatchExtension { } public List getPastMeasures(String resourceKey, Snapshot projectPastSnapshot) { - String sql = "select m.metric_id, m.characteristic_id, m.rule_id, m.rule_priority, m.value from project_measures m, snapshots s" + + String sql = "select m.metric_id, m.characteristic_id, m.rule_id, m.value from project_measures m, snapshots s" + " where m.snapshot_id=s.id and m.metric_id in (:metricIds) " + " and (s.root_snapshot_id=:rootSnapshotId or s.id=:rootSnapshotId) and s.status=:status and s.project_id=(select p.id from projects p where p.kee=:resourceKey and p.qualifier<>:lib)"; return session.createNativeQuery(sql) @@ -94,17 +94,11 @@ public class PastMeasuresLoader implements BatchExtension { return number!=null ? number.intValue() : null; } - public static Integer getSeverityId(Object[] row) { - // can be BigDecimal on Oracle - Number number = (Number) row[3]; - return number!=null ? number.intValue() : null; - } - public static boolean hasValue(Object[] row) { - return row[4] != null; + return row[3] != null; } public static double getValue(Object[] row) { - return ((Number) row[4]).doubleValue(); + return ((Number) row[3]).doubleValue(); } } diff --git a/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java b/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java index 9edfa7e98ad..023a71496c3 100644 --- a/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java +++ b/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java @@ -42,7 +42,7 @@ public class SchemaMigration { - complete the Derby DDL file used for unit tests : sonar-testing-harness/src/main/resources/org/sonar/test/persistence/sonar-test.ddl */ - public static final int LAST_VERSION = 230; + public static final int LAST_VERSION = 231; public final static String TABLE_NAME = "schema_migrations"; diff --git a/sonar-core/src/main/resources/org/sonar/persistence/rows-derby.sql b/sonar-core/src/main/resources/org/sonar/persistence/rows-derby.sql index 27aa544dbe3..8f29cef7727 100644 --- a/sonar-core/src/main/resources/org/sonar/persistence/rows-derby.sql +++ b/sonar-core/src/main/resources/org/sonar/persistence/rows-derby.sql @@ -165,6 +165,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('220'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('221'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('222'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('230'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('231'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java index 9d4ef31510c..6701e1c9b2f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java @@ -106,10 +106,6 @@ public final class MeasuresFilters { }; } - public static MeasuresFilter rulePriority(final Metric metric, final RulePriority priority) { - return new RulePriorityFilter(metric, priority); - } - /** * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2007 */ @@ -204,21 +200,6 @@ public final class MeasuresFilters { } } - private static class RulePriorityFilter extends AbstractRuleMeasureFilter { - private RulePriority priority; - - protected RulePriorityFilter(Metric metric, RulePriority priority) { - super(metric); - this.priority = priority; - } - - @Override - boolean doApply(RuleMeasure measure) { - return measure.getRule() == null - && priority.equals(measure.getRulePriority()); - } - } - /** * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2007 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/RuleMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/RuleMeasure.java index 99b9ebac7e9..1c62e5844b3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/RuleMeasure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/RuleMeasure.java @@ -58,7 +58,7 @@ public class RuleMeasure extends Measure { this.rulePriority = rulePriority; } -/** + /** * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 */ @Deprecated @@ -88,10 +88,9 @@ public class RuleMeasure extends Measure { } RuleMeasure other = (RuleMeasure) obj; return new EqualsBuilder() - .append(getMetric(), other.getMetric()) - .append(rule, other.rule) - .append(rulePriority, other.rulePriority) - .isEquals(); + .append(getMetric(), other.getMetric()) + .append(rule, other.rule) + .isEquals(); } @Override @@ -102,34 +101,33 @@ public class RuleMeasure extends Measure { @Override public int hashCode() { return new HashCodeBuilder(17, 37). - append(getMetric()). - append(rule). - append(rulePriority). - toHashCode(); + append(getMetric()). + append(rule). + toHashCode(); } @Override public String toString() { return new ToStringBuilder(this). - append("id", getId()). - append("metric", metric). - append("value", value). - append("data", data). - append("description", description). - append("alertStatus", alertStatus). - append("alertText", alertText). - append("tendency", tendency). - append("rule", rule). - append("priority", rulePriority). - toString(); + append("id", getId()). + append("metric", metric). + append("rule", rule). + append("value", value). + append("data", data). + append("description", description). + append("alertStatus", alertStatus). + append("alertText", alertText). + append("tendency", tendency). + append("severity", rulePriority). + toString(); } public static RuleMeasure createForRule(Metric metric, Rule rule, Double value) { - return (RuleMeasure) new RuleMeasure(metric, rule, null, null).setValue(value); + return new RuleMeasure(metric, rule, null, null).setValue(value); } public static RuleMeasure createForPriority(Metric metric, RulePriority priority, Double value) { - return (RuleMeasure) new RuleMeasure(metric, null, priority, null).setValue(value); + return new RuleMeasure(metric, null, priority, null).setValue(value); } /** diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasuresFiltersTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasuresFiltersTest.java index 82bb96efad2..d1d65cbe842 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasuresFiltersTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasuresFiltersTest.java @@ -52,18 +52,6 @@ public class MeasuresFiltersTest { assertThat(MeasuresFilters.all().filter(measures).size(), is(2)); } - @Test - public void rulePriority() { - MeasuresFilter filter = MeasuresFilters.rulePriority(CoreMetrics.VIOLATIONS, RulePriority.CRITICAL); - List measures = Arrays.asList( - RuleMeasure.createForPriority(CoreMetrics.VIOLATIONS, RulePriority.CRITICAL, 50.0), - RuleMeasure.createForPriority(CoreMetrics.VIOLATIONS, RulePriority.BLOCKER, 10.0), - RuleMeasure.createForPriority(CoreMetrics.COVERAGE, RulePriority.CRITICAL, 400.0), - new Measure(CoreMetrics.VIOLATIONS, 500.0)); - - assertThat(filter.filter(measures).getValue(), is(50.0)); - } - @Test public void rule() { Rule rule1 = new Rule("pmd", "key1"); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/RuleMeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/RuleMeasureTest.java index 12e25cb675a..d7c2cbdf06e 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/RuleMeasureTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/RuleMeasureTest.java @@ -29,7 +29,7 @@ import static org.junit.Assert.assertFalse; public class RuleMeasureTest { @Test - public void equals() { + public void shouldEquals() { assertEquals( RuleMeasure.createForPriority(CoreMetrics.CLASSES, RulePriority.CRITICAL, 4.5), RuleMeasure.createForPriority(CoreMetrics.CLASSES, RulePriority.CRITICAL, 3.4)); @@ -41,19 +41,14 @@ public class RuleMeasureTest { } @Test - public void notEquals() { + public void shouldNotEquals() { assertNotEquals( - RuleMeasure.createForPriority(CoreMetrics.CLASSES, RulePriority.CRITICAL, 4.5), - RuleMeasure.createForPriority(CoreMetrics.CLASSES, RulePriority.BLOCKER, 3.4)); - - assertNotEquals( - RuleMeasure.createForRule(CoreMetrics.CLASSES, new Rule("pmd", "abc1"), 4.5), - RuleMeasure.createForRule(CoreMetrics.CLASSES, new Rule("pmd", "def2"), 3.4)); + RuleMeasure.createForRule(CoreMetrics.BLOCKER_VIOLATIONS, new Rule("pmd", "abc1"), 4.5), + RuleMeasure.createForRule(CoreMetrics.BLOCKER_VIOLATIONS, new Rule("pmd", "def2"), 3.4)); assertNotEquals( - RuleMeasure.createForPriority(CoreMetrics.CLASSES, RulePriority.CRITICAL, 4.5), - RuleMeasure.createForRule(CoreMetrics.CLASSES, new Rule("pmd", "abc1"), 3.4)); - + RuleMeasure.createForRule(CoreMetrics.INFO_VIOLATIONS, new Rule("pmd", "abc1"), 4.5), + RuleMeasure.createForRule(CoreMetrics.BLOCKER_VIOLATIONS, new Rule("pmd", "abc1"), 3.4)); } private void assertNotEquals(RuleMeasure rm1, RuleMeasure rm2) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/IsRuleMeasure.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/IsRuleMeasure.java index 61469320dbb..74668606a4a 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/test/IsRuleMeasure.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/IsRuleMeasure.java @@ -27,41 +27,27 @@ import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; import org.sonar.api.measures.RuleMeasure; import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RulePriority; public class IsRuleMeasure extends BaseMatcher { private Metric metric = null; private Rule rule = null; - private RulePriority priority = null; private Double value = null; - public IsRuleMeasure(Metric metric, Rule rule, RulePriority priority, Double value) { + public IsRuleMeasure(Metric metric, Rule rule, Double value) { this.metric = metric; this.rule = rule; - this.priority = priority; this.value = value; } - /** - * @deprecated since 2.5 - * category not used any more - see http://jira.codehaus.org/browse/SONAR-2007 , so use - * {@link #IsRuleMeasure(Metric, Rule, RulePriority, Double)} instead - */ - @Deprecated - public IsRuleMeasure(Metric metric, Rule rule, Integer category, RulePriority priority, Double value) { - this(metric, rule, priority, value); - } - public boolean matches(Object o) { if (!(o instanceof RuleMeasure)) { return false; } RuleMeasure m = (RuleMeasure) o; return ObjectUtils.equals(metric, m.getMetric()) && - ObjectUtils.equals(rule, m.getRule()) && - ObjectUtils.equals(priority, m.getRulePriority()) && - NumberUtils.compare(value, m.getValue()) == 0; + ObjectUtils.equals(rule, m.getRule()) && + NumberUtils.compare(value, m.getValue()) == 0; } public void describeTo(Description description) { diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/drilldown_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/drilldown_controller.rb index ab1a1d13d01..809914e1739 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/drilldown_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/drilldown_controller.rb @@ -78,9 +78,11 @@ class DrilldownController < ApplicationController metric_prefix = 'new_' end - @priority_id=(params[:priority].blank? ? nil : Sonar::RulePriority.id(params[:priority])) - if @rule.nil? && @priority_id - @metric = Metric::by_key("#{metric_prefix}#{params[:priority].downcase}_violations") + @severity = params[:severity] || params[:priority] + rule_severity = params[:rule_sev] || @severity + if rule_severity + # Filter resources by severity + @metric = Metric::by_key("#{metric_prefix}#{rule_severity.downcase}_violations") else @metric = Metric::by_key("#{metric_prefix}violations") end @@ -114,6 +116,25 @@ class DrilldownController < ApplicationController @highlighted_resource=@project end + + # + # Initialize filter by rule + # + if @severity + # Filter on severity -> filter rule measures by the selected metric + @rule_measures = @snapshot.rule_measures(@metric) + else + # No filter -> loads all the rules + metrics=[ + Metric.by_key("#{metric_prefix}blocker_violations"), + Metric.by_key("#{metric_prefix}critical_violations"), + Metric.by_key("#{metric_prefix}major_violations"), + Metric.by_key("#{metric_prefix}minor_violations"), + Metric.by_key("#{metric_prefix}info_violations") + ] + @rule_measures = @snapshot.rule_measures(metrics) + end + @display_viewers=display_violation_viewers?(@drilldown.highlighted_snapshot || @snapshot) end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb index 0532898a30c..14a503c4fc4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb @@ -227,8 +227,16 @@ class ProjectMeasure < ActiveRecord::Base metric.short_name end + # Deprecated in v.2.13. Replaced by severity() def rule_priority_text - rule_priority ? Sonar::RulePriority.to_s(rule_priority) : nil + severity + end + + def severity + @severity ||= + begin + rule_priority ? Sonar::RulePriority.to_s(rule_priority) : nil + end end def key @@ -237,8 +245,6 @@ class ProjectMeasure < ActiveRecord::Base "#{metric_key}_rule_#{rule_id}" elsif characteristic_id "#{metric_key}_c_#{characteristic_id}" - else - "#{metric_key}_#{rule_priority_text}" end else metric_key diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/snapshot.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/snapshot.rb index 7b5f9034fab..be8b15b990d 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/snapshot.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/snapshot.rb @@ -27,9 +27,9 @@ class Snapshot < ActiveRecord::Base belongs_to :root_snapshot, :class_name => 'Snapshot', :foreign_key => 'root_snapshot_id' belongs_to :characteristic - has_many :measures, :class_name => 'ProjectMeasure', :conditions => 'rule_id IS NULL AND rule_priority IS NULL AND characteristic_id IS NULL' - has_many :rulemeasures, :class_name => 'ProjectMeasure', :conditions => '(rule_id IS NOT NULL OR rule_priority IS NOT NULL) AND characteristic_id IS NULL' - has_many :characteristic_measures, :class_name => 'ProjectMeasure', :conditions => 'rule_id IS NULL AND rule_priority IS NULL AND characteristic_id IS NOT NULL' + has_many :measures, :class_name => 'ProjectMeasure', :conditions => 'rule_id IS NULL AND characteristic_id IS NULL' + has_many :rulemeasures, :class_name => 'ProjectMeasure', :conditions => 'rule_id IS NOT NULL AND characteristic_id IS NULL', :include => 'rule' + has_many :characteristic_measures, :class_name => 'ProjectMeasure', :conditions => 'rule_id IS NULL AND characteristic_id IS NOT NULL' has_many :events, :dependent => :destroy, :order => 'event_date DESC' has_one :source, :class_name => 'SnapshotSource', :dependent => :destroy @@ -175,18 +175,15 @@ class Snapshot < ActiveRecord::Base m ? m.formatted_value : nil end - def rule_measures(metric=nil, rule_priority=nil) + def rule_measures(metrics=nil, rule=nil) + if metrics + metric_ids=[metrics].flatten.map{|metric| metric.id} + end rulemeasures.select do |m| - m.rule_id && (metric ? m.metric_id==metric.id : true) && (rule_priority ? m.rule_priority==rule_priority : true) + (metric_ids.nil? || metric_ids.include?(m.metric_id)) && (rule.nil? || m.rule_id==rule.id) end end - def rule_priority_measures(metric_key) - rulemeasures.select do |measure| - measure.rule_id.nil? && measure.rule_priority && measure.metric && measure.metric.key==metric_key - end - end - def self.snapshot_by_date(resource_id, date) if resource_id && date Snapshot.find(:first, :conditions => ['created_at>=? and created_at 'created_at desc') diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_rule_priority.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_severity.erb similarity index 50% rename from sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_rule_priority.erb rename to sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_severity.erb index 56eae8f5b59..25b19b680eb 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_rule_priority.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_severity.erb @@ -1,6 +1,9 @@ - - - +<% selected=(severity==@severity) %> + + + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb index a41f2036dc3..baa502e2a70 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb @@ -47,24 +47,25 @@
<%= image_tag 'priority/BLOCKER.png'%>  <%= link_to message('blocker'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'BLOCKER'} %>  <%= link_to message('blocker'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :severity => 'BLOCKER'} %> <%= format_measure(blocker_violations) -%>
<%= image_tag 'priority/CRITICAL.png' %>  <%= link_to message('critical'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'CRITICAL'} %>  <%= link_to message('critical'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :severity => 'CRITICAL'} %> <%= format_measure(critical_violations) -%>
<%= image_tag 'priority/MAJOR.png' %>  <%= link_to message('major'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'MAJOR'} %>  <%= link_to message('major'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :severity => 'MAJOR'} %> <%= format_measure(major_violations) -%>
<%= image_tag 'priority/MINOR.png' %>  <%= link_to message('minor'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'MINOR'} %>  <%= link_to message('minor'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :severity => 'MINOR'} %> <%= format_measure(minor_violations) -%>
<%= image_tag 'priority/INFO.png' %>  <%= link_to message('info'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'INFO'} %>  <%= link_to message('info'), {:controller => 'drilldown', :action => 'violations', :id => @project.key, :severity => 'INFO'} %> <%= format_measure(info_violations) -%>
<%= image_tag "priority/#{priority_id}.png" %><%= link_to Sonar::RulePriority.to_s(priority_id, true), {:controller => 'drilldown', :action => 'violations', :id => @project.id, :priority => Sonar::RulePriority.to_s(priority_id), :period => @period} %>
<%= image_tag "priority/#{severity}.png" %> + <%= link_to message("severity.#{severity}"), {:controller => 'drilldown', :action => 'violations', :id => @project.id, :severity => (selected ? nil : severity), :period => @period} %> + <%= @period ? format_variation(measure, :index => @period, :style => 'light') : format_measure(measure) -%>
<% column.measures.each do |measure| resource=column.resource(measure) - clazz = cycle("even hoverable", "odd hoverable", :name => "col_#{column.scope}") - clazz = clazz + ' selected' if column.selected_snapshot && column.selected_snapshot.project_id==resource.id + selected = column.selected_snapshot && column.selected_snapshot.project_id==resource.id + clazz = cycle("even", "odd", :name => "col_#{column.scope}") + clazz = clazz + ' selected' if selected %>
<% if resource.entity? if resource.copy_resource_id %> - <%= qualifier_icon(resource) %> + <%= qualifier_icon(resource) -%> <%= link_to(resource.name, {:only_path => true, :overwrite_params => {:rids => nil, :id => resource.copy_resource_id}}) -%> <% else %> - <%= qualifier_icon(resource) %> + <%= qualifier_icon(resource) -%> <%= resource.name(false) -%> <% end else %> - <%= link_to(image_tag('zoom.png'), {:id => resource.id, :metric => @metric.id}, {:class => 'nolink'}) %> - <%= qualifier_icon(resource) %> - <%= link_to(resource.name, {:only_path => true, :overwrite_params => {:rids => rids + [resource.id]}}) -%> + <%= link_to(image_tag('zoom.png'), {:id => resource.id, :metric => @metric.id}, {:class => 'nolink'}) -%> + <%= qualifier_icon(resource) -%> + <%= link_to(resource.name, {:only_path => true, :overwrite_params => {:rids => (selected ? rids-[resource.id] : rids+[resource.id])}}) -%> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb index 37fac4ce8ad..21421403622 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb @@ -50,34 +50,27 @@ %>

<%= message('violations_drilldown.col.severity') -%>

- <%= render :partial => 'rule_priority', :locals => {:css => 'even', :priority_id => Sonar::RulePriority::PRIORITY_BLOCKER, :max => max, :measure => blocker_violations }%> - <%= render :partial => 'rule_priority', :locals => {:css => 'odd', :priority_id => Sonar::RulePriority::PRIORITY_CRITICAL, :max => max, :measure => critical_violations }%> - <%= render :partial => 'rule_priority', :locals => {:css => 'even', :priority_id => Sonar::RulePriority::PRIORITY_MAJOR, :max => max, :measure => major_violations }%> - <%= render :partial => 'rule_priority', :locals => {:css => 'odd', :priority_id => Sonar::RulePriority::PRIORITY_MINOR, :max => max, :measure => minor_violations }%> - <%= render :partial => 'rule_priority', :locals => {:css => 'even', :priority_id => Sonar::RulePriority::PRIORITY_INFO, :max => max, :measure => info_violations }%> + <%= render :partial => 'severity', :locals => {:css => 'even', :severity => 'BLOCKER', :max => max, :measure => blocker_violations }%> + <%= render :partial => 'severity', :locals => {:css => 'odd', :severity => 'CRITICAL', :max => max, :measure => critical_violations }%> + <%= render :partial => 'severity', :locals => {:css => 'even', :severity => 'MAJOR', :max => max, :measure => major_violations }%> + <%= render :partial => 'severity', :locals => {:css => 'odd', :severity => 'MINOR', :max => max, :measure => minor_violations }%> + <%= render :partial => 'severity', :locals => {:css => 'even', :severity => 'INFO', :max => max, :measure => info_violations }%>

<%= message('violations_drilldown.col.rule') -%>

- +
<% - if @period - rule_measures=@snapshot.rule_measures(Metric.by_key('new_violations'), @priority_id) - else - rule_measures=@snapshot.rule_measures(Metric.by_key('violations'), @priority_id) - end max=0 rule_index=0 - rule_measures.each do |m| + @rule_measures.each do |m| value = m.send(value_column) if m max=value if value && value>max end - rule_ids=rule_measures.collect{ |measure| measure.rule_id}.uniq + rule_ids=@rule_measures.collect{ |measure| measure.rule_id}.uniq rules = (rule_ids.empty? ? [] : Rule.find(rule_ids)) - rules_hash={} - rules.each { |rule| rules_hash[rule.id]=rule } - rule_measures.sort do|x,y| + @rule_measures.sort do|x,y| val=y.rule_priority<=>x.rule_priority if val==0 x_value=x.send(value_column) @@ -89,17 +82,18 @@ end.each do |rule_measure| value = rule_measure.send(value_column) next if value.nil? || value==0 - rule=rules_hash[rule_measure.rule_id] + rule=rule_measure.rule clazz = cycle('even', 'odd', :name => 'rules') - clazz = clazz + ' selected' if @rule && @rule.id==rule_measure.rule_id + selected = @rule && @rule.id==rule_measure.rule_id + clazz = clazz + ' selected' if selected rule_index+=1 %> +
" title="<%= message('violations_drilldown.click_for_more_on_x', :params => [rule.plugin_name, rule.plugin_rule_key]) -%>" onclick="window.open(this.href,'rule','height=800,width=900,scrollbars=1,resizable=1');return false;" href="<%= url_for :controller => 'rules', :action => 'show', :id => rule.key, :layout => 'false' -%>"> - - <%= link_to(rule.name, {:overwrite_params => {:rule => rule.key, :sid => nil, :priority => Sonar::RulePriority.to_s(@priority_id)}}, :title => "#{rule.plugin_name}: #{rule.plugin_rule_key}") %> + <%= link_to(rule.name, {:rule => (selected ? nil : rule.key), :rule_sev => (selected ? nil : rule_measure.severity), :sid => nil, :severity => @severity, :period => @period, :rids => (selected ? nil : @selected_rids)}, :title => "#{rule.plugin_name}: #{rule.plugin_rule_key}") -%> <%= @period ? format_variation(rule_measure, :period => @period, :style => 'light') : rule_measure.formatted_value -%> @@ -133,7 +127,8 @@ column.measures.each do |measure| resource=column.resource(measure) clazz = cycle('even', 'odd', :name => "col_#{column.scope}") - if column.selected_snapshot && column.selected_snapshot.project_id==resource.id + selected = column.selected_snapshot && column.selected_snapshot.project_id==resource.id + if selected clazz += ' selected' paths << [h(resource.name), @selected_rids-[resource.id]] end @@ -143,17 +138,17 @@ <% if resource.entity? if resource.copy_resource_id %> - <%= qualifier_icon(resource) %> + <%= qualifier_icon(resource) -%> <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => nil, :id => resource.copy_resource_id}}) -%> <% else %> - <%= qualifier_icon(resource) %> - <%= resource.name(false) %> + <%= qualifier_icon(resource) -%> + <%= resource.name(false) %> <% - end + end else %> <%= link_to(image_tag('zoom.png'), {:id => resource.id}, {:class => 'nolink'}) %> <%= qualifier_icon(resource) %> - <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => rids + [resource.id]}}) -%> + <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => (selected ? rids-[resource.id] : rids+[resource.id])}}) -%> <% end %> @@ -169,23 +164,7 @@ end %>
-
-
-<%= message('violations_drilldown.path') -%>: -<% if @priority_id %> -<%= Sonar::RulePriority.to_s(@priority_id, true) %> <%= link_to message('clear_verb'), {:overwrite_params => {:priority => nil}} %> -<% else %> -<%= message('violations_drilldown.any_severity') -%> -<% end %> »  -<% if @rule %> -<%= h @rule.name %> <%= link_to message('clear_verb'), {:overwrite_params => {:rule => nil}} %> -<% else %> -<%= message('violations_drilldown.any_rule') -%> -<% end %> »  -<% paths.each do |path| %> -<%= path[0] %> <%= link_to message('clear_verb'), {:overwrite_params => {:rids => path[1]}} %> »  -<% end %> -
+