/* * Ada Sonar Plugin * Copyright (C) 2010 Akram Ben Aissi * 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.ada.rules; import java.io.IOException; import java.io.Writer; import java.util.List; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.RuleParam; import org.sonar.api.utils.SonarException; import org.sonar.plugins.ada.Ada; import org.sonar.plugins.ada.AdaPlugin; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; public class AdaProfileExporter extends ProfileExporter { private Configuration conf; public AdaProfileExporter(Configuration configuration) { super(AdaRuleRepository.REPOSITORY_KEY, AdaRuleRepository.REPOSITORY_NAME); this.conf = configuration; setSupportedLanguages(Ada.LANGUAGE_KEY); setMimeType("application/xml"); } /** * for unit tests */ AdaProfileExporter() { this(new BaseConfiguration()); } public void exportProfile(RulesProfile profile, Writer writer) { try { ListMultimap<String, ActiveRule> activeRulesByConfigKey = arrangeByConfigKey(profile.getActiveRulesByRepository(AdaPlugin.KEY)); generateXML(writer, activeRulesByConfigKey); } catch (IOException e) { throw new SonarException("Fail to export the profile " + profile, e); } } private void generateXML(Writer writer, ListMultimap<String, ActiveRule> activeRulesByConfigKey) throws IOException { appendXmlHeader(writer); appendCustomFilters(writer); appendCheckerModules(writer, activeRulesByConfigKey); appendTreeWalker(writer, activeRulesByConfigKey); appendXmlFooter(writer); } private void appendXmlHeader(Writer writer) throws IOException { writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writer.append("<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration "); writer.append("1.2//EN\" \"http://www.puppycrawl.com/dtds/configuration_1_2.dtd\">"); writer.append("<!-- Generated by Sonar -->" + "<module name=\"Checker\">"); } private void appendCustomFilters(Writer writer) throws IOException { String filtersXML = conf.getString(AdaPlugin.FILTERS_KEY, AdaPlugin.FILTERS_DEFAULT_VALUE); if (StringUtils.isNotBlank(filtersXML)) { writer.append(filtersXML); } } private void appendCheckerModules(Writer writer, ListMultimap<String, ActiveRule> activeRulesByConfigKey) throws IOException { for (String configKey : activeRulesByConfigKey.keySet()) { if ( !isInTreeWalker(configKey)) { List<ActiveRule> activeRules = activeRulesByConfigKey.get(configKey); for (ActiveRule activeRule : activeRules) { appendModule(writer, activeRule, activeRules.size() > 1); } } } } private void appendTreeWalker(Writer writer, ListMultimap<String, ActiveRule> activeRulesByConfigKey) throws IOException { writer.append("<module name=\"TreeWalker\">"); writer.append("<module name=\"FileContentsHolder\"/> "); for (String configKey : activeRulesByConfigKey.keySet()) { if (isInTreeWalker(configKey)) { List<ActiveRule> activeRules = activeRulesByConfigKey.get(configKey); for (ActiveRule activeRule : activeRules) { appendModule(writer, activeRule, activeRules.size() > 1); } } } writer.append("</module>"); } private void appendXmlFooter(Writer writer) throws IOException { writer.append("</module>"); } static boolean isInTreeWalker(String configKey) { return StringUtils.startsWithIgnoreCase(configKey, "Checker/TreeWalker/"); } private static ListMultimap<String, ActiveRule> arrangeByConfigKey(List<ActiveRule> activeRules) { ListMultimap<String, ActiveRule> result = ArrayListMultimap.create(); if (activeRules != null) { for (ActiveRule activeRule : activeRules) { result.put(activeRule.getConfigKey(), activeRule); } } return result; } private void appendModule(Writer writer, ActiveRule activeRule, boolean manyInstances) throws IOException { String moduleName = StringUtils.substringAfterLast(activeRule.getConfigKey(), "/"); writer.append("<module name=\""); StringEscapeUtils.escapeXml(writer, moduleName); writer.append("\">"); if (manyInstances) { appendModuleProperty(writer, "id", activeRule.getRuleKey()); } appendModuleProperty(writer, "severity", AdaRulePriorityMapper.to(activeRule.getPriority())); appendRuleParameters(writer, activeRule); writer.append("</module>"); } private void appendRuleParameters(Writer writer, ActiveRule activeRule) throws IOException { for (RuleParam ruleParam : activeRule.getRule().getParams()) { String value = activeRule.getParameter(ruleParam.getKey()); if (StringUtils.isNotBlank(value)) { appendModuleProperty(writer, ruleParam.getKey(), value); } } } private void appendModuleProperty(Writer writer, String propertyKey, String propertyValue) throws IOException { if (StringUtils.isNotBlank(propertyValue)) { writer.append("<property name=\""); StringEscapeUtils.escapeXml(writer, propertyKey); writer.append("\" value=\""); StringEscapeUtils.escapeXml(writer, propertyValue); writer.append("\"/>"); } } }