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;
021
022import java.io.Reader;
023import java.util.Map;
024
025import org.apache.commons.lang.StringUtils;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028import org.sonar.api.profiles.ProfileImporter;
029import org.sonar.api.profiles.RulesProfile;
030import org.sonar.api.resources.Java;
031import org.sonar.api.rules.Rule;
032import org.sonar.api.rules.RuleFinder;
033import org.sonar.api.rules.RulePriority;
034import org.sonar.api.rules.RuleQuery;
035import org.sonar.api.utils.ValidationMessages;
036import org.sonar.plugins.findbugs.xml.FindBugsFilter;
037
038import com.thoughtworks.xstream.XStream;
039
040public class FindbugsProfileImporter extends ProfileImporter {
041
042  private final RuleFinder ruleFinder;
043  private static final Logger LOG = LoggerFactory.getLogger(FindbugsProfileImporter.class);
044
045  public FindbugsProfileImporter(RuleFinder ruleFinder) {
046    super(FindbugsConstants.REPOSITORY_KEY, FindbugsConstants.PLUGIN_NAME);
047    setSupportedLanguages(Java.KEY);
048    this.ruleFinder = ruleFinder;
049  }
050
051  @Override
052  public RulesProfile importProfile(Reader findbugsConf, ValidationMessages messages) {
053    RulesProfile profile = RulesProfile.create();
054    try {
055      XStream xStream = FindBugsFilter.createXStream();
056      FindBugsFilter filter = (FindBugsFilter) xStream.fromXML(findbugsConf);
057
058      activateRulesByCategory(profile, filter, messages);
059      activateRulesByCode(profile, filter, messages);
060      activateRulesByPattern(profile, filter, messages);
061
062      return profile;
063    } catch (Exception e) {
064      String errorMessage = "The Findbugs configuration file is not valid";
065      messages.addErrorText(errorMessage + " : " + e.getMessage());
066      LOG.error(errorMessage, e);
067      return profile;
068    }
069  }
070
071  private void activateRulesByPattern(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) {
072    for (Map.Entry<String, RulePriority> patternLevel : filter.getPatternLevels(new FindbugsLevelUtils()).entrySet()) {
073      Rule rule = ruleFinder.findByKey(FindbugsConstants.REPOSITORY_KEY, patternLevel.getKey());
074      if (rule != null) {
075        profile.activateRule(rule, patternLevel.getValue());
076      } else {
077        messages.addWarningText("Unable to activate unknown rule : '" + patternLevel.getKey() + "'");
078      }
079    }
080  }
081
082  private void activateRulesByCode(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) {
083    for (Map.Entry<String, RulePriority> codeLevel : filter.getCodeLevels(new FindbugsLevelUtils()).entrySet()) {
084      boolean someRulesHaveBeenActivated = false;
085      for (Rule rule : ruleFinder.findAll(RuleQuery.create().withRepositoryKey(FindbugsConstants.REPOSITORY_KEY))) {
086        if (rule.getKey().equals(codeLevel.getKey()) || StringUtils.startsWith(rule.getKey(), codeLevel.getKey() + "_")) {
087          someRulesHaveBeenActivated = true;
088          profile.activateRule(rule, codeLevel.getValue());
089        }
090      }
091      if ( !someRulesHaveBeenActivated) {
092        messages.addWarningText("Unable to find any rules associated to code  : '" + codeLevel.getKey() + "'");
093      }
094    }
095  }
096
097  private void activateRulesByCategory(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) {
098    for (Map.Entry<String, RulePriority> categoryLevel : filter.getCategoryLevels(new FindbugsLevelUtils()).entrySet()) {
099      boolean someRulesHaveBeenActivated = false;
100      String sonarCateg = FindbugsCategory.findbugsToSonar(categoryLevel.getKey());
101      for (Rule rule : ruleFinder.findAll(RuleQuery.create().withRepositoryKey(FindbugsConstants.REPOSITORY_KEY))) {
102        if (sonarCateg != null && rule.getName().startsWith(sonarCateg)) {
103          someRulesHaveBeenActivated = true;
104          profile.activateRule(rule, categoryLevel.getValue());
105        }
106      }
107      if ( !someRulesHaveBeenActivated) {
108        messages.addWarningText("Unable to find any rules associated to category  : '" + categoryLevel.getKey() + "'");
109      }
110    }
111  }
112}