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