Skip to content

Commit

Permalink
CU-85zrnb6u1_PW---631--XML-Handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ptorres-prowide committed Feb 23, 2023
1 parent 32a4328 commit eb43849
Show file tree
Hide file tree
Showing 11 changed files with 359 additions and 9 deletions.
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,8 +308,12 @@ public String message(MxWriteConfiguration conf) {

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

Charset charsetToUse =conf.charset != null? conf.charset:Charset.defaultCharset();
if (usableConf.includeXMLDeclaration) {
xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
xml.append("<?xml version=\"1.0\" encoding=\"");
xml.append(charsetToUse.name());
xml.append("\" ?>\n");
}

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

return toEncodedString(getBytes(xml.toString(), UTF_8), charsetToUse);
}

/**
Expand Down Expand Up @@ -510,7 +520,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
Loading

0 comments on commit eb43849

Please sign in to comment.