All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.php.codesniffer.PhpCodeSnifferProfileExporter Maven / Gradle / Ivy

Go to download

Sonar PHP Plugin is set of tools that brings PHP support to sonar. It relies on Sonar core, PHP Depend, PHPMD, PHP_CodeSniffer and PHPUnit

There is a newer version: 2.4.1
Show newest version
/*
 * Sonar PHP Plugin
 * Copyright (C) 2010 Codehaus Sonar Plugins
 * [email protected]
 *
 * 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.php.codesniffer;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.sonar.api.profiles.ProfileExporter;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.ActiveRuleParam;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.php.api.Php;
import org.sonar.plugins.php.pmd.xml.PmdProperty;
import org.sonar.plugins.php.pmd.xml.PmdRule;
import org.sonar.plugins.php.pmd.xml.PmdRuleset;

/**
 * @author Akram Ben Aissi
 */
public class PhpCodeSnifferProfileExporter extends ProfileExporter {

  public static final String XPATH_CLASS = "net.sourceforge.pmd.rules.XPathRule";
  public static final String XPATH_EXPRESSION_PARAM = "xpath";
  public static final String XPATH_MESSAGE_PARAM = "message";

  private PhpCodeSnifferPriorityMapper mapper;

  /**
   * Instantiate the profile exporter. Exports are xml, mime type is set to fit.
   */
  public PhpCodeSnifferProfileExporter(PhpCodeSnifferPriorityMapper mapper) {
    super(PhpCodeSnifferRuleRepository.PHPCS_REPOSITORY_KEY, PhpCodeSnifferRuleRepository.PHPCS_REPOSITORY_NAME);
    setSupportedLanguages(Php.KEY);
    setMimeType("application/xml");
    this.mapper = mapper;
  }

  /**
   * Perform export: Materialize the current active rule set for the profile. The convert it to XML.
   * 
   * @see org.sonar.api.profiles.ProfileExporter#exportProfile(org.sonar.api.profiles.RulesProfile, java.io.Writer)
   */
  @Override
  public void exportProfile(RulesProfile profile, Writer writer) {
    try {
      List activeRulesByRepository = profile.getActiveRulesByRepository(PhpCodeSnifferRuleRepository.PHPCS_REPOSITORY_KEY);
      PmdRuleset ruleset = createRuleset(activeRulesByRepository, profile.getName());
      String xmlModules = exportRulesetToXml(ruleset);
      writer.append(xmlModules);
      writer.flush();
    } catch (IOException e) {
      throw new SonarException("Fail to export the profile " + profile, e);
    }
  }

  /**
   * Materialize the current active rule set for the profile
   * 
   * @param activeRules
   * @param profileName
   * @return
   */
  protected PmdRuleset createRuleset(List activeRules, String profileName) {
    PmdRuleset ruleset = new PmdRuleset(profileName);
    for (ActiveRule activeRule : activeRules) {
      if (activeRule.getRule().getRepositoryKey().equals(PhpCodeSnifferRuleRepository.PHPCS_REPOSITORY_KEY)) {
        String configKey = activeRule.getRule().getKey();
        PmdRule rule = new PmdRule(configKey, mapper.to(activeRule.getSeverity()));
        List properties = null;
        List activeRuleParams = activeRule.getActiveRuleParams();
        if (activeRuleParams != null && !activeRuleParams.isEmpty()) {
          properties = new ArrayList();
          for (ActiveRuleParam activeRuleParam : activeRuleParams) {
            properties.add(new PmdProperty(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue()));
          }
        }
        rule.setProperties(properties);
        ruleset.addRule(rule);
        processXPathRule(activeRule.getRuleKey(), rule);
      }
    }
    return ruleset;
  }

  /**
   * @param sonarRuleKey
   * @param rule
   */
  protected void processXPathRule(String sonarRuleKey, PmdRule rule) {
    if (XPATH_CLASS.equals(rule.getRef())) {
      rule.setRef(null);
      rule.setMessage(rule.getProperty(XPATH_MESSAGE_PARAM).getValue());
      rule.removeProperty(XPATH_MESSAGE_PARAM);
      PmdProperty xpathExp = rule.getProperty(XPATH_EXPRESSION_PARAM);
      xpathExp.setCdataValue(xpathExp.getValue());
      rule.setClazz(XPATH_CLASS);
      rule.setName(sonarRuleKey);
    }
  }

  /**
   * @param pmdRuleset
   * @return
   */
  protected String exportRulesetToXml(PmdRuleset pmdRuleset) {
    Element rulesetNode = new Element("ruleset");
    addAttribute(rulesetNode, "name", pmdRuleset.getName());
    addChild(rulesetNode, "description", pmdRuleset.getDescription());
    for (PmdRule pmdRule : pmdRuleset.getPmdRules()) {
      // Generate the main  element
      Element ruleNode = new Element("rule");
      addAttribute(ruleNode, "ref", pmdRule.getRef());
      addAttribute(ruleNode, "class", pmdRule.getClazz());
      addAttribute(ruleNode, "message", pmdRule.getMessage());
      addAttribute(ruleNode, "name", pmdRule.getName());
      addChild(ruleNode, "severity", pmdRule.getPriority());
      rulesetNode.addContent(ruleNode);
      // If there are params, generate another  element
      // IMPORTANT NOTE: this is a hack because PHPCS does not currently accept parameters for rules.
      // The params need to be set on the sniff itself after the declaration of the rule...
      // SEE: https://jira.codehaus.org/browse/SONARPLUGINS-1508
      if (pmdRule.hasProperties()) {
        // => "ruleNode" is a new element !!
        ruleNode = new Element("rule");
        // => but this element must refer to the sniff, not to the rule
        addAttribute(ruleNode, "ref", StringUtils.substringBeforeLast(pmdRule.getRef(), "."));
        // and then add the properties "normally"
        Element propertiesNode = new Element("properties");
        ruleNode.addContent(propertiesNode);
        for (PmdProperty property : pmdRule.getProperties()) {
          Element propertyNode = new Element("property");
          propertyNode.setAttribute("name", property.getName());
          if (property.isCdataValue()) {
            Element valueNode = new Element("value");
            valueNode.addContent(new CDATA(property.getCdataValue()));
            propertyNode.addContent(valueNode);
          } else {
            propertyNode.setAttribute("value", property.getValue());
          }
          propertiesNode.addContent(propertyNode);
        }
        // and we add this extra  element
        rulesetNode.addContent(ruleNode);
      }
    }
    XMLOutputter serializer = new XMLOutputter(Format.getPrettyFormat());
    StringWriter xml = new StringWriter();
    try {
      serializer.output(new Document(rulesetNode), xml);
    } catch (IOException e) {
      throw new SonarException("A exception occured while generating the PMD configuration file.", e);
    }
    return xml.toString();
  }

  /**
   * @param elt
   * @param name
   * @param text
   */
  private void addChild(Element elt, String name, String text) {
    if (text != null) {
      elt.addContent(new Element(name).setText(text));
    }
  }

  /**
   * @param elt
   * @param name
   * @param value
   */
  private void addAttribute(Element elt, String name, String value) {
    if (value != null) {
      elt.setAttribute(name, value);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy