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     */
020    package org.sonar.plugins.findbugs;
021    
022    import java.io.Reader;
023    import java.util.Map;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    import org.sonar.api.profiles.ProfileImporter;
029    import org.sonar.api.profiles.RulesProfile;
030    import org.sonar.api.resources.Java;
031    import org.sonar.api.rules.Rule;
032    import org.sonar.api.rules.RuleFinder;
033    import org.sonar.api.rules.RulePriority;
034    import org.sonar.api.rules.RuleQuery;
035    import org.sonar.api.utils.ValidationMessages;
036    import org.sonar.plugins.findbugs.xml.FindBugsFilter;
037    
038    import com.thoughtworks.xstream.XStream;
039    
040    public 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    }