From 57e3880ce377ef56b6276a13d6d91fcf5f71b67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Sat, 8 Mar 2025 12:19:32 +0100 Subject: [PATCH] Add utility to create a org.xml.sax.XMLReader Closes gh-1471 --- .../PayloadTransformingInterceptor.java | 6 ++---- .../wsdl/wsdl11/SimpleWsdl11Definition.java | 9 +++----- .../ws/AbstractWebServiceMessageTest.java | 5 +---- .../server/endpoint/AbstractEndpointTest.java | 6 ++---- .../org/springframework/xml/sax/SaxUtils.java | 21 +++++++++++++++++++ .../xml/validation/SchemaLoaderUtils.java | 12 ++++++++++- .../xml/validation/XMLReaderFactoryUtils.java | 20 +++++------------- .../xml/dom/DomContentHandlerTest.java | 6 ++---- .../xml/transform/TraxUtilsTest.java | 6 ++---- 9 files changed, 49 insertions(+), 42 deletions(-) diff --git a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java index 32a79d6d..80a805b7 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java @@ -19,7 +19,6 @@ package org.springframework.ws.server.endpoint.interceptor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; @@ -38,6 +37,7 @@ import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.context.MessageContext; import org.springframework.ws.server.EndpointInterceptor; +import org.springframework.xml.sax.SaxUtils; import org.springframework.xml.transform.ResourceSource; import org.springframework.xml.transform.TransformerObjectSupport; @@ -139,9 +139,7 @@ public class PayloadTransformingInterceptor extends TransformerObjectSupport throw new IllegalArgumentException("Setting either 'requestXslt' or 'responseXslt' is required"); } TransformerFactory transformerFactory = getTransformerFactory(); - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader(); + XMLReader xmlReader = SaxUtils.namespaceAwareXmlReader(); xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); if (this.requestXslt != null) { Assert.isTrue(this.requestXslt.exists(), "requestXslt \"" + this.requestXslt + "\" does not exit"); diff --git a/spring-ws-core/src/main/java/org/springframework/ws/wsdl/wsdl11/SimpleWsdl11Definition.java b/spring-ws-core/src/main/java/org/springframework/ws/wsdl/wsdl11/SimpleWsdl11Definition.java index fe34d912..893df556 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/wsdl/wsdl11/SimpleWsdl11Definition.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/wsdl/wsdl11/SimpleWsdl11Definition.java @@ -18,8 +18,6 @@ package org.springframework.ws.wsdl.wsdl11; import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Source; import org.xml.sax.SAXException; @@ -29,6 +27,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.ws.wsdl.WsdlDefinitionException; +import org.springframework.xml.sax.SaxUtils; import org.springframework.xml.transform.ResourceSource; /** @@ -73,13 +72,11 @@ public class SimpleWsdl11Definition implements Wsdl11Definition, InitializingBea @Override public Source getSource() { try { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader(); + XMLReader xmlReader = SaxUtils.namespaceAwareXmlReader(); xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); return new ResourceSource(xmlReader, this.wsdlResource); } - catch (SAXException | ParserConfigurationException ex) { + catch (SAXException ex) { throw new WsdlDefinitionException("Could not create XMLReader", ex); } catch (IOException ex) { diff --git a/spring-ws-core/src/test/java/org/springframework/ws/AbstractWebServiceMessageTest.java b/spring-ws-core/src/test/java/org/springframework/ws/AbstractWebServiceMessageTest.java index 90038819..587e21ad 100644 --- a/spring-ws-core/src/test/java/org/springframework/ws/AbstractWebServiceMessageTest.java +++ b/spring-ws-core/src/test/java/org/springframework/ws/AbstractWebServiceMessageTest.java @@ -26,7 +26,6 @@ import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; @@ -188,9 +187,7 @@ public abstract class AbstractWebServiceMessageTest { } private void validateMessage() throws Exception { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader(); + XMLReader xmlReader = SaxUtils.namespaceAwareXmlReader(); xmlReader.setContentHandler(new DefaultHandler()); ByteArrayOutputStream os = new ByteArrayOutputStream(); this.webServiceMessage.writeTo(os); diff --git a/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/AbstractEndpointTest.java b/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/AbstractEndpointTest.java index 1ee1a29b..5b5d2ca7 100644 --- a/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/AbstractEndpointTest.java +++ b/spring-ws-core/src/test/java/org/springframework/ws/server/endpoint/AbstractEndpointTest.java @@ -24,7 +24,6 @@ import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; @@ -41,6 +40,7 @@ import org.xml.sax.XMLReader; import org.springframework.util.xml.StaxUtils; import org.springframework.xml.DocumentBuilderFactoryUtils; import org.springframework.xml.XMLInputFactoryUtils; +import org.springframework.xml.sax.SaxUtils; @SuppressWarnings("Since15") public abstract class AbstractEndpointTest { @@ -67,9 +67,7 @@ public abstract class AbstractEndpointTest { @Test public void testSaxSource() throws Exception { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - XMLReader reader = parserFactory.newSAXParser().getXMLReader(); + XMLReader reader = SaxUtils.namespaceAwareXmlReader(); InputSource inputSource = new InputSource(new StringReader(REQUEST)); testSource(new SAXSource(reader, inputSource)); } diff --git a/spring-xml/src/main/java/org/springframework/xml/sax/SaxUtils.java b/spring-xml/src/main/java/org/springframework/xml/sax/SaxUtils.java index ecd2676b..09e9feca 100644 --- a/spring-xml/src/main/java/org/springframework/xml/sax/SaxUtils.java +++ b/spring-xml/src/main/java/org/springframework/xml/sax/SaxUtils.java @@ -20,9 +20,14 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; import org.springframework.core.io.Resource; @@ -36,6 +41,22 @@ public abstract class SaxUtils { private static final Log logger = LogFactory.getLog(SaxUtils.class); + /** + * Create a default {@link XMLReader} that is + * {@linkplain SAXParserFactory#setNamespaceAware(boolean) namespace aware}. + * @return a new {@link XMLReader} + */ + public static XMLReader namespaceAwareXmlReader() throws SAXException { + try { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + parserFactory.setNamespaceAware(true); + return parserFactory.newSAXParser().getXMLReader(); + } + catch (ParserConfigurationException ex) { + throw new IllegalStateException(ex); + } + } + /** * Creates a SAX {@code InputSource} from the given resource. Sets the system * identifier to the resource's {@code URL}, if available. diff --git a/spring-xml/src/main/java/org/springframework/xml/validation/SchemaLoaderUtils.java b/spring-xml/src/main/java/org/springframework/xml/validation/SchemaLoaderUtils.java index a431cdbc..1955bed7 100644 --- a/spring-xml/src/main/java/org/springframework/xml/validation/SchemaLoaderUtils.java +++ b/spring-xml/src/main/java/org/springframework/xml/validation/SchemaLoaderUtils.java @@ -27,6 +27,7 @@ import org.xml.sax.XMLReader; import org.springframework.core.io.Resource; import org.springframework.util.Assert; +import org.springframework.xml.sax.SaxUtils; import org.springframework.xml.transform.ResourceSource; /** @@ -66,7 +67,7 @@ public abstract class SchemaLoaderUtils { Assert.notEmpty(resources, "No resources given"); Assert.hasLength(schemaLanguage, "No schema language provided"); Source[] schemaSources = new Source[resources.length]; - XMLReader xmlReader = XMLReaderFactoryUtils.createXMLReader(); + XMLReader xmlReader = offlinerXmlReader(); xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); for (int i = 0; i < resources.length; i++) { Assert.notNull(resources[i], "Resource is null"); @@ -77,6 +78,15 @@ public abstract class SchemaLoaderUtils { return schemaFactory.newSchema(schemaSources); } + private static XMLReader offlinerXmlReader() throws SAXException { + XMLReader xmlReader = SaxUtils.namespaceAwareXmlReader(); + xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); + xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + return xmlReader; + } + /** * Retrieves the URL from the given resource as System ID. Returns {@code null} if it * cannot be opened. diff --git a/spring-xml/src/main/java/org/springframework/xml/validation/XMLReaderFactoryUtils.java b/spring-xml/src/main/java/org/springframework/xml/validation/XMLReaderFactoryUtils.java index e2f441eb..05e7998b 100644 --- a/spring-xml/src/main/java/org/springframework/xml/validation/XMLReaderFactoryUtils.java +++ b/spring-xml/src/main/java/org/springframework/xml/validation/XMLReaderFactoryUtils.java @@ -16,19 +16,21 @@ package org.springframework.xml.validation; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; +import org.springframework.xml.sax.SaxUtils; + /** * General utilities to create an {@link XMLReader}. * * @author Greg Turnquist * @since 3.0.5 + * @deprecated since 4.0.12 in favor of {@link SaxUtils} */ +@Deprecated(since = "4.0.12", forRemoval = true) public abstract class XMLReaderFactoryUtils { /** @@ -36,7 +38,7 @@ public abstract class XMLReaderFactoryUtils { * @see SAXParser#getXMLReader() */ public static XMLReader createXMLReader() throws SAXException { - XMLReader xmlReader = namespaceAwareXmlReader(); + XMLReader xmlReader = SaxUtils.namespaceAwareXmlReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); @@ -44,16 +46,4 @@ public abstract class XMLReaderFactoryUtils { return xmlReader; } - private static XMLReader namespaceAwareXmlReader() throws SAXException { - try { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - return parserFactory.newSAXParser().getXMLReader(); - } - catch (ParserConfigurationException ex) { - throw new IllegalStateException(ex); - } - - } - } diff --git a/spring-xml/src/test/java/org/springframework/xml/dom/DomContentHandlerTest.java b/spring-xml/src/test/java/org/springframework/xml/dom/DomContentHandlerTest.java index d9c182ca..5be63154 100644 --- a/spring-xml/src/test/java/org/springframework/xml/dom/DomContentHandlerTest.java +++ b/spring-xml/src/test/java/org/springframework/xml/dom/DomContentHandlerTest.java @@ -20,7 +20,6 @@ import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.SAXParserFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -30,6 +29,7 @@ import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.springframework.xml.DocumentBuilderFactoryUtils; +import org.springframework.xml.sax.SaxUtils; import static org.xmlunit.assertj.XmlAssert.assertThat; @@ -63,9 +63,7 @@ public class DomContentHandlerTest { documentBuilderFactory.setNamespaceAware(true); this.documentBuilder = documentBuilderFactory.newDocumentBuilder(); this.result = this.documentBuilder.newDocument(); - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - this.xmlReader = parserFactory.newSAXParser().getXMLReader(); + this.xmlReader = SaxUtils.namespaceAwareXmlReader(); } @Test diff --git a/spring-xml/src/test/java/org/springframework/xml/transform/TraxUtilsTest.java b/spring-xml/src/test/java/org/springframework/xml/transform/TraxUtilsTest.java index 3c2d5bd2..1a778f89 100644 --- a/spring-xml/src/test/java/org/springframework/xml/transform/TraxUtilsTest.java +++ b/spring-xml/src/test/java/org/springframework/xml/transform/TraxUtilsTest.java @@ -28,7 +28,6 @@ import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; @@ -57,6 +56,7 @@ import org.xml.sax.helpers.DefaultHandler; import org.springframework.util.xml.StaxUtils; import org.springframework.xml.DocumentBuilderFactoryUtils; import org.springframework.xml.XMLInputFactoryUtils; +import org.springframework.xml.sax.SaxUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -119,9 +119,7 @@ public class TraxUtilsTest { @Test public void testDoWithSaxSource() throws Exception { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - XMLReader reader = parserFactory.newSAXParser().getXMLReader(); + XMLReader reader = SaxUtils.namespaceAwareXmlReader(); InputSource inputSource = new InputSource(); TraxUtils.SourceCallback mock = createMock(TraxUtils.SourceCallback.class);