All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.verapdf.policy.SchematronPipeline Maven / Gradle / Ivy

/**
 * This file is part of veraPDF Library core, a module of the veraPDF project.
 * Copyright (c) 2015, veraPDF Consortium 
 * All rights reserved.
 *
 * veraPDF Library core is free software: you can redistribute it and/or modify
 * it under the terms of either:
 *
 * The GNU General public license GPLv3+.
 * You should have received a copy of the GNU General Public License
 * along with veraPDF Library core as the LICENSE.GPL file in the root of the source
 * tree.  If not, see http://www.gnu.org/licenses/ or
 * https://www.gnu.org/licenses/gpl-3.0.en.html.
 *
 * The Mozilla Public License MPLv2+.
 * You should have received a copy of the Mozilla Public License along with
 * veraPDF Library core as the LICENSE.MPL file in the root of the source tree.
 * If a copy of the MPL was not distributed with this file, you can obtain one at
 * http://mozilla.org/MPL/2.0/.
 */
/**
 * 
 */
package org.verapdf.policy;

import javax.xml.XMLConstants;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Carl Wilson
 *         carlwilson AT github
 * @version 0.1 Created 12 Dec 2016:16:52:10
 */

final class SchematronPipeline {
	private static final Logger LOGGER = Logger.getLogger(SchematronPipeline.class.getName());

	static final ClassLoader cl = SchematronPipeline.class.getClassLoader();
	private static final TransformerFactory factory = getTransformerFactory();
	private static final String xslExt = ".xsl"; //$NON-NLS-1$
	private static final String resourcePath = "org/verapdf/policy/schematron/pipeline/"; //$NON-NLS-1$
	private static final String isoDsdlXsl = resourcePath + "iso_dsdl_include" + xslExt; //$NON-NLS-1$
	private static final String isoExpXsl = resourcePath + "iso_abstract_expand" + xslExt; //$NON-NLS-1$
	private static final String isoSvrlXsl = resourcePath + "iso_svrl_for_xslt1" + xslExt; //$NON-NLS-1$
	private static final Templates cachedIsoDsdXsl = createCachedTransform(isoDsdlXsl);
	private static final Templates cachedExpXsl = createCachedTransform(isoExpXsl);
	private static final Templates cachedIsoSvrlXsl = createCachedTransform(isoSvrlXsl);

	private SchematronPipeline() {
	}

	public static void processSchematron(InputStream schematronSource, OutputStream xslDest)
			throws TransformerException, IOException {
		File isoDsdResult = createTempFileResult(cachedIsoDsdXsl.newTransformer(), new StreamSource(schematronSource),
				"IsoDsd"); //$NON-NLS-1$
		File isoExpResult = createTempFileResult(cachedExpXsl.newTransformer(), new StreamSource(isoDsdResult),
				"ExpXsl"); //$NON-NLS-1$
		Transformer transformer = cachedIsoSvrlXsl.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "no");
		transformer.transform(new StreamSource(isoExpResult), new StreamResult(xslDest));
		if (!isoDsdResult.delete()) {
			isoDsdResult.deleteOnExit();
		}
		if (!isoExpResult.delete()) {
			isoExpResult.deleteOnExit();
		}
	}

	static Templates createCachedTransform(final String transName) {
		try {
			return factory.newTemplates(new StreamSource(cl.getResourceAsStream(transName)));
		} catch (TransformerConfigurationException excep) {
			throw new IllegalStateException("Policy Schematron transformer XSL " + transName + " not found.", excep); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform,
			final String suffix) throws TransformerException, IOException {
		File result = File.createTempFile("veraPDF_", suffix); //$NON-NLS-1$

		try (FileOutputStream fos = new FileOutputStream(result)) {
			transformer.transform(toTransform, new StreamResult(fos));
		}
		return result;
	}

	private static TransformerFactory getTransformerFactory() {
		TransformerFactory fact = TransformerFactory.newInstance();
		try {
			fact.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
			fact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "file");
		} catch (TransformerConfigurationException e) {
			LOGGER.log(Level.WARNING, "Unable to secure xsl transformer");
		}
		fact.setURIResolver(new ClasspathResourceURIResolver());
		return fact;
	}

	private static class ClasspathResourceURIResolver implements URIResolver {
		ClasspathResourceURIResolver() {
			// Do nothing, just prevents synthetic access warning.
		}

		@Override
		public Source resolve(String href, String base) throws TransformerException {
			InputStream inputStream;
			File file = new File(href);
			if (file.exists()) {
				try {
					inputStream = new FileInputStream(file);
				} catch (FileNotFoundException e) {
					LOGGER.log(Level.SEVERE, "File not found but exists", e);
					inputStream = new ByteArrayInputStream(new byte[0]);
				}
			} else {
				inputStream = cl.getResourceAsStream(resourcePath + href);
			}
			return new StreamSource(inputStream);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy