001    /*
002     * Copyright (C) 2010 Evgeny Mandrikov
003     *
004     * Sonar-IDE is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Lesser General Public
006     * License as published by the Free Software Foundation; either
007     * version 3 of the License, or (at your option) any later version.
008     *
009     * Sonar-IDE is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with Sonar-IDE; if not, write to the Free Software
016     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
017     */
018    
019    package org.sonar.ide.shared.violations;
020    
021    import org.apache.commons.lang.builder.ToStringBuilder;
022    import org.sonar.ide.api.SourceCodeDiff;
023    import org.sonar.wsclient.services.Violation;
024    
025    import java.util.*;
026    
027    /**
028     * @author Evgeny Mandrikov
029     */
030    public final class ViolationUtils {
031      public static final String PRIORITY_BLOCKER = "blocker";
032      public static final String PRIORITY_CRITICAL = "critical";
033      public static final String PRIORITY_MAJOR = "major";
034      public static final String PRIORITY_MINOR = "minor";
035      public static final String PRIORITY_INFO = "info";
036    
037      /**
038       * Sorts violations by priority in descending order.
039       *
040       * @param violations list of violations to sort
041       * @return sorted list of violations
042       */
043      public static List<Violation> sortByPriority(List<Violation> violations) {
044        Collections.sort(violations, new PriorityComparator());
045        return violations;
046      }
047    
048      public static Map<Integer, List<Violation>> splitByLines(Collection<Violation> violations) {
049        Map<Integer, List<Violation>> violationsByLine = new HashMap<Integer, List<Violation>>();
050        for (Violation violation : violations) {
051          final List<Violation> collection;
052          if (violationsByLine.containsKey(violation.getLine())) {
053            collection = violationsByLine.get(violation.getLine());
054          } else {
055            collection = new ArrayList<Violation>();
056            violationsByLine.put(violation.getLine(), collection);
057          }
058          collection.add(violation);
059        }
060        return violationsByLine;
061      }
062    
063      /**
064       * Converts priority from string to integer.
065       *
066       * @param priority priority to convert
067       * @return converted priority
068       */
069      public static int convertPriority(String priority) {
070        if (PRIORITY_BLOCKER.equalsIgnoreCase(priority)) {
071          return 0;
072        } else if (PRIORITY_CRITICAL.equalsIgnoreCase(priority)) {
073          return 1;
074        } else if (PRIORITY_MAJOR.equalsIgnoreCase(priority)) {
075          return 2;
076        } else if (PRIORITY_MINOR.equalsIgnoreCase(priority)) {
077          return 3;
078        } else if (PRIORITY_INFO.equalsIgnoreCase(priority)) {
079          return 4;
080        }
081        return 4;
082      }
083    
084      public static String getDescription(Violation violation) {
085        return violation.getRuleName() + " : " + violation.getMessage();
086      }
087    
088      public static List<Violation> convertLines(Collection<Violation> violations, SourceCodeDiff diff) {
089        List<Violation> result = new ArrayList<Violation>();
090    
091        for (Violation violation : violations) {
092          Integer originalLine = violation.getLine();
093          if (originalLine == null || originalLine == 0) {
094            // skip violation on whole file
095            // TODO Godin: we can show them on first line
096            continue;
097          }
098    
099          int newLine = diff.newLine(originalLine);
100          // skip violation, which doesn't match any line
101          if (newLine != -1) {
102            violation.setLine(newLine);
103            result.add(violation);
104          }
105        }
106        return result;
107      }
108    
109      static class PriorityComparator implements Comparator<Violation> {
110        public int compare(Violation o1, Violation o2) {
111          int p1 = convertPriority(o1.getPriority());
112          int p2 = convertPriority(o2.getPriority());
113          return p1 - p2;
114        }
115      }
116    
117      /**
118       * @param violations collection to convert to string
119       * @return string representation of collection
120       * @see #toString(org.sonar.wsclient.services.Violation)
121       */
122      public static String toString(Collection<Violation> violations) {
123        StringBuilder sb = new StringBuilder().append('[');
124        for (Violation violation : violations) {
125          sb.append(toString(violation)).append(',');
126        }
127        sb.append(']');
128        return sb.toString();
129      }
130    
131      /**
132       * TODO Godin: can we include this method into sonar-ws-client for debug purposes ?
133       *
134       * @param violation violation to convert to string
135       * @return string representation of violation
136       * @see #toString(java.util.Collection)
137       */
138      public static String toString(Violation violation) {
139        return new ToStringBuilder(violation)
140            .append("message", violation.getMessage())
141            .append("priority", violation.getPriority())
142            .append("line", violation.getLine())
143            .toString();
144      }
145    
146      /**
147       * Hide utility-class constructor.
148       */
149      private ViolationUtils() {
150      }
151    }