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.server.filters;
021
022import com.google.common.collect.Ordering;
023
024import java.io.Serializable;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.Comparator;
028import java.util.Iterator;
029import java.util.List;
030
031public class FilterResult {
032  private List<Object[]> rows;
033  private Filter filter;
034  public static final int SORTED_COLUMN_INDEX = 3;
035
036  public FilterResult(Filter filter, List<Object[]> rows) {
037    this.rows = new ArrayList<Object[]>(rows);
038    this.filter = filter;
039  }
040
041  /**
042   * @return a list of arrays
043   */
044  public List<Object[]> getRows() {
045    return rows;
046  }
047
048  public int size() {
049    return rows.size();
050  }
051
052  public Integer getSnapshotId(Object[] row) {
053    return (Integer) row[getSnapshotIdIndex()];
054  }
055
056  public Integer getProjectId(Object[] row) {
057    return (Integer) row[getProjectIdIndex()];
058  }
059
060  public Integer getRootProjectId(Object[] row) {
061    return (Integer) row[getRootProjectIdIndex()];
062  }
063
064  public int getSnapshotIdIndex() {
065    return 0;
066  }
067
068  public int getProjectIdIndex() {
069    return 1;
070  }
071
072  public int getRootProjectIdIndex() {
073    return 2;
074  }
075
076  public void sort() {
077    if (filter.isSorted()) {
078      Comparator<Object[]> comparator = (filter.isTextSort() ? new StringIgnoreCaseComparator(SORTED_COLUMN_INDEX) : new NumericComparator(SORTED_COLUMN_INDEX));
079      if (!filter.isAscendingSort()) {
080        comparator = Ordering.from(comparator).reverse();
081      }
082      Collections.sort(rows, comparator);
083    }
084  }
085
086  public void removeUnvalidRows() {
087    int numberOfCriteria = filter.getMeasureCriteria().size();
088    if (numberOfCriteria > 0) {
089      int fromColumnIndex = (filter.isSorted() ? SORTED_COLUMN_INDEX + 1 : SORTED_COLUMN_INDEX);
090      for (Iterator<Object[]> it = rows.iterator(); it.hasNext(); ) {
091        Object[] row = it.next();
092        boolean remove = false;
093        for (int index = 0; index < numberOfCriteria; index++) {
094          if (row[fromColumnIndex + index] == null) {
095            remove = true;
096          }
097        }
098        if (remove) {
099          it.remove();
100        }
101      }
102    }
103  }
104
105  static final class NumericComparator implements Comparator<Object[]>, Serializable {
106    private static final long serialVersionUID = 4627704879575964978L;
107    private int index;
108
109    NumericComparator(int index) {
110      this.index = index;
111    }
112
113    public int compare(Object[] a1, Object[] a2) {
114      Comparable c1 = (Comparable) a1[index];
115      Comparable o2 = (Comparable) a2[index];
116
117      return (c1 == null ? -1 : (o2 == null ? 1 : c1.compareTo(o2)));
118    }
119  }
120
121  static final class StringIgnoreCaseComparator implements Comparator<Object[]>, Serializable {
122    private static final long serialVersionUID = 963926659201833101L;
123    private int index;
124
125    StringIgnoreCaseComparator(int index) {
126      this.index = index;
127    }
128
129    public int compare(Object[] o1, Object[] o2) {
130      String s1 = (String) o1[index];
131      if (s1 == null) {
132        return -1;
133      }
134      String s2 = (String) o2[index];
135      if (s2 == null) {
136        return 1;
137      }
138      return s1.compareToIgnoreCase(s2);
139    }
140  }
141}
142