001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2013 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * SonarQube is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.measures; 021 022import org.sonar.api.rules.Rule; 023import org.sonar.api.technicaldebt.batch.Characteristic; 024import org.sonar.api.technicaldebt.batch.Requirement; 025 026import java.util.ArrayList; 027import java.util.Collection; 028import java.util.Collections; 029import java.util.List; 030 031/** 032 * @since 1.10 033 */ 034public final class MeasuresFilters { 035 036 private MeasuresFilters() { 037 } 038 039 public static MeasuresFilter<Collection<Measure>> all() { 040 return new MeasuresFilter<Collection<Measure>>() { 041 public Collection<Measure> filter(Collection<Measure> measures) { 042 return measures; 043 } 044 }; 045 } 046 047 public static MeasuresFilter<Measure> metric(final Metric metric) { 048 return metric(metric.getKey()); 049 } 050 051 public static MeasuresFilter<Measure> metric(final String metricKey) { 052 return new MetricFilter<Measure>(metricKey) { 053 054 public Measure filter(Collection<Measure> measures) { 055 if (measures == null) { 056 return null; 057 } 058 for (Measure measure : measures) { 059 if (measure.getClass().equals(Measure.class) && 060 measure.getMetricKey().equals(metricKey) && 061 measure.getCharacteristic() == null && 062 measure.getPersonId() == null) { 063 return measure; 064 } 065 } 066 return null; 067 } 068 }; 069 } 070 071 public static MeasuresFilter<Measure> characteristic(final Metric metric, final Characteristic characteristic) { 072 return new MetricFilter<Measure>(metric) { 073 074 public Measure filter(Collection<Measure> measures) { 075 if (measures == null) { 076 return null; 077 } 078 for (Measure measure : measures) { 079 if (measure.getClass().equals(Measure.class) && 080 measure.getMetric().equals(metric) && 081 measure.getPersonId() == null && 082 isSameCharacteristic(measure, characteristic)) { 083 return measure; 084 } 085 } 086 return null; 087 } 088 }; 089 } 090 091 private static boolean isSameCharacteristic(Measure measure, final Characteristic characteristic){ 092 Characteristic measureCharacteristic = measure.getCharacteristic(); 093 return measureCharacteristic != null && 094 measureCharacteristic.equals(characteristic); 095 } 096 097 public static MeasuresFilter<Measure> requirement(final Metric metric, final Requirement requirement) { 098 return new MetricFilter<Measure>(metric) { 099 100 public Measure filter(Collection<Measure> measures) { 101 if (measures == null) { 102 return null; 103 } 104 for (Measure measure : measures) { 105 if (measure.getClass().equals(Measure.class) && 106 measure.getMetric().equals(metric) && 107 measure.getPersonId() == null && 108 isSameRequirement(measure, requirement)) { 109 return measure; 110 } 111 } 112 return null; 113 } 114 }; 115 } 116 117 private static boolean isSameRequirement(Measure measure, final Requirement requirement){ 118 Requirement measureRequirement = measure.getRequirement(); 119 return measureRequirement != null && 120 measureRequirement.equals(requirement); 121 } 122 123 /** 124 * @since 2.0 125 */ 126 public static MeasuresFilter<Measure> measure(final Measure measure) { 127 return new MeasuresFilter<Measure>() { 128 public Measure filter(Collection<Measure> measures) { 129 if (measures == null) { 130 return null; 131 } 132 for (Measure m : measures) { 133 if (m.equals(measure)) { 134 return m; 135 } 136 } 137 return null; 138 } 139 }; 140 } 141 142 /** 143 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2007 144 */ 145 @Deprecated 146 public static MeasuresFilter<RuleMeasure> ruleCategory(final Metric metric, final Integer category) { 147 return new RuleCategoryFilter(metric, category); 148 } 149 150 public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final Rule rule) { 151 return new RuleFilter(metric, rule); 152 } 153 154 /** 155 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2007 156 */ 157 @Deprecated 158 public static MeasuresFilter<Collection<RuleMeasure>> ruleCategories(final Metric metric) { 159 return new MetricFilter<Collection<RuleMeasure>>(metric) { 160 161 public Collection<RuleMeasure> filter(Collection<Measure> measures) { 162 return Collections.emptyList(); 163 } 164 }; 165 } 166 167 public static MeasuresFilter<Collection<RuleMeasure>> rules(final Metric metric) { 168 return new MetricFilter<Collection<RuleMeasure>>(metric) { 169 170 private boolean apply(Measure measure) { 171 return measure instanceof RuleMeasure && metric.equals(measure.getMetric()) 172 && measure.getPersonId() == null && ((RuleMeasure) measure).getRule() != null; 173 } 174 175 public Collection<RuleMeasure> filter(Collection<Measure> measures) { 176 if (measures == null) { 177 return null; 178 } 179 List<RuleMeasure> result = new ArrayList<RuleMeasure>(); 180 for (Measure measure : measures) { 181 if (apply(measure)) { 182 result.add((RuleMeasure) measure); 183 } 184 } 185 return result; 186 } 187 }; 188 } 189 190 /** 191 * Used for internal optimizations. 192 */ 193 public abstract static class MetricFilter<M> implements MeasuresFilter<M> { 194 private final String metricKey; 195 196 protected MetricFilter(Metric metric) { 197 this.metricKey = metric.getKey(); 198 } 199 200 protected MetricFilter(String metricKey) { 201 this.metricKey = metricKey; 202 } 203 204 public String filterOnMetricKey() { 205 return metricKey; 206 } 207 } 208 209 private abstract static class AbstractRuleMeasureFilter<M> extends MetricFilter<M> { 210 protected AbstractRuleMeasureFilter(Metric metric) { 211 super(metric); 212 } 213 214 private boolean apply(Measure measure) { 215 return measure instanceof RuleMeasure 216 && filterOnMetricKey().equals(measure.getMetricKey()) 217 && measure.getPersonId() == null 218 && doApply((RuleMeasure) measure); 219 } 220 221 abstract boolean doApply(RuleMeasure ruleMeasure); 222 223 public M filter(Collection<Measure> measures) { 224 if (measures == null) { 225 return null; 226 } 227 for (Measure measure : measures) { 228 if (apply(measure)) { 229 return (M) measure; 230 } 231 } 232 return null; 233 } 234 } 235 236 /** 237 * @deprecated since 2.5. See http://jira.codehaus.org/browse/SONAR-2007 238 */ 239 @Deprecated 240 private static class RuleCategoryFilter extends AbstractRuleMeasureFilter<RuleMeasure> { 241 242 protected RuleCategoryFilter(Metric metric, Integer categ) { 243 super(metric); 244 } 245 246 @Override 247 boolean doApply(RuleMeasure measure) { 248 return false; 249 } 250 } 251 252 253 private static class RuleFilter extends AbstractRuleMeasureFilter<RuleMeasure> { 254 private Rule rule; 255 256 protected RuleFilter(Metric metric, Rule rule) { 257 super(metric); 258 this.rule = rule; 259 } 260 261 @Override 262 boolean doApply(RuleMeasure measure) { 263 return measure.getRule() != null 264 && rule.equals(measure.getRule()); 265 } 266 } 267}