org.sonar.dotnet.tools.stylecop.MsBuildFileGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.sonar.dotnet.tools.stylecop.MsBuildFileGenerator.java

Source

/*
 * .NET tools :: StyleCop Runner
 * Copyright (C) 2010 Jose Chillan, Alexandre Victoor and 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.dotnet.tools.stylecop;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.sonar.api.utils.SonarException;
import org.sonar.dotnet.tools.commons.visualstudio.VisualStudioProject;
import org.sonar.dotnet.tools.commons.visualstudio.VisualStudioSolution;

import com.google.common.collect.Lists;

/**
 * Class that generates MSBuild
 */
public class MsBuildFileGenerator {

    protected static final String MSBUILD_FILE = "stylecop-msbuild.xml";
    private VisualStudioSolution solution;
    private File styleCopRuleFile;
    private File reportFile;
    private File styleCopFolder;

    public MsBuildFileGenerator(VisualStudioSolution solution, File styleCopRuleFile, File reportFile,
            File styleCopFolder) {
        this.solution = solution;
        this.styleCopRuleFile = styleCopRuleFile;
        this.reportFile = reportFile;
        this.styleCopFolder = styleCopFolder;
    }

    /**
     * Generates the MSBuild file in the given output folder
     * 
     * @param outputFolder
     *          the output folder
     * @param vsProject
     *          the VS project that should be analysed. May be NULL, in which case all the projects of the solution will be analysed.
     */
    public File generateFile(File outputFolder, VisualStudioProject vsProject) {
        File msBuildFile = new File(outputFolder, MSBUILD_FILE);
        List<VisualStudioProject> vsProjects = solution.getProjects();
        if (vsProject != null) {
            vsProjects = Lists.newArrayList(vsProject);
        }

        FileWriter writer = null;
        try {
            writer = new FileWriter(msBuildFile);
            generateContent(writer, styleCopRuleFile, reportFile, vsProjects);
            writer.flush();
        } catch (IOException e) {
            throw new SonarException("Error while generating the MSBuild file needed to launch StyleCop: "
                    + msBuildFile.getAbsolutePath(), e);
        } finally {
            IOUtils.closeQuietly(writer);
        }

        return msBuildFile;
    }

    protected void generateContent(Writer writer, File styleCopRuleFile, File reportFile,
            List<VisualStudioProject> vsProjects) throws IOException {
        writer.append("<?xml version=\"1.0\" ?>\n");
        writer.append(
                "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" DefaultTargets=\"StyleCopLaunch\" ToolsVersion=\"3.5\">\n");
        writer.append("    <PropertyGroup>\n");
        writer.append("        <ProjectRoot>");
        StringEscapeUtils.escapeXml(writer, solution.getSolutionDir().getAbsolutePath());
        writer.append("</ProjectRoot>\n");
        writer.append("        <StyleCopRoot>");
        StringEscapeUtils.escapeXml(writer, styleCopFolder.getAbsolutePath());
        writer.append("</StyleCopRoot>\n");
        writer.append("    </PropertyGroup>\n");
        writer.append(
                "    <UsingTask TaskName=\"StyleCopTask\" AssemblyFile=\"$(StyleCopRoot)\\Microsoft.StyleCop.dll\"></UsingTask>\n");
        writer.append("    <ItemGroup>\n");
        generateProjectList(writer, vsProjects);
        writer.append("    </ItemGroup>\n");
        writer.append("    <Target Name=\"StyleCopLaunch\">\n");
        writer.append("        <CreateItem Include=\"%(Project.RootDir)%(Project.Directory)**\\*.cs\">\n");
        writer.append("            <Output ItemName=\"SourceAnalysisFiles\" TaskParameter=\"Include\"></Output>\n");
        writer.append("        </CreateItem>\n");
        writer.append("        <StyleCopTask MaxViolationCount=\"-1\" OverrideSettingsFile=\"");
        StringEscapeUtils.escapeXml(writer, styleCopRuleFile.getAbsolutePath());
        writer.append("\"\n            OutputFile=\"");
        StringEscapeUtils.escapeXml(writer, reportFile.getAbsolutePath());
        writer.append("\"\n            TreatErrorsAsWarnings=\"true\" ForceFullAnalysis=\"true\"\n");
        writer.append("            SourceFiles=\"@(SourceAnalysisFiles);@(CSFile)\"\n");
        writer.append("            ProjectFullPath=\"");
        StringEscapeUtils.escapeXml(writer, solution.getSolutionFile().getAbsolutePath());
        writer.append("\"></StyleCopTask>\n");
        writer.append("    </Target>\n");
        writer.append("</Project>");
    }

    private void generateProjectList(Writer writer, List<VisualStudioProject> vsProjects) throws IOException {
        for (VisualStudioProject project : vsProjects) {
            if (project.getProjectFile() == null) {
                // this is a Web project without ".csproj" file, we need to add a wildcard pattern
                writer.append("        <CSFile Include=\"");
                StringEscapeUtils.escapeXml(writer, project.getDirectory().getAbsolutePath() + "\\**\\*.cs");
                writer.append("\"></CSFile>\n");
            } else {
                writer.append("        <Project Include=\"");
                StringEscapeUtils.escapeXml(writer, project.getProjectFile().getAbsolutePath());
                writer.append("\"></Project>\n");
            }
        }
    }

}