pdvrieze / xmlutil

XML Serialization library for Kotlin
https://pdvrieze.github.io/xmlutil/
Apache License 2.0
363 stars 30 forks source link

DefaultXmlSerializationPolicy deprecated constructor #184

Closed chrisbrkt closed 6 months ago

chrisbrkt commented 9 months ago

I'm using a custom XML policy by inheriting from DefaultXmlSerializationPolicy to override the effective output kind and name. However, I can see with the latest version, 0.86.2, the constructor is now deprecated. The available constructor, using the builder, is available but the Builder itself has an internal constructor that we can't use. Any guidance on that? Is there a different way now to create a custom XML policy? Thanks!

pdvrieze commented 9 months ago

Sorry for that. The problem with the constructors is that it breaks when I add a property (or I need to add many compatibility constructors - that doesn't scale). For the builder that is no issue though, so I will make sure to have a public or protected constructor for it. In the meantime I will not remove the deprecated constructors anytime soon.

pdvrieze commented 9 months ago

Just to clarify, extending the default policy is a supported approach.

pdvrieze commented 9 months ago

I've just pushed a "fix" for this for now. I've added a public no-arg constructor to the Builder (you can even subclass it for your own configuration) and made the constructor that takes an existing policy instance as initialization public as well. Good to see that the policy is useful for people.

chrisbrkt commented 9 months ago

Thank you so much for the quick reply and fix; looking forward for the new release! Dealing with XML can be a nightmare and in our case, the policy was a life saver :)

pdvrieze commented 9 months ago

@chrisbrkt You should be able to test it out using a snapshot release (I understand that may not be good enough for production).

chrisbrkt commented 9 months ago

Yea I cannot really go to production or push changes in the product using snapshot releases but I'll give it a go for sure!

chrisbrkt commented 9 months ago

I just looked at it and I guess I'm still missing some guidance. So my current implementation is:

object XmlPolicy : DefaultXmlSerializationPolicy( pedantic = false, autoPolymorphic = false, encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.ANNOTATED, unknownChildHandler = XmlConfig.IGNORING_UNKNOWN_CHILD_HANDLER )

I'm trying to replace that inheritance with a non deprecated constructor. I can see I can use the builder but I cannot really use the constructor since it's internal and I cannot inherit from the builder to create my own since the fields are final. Any thoughts or am I missing something?

pdvrieze commented 9 months ago

@chrisbrkt The new approach should be that you have something like:

class MyXmlPolicy(builder : DefaultXmlSerializationPolicy) : DefaultXmlSerializationPolicy(builder) {
  constructor(): this(DefaultXmlSerializationPolicy.Builder().apply { pedantic = false; autoPolymorphic = false; /*etc*/ })
  override fun effectiveOutputKind(/*args*/): OutputKind { /*impl*/ }
}

The policy will need the builder as it may add parameters every now and then. The builder abstracts this in a way that allows for adding parameters without having to change the constructor. So if you want to have a subclass with different defaults you do it as above (setting them through the builder). The properties in the builder are final as it makes no sense to have them overridden, they are just temporary value holders.

chrisbrkt commented 9 months ago

Oh right.. Awesome, that works perfectly! Thank you

pdvrieze commented 6 months ago

Just released