/* * Sonar Flex Plugin * Copyright (C) 2010 SonarSource * dev@sonar.codehaus.org * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ package org.sonar.plugins.flex.flexpmd.xml; import com.thoughtworks.xstream.XStream; import org.apache.commons.io.IOUtils; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.*; import org.sonar.api.utils.SonarException; import org.sonar.plugins.flex.flexpmd.FlexPmdConstants; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public final class FlexRulesUtils { private FlexRulesUtils() { } public static Ruleset buildRuleSetFromXml(String configuration) { XStream xstream = new XStream(); xstream.setClassLoader(FlexRulesUtils.class.getClassLoader()); xstream.processAnnotations(Ruleset.class); xstream.processAnnotations(FlexRule.class); xstream.processAnnotations(Property.class); xstream.aliasSystemAttribute("ref", "class"); return (Ruleset) xstream.fromXML(configuration); } public static String buildXmlFromRuleset(Ruleset tree) { XStream xstream = new XStream(); xstream.setClassLoader(FlexRulesUtils.class.getClassLoader()); xstream.processAnnotations(Ruleset.class); xstream.processAnnotations(FlexRule.class); xstream.processAnnotations(Property.class); return addHeaderToXml(xstream.toXML(tree)); } private static String addHeaderToXml(String xmlModules) { String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; return header + xmlModules; } public static String getConfigurationFromFile(String path) { InputStream inputStream = Ruleset.class.getResourceAsStream(path); String configuration = null; try { configuration = IOUtils.toString(inputStream, "UTF-8"); } catch (IOException e) { throw new SonarException("Unable to read configuration file for the profile : " + path, e); } finally { IOUtils.closeQuietly(inputStream); } return configuration; } private static final String resourcePath = "/org/sonar/plugins/flex/flexpmd/"; public static List<Rule> getInitialReferential() { return parseReferential(resourcePath + "rules.xml"); } public static List<Rule> parseReferential(String path) { Ruleset ruleset = FlexRulesUtils.buildRuleSetFromXml(FlexRulesUtils.getConfigurationFromFile(path)); List<Rule> rulesRepository = new ArrayList<Rule>(); for (FlexRule fRule : ruleset.getRules()) { rulesRepository.add(createRepositoryRule(fRule)); } return rulesRepository; } public static List<ActiveRule> importConfiguration(String configuration, List<Rule> rulesRepository) { Ruleset ruleset = FlexRulesUtils.buildRuleSetFromXml(configuration); List<ActiveRule> activeRules = new ArrayList<ActiveRule>(); for (FlexRule fRule : ruleset.getRules()) { ActiveRule activeRule = createActiveRule(fRule, rulesRepository); if (activeRule != null) { activeRules.add(activeRule); } } return activeRules; } public static String exportConfiguration(RulesProfile activeProfile) { Ruleset tree = buildRulesetFromActiveProfile(activeProfile.getActiveRulesByRepository(FlexPmdConstants.REPOSITORY_KEY)); return FlexRulesUtils.buildXmlFromRuleset(tree); } private static Rule createRepositoryRule(FlexRule fRule) { RulePriority priority = severityFromLevel(fRule.getPriority()); Rule rule = Rule.create(FlexPmdConstants.REPOSITORY_KEY, fRule.getClazz(), fRule.getMessage()) .setSeverity(priority); rule.setDescription(fRule.getDescription()); List<RuleParam> ruleParams = new ArrayList<RuleParam>(); if (fRule.getProperties() != null) { for (Property property : fRule.getProperties()) { RuleParam param = rule.createParameter() .setKey(property.getName()) .setDescription(property.getName()) .setType("i"); ruleParams.add(param); } } rule.setParams(ruleParams); return rule; } private static ActiveRule createActiveRule(FlexRule fRule, List<Rule> rulesRepository) { String clazz = fRule.getClazz(); RulePriority fRulePriority = severityFromLevel(fRule.getPriority()); for (Rule rule : rulesRepository) { if (rule.getKey().equals(clazz)) { RulePriority priority = fRulePriority != null ? fRulePriority : rule.getSeverity(); ActiveRule activeRule = new ActiveRule(null, rule, priority); activeRule.setActiveRuleParams(buildActiveRuleParams(fRule, rule, activeRule)); return activeRule; } } return null; } static List<ActiveRuleParam> buildActiveRuleParams(FlexRule flexRule, Rule repositoryRule, ActiveRule activeRule) { List<ActiveRuleParam> activeRuleParams = new ArrayList<ActiveRuleParam>(); if (flexRule.getProperties() != null) { for (Property property : flexRule.getProperties()) { if (repositoryRule.getParams() != null) { for (RuleParam ruleParam : repositoryRule.getParams()) { if (ruleParam.getKey().equals(property.getName())) { activeRuleParams.add(new ActiveRuleParam(activeRule, ruleParam, property.getValue())); } } } } } return activeRuleParams; } static Ruleset buildRulesetFromActiveProfile(List<ActiveRule> activeRules) { Ruleset ruleset = new Ruleset(); for (ActiveRule activeRule : activeRules) { if (activeRule.getRule().getRepositoryKey().equals(FlexPmdConstants.REPOSITORY_KEY)) { String key = activeRule.getRule().getKey(); String priority = severityToLevel(activeRule.getSeverity()); FlexRule flexRule = new FlexRule(key, priority); List<Property> properties = new ArrayList<Property>(); for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) { properties.add(new Property(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue())); } flexRule.setProperties(properties); flexRule.setMessage(activeRule.getRule().getName()); ruleset.addRule(flexRule); } } return ruleset; } private static RulePriority severityFromLevel(String level) { if ("1".equals(level)) { return RulePriority.BLOCKER; } if ("2".equals(level)) { return RulePriority.CRITICAL; } if ("3".equals(level)) { return RulePriority.MAJOR; } if ("4".equals(level)) { return RulePriority.MINOR; } if ("5".equals(level)) { return RulePriority.INFO; } return null; } private static String severityToLevel(RulePriority priority) { if (priority.equals(RulePriority.BLOCKER)) { return "1"; } if (priority.equals(RulePriority.CRITICAL)) { return "2"; } if (priority.equals(RulePriority.MAJOR)) { return "3"; } if (priority.equals(RulePriority.MINOR)) { return "4"; } if (priority.equals(RulePriority.INFO)) { return "5"; } throw new IllegalArgumentException("Level not supported: " + priority); } }