001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.dto.swagger; 014 015import static org.apache.juneau.internal.BeanPropertyUtils.*; 016import static org.apache.juneau.internal.ArrayUtils.*; 017 018import java.util.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.annotation.*; 022import org.apache.juneau.internal.*; 023import org.apache.juneau.json.*; 024import org.apache.juneau.utils.*; 025 026/** 027 * A limited subset of JSON-Schema's items object. 028 * 029 * <p> 030 * It is used by parameter definitions that are not located in "body". 031 * 032 * <h5 class='section'>Example:</h5> 033 * <p class='bcode w800'> 034 * <jc>// Construct using SwaggerBuilder.</jc> 035 * Items x = <jsm>items</jsm>(<js>"string"</js>).minLength(2); 036 * 037 * <jc>// Serialize using JsonSerializer.</jc> 038 * String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x); 039 * 040 * <jc>// Or just use toString() which does the same as above.</jc> 041 * String json = x.toString(); 042 * </p> 043 * <p class='bcode w800'> 044 * <jc>// Output</jc> 045 * { 046 * <js>"type"</js>: <js>"string"</js>, 047 * <js>"minLength"</js>: 2 048 * } 049 * </p> 050 * 051 * <h5 class='section'>See Also:</h5> 052 * <ul class='doctree'> 053 * <li class='link'>{@doc juneau-dto.Swagger} 054 * </ul> 055 */ 056@Bean(properties="type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,*") 057public class Items extends SwaggerElement { 058 059 private static final String[] VALID_TYPES = {"string", "number", "integer", "boolean", "array"}; 060 private static final String[] VALID_COLLECTION_FORMATS = {"csv","ssv","tsv","pipes","multi"}; 061 062 private String 063 type, 064 format, 065 collectionFormat, 066 pattern, 067 ref; 068 private Number 069 maximum, 070 minimum, 071 multipleOf; 072 private Integer 073 maxLength, 074 minLength, 075 maxItems, 076 minItems; 077 private Boolean 078 exclusiveMaximum, 079 exclusiveMinimum, 080 uniqueItems; 081 private Items items; 082 private Object _default; 083 private List<Object> _enum; 084 085 /** 086 * Default constructor. 087 */ 088 public Items() {} 089 090 /** 091 * Copy constructor. 092 * 093 * @param copyFrom The object to copy. 094 */ 095 public Items(Items copyFrom) { 096 super(copyFrom); 097 098 this.type = copyFrom.type; 099 this.format = copyFrom.format; 100 this.collectionFormat = copyFrom.collectionFormat; 101 this.pattern = copyFrom.pattern; 102 this.maximum = copyFrom.maximum; 103 this.minimum = copyFrom.minimum; 104 this.multipleOf = copyFrom.multipleOf; 105 this.maxLength = copyFrom.maxLength; 106 this.minLength = copyFrom.minLength; 107 this.maxItems = copyFrom.maxItems; 108 this.minItems = copyFrom.minItems; 109 this.exclusiveMaximum = copyFrom.exclusiveMaximum; 110 this.exclusiveMinimum = copyFrom.exclusiveMinimum; 111 this.uniqueItems = copyFrom.uniqueItems; 112 this.items = copyFrom.items == null ? null : copyFrom.items.copy(); 113 this._default = copyFrom._default; 114 this._enum = newList(copyFrom._enum); 115 this.ref = copyFrom.ref; 116 } 117 118 /** 119 * Make a deep copy of this object. 120 * 121 * @return A deep copy of this object. 122 */ 123 public Items copy() { 124 return new Items(this); 125 } 126 127 128 @Override /* SwaggerElement */ 129 protected Items strict() { 130 super.strict(); 131 return this; 132 } 133 134 /** 135 * Bean property getter: <property>type</property>. 136 * 137 * <p> 138 * The internal type of the array. 139 * 140 * @return The property value, or <jk>null</jk> if it is not set. 141 */ 142 public String getType() { 143 return type; 144 } 145 146 /** 147 * Bean property setter: <property>type</property>. 148 * 149 * <p> 150 * The internal type of the array. 151 * 152 * <h5 class='section'>See Also:</h5> 153 * <ul class='doctree'> 154 * <li class='extlink'>{@doc SwaggerDataTypes} 155 * </ul> 156 * 157 * @param value 158 * The new value for this property. 159 * <br>Valid values: 160 * <ul> 161 * <li><js>"string"</js> 162 * <li><js>"number"</js> 163 * <li><js>"integer"</js> 164 * <li><js>"boolean"</js> 165 * <li><js>"array"</js> 166 * </ul> 167 * <br>Property value is required. 168 * @return This object (for method chaining). 169 */ 170 public Items setType(String value) { 171 if (isStrict() && ! contains(value, VALID_TYPES)) 172 throw new RuntimeException( 173 "Invalid value passed in to setType(String). Value='"+value+"', valid values=" 174 + SimpleJsonSerializer.DEFAULT.toString(VALID_TYPES)); 175 type = value; 176 return this; 177 } 178 179 /** 180 * Same as {@link #setType(String)}. 181 * 182 * @param value 183 * The new value for this property. 184 * <br>Non-String values will be converted to String using <code>toString()</code>. 185 * <br>Valid values: 186 * <ul> 187 * <li><js>"string"</js> 188 * <li><js>"number"</js> 189 * <li><js>"integer"</js> 190 * <li><js>"boolean"</js> 191 * <li><js>"array"</js> 192 * </ul> 193 * <br>Can be <jk>null</jk> to unset the property. 194 * @return This object (for method chaining). 195 */ 196 public Items type(Object value) { 197 return setType(toStringVal(value)); 198 } 199 200 /** 201 * Bean property getter: <property>format</property>. 202 * 203 * <p> 204 * The extending format for the previously mentioned <code>type</code>. 205 * 206 * <h5 class='section'>See Also:</h5> 207 * <ul> 208 * <li class='extlink'>{@doc SwaggerDataTypeFormats} 209 * </ul> 210 * 211 * @return The property value, or <jk>null</jk> if it is not set. 212 */ 213 public String getFormat() { 214 return format; 215 } 216 217 /** 218 * Bean property setter: <property>format</property>. 219 * 220 * <p> 221 * The extending format for the previously mentioned <code>type</code>. 222 * 223 * <h5 class='section'>See Also:</h5> 224 * <ul> 225 * <li class='extlink'>{@doc SwaggerDataTypeFormats} 226 * </ul> 227 * 228 * @param value 229 * The new value for this property. 230 * <br>Can be <jk>null</jk> to unset the property. 231 * @return This object (for method chaining). 232 */ 233 public Items setFormat(String value) { 234 format = value; 235 return this; 236 } 237 238 /** 239 * Same as {@link #setFormat(String)}. 240 * 241 * @param value 242 * The new value for this property. 243 * <br>Non-String values will be converted to String using <code>toString()</code>. 244 * <br>Can be <jk>null</jk> to unset the property. 245 * @return This object (for method chaining). 246 */ 247 public Items format(Object value) { 248 return setFormat(toStringVal(value)); 249 } 250 251 /** 252 * Bean property getter: <property>items</property>. 253 * 254 * <p> 255 * Describes the type of items in the array. 256 * 257 * @return The property value, or <jk>null</jk> if it is not set. 258 */ 259 public Items getItems() { 260 return items; 261 } 262 263 /** 264 * Bean property setter: <property>items</property>. 265 * 266 * <p> 267 * Describes the type of items in the array. 268 * 269 * @param value 270 * The new value for this property. 271 * <br>Property value is required if <code>type</code> is <js>"array"</js>. 272 * <br>Can be <jk>null</jk> to unset the property. 273 * @return This object (for method chaining). 274 */ 275 public Items setItems(Items value) { 276 items = value; 277 return this; 278 } 279 280 /** 281 * Same as {@link #setItems(Items)}. 282 * 283 * @param value 284 * The new value for this property. 285 * <br>Property value is required if <code>type</code> is <js>"array"</js>. 286 * <br>Valid types: 287 * <ul> 288 * <li>{@link Items} 289 * <li><code>String</code> - JSON object representation of {@link Items} 290 * <h5 class='figure'>Example:</h5> 291 * <p class='bcode w800'> 292 * items(<js>"{type:'type',format:'format',...}"</js>); 293 * </p> 294 * </ul> 295 * <br>Can be <jk>null</jk> to unset the property. 296 * @return This object (for method chaining). 297 */ 298 public Items items(Object value) { 299 return setItems(toType(value, Items.class)); 300 } 301 302 /** 303 * Bean property getter: <property>collectionFormat</property>. 304 * 305 * <p> 306 * Determines the format of the array if type array is used. 307 * 308 * @return The property value, or <jk>null</jk> if it is not set. 309 */ 310 public String getCollectionFormat() { 311 return collectionFormat; 312 } 313 314 /** 315 * Bean property setter: <property>collectionFormat</property>. 316 * 317 * <p> 318 * Determines the format of the array if type array is used. 319 * 320 * @param value 321 * The new value for this property. 322 * <br>Valid values: 323 * <ul> 324 * <li><js>"csv"</js> (default) - comma separated values <code>foo,bar</code>. 325 * <li><js>"ssv"</js> - space separated values <code>foo bar</code>. 326 * <li><js>"tsv"</js> - tab separated values <code>foo\tbar</code>. 327 * <li><js>"pipes"</js> - pipe separated values <code>foo|bar</code>. 328 * </ul> 329 * <br>Can be <jk>null</jk> to unset the property. 330 * @return This object (for method chaining). 331 */ 332 public Items setCollectionFormat(String value) { 333 if (isStrict() && ! contains(value, VALID_COLLECTION_FORMATS)) 334 throw new FormattedRuntimeException( 335 "Invalid value passed in to setCollectionFormat(String). Value=''{0}'', valid values={1}", 336 value, VALID_COLLECTION_FORMATS 337 ); 338 collectionFormat = value; 339 return this; 340 } 341 342 /** 343 * Same as {@link #setCollectionFormat(String)}. 344 * 345 * @param value 346 * The new value for this property. 347 * <br>Non-String values will be converted to String using <code>toString()</code>. 348 * <br>Valid values: 349 * <ul> 350 * <li><js>"csv"</js> (default) - comma separated values <code>foo,bar</code>. 351 * <li><js>"ssv"</js> - space separated values <code>foo bar</code>. 352 * <li><js>"tsv"</js> - tab separated values <code>foo\tbar</code>. 353 * <li><js>"pipes"</js> - pipe separated values <code>foo|bar</code>. 354 * </ul> 355 * <br>Can be <jk>null</jk> to unset the property. 356 * @return This object (for method chaining). 357 */ 358 public Items collectionFormat(Object value) { 359 return setCollectionFormat(toStringVal(value)); 360 } 361 362 /** 363 * Bean property getter: <property>default</property>. 364 * 365 * <p> 366 * Declares the value of the item that the server will use if none is provided. 367 * 368 * <h5 class='section'>Notes:</h5> 369 * <ul class='spaced-list'> 370 * <li> 371 * <js>"default"</js> has no meaning for required items. 372 * <li> 373 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type. 374 * </ul> 375 * 376 * <h5 class='section'>See Also:</h5> 377 * <ul> 378 * <li class='extlink'>{@doc JsonSchemaValidation} 379 * </ul> 380 * 381 * @return The property value, or <jk>null</jk> if it is not set. 382 */ 383 public Object getDefault() { 384 return _default; 385 } 386 387 /** 388 * Bean property setter: <property>default</property>. 389 * 390 * <p> 391 * Declares the value of the item that the server will use if none is provided. 392 * 393 * <h5 class='section'>Notes:</h5> 394 * <ul class='spaced-list'> 395 * <li> 396 * <js>"default"</js> has no meaning for required items. 397 * <li> 398 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type. 399 * </ul> 400 * 401 * <h5 class='section'>See Also:</h5> 402 * <ul> 403 * <li class='extlink'>{@doc JsonSchemaValidation} 404 * </ul> 405 * 406 * @param value 407 * The new value for this property. 408 * <br>Can be <jk>null</jk> to unset the property. 409 * @return This object (for method chaining). 410 */ 411 public Items setDefault(Object value) { 412 _default = value; 413 return this; 414 } 415 416 /** 417 * Same as {@link #setDefault(Object)}. 418 * 419 * @param value 420 * The new value for this property. 421 * <br>Can be <jk>null</jk> to unset the property. 422 * @return This object (for method chaining). 423 */ 424 public Items _default(Object value) { 425 return setDefault(value); 426 } 427 428 /** 429 * Bean property getter: <property>maximum</property>. 430 * 431 * <h5 class='section'>See Also:</h5> 432 * <ul> 433 * <li class='extlink'>{@doc JsonSchemaValidation} 434 * </ul> 435 * 436 * @return The property value, or <jk>null</jk> if it is not set. 437 */ 438 public Number getMaximum() { 439 return maximum; 440 } 441 442 /** 443 * Bean property setter: <property>maximum</property>. 444 * 445 * <h5 class='section'>See Also:</h5> 446 * <ul> 447 * <li class='extlink'>{@doc JsonSchemaValidation} 448 * </ul> 449 * 450 * @param value 451 * The new value for this property. 452 * <br>Can be <jk>null</jk> to unset the property. 453 * @return This object (for method chaining). 454 */ 455 public Items setMaximum(Number value) { 456 maximum = value; 457 return this; 458 } 459 460 /** 461 * Same as {@link #setMaximum(Number)}. 462 * 463 * @param value 464 * The new value for this property. 465 * <br>Non-Number values will be converted to Number using <code>toString()</code> then best number match. 466 * <br>Can be <jk>null</jk> to unset the property. 467 * @return This object (for method chaining). 468 */ 469 public Items maximum(Object value) { 470 return setMaximum(toNumber(value)); 471 } 472 473 /** 474 * Bean property getter: <property>exclusiveMaximum</property>. 475 * 476 * <h5 class='section'>See Also:</h5> 477 * <ul> 478 * <li class='extlink'>{@doc JsonSchemaValidation} 479 * </ul> 480 * 481 * @return The property value, or <jk>null</jk> if it is not set. 482 */ 483 public Boolean getExclusiveMaximum() { 484 return exclusiveMaximum; 485 } 486 487 /** 488 * Bean property setter: <property>exclusiveMaximum</property>. 489 * 490 * <h5 class='section'>See Also:</h5> 491 * <ul> 492 * <li class='extlink'>{@doc JsonSchemaValidation} 493 * </ul> 494 * 495 * @param value 496 * The new value for this property. 497 * <br>Can be <jk>null</jk> to unset the property. 498 * @return This object (for method chaining). 499 */ 500 public Items setExclusiveMaximum(Boolean value) { 501 exclusiveMaximum = value; 502 return this; 503 } 504 505 /** 506 * Same as {@link #setExclusiveMaximum(Boolean)}. 507 * 508 * @param value 509 * The new value for this property. 510 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 511 * <br>Can be <jk>null</jk> to unset the property. 512 * @return This object (for method chaining). 513 */ 514 public Items exclusiveMaximum(Object value) { 515 return setExclusiveMaximum(toBoolean(value)); 516 } 517 518 /** 519 * Bean property getter: <property>minimum</property>. 520 * 521 * <h5 class='section'>See Also:</h5> 522 * <ul> 523 * <li class='extlink'>{@doc JsonSchemaValidation} 524 * </ul> 525 * 526 * @return The property value, or <jk>null</jk> if it is not set. 527 */ 528 public Number getMinimum() { 529 return minimum; 530 } 531 532 /** 533 * Bean property setter: <property>minimum</property>. 534 * 535 * <h5 class='section'>See Also:</h5> 536 * <ul> 537 * <li class='extlink'>{@doc JsonSchemaValidation} 538 * </ul> 539 * 540 * @param value 541 * The new value for this property. 542 * <br>Can be <jk>null</jk> to unset the property. 543 * @return This object (for method chaining). 544 */ 545 public Items setMinimum(Number value) { 546 minimum = value; 547 return this; 548 } 549 550 /** 551 * Same as {@link #setMinimum(Number)}. 552 * 553 * @param value 554 * The new value for this property. 555 * <br>Non-Number values will be converted to Number using <code>toString()</code> then best number match. 556 * <br>Can be <jk>null</jk> to unset the property. 557 * @return This object (for method chaining). 558 */ 559 public Items minimum(Object value) { 560 return setMinimum(toNumber(value)); 561 } 562 563 /** 564 * Bean property getter: <property>exclusiveMinimum</property>. 565 * 566 * <h5 class='section'>See Also:</h5> 567 * <ul> 568 * <li class='extlink'>{@doc JsonSchemaValidation} 569 * </ul> 570 * 571 * @return The property value, or <jk>null</jk> if it is not set. 572 */ 573 public Boolean getExclusiveMinimum() { 574 return exclusiveMinimum; 575 } 576 577 /** 578 * Bean property setter: <property>exclusiveMinimum</property>. 579 * 580 * <h5 class='section'>See Also:</h5> 581 * <ul> 582 * <li class='extlink'>{@doc JsonSchemaValidation} 583 * </ul> 584 * 585 * @param value 586 * The new value for this property. 587 * <br>Can be <jk>null</jk> to unset the property. 588 * @return This object (for method chaining). 589 */ 590 public Items setExclusiveMinimum(Boolean value) { 591 exclusiveMinimum = value; 592 return this; 593 } 594 595 /** 596 * Same as {@link #setExclusiveMinimum(Boolean)}. 597 * 598 * @param value 599 * The new value for this property. 600 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 601 * <br>Can be <jk>null</jk> to unset the property. 602 * @return This object (for method chaining). 603 */ 604 public Items exclusiveMinimum(Object value) { 605 return setExclusiveMinimum(toBoolean(value)); 606 } 607 608 /** 609 * Bean property getter: <property>maxLength</property>. 610 * 611 * <h5 class='section'>See Also:</h5> 612 * <ul> 613 * <li class='extlink'>{@doc JsonSchemaValidation} 614 * </ul> 615 * 616 * @return The property value, or <jk>null</jk> if it is not set. 617 */ 618 public Integer getMaxLength() { 619 return maxLength; 620 } 621 622 /** 623 * Bean property setter: <property>maxLength</property>. 624 * 625 * <h5 class='section'>See Also:</h5> 626 * <ul> 627 * <li class='extlink'>{@doc JsonSchemaValidation} 628 * </ul> 629 * 630 * @param value 631 * The new value for this property. 632 * <br>Can be <jk>null</jk> to unset the property. 633 * @return This object (for method chaining). 634 */ 635 public Items setMaxLength(Integer value) { 636 maxLength = value; 637 return this; 638 } 639 640 /** 641 * Same as {@link #setMaxLength(Integer)}. 642 * 643 * @param value 644 * The new value for this property. 645 * <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>. 646 * <br>Can be <jk>null</jk> to unset the property. 647 * @return This object (for method chaining). 648 */ 649 public Items maxLength(Object value) { 650 return setMaxLength(toInteger(value)); 651 } 652 653 /** 654 * Bean property getter: <property>minLength</property>. 655 * 656 * <h5 class='section'>See Also:</h5> 657 * <ul> 658 * <li class='extlink'>{@doc JsonSchemaValidation} 659 * </ul> 660 * 661 * @return The property value, or <jk>null</jk> if it is not set. 662 */ 663 public Integer getMinLength() { 664 return minLength; 665 } 666 667 /** 668 * Bean property setter: <property>minLength</property>. 669 * 670 * <h5 class='section'>See Also:</h5> 671 * <ul> 672 * <li class='extlink'>{@doc JsonSchemaValidation} 673 * </ul> 674 * 675 * @param value 676 * The new value for this property. 677 * <br>Can be <jk>null</jk> to unset the property. 678 * @return This object (for method chaining). 679 */ 680 public Items setMinLength(Integer value) { 681 minLength = value; 682 return this; 683 } 684 685 /** 686 * Same as {@link #setMinLength(Integer)}. 687 * 688 * @param value 689 * The new value for this property. 690 * <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>. 691 * <br>Can be <jk>null</jk> to unset the property. 692 * @return This object (for method chaining). 693 */ 694 public Items minLength(Object value) { 695 return setMinLength(toInteger(value)); 696 } 697 698 /** 699 * Bean property getter: <property>pattern</property>. 700 * 701 * <h5 class='section'>See Also:</h5> 702 * <ul> 703 * <li class='extlink'>{@doc JsonSchemaValidation} 704 * </ul> 705 * 706 * @return The property value, or <jk>null</jk> if it is not set. 707 */ 708 public String getPattern() { 709 return pattern; 710 } 711 712 /** 713 * Bean property setter: <property>pattern</property>. 714 * 715 * <p> 716 * This string SHOULD be a valid regular expression. 717 * 718 * <h5 class='section'>See Also:</h5> 719 * <ul> 720 * <li class='extlink'>{@doc JsonSchemaValidation} 721 * </ul> 722 * 723 * @param value 724 * The new value for this property. 725 * <br>Can be <jk>null</jk> to unset the property. 726 * @return This object (for method chaining). 727 */ 728 public Items setPattern(String value) { 729 pattern = value; 730 return this; 731 } 732 733 /** 734 * Same as {@link #setPattern(String)}. 735 * 736 * @param value 737 * The new value for this property. 738 * <br>Non-String values will be converted to String using <code>toString()</code>. 739 * <br>Can be <jk>null</jk> to unset the property. 740 * @return This object (for method chaining). 741 */ 742 public Items pattern(Object value) { 743 return setPattern(toStringVal(value)); 744 } 745 746 /** 747 * Bean property getter: <property>maxItems</property>. 748 * 749 * <h5 class='section'>See Also:</h5> 750 * <ul> 751 * <li class='extlink'>{@doc JsonSchemaValidation} 752 * </ul> 753 * 754 * @return The property value, or <jk>null</jk> if it is not set. 755 */ 756 public Integer getMaxItems() { 757 return maxItems; 758 } 759 760 /** 761 * Bean property setter: <property>maxItems</property>. 762 * 763 * <h5 class='section'>See Also:</h5> 764 * <ul> 765 * <li class='extlink'>{@doc JsonSchemaValidation} 766 * </ul> 767 * 768 * @param value 769 * The new value for this property. 770 * <br>Can be <jk>null</jk> to unset the property. 771 * @return This object (for method chaining). 772 */ 773 public Items setMaxItems(Integer value) { 774 maxItems = value; 775 return this; 776 } 777 778 /** 779 * Same as {@link #setMaxItems(Integer)}. 780 * 781 * @param value 782 * The new value for this property. 783 * <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>. 784 * <br>Can be <jk>null</jk> to unset the property. 785 * @return This object (for method chaining). 786 */ 787 public Items maxItems(Object value) { 788 return setMaxItems(toInteger(value)); 789 } 790 791 /** 792 * Bean property getter: <property>minItems</property>. 793 * 794 * <h5 class='section'>See Also:</h5> 795 * <ul> 796 * <li class='extlink'>{@doc JsonSchemaValidation} 797 * </ul> 798 * 799 * @return The property value, or <jk>null</jk> if it is not set. 800 */ 801 public Integer getMinItems() { 802 return minItems; 803 } 804 805 /** 806 * Bean property setter: <property>minItems</property>. 807 * 808 * <h5 class='section'>See Also:</h5> 809 * <ul> 810 * <li class='extlink'>{@doc JsonSchemaValidation} 811 * </ul> 812 * 813 * @param value 814 * The new value for this property. 815 * <br>Can be <jk>null</jk> to unset the property. 816 * @return This object (for method chaining). 817 */ 818 public Items setMinItems(Integer value) { 819 minItems = value; 820 return this; 821 } 822 823 /** 824 * Same as {@link #setMinItems(Integer)}. 825 * 826 * @param value 827 * The new value for this property. 828 * <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>. 829 * <br>Can be <jk>null</jk> to unset the property. 830 * @return This object (for method chaining). 831 */ 832 public Items minItems(Object value) { 833 return setMinItems(toInteger(value)); 834 } 835 836 /** 837 * Bean property getter: <property>uniqueItems</property>. 838 * 839 * <h5 class='section'>See Also:</h5> 840 * <ul> 841 * <li class='extlink'>{@doc JsonSchemaValidation} 842 * </ul> 843 * 844 * @return The property value, or <jk>null</jk> if it is not set. 845 */ 846 public Boolean getUniqueItems() { 847 return uniqueItems; 848 } 849 850 /** 851 * Bean property setter: <property>uniqueItems</property>. 852 * 853 * <h5 class='section'>See Also:</h5> 854 * <ul> 855 * <li class='extlink'>{@doc JsonSchemaValidation} 856 * </ul> 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 (for method chaining). 862 */ 863 public Items setUniqueItems(Boolean value) { 864 uniqueItems = value; 865 return this; 866 } 867 868 /** 869 * Same as {@link #setUniqueItems(Boolean)}. 870 * 871 * @param value 872 * The new value for this property. 873 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 874 * <br>Can be <jk>null</jk> to unset the property. 875 * @return This object (for method chaining). 876 */ 877 public Items uniqueItems(Object value) { 878 return setUniqueItems(toBoolean(value)); 879 } 880 881 /** 882 * Bean property getter: <property>enum</property>. 883 * 884 * <h5 class='section'>See Also:</h5> 885 * <ul> 886 * <li class='extlink'>{@doc JsonSchemaValidation} 887 * </ul> 888 * 889 * @return The property value, or <jk>null</jk> if it is not set. 890 */ 891 public List<Object> getEnum() { 892 return _enum; 893 } 894 895 /** 896 * Bean property setter: <property>enum</property>. 897 * 898 * <h5 class='section'>See Also:</h5> 899 * <ul> 900 * <li class='extlink'>{@doc JsonSchemaValidation} 901 * </ul> 902 * 903 * @param value 904 * The new value for this property. 905 * <br>Can be <jk>null</jk> to unset the property. 906 * @return This object (for method chaining). 907 */ 908 public Items setEnum(Collection<Object> value) { 909 _enum = newList(value); 910 return this; 911 } 912 913 /** 914 * Adds one or more values to the <property>enum</property> property. 915 * 916 * @param values 917 * The values to add to this property. 918 * <br>Ignored if <jk>null</jk>. 919 * @return This object (for method chaining). 920 */ 921 public Items addEnum(Collection<Object> values) { 922 _enum = addToList(_enum, values); 923 return this; 924 } 925 926 /** 927 * Adds one or more values to the <property>enum</property> property. 928 * 929 * @param values 930 * The values to add to this property. 931 * <br>Valid types: 932 * <ul> 933 * <li><code>Object</code> 934 * <li><code>Collection<Object></code> 935 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 936 * <h5 class='figure'>Example:</h5> 937 * <p class='bcode w800'> 938 * _enum(<js>"['foo','bar']"</js>); 939 * </p> 940 * <li><code>String</code> - Individual values 941 * <h5 class='figure'>Example:</h5> 942 * <p class='bcode w800'> 943 * _enum(<js>"foo"</js>, <js>"bar"</js>); 944 * </p> 945 * </ul> 946 * <br>Ignored if <jk>null</jk>. 947 * @return This object (for method chaining). 948 */ 949 public Items _enum(Object...values) { 950 _enum = addToList(_enum, values, Object.class); 951 return this; 952 } 953 954 /** 955 * Bean property getter: <property>multipleOf</property>. 956 * 957 * <h5 class='section'>See Also:</h5> 958 * <ul> 959 * <li class='extlink'>{@doc JsonSchemaValidation} 960 * </ul> 961 * 962 * @return The property value, or <jk>null</jk> if it is not set. 963 */ 964 public Number getMultipleOf() { 965 return multipleOf; 966 } 967 968 /** 969 * Bean property setter: <property>multipleOf</property>. 970 * 971 * <h5 class='section'>See Also:</h5> 972 * <ul> 973 * <li class='extlink'>{@doc JsonSchemaValidation} 974 * </ul> 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 (for method chaining). 980 */ 981 public Items setMultipleOf(Number value) { 982 multipleOf = value; 983 return this; 984 } 985 986 /** 987 * Same as {@link #setMultipleOf(Number)}. 988 * 989 * @param value 990 * The new value for this property. 991 * <br>Non-Number values will be converted to Number using <code>toString()</code> then best number match. 992 * <br>Can be <jk>null</jk> to unset the property. 993 * @return This object (for method chaining). 994 */ 995 public Items multipleOf(Object value) { 996 return setMultipleOf(toNumber(value)); 997 } 998 999 /** 1000 * Bean property getter: <property>$ref</property>. 1001 * 1002 * @return The property value, or <jk>null</jk> if it is not set. 1003 */ 1004 @BeanProperty("$ref") 1005 public String getRef() { 1006 return ref; 1007 } 1008 1009 /** 1010 * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute. 1011 * 1012 * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute. 1013 */ 1014 public boolean hasRef() { 1015 return ref != null; 1016 } 1017 1018 /** 1019 * Bean property setter: <property>$ref</property>. 1020 * 1021 * @param value 1022 * The new value for this property. 1023 * <br>Can be <jk>null</jk> to unset the property. 1024 * @return This object (for method chaining). 1025 */ 1026 @BeanProperty("$ref") 1027 public Items setRef(Object value) { 1028 ref = StringUtils.asString(value); 1029 return this; 1030 } 1031 1032 /** 1033 * Same as {@link #setRef(Object)}. 1034 * 1035 * @param value 1036 * The new value for this property. 1037 * <br>Can be <jk>null</jk> to unset the property. 1038 * @return This object (for method chaining). 1039 */ 1040 public Items ref(Object value) { 1041 return setRef(value); 1042 } 1043 1044 @Override /* SwaggerElement */ 1045 public <T> T get(String property, Class<T> type) { 1046 if (property == null) 1047 return null; 1048 switch (property) { 1049 case "type": return toType(getType(), type); 1050 case "format": return toType(getFormat(), type); 1051 case "items": return toType(getItems(), type); 1052 case "collectionFormat": return toType(getCollectionFormat(), type); 1053 case "default": return toType(getDefault(), type); 1054 case "maximum": return toType(getMaximum(), type); 1055 case "exclusiveMaximum": return toType(getExclusiveMaximum(), type); 1056 case "minimum": return toType(getMinimum(), type); 1057 case "exclusiveMinimum": return toType(getExclusiveMinimum(), type); 1058 case "maxLength": return toType(getMaxLength(), type); 1059 case "minLength": return toType(getMinLength(), type); 1060 case "pattern": return toType(getPattern(), type); 1061 case "maxItems": return toType(getMaxItems(), type); 1062 case "minItems": return toType(getMinItems(), type); 1063 case "uniqueItems": return toType(getUniqueItems(), type); 1064 case "enum": return toType(getEnum(), type); 1065 case "multipleOf": return toType(getMultipleOf(), type); 1066 case "$ref": return toType(getRef(), type); 1067 default: return super.get(property, type); 1068 } 1069 } 1070 1071 @Override /* SwaggerElement */ 1072 public Items set(String property, Object value) { 1073 if (property == null) 1074 return this; 1075 switch (property) { 1076 case "type": return type(value); 1077 case "format": return format(value); 1078 case "items": return items(value); 1079 case "collectionFormat": return collectionFormat(value); 1080 case "default": return _default(value); 1081 case "maximum": return maximum(value); 1082 case "exclusiveMaximum": return exclusiveMaximum(value); 1083 case "minimum": return minimum(value); 1084 case "exclusiveMinimum": return exclusiveMinimum(value); 1085 case "maxLength": return maxLength(value); 1086 case "minLength": return minLength(value); 1087 case "pattern": return pattern(value); 1088 case "maxItems": return maxItems(value); 1089 case "minItems": return minItems(value); 1090 case "uniqueItems": return uniqueItems(value); 1091 case "enum": return setEnum(null)._enum(value); 1092 case "multipleOf": return multipleOf(value); 1093 case "$ref": return ref(value); 1094 default: 1095 super.set(property, value); 1096 return this; 1097 } 1098 } 1099 1100 @Override /* SwaggerElement */ 1101 public Set<String> keySet() { 1102 ASet<String> s = new ASet<String>() 1103 .appendIf(type != null, "type") 1104 .appendIf(format != null, "format") 1105 .appendIf(items != null, "items") 1106 .appendIf(collectionFormat != null, "collectionFormat") 1107 .appendIf(_default != null, "default") 1108 .appendIf(maximum != null, "maximum") 1109 .appendIf(exclusiveMaximum != null, "exclusiveMaximum") 1110 .appendIf(minimum != null, "minimum") 1111 .appendIf(exclusiveMinimum != null, "exclusiveMinimum") 1112 .appendIf(maxLength != null, "maxLength") 1113 .appendIf(minLength != null, "minLength") 1114 .appendIf(pattern != null, "pattern") 1115 .appendIf(maxItems != null, "maxItems") 1116 .appendIf(minItems != null, "minItems") 1117 .appendIf(uniqueItems != null, "uniqueItems") 1118 .appendIf(_enum != null, "enum") 1119 .appendIf(multipleOf != null, "multipleOf") 1120 .appendIf(ref != null, "$ref"); 1121 return new MultiSet<>(s, super.keySet()); 1122 } 1123 1124 /** 1125 * Resolves any <js>"$ref"</js> attributes in this element. 1126 * 1127 * @param swagger The swagger document containing the definitions. 1128 * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops. 1129 * @param maxDepth 1130 * The maximum depth to resolve references. 1131 * <br>After that level is reached, <code>$ref</code> references will be left alone. 1132 * <br>Useful if you have very complex models and you don't want your swagger page to be overly-complex. 1133 * @return 1134 * This object with references resolved. 1135 * <br>May or may not be the same object. 1136 */ 1137 public Items resolveRefs(Swagger swagger, Deque<String> refStack, int maxDepth) { 1138 1139 if (ref != null) { 1140 if (refStack.contains(ref) || refStack.size() >= maxDepth) 1141 return this; 1142 refStack.addLast(ref); 1143 Items r = swagger.findRef(ref, Items.class).resolveRefs(swagger, refStack, maxDepth); 1144 refStack.removeLast(); 1145 return r; 1146 } 1147 1148 set("properties", resolveRefs(get("properties"), swagger, refStack, maxDepth)); 1149 1150 if (items != null) 1151 items = items.resolveRefs(swagger, refStack, maxDepth); 1152 1153 set("example", null); 1154 1155 return this; 1156 } 1157 1158 /* Resolve references in extra attributes */ 1159 private Object resolveRefs(Object o, Swagger swagger, Deque<String> refStack, int maxDepth) { 1160 if (o instanceof ObjectMap) { 1161 ObjectMap om = (ObjectMap)o; 1162 Object ref = om.get("$ref"); 1163 if (ref instanceof CharSequence) { 1164 String sref = ref.toString(); 1165 if (refStack.contains(sref) || refStack.size() >= maxDepth) 1166 return o; 1167 refStack.addLast(sref); 1168 Object o2 = swagger.findRef(sref, Object.class); 1169 o2 = resolveRefs(o2, swagger, refStack, maxDepth); 1170 refStack.removeLast(); 1171 return o2; 1172 } 1173 for (Map.Entry<String,Object> e : om.entrySet()) 1174 e.setValue(resolveRefs(e.getValue(), swagger, refStack, maxDepth)); 1175 } 1176 if (o instanceof ObjectList) 1177 for (ListIterator<Object> li = ((ObjectList)o).listIterator(); li.hasNext();) 1178 li.set(resolveRefs(li.next(), swagger, refStack, maxDepth)); 1179 return o; 1180 } 1181}