/** * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * * Copyright 2012-2015 the original author or authors. */ package org.assertj.swing.junit.ant; import static org.assertj.core.util.Strings.concat; import java.io.File; import java.net.URL; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.Delete; import org.apache.tools.ant.taskdefs.TempFile; import org.apache.tools.ant.taskdefs.XSLTProcess; import org.apache.tools.ant.taskdefs.XSLTProcess.Param; import org.apache.tools.ant.taskdefs.optional.junit.AggregateTransformer; import org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.resources.FileResource; import org.apache.tools.ant.types.resources.URLResource; import org.apache.tools.ant.util.FileUtils; /** * Transforms a JUnit XML report. The default transformation generates an HTML report in either framed or non-framed * style. * * @author Alex Ruiz */ public class ReportTransformer extends AggregateTransformer { private static final String XSL_FILE_PATH = "org/fest/swing/junit/ant/"; private Path classpath; /** The parameters that will be sent to the XSL transformation. */ private final List<Param> params; /** Instance of a utility class to use for file operations. */ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** Used to ensure the uniqueness of a property. */ private static int counter; /** * Creates a new <code>{@link ReportTransformer}</code>. * * @param task task delegating to this class. */ public ReportTransformer(Task task) { super(task); params = new CopyOnWriteArrayList<Param>(); } /** * Create an instance of an XSL parameter for configuration by Ant. * * @return an instance of the <code>Param</code> class to be configured. */ @Override public Param createParam() { Param p = new Param(); params.add(p); return p; } /** * Performs the XSLT transformation to generate the HTML report. * * @throws BuildException thrown if something goes wrong with the transformation. */ @Override public void transform() throws BuildException { checkOptions(); TempFile tempFileTask = tempFileTask(); XSLTProcess xsltTask = xsltTask(); File outputFile = outputFile(tempFileTask); xsltTask.setOut(outputFile); createNewParams(xsltTask); createOutputDirParam(xsltTask); long startingTime = System.currentTimeMillis(); try { xsltTask.execute(); } catch (Exception e) { throw new BuildException(concat("Errors while applying transformations: ", e.getMessage()), e); } long transformTime = System.currentTimeMillis() - startingTime; task.log(concat("Transform time: ", String.valueOf(transformTime), " ms")); delete(outputFile); } private XSLTProcess xsltTask() { XSLTProcess xsltTask = new XSLTProcess(); xsltTask.bindToOwner(task); xsltTask.setClasspath(classpath); xsltTask.setXslResource(getStylesheet()); xsltTask.setIn(((XMLResultAggregator) task).getDestinationFile()); return xsltTask; } /** * Access the stylesheet to be used as a resource. * * @return stylesheet as a resource */ @Override protected Resource getStylesheet() { String xslname = "junit-frames.xsl"; if (NOFRAMES.equals(format)) xslname = "junit-noframes.xsl"; if (styleDir == null) { URLResource stylesheet = new URLResource(); URL stylesheetURL = getClass().getClassLoader().getResource(concat(XSL_FILE_PATH, xslname)); stylesheet.setURL(stylesheetURL); return stylesheet; } FileResource stylesheet = new FileResource(); File stylesheetFile = new File(styleDir, xslname); stylesheet.setFile(stylesheetFile); return stylesheet; } private TempFile tempFileTask() { TempFile tempFileTask = new TempFile(); tempFileTask.bindToOwner(task); return tempFileTask; } private File outputFile(TempFile tempFileTask) { Project project = task.getProject(); if (format.equals(FRAMES)) { String tempFileProperty = concat(getClass().getName(), String.valueOf(counter++)); setUpTempFileTask(tempFileTask, tempFileProperty); return new File(project.getProperty(tempFileProperty)); } return new File(toDir, "junit-noframes.html"); } private void setUpTempFileTask(TempFile tempFileTask, String tempFileProperty) { Project project = task.getProject(); File tmp = FILE_UTILS.resolveFile(project.getBaseDir(), project.getProperty("java.io.tmpdir")); tempFileTask.setDestDir(tmp); tempFileTask.setProperty(tempFileProperty); tempFileTask.execute(); } private void createNewParams(XSLTProcess xsltTask) { for (Param param : params) { Param p = xsltTask.createParam(); p.setProject(task.getProject()); p.setName(param.getName()); p.setExpression(param.getExpression()); } } private void createOutputDirParam(XSLTProcess xsltTask) { Param p = xsltTask.createParam(); p.setProject(task.getProject()); p.setName("output.dir"); p.setExpression(toDir.getAbsolutePath()); } private void delete(File outputFile) { if (!format.equals(FRAMES)) return; Delete deleteTask = new Delete(); deleteTask.bindToOwner(task); deleteTask.setFile(outputFile); deleteTask.execute(); } /** * Sets an additional classpath. * * @param classpath the additional classpath to append to the current one. */ public void setClasspath(Path classpath) { createClasspath().append(classpath); } /** * Sets a reference to a classpath. * * @param r the reference to set. */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); } /** * Creates the current classpath. * * @return the created classpath. */ @Override public Path createClasspath() { if (classpath == null) classpath = new Path(task.getProject()); return classpath.createPath(); } }