![JAR search and dependency download from the Maven repository](/logo.png)
org.daisy.maven.xproc.xprocspec.XProcSpecRunner Maven / Gradle / Ivy
package org.daisy.maven.xproc.xprocspec;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import static com.google.common.io.Files.asByteSink;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import net.sf.saxon.xpath.XPathFactoryImpl;
import org.daisy.maven.xproc.api.XProcExecutionException;
import org.daisy.maven.xproc.api.XProcEngine;
import org.xml.sax.InputSource;
public class XProcSpecRunner {
private XProcEngine engine;
public void setXProcEngine(XProcEngine engine) {
this.engine = engine;
}
protected void activate() {
if (engine == null) {
// We are not in an OSGi environment, try with ServiceLoader
ServiceLoader xprocEngines = ServiceLoader.load(XProcEngine.class);
try {
engine = xprocEngines.iterator().next();
} catch (NoSuchElementException e) {
throw new RuntimeException("Could not find any XProc engines on the classpath.");
}
}
}
public boolean run(Map tests,
File reportsDir,
File surefireReportsDir,
File tempDir,
File catalog,
Reporter reporter) {
if (engine == null)
activate();
engine.setCatalog(catalog);
URI xprocspec = asURI(XProcSpecRunner.class.getResource("/content/xml/xproc/xprocspec.xpl"));
URI xprocspecSummary = asURI(XProcSpecRunner.class.getResource("/xprocspec-extra/xprocspec-summary.xpl"));
URL xspecCss = XProcSpecRunner.class.getResource("/xprocspec-extra/xspec.css");
reportsDir.mkdirs();
surefireReportsDir.mkdirs();
int totalRun = 0;
int totalFailures = 0;
int totalErrors = 0;
int totalSkipped = 0;
long startTime = System.nanoTime();
reporter.init();
for (String testName : tests.keySet()) {
File test = tests.get(testName);
File report = new File(reportsDir, testName + ".html");
File surefireReport = new File(surefireReportsDir, "TEST-" + testName + ".xml");
Map> input = ImmutableMap.of("source", Arrays.asList(new String[]{asURI(test).toASCIIString()}));
Map output = ImmutableMap.of("html", asURI(report).toASCIIString(),
"junit", asURI(surefireReport).toASCIIString());
Map options = ImmutableMap.of("temp-dir", asURI(tempDir) + "/tmp/");
reporter.running(testName);
try {
engine.run(xprocspec.toASCIIString(), input, output, options, null);
if (!surefireReport.exists()) {
totalRun += 1;
totalErrors += 1;
reporter.result(1, 0, 1, 0, 0L, null, null); }
else {
Integer run = (Integer)evaluateXPath(surefireReport, "sum(/testsuites/@tests)", null, Integer.class);
Integer failures = (Integer)evaluateXPath(surefireReport, "number(/testsuites/@failures)", null, Integer.class);
Integer errors = (Integer)evaluateXPath(surefireReport, "number(/testsuites/@errors)", null, Integer.class);
Integer skipped = (Integer)evaluateXPath(surefireReport, "sum(/testsuites/*/number(@skipped))", null, Integer.class);
Long time = (Long)evaluateXPath(surefireReport, "number(/testsuites/@time)", null, Long.class);
totalRun += run;
totalFailures += failures;
totalErrors += errors;
totalSkipped += skipped;
reporter.result(run, failures, errors, skipped, time, null, null); }}
catch (XProcExecutionException e) {
totalRun += 1;
totalErrors += 1;
reporter.result(1, 0, 1, 0, 0L, e.getMessage(), Throwables.getStackTraceAsString(e)); }
}
long totalTime = TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
reporter.finish(totalRun, totalFailures, totalErrors, totalSkipped, totalTime);
/* Generate summary */
try {
StringBuilder testNames = new StringBuilder();
StringBuilder surefireReports = new StringBuilder();
StringBuilder reports = new StringBuilder();
File summary = new File(reportsDir, "index.html");
File css = new File(reportsDir, "xspec.css");
for (String testName : tests.keySet()) {
testNames.append(testName);
testNames.append(" ");
File surefireReport = new File(surefireReportsDir, "TEST-" + testName + ".xml");
surefireReports.append(asURI(surefireReport).toASCIIString());
surefireReports.append(" ");
File report = new File(reportsDir, testName + ".html");
reports.append(asURI(report).toASCIIString());
reports.append(" "); }
testNames.deleteCharAt(testNames.length() - 1);
surefireReports.deleteCharAt(surefireReports.length() - 1);
reports.deleteCharAt(reports.length() - 1);
Map output = ImmutableMap.of("result", asURI(summary).toASCIIString());
Map params = ImmutableMap.of("test-names", testNames.toString(),
"surefire-reports", surefireReports.toString(),
"reports", reports.toString());
engine.run(xprocspecSummary.toASCIIString(), null, output, null, ImmutableMap.of("parameters", params));
asByteSink(css).writeFrom(xspecCss.openStream()); }
catch (XProcExecutionException e) {
throw new RuntimeException(e); }
catch (IOException e) {
throw new RuntimeException(e); }
return totalErrors == 0 && totalFailures == 0;
}
public boolean run(File testsDir,
File reportsDir,
File surefireReportsDir,
File tempDir,
Reporter reporter) {
Map tests = new HashMap();
for (File file : listXProcSpecFilesRecursively(testsDir))
tests.put(
file.getAbsolutePath().substring(testsDir.getAbsolutePath().length() + 1)
.replaceAll("\\.xprocspec$", "")
.replaceAll("[\\./\\\\]", "_"),
file);
File catalog = new File(testsDir, "catalog.xml");
if (!catalog.exists()) catalog = null;
return run(tests, reportsDir, surefireReportsDir, tempDir, catalog, reporter);
}
public static interface Reporter {
public void init();
public void running(String name) ;
public void result(int run, int failures, int errors, int skipped, long time, String shortDesc, String longDesc);
public void finish(int run, int failures, int errors, int skipped, long time);
public static class DefaultReporter implements Reporter {
private PrintStream stream;
private String currentTest;
private List failedTests = new ArrayList();
private List testsInError = new ArrayList();
public DefaultReporter() {
this(System.out);
}
public DefaultReporter(PrintStream stream) {
this.stream = stream;
}
private void println(String format, Object... args) {
stream.format(format + "\n", args);
}
public void init() {
println("-------------------------------------------------------");
println(" X P R O C S P E C T E S T S");
println("-------------------------------------------------------");
}
public void running(String name) {
println("Running %s", name);
currentTest = name;
}
public void result(int run, int failures, int errors, int skipped, long time, String shortDesc, String longDesc) {
println("Tests run: %d, Failures: %d, Errors: %d, Skipped: %d, Time elapsed: %s sec%s",
run, failures, errors, skipped, (new DecimalFormat("0.#")).format(time),
(failures > 0 || errors > 0) ? " <<< FAILURE!" : "");
List summary = errors > 0 ? testsInError : failures > 0 ? failedTests : null;
if (summary != null) {
if (shortDesc != null)
summary.add(currentTest + ": " + shortDesc);
else
summary.add(currentTest); }
if (longDesc != null)
println(longDesc);
}
public void finish(int run, int failures, int errors, int skipped, long time) {
if (run == 0)
println("There are no tests to run.");
println("");
println("Results :");
println("");
if (failedTests.size() > 0) {
println("Failed tests:");
for (String test : failedTests)
println(" " + test);
println(""); }
if (testsInError.size() > 0) {
println("Tests in error:");
for (String test : testsInError)
println(" " + test);
println(""); }
println("Tests run: %d, Failures: %d, Errors: %d, Skipped: %d", run, failures, errors, skipped);
}
}
}
/*
* FileUtils.listFiles from Apache Commons IO could be used here as well,
* but would introduce another dependency.
*/
private static Collection listXProcSpecFilesRecursively(File directory) {
ImmutableList.Builder builder = new ImmutableList.Builder();
for (File file : directory.listFiles()) {
if (file.isDirectory())
builder.addAll(listXProcSpecFilesRecursively(file));
else if (file.getName().endsWith(".xprocspec"))
builder.add(file); }
return builder.build();
}
public static URI asURI(Object o) {
try {
if (o instanceof URI)
return (URI)o;
if (o instanceof File)
return asURI(((File)o).toURI());
if (o instanceof URL) {
URL url = (URL)o;
if (url.getProtocol().equals("jar"))
return new URI("jar:" + new URI(null, url.getAuthority(), url.getPath(), url.getQuery(), url.getRef()).toASCIIString());
String authority = (url.getPort() != -1) ?
url.getHost() + ":" + url.getPort() :
url.getHost();
return new URI(url.getProtocol(), authority, url.getPath(), url.getQuery(), url.getRef()); }}
catch (Exception e) {}
throw new RuntimeException("Object can not be converted to URI: " + o);
}
private static XPath xpath = new XPathFactoryImpl().newXPath();
public static Object evaluateXPath(File file, String expression, final Map namespaces, Class> type) {
try {
if (namespaces != null)
xpath.setNamespaceContext(
new NamespaceContext() {
public String getNamespaceURI(String prefix) {
return namespaces.get(prefix); }
public String getPrefix(String namespaceURI) {
for (String prefix : namespaces.keySet())
if (namespaces.get(prefix).equals(namespaceURI))
return prefix;
return null; }
public Iterator getPrefixes(String namespaceURI) {
List prefixes = new ArrayList();
for (String prefix : namespaces.keySet())
if (namespaces.get(prefix).equals(namespaceURI))
prefixes.add(prefix);
return prefixes.iterator(); }});
else
xpath.setNamespaceContext(null);
XPathExpression expr = xpath.compile(expression);
InputSource source = new InputSource(file.toURI().toURL().openStream());
if (type.equals(Boolean.class))
return expr.evaluate(source, XPathConstants.BOOLEAN);
if (type.equals(String.class))
return expr.evaluate(source, XPathConstants.STRING);
if (type.equals(Integer.class))
return ((Double)expr.evaluate(source, XPathConstants.NUMBER)).intValue();
if (type.equals(Long.class))
return ((Double)expr.evaluate(source, XPathConstants.NUMBER)).longValue();
else
throw new RuntimeException("Cannot evaluate to a " + type.getName()); }
catch (Exception e) {
throw new RuntimeException("Exception occured during XPath evaluation.", e); }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy