From 0ac1a88928e9281dd0b59692328b91191714fadd Mon Sep 17 00:00:00 2001 From: Christian Bethge Date: Tue, 29 Aug 2023 15:02:52 +0200 Subject: [PATCH] use Templates for compiled XSLT instead of Transformer - use Templates are thread-safe and NOT Transformer --- .../data/internal/MetadataFormat.java | 11 ++++++----- .../data/internal/MetadataTransformer.java | 18 +++++++++--------- .../format/MetadataFormatManager.java | 7 ++++--- .../handlers/GetRecordHandler.java | 8 ++++---- .../handlers/ListRecordsHandler.java | 8 ++++---- .../services/api/ResourceResolver.java | 4 +++- .../services/impl/FileResourceResolver.java | 6 ++++-- .../transform/TransformManager.java | 4 ++-- .../dataprovider/transform/XSLTemplates.java | 11 +++++++++++ .../dataprovider/transform/XSLTransformer.java | 11 ----------- .../com/lyncode/xoai/util/XSLPipeline.java | 4 +++- .../acceptance/AbstractDataProviderTest.java | 5 ++++- .../xoai/tests/dataprovider/unit/XmlTest.java | 8 +++++--- .../xoai/tests/util/XSLPipelineTest.java | 4 ++-- src/test/resources/identity_transform.xsl | 7 +++++++ 15 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 src/main/java/com/lyncode/xoai/dataprovider/transform/XSLTemplates.java delete mode 100644 src/main/java/com/lyncode/xoai/dataprovider/transform/XSLTransformer.java create mode 100644 src/test/resources/identity_transform.xsl diff --git a/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataFormat.java b/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataFormat.java index cba9af62..22f8ee81 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataFormat.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataFormat.java @@ -19,6 +19,7 @@ import com.lyncode.xoai.dataprovider.data.ItemIdentifier; import com.lyncode.xoai.dataprovider.filter.conditions.Condition; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; /** @@ -27,14 +28,14 @@ */ public class MetadataFormat { private String prefix; - private Transformer xsltTransformer; + private Templates xsltTemplates; private String namespace; private String schemaLocation; private Condition filter; - public MetadataFormat(String prefix, Transformer transformer, String namespace, String schemaLocation) { + public MetadataFormat(String prefix, Templates xsltTemplates, String namespace, String schemaLocation) { this.prefix = prefix; - this.xsltTransformer = transformer; + this.xsltTemplates = xsltTemplates; this.namespace = namespace; this.schemaLocation = schemaLocation; } @@ -43,8 +44,8 @@ public String getPrefix() { return prefix; } - public Transformer getTransformer() { - return xsltTransformer; + public Templates getXsltTemplates() { + return xsltTemplates; } public String getNamespace() { diff --git a/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataTransformer.java b/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataTransformer.java index 6ffe0bc3..c2c27184 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataTransformer.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/data/internal/MetadataTransformer.java @@ -16,28 +16,28 @@ package com.lyncode.xoai.dataprovider.data.internal; -import com.lyncode.xoai.dataprovider.transform.XSLTransformer; +import com.lyncode.xoai.dataprovider.transform.XSLTemplates; /** * @version 3.1.0 */ public class MetadataTransformer { - private XSLTransformer xslTransformer; + private XSLTemplates xslTemplates; public MetadataTransformer() { - xslTransformer = null; + xslTemplates = null; } - public MetadataTransformer(XSLTransformer xsltTransformer) { - this.xslTransformer = xsltTransformer; + public MetadataTransformer(XSLTemplates xslTemplates) { + this.xslTemplates = xslTemplates; } - public boolean hasTransformer() { - return (this.xslTransformer != null); + public boolean hasXslTemplates() { + return (this.xslTemplates != null); } - public XSLTransformer getXslTransformer() { - return this.xslTransformer; + public XSLTemplates getXslTemplates() { + return this.xslTemplates; } } diff --git a/src/main/java/com/lyncode/xoai/dataprovider/format/MetadataFormatManager.java b/src/main/java/com/lyncode/xoai/dataprovider/format/MetadataFormatManager.java index 3617b203..88be55a3 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/format/MetadataFormatManager.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/format/MetadataFormatManager.java @@ -26,6 +26,7 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import java.io.IOException; @@ -48,17 +49,17 @@ public MetadataFormatManager(ResourceResolver resolver, List(); for (FormatConfiguration format : config) { - Transformer transformer = null; + Templates templates = null; try { - transformer = resolver.getTransformer(format.getXslt()); + templates = resolver.getTemplates(format.getXslt()); } catch (TransformerConfigurationException e) { throw new ConfigurationException(e.getMessage(), e); } catch (IOException e) { throw new ConfigurationException(e.getMessage(), e); } - MetadataFormat metadataFormat = new MetadataFormat(format.getPrefix(), transformer, format.getNamespace(), format.getSchemaLocation()); + MetadataFormat metadataFormat = new MetadataFormat(format.getPrefix(), templates, format.getNamespace(), format.getSchemaLocation()); if (format.hasFilter()) metadataFormat.setFilter(filterManager.getFilter(format.getFilter().getReference())); contexts.put(format.getId(), metadataFormat); diff --git a/src/main/java/com/lyncode/xoai/dataprovider/handlers/GetRecordHandler.java b/src/main/java/com/lyncode/xoai/dataprovider/handlers/GetRecordHandler.java index 07111202..241d64d5 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/handlers/GetRecordHandler.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/handlers/GetRecordHandler.java @@ -54,14 +54,14 @@ public GetRecordType handle(OAIParameters parameters) throws OAIException, Handl if (!itemHelper.getItem().isDeleted()) { MetadataType metadata = null; try { - if (context.getTransformer().hasTransformer()) { + if (context.getTransformer().hasXslTemplates()) { metadata = new MetadataType(itemHelper.toPipeline(true) - .apply(context.getTransformer().getXslTransformer().getValue()) - .apply(format.getTransformer()) + .apply(context.getTransformer().getXslTemplates().getValue()) + .apply(format.getXsltTemplates()) .getTransformed()); } else { metadata = new MetadataType(itemHelper.toPipeline(true) - .apply(format.getTransformer()) + .apply(format.getXsltTemplates()) .getTransformed()); } } catch (WritingXmlException e) { diff --git a/src/main/java/com/lyncode/xoai/dataprovider/handlers/ListRecordsHandler.java b/src/main/java/com/lyncode/xoai/dataprovider/handlers/ListRecordsHandler.java index 20566b28..87af5c20 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/handlers/ListRecordsHandler.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/handlers/ListRecordsHandler.java @@ -150,14 +150,14 @@ private RecordType createRecord(OAIParameters parameters, Item item) if (!item.isDeleted()) { MetadataType metadata = null; try { - if (context.getTransformer().hasTransformer()) { + if (context.getTransformer().hasXslTemplates()) { metadata = new MetadataType(itemHelperWrap.toPipeline(true) - .apply(context.getTransformer().getXslTransformer().getValue()) - .apply(format.getTransformer()) + .apply(context.getTransformer().getXslTemplates().getValue()) + .apply(format.getXsltTemplates()) .getTransformed()); } else { metadata = new MetadataType(itemHelperWrap.toPipeline(true) - .apply(format.getTransformer()) + .apply(format.getXsltTemplates()) .getTransformed()); } } catch (WritingXmlException e) { diff --git a/src/main/java/com/lyncode/xoai/dataprovider/services/api/ResourceResolver.java b/src/main/java/com/lyncode/xoai/dataprovider/services/api/ResourceResolver.java index a02f2987..5e241472 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/services/api/ResourceResolver.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/services/api/ResourceResolver.java @@ -1,5 +1,6 @@ package com.lyncode.xoai.dataprovider.services.api; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import java.io.IOException; @@ -7,5 +8,6 @@ public interface ResourceResolver { InputStream getResource(String path) throws IOException; - Transformer getTransformer (String path) throws IOException, TransformerConfigurationException; + + Templates getTemplates(String path) throws IOException, TransformerConfigurationException; } diff --git a/src/main/java/com/lyncode/xoai/dataprovider/services/impl/FileResourceResolver.java b/src/main/java/com/lyncode/xoai/dataprovider/services/impl/FileResourceResolver.java index 29a7fe67..fd70b454 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/services/impl/FileResourceResolver.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/services/impl/FileResourceResolver.java @@ -2,6 +2,7 @@ import com.lyncode.xoai.dataprovider.services.api.ResourceResolver; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; @@ -24,8 +25,9 @@ public InputStream getResource(String path) throws IOException { return new FileInputStream(new File(basePath, path)); } + @Override - public Transformer getTransformer(String path) throws IOException, TransformerConfigurationException { - return tFactory.newTransformer(new StreamSource(getResource(path))); + public Templates getTemplates(String path) throws IOException, TransformerConfigurationException { + return tFactory.newTemplates(new StreamSource(getResource(path))); } } diff --git a/src/main/java/com/lyncode/xoai/dataprovider/transform/TransformManager.java b/src/main/java/com/lyncode/xoai/dataprovider/transform/TransformManager.java index 334de27f..254ded11 100644 --- a/src/main/java/com/lyncode/xoai/dataprovider/transform/TransformManager.java +++ b/src/main/java/com/lyncode/xoai/dataprovider/transform/TransformManager.java @@ -42,8 +42,8 @@ public TransformManager(ResourceResolver resolver, List { + public XSLTemplates(Templates templates) { + super(templates); + } +} diff --git a/src/main/java/com/lyncode/xoai/dataprovider/transform/XSLTransformer.java b/src/main/java/com/lyncode/xoai/dataprovider/transform/XSLTransformer.java deleted file mode 100644 index c5191ea4..00000000 --- a/src/main/java/com/lyncode/xoai/dataprovider/transform/XSLTransformer.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.lyncode.xoai.dataprovider.transform; - -import com.lyncode.xoai.util.TinyType; - -import javax.xml.transform.Transformer; - -public class XSLTransformer extends TinyType { - public XSLTransformer(Transformer transformer) { - super(transformer); - } -} diff --git a/src/main/java/com/lyncode/xoai/util/XSLPipeline.java b/src/main/java/com/lyncode/xoai/util/XSLPipeline.java index eb8c18a0..e686521d 100644 --- a/src/main/java/com/lyncode/xoai/util/XSLPipeline.java +++ b/src/main/java/com/lyncode/xoai/util/XSLPipeline.java @@ -1,6 +1,7 @@ package com.lyncode.xoai.util; import javax.xml.transform.OutputKeys; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; @@ -19,8 +20,9 @@ public XSLPipeline(InputStream inputStream, boolean omitXMLDeclaration) { this.omitXMLDeclaration = omitXMLDeclaration; } - public XSLPipeline apply(Transformer xslTransformer) throws TransformerException { + public XSLPipeline apply(Templates xslTemplates) throws TransformerException { outputStream = new ByteArrayOutputStream(); + Transformer xslTransformer = xslTemplates.newTransformer(); xslTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, (omitXMLDeclaration) ? "yes" : "no"); xslTransformer.transform(new StreamSource(inputStream), new StreamResult(outputStream)); inputStream = new ByteArrayInputStream(outputStream.toByteArray()); diff --git a/src/test/java/com/lyncode/xoai/tests/dataprovider/acceptance/AbstractDataProviderTest.java b/src/test/java/com/lyncode/xoai/tests/dataprovider/acceptance/AbstractDataProviderTest.java index 9f6551c3..f1f76794 100644 --- a/src/test/java/com/lyncode/xoai/tests/dataprovider/acceptance/AbstractDataProviderTest.java +++ b/src/test/java/com/lyncode/xoai/tests/dataprovider/acceptance/AbstractDataProviderTest.java @@ -35,6 +35,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.ParseException; @@ -70,7 +71,9 @@ public abstract class AbstractDataProviderTest { @Before public void setUp() throws IOException, TransformerConfigurationException, ParseException { - when(resourceResolver.getTransformer(XOAI_XSLT_LOCATION)).thenReturn(tFactory.newTransformer()); + when(resourceResolver.getTemplates(XOAI_XSLT_LOCATION)). + thenReturn(tFactory.newTemplates(new StreamSource( + this.getClass().getClassLoader().getResourceAsStream("identity_transform.xsl")))); configuration = new Configuration().withIndented(true); diff --git a/src/test/java/com/lyncode/xoai/tests/dataprovider/unit/XmlTest.java b/src/test/java/com/lyncode/xoai/tests/dataprovider/unit/XmlTest.java index 37ba68fe..6333e157 100644 --- a/src/test/java/com/lyncode/xoai/tests/dataprovider/unit/XmlTest.java +++ b/src/test/java/com/lyncode/xoai/tests/dataprovider/unit/XmlTest.java @@ -7,9 +7,10 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import javax.xml.transform.Transformer; +import javax.xml.transform.Templates; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayOutputStream; public abstract class XmlTest { @@ -27,9 +28,10 @@ protected String theOutput() { return output.toString(); } - protected Transformer identityTransformer() { + protected Templates identityTemplate() { try { - return tFactory.newTransformer(); + return tFactory.newTemplates(new StreamSource( + this.getClass().getClassLoader().getResourceAsStream("identity_transform.xsl"))); } catch (TransformerConfigurationException e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/src/test/java/com/lyncode/xoai/tests/util/XSLPipelineTest.java b/src/test/java/com/lyncode/xoai/tests/util/XSLPipelineTest.java index f23a8a2e..685eb3bc 100644 --- a/src/test/java/com/lyncode/xoai/tests/util/XSLPipelineTest.java +++ b/src/test/java/com/lyncode/xoai/tests/util/XSLPipelineTest.java @@ -30,14 +30,14 @@ public void shouldGiveTheSameIfNoTransformationIsApplied() throws IOException { @Test public void shouldTransformWithXmlDeclarationOnTop() throws TransformerException, IOException { XSLPipeline underTest = new XSLPipeline(input, false); - underTest.apply(identityTransformer()); + underTest.apply(identityTemplate()); assertThat(IOUtils.toString(underTest.getTransformed()), containsString(" + + + + + + \ No newline at end of file