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     */
020    package org.sonar.server.filters;
021    
022    import com.google.common.collect.Lists;
023    import com.google.common.collect.Sets;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.apache.commons.lang.builder.ReflectionToStringBuilder;
027    import org.apache.commons.lang.builder.ToStringStyle;
028    import org.sonar.api.resources.Qualifiers;
029    
030    import java.util.List;
031    import java.util.Set;
032    
033    public class Filter {
034    
035      // path
036      private Integer rootSnapshotId;
037      private Integer baseSnapshotId;
038      private String baseSnapshotPath;
039    
040      // filters on resources
041      private Set<String> scopes;
042      private Set<String> qualifiers;
043      private Set<String> languages;
044      private Set<Integer> favouriteIds;
045      private DateCriterion dateCriterion;
046      private String keyRegexp;
047      private String nameRegexp;
048      private boolean isViewContext = false;
049    
050      // filters on measures
051      private List<MeasureCriterion> measureCriteria = Lists.newLinkedList();
052      private int periodIndex = 0;
053    
054      // sorting
055      private Integer sortedMetricId;
056      private Boolean sortedByMeasureVariation = Boolean.FALSE;
057      private boolean sortedByLanguage;
058      private boolean sortedByName;
059      private boolean sortedByKey;
060      private boolean sortedByDate;
061      private boolean sortedByVersion;
062      private boolean isNumericMetric = true;
063      private boolean ascendingSort = true;
064    
065      public Filter setPath(Integer rootSnapshotId, Integer snapshotId, String snapshotPath, boolean isViewContext) {
066        this.baseSnapshotId = snapshotId;
067        if (rootSnapshotId == null) {
068          this.rootSnapshotId = snapshotId;
069        } else {
070          this.rootSnapshotId = rootSnapshotId;
071        }
072        this.baseSnapshotPath = StringUtils.defaultString(snapshotPath, ""); //With Oracle the path can be null (see SONAR-2582)
073        this.isViewContext = isViewContext;
074        return this;
075      }
076    
077      public Integer getRootSnapshotId() {
078        return rootSnapshotId;
079      }
080    
081      public boolean hasBaseSnapshot() {
082        return baseSnapshotId != null;
083      }
084    
085      public Integer getBaseSnapshotId() {
086        return baseSnapshotId;
087      }
088    
089      public String getBaseSnapshotPath() {
090        return baseSnapshotPath;
091      }
092    
093      public boolean isViewContext() {
094        return isViewContext;
095      }
096    
097      public void setViewContext(boolean b) {
098        isViewContext = b;
099      }
100    
101      public Set<String> getScopes() {
102        return scopes;
103      }
104    
105      public boolean hasScopes() {
106        return scopes != null && !scopes.isEmpty();
107      }
108    
109      public Filter setScopes(Set<String> scopes) {
110        this.scopes = scopes;
111        return this;
112      }
113    
114      public Filter setScopes(String... scopes) {
115        this.scopes = Sets.newHashSet(scopes);
116        return this;
117      }
118    
119      public Set<String> getQualifiers() {
120        return qualifiers;
121      }
122    
123      public boolean hasQualifiers() {
124        return qualifiers != null && !qualifiers.isEmpty();
125      }
126    
127      public Filter setQualifiers(Set<String> qualifiers) {
128        this.qualifiers = qualifiers;
129        return this;
130      }
131    
132      public Filter setQualifiers(String... qualifiers) {
133        this.qualifiers = Sets.newHashSet(qualifiers);
134        return this;
135      }
136    
137      public Set<String> getLanguages() {
138        return languages;
139      }
140    
141      public boolean hasLanguages() {
142        return languages != null && !languages.isEmpty();
143      }
144    
145      public Filter setLanguages(Set<String> languages) {
146        this.languages = languages;
147        return this;
148      }
149    
150      public Filter setLanguages(String... languages) {
151        this.languages = Sets.newHashSet(languages);
152        return this;
153      }
154    
155      public Set<Integer> getFavouriteIds() {
156        return favouriteIds;
157      }
158    
159      public boolean hasFavouriteIds() {
160        return favouriteIds != null && !favouriteIds.isEmpty();
161      }
162    
163      public Filter setFavouriteIds(Set<Integer> favouriteIds) {
164        this.favouriteIds = favouriteIds;
165        return this;
166      }
167    
168      public Filter setFavouriteIds(Integer... favouriteIds) {
169        this.favouriteIds = Sets.newHashSet(favouriteIds);
170        return this;
171      }
172    
173      public Integer getSortedMetricId() {
174        return sortedMetricId;
175      }
176    
177      public boolean isNumericMetric() {
178        return isNumericMetric;
179      }
180    
181      public boolean isTextSort() {
182        return !isNumericMetric || sortedByLanguage || sortedByName || sortedByVersion || sortedByKey;
183      }
184    
185      public Filter setSortedMetricId(Integer id, boolean isNumericValue, Boolean isVariation) {
186        unsetSorts();
187        this.sortedMetricId = id;
188        this.isNumericMetric = isNumericValue;
189        this.sortedByMeasureVariation = isVariation;
190        return this;
191      }
192    
193      public boolean isSortedByLanguage() {
194        return sortedByLanguage;
195      }
196    
197      public Filter setSortedByLanguage() {
198        unsetSorts();
199        this.sortedByLanguage = true;
200        return this;
201      }
202    
203      public boolean isSortedByName() {
204        return sortedByName;
205      }
206    
207      public boolean isSortedByKey() {
208        return sortedByKey;
209      }
210    
211      public boolean isSortedByVersion() {
212        return sortedByVersion;
213      }
214    
215      public Filter setSortedByVersion() {
216        unsetSorts();
217        this.sortedByVersion = true;
218        return this;
219      }
220    
221      public boolean isSorted() {
222        return isSortedByLanguage() || isSortedByName() || isSortedByKey() || isSortedByDate() || isSortedByVersion() || getSortedMetricId() != null;
223      }
224    
225      public boolean isSortedByDate() {
226        return sortedByDate;
227      }
228    
229      public Filter setSortedByDate() {
230        unsetSorts();
231        sortedByDate = true;
232        return this;
233      }
234    
235      public Filter setSortedByName() {
236        unsetSorts();
237        this.sortedByName = true;
238        return this;
239      }
240    
241      public Filter setSortedByKey() {
242        unsetSorts();
243        this.sortedByKey = true;
244        return this;
245      }
246    
247      private void unsetSorts() {
248        this.sortedByDate = false;
249        this.sortedByLanguage = false;
250        this.sortedByName = false;
251        this.sortedByKey = false;
252        this.sortedMetricId = null;
253        this.sortedByVersion = false;
254        this.isNumericMetric = true;
255      }
256    
257      public List<MeasureCriterion> getMeasureCriteria() {
258        return measureCriteria;
259      }
260    
261      public Filter setMeasureCriteria(List<MeasureCriterion> l) {
262        this.measureCriteria = l;
263        return this;
264      }
265    
266      public Filter addMeasureCriterion(MeasureCriterion c) {
267        this.measureCriteria.add(c);
268        return this;
269      }
270    
271      public Filter createMeasureCriterionOnValue(Integer metricId, String operator, Double value, Boolean variation) {
272        this.measureCriteria.add(new MeasureCriterion(metricId, operator, value, variation));
273        return this;
274      }
275    
276      public boolean hasMeasureCriteria() {
277        return !measureCriteria.isEmpty();
278      }
279    
280      protected boolean hasMeasureCriteriaOnMetric(Integer metricId) {
281        if (metricId != null) {
282          for (MeasureCriterion criterion : measureCriteria) {
283            if (metricId.equals(criterion.getMetricId())) {
284              return true;
285            }
286          }
287        }
288        return false;
289      }
290    
291      public boolean mustJoinMeasuresTable() {
292        return sortedMetricId != null || hasMeasureCriteria();
293      }
294    
295      public boolean isAscendingSort() {
296        return ascendingSort;
297      }
298    
299      public Filter setAscendingSort(boolean b) {
300        this.ascendingSort = b;
301        return this;
302      }
303    
304      public DateCriterion getDateCriterion() {
305        return dateCriterion;
306      }
307    
308      public Filter setDateCriterion(DateCriterion dc) {
309        this.dateCriterion = dc;
310        return this;
311      }
312    
313      public Filter setDateCriterion(String operator, Integer daysAgo) {
314        this.dateCriterion = new DateCriterion().setOperator(operator).setDate(daysAgo);
315        return this;
316      }
317    
318      public String getKeyRegexp() {
319        return keyRegexp;
320      }
321    
322      public Filter setKeyRegexp(String s) {
323        this.keyRegexp = s;
324        return this;
325      }
326    
327      public String getNameRegexp() {
328        return nameRegexp;
329      }
330    
331      public Filter setNameRegexp(String s) {
332        this.nameRegexp = s;
333        return this;
334      }
335    
336      public int getPeriodIndex() {
337        return periodIndex;
338      }
339    
340      public void setPeriodIndex(int i) {
341        this.periodIndex = i;
342      }
343    
344      public boolean isOnPeriod() {
345        return periodIndex > 0;
346      }
347    
348      static String getVariationColumn(int periodIndex) {
349        switch (periodIndex) {
350          case 1:
351            return "variation_value_1";
352          case 2:
353            return "variation_value_2";
354          case 3:
355            return "variation_value_3";
356          case 4:
357            return "variation_value_4";
358          case 5:
359            return "variation_value_5";
360          default:
361            return null;
362        }
363      }
364    
365      String getColumnToSort() {
366        String col = "text_value";
367        if (isNumericMetric()) {
368          col = (sortedByMeasureVariation == Boolean.TRUE ? getVariationColumn(periodIndex) : "value");
369        }
370        return col;
371      }
372    
373      public boolean mustReturnEmptyResult() {
374        boolean hasCriterionOnVariation = false;
375        for (MeasureCriterion criterion : measureCriteria) {
376          if (criterion.isVariation() == Boolean.TRUE) {
377            hasCriterionOnVariation = true;
378          }
379        }
380        return (hasCriterionOnVariation && !isOnPeriod());
381      }
382    
383      @Override
384      public String toString() {
385        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
386      }
387    
388      public static Filter createForAllQualifiers() {
389        return new Filter().setQualifiers(
390            Qualifiers.VIEW, Qualifiers.SUBVIEW,
391            Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.DIRECTORY, Qualifiers.PACKAGE,
392            Qualifiers.FILE, Qualifiers.CLASS, Qualifiers.UNIT_TEST_FILE, Qualifiers.LIBRARY, Qualifiers.PARAGRAPH);
393      }
394    }