org.codehaus.mojo.fitnesse.FitnesseReportMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.fitnesse.FitnesseReportMojo.java

Source

package org.codehaus.mojo.fitnesse;

/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;

/**
 * Generates a <a href="http://fitnesse.org">FitNesse</a> report from a FitNesse web server. The generated report is an
 * external report generated FitNesse itself. If the project use Clover for code coverage and if FitNesse has clover
 * dependency (ie use the <i>ArtifactId-Version-clover.jar</i>), the code executed during the FitNesse execution (phase
 * integration-test) will be had to the unit-test code coverage. See the <a href="examples/multiproject.html">clover
 * example</a>.
 * 
 * @goal fitnesse
 * @aggregator
 */
public class FitnesseReportMojo extends AbstractMavenReport {

    /**
     * The Maven project instance for the executing project.
     * <p>
     * Note: This is passed by Maven and must not be configured by the user.
     * </p>
     * 
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * Report output directory. It should be defined in the reporting section of the pom.
     * 
     * @parameter expression="${project.build.directory}/generated-site/xdoc/fitnesse"
     * @required
     */
    private File xmlOutputDirectory;

    /**
     * The directory where the Fitnesse report will be generated.
     * @parameter expression="${project.reporting.outputDirectory}/fitnesse"
     * @required
     */
    private File outputDirectory;

    /**
     * The directory where the Fitnesse report has be generated. It must be defined when it's not the default value
     * (${project.build.directory}/fitnesse. It's the case for exemple with the clover plugin (that use
     * ${project.build.directory}/clover/fitnesse).
     * 
     * @parameter
     */
    private File fitnesseOutputDirectory;

    /**
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private File workingDir;

    /**
     * <p>
     * Note: This is passed by Maven and must not be configured by the user.
     * </p>
     * 
     * @component
     */
    private Renderer siteRenderer;

    /**
     * @see org.apache.maven.reporting.AbstractMavenReport#executeReport(java.util.Locale)
     */
    protected void executeReport(Locale pArg0) throws MavenReportException {
        // Ensure the output directory exists
        getLog().info("outputDirectory=" + outputDirectory);
        this.outputDirectory.mkdirs();
        this.xmlOutputDirectory.mkdirs();

        checkReport();

        createReport();
        createIndex();
        copyAllResources(this.outputDirectory, getLog(), getClass().getClassLoader());

        getLog().info("Fitnesse report finished");
    }

    public static void copyAllResources(File pToDir, Log pLog, ClassLoader pLoader) throws MavenReportException {
        copyResource(pToDir, "fitnesse.js", pLog, pLoader);
        copyResource(pToDir, "fitnesse_base.css", pLog, pLoader);
        copyResource(pToDir, "fitnesse_print.css", pLog, pLoader);
        // images
        new File(pToDir + "/images").mkdir();
        copyResource(pToDir, "images/collapsableClosed.gif", pLog, pLoader);
        copyResource(pToDir, "images/collapsableOpen.gif", pLog, pLoader);
        copyResource(pToDir, "images/FitNesseLogo.gif", pLog, pLoader);
        copyResource(pToDir, "images/FitNesseLogoMedium.jpg", pLog, pLoader);
        copyResource(pToDir, "images/folder.gif", pLog, pLoader);
        copyResource(pToDir, "images/importedPage.jpg", pLog, pLoader);
        copyResource(pToDir, "images/virtualPage.jpg", pLog, pLoader);
        new File(pToDir + "/images/executionStatus").mkdir();
        copyResource(pToDir, "images/executionStatus/error.gif", pLog, pLoader);
        copyResource(pToDir, "images/executionStatus/ok.gif", pLog, pLoader);
        copyResource(pToDir, "images/executionStatus/output.gif", pLog, pLoader);
    }

    private static void copyResource(File pToDir, String pFileName, Log pLog, ClassLoader pLoader)
            throws MavenReportException {
        File tDest = new File(pToDir + "/" + pFileName);
        copyFile(pLog, pLoader.getResourceAsStream("fitnesse_resources/" + pFileName), tDest);
    }

    private void createReport() throws MavenReportException {
        File curFile;
        File[] tFileArray = getFitnesseReportDir().listFiles();
        for (int i = 0; i < tFileArray.length; i++) {
            curFile = tFileArray[i];
            if (!curFile.exists()) {
                throw new MavenReportException("Unable to find Fitnesse report for server " + curFile);
            }
            if (curFile.getName().startsWith(FitnesseRunnerMojo.FITNESSE_RESULT_PREFIX)) {
                File tDestFile = new File(outputDirectory + "/" + curFile.getName());
                try {
                    copyFile(getLog(), new FileInputStream(curFile), tDestFile);
                } catch (IOException e) {
                    throw new MavenReportException("Unable to create File [" + curFile.getAbsolutePath() + "].", e);
                }
            }
        }
    }

    void checkReport() throws MavenReportException {
        if (getFitnesseReportDir().listFiles().length == 0) {
            getLog().error("Your should configure at least one Fitnesse server. "
                    + "Check your Fitnesse plugin configuration.");
            throw new MavenReportException("Your should configure at least one Fitnesse server. "
                    + "Check your Fitnesse plugin configuration.");
        }
    }

    static void copyFile(Log pLogger, InputStream pIn, File pDestFile) throws MavenReportException {
        FileOutputStream tOut = null;
        try {
            if (!pDestFile.exists()) {
                pDestFile.createNewFile();
            }
            tOut = new FileOutputStream(pDestFile);
            byte[] tBuff = new byte[100];
            int tRead = pIn.read(tBuff);
            while (tRead >= 0) {
                tOut.write(tBuff, 0, tRead);
                tRead = pIn.read(tBuff);
            }
            pLogger.debug("File copied to " + pDestFile);
            pLogger.debug("File exist " + pDestFile.exists());
        } catch (FileNotFoundException e) {
            throw new MavenReportException("File doesn't exist", e);
        } catch (IOException e) {
            throw new MavenReportException("Unable to write into file...", e);
        } finally {
            try {
                if (tOut != null) {
                    tOut.close();
                }
                if (pIn != null) {
                    pIn.close();
                }
            } catch (IOException e) {
                throw new MavenReportException("Unable to close report file report...", e);
            }
        }
    }

    File getFitnesseReportDir() throws MavenReportException {
        File tExecutionFile;
        if (fitnesseOutputDirectory != null) {
            getLog().info("Using the specified fitnesse outpout directory " + fitnesseOutputDirectory);
            tExecutionFile = fitnesseOutputDirectory;
        } else {
            getLog().debug("Trying to find the fitnesse default dir...");
            tExecutionFile = new File(workingDir + "/fitnesse");
            if (!tExecutionFile.exists()) {
                getLog().info("Fitnesse default report not found, " + tExecutionFile);
                getLog().debug("Trying to find the fitnesse with clover dir...");
                tExecutionFile = new File(workingDir + "/clover/fitnesse");
            }
        }

        FilenameFilter filterSvnDirectory = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return !name.equals(".svn");
            }
        };

        if (!tExecutionFile.exists() || !tExecutionFile.isDirectory()
                || tExecutionFile.list(filterSvnDirectory).length == 0) {
            String tError = "Can't find any report in the following folder: ["
                    + fitnesseOutputDirectory.getAbsolutePath() + "], ["
                    + new File(workingDir + "/fitnesse").getAbsolutePath() + "] or ["
                    + tExecutionFile.getAbsolutePath() + "]";

            throw new MavenReportException(tError);
        } else {
            return tExecutionFile;
        }
    }

    void createIndex() throws MavenReportException {
        if (outputDirectory.listFiles().length > 1) {
            File tIndex = new File(this.xmlOutputDirectory + "/index.xml");
            FileWriter tWriter = null;
            int tNbPage = 0;
            try {
                tIndex.createNewFile();
                tWriter = new FileWriter(tIndex);
                tWriter.write("<document>\n");
                tWriter.write(" <properties>\n");
                tWriter.write("   <title>maven-fitnesse-plugin - execution report</title>\n");
                tWriter.write(" </properties>\n");
                tWriter.write(" <body>\n");

                tWriter.write("<section name=\"List of the Fitnesse Pages:\">\n");
                tWriter.write("<ul>\n");
                FitnessePage curChil;
                File[] tFileArray = outputDirectory.listFiles();
                for (int i = 0; i < tFileArray.length; i++) {
                    curChil = new FitnessePage(tFileArray[i]);
                    if (curChil.isFitnessePageResult()) {
                        tWriter.write("<li><a href=\"" + curChil.getName() + "\">" + curChil.getFitnessePageName()
                                + ".html</a></li>\n");
                        tNbPage++;
                    }
                }
                tWriter.write("</ul>\n");
                tWriter.write("</section>\n");
                tWriter.write("</body>\n");
                tWriter.write("</document>\n");
                tWriter.flush();
            } catch (IOException e) {
                throw new MavenReportException("Unable to create index file " + tIndex.getAbsolutePath(), e);
            } finally {
                if (tWriter != null) {
                    try {
                        tWriter.close();
                    } catch (IOException e) {
                        throw new MavenReportException("Unable to close index file " + tIndex.getAbsolutePath(), e);
                    }
                }
            }
            if (tNbPage == 1) {
                tIndex.delete();
            }
        }
    }

    /**
     * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
     */
    protected String getOutputDirectory() {
        return this.outputDirectory.getAbsoluteFile().toString();
    }

    /**
     * @see org.apache.maven.reporting.AbstractMavenReport#getProject()
     */
    protected MavenProject getProject() {
        return project;
    }

    /**
     * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
     */
    protected Renderer getSiteRenderer() {
        return this.siteRenderer;
    }

    /**
     * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
     */
    public String getDescription(Locale locale) {
        return "Fitnesse report";
    }

    /**
     * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
     */
    public String getName(Locale locale) {
        return "Fitnesse report";
    }

    /**
     * @see org.apache.maven.reporting.MavenReport#getOutputName()
     */
    public String getOutputName() {
        File tDir;
        FitnessePage curChild = null, tGoodFile = null;
        try {
            tDir = getFitnesseReportDir();
            String[] tChildren = tDir.list();
            int tNbPage = 0;
            for (int i = 0; i < tChildren.length; i++) {
                curChild = new FitnessePage(new File(tChildren[i]));
                if (curChild.isFitnessePageResult()) {
                    tNbPage++;
                    tGoodFile = curChild;
                }
            }
            if (tNbPage == 1) {
                return "fitnesse/" + FitnesseRunnerMojo.FITNESSE_RESULT_PREFIX + "_"
                        + tGoodFile.getFitnessePageName();
            } else {
                return "fitnesse/index";
            }
        } catch (MavenReportException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Always return true as we're using the report generated by Clover rather than creating our own report.
     * 
     * @return true
     */
    public boolean isExternalReport() {
        return true;
    }

    void setWorkingDir(File pWorkingDir) {
        workingDir = pWorkingDir;
    }

    void setFitnesseOutputDirectory(File pFitnesseOutputDirectory) {
        fitnesseOutputDirectory = pFitnesseOutputDirectory;
    }

    void setOutputDirectory(File pOutputDirectory) {
        outputDirectory = pOutputDirectory;
    }

    public void setXmlOutputDirectory(File xmlOutputDirectory) {
        this.xmlOutputDirectory = xmlOutputDirectory;
    }

}