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      public static MeasuresFilter<RuleMeasure> rulePriority(final Metric metric, final RulePriority priority) {
064        return new RulePriorityFilter(metric, priority);
065      }
066    
067      public static MeasuresFilter<RuleMeasure> ruleCategory(final Metric metric, final Integer category) {
068        return new RuleCategoryFilter(metric, category);
069      }
070    
071      public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final Rule rule) {
072        return new RuleFilter(metric, rule);
073      }
074    
075      public static MeasuresFilter<Collection<RuleMeasure>> ruleCategories(final Metric metric) {
076        return new MetricFilter<Collection<RuleMeasure>>(metric) {
077    
078          private boolean apply(Measure measure) {
079            return measure instanceof RuleMeasure
080                && metric.equals(measure.getMetric())
081                && ((RuleMeasure) measure).getRule() == null
082                && ((RuleMeasure) measure).getRuleCategory() != null;
083          }
084    
085          public Collection<RuleMeasure> filter(Collection<Measure> measures) {
086            List<RuleMeasure> result = new ArrayList<RuleMeasure>();
087            if (measures != null) {
088              for (Measure measure : measures) {
089                if (apply(measure)) {
090                  result.add((RuleMeasure) measure);
091                }
092              }
093            }
094            return result;
095          }
096        };
097      }
098    
099      public static MeasuresFilter<Collection<RuleMeasure>> rules(final Metric metric) {
100        return new MetricFilter<Collection<RuleMeasure>>(metric) {
101    
102          private boolean apply(Measure measure) {
103            return measure instanceof RuleMeasure
104                && metric.equals(measure.getMetric())
105                && ((RuleMeasure) measure).getRule() != null;
106          }
107    
108          public Collection<RuleMeasure> filter(Collection<Measure> measures) {
109            if (measures == null) {
110              return null;
111            }
112            List<RuleMeasure> result = new ArrayList<RuleMeasure>();
113            for (Measure measure : measures) {
114              if (apply(measure)) {
115                result.add((RuleMeasure) measure);
116              }
117            }
118            return result;
119          }
120        };
121      }
122    
123      /**
124       * Used for internal optimizations.
125       */
126      public static abstract class MetricFilter<M> implements MeasuresFilter<M> {
127        private final Metric metric;
128    
129        protected MetricFilter(Metric metric) {
130          this.metric = metric;
131        }
132    
133        public Metric filterOnMetric() {
134          return metric;
135        }
136      }
137    
138      private abstract static class AbstractRuleMeasureFilter<M> extends MetricFilter<M> {
139        protected AbstractRuleMeasureFilter(Metric metric) {
140          super(metric);
141        }
142    
143        private boolean apply(Measure measure) {
144          return measure instanceof RuleMeasure
145              && filterOnMetric().equals(measure.getMetric())
146              && doApply((RuleMeasure) measure);
147        }
148    
149        abstract boolean doApply(RuleMeasure ruleMeasure);
150    
151        public M filter(Collection<Measure> measures) {
152          if (measures == null) {
153            return null;
154          }
155          for (Measure measure : measures) {
156            if (apply(measure)) {
157              return (M) measure;
158            }
159          }
160          return null;
161        }
162      }
163    
164      private static class RulePriorityFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
165        private RulePriority priority;
166    
167        protected RulePriorityFilter(Metric metric, RulePriority priority) {
168          super(metric);
169          this.priority = priority;
170        }
171    
172        @Override
173        boolean doApply(RuleMeasure measure) {
174          return measure.getRule() == null
175              && measure.getRuleCategory() == null
176              && priority.equals(measure.getRulePriority());
177        }
178      }
179    
180      private static class RuleCategoryFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
181        private Integer categ;
182    
183        protected RuleCategoryFilter(Metric metric, Integer categ) {
184          super(metric);
185          this.categ = categ;
186        }
187    
188        @Override
189        boolean doApply(RuleMeasure measure) {
190          return measure.getRule() == null
191              && categ.equals(measure.getRuleCategory())
192              && measure.getRulePriority() == null;
193        }
194      }
195    
196    
197      private static class RuleFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
198        private Rule rule;
199    
200        protected RuleFilter(Metric metric, Rule rule) {
201          super(metric);
202          this.rule = rule;
203        }
204    
205        @Override
206        boolean doApply(RuleMeasure measure) {
207          return measure.getRule() != null
208              && rule.equals(measure.getRule());
209        }
210      }
211    }