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.plugins.findbugs.xml; 021 022import com.thoughtworks.xstream.XStream; 023import com.thoughtworks.xstream.annotations.XStreamAlias; 024import com.thoughtworks.xstream.annotations.XStreamImplicit; 025import org.apache.commons.lang.StringUtils; 026import org.sonar.api.rules.RulePriority; 027import org.sonar.plugins.findbugs.FindbugsLevelUtils; 028 029import java.util.*; 030 031@XStreamAlias("FindBugsFilter") 032public class FindBugsFilter { 033 034 private static final String PATTERN_SEPARATOR = ","; 035 private static final String CODE_SEPARATOR = ","; 036 private static final String CATEGORY_SEPARATOR = ","; 037 038 @XStreamImplicit 039 private List<Match> matchs; 040 041 public FindBugsFilter() { 042 matchs = new ArrayList<Match>(); 043 } 044 045 public String toXml() { 046 XStream xstream = createXStream(); 047 return xstream.toXML(this); 048 } 049 050 public List<Match> getMatchs() { 051 return matchs; 052 } 053 054 public List<Match> getChildren() { 055 return matchs; 056 } 057 058 public void setMatchs(List<Match> matchs) { 059 this.matchs = matchs; 060 } 061 062 public void addMatch(Match child) { 063 matchs.add(child); 064 } 065 066 public Map<String, RulePriority> getPatternLevels(FindbugsLevelUtils priorityMapper) { 067 BugInfoSplitter splitter = new BugInfoSplitter() { 068 public String getSeparator() { 069 return PATTERN_SEPARATOR; 070 } 071 072 public String getVar(Bug bug) { 073 return bug.getPattern(); 074 } 075 }; 076 return processMatches(priorityMapper, splitter); 077 } 078 079 public Map<String, RulePriority> getCodeLevels(FindbugsLevelUtils priorityMapper) { 080 BugInfoSplitter splitter = new BugInfoSplitter() { 081 public String getSeparator() { 082 return CODE_SEPARATOR; 083 } 084 085 public String getVar(Bug bug) { 086 return bug.getCode(); 087 } 088 }; 089 return processMatches(priorityMapper, splitter); 090 } 091 092 public Map<String, RulePriority> getCategoryLevels(FindbugsLevelUtils priorityMapper) { 093 BugInfoSplitter splitter = new BugInfoSplitter() { 094 public String getSeparator() { 095 return CATEGORY_SEPARATOR; 096 } 097 098 public String getVar(Bug bug) { 099 return bug.getCategory(); 100 } 101 }; 102 return processMatches(priorityMapper, splitter); 103 } 104 105 private RulePriority getRulePriority(Priority priority, FindbugsLevelUtils priorityMapper) { 106 return priority != null ? priorityMapper.from(priority.getValue()) : null; 107 } 108 109 private Map<String, RulePriority> processMatches(FindbugsLevelUtils priorityMapper, BugInfoSplitter splitter) { 110 Map<String, RulePriority> result = new HashMap<String, RulePriority>(); 111 for (Match child : getChildren()) { 112 if (child.getOrs() != null) { 113 for (OrFilter orFilter : child.getOrs()) { 114 completeLevels(result, orFilter.getBugs(), child.getPriority(), priorityMapper, splitter); 115 } 116 } 117 if (child.getBug() != null) { 118 completeLevels(result, Arrays.asList(child.getBug()), child.getPriority(), priorityMapper, splitter); 119 } 120 } 121 return result; 122 } 123 124 private void completeLevels(Map<String, RulePriority> result, List<Bug> bugs, Priority priority, FindbugsLevelUtils priorityMapper, BugInfoSplitter splitter) { 125 if (bugs == null) { 126 return; 127 } 128 RulePriority rulePriority = getRulePriority(priority, priorityMapper); 129 for (Bug bug : bugs) { 130 String varToSplit = splitter.getVar(bug); 131 if (!StringUtils.isBlank(varToSplit)) { 132 String[] splitted = StringUtils.split(varToSplit, splitter.getSeparator()); 133 for (String code : splitted) { 134 mapRulePriority(result, rulePriority, code); 135 } 136 } 137 } 138 } 139 140 private interface BugInfoSplitter { 141 String getVar(Bug bug); 142 143 String getSeparator(); 144 } 145 146 private void mapRulePriority(Map<String, RulePriority> prioritiesByRule, RulePriority priority, String key) { 147 if (prioritiesByRule.containsKey(key) && prioritiesByRule.get(key) != null) { 148 if (prioritiesByRule.get(key).compareTo(priority) < 0) { 149 prioritiesByRule.put(key, priority); 150 } 151 } else { 152 prioritiesByRule.put(key, priority); 153 } 154 } 155 156 public static XStream createXStream() { 157 XStream xstream = new XStream(); 158 xstream.setClassLoader(FindBugsFilter.class.getClassLoader()); 159 xstream.processAnnotations(FindBugsFilter.class); 160 xstream.processAnnotations(Match.class); 161 xstream.processAnnotations(Bug.class); 162 xstream.processAnnotations(Priority.class); 163 xstream.processAnnotations(ClassFilter.class); 164 xstream.processAnnotations(PackageFilter.class); 165 xstream.processAnnotations(MethodFilter.class); 166 xstream.processAnnotations(FieldFilter.class); 167 xstream.processAnnotations(LocalFilter.class); 168 xstream.processAnnotations(OrFilter.class); 169 return xstream; 170 } 171}