/* * Sonar, open source software quality management tool. * Copyright (C) 2009 SonarSource SA * * Sonar is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * Sonar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Sonar; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ package org.sonar.plugins.jlint.xml; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.RulePriorityMapper; import org.sonar.plugins.jlint.JlintPlugin; import org.sonar.plugins.jlint.JlintRulePriorityMapper; import java.io.IOException; import java.io.InputStream; import java.util.*; @XStreamAlias("JlintFilter") public class JlintFilter { private static final String PATTERN_SEPARATOR = ","; private static final String CODE_SEPARATOR = ","; private static final String CATEGORY_SEPARATOR = ","; @XStreamImplicit private List<Match> matchs; public JlintFilter() { matchs = new ArrayList<Match>(); } public String toXml() { XStream xstream = createXStream(); return xstream.toXML(this); } public List<Match> getMatchs() { return matchs; } public List<Match> getChildren() { return matchs; } public void setMatchs(List<Match> matchs) { this.matchs = matchs; } public void addMatch(Match child) { matchs.add(child); } public Map<String, RulePriority> getPatternLevels(RulePriorityMapper priorityMapper) { BugInfoSplitter splitter = new BugInfoSplitter() { public String getSeparator() { return PATTERN_SEPARATOR; } public String getVar(Bug bug) { return bug.getPattern(); } }; return processMatches(priorityMapper, splitter); } public Map<String, RulePriority> getCodeLevels(RulePriorityMapper priorityMapper) { BugInfoSplitter splitter = new BugInfoSplitter() { public String getSeparator() { return CODE_SEPARATOR; } public String getVar(Bug bug) { return bug.getCode(); } }; return processMatches(priorityMapper, splitter); } public Map<String, RulePriority> getCategoryLevels(RulePriorityMapper priorityMapper) { BugInfoSplitter splitter = new BugInfoSplitter() { public String getSeparator() { return CATEGORY_SEPARATOR; } public String getVar(Bug bug) { return bug.getCategory(); } }; return processMatches(priorityMapper, splitter); } private RulePriority getRulePriority(Priority priority, RulePriorityMapper priorityMapper) { return (priority != null) ? priorityMapper.from(priority.getValue()) : null; } private Map<String, RulePriority> processMatches(RulePriorityMapper priorityMapper, BugInfoSplitter splitter) { Map<String, RulePriority> result = new HashMap<String, RulePriority>(); for (Match child : getChildren()) { if (child.getOrs() != null) { for (OrFilter orFilter : child.getOrs()) { completeLevels(result, orFilter.getBugs(), child.getPriority(), priorityMapper, splitter); } } if (child.getBug() != null) { completeLevels(result, Arrays.asList(child.getBug()), child.getPriority(), priorityMapper, splitter); } } return result; } private void completeLevels(Map<String, RulePriority> result, List<Bug> bugs, Priority priority, RulePriorityMapper priorityMapper, BugInfoSplitter splitter) { if (bugs == null) { return; } RulePriority rulePriority = getRulePriority(priority, priorityMapper); for (Bug bug : bugs) { String varToSplit = splitter.getVar(bug); if (!StringUtils.isBlank(varToSplit)) { String[] splitted = StringUtils.split(varToSplit, splitter.getSeparator()); for (String code : splitted) { mapRulePriority(result, rulePriority, code); } } } } private interface BugInfoSplitter { String getVar(Bug bug); String getSeparator(); } private void mapRulePriority(Map<String, RulePriority> prioritiesByRule, RulePriority priority, String key) { if (prioritiesByRule.containsKey(key)) { if (prioritiesByRule.get(key).compareTo(priority) < 0) { prioritiesByRule.put(key, priority); } } else { prioritiesByRule.put(key, priority); } } public static XStream createXStream() { XStream xstream = new XStream(); xstream.processAnnotations(JlintFilter.class); xstream.processAnnotations(Match.class); xstream.processAnnotations(Bug.class); xstream.processAnnotations(Priority.class); xstream.processAnnotations(ClassFilter.class); xstream.processAnnotations(PackageFilter.class); xstream.processAnnotations(MethodFilter.class); xstream.processAnnotations(FieldFilter.class); xstream.processAnnotations(LocalFilter.class); xstream.processAnnotations(OrFilter.class); return xstream; } public static JlintFilter fromXml(String xml) { try { XStream xStream = createXStream(); InputStream inputStream = IOUtils.toInputStream(xml, "UTF-8"); return (JlintFilter) xStream.fromXML(inputStream); } catch (IOException e) { throw new RuntimeException("can't read configuration file", e); } } public static JlintFilter fromActiveRules(List<ActiveRule> activeRules, JlintRulePriorityMapper mapper) { JlintFilter root = new JlintFilter(); for (ActiveRule activeRule : activeRules) { if (JlintPlugin.KEY.equals(activeRule.getPluginName())) { Match child = createChild(activeRule, mapper); root.addMatch(child); } } return root; } private static Match createChild(ActiveRule activeRule, JlintRulePriorityMapper mapper) { Match child = new Match(); child.setBug(new Bug(activeRule.getConfigKey())); return child; } }