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

org.fryske_akademy.transformation.XslTransformer Maven / Gradle / Ivy

Go to download

ValidationHelpers with to and from XML methods and JAXB classes for tei dictionaries

There is a newer version: 5.9
Show newest version
package org.fryske_akademy.transformation;

/*-
 * #%L
 * teidictionaries
 * %%
 * Copyright (C) 2020 - 2021 Fryske Akademy
 * %%
 * 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.
 * #L%
 */

import name.dmaus.schxslt.SchematronException;
import org.fryske_akademy.validation.lex0.Lex0_RngValidationHelper;
import org.xml.sax.SAXException;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * generic xslt transformer. also provides transformation from customized TEI of the Fryske Akademy to TEI Lex-0
 */
public class XslTransformer {

    private static final TransformerFactory FACTORY = TransformerFactory.newInstance();

    private final Map params = new HashMap<>();

    private final Transformer transformer;

    private static final Map TEMPLATES = new HashMap<>();

    /**
     * Constructs a new transformer (and templates if not cached and cache is enabled) and caches the templates it caching is enabled.
     *
     * @param id
     * @param source
     * @return
     * @throws TransformerConfigurationException
     */
    private static Transformer get(String id, StreamSource source, boolean newFactory) throws TransformerConfigurationException {
        boolean has = id != null && TEMPLATES.containsKey(id);

        synchronized (TEMPLATES) {
            if (has) {
                return TEMPLATES.get(id).newTransformer();
            }

            Templates t = newFactory ?
                    TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",
                            XslTransformer.class.getClassLoader()).newTemplates(source) :
                    FACTORY.newTemplates(source);
            if (id!=null) TEMPLATES.put(id, t);
            return t.newTransformer();
        }
    }

    public XslTransformer(File stylesheet) throws TransformerConfigurationException, FileNotFoundException {
        transformer = get(stylesheet.getAbsolutePath(), new StreamSource(stylesheet), false);
    }

    public XslTransformer(InputStream stylesheet, String id, boolean newFactory) throws TransformerConfigurationException {
        transformer = get(id, new StreamSource(stylesheet),newFactory);
    }

    public XslTransformer(InputStream stylesheet, boolean newFactory) throws TransformerConfigurationException {
        transformer = get(null, new StreamSource(stylesheet),newFactory);
    }

    public XslTransformer(Reader stylesheet, boolean newFactory) throws TransformerConfigurationException {
        transformer = get(null, new StreamSource(stylesheet),newFactory);
    }

    /**
     * stylesheet is assumed to be a resource URI
     *
     * @param stylesheet
     * @throws TransformerConfigurationException
     */
    public XslTransformer(String stylesheet) throws TransformerConfigurationException {
        transformer = get(stylesheet, new StreamSource(stylesheet),false);
    }

    public XslTransformer(String stylesheet, Reader sheet) throws TransformerConfigurationException {
        transformer = get(stylesheet, new StreamSource(sheet),false);
    }

    public String transform(String source)
            throws TransformerException {
        StreamSource ssSource = new StreamSource(new StringReader(source));
        StringWriter result = new StringWriter();
        StreamResult streamResult = new StreamResult(result);

        synchronized (transformer) {
            for (Entry e : params.entrySet()) {
                transformer.setParameter(e.getKey(), e.getValue());
            }

            transformer.transform(ssSource, streamResult);
            transformer.reset();
        }

        return result.toString();
    }

    public  W streamTransform(Reader source, W result)
            throws TransformerException {
        StreamSource ssSource = new StreamSource(source);
        StreamResult streamResult = new StreamResult(result);

        synchronized (transformer) {
            for (Entry e : params.entrySet()) {
                transformer.setParameter(e.getKey(), e.getValue());
            }

            transformer.transform(ssSource, streamResult);
            transformer.reset();
        }
        return result;

    }

    public void addParameter(String key, String value) {
        params.put(key, value);
    }

    public void clearParameters() {
        params.clear();
    }

    /**
     * clear cached templates
     */
    public static void clear() {
        TEMPLATES.clear();
    }

    /**
     * remove cached templates for id
     * @param id
     */
    public static void clear(String id) {
        TEMPLATES.remove(id);
    }

    public void setErrorListener(ErrorListener errorListener) {
        transformer.setErrorListener(errorListener);
    }

    private static class TeeWriter extends Writer {

        private final StringWriter sw;
        private final Writer writer;

        public TeeWriter(Writer writer) {
            this.writer = writer;
            sw=writer instanceof StringWriter ? (StringWriter) writer : new StringWriter();
        }

        @Override
        public void write(char[] chars, int i, int i1) throws IOException {
            writer.write(chars,i,i1);
            if (!(writer instanceof StringWriter)) sw.write(chars,i,i1);
        }

        @Override
        public void flush() throws IOException {
            writer.flush();
            if (!(writer instanceof StringWriter)) sw.flush();
        }

        @Override
        public void close() throws IOException {
            writer.close();
            if (!(writer instanceof StringWriter)) sw.close();
        }
    }

    /**
     * convert customized TEI of the Fryske Akademy to TEI Lex-0
     * @param xml
     * @param writer
     * @param validate
     * @throws TransformerException
     * @throws IOException
     * @throws SchematronException
     * @throws SAXException
     */
    public static void FaToLex0(String xml, Writer writer, boolean validate) throws TransformerException, IOException, SchematronException, SAXException {
        FaToLex0(new StringReader(xml),writer,validate);
    }

    /**
     * convert customized TEI of the Fryske Akademy to TEI Lex-0
     * @param reader
     * @param writer
     * @param validate
     * @throws TransformerException
     * @throws IOException
     * @throws SchematronException
     * @throws SAXException
     */
    public static void FaToLex0(Reader reader, Writer writer, boolean validate) throws TransformerException, IOException, SchematronException, SAXException {
        XslTransformer transformer = new XslTransformer("src/main/resources/xslt/teiToLex0.xslt");
        Writer w = validate?new TeeWriter(writer):writer;
        transformer.streamTransform(reader,w);
        if (validate) {
            Lex0_RngValidationHelper.validateRngSchematron(((TeeWriter)w).sw.toString());
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy