001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.bean.openapi3; 018 019import static org.apache.juneau.commons.utils.CollectionUtils.*; 020import static org.apache.juneau.bean.openapi3.OpenApiCopyUtils.*; 021import static org.apache.juneau.commons.utils.Shorts.*; 022import static org.apache.juneau.marshall.internal.ConverterUtils.*; 023 024import java.util.*; 025 026import org.apache.juneau.commons.bean.*; 027import org.apache.juneau.commons.collections.*; 028 029/** 030 * Allows the definition of input and output data types. 031 * 032 * <p> 033 * The Schema Object allows the definition of input and output data types, including objects, primitives, and arrays. 034 * This object is an extended subset of the JSON Schema Specification Draft 4, with additional extensions provided 035 * by the OpenAPI Specification to allow for more complete documentation. 036 * 037 * <h5 class='section'>OpenAPI Specification:</h5> 038 * <p> 039 * The Schema Object supports all properties from JSON Schema Draft 4, including but not limited to: 040 * <ul class='spaced-list'> 041 * <li><c>type</c> (string) - The data type. Values: <js>"string"</js>, <js>"number"</js>, <js>"integer"</js>, <js>"boolean"</js>, <js>"array"</js>, <js>"object"</js> 042 * <li><c>format</c> (string) - The format modifier (e.g., <js>"int32"</js>, <js>"int64"</js>, <js>"float"</js>, <js>"double"</js>, <js>"date"</js>, <js>"date-time"</js>) 043 * <li><c>title</c> (string) - A short title for the schema 044 * <li><c>description</c> (string) - A description of the schema (CommonMark syntax may be used) 045 * <li><c>default</c> (any) - The default value 046 * <li><c>multipleOf</c> (number) - Must be a multiple of this value 047 * <li><c>maximum</c> (number) - Maximum value (inclusive by default) 048 * <li><c>exclusiveMaximum</c> (boolean) - If true, maximum is exclusive 049 * <li><c>minimum</c> (number) - Minimum value (inclusive by default) 050 * <li><c>exclusiveMinimum</c> (boolean) - If true, minimum is exclusive 051 * <li><c>maxLength</c> (integer) - Maximum string length 052 * <li><c>minLength</c> (integer) - Minimum string length 053 * <li><c>pattern</c> (string) - Regular expression pattern the string must match 054 * <li><c>maxItems</c> (integer) - Maximum array length 055 * <li><c>minItems</c> (integer) - Minimum array length 056 * <li><c>uniqueItems</c> (boolean) - If true, array items must be unique 057 * <li><c>maxProperties</c> (integer) - Maximum number of object properties 058 * <li><c>minProperties</c> (integer) - Minimum number of object properties 059 * <li><c>required</c> (array of string) - Required property names 060 * <li><c>enum</c> (array) - Possible values for this schema 061 * <li><c>properties</c> (map of {@link SchemaInfo}) - Object property definitions 062 * <li><c>items</c> ({@link Items}) - Schema for array items 063 * <li><c>allOf</c> (array of {@link SchemaInfo}) - Must validate against all schemas 064 * <li><c>oneOf</c> (array of {@link SchemaInfo}) - Must validate against exactly one schema 065 * <li><c>anyOf</c> (array of {@link SchemaInfo}) - Must validate against any schema 066 * <li><c>not</c> ({@link SchemaInfo}) - Must not validate against this schema 067 * <li><c>nullable</c> (boolean) - Allows the value to be null (OpenAPI 3.0 extension) 068 * <li><c>discriminator</c> ({@link Discriminator}) - Discriminator for polymorphism (OpenAPI extension) 069 * <li><c>readOnly</c> (boolean) - Relevant only for Schema properties (OpenAPI extension) 070 * <li><c>writeOnly</c> (boolean) - Relevant only for Schema properties (OpenAPI extension) 071 * <li><c>xml</c> ({@link Xml}) - XML representation details (OpenAPI extension) 072 * <li><c>externalDocs</c> ({@link ExternalDocumentation}) - Additional external documentation (OpenAPI extension) 073 * <li><c>example</c> (any) - Example value (OpenAPI extension) 074 * <li><c>deprecated</c> (boolean) - Specifies that the schema is deprecated (OpenAPI extension) 075 * </ul> 076 * 077 * <h5 class='section'>Example:</h5> 078 * <p class='bjava'> 079 * <jc>// Create a schema for a Pet object</jc> 080 * SchemaInfo <jv>schema</jv> = <jk>new</jk> SchemaInfo() 081 * .setType(<js>"object"</js>) 082 * .setRequired(<js>"id"</js>, <js>"name"</js>) 083 * .setProperties( 084 * JsonMap.<jsm>of</jsm>( 085 * <js>"id"</js>, <jk>new</jk> SchemaInfo().setType(<js>"integer"</js>).setFormat(<js>"int64"</js>), 086 * <js>"name"</js>, <jk>new</jk> SchemaInfo().setType(<js>"string"</js>), 087 * <js>"tag"</js>, <jk>new</jk> SchemaInfo().setType(<js>"string"</js>) 088 * ) 089 * ); 090 * </p> 091 * 092 * <h5 class='section'>See Also:</h5><ul> 093 * <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#schema-object">OpenAPI Specification > Schema Object</a> 094 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/data-models/">OpenAPI Data Models</a> 095 * <li class='link'><a class="doclink" href="https://json-schema.org/">JSON Schema Specification</a> 096 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a> 097 * </ul> 098 */ 099@SuppressWarnings({ 100 "java:S116", // Field names intentionally match JSON property names 101 "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants 102 "java:S1479" // Switch statement has 37 cases, exceeding recommended limit of 30 - necessary for bean property mapping 103}) 104public class SchemaInfo extends OpenApiElement { 105 106 private String format; 107 private String title; 108 private String description; 109 private String pattern; 110 private String ref; 111 private String type; 112 private Number multipleOf; 113 private Number maximum; 114 private Number minimum; 115 private Integer maxLength; 116 private Integer minLength; 117 private Integer maxItems; 118 private Integer minItems; 119 private Integer maxProperties; 120 private Integer minProperties; 121 private Boolean exclusiveMaximum; 122 private Boolean exclusiveMinimum; 123 private Boolean uniqueItems; 124 private Boolean nullable; 125 private Boolean writeOnly; 126 private Boolean readOnly; 127 private Boolean deprecated; 128 private Object default_; 129 private Object example; 130 private Items items; 131 private Xml xml; 132 private ExternalDocumentation externalDocs; 133 private final List<Object> allOf = list(); 134 private final List<Object> oneOf = list(); 135 private final List<Object> anyOf = list(); 136 private final List<Object> enum_ = list(); 137 private final List<String> required = list(); 138 private Discriminator discriminator; 139 private Map<String,SchemaInfo> properties; 140 private SchemaInfo additionalProperties; 141 private SchemaInfo not; 142 143 /** 144 * Default constructor. 145 */ 146 public SchemaInfo() {} 147 148 /** 149 * Copy constructor. 150 * 151 * @param copyFrom The object to copy. 152 */ 153 public SchemaInfo(SchemaInfo copyFrom) { 154 super(copyFrom); 155 156 this.format = copyFrom.format; 157 this.title = copyFrom.title; 158 this.description = copyFrom.description; 159 this.ref = copyFrom.ref; 160 this.nullable = copyFrom.nullable; 161 this.writeOnly = copyFrom.writeOnly; 162 this.deprecated = copyFrom.deprecated; 163 this.pattern = copyFrom.pattern; 164 this.type = copyFrom.type; 165 this.discriminator = copyOf(copyFrom.discriminator); 166 this.multipleOf = copyFrom.multipleOf; 167 this.maximum = copyFrom.maximum; 168 this.minimum = copyFrom.minimum; 169 this.maxLength = copyFrom.maxLength; 170 this.minLength = copyFrom.minLength; 171 this.maxItems = copyFrom.maxItems; 172 this.minItems = copyFrom.minItems; 173 this.maxProperties = copyFrom.maxProperties; 174 this.minProperties = copyFrom.minProperties; 175 this.exclusiveMaximum = copyFrom.exclusiveMaximum; 176 this.exclusiveMinimum = copyFrom.exclusiveMinimum; 177 this.uniqueItems = copyFrom.uniqueItems; 178 this.readOnly = copyFrom.readOnly; 179 this.default_ = copyFrom.default_; 180 this.example = copyFrom.example; 181 this.items = copyOf(copyFrom.items); 182 this.xml = copyOf(copyFrom.xml); 183 this.externalDocs = copyOf(copyFrom.externalDocs); 184 enum_.addAll(copyFrom.enum_); 185 allOf.addAll(copyFrom.allOf); 186 required.addAll(copyFrom.required); 187 anyOf.addAll(copyFrom.anyOf); 188 oneOf.addAll(copyFrom.oneOf); 189 this.properties = copyOf(copyFrom.properties, SchemaInfo::copy); 190 this.additionalProperties = copyOf(copyFrom.additionalProperties); 191 this.not = copyOf(copyFrom.not); 192 } 193 194 /** 195 * Adds one or more values to the <property>allOf</property> property. 196 * 197 * @param values 198 * The values to add to this property. 199 * <br>Valid types: 200 * <ul> 201 * <li><code>Object</code> 202 * <li><code>Collection<Object></code> 203 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 204 * <h5 class='figure'>Example:</h5> 205 * <p class='bcode'> 206 * allOf(<js>"['foo','bar']"</js>); 207 * </p> 208 * <li><code>String</code> - Individual values 209 * <h5 class='figure'>Example:</h5> 210 * <p class='bcode'> 211 * allOf(<js>"foo"</js>, <js>"bar"</js>); 212 * </p> 213 * </ul> 214 * <br>Ignored if <jk>null</jk>. 215 * @return This object 216 */ 217 public SchemaInfo addAllOf(Object...values) { 218 addAllNn(allOf, values); 219 return this; 220 } 221 222 /** 223 * Adds one or more values to the <property>anyOf</property> property. 224 * 225 * @param values 226 * The values to add to this property. 227 * <br>Valid types: 228 * <ul> 229 * <li><code>Object</code> 230 * <li><code>Collection<Object></code> 231 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 232 * <h5 class='figure'>Example:</h5> 233 * <p class='bcode'> 234 * anyOf(<js>"['foo','bar']"</js>); 235 * </p> 236 * <li><code>String</code> - Individual values 237 * <h5 class='figure'>Example:</h5> 238 * <p class='bcode'> 239 * anyOf(<js>"foo"</js>, <js>"bar"</js>); 240 * </p> 241 * </ul> 242 * <br>Ignored if <jk>null</jk>. 243 * @return This object 244 */ 245 public SchemaInfo addAnyOf(Object...values) { 246 addAllNn(anyOf, values); 247 return this; 248 } 249 250 /** 251 * Adds one or more values to the <property>enum</property> property. 252 * 253 * @param values 254 * The values to add to this property. 255 * <br>Valid types: 256 * <ul> 257 * <li><code>Object</code> 258 * <li><code>Collection<Object></code> 259 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 260 * <h5 class='figure'>Example:</h5> 261 * <p class='bcode'> 262 * enum_(<js>"['foo','bar']"</js>); 263 * </p> 264 * <li><code>String</code> - Individual values 265 * <h5 class='figure'>Example:</h5> 266 * <p class='bcode'> 267 * enum_(<js>"foo"</js>, <js>"bar"</js>); 268 * </p> 269 * </ul> 270 * <br>Ignored if <jk>null</jk>. 271 * @return This object 272 */ 273 public SchemaInfo addEnum(Object...values) { 274 addAllNn(enum_, values); 275 return this; 276 } 277 278 /** 279 * Adds one or more values to the <property>oneOf</property> property. 280 * 281 * @param values 282 * The values to add to this property. 283 * <br>Valid types: 284 * <ul> 285 * <li><code>Object</code> 286 * <li><code>Collection<Object></code> 287 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 288 * <h5 class='figure'>Example:</h5> 289 * <p class='bcode'> 290 * oneOf(<js>"['foo','bar']"</js>); 291 * </p> 292 * <li><code>String</code> - Individual values 293 * <h5 class='figure'>Example:</h5> 294 * <p class='bcode'> 295 * oneOf(<js>"foo"</js>, <js>"bar"</js>); 296 * </p> 297 * </ul> 298 * <br>Ignored if <jk>null</jk>. 299 * @return This object 300 */ 301 public SchemaInfo addOneOf(Object...values) { 302 addAllNn(oneOf, values); 303 return this; 304 } 305 306 /** 307 * Bean property appender: <property>properties</property>. 308 * 309 * @param key The property key. Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown. 310 * @param value The property value. Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown. 311 * @return This object. 312 */ 313 public SchemaInfo addProperty(String key, SchemaInfo value) { 314 reqnn("key", key); 315 reqnn("value", value); 316 if (properties == null) 317 properties = map(); 318 properties.put(key, value); 319 return this; 320 } 321 322 /** 323 * Same as {@link #addRequired(String...)}. 324 * 325 * @param values 326 * The new value for this property. 327 * <br>Valid types: 328 * <ul> 329 * <li><code>Collection<String></code> 330 * <li><code>String</code> - JSON array representation of <code>Collection<String></code> 331 * <h5 class='figure'>Example:</h5> 332 * <p class='bcode'> 333 * schemes(<js>"['scheme1','scheme2']"</js>); 334 * </p> 335 * <li><code>String</code> - Individual values 336 * <h5 class='figure'>Example:</h5> 337 * <p class='bcode'> 338 * schemes(<js>"scheme1</js>, <js>"scheme2"</js>); 339 * </p> 340 * </ul> 341 * @return This object 342 */ 343 public SchemaInfo addRequired(String...values) { 344 addAllNn(required, values); 345 return this; 346 } 347 348 /** 349 * Make a deep copy of this object. 350 * 351 * @return A deep copy of this object. 352 */ 353 public SchemaInfo copy() { 354 return new SchemaInfo(this); 355 } 356 357 @Override /* Overridden from SwaggerElement */ 358 public <T> T get(String property, Class<T> type) { 359 reqnn("property", property); 360 return switch (property) { 361 case "format" -> toType(getFormat(), type); 362 case "title" -> toType(getTitle(), type); 363 case "description" -> toType(getDescription(), type); 364 case "default" -> toType(getDefault(), type); 365 case "multipleOf" -> toType(getMultipleOf(), type); 366 case "maximum" -> toType(getMaximum(), type); 367 case "exclusiveMaximum" -> toType(getExclusiveMaximum(), type); 368 case "minimum" -> toType(getMinimum(), type); 369 case "exclusiveMinimum" -> toType(getExclusiveMinimum(), type); 370 case "maxLength" -> toType(getMaxLength(), type); 371 case "minLength" -> toType(getMinLength(), type); 372 case "pattern" -> toType(getPattern(), type); 373 case "maxItems" -> toType(getMaxItems(), type); 374 case "minItems" -> toType(getMinItems(), type); 375 case "uniqueItems" -> toType(getUniqueItems(), type); 376 case "maxProperties" -> toType(getMaxProperties(), type); 377 case "minProperties" -> toType(getMinProperties(), type); 378 case "required" -> toType(getRequired(), type); 379 case "enum" -> toType(getEnum(), type); 380 case "type" -> toType(getType(), type); 381 case "items" -> toType(getItems(), type); 382 case "allOf" -> toType(getAllOf(), type); 383 case "oneOf" -> toType(getOneOf(), type); 384 case "anyOf" -> toType(getAnyOf(), type); 385 case "properties" -> toType(getProperties(), type); 386 case "additionalProperties" -> toType(getAdditionalProperties(), type); 387 case "not" -> toType(getNot(), type); 388 case "nullable" -> toType(getNullable(), type); 389 case "deprecated" -> toType(getDeprecated(), type); 390 case "discriminator" -> toType(getDiscriminator(), type); 391 case "readOnly" -> toType(getReadOnly(), type); 392 case "writeOnly" -> toType(getWriteOnly(), type); 393 case "xml" -> toType(getXml(), type); 394 case "externalDocs" -> toType(getExternalDocs(), type); 395 case "example" -> toType(getExample(), type); 396 case "$ref" -> toType(getRef(), type); 397 default -> super.get(property, type); 398 }; 399 } 400 401 /** 402 * Bean property getter: <property>additionalProperties</property>. 403 * 404 * @return The property value, or <jk>null</jk> if it is not set. 405 */ 406 public SchemaInfo getAdditionalProperties() { return additionalProperties; } 407 408 /** 409 * Bean property getter: <property>allOf</property>. 410 * 411 * @return The property value, or <jk>null</jk> if it is not set. 412 */ 413 public List<Object> getAllOf() { return nie(allOf); } 414 415 /** 416 * Bean property getter: <property>anyOf</property>. 417 * 418 * @return The property value, or <jk>null</jk> if it is not set. 419 */ 420 public List<Object> getAnyOf() { return nie(anyOf); } 421 422 /** 423 * Bean property getter: <property>default</property>. 424 * 425 * <p> 426 * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object. 427 * 428 * @return The property value, or <jk>null</jk> if it is not set. 429 */ 430 public Object getDefault() { return default_; } 431 432 /** 433 * Bean property getter: <property>deprecated</property>. 434 * 435 * @return The property value, or <jk>null</jk> if it is not set. 436 */ 437 public Boolean getDeprecated() { return deprecated; } 438 439 /** 440 * Bean property getter: <property>description</property>. 441 * 442 * @return The property value, or <jk>null</jk> if it is not set. 443 */ 444 public String getDescription() { return description; } 445 446 /** 447 * Bean property getter: <property>discriminator</property>. 448 * 449 * @return The property value, or <jk>null</jk> if it is not set. 450 */ 451 public Discriminator getDiscriminator() { return discriminator; } 452 453 /** 454 * Bean property getter: <property>enum</property>. 455 * 456 * @return The property value, or <jk>null</jk> if it is not set. 457 */ 458 public List<Object> getEnum() { return nie(enum_); } 459 460 /** 461 * Bean property getter: <property>example</property>. 462 * 463 * @return The property value, or <jk>null</jk> if it is not set. 464 */ 465 public Object getExample() { return example; } 466 467 /** 468 * Bean property getter: <property>exclusiveMaximum</property>. 469 * 470 * @return The property value, or <jk>null</jk> if it is not set. 471 */ 472 public Boolean getExclusiveMaximum() { return exclusiveMaximum; } 473 474 /** 475 * Bean property getter: <property>exclusiveMinimum</property>. 476 * 477 * @return The property value, or <jk>null</jk> if it is not set. 478 */ 479 public Boolean getExclusiveMinimum() { return exclusiveMinimum; } 480 481 /** 482 * Bean property getter: <property>externalDocs</property>. 483 * 484 * @return The property value, or <jk>null</jk> if it is not set. 485 */ 486 public ExternalDocumentation getExternalDocs() { return externalDocs; } 487 488 /** 489 * Bean property getter: <property>format</property>. 490 * 491 * @return The property value, or <jk>null</jk> if it is not set. 492 */ 493 public String getFormat() { return format; } 494 495 /** 496 * Bean property getter: <property>items</property>. 497 * 498 * @return The property value, or <jk>null</jk> if it is not set. 499 */ 500 public Items getItems() { return items; } 501 502 /** 503 * Bean property getter: <property>maximum</property>. 504 * 505 * @return The property value, or <jk>null</jk> if it is not set. 506 */ 507 public Number getMaximum() { return maximum; } 508 509 /** 510 * Bean property getter: <property>maxItems</property>. 511 * 512 * @return The property value, or <jk>null</jk> if it is not set. 513 */ 514 public Integer getMaxItems() { return maxItems; } 515 516 /** 517 * Bean property getter: <property>maxLength</property>. 518 * 519 * @return The property value, or <jk>null</jk> if it is not set. 520 */ 521 public Integer getMaxLength() { return maxLength; } 522 523 /** 524 * Bean property getter: <property>maxProperties</property>. 525 * 526 * @return The property value, or <jk>null</jk> if it is not set. 527 */ 528 public Integer getMaxProperties() { return maxProperties; } 529 530 /** 531 * Bean property getter: <property>minimum</property>. 532 * 533 * @return The property value, or <jk>null</jk> if it is not set. 534 */ 535 public Number getMinimum() { return minimum; } 536 537 /** 538 * Bean property getter: <property>minItems</property>. 539 * 540 * @return The property value, or <jk>null</jk> if it is not set. 541 */ 542 public Integer getMinItems() { return minItems; } 543 544 /** 545 * Bean property getter: <property>minLength</property>. 546 * 547 * @return The property value, or <jk>null</jk> if it is not set. 548 */ 549 public Integer getMinLength() { return minLength; } 550 551 /** 552 * Bean property getter: <property>minProperties</property>. 553 * 554 * @return The property value, or <jk>null</jk> if it is not set. 555 */ 556 public Integer getMinProperties() { return minProperties; } 557 558 /** 559 * Bean property getter: <property>multipleOf</property>. 560 * 561 * @return The property value, or <jk>null</jk> if it is not set. 562 */ 563 public Number getMultipleOf() { return multipleOf; } 564 565 /** 566 * Bean property getter: <property>not</property>. 567 * 568 * @return The property value, or <jk>null</jk> if it is not set. 569 */ 570 public SchemaInfo getNot() { return not; } 571 572 /** 573 * Bean property getter: <property>nullable</property>. 574 * 575 * @return The property value, or <jk>null</jk> if it is not set. 576 */ 577 public Boolean getNullable() { return nullable; } 578 579 /** 580 * Bean property getter: <property>oneOf</property>. 581 * 582 * @return The property value, or <jk>null</jk> if it is not set. 583 */ 584 public List<Object> getOneOf() { return nie(oneOf); } 585 586 /** 587 * Bean property getter: <property>pattern</property>. 588 * 589 * @return The property value, or <jk>null</jk> if it is not set. 590 */ 591 public String getPattern() { return pattern; } 592 593 /** 594 * Bean property getter: <property>properties</property>. 595 * 596 * @return The property value, or <jk>null</jk> if it is not set. 597 */ 598 public Map<String,SchemaInfo> getProperties() { return u(properties); } 599 600 /** 601 * Bean property getter: <property>readOnly</property>. 602 * 603 * @return The property value, or <jk>null</jk> if it is not set. 604 */ 605 public Boolean getReadOnly() { return readOnly; } 606 607 /** 608 * Bean property getter: <property>$ref</property>. 609 * 610 * @return The property value, or <jk>null</jk> if it is not set. 611 */ 612 @BeanProp("$ref") 613 public String getRef() { return ref; } 614 615 /** 616 * Bean property getter: <property>required</property>. 617 * 618 * <p> 619 * The list of required properties. 620 * 621 * <p> 622 * <b>Note:</b> Named/typed <c>required</c> (<c>List<String></c>) here per the OpenAPI 3.x JSON Schema 623 * subset, vs. <c>requiredProperties</c> (<c>Set<String></c>) in swagger-v2's sibling 624 * {@code org.apache.juneau.bean.swagger.SchemaInfo}. This is an intentional, maintainer-confirmed divergence 625 * (PARITY-02): each module tracks its own spec version's canonical field name/type; swagger-v2 additionally 626 * carries a separate boolean {@code getRequired()}/{@code setRequired(Boolean)} pair that this module has no 627 * equivalent for. No rename/retype planned. 628 * 629 * @return The property value, or <jk>null</jk> if it is not set. 630 */ 631 public List<String> getRequired() { return nie(required); } 632 633 /** 634 * Bean property getter: <property>title</property>. 635 * 636 * @return The property value, or <jk>null</jk> if it is not set. 637 */ 638 public String getTitle() { return title; } 639 640 /** 641 * Bean property getter: <property>type</property>. 642 * 643 * @return The property value, or <jk>null</jk> if it is not set. 644 */ 645 public String getType() { return type; } 646 647 /** 648 * Bean property getter: <property>uniqueItems</property>. 649 * 650 * @return The property value, or <jk>null</jk> if it is not set. 651 */ 652 public Boolean getUniqueItems() { return uniqueItems; } 653 654 /** 655 * Bean property getter: <property>writeOnly</property>. 656 * 657 * @return The property value, or <jk>null</jk> if it is not set. 658 */ 659 public Boolean getWriteOnly() { return writeOnly; } 660 661 /** 662 * Bean property getter: <property>xml</property>. 663 * 664 * @return The property value, or <jk>null</jk> if it is not set. 665 */ 666 public Xml getXml() { return xml; } 667 668 @Override /* Overridden from SwaggerElement */ 669 public Set<String> keySet() { 670 // @formatter:off 671 var s = stb(String.class) 672 .addIf(nn(ref), "$ref") 673 .addIf(nn(additionalProperties), "additionalProperties") 674 .addIf(ine(allOf), "allOf") 675 .addIf(ine(anyOf), "anyOf") 676 .addIf(nn(default_), "default") 677 .addIf(nn(deprecated), "deprecated") 678 .addIf(nn(description), "description") 679 .addIf(nn(discriminator), "discriminator") 680 .addIf(ine(enum_), "enum") 681 .addIf(nn(example), "example") 682 .addIf(nn(exclusiveMaximum), "exclusiveMaximum") 683 .addIf(nn(exclusiveMinimum), "exclusiveMinimum") 684 .addIf(nn(externalDocs), "externalDocs") 685 .addIf(nn(format), "format") 686 .addIf(nn(items), "items") 687 .addIf(nn(maxItems), "maxItems") 688 .addIf(nn(maxLength), "maxLength") 689 .addIf(nn(maxProperties), "maxProperties") 690 .addIf(nn(maximum), "maximum") 691 .addIf(nn(minItems), "minItems") 692 .addIf(nn(minLength), "minLength") 693 .addIf(nn(minProperties), "minProperties") 694 .addIf(nn(minimum), "minimum") 695 .addIf(nn(multipleOf), "multipleOf") 696 .addIf(nn(not), "not") 697 .addIf(nn(nullable), "nullable") 698 .addIf(ine(oneOf), "oneOf") 699 .addIf(nn(pattern), "pattern") 700 .addIf(nn(properties), "properties") 701 .addIf(nn(readOnly), "readOnly") 702 .addIf(ine(required), "required") 703 .addIf(nn(title), "title") 704 .addIf(nn(type), "type") 705 .addIf(nn(uniqueItems), "uniqueItems") 706 .addIf(nn(writeOnly), "writeOnly") 707 .addIf(nn(xml), "xml") 708 .build(); 709 // @formatter:on 710 return new MultiSet<>(s, super.keySet()); 711 } 712 713 /** 714 * Resolves any <js>"$ref"</js> attributes in this element. 715 * 716 * @param openApi The swagger document containing the definitions. 717 * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops. 718 * @param maxDepth 719 * The maximum depth to resolve references. 720 * <br>After that level is reached, <code>$ref</code> references will be left alone. 721 * <br>Useful if you have very complex models and you don't want your swagger page to be overly-complex. 722 * @return 723 * This object with references resolved. 724 * <br>May or may not be the same object. 725 */ 726 public SchemaInfo resolveRefs(OpenApi openApi, Deque<String> refStack, int maxDepth) { 727 728 if (nn(ref)) { 729 if (refStack.contains(ref) || refStack.size() >= maxDepth) 730 return this; 731 refStack.addLast(ref); 732 var r = openApi.findRef(ref, SchemaInfo.class); 733 r = r.resolveRefs(openApi, refStack, maxDepth); 734 refStack.removeLast(); 735 return r; 736 } 737 738 if (nn(items)) 739 items = items.resolveRefs(openApi, refStack, maxDepth); 740 741 if (nn(properties)) 742 for (var e : properties.entrySet()) 743 e.setValue(e.getValue().resolveRefs(openApi, refStack, maxDepth)); 744 745 if (nn(additionalProperties)) 746 additionalProperties = additionalProperties.resolveRefs(openApi, refStack, maxDepth); 747 748 this.example = null; 749 750 return this; 751 } 752 753 @Override /* Overridden from SwaggerElement */ 754 public SchemaInfo set(String property, Object value) { 755 reqnn("property", property); 756 return switch (property) { 757 case "$ref" -> setRef(value); 758 case "additionalProperties" -> setAdditionalProperties(toType(value, SchemaInfo.class)); 759 case "allOf" -> setAllOf(lb(Object.class).addAny(value).sparse().build()); 760 case "anyOf" -> setAnyOf(lb(Object.class).addAny(value).sparse().build()); 761 case "default" -> setDefault(value); 762 case "deprecated" -> setDeprecated(toBoolean(value)); 763 case "description" -> setDescription(s(value)); 764 case "discriminator" -> setDiscriminator(toType(value, Discriminator.class)); 765 case "enum" -> setEnum(lb(Object.class).addAny(value).sparse().build()); 766 case "example" -> setExample(value); 767 case "exclusiveMaximum" -> setExclusiveMaximum(toBoolean(value)); 768 case "exclusiveMinimum" -> setExclusiveMinimum(toBoolean(value)); 769 case "externalDocs" -> setExternalDocs(toType(value, ExternalDocumentation.class)); 770 case "format" -> setFormat(s(value)); 771 case "items" -> setItems(toType(value, Items.class)); 772 case "maxItems" -> setMaxItems(toInteger(value)); 773 case "maxLength" -> setMaxLength(toInteger(value)); 774 case "maxProperties" -> setMaxProperties(toInteger(value)); 775 case "maximum" -> setMaximum(toNumber(value)); 776 case "minItems" -> setMinItems(toInteger(value)); 777 case "minLength" -> setMinLength(toInteger(value)); 778 case "minProperties" -> setMinProperties(toInteger(value)); 779 case "minimum" -> setMinimum(toNumber(value)); 780 case "multipleOf" -> setMultipleOf(toNumber(value)); 781 case "not" -> setNot(toType(value, SchemaInfo.class)); 782 case "nullable" -> setNullable(toBoolean(value)); 783 case "oneOf" -> setOneOf(lb(Object.class).addAny(value).sparse().build()); 784 case "pattern" -> setPattern(s(value)); 785 case "properties" -> setProperties(toMapBuilder(value, String.class, SchemaInfo.class).sparse().build()); 786 case "readOnly" -> setReadOnly(toBoolean(value)); 787 case "required" -> setRequired(lb(String.class).addAny(value).sparse().build()); 788 case "title" -> setTitle(s(value)); 789 case "type" -> setType(s(value)); 790 case "uniqueItems" -> setUniqueItems(toBoolean(value)); 791 case "writeOnly" -> setWriteOnly(toBoolean(value)); 792 case "xml" -> setXml(toType(value, Xml.class)); 793 default -> { 794 super.set(property, value); 795 yield this; 796 } 797 }; 798 } 799 800 /** 801 * Bean property setter: <property>additionalProperties</property>. 802 * 803 * @param value 804 * The new value for this property. 805 * <br>Can be <jk>null</jk> to unset the property. 806 * @return This object 807 */ 808 public SchemaInfo setAdditionalProperties(SchemaInfo value) { 809 additionalProperties = value; 810 return this; 811 } 812 813 /** 814 * Bean property setter: <property>allOf</property>. 815 * 816 * @param value 817 * The new value for this property. 818 * <br>Can be <jk>null</jk> to unset the property. 819 * @return This object 820 */ 821 public SchemaInfo setAllOf(Collection<Object> value) { 822 allOf.clear(); 823 if (nn(value)) 824 allOf.addAll(value); 825 return this; 826 } 827 828 /** 829 * Bean property setter: <property>anyOf</property>. 830 * 831 * @param value 832 * The new value for this property. 833 * <br>Can be <jk>null</jk> to unset the property. 834 * @return This object 835 */ 836 public SchemaInfo setAnyOf(Collection<Object> value) { 837 anyOf.clear(); 838 if (nn(value)) 839 anyOf.addAll(value); 840 return this; 841 } 842 843 /** 844 * Bean property setter: <property>default</property>. 845 * 846 * <p> 847 * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object. 848 * 849 * @param value 850 * The new value for this property. 851 * <br>Can be <jk>null</jk> to unset the property. 852 * @return This object 853 */ 854 public SchemaInfo setDefault(Object value) { 855 default_ = value; 856 return this; 857 } 858 859 /** 860 * Bean property setter: <property>deprecated</property>. 861 * 862 * @param value 863 * The new value for this property. 864 * <br>Can be <jk>null</jk> to unset the property. 865 * @return This object 866 */ 867 public SchemaInfo setDeprecated(Boolean value) { 868 deprecated = value; 869 return this; 870 } 871 872 /** 873 * Bean property setter: <property>description</property>. 874 * 875 * @param value 876 * The new value for this property. 877 * <br>Can be <jk>null</jk> to unset the property. 878 * @return This object 879 */ 880 public SchemaInfo setDescription(String value) { 881 description = value; 882 return this; 883 } 884 885 /** 886 * Bean property setter: <property>discriminator</property>. 887 * 888 * @param value 889 * The new value for this property. 890 * <br>Can be <jk>null</jk> to unset the property. 891 * @return This object 892 */ 893 public SchemaInfo setDiscriminator(Discriminator value) { 894 discriminator = value; 895 return this; 896 } 897 898 /** 899 * Bean property setter: <property>enum</property>. 900 * 901 * @param value 902 * The new value for this property. 903 * <br>Can be <jk>null</jk> to unset the property. 904 * @return This object 905 */ 906 public SchemaInfo setEnum(Collection<Object> value) { 907 enum_.clear(); 908 if (nn(value)) 909 enum_.addAll(value); 910 return this; 911 } 912 913 /** 914 * Bean property setter: <property>example</property>. 915 * 916 * @param value 917 * The new value for this property. 918 * <br>Can be <jk>null</jk> to unset the property. 919 * @return This object 920 */ 921 public SchemaInfo setExample(Object value) { 922 example = value; 923 return this; 924 } 925 926 /** 927 * Bean property setter: <property>exclusiveMaximum</property>. 928 * 929 * @param value 930 * The new value for this property. 931 * <br>Can be <jk>null</jk> to unset the property. 932 * @return This object 933 */ 934 public SchemaInfo setExclusiveMaximum(Boolean value) { 935 exclusiveMaximum = value; 936 return this; 937 } 938 939 /** 940 * Bean property setter: <property>exclusiveMinimum</property>. 941 * 942 * @param value 943 * The new value for this property. 944 * <br>Can be <jk>null</jk> to unset the property. 945 * @return This object 946 */ 947 public SchemaInfo setExclusiveMinimum(Boolean value) { 948 exclusiveMinimum = value; 949 return this; 950 } 951 952 /** 953 * Bean property setter: <property>externalDocs</property>. 954 * 955 * @param value 956 * The new value for this property. 957 * <br>Can be <jk>null</jk> to unset the property. 958 * @return This object 959 */ 960 public SchemaInfo setExternalDocs(ExternalDocumentation value) { 961 externalDocs = value; 962 return this; 963 } 964 965 /** 966 * Bean property setter: <property>format</property>. 967 * 968 * @param value 969 * The new value for this property. 970 * <br>Can be <jk>null</jk> to unset the property. 971 * <br>Formats defined by the OAS include: 972 * <ul> 973 * <li><js>"int32"</js> 974 * <li><js>"int64"</js> 975 * <li><js>"float"</js> 976 * <li><js>"double"</js> 977 * <li><js>"byte"</js> 978 * <li><js>"binary"</js> 979 * <li><js>"date"</js> 980 * <li><js>"date-time"</js> 981 * <li><js>"password"</js> 982 * </ul> 983 * @return This object 984 */ 985 public SchemaInfo setFormat(String value) { 986 format = value; 987 return this; 988 } 989 990 /** 991 * Bean property setter: <property>items</property>. 992 * 993 * @param value 994 * The new value for this property. 995 * <br>Can be <jk>null</jk> to unset the property. 996 * @return This object 997 */ 998 public SchemaInfo setItems(Items value) { 999 items = value; 1000 return this; 1001 } 1002 1003 /** 1004 * Bean property setter: <property>maximum</property>. 1005 * 1006 * @param value 1007 * The new value for this property. 1008 * <br>Can be <jk>null</jk> to unset the property. 1009 * @return This object 1010 */ 1011 public SchemaInfo setMaximum(Number value) { 1012 maximum = value; 1013 return this; 1014 } 1015 1016 /** 1017 * Bean property setter: <property>maxItems</property>. 1018 * 1019 * @param value 1020 * The new value for this property. 1021 * <br>Can be <jk>null</jk> to unset the property. 1022 * @return This object 1023 */ 1024 public SchemaInfo setMaxItems(Integer value) { 1025 maxItems = value; 1026 return this; 1027 } 1028 1029 /** 1030 * Bean property setter: <property>maxLength</property>. 1031 * 1032 * @param value 1033 * The new value for this property. 1034 * <br>Can be <jk>null</jk> to unset the property. 1035 * @return This object 1036 */ 1037 public SchemaInfo setMaxLength(Integer value) { 1038 maxLength = value; 1039 return this; 1040 } 1041 1042 /** 1043 * Bean property setter: <property>maxProperties</property>. 1044 * 1045 * @param value 1046 * The new value for this property. 1047 * <br>Can be <jk>null</jk> to unset the property. 1048 * @return This object 1049 */ 1050 public SchemaInfo setMaxProperties(Integer value) { 1051 maxProperties = value; 1052 return this; 1053 } 1054 1055 /** 1056 * Bean property setter: <property>minimum</property>. 1057 * 1058 * @param value 1059 * The new value for this property. 1060 * <br>Can be <jk>null</jk> to unset the property. 1061 * @return This object 1062 */ 1063 public SchemaInfo setMinimum(Number value) { 1064 minimum = value; 1065 return this; 1066 } 1067 1068 /** 1069 * Bean property setter: <property>minItems</property>. 1070 * 1071 * @param value 1072 * The new value for this property. 1073 * <br>Can be <jk>null</jk> to unset the property. 1074 * @return This object 1075 */ 1076 public SchemaInfo setMinItems(Integer value) { 1077 minItems = value; 1078 return this; 1079 } 1080 1081 /** 1082 * Bean property setter: <property>minLength</property>. 1083 * 1084 * @param value 1085 * The new value for this property. 1086 * <br>Can be <jk>null</jk> to unset the property. 1087 * @return This object 1088 */ 1089 public SchemaInfo setMinLength(Integer value) { 1090 minLength = value; 1091 return this; 1092 } 1093 1094 /** 1095 * Bean property setter: <property>minProperties</property>. 1096 * 1097 * @param value 1098 * The new value for this property. 1099 * <br>Can be <jk>null</jk> to unset the property. 1100 * @return This object 1101 */ 1102 public SchemaInfo setMinProperties(Integer value) { 1103 minProperties = value; 1104 return this; 1105 } 1106 1107 /** 1108 * Bean property setter: <property>multipleOf</property>. 1109 * 1110 * @param value 1111 * The new value for this property. 1112 * <br>Can be <jk>null</jk> to unset the property. 1113 * @return This object 1114 */ 1115 public SchemaInfo setMultipleOf(Number value) { 1116 multipleOf = value; 1117 return this; 1118 } 1119 1120 /** 1121 * Bean property setter: <property>not</property>. 1122 * 1123 * @param value 1124 * The new value for this property. 1125 * <br>Can be <jk>null</jk> to unset the property. 1126 * @return This object 1127 */ 1128 public SchemaInfo setNot(SchemaInfo value) { 1129 not = value; 1130 return this; 1131 } 1132 1133 /** 1134 * Bean property setter: <property>nullable</property>. 1135 * 1136 * @param value 1137 * The new value for this property. 1138 * <br>Can be <jk>null</jk> to unset the property. 1139 * @return This object 1140 */ 1141 public SchemaInfo setNullable(Boolean value) { 1142 nullable = value; 1143 return this; 1144 } 1145 1146 /** 1147 * Bean property setter: <property>oneOf</property>. 1148 * 1149 * @param value 1150 * The new value for this property. 1151 * <br>Can be <jk>null</jk> to unset the property. 1152 * @return This object 1153 */ 1154 public SchemaInfo setOneOf(Collection<Object> value) { 1155 oneOf.clear(); 1156 if (nn(value)) 1157 oneOf.addAll(value); 1158 return this; 1159 } 1160 1161 /** 1162 * Bean property setter: <property>pattern</property>. 1163 * 1164 * <p> 1165 * This string SHOULD be a valid regular expression. 1166 * 1167 * @param value 1168 * The new value for this property. 1169 * <br>Can be <jk>null</jk> to unset the property. 1170 * @return This object 1171 */ 1172 public SchemaInfo setPattern(String value) { 1173 pattern = value; 1174 return this; 1175 } 1176 1177 /** 1178 * Bean property setter: <property>properties</property>. 1179 * 1180 * @param value 1181 * The new value for this property. 1182 * <br>Can be <jk>null</jk> to unset the property. 1183 * @return This object 1184 */ 1185 public SchemaInfo setProperties(Map<String,SchemaInfo> value) { 1186 properties = copyOf(value); 1187 return this; 1188 } 1189 1190 /** 1191 * Bean property setter: <property>readOnly</property>. 1192 * 1193 * @param value 1194 * The new value for this property. 1195 * <br>Can be <jk>null</jk> to unset the property. 1196 * @return This object 1197 */ 1198 public SchemaInfo setReadOnly(Boolean value) { 1199 readOnly = value; 1200 return this; 1201 } 1202 1203 /** 1204 * Bean property setter: <property>$ref</property>. 1205 * 1206 * @param value 1207 * The new value for this property. 1208 * <br>Can be <jk>null</jk> to unset the property. 1209 * @return This object 1210 */ 1211 @BeanProp("$ref") 1212 public SchemaInfo setRef(Object value) { 1213 ref = s(value); 1214 return this; 1215 } 1216 1217 /** 1218 * Bean property setter: <property>required</property>. 1219 * 1220 * <p> 1221 * The list of required properties. 1222 * 1223 * @param value 1224 * The new value for this property. 1225 * <br>Can be <jk>null</jk> to unset the property. 1226 * @return This object 1227 */ 1228 public SchemaInfo setRequired(Collection<String> value) { 1229 required.clear(); 1230 if (nn(value)) 1231 required.addAll(value); 1232 return this; 1233 } 1234 1235 /** 1236 * Bean property setter: <property>title</property>. 1237 * 1238 * @param value 1239 * The new value for this property. 1240 * <br>Can be <jk>null</jk> to unset the property. 1241 * @return This object 1242 */ 1243 public SchemaInfo setTitle(String value) { 1244 title = value; 1245 return this; 1246 } 1247 1248 /** 1249 * Bean property setter: <property>type</property>. 1250 * 1251 * @param value 1252 * The new value for this property. 1253 * <br>Can be <jk>null</jk> to unset the property. 1254 * <br>Possible values include: 1255 * <ul> 1256 * <li><js>"object"</js> 1257 * <li><js>"string"</js> 1258 * <li><js>"number"</js> 1259 * <li><js>"integer"</js> 1260 * <li><js>"boolean"</js> 1261 * <li><js>"array"</js> 1262 * <li><js>"file"</js> 1263 * </ul> 1264 * @return This object 1265 */ 1266 public SchemaInfo setType(String value) { 1267 type = value; 1268 return this; 1269 } 1270 1271 /** 1272 * Bean property setter: <property>uniqueItems</property>. 1273 * 1274 * @param value 1275 * The new value for this property. 1276 * <br>Can be <jk>null</jk> to unset the property. 1277 * @return This object 1278 */ 1279 public SchemaInfo setUniqueItems(Boolean value) { 1280 uniqueItems = value; 1281 return this; 1282 } 1283 1284 /** 1285 * Bean property setter: <property>writeOnly</property>. 1286 * 1287 * @param value 1288 * The new value for this property. 1289 * <br>Can be <jk>null</jk> to unset the property. 1290 * @return This object 1291 */ 1292 public SchemaInfo setWriteOnly(Boolean value) { 1293 writeOnly = value; 1294 return this; 1295 } 1296 1297 /** 1298 * Bean property setter: <property>xml</property>. 1299 * 1300 * @param value 1301 * The new value for this property. 1302 * <br>Can be <jk>null</jk> to unset the property. 1303 * @return This object 1304 */ 1305 public SchemaInfo setXml(Xml value) { 1306 xml = value; 1307 return this; 1308 } 1309 1310 @Override /* Overridden from OpenApiElement */ 1311 public SchemaInfo strict() { 1312 super.strict(); 1313 return this; 1314 } 1315 1316 @Override /* Overridden from OpenApiElement */ 1317 public SchemaInfo strict(Object value) { 1318 super.strict(value); 1319 return this; 1320 } 1321}