001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 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.rule.RuleKey; 023import org.sonar.api.rules.Rule; 024import org.sonar.api.technicaldebt.batch.Characteristic; 025import org.sonar.api.technicaldebt.batch.Requirement; 026 027import java.util.ArrayList; 028import java.util.Collection; 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 @Override 042 public Collection<Measure> filter(Collection<Measure> measures) { 043 Collection<Measure> all = new ArrayList<>(); 044 for (Measure measure : measures) { 045 if (measure != null) { 046 all.add(measure); 047 } 048 } 049 return all; 050 } 051 }; 052 } 053 054 public static MeasuresFilter<Measure> metric(final org.sonar.api.batch.measure.Metric<?> metric) { 055 return metric(metric.key()); 056 } 057 058 public static MeasuresFilter<Measure> metric(final String metricKey) { 059 return new MetricFilter<Measure>(metricKey) { 060 @Override 061 public Measure filter(Collection<Measure> measures) { 062 if (measures == null) { 063 return null; 064 } 065 for (Measure measure : measures) { 066 if (measure.getClass().equals(Measure.class) && 067 measure.getMetricKey().equals(metricKey) && 068 measure.getCharacteristic() == null && 069 measure.getPersonId() == null) { 070 return measure; 071 } 072 } 073 return null; 074 } 075 }; 076 } 077 078 public static MeasuresFilter<Measure> characteristic(final Metric metric, final Characteristic characteristic) { 079 return new MetricFilter<Measure>(metric) { 080 081 @Override 082 public Measure filter(Collection<Measure> measures) { 083 if (measures == null) { 084 return null; 085 } 086 for (Measure measure : measures) { 087 if (measure.getClass().equals(Measure.class) && 088 measure.getMetric().equals(metric) && 089 measure.getPersonId() == null && 090 isSameCharacteristic(measure, characteristic)) { 091 return measure; 092 } 093 } 094 return null; 095 } 096 }; 097 } 098 099 private static boolean isSameCharacteristic(Measure measure, final Characteristic characteristic) { 100 Characteristic measureCharacteristic = measure.getCharacteristic(); 101 return measureCharacteristic != null && 102 measureCharacteristic.equals(characteristic); 103 } 104 105 /** 106 * @deprecated since 4.3 107 */ 108 @Deprecated 109 public static MeasuresFilter<Measure> requirement(final Metric metric, final Requirement requirement) { 110 return new MetricFilter<Measure>(metric) { 111 112 @Override 113 public Measure filter(Collection<Measure> measures) { 114 if (measures == null) { 115 return null; 116 } 117 for (Measure measure : measures) { 118 if (measure.getClass().equals(Measure.class) && 119 measure.getMetric().equals(metric) && 120 measure.getPersonId() == null && 121 isSameRequirement(measure, requirement)) { 122 return measure; 123 } 124 } 125 return null; 126 } 127 }; 128 } 129 130 private static boolean isSameRequirement(Measure measure, final Requirement requirement) { 131 Requirement measureRequirement = measure.getRequirement(); 132 return measureRequirement != null && 133 measureRequirement.equals(requirement); 134 } 135 136 /** 137 * @since 2.0 138 */ 139 public static MeasuresFilter<Measure> measure(final Measure measure) { 140 return new MeasuresFilter<Measure>() { 141 @Override 142 public Measure filter(Collection<Measure> measures) { 143 if (measures == null) { 144 return null; 145 } 146 for (Measure m : measures) { 147 if (m.equals(measure)) { 148 return m; 149 } 150 } 151 return null; 152 } 153 }; 154 } 155 156 public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final RuleKey ruleKey) { 157 return new RuleFilter(metric, ruleKey); 158 } 159 160 public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final Rule rule) { 161 return rule(metric, rule.ruleKey()); 162 } 163 164 public static MeasuresFilter<Collection<RuleMeasure>> rules(final Metric metric) { 165 return new MetricFilter<Collection<RuleMeasure>>(metric) { 166 167 private boolean apply(Measure measure) { 168 return measure instanceof RuleMeasure && metric.equals(measure.getMetric()) 169 && measure.getPersonId() == null && ((RuleMeasure) measure).ruleKey() != null; 170 } 171 172 @Override 173 public Collection<RuleMeasure> filter(Collection<Measure> measures) { 174 if (measures == null) { 175 return null; 176 } 177 List<RuleMeasure> result = new ArrayList<>(); 178 for (Measure measure : measures) { 179 if (apply(measure)) { 180 result.add((RuleMeasure) measure); 181 } 182 } 183 return result; 184 } 185 }; 186 } 187 188 /** 189 * Used for internal optimizations. 190 */ 191 public abstract static class MetricFilter<M> implements MeasuresFilter<M> { 192 private final String metricKey; 193 194 protected MetricFilter(Metric metric) { 195 this.metricKey = metric.getKey(); 196 } 197 198 protected MetricFilter(String metricKey) { 199 this.metricKey = metricKey; 200 } 201 202 public String filterOnMetricKey() { 203 return metricKey; 204 } 205 } 206 207 /** 208 * @deprecated since 5.2. The measures related to rules are computed on server side by Compute Engine. 209 */ 210 @Deprecated 211 private abstract static class AbstractRuleMeasureFilter<M> extends MetricFilter<M> { 212 protected AbstractRuleMeasureFilter(Metric metric) { 213 super(metric); 214 } 215 216 private boolean apply(Measure measure) { 217 return measure instanceof RuleMeasure 218 && filterOnMetricKey().equals(measure.getMetricKey()) 219 && measure.getPersonId() == null 220 && doApply((RuleMeasure) measure); 221 } 222 223 abstract boolean doApply(RuleMeasure ruleMeasure); 224 225 @Override 226 public M filter(Collection<Measure> measures) { 227 if (measures == null) { 228 return null; 229 } 230 for (Measure measure : measures) { 231 if (apply(measure)) { 232 return (M) measure; 233 } 234 } 235 return null; 236 } 237 } 238 239 /** 240 * @deprecated since 5.2. Useless by design because of Compute Engine 241 */ 242 @Deprecated 243 private static class RuleFilter extends AbstractRuleMeasureFilter<RuleMeasure> { 244 private RuleKey ruleKey; 245 246 protected RuleFilter(Metric metric, RuleKey ruleKey) { 247 super(metric); 248 this.ruleKey = ruleKey; 249 } 250 251 @Override 252 boolean doApply(RuleMeasure measure) { 253 return measure.ruleKey() != null 254 && ruleKey.equals(measure.ruleKey()); 255 } 256 } 257}