97 lines
3.6 KiB
Java
97 lines
3.6 KiB
Java
package eu.dnetlib.common.mapping.xslt;
|
|
|
|
import java.io.StringWriter;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import javax.xml.transform.stream.StreamSource;
|
|
|
|
import org.apache.commons.io.IOUtils;
|
|
|
|
import eu.dnetlib.common.clients.DnetServiceClientFactory;
|
|
import eu.dnetlib.common.clients.SimpleResourceClient;
|
|
import eu.dnetlib.common.clients.VocabularyClient;
|
|
import eu.dnetlib.common.mapping.RecordTransformer;
|
|
import eu.dnetlib.common.mapping.xslt.functions.CalculateMd5;
|
|
import eu.dnetlib.common.mapping.xslt.functions.XsltDateCleaner;
|
|
import eu.dnetlib.common.mapping.xslt.functions.XsltPersonCleaner;
|
|
import eu.dnetlib.common.mapping.xslt.functions.XsltVocabularyCleaner;
|
|
import eu.dnetlib.errors.TransformationException;
|
|
import net.sf.saxon.s9api.Processor;
|
|
import net.sf.saxon.s9api.QName;
|
|
import net.sf.saxon.s9api.SaxonApiException;
|
|
import net.sf.saxon.s9api.Serializer;
|
|
import net.sf.saxon.s9api.XdmAtomicValue;
|
|
import net.sf.saxon.s9api.XdmNode;
|
|
import net.sf.saxon.s9api.XmlProcessingError;
|
|
import net.sf.saxon.s9api.XsltCompiler;
|
|
import net.sf.saxon.s9api.XsltExecutable;
|
|
import net.sf.saxon.s9api.XsltTransformer;
|
|
|
|
public class XsltTransformerFactory {
|
|
|
|
private final DnetServiceClientFactory clientFactory;
|
|
|
|
public static final String QNAME_BASE_URI = "http://eu/dnetlib/transform";
|
|
|
|
public XsltTransformerFactory(final DnetServiceClientFactory clientFactory) {
|
|
this.clientFactory = clientFactory;
|
|
}
|
|
|
|
public RecordTransformer<String, String> getTransformerById(final String ruleId, final Map<String, Object> params) throws TransformationException {
|
|
final String xsltText =
|
|
this.clientFactory.getClient(SimpleResourceClient.class)
|
|
.findResourceContent(SimpleResourceClient.ResourceType.transformation_rule_xslt, ruleId, String.class);
|
|
|
|
return getTransformerByXSLT(xsltText, params);
|
|
}
|
|
|
|
public RecordTransformer<String, String> getTransformerByXSLT(final String xsltText, final Map<String, Object> params) throws TransformationException {
|
|
final Processor processor = new Processor(false);
|
|
processor.registerExtensionFunction(new CalculateMd5());
|
|
processor.registerExtensionFunction(new XsltDateCleaner());
|
|
processor.registerExtensionFunction(new XsltPersonCleaner());
|
|
processor.registerExtensionFunction(new XsltVocabularyCleaner(this.clientFactory.getClient(VocabularyClient.class)));
|
|
|
|
final List<XmlProcessingError> errorList = new ArrayList<>();
|
|
|
|
final XsltCompiler comp = processor.newXsltCompiler();
|
|
comp.setErrorList(errorList);
|
|
params.forEach((k, v) -> comp.setParameter(new QName(k), XdmAtomicValue.makeAtomicValue(v)));
|
|
|
|
try {
|
|
final XsltExecutable xslt = comp.compile(new StreamSource(IOUtils.toInputStream(xsltText, StandardCharsets.UTF_8)));
|
|
return xml -> {
|
|
try {
|
|
final XdmNode source = processor
|
|
.newDocumentBuilder()
|
|
.build(new StreamSource(IOUtils.toInputStream(xml, StandardCharsets.UTF_8)));
|
|
|
|
final XsltTransformer trans = xslt.load();
|
|
trans.setInitialContextNode(source);
|
|
|
|
final StringWriter output = new StringWriter();
|
|
final Serializer out = processor.newSerializer(output);
|
|
out.setOutputProperty(Serializer.Property.METHOD, "xml");
|
|
out.setOutputProperty(Serializer.Property.INDENT, "yes");
|
|
|
|
trans.setDestination(out);
|
|
trans.transform();
|
|
|
|
return output.toString();
|
|
} catch (final SaxonApiException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
};
|
|
} catch (final Throwable e) {
|
|
final StringWriter sw = new StringWriter();
|
|
sw.append("XSLT failure");
|
|
errorList.forEach(err -> sw.append("\n\t[XSLT ERR] " + err.getMessage()));
|
|
throw new TransformationException(sw.toString(), e);
|
|
}
|
|
}
|
|
|
|
}
|