Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CU-85zrnb6u1_PW---631--XML-Handling #75

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Prowide ISO 20022 - CHANGELOG

#### 9.3.6-SNAPSHOT
* (PW-631) Changed the XML marshaling/unmarshalling to honor the default system encoding, and added optional parameters to use a specific charset if needed

#### 9.3.5 - January 2023
* Added an optional way to pass a JaxbContext instance to the parse and write methods

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,18 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

import static java.nio.charset.StandardCharsets.*;
import static org.apache.commons.lang3.StringUtils.getBytes;
import static org.apache.commons.lang3.StringUtils.toEncodedString;


/**
* Base class for specific MX messages.<br>
Expand Down Expand Up @@ -303,10 +308,10 @@ public String message(MxWriteConfiguration conf) {

String root = usableConf.rootElement;
StringBuilder xml = new StringBuilder();

if (usableConf.includeXMLDeclaration) {
xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
}

params.prefix = usableConf.headerPrefix;
final String header = header(params);
if (header != null) {
Expand All @@ -319,6 +324,7 @@ public String message(MxWriteConfiguration conf) {
if (header != null) {
xml.append("</").append(root).append(">");
}

return xml.toString();
}

Expand Down Expand Up @@ -510,7 +516,7 @@ public void write(final File file) throws IOException {
@ProwideDeprecated(phase2 = TargetYear.SRU2023)
public void write(final OutputStream stream) throws IOException {
Objects.requireNonNull(stream, "the stream to write cannot be null");
stream.write(message().getBytes(StandardCharsets.UTF_8));
stream.write(message().getBytes(UTF_8));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static Optional<AppHdr> parse(final String xml, MxReadParams params) {

private static AppHdr parseHeaderFromSAXSource(final String xml, final String namespace, final MxReadParams params) {

SAXSource source = MxParseUtils.createFilteredSAXSource(xml, AppHdr.HEADER_LOCALNAME);
SAXSource source = MxParseUtils.createFilteredSAXSource(xml, AppHdr.HEADER_LOCALNAME, null);

if (StringUtils.equals(LegacyAppHdr.NAMESPACE, namespace)) {
// parse legacy AH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.sax.SAXSource;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
Expand All @@ -52,14 +53,18 @@ public class MxParseUtils {
* @return a safe source
* @since 9.2.1
*/
static SAXSource createFilteredSAXSource(final String xml, final String localName) {
static SAXSource createFilteredSAXSource(final String xml, final String localName, Charset charset) {
XMLReader documentReader = SafeXmlUtils.reader(true, null);

NamespaceAndElementFilter documentFilter = new NamespaceAndElementFilter(localName);
documentFilter.setParent(documentReader);

InputSource documentInputSource = new InputSource(new StringReader(xml));

if (charset != null) {
documentInputSource.setEncoding(charset.name());
} else {
documentInputSource.setEncoding(Charset.defaultCharset().name());
}
return new SAXSource(documentFilter, documentInputSource);
}

Expand Down Expand Up @@ -108,6 +113,12 @@ static Object parseSAXSource(final SAXSource source, final Class targetClass, fi
}
}

if(params.charset!=null){
source.getInputSource().setEncoding(params.charset.name());
} else {
source.getInputSource().setEncoding(Charset.defaultCharset().name());
}

JAXBElement element = unmarshaller.unmarshal(source, targetClass);
if (element != null) {
return element.getValue();
Expand Down Expand Up @@ -166,7 +177,7 @@ static Object parse(final Class targetClass, final String xml, final Class<?>[]
Objects.requireNonNull(params, "unmarshalling params cannot be null");

try {
SAXSource saxSource = createFilteredSAXSource(xml, localName);
SAXSource saxSource = createFilteredSAXSource(xml, localName, params.charset);
return parseSAXSource(saxSource, targetClass, classes, params);

} catch (final Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.prowidesoftware.swift.model.mx.adapters.TypeAdaptersConfiguration;

import javax.xml.bind.JAXBContext;
import java.nio.charset.Charset;

/**
* Options to customize the behaviour of the MX parser (XML into model) in the {@link AbstractMX} and its specific
Expand All @@ -39,6 +40,12 @@ public class MxReadConfiguration {
*/
public JAXBContext context;

/**
* Optional parameter to use a specific charset when unmarshalling XML content, if not set, the system default is used
* @since 9.3.6
*/
public Charset charset;

/**
* Creates a configuration with the default adapters
*/
Expand All @@ -52,6 +59,7 @@ public MxReadConfiguration() {
public MxReadConfiguration(MxWriteConfiguration writeConf) {
this.adapters = writeConf.adapters;
this.context = writeConf.context;
this.charset = writeConf.charset;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public static AbstractMX parse(final Class<? extends AbstractMX> targetClass, fi

try {

SAXSource documentSource = MxParseUtils.createFilteredSAXSource(xml, AbstractMX.DOCUMENT_LOCALNAME);
SAXSource documentSource = MxParseUtils.createFilteredSAXSource(xml, AbstractMX.DOCUMENT_LOCALNAME, params.charset);
final AbstractMX parsedDocument = (AbstractMX) MxParseUtils.parseSAXSource(documentSource, targetClass, classes, params);

Optional<AbstractMX> mx = Optional.ofNullable(parsedDocument);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import javax.xml.bind.JAXBContext;

import java.nio.charset.Charset;

/**
* Simple DTO to encapsulate parameters in the different XML-to-model parser implementation methods in the API
*
Expand All @@ -45,6 +47,12 @@ public class MxReadParams {
*/
public JAXBContext context;

/**
* Optional parameter to use a specific charset when unmarshalling XML content, if not set, the system default is used
* @since 9.3.6
*/
public Charset charset;

public MxReadParams() {
this.adapters = new TypeAdaptersConfiguration();
}
Expand All @@ -54,6 +62,7 @@ public MxReadParams(MxReadConfiguration conf) {
if (conf != null) {
this.adapters = conf.adapters;
this.context = conf.context;
this.charset = conf.charset;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.prowidesoftware.swift.model.mx.adapters.TypeAdaptersConfiguration;

import javax.xml.bind.JAXBContext;
import java.nio.charset.Charset;

/**
* Options to customize the behaviour of the MX writer (model into XML serialization) in the {@link AbstractMX}
Expand Down Expand Up @@ -73,6 +74,12 @@ public class MxWriteConfiguration {
*/
public JAXBContext context;

/**
* Optional parameter to use a specific charset when unmarshalling XML content, if not set, the system default is used
* @since 9.3.6
*/
public Charset charset;

/**
* Creates a configuration with the default options and adapters
*/
Expand All @@ -99,6 +106,7 @@ public MxWriteConfiguration(MxReadConfiguration readConf) {
this();
this.adapters = readConf.adapters;
this.context = readConf.context;
this.charset = readConf.charset;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.prowidesoftware.swift.model.mx.adapters.TypeAdaptersConfiguration;

import javax.xml.bind.JAXBContext;
import java.nio.charset.Charset;

/**
* Simple DTO to encapsulate parameters in the different model-to-XML serialization implementation methods in the API
Expand Down Expand Up @@ -52,6 +53,12 @@ public class MxWriteParams {
*/
public TypeAdaptersConfiguration adapters;

/**
* Optional parameter to use a specific charset when marshalling into XML, if not set, the system default is used
* @since 9.3.6
*/
public Charset charset;

public MxWriteParams() {
this(new MxWriteConfiguration());
}
Expand All @@ -64,6 +71,7 @@ public MxWriteParams() {
this.escapeHandler = notNullConf.escapeHandler;
this.adapters = notNullConf.adapters;
this.context = notNullConf.context;
this.charset = notNullConf.charset;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ static Marshaller createMarshaller(final JAXBContext context, final MxWriteParam
marshaller.setAdapter(adapter);
}
}

if (params.charset != null) {
marshaller.setProperty(Marshaller.JAXB_ENCODING, params.charset.name());
}
return marshaller;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import com.prowidesoftware.swift.model.mx.dic.PaymentInstructionInformation3;
import org.junit.jupiter.api.Test;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand Down Expand Up @@ -62,6 +65,7 @@ public void testWriteDefaultMinimumEscapeHandler() {
conf.escapeHandler = new MinimumEscapeHandler();
String xml = mx.message(conf);

System.out.println(Charset.defaultCharset().name());
assertTrue(xml.contains("текст текст öñ"));

MxPain00100103 mx2 = MxPain00100103.parse(xml);
Expand Down
Loading