prowide / prowide-iso20022

Comprehensive business model and parser for all ISO 20022 messages
https://www.prowidesoftware.com
Apache License 2.0
142 stars 66 forks source link

Remove XMLGregorianCalendar in favor of java.time.* #36

Closed pauljohe-dnb closed 2 years ago

pauljohe-dnb commented 2 years ago

XMLGregorianCalendar is a pain to use and nowadays, it is much more common to bind JAXB classes to some type of java.time.* variant.

For example, including this in the JAXB code generation:

<jxb:bindings version="2.0"
        xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        jxb:extensionBindingPrefixes="xjc"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <jxb:globalBindings>
      <xjc:javaType name="java.time.OffsetDateTime" xmlType="xs:dateTime"
          adapter="io.github.threetenjaxb.core.OffsetDateTimeXmlAdapter"/>
      <xjc:javaType name="java.time.LocalDate" xmlType="xs:date"
          adapter="io.github.threetenjaxb.core.LocalDateXmlAdapter"/>
    </jxb:globalBindings>
</jxb:bindings>

Is there any reason the JAXB generation is not included in the source code so that others could manipulate the generated code as well (for example, to add in a builder pattern, etc.)?

zubri commented 2 years ago

I've just commented the reason in #34

The migration of XMLGregorianCalendar to java.time is a good idea. Will find some time to explore it and include it in the code generation with backward compatibility (deprecation of existing code, if possible).

pauljohe-dnb commented 2 years ago

Cool! 👍

The io.github.threeten-jaxb seems to be an OK library for java.time adapters, although some customized adapters might be more flexible for this library. Sometimes users may wish to include timezone offset, and sometimes they may wish not to include it in the marshalled XML. That has been my experience with different projects in any case (for example, for instant ISO-20022 messages, one project required all xsd:datetime XML representations as Zulu time). With your own custom adapter, you could perhaps provide an API for setting the output format regardless of which java.time class is chosen for your java code.

Also, I guess backwards compatibility for setters would be possible with method overloading, but not for the getters.

zubri commented 2 years ago

In release 9.2.6 I've added a way to customize the date time, time and date elements with custom adapters.

The model is annotated with a default implementation for the IsoDateTime, IsoTime and IsoDate types. Where the default adapter classes are actually a wrapper. Then a default implementation is provided for each type, but anyone can tweak the default or inject its own class.

The way to configure this is by some new parameters in the marshaling and unmarshalling API. For example:

MxWriteConfiguration conf = new MxWriteConfiguration(); conf.adapters.dateTimeAdapter = new IsoDateTimeAdapter(new ZonedDateTimeAdapter(new SimpleDateFormat("yy-MM-dd HH:mm")));

conf.adapters.dateAdapter = new IsoDateAdapter(new SimpleDateAdapter(new SimpleDateFormat("yy-MM-dd")));

final String xml = mx.message(conf);

Default adapters use zoned local time (offset always present) for date time and time. Since these days that's what most infrastructures and CUGs require (for example CBPR+).

I think the wrapper approach is is quite flexible, and should cover most of the use cases for now.

Changing the XMLGregorianCalendar in the model for new java time classes would be a compile breaking change, so that will need to wait for a major release, probably along a SRU yearly update.

Regards