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