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