org.fryske_akademy.transformation.XslTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of teidictionaries Show documentation
Show all versions of teidictionaries Show documentation
ValidationHelpers with to and from XML methods and JAXB classes for tei dictionaries
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());
}
}
}