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.checkstyle; 021 022import com.puppycrawl.tools.checkstyle.ConfigurationLoader; 023import com.puppycrawl.tools.checkstyle.DefaultConfiguration; 024import com.puppycrawl.tools.checkstyle.PropertiesExpander; 025import com.puppycrawl.tools.checkstyle.api.CheckstyleException; 026import org.apache.commons.io.IOUtils; 027import org.apache.commons.lang.CharEncoding; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030import org.sonar.api.BatchExtension; 031import org.sonar.api.CoreProperties; 032import org.sonar.api.Property; 033import org.sonar.api.config.Settings; 034import org.sonar.api.profiles.RulesProfile; 035import org.sonar.api.resources.InputFileUtils; 036import org.sonar.api.resources.Java; 037import org.sonar.api.resources.ProjectFileSystem; 038import org.sonar.api.utils.SonarException; 039 040import java.io.File; 041import java.io.FileOutputStream; 042import java.io.IOException; 043import java.io.OutputStreamWriter; 044import java.io.Writer; 045import java.nio.charset.Charset; 046import java.util.List; 047import java.util.Locale; 048import java.util.Properties; 049 050@org.sonar.api.Properties({ 051 @Property( 052 key = CheckstyleConfiguration.PROPERTY_GENERATE_XML, 053 defaultValue = "false", 054 name = "Generate XML Report", 055 project = false, global = false 056 ) 057}) 058public class CheckstyleConfiguration implements BatchExtension { 059 060 private static final Logger LOG = LoggerFactory.getLogger(CheckstyleConfiguration.class); 061 public static final String PROPERTY_GENERATE_XML = "sonar.checkstyle.generateXml"; 062 063 private final CheckstyleProfileExporter confExporter; 064 private final RulesProfile profile; 065 private final Settings conf; 066 private final ProjectFileSystem fileSystem; 067 068 public CheckstyleConfiguration(Settings conf, CheckstyleProfileExporter confExporter, RulesProfile profile, ProjectFileSystem fileSystem) { 069 this.conf = conf; 070 this.confExporter = confExporter; 071 this.profile = profile; 072 this.fileSystem = fileSystem; 073 } 074 075 public File getXMLDefinitionFile() { 076 Writer writer = null; 077 File xmlFile = new File(fileSystem.getSonarWorkingDirectory(), "checkstyle.xml"); 078 try { 079 writer = new OutputStreamWriter(new FileOutputStream(xmlFile, false), CharEncoding.UTF_8); 080 confExporter.exportProfile(profile, writer); 081 writer.flush(); 082 return xmlFile; 083 084 } catch (IOException e) { 085 throw new SonarException("Fail to save the Checkstyle configuration to " + xmlFile.getPath(), e); 086 087 } finally { 088 IOUtils.closeQuietly(writer); 089 } 090 } 091 092 public List<File> getSourceFiles() { 093 return InputFileUtils.toFiles(fileSystem.mainFiles(Java.KEY)); 094 } 095 096 public File getTargetXMLReport() { 097 if (conf.getBoolean(PROPERTY_GENERATE_XML)) { 098 return new File(fileSystem.getSonarWorkingDirectory(), "checkstyle-result.xml"); 099 } 100 return null; 101 } 102 103 public com.puppycrawl.tools.checkstyle.api.Configuration getCheckstyleConfiguration() throws CheckstyleException { 104 File xmlConfig = getXMLDefinitionFile(); 105 106 LOG.info("Checkstyle configuration: " + xmlConfig.getAbsolutePath()); 107 com.puppycrawl.tools.checkstyle.api.Configuration configuration = toCheckstyleConfiguration(xmlConfig); 108 defineCharset(configuration); 109 return configuration; 110 } 111 112 static com.puppycrawl.tools.checkstyle.api.Configuration toCheckstyleConfiguration(File xmlConfig) throws CheckstyleException { 113 return ConfigurationLoader.loadConfiguration(xmlConfig.getAbsolutePath(), new PropertiesExpander(new Properties())); 114 } 115 116 private void defineCharset(com.puppycrawl.tools.checkstyle.api.Configuration configuration) { 117 com.puppycrawl.tools.checkstyle.api.Configuration[] modules = configuration.getChildren(); 118 for (com.puppycrawl.tools.checkstyle.api.Configuration module : modules) { 119 if (("Checker".equals(module.getName()) || "com.puppycrawl.tools.checkstyle.Checker".equals(module.getName())) && (module instanceof DefaultConfiguration)) { 120 Charset charset = getCharset(); 121 LOG.info("Checkstyle charset: " + charset.name()); 122 ((DefaultConfiguration) module).addAttribute("charset", charset.name()); 123 } 124 } 125 } 126 127 public Locale getLocale() { 128 return new Locale(conf.getString(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY)); 129 } 130 131 public Charset getCharset() { 132 Charset charset = fileSystem.getSourceCharset(); 133 if (charset == null) { 134 charset = Charset.forName(System.getProperty("file.encoding", CharEncoding.UTF_8)); 135 } 136 return charset; 137 } 138}