Search in sources :

Example 1 with TransformerCustomizerSCH

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();
            }
        }
    }
}
Also used : BuildContext(org.sonatype.plexus.build.incremental.BuildContext) FileSystemResource(com.helger.commons.io.resource.FileSystemResource) SchematronProviderXSLTFromSCH(com.helger.schematron.sch.SchematronProviderXSLTFromSCH) XMLHelper(com.helger.xml.XMLHelper) Component(org.apache.maven.plugins.annotations.Component) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Parameter(org.apache.maven.plugins.annotations.Parameter) ErrorListener(javax.xml.transform.ErrorListener) FileHelper(com.helger.commons.io.file.FileHelper) Mojo(org.apache.maven.plugins.annotations.Mojo) TransformerCustomizerSCH(com.helger.schematron.sch.TransformerCustomizerSCH) MavenProject(org.apache.maven.project.MavenProject) Document(org.w3c.dom.Document) FilenameHelper(com.helger.commons.io.file.FilenameHelper) CSVRL(com.helger.schematron.svrl.CSVRL) Map(java.util.Map) VisibleForTesting(com.helger.commons.annotation.VisibleForTesting) XMLWriterSettings(com.helger.xml.serialize.write.XMLWriterSettings) LifecyclePhase(org.apache.maven.plugins.annotations.LifecyclePhase) ExecutorServiceHelper(com.helger.commons.concurrent.ExecutorServiceHelper) XMLConstants(javax.xml.XMLConstants) ReturnsMutableCopy(com.helger.commons.annotation.ReturnsMutableCopy) Nonnull(javax.annotation.Nonnull) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) OutputStream(java.io.OutputStream) CGlobal(com.helger.commons.CGlobal) StringHelper(com.helger.commons.string.StringHelper) StaticLoggerBinder(org.slf4j.impl.StaticLoggerBinder) MapBasedNamespaceContext(com.helger.xml.namespace.MapBasedNamespaceContext) IReadableResource(com.helger.commons.io.resource.IReadableResource) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) XMLWriter(com.helger.xml.serialize.write.XMLWriter) File(java.io.File) Executors(java.util.concurrent.Executors) MojoFailureException(org.apache.maven.plugin.MojoFailureException) CommonsHashMap(com.helger.commons.collection.impl.CommonsHashMap) Wrapper(com.helger.commons.wrapper.Wrapper) ICommonsMap(com.helger.commons.collection.impl.ICommonsMap) DirectoryScanner(org.codehaus.plexus.util.DirectoryScanner) Since(com.helger.commons.annotation.Since) AbstractMojo(org.apache.maven.plugin.AbstractMojo) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) ThreadHelper(com.helger.commons.concurrent.ThreadHelper) TransformerCustomizerSCH(com.helger.schematron.sch.TransformerCustomizerSCH) OutputStream(java.io.OutputStream) IReadableResource(com.helger.commons.io.resource.IReadableResource) FileSystemResource(com.helger.commons.io.resource.FileSystemResource) Document(org.w3c.dom.Document) ErrorListener(javax.xml.transform.ErrorListener) MapBasedNamespaceContext(com.helger.xml.namespace.MapBasedNamespaceContext) DirectoryScanner(org.codehaus.plexus.util.DirectoryScanner) Wrapper(com.helger.commons.wrapper.Wrapper) XMLWriterSettings(com.helger.xml.serialize.write.XMLWriterSettings) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ExecutorService(java.util.concurrent.ExecutorService) File(java.io.File)

Aggregations

CGlobal (com.helger.commons.CGlobal)1 ReturnsMutableCopy (com.helger.commons.annotation.ReturnsMutableCopy)1 Since (com.helger.commons.annotation.Since)1 VisibleForTesting (com.helger.commons.annotation.VisibleForTesting)1 CommonsHashMap (com.helger.commons.collection.impl.CommonsHashMap)1 ICommonsMap (com.helger.commons.collection.impl.ICommonsMap)1 ExecutorServiceHelper (com.helger.commons.concurrent.ExecutorServiceHelper)1 ThreadHelper (com.helger.commons.concurrent.ThreadHelper)1 FileHelper (com.helger.commons.io.file.FileHelper)1 FilenameHelper (com.helger.commons.io.file.FilenameHelper)1 FileSystemResource (com.helger.commons.io.resource.FileSystemResource)1 IReadableResource (com.helger.commons.io.resource.IReadableResource)1 StringHelper (com.helger.commons.string.StringHelper)1 Wrapper (com.helger.commons.wrapper.Wrapper)1 SchematronProviderXSLTFromSCH (com.helger.schematron.sch.SchematronProviderXSLTFromSCH)1 TransformerCustomizerSCH (com.helger.schematron.sch.TransformerCustomizerSCH)1 CSVRL (com.helger.schematron.svrl.CSVRL)1 XMLHelper (com.helger.xml.XMLHelper)1 MapBasedNamespaceContext (com.helger.xml.namespace.MapBasedNamespaceContext)1 XMLWriter (com.helger.xml.serialize.write.XMLWriter)1