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

xs:choice and -XInheritance #78

Open
at055612 opened this issue Jun 4, 2024 · 0 comments
Open

xs:choice and -XInheritance #78

at055612 opened this issue Jun 4, 2024 · 0 comments

Comments

@at055612
Copy link
Contributor

at055612 commented Jun 4, 2024

master...at055612:jaxb2-rich-contract-plugin:inheritance-and-choice

I am using jaxb-rich-contract-plugin in conjunction with the -XInheritance arg of the jaxb-plugins plugin. This allows for having a common interface class for all items in a choice when this cannot be achieved with extension in the xsd (e.g. if some/all of them already extend something else).

This used to work after this PR https://github.com/mklemm/jaxb-rich-contract-plugin/pull/53/files#diff-056f4b958f99f841eae8c7cbe0de52fd4e08bada6ab322fe43b3b639976bf600 but is now broken after some of that was backed out.

On my branch, build the test module.


Look at com.kscs.jaxb2.contract.test.JavadocAnnotations.ChoiceOfElementsTwo
This is working OK due to the presence of the common Transport super type in the xsd.

binding:

		<jxb:bindings node="//xs:element[@name='choice-of-elements-two']/xs:complexType/xs:choice">
			<jxb:property name="transport">
				<jxb:baseType name="Transport" />
			</jxb:property>
		</jxb:bindings>

Generated code:

    public static class ChoiceOfElementsTwo implements Cloneable {

        protected Transport transport;
...
        public static class Builder<_B >implements Buildable {

            protected final _B _parentBuilder;
            protected final JavadocAnnotations.ChoiceOfElementsTwo _storedValue;
            // transport is a Transport.Builder
            private com.kscs.jaxb2.contract.test.Transport.Builder<JavadocAnnotations.ChoiceOfElementsTwo.Builder<_B>> transport;
...
            public JavadocAnnotations.ChoiceOfElementsTwo.Builder<_B> withTransport(final Transport transport) {
                this.transport = ((transport == null)?null:new com.kscs.jaxb2.contract.test.Transport.Builder<>(this, transport, false));
                return this;
            }
            public JavadocAnnotations.ChoiceOfElementsTwo.Builder<_B> withBike(final Bike bike) {
                this.transport = ((bike == null)?null:new Bike.Builder<>(this, bike, false));
                return this;
            }

Look at com.kscs.jaxb2.contract.test.ReservedWordsSingleChoice
Using Object as the common type. This works but withObject(Object object) is not clear or type safe.

binding:

		<jxb:bindings node="//xs:element[@name='reserved-words-single-choice']/xs:complexType/xs:choice">
			<jxb:property name="object">
				<jxb:baseType name="java.lang.Object" />
			</jxb:property>
		</jxb:bindings>

Generated code:

public class ReservedWordsSingleChoice implements Cloneable {

    protected Object object;
...
    public static class Builder<_B >implements Buildable {

        protected final _B _parentBuilder;
        protected final ReservedWordsSingleChoice _storedValue;
        // object is NOT a builder, but as Object is the super type for everything it compiles
        private Object object;

        public ReservedWordsSingleChoice.Builder<_B> withObject(final Object object) {
            this.object = object;
            return this;
        }
        public ReservedWordsSingleChoice.Builder<_B> withImport(final Import _import) {
            this.object = ((_import == null)?null:new Import.Builder<>(this, _import, false));
            return this;
        }

Look at com.kscs.jaxb2.contract.test.InheritanceSingleChoice
This one won't compile.

bind the choice items to the Reserved interface using -XInheritance plugin and set it as the base type for the choice:

		<jxb:bindings
				multiple="true"
				node="xs:complexType[@name='class' or @name='import']">
			<inheritance:implements>Reserved</inheritance:implements>
		</jxb:bindings>

		<jxb:bindings node="//xs:element[@name='inheritance-single-choice']/xs:complexType/xs:choice">
			<jxb:property name="reserved">
				<jxb:baseType name="Reserved" />
			</jxb:property>
		</jxb:bindings>

Generated code:

public class InheritanceSingleChoice implements Cloneable {

    protected Reserved reserved;
...
    public static class Builder<_B >implements Buildable {

        protected final _B _parentBuilder;
        protected final InheritanceSingleChoice _storedValue;
        // NOT a builder class
        private Reserved reserved;

        public InheritanceSingleChoice.Builder<_B> withReserved(final Reserved reserved) {
            this.reserved = reserved;
            return this;
        }
        public InheritanceSingleChoice.Builder<_B> withImport(final Import _import) {
            // Does not compile as reserve is not a builder/buildable
            this.reserved = ((_import == null)?null:new Import.Builder<>(this, _import, false));
            return this;
        }

I appreciate that -XInheritance is not yours but it is very useful for adding marker interfaces to choice items to make the builder methods much clearer when there is no common supertype in the xsd.

I think my original PR changed it so the builder had a field like this + some other changes to the constructors.

        private Buildable reserved;

Given that my original PR broke some of your use cases it is difficult for me to try to fix this without breaking them again. I would be grateful if you could have a look to see if this can be fixed in a way that satisfies your cases and mine.

Tested on v4.2.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant