use of com.helger.schematron.sch.TransformerCustomizerSCH in project ph-schematron by phax.
the class Schematron2XSLTMojo method execute.
public void execute() throws MojoExecutionException, MojoFailureException {
StaticLoggerBinder.getSingleton().setMavenLog(getLog());
if (m_aSchematronDirectory == null)
throw new MojoExecutionException("No Schematron directory specified!");
if (m_aSchematronDirectory.exists() && !m_aSchematronDirectory.isDirectory())
throw new MojoExecutionException("The specified Schematron directory " + m_aSchematronDirectory + " is not a directory!");
if (StringHelper.hasNoText(m_sSchematronPattern))
throw new MojoExecutionException("No Schematron pattern specified!");
if (m_aXsltDirectory == null)
throw new MojoExecutionException("No XSLT directory specified!");
if (m_aXsltDirectory.exists() && !m_aXsltDirectory.isDirectory())
throw new MojoExecutionException("The specified XSLT directory " + m_aXsltDirectory + " is not a directory!");
if (StringHelper.hasNoText(m_sXsltExtension) || !m_sXsltExtension.startsWith("."))
throw new MojoExecutionException("The XSLT extension '" + m_sXsltExtension + "' is invalid!");
if (!m_aXsltDirectory.exists() && !m_aXsltDirectory.mkdirs())
throw new MojoExecutionException("Failed to create the XSLT directory " + m_aXsltDirectory);
// for all Schematron files that match the pattern
final DirectoryScanner aScanner = new DirectoryScanner();
aScanner.setBasedir(m_aSchematronDirectory);
aScanner.setIncludes(new String[] { m_sSchematronPattern });
aScanner.setCaseSensitive(true);
aScanner.scan();
final String[] aFilenames = aScanner.getIncludedFiles();
if (aFilenames != null) {
for (final String sFilename : aFilenames) {
final File aFile = new File(m_aSchematronDirectory, sFilename);
// 1. build XSLT file name (outputdir + localpath with new extension)
final File aXSLTFile = new File(m_aXsltDirectory, FilenameHelper.getWithoutExtension(sFilename) + m_sXsltExtension);
getLog().info("Converting Schematron file '" + aFile.getPath() + "' to XSLT file '" + aXSLTFile.getPath() + "'");
// 2. The Schematron resource
final IReadableResource aSchematronResource = new FileSystemResource(aFile);
// 3. Check if the XSLT file already exists
if (aXSLTFile.exists() && !m_bOverwriteWithoutQuestion) {
// 3.1 Not overwriting the existing file
getLog().debug("Skipping XSLT file '" + aXSLTFile.getPath() + "' because it already exists!");
} else {
// 3.2 Create the directory, if necessary
final File aXsltFileDirectory = aXSLTFile.getParentFile();
if (aXsltFileDirectory != null && !aXsltFileDirectory.exists()) {
getLog().debug("Creating directory '" + aXsltFileDirectory.getPath() + "'");
if (!aXsltFileDirectory.mkdirs()) {
final String sMessage = "Failed to convert '" + aFile.getPath() + "' because directory '" + aXsltFileDirectory.getPath() + "' could not be created";
getLog().error(sMessage);
throw new MojoFailureException(sMessage);
}
}
// 3.3 The main SCH to XSLT conversion
final Wrapper<MojoFailureException> fe = new Wrapper<>();
final Wrapper<MojoExecutionException> ee = new Wrapper<>();
final Runnable r = () -> {
try {
buildContext.removeMessages(aFile);
// Custom error listener to log to the Mojo logger
final ErrorListener aMojoErrorListener = new PluginErrorListener(buildContext, aFile);
// Custom error listener
// No custom URI resolver
// Specified phase - default = null
// Specified language code - default = null
final TransformerCustomizerSCH aCustomizer = new TransformerCustomizerSCH().setErrorListener(aMojoErrorListener).setPhase(m_sPhaseName).setLanguageCode(m_sLanguageCode).setParameters(m_aCustomParameters).setForceCacheResult(m_bForceCacheResult);
getLog().debug("Compiling Schematron instance " + aSchematronResource.toString());
final Document aXsltDoc = SchematronProviderXSLTFromSCH.createSchematronXSLT(aSchematronResource, aCustomizer);
if (aXsltDoc != null) {
if (StringHelper.hasText(m_sXSLTHeader)) {
// Inject the header into the XSLT
aXsltDoc.insertBefore(aXsltDoc.createComment(m_sXSLTHeader), aXsltDoc.getDocumentElement());
}
// Write the resulting XSLT file to disk
final MapBasedNamespaceContext aNSContext = new MapBasedNamespaceContext().addMapping("svrl", CSVRL.SVRL_NAMESPACE_URI);
// Add all namespaces from XSLT document root
final String sNSPrefix = XMLConstants.XMLNS_ATTRIBUTE + ":";
XMLHelper.forAllAttributes(aXsltDoc.getDocumentElement(), (sAttrName, sAttrValue) -> {
if (sAttrName.startsWith(sNSPrefix))
aNSContext.addMapping(sAttrName.substring(sNSPrefix.length()), sAttrValue);
});
final XMLWriterSettings aXWS = new XMLWriterSettings().setNamespaceContext(aNSContext).setPutNamespaceContextPrefixesInRoot(true);
final OutputStream aOS = FileHelper.getOutputStream(aXSLTFile);
if (aOS == null)
throw new IllegalStateException("Failed to open output stream for file " + aXSLTFile.getAbsolutePath());
XMLWriter.writeToStream(aXsltDoc, aOS, aXWS);
getLog().debug("Finished creating XSLT file '" + aXSLTFile.getPath() + "'");
buildContext.refresh(aXsltFileDirectory);
} else {
final String message = "Failed to convert '" + aFile.getPath() + "': the Schematron resource is invalid";
getLog().error(message);
throw new MojoFailureException(message);
}
} catch (final MojoFailureException up) {
fe.set(up);
} catch (final Exception ex) {
final String sMessage = "Failed to convert '" + aFile.getPath() + "' to XSLT file '" + aXSLTFile.getPath() + "'";
getLog().error(sMessage, ex);
ee.set(new MojoExecutionException(sMessage, ex));
}
};
if (m_bShowProgress) {
// Run conversion in one thread and run another thread that logs the
// time
final ExecutorService aES = Executors.newSingleThreadExecutor();
aES.submit(r);
final long nStartTime = System.currentTimeMillis();
final AtomicBoolean aLoggedAnything = new AtomicBoolean(false);
final Thread t = new Thread(() -> {
long nLastSecs = 0;
while (!Thread.currentThread().isInterrupted()) {
if (ThreadHelper.sleep(500).isSuccess()) {
final long nDurationSecs = (System.currentTimeMillis() - nStartTime) / CGlobal.MILLISECONDS_PER_SECOND;
// Log only every x seconds
if (nDurationSecs >= nLastSecs + 5) {
getLog().info("Schematron conversion of '" + aFile.getName() + "' already takes " + nDurationSecs + " seconds - please wait...");
nLastSecs = nDurationSecs;
aLoggedAnything.set(true);
}
}
}
});
t.setDaemon(true);
t.start();
ExecutorServiceHelper.shutdownAndWaitUntilAllTasksAreFinished(aES);
t.interrupt();
if (aLoggedAnything.get()) {
// Log finalization of conversion if it took longer
final long nDurationSecs = (System.currentTimeMillis() - nStartTime) / CGlobal.MILLISECONDS_PER_SECOND;
getLog().info("Schematron conversion of '" + aFile.getName() + "' was finalized after " + nDurationSecs + " seconds");
}
} else {
// No progress version
r.run();
}
// Did any exceptions occur?
if (fe.isSet())
throw fe.get();
if (ee.isSet())
throw ee.get();
}
}
}
}
Aggregations