001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar 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 * Sonar 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
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.measures;
021
022 import org.sonar.api.rules.Rule;
023 import org.sonar.api.rules.RulePriority;
024
025 import java.util.ArrayList;
026 import java.util.Collection;
027 import java.util.List;
028
029 /**
030 * @since 1.10
031 */
032 public final class MeasuresFilters {
033
034 private MeasuresFilters() {
035 }
036
037 public static MeasuresFilter<Collection<Measure>> all() {
038 return new MeasuresFilter<Collection<Measure>>() {
039 public Collection<Measure> filter(Collection<Measure> measures) {
040 return measures;
041 }
042 };
043 }
044
045 public static MeasuresFilter<Measure> metric(final Metric metric) {
046 return new MetricFilter<Measure>(metric) {
047
048 public Measure filter(Collection<Measure> measures) {
049 if (measures == null) {
050 return null;
051 }
052 for (Measure measure : measures) {
053 if (measure.getClass().equals(Measure.class) &&
054 measure.getMetric().equals(metric)) {
055 return measure;
056 }
057 }
058 return null;
059 }
060 };
061 }
062
063 /**
064 * @since 2.0
065 */
066 public static MeasuresFilter<Measure> measure(final Measure measure) {
067 return new MeasuresFilter<Measure>() {
068 public Measure filter(Collection<Measure> measures) {
069 if (measures==null) {
070 return null;
071 }
072 for (Measure m : measures) {
073 if (m.equals(measure)) {
074 return m;
075 }
076 }
077 return null;
078 }
079 };
080 }
081
082 public static MeasuresFilter<RuleMeasure> rulePriority(final Metric metric, final RulePriority priority) {
083 return new RulePriorityFilter(metric, priority);
084 }
085
086 public static MeasuresFilter<RuleMeasure> ruleCategory(final Metric metric, final Integer category) {
087 return new RuleCategoryFilter(metric, category);
088 }
089
090 public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final Rule rule) {
091 return new RuleFilter(metric, rule);
092 }
093
094 public static MeasuresFilter<Collection<RuleMeasure>> ruleCategories(final Metric metric) {
095 return new MetricFilter<Collection<RuleMeasure>>(metric) {
096
097 private boolean apply(Measure measure) {
098 return measure instanceof RuleMeasure
099 && metric.equals(measure.getMetric())
100 && ((RuleMeasure) measure).getRule() == null
101 && ((RuleMeasure) measure).getRuleCategory() != null;
102 }
103
104 public Collection<RuleMeasure> filter(Collection<Measure> measures) {
105 List<RuleMeasure> result = new ArrayList<RuleMeasure>();
106 if (measures != null) {
107 for (Measure measure : measures) {
108 if (apply(measure)) {
109 result.add((RuleMeasure) measure);
110 }
111 }
112 }
113 return result;
114 }
115 };
116 }
117
118 public static MeasuresFilter<Collection<RuleMeasure>> rules(final Metric metric) {
119 return new MetricFilter<Collection<RuleMeasure>>(metric) {
120
121 private boolean apply(Measure measure) {
122 return measure instanceof RuleMeasure
123 && metric.equals(measure.getMetric())
124 && ((RuleMeasure) measure).getRule() != null;
125 }
126
127 public Collection<RuleMeasure> filter(Collection<Measure> measures) {
128 if (measures == null) {
129 return null;
130 }
131 List<RuleMeasure> result = new ArrayList<RuleMeasure>();
132 for (Measure measure : measures) {
133 if (apply(measure)) {
134 result.add((RuleMeasure) measure);
135 }
136 }
137 return result;
138 }
139 };
140 }
141
142 /**
143 * Used for internal optimizations.
144 */
145 public static abstract class MetricFilter<M> implements MeasuresFilter<M> {
146 private final Metric metric;
147
148 protected MetricFilter(Metric metric) {
149 this.metric = metric;
150 }
151
152 public Metric filterOnMetric() {
153 return metric;
154 }
155 }
156
157 private abstract static class AbstractRuleMeasureFilter<M> extends MetricFilter<M> {
158 protected AbstractRuleMeasureFilter(Metric metric) {
159 super(metric);
160 }
161
162 private boolean apply(Measure measure) {
163 return measure instanceof RuleMeasure
164 && filterOnMetric().equals(measure.getMetric())
165 && doApply((RuleMeasure) measure);
166 }
167
168 abstract boolean doApply(RuleMeasure ruleMeasure);
169
170 public M filter(Collection<Measure> measures) {
171 if (measures == null) {
172 return null;
173 }
174 for (Measure measure : measures) {
175 if (apply(measure)) {
176 return (M) measure;
177 }
178 }
179 return null;
180 }
181 }
182
183 private static class RulePriorityFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
184 private RulePriority priority;
185
186 protected RulePriorityFilter(Metric metric, RulePriority priority) {
187 super(metric);
188 this.priority = priority;
189 }
190
191 @Override
192 boolean doApply(RuleMeasure measure) {
193 return measure.getRule() == null
194 && measure.getRuleCategory() == null
195 && priority.equals(measure.getRulePriority());
196 }
197 }
198
199 private static class RuleCategoryFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
200 private Integer categ;
201
202 protected RuleCategoryFilter(Metric metric, Integer categ) {
203 super(metric);
204 this.categ = categ;
205 }
206
207 @Override
208 boolean doApply(RuleMeasure measure) {
209 return measure.getRule() == null
210 && categ.equals(measure.getRuleCategory())
211 && measure.getRulePriority() == null;
212 }
213 }
214
215
216 private static class RuleFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
217 private Rule rule;
218
219 protected RuleFilter(Metric metric, Rule rule) {
220 super(metric);
221 this.rule = rule;
222 }
223
224 @Override
225 boolean doApply(RuleMeasure measure) {
226 return measure.getRule() != null
227 && rule.equals(measure.getRule());
228 }
229 }
230 }