001/*
002 * SonarQube
003 * Copyright (C) 2009-2017 SonarSource SA
004 * mailto:info AT sonarsource DOT com
005 *
006 * This program 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 * This program 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 java.util.ArrayList;
023import java.util.Collection;
024import java.util.List;
025import javax.annotation.Nullable;
026import org.sonar.api.rule.RuleKey;
027import org.sonar.api.rules.Rule;
028
029/**
030 * @since 1.10
031 * @deprecated since 5.6. Sensor should only save measures and not read them.
032 */
033@Deprecated
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(@Nullable 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.getPersonId() == null) {
069            return measure;
070          }
071        }
072        return null;
073      }
074    };
075  }
076
077  /**
078   * @since 2.0
079   */
080  public static MeasuresFilter<Measure> measure(final Measure measure) {
081    return new MeasuresFilter<Measure>() {
082      @Override
083      public Measure filter(@Nullable Collection<Measure> measures) {
084        if (measures == null) {
085          return null;
086        }
087        for (Measure m : measures) {
088          if (m.equals(measure)) {
089            return m;
090          }
091        }
092        return null;
093      }
094    };
095  }
096
097  public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final RuleKey ruleKey) {
098    return new RuleFilter(metric, ruleKey);
099  }
100
101  public static MeasuresFilter<RuleMeasure> rule(final Metric metric, final Rule rule) {
102    return rule(metric, rule.ruleKey());
103  }
104
105  public static MeasuresFilter<Collection<RuleMeasure>> rules(final Metric metric) {
106    return new MetricFilter<Collection<RuleMeasure>>(metric) {
107
108      private boolean apply(Measure measure) {
109        return measure instanceof RuleMeasure && metric.equals(measure.getMetric())
110          && measure.getPersonId() == null && ((RuleMeasure) measure).ruleKey() != null;
111      }
112
113      @Override
114      public Collection<RuleMeasure> filter(@Nullable Collection<Measure> measures) {
115        if (measures == null) {
116          return null;
117        }
118        List<RuleMeasure> result = new ArrayList<>();
119        for (Measure measure : measures) {
120          if (apply(measure)) {
121            result.add((RuleMeasure) measure);
122          }
123        }
124        return result;
125      }
126    };
127  }
128
129  /**
130   * Used for internal optimizations.
131   */
132  public abstract static class MetricFilter<M> implements MeasuresFilter<M> {
133    private final String metricKey;
134
135    protected MetricFilter(Metric metric) {
136      this.metricKey = metric.getKey();
137    }
138
139    protected MetricFilter(String metricKey) {
140      this.metricKey = metricKey;
141    }
142
143    public String filterOnMetricKey() {
144      return metricKey;
145    }
146  }
147
148  /**
149   * @deprecated since 5.2. The measures related to rules are computed on server side by Compute Engine.
150   */
151  @Deprecated
152  private abstract static class AbstractRuleMeasureFilter<M> extends MetricFilter<M> {
153    protected AbstractRuleMeasureFilter(Metric metric) {
154      super(metric);
155    }
156
157    private boolean apply(Measure measure) {
158      return measure instanceof RuleMeasure
159        && filterOnMetricKey().equals(measure.getMetricKey())
160        && measure.getPersonId() == null
161        && doApply((RuleMeasure) measure);
162    }
163
164    abstract boolean doApply(RuleMeasure ruleMeasure);
165
166    @Override
167    public M filter(@Nullable Collection<Measure> measures) {
168      if (measures == null) {
169        return null;
170      }
171      for (Measure measure : measures) {
172        if (apply(measure)) {
173          return (M) measure;
174        }
175      }
176      return null;
177    }
178  }
179
180  /**
181   * @deprecated since 5.2. Useless by design because of Compute Engine
182   */
183  @Deprecated
184  private static class RuleFilter extends AbstractRuleMeasureFilter<RuleMeasure> {
185    private RuleKey ruleKey;
186
187    protected RuleFilter(Metric metric, RuleKey ruleKey) {
188      super(metric);
189      this.ruleKey = ruleKey;
190    }
191
192    @Override
193    boolean doApply(RuleMeasure measure) {
194      return measure.ruleKey() != null
195        && ruleKey.equals(measure.ruleKey());
196    }
197  }
198}