diff --git a/CHANGELOG.md b/CHANGELOG.md index 6471f86..ab49d84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 3.5.0 +### Changed +- #214 Trim attribute values + ## 3.4.0 ### Changed - fix: #153 Invalid status code: 524 diff --git a/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/AttributeTrimmingFilter.java b/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/AttributeTrimmingFilter.java new file mode 100644 index 0000000..21367bf --- /dev/null +++ b/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/AttributeTrimmingFilter.java @@ -0,0 +1,29 @@ +package org.lfenergy.shapeshifter.core.common.xml; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * A custom XML filter that trims whitespace from the values of XML element attributes. + *

+ * This filter extends the {@link XMLFilterImpl} class, allowing it to intercept and modify + * the XML parsing process. Specifically, it overrides the {@code startElement} method to + * ensure that all attribute values are stripped of leading and trailing whitespace. + *

+ */ +class AttributeTrimmingFilter extends XMLFilterImpl { + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + var trimmedAttributes = new AttributesImpl(attributes); + + for (var i = 0; i < trimmedAttributes.getLength(); i++) { + var value = trimmedAttributes.getValue(i); + trimmedAttributes.setValue(i, value != null ? value.trim() : null); + } + + super.startElement(uri, localName, qName, trimmedAttributes); + } +} diff --git a/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializer.java b/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializer.java index c3349ca..5a53f49 100644 --- a/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializer.java +++ b/core/src/main/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializer.java @@ -5,14 +5,16 @@ package org.lfenergy.shapeshifter.core.common.xml; import jakarta.xml.bind.JAXBException; -import java.io.StringReader; -import java.io.StringWriter; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.sax.SAXSource; import org.lfenergy.shapeshifter.core.common.exception.UftpConnectorException; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.sax.SAXSource; +import java.io.StringReader; +import java.io.StringWriter; public class XmlSerializer { @@ -32,8 +34,8 @@ public String toXml(final T object) { public T fromXml(String xmlString, Class typeToUnmarshal) { try { - var xmlSource = new SAXSource(SAX_PARSER_FACTORY.newSAXParser().getXMLReader(), - new InputSource(new StringReader(xmlString))); + var xmlSource = new SAXSource(xmlReader(), + new InputSource(new StringReader(xmlString))); var unmarshaller = jaxbTools.createUnmarshaller(typeToUnmarshal); return typeToUnmarshal.cast(unmarshaller.unmarshal(xmlSource)); } catch (JAXBException | ParserConfigurationException | SAXException cause) { @@ -41,6 +43,15 @@ public T fromXml(String xmlString, Class typeToUnmarshal) { } } + private static XMLReader xmlReader() throws ParserConfigurationException, SAXException { + var parser = SAX_PARSER_FACTORY.newSAXParser(); + + var attributeTrimmingFilter = new AttributeTrimmingFilter(); + attributeTrimmingFilter.setParent(parser.getXMLReader()); + + return attributeTrimmingFilter; + } + /** * Creates a SAX Parser factory with some measures to prevent XML External Entity vulnerabilities Taken from: ... diff --git a/core/src/test/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializerTest.java b/core/src/test/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializerTest.java index 5767ed1..26d0789 100644 --- a/core/src/test/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializerTest.java +++ b/core/src/test/java/org/lfenergy/shapeshifter/core/common/xml/XmlSerializerTest.java @@ -48,6 +48,13 @@ void fromXml_PayloadMessage() { assertThat(flexRequest).isNotNull(); } + @Test + void fromXml_attributesTrailingSpaces() { + var flexRequest = xmlSerializer.fromXml("", FlexRequest.class); + + assertThat(flexRequest.getContractID()).isEqualTo("abc"); + } + @Test void fromXml_PayloadMessage_with_prolog() { var flexRequest = xmlSerializer.fromXml(XML_PROLOG + FLEX_REQUEST_XML, FlexRequest.class);