mbknor / mbknor-jackson-jsonSchema

Generate JSON Schema with Polymorphism using Jackson annotations
MIT License
234 stars 79 forks source link

Support for restrictions in local definitions instead of in-lined #166

Open theseeker58 opened 2 years ago

theseeker58 commented 2 years ago

I have an xsd schema that features many complexTypes like this

    <xs:complexType name="GroupHeader78">
        <xs:sequence>
            <xs:element name="MsgId" type="Max35Text"/>
            <xs:element name="CreDtTm" type="ISODateTime"/>
            <xs:element name="NbOfTxs" type="Max15NumericText"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CtrlSum" type="DecimalNumber"/>
            <xs:element name="InitgPty" type="PartyIdentification135"/>
        </xs:sequence>
    </xs:complexType>

where Max35Text is just a referenced simpleType based on xs:string with some restrictions

    <xs:simpleType name="Max35Text">
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="35"/>
        </xs:restriction>
    </xs:simpleType>

xjc, wrapped in jaxb2-maven-plugin, automatically generates a GroupHeader78 Class where, for example, the mentioned property msgId is a String, annotated with Bean Validation @Size(min = 1, max = 35) thanks to -XJsr303Annotations switch from krasa-jaxb-tools

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GroupHeader78", propOrder = {
    "msgId",
    "creDtTm",
    "nbOfTxs",
    "ctrlSum",
    "initgPty"
})
public class GroupHeader78 implements Serializable, Equals2
{

    private final static long serialVersionUID = 1L;
    @XmlElement(name = "MsgId", required = true)
    @NotNull
    @Size(min = 1, max = 35)
    protected String msgId;
    @XmlElement(name = "CreDtTm", required = true, type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    @NotNull
    protected Instant creDtTm;
    @XmlElement(name = "NbOfTxs", required = true)
    @NotNull
    @Pattern(regexp = "[0-9]{1,15}")
    protected String nbOfTxs;
    @XmlElement(name = "CtrlSum")
    @Digits(integer = 18, fraction = 17)
    protected BigDecimal ctrlSum;
    @XmlElement(name = "InitgPty", required = true)
    @NotNull
    @Valid
    protected PartyIdentification135 initgPty;

The generated JSON schema excerpt is the following

    "GroupHeader78" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "msg_id" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 35
        }

Instead of the in-lined string restrictions I would like to get a schema like this

    "GroupHeader78" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "msg_id" : {
          "type" : "string",
          "$ref": "#/definitions/Max35Text"
        }

where Max35Text is defined aside (in the same file), just like the simpleType in the original xsd schema

     "Max35Text": {
         "type": "string",
         "minLenght": 1,
         "maxLenght": 35
     },

I couldn't figure out if it's possible to configure the plugin to get this done. Any help/suggestion is appreciated

theseeker58 commented 2 years ago

Found a solution! setting true mapSimpleTypeDef (default is false) in jaxb:globalBindings did the trick <jaxb:globalBindings mapSimpleTypeDef="true"> Map35Text and other simpleType declarations like that are generated as Class by xjc with a value string property with restrictions. Therefore jsonSchema generates

    "Max35Text" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "value" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 35
        }
      }
    },

I'd have preferred this simpler form without the value property

      "Max35Text": {
          "type": "string",
          "minLenght": 1,
          "maxLenght": 35
      },

but I must admit that it depends on xjc and not on jsonSchema that does its job accordingly. I'm getting closer... I don't know if using Lombok those classes turn to something like c language typedef struct and so getting more practical in this context