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