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