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.swagger; 018 019import static org.apache.juneau.common.utils.Utils.*; 020import static org.apache.juneau.internal.CollectionUtils.*; 021import static org.apache.juneau.internal.ConverterUtils.*; 022 023import java.util.*; 024 025import org.apache.juneau.*; 026import org.apache.juneau.annotation.*; 027import org.apache.juneau.common.utils.*; 028import org.apache.juneau.internal.*; 029import org.apache.juneau.marshaller.*; 030 031/** 032 * A limited subset of JSON-Schema's items object. 033 * 034 * <p> 035 * The Items Object is a limited subset of JSON-Schema's items object for Swagger 2.0. It is used by parameter 036 * definitions that are not located in "body" to describe the type of items in an array. This is particularly useful 037 * for query parameters, path parameters, and header parameters that accept arrays. 038 * 039 * <h5 class='section'>Swagger Specification:</h5> 040 * <p> 041 * The Items Object supports the following fields from JSON Schema: 042 * <ul class='spaced-list'> 043 * <li><c>type</c> (string, REQUIRED) - The data type. Values: <js>"string"</js>, <js>"number"</js>, <js>"integer"</js>, <js>"boolean"</js>, <js>"array"</js> 044 * <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>) 045 * <li><c>items</c> ({@link Items}) - Required if type is <js>"array"</js>. Describes the type of items in the array 046 * <li><c>collectionFormat</c> (string) - How multiple values are formatted. Values: <js>"csv"</js>, <js>"ssv"</js>, <js>"tsv"</js>, <js>"pipes"</js>, <js>"multi"</js> 047 * <li><c>default</c> (any) - The default value 048 * <li><c>maximum</c> (number), <c>exclusiveMaximum</c> (boolean), <c>minimum</c> (number), <c>exclusiveMinimum</c> (boolean) - Numeric constraints 049 * <li><c>maxLength</c> (integer), <c>minLength</c> (integer), <c>pattern</c> (string) - String constraints 050 * <li><c>maxItems</c> (integer), <c>minItems</c> (integer), <c>uniqueItems</c> (boolean) - Array constraints 051 * <li><c>enum</c> (array) - Possible values for this item 052 * <li><c>multipleOf</c> (number) - Must be a multiple of this value 053 * </ul> 054 * 055 * <h5 class='section'>Example:</h5> 056 * <p class='bjava'> 057 * <jc>// Construct using SwaggerBuilder.</jc> 058 * Items <jv>items</jv> = <jsm>items</jsm>(<js>"string"</js>).minLength(2); 059 * 060 * <jc>// Serialize using JsonSerializer.</jc> 061 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>items</jv>); 062 * 063 * <jc>// Or just use toString() which does the same as above.</jc> 064 * <jv>json</jv> = <jv>items</jv>.toString(); 065 * </p> 066 * <p class='bjson'> 067 * <jc>// Output</jc> 068 * { 069 * <js>"type"</js>: <js>"string"</js>, 070 * <js>"minLength"</js>: 2 071 * } 072 * </p> 073 * 074 * <h5 class='section'>See Also:</h5><ul> 075 * <li class='link'><a class="doclink" href="https://swagger.io/specification/v2/#items-object">Swagger 2.0 Specification > Items Object</a> 076 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/2-0/describing-parameters/">Swagger Describing Parameters</a> 077 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a> 078 * </ul> 079 */ 080public class Items extends SwaggerElement { 081 082 private static final String[] VALID_TYPES = {"string", "number", "integer", "boolean", "array"}; 083 private static final String[] VALID_COLLECTION_FORMATS = {"csv","ssv","tsv","pipes","multi"}; 084 085 private String 086 type, 087 format, 088 collectionFormat, 089 pattern, 090 ref; 091 private Number 092 maximum, 093 minimum, 094 multipleOf; 095 private Integer 096 maxLength, 097 minLength, 098 maxItems, 099 minItems; 100 private Boolean 101 exclusiveMaximum, 102 exclusiveMinimum, 103 uniqueItems; 104 private Items items; // NOSONAR - Intentional naming. 105 private Object _default; // NOSONAR - Intentional naming. 106 private Set<Object> _enum; // NOSONAR - Intentional naming. 107 108 /** 109 * Default constructor. 110 */ 111 public Items() {} 112 113 /** 114 * Copy constructor. 115 * 116 * @param copyFrom The object to copy. 117 */ 118 public Items(Items copyFrom) { 119 super(copyFrom); 120 121 this.collectionFormat = copyFrom.collectionFormat; 122 this._default = copyFrom._default; 123 this._enum = copyOf(copyFrom._enum); 124 this.exclusiveMaximum = copyFrom.exclusiveMaximum; 125 this.exclusiveMinimum = copyFrom.exclusiveMinimum; 126 this.format = copyFrom.format; 127 this.items = copyFrom.items == null ? null : copyFrom.items.copy(); 128 this.maximum = copyFrom.maximum; 129 this.maxItems = copyFrom.maxItems; 130 this.maxLength = copyFrom.maxLength; 131 this.minimum = copyFrom.minimum; 132 this.minItems = copyFrom.minItems; 133 this.minLength = copyFrom.minLength; 134 this.multipleOf = copyFrom.multipleOf; 135 this.pattern = copyFrom.pattern; 136 this.ref = copyFrom.ref; 137 this.type = copyFrom.type; 138 this.uniqueItems = copyFrom.uniqueItems; 139 } 140 141 /** 142 * Make a deep copy of this object. 143 * 144 * @return A deep copy of this object. 145 */ 146 public Items copy() { 147 return new Items(this); 148 } 149 150 @Override /* Overridden from SwaggerElement */ 151 public Items strict() { 152 super.strict(); 153 return this; 154 } 155 156 /** 157 * Sets strict mode on this bean. 158 * 159 * @param value 160 * The new value for this property. 161 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 162 * <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>). 163 * @return This object. 164 */ 165 @Override 166 public Items strict(Object value) { 167 super.strict(value); 168 return this; 169 } 170 171 //----------------------------------------------------------------------------------------------------------------- 172 // Properties 173 //----------------------------------------------------------------------------------------------------------------- 174 175 /** 176 * Bean property getter: <property>collectionFormat</property>. 177 * 178 * <p> 179 * Determines the format of the array if type array is used. 180 * 181 * @return The property value, or <jk>null</jk> if it is not set. 182 */ 183 public String getCollectionFormat() { 184 return collectionFormat; 185 } 186 187 /** 188 * Bean property setter: <property>collectionFormat</property>. 189 * 190 * <p> 191 * Determines the format of the array if type array is used. 192 * 193 * @param value 194 * The new value for this property. 195 * <br>Valid values: 196 * <ul> 197 * <li><js>"csv"</js> (default) - comma separated values <c>foo,bar</c>. 198 * <li><js>"ssv"</js> - space separated values <c>foo bar</c>. 199 * <li><js>"tsv"</js> - tab separated values <c>foo\tbar</c>. 200 * <li><js>"pipes"</js> - pipe separated values <c>foo|bar</c>. 201 * </ul> 202 * <br>Can be <jk>null</jk> to unset the property. 203 * @return This object. 204 */ 205 public Items setCollectionFormat(String value) { 206 if (isStrict() && ! ArrayUtils.contains(value, VALID_COLLECTION_FORMATS)) 207 throw new BasicRuntimeException( 208 "Invalid value passed in to setCollectionFormat(String). Value=''{0}'', valid values={1}", 209 value, Json5.of(VALID_COLLECTION_FORMATS) 210 ); 211 collectionFormat = value; 212 return this; 213 } 214 215 /** 216 * Bean property getter: <property>default</property>. 217 * 218 * <p> 219 * Declares the value of the item that the server will use if none is provided. 220 * 221 * <h5 class='section'>Notes:</h5><ul> 222 * <li class='note'> 223 * <js>"default"</js> has no meaning for required items. 224 * <li class='note'> 225 * Unlike JSON Schema this value MUST conform to the defined <c>type</c> for the data type. 226 * </ul> 227 * 228 * @return The property value, or <jk>null</jk> if it is not set. 229 */ 230 public Object getDefault() { 231 return _default; 232 } 233 234 /** 235 * Bean property setter: <property>default</property>. 236 * 237 * <p> 238 * Declares the value of the item that the server will use if none is provided. 239 * 240 * <h5 class='section'>Notes:</h5><ul> 241 * <li class='note'> 242 * <js>"default"</js> has no meaning for required items. 243 * <li class='note'> 244 * Unlike JSON Schema this value MUST conform to the defined <c>type</c> for the data type. 245 * </ul> 246 * 247 * @param value 248 * The new value for this property. 249 * <br>Can be <jk>null</jk> to unset the property. 250 * @return This object. 251 */ 252 public Items setDefault(Object value) { 253 _default = value; 254 return this; 255 } 256 257 /** 258 * Bean property getter: <property>enum</property>. 259 * 260 * @return The property value, or <jk>null</jk> if it is not set. 261 */ 262 public Set<Object> getEnum() { 263 return _enum; 264 } 265 266 /** 267 * Bean property setter: <property>enum</property>. 268 * 269 * @param value 270 * The new value for this property. 271 * <br>Can be <jk>null</jk> to unset the property. 272 * @return This object. 273 */ 274 public Items setEnum(Collection<Object> value) { 275 _enum = setFrom(value); 276 return this; 277 } 278 279 /** 280 * Bean property setter: <property>enum</property>. 281 * 282 * @param value 283 * The new value for this property. 284 * <br>Can be <jk>null</jk> to unset the property. 285 * @return This object. 286 */ 287 public Items setEnum(Object...value) { 288 return setEnum(Arrays.asList(value)); 289 } 290 291 /** 292 * Bean property fluent setter: <property>enum</property>. 293 * 294 * @param value 295 * The new value for this property. 296 * <br>String values can be JSON arrays. 297 * @return This object. 298 */ 299 public Items addEnum(Object...value) { 300 setEnum(setBuilder(_enum).sparse().add(value).build()); 301 return this; 302 } 303 304 /** 305 * Bean property getter: <property>exclusiveMaximum</property>. 306 * 307 * @return The property value, or <jk>null</jk> if it is not set. 308 */ 309 public Boolean getExclusiveMaximum() { 310 return exclusiveMaximum; 311 } 312 313 /** 314 * Bean property setter: <property>exclusiveMaximum</property>. 315 * 316 * @param value 317 * The new value for this property. 318 * <br>Can be <jk>null</jk> to unset the property. 319 * @return This object. 320 */ 321 public Items setExclusiveMaximum(Boolean value) { 322 exclusiveMaximum = value; 323 return this; 324 } 325 326 /** 327 * Bean property getter: <property>exclusiveMinimum</property>. 328 * 329 * @return The property value, or <jk>null</jk> if it is not set. 330 */ 331 public Boolean getExclusiveMinimum() { 332 return exclusiveMinimum; 333 } 334 335 /** 336 * Bean property setter: <property>exclusiveMinimum</property>. 337 * 338 * @param value 339 * The new value for this property. 340 * <br>Can be <jk>null</jk> to unset the property. 341 * @return This object. 342 */ 343 public Items setExclusiveMinimum(Boolean value) { 344 exclusiveMinimum = value; 345 return this; 346 } 347 348 /** 349 * Bean property getter: <property>format</property>. 350 * 351 * <p> 352 * The extending format for the previously mentioned <c>type</c>. 353 * 354 * @return The property value, or <jk>null</jk> if it is not set. 355 */ 356 public String getFormat() { 357 return format; 358 } 359 360 /** 361 * Bean property setter: <property>format</property>. 362 * 363 * <p> 364 * The extending format for the previously mentioned <c>type</c>. 365 * 366 * @param value 367 * The new value for this property. 368 * <br>Can be <jk>null</jk> to unset the property. 369 * @return This object. 370 */ 371 public Items setFormat(String value) { 372 format = value; 373 return this; 374 } 375 376 /** 377 * Bean property getter: <property>items</property>. 378 * 379 * <p> 380 * Describes the type of items in the array. 381 * 382 * @return The property value, or <jk>null</jk> if it is not set. 383 */ 384 public Items getItems() { 385 return items; 386 } 387 388 /** 389 * Bean property setter: <property>items</property>. 390 * 391 * <p> 392 * Describes the type of items in the array. 393 * 394 * @param value 395 * The new value for this property. 396 * <br>Property value is required if <c>type</c> is <js>"array"</js>. 397 * <br>Can be <jk>null</jk> to unset the property. 398 * @return This object. 399 */ 400 public Items setItems(Items value) { 401 items = value; 402 return this; 403 } 404 405 /** 406 * Bean property getter: <property>maximum</property>. 407 * 408 * @return The property value, or <jk>null</jk> if it is not set. 409 */ 410 public Number getMaximum() { 411 return maximum; 412 } 413 414 /** 415 * Bean property setter: <property>maximum</property>. 416 * 417 * @param value 418 * The new value for this property. 419 * <br>Can be <jk>null</jk> to unset the property. 420 * @return This object. 421 */ 422 public Items setMaximum(Number value) { 423 maximum = value; 424 return this; 425 } 426 427 /** 428 * Bean property getter: <property>maxItems</property>. 429 * 430 * @return The property value, or <jk>null</jk> if it is not set. 431 */ 432 public Integer getMaxItems() { 433 return maxItems; 434 } 435 436 /** 437 * Bean property setter: <property>maxItems</property>. 438 * 439 * @param value 440 * The new value for this property. 441 * <br>Can be <jk>null</jk> to unset the property. 442 * @return This object. 443 */ 444 public Items setMaxItems(Integer value) { 445 maxItems = value; 446 return this; 447 } 448 449 //----------------------------------------------------------------------------------------------------------------- 450 // maxLength 451 //----------------------------------------------------------------------------------------------------------------- 452 453 /** 454 * Bean property getter: <property>maxLength</property>. 455 * 456 * @return The property value, or <jk>null</jk> if it is not set. 457 */ 458 public Integer getMaxLength() { 459 return maxLength; 460 } 461 462 /** 463 * Bean property setter: <property>maxLength</property>. 464 * 465 * @param value 466 * The new value for this property. 467 * <br>Can be <jk>null</jk> to unset the property. 468 * @return This object. 469 */ 470 public Items setMaxLength(Integer value) { 471 maxLength = value; 472 return this; 473 } 474 475 /** 476 * Bean property getter: <property>minimum</property>. 477 * 478 * @return The property value, or <jk>null</jk> if it is not set. 479 */ 480 public Number getMinimum() { 481 return minimum; 482 } 483 484 /** 485 * Bean property setter: <property>minimum</property>. 486 * 487 * @param value 488 * The new value for this property. 489 * <br>Can be <jk>null</jk> to unset the property. 490 * @return This object. 491 */ 492 public Items setMinimum(Number value) { 493 minimum = value; 494 return this; 495 } 496 497 /** 498 * Bean property getter: <property>minItems</property>. 499 * 500 * @return The property value, or <jk>null</jk> if it is not set. 501 */ 502 public Integer getMinItems() { 503 return minItems; 504 } 505 506 /** 507 * Bean property setter: <property>minItems</property>. 508 * 509 * @param value 510 * The new value for this property. 511 * <br>Can be <jk>null</jk> to unset the property. 512 * @return This object. 513 */ 514 public Items setMinItems(Integer value) { 515 minItems = value; 516 return this; 517 } 518 519 /** 520 * Bean property getter: <property>minLength</property>. 521 * 522 * @return The property value, or <jk>null</jk> if it is not set. 523 */ 524 public Integer getMinLength() { 525 return minLength; 526 } 527 528 /** 529 * Bean property setter: <property>minLength</property>. 530 * 531 * @param value 532 * The new value for this property. 533 * <br>Can be <jk>null</jk> to unset the property. 534 * @return This object. 535 */ 536 public Items setMinLength(Integer value) { 537 minLength = value; 538 return this; 539 } 540 541 /** 542 * Bean property getter: <property>multipleOf</property>. 543 * 544 * @return The property value, or <jk>null</jk> if it is not set. 545 */ 546 public Number getMultipleOf() { 547 return multipleOf; 548 } 549 550 /** 551 * Bean property setter: <property>multipleOf</property>. 552 * 553 * @param value 554 * The new value for this property. 555 * <br>Can be <jk>null</jk> to unset the property. 556 * @return This object. 557 */ 558 public Items setMultipleOf(Number value) { 559 multipleOf = value; 560 return this; 561 } 562 563 /** 564 * Bean property getter: <property>pattern</property>. 565 * 566 * @return The property value, or <jk>null</jk> if it is not set. 567 */ 568 public String getPattern() { 569 return pattern; 570 } 571 572 /** 573 * Bean property setter: <property>pattern</property>. 574 * 575 * @param value 576 * The new value for this property. 577 * <br>This string SHOULD be a valid regular expression. 578 * <br>Can be <jk>null</jk> to unset the property. 579 * @return This object. 580 */ 581 public Items setPattern(String value) { 582 pattern = value; 583 return this; 584 } 585 586 /** 587 * Bean property getter: <property>$ref</property>. 588 * 589 * @return The property value, or <jk>null</jk> if it is not set. 590 */ 591 @Beanp("$ref") 592 public String getRef() { 593 return ref; 594 } 595 596 /** 597 * Bean property setter: <property>$ref</property>. 598 * 599 * @param value 600 * The new value for this property. 601 * <br>Can be <jk>null</jk> to unset the property. 602 * @return This object. 603 */ 604 @Beanp("$ref") 605 public Items setRef(String value) { 606 ref = value; 607 return this; 608 } 609 610 /** 611 * Bean property getter: <property>type</property>. 612 * 613 * <p> 614 * The internal type of the array. 615 * 616 * @return The property value, or <jk>null</jk> if it is not set. 617 */ 618 public String getType() { 619 return type; 620 } 621 622 /** 623 * Bean property setter: <property>type</property>. 624 * 625 * <p> 626 * The internal type of the array. 627 * 628 * @param value 629 * The new value for this property. 630 * <br>Valid values: 631 * <ul> 632 * <li><js>"string"</js> 633 * <li><js>"number"</js> 634 * <li><js>"integer"</js> 635 * <li><js>"boolean"</js> 636 * <li><js>"array"</js> 637 * </ul> 638 * <br>Property value is required. 639 * <br>Can be <jk>null</jk> to unset the property. 640 * @return This object. 641 */ 642 public Items setType(String value) { 643 if (isStrict() && ! ArrayUtils.contains(value, VALID_TYPES)) 644 throw new BasicRuntimeException("Invalid value passed in to setType(String). Value=''{0}'', valid values={1}", value, Json5.of(VALID_TYPES)); 645 type = value; 646 return this; 647 } 648 649 /** 650 * Bean property getter: <property>uniqueItems</property>. 651 * 652 * @return The property value, or <jk>null</jk> if it is not set. 653 */ 654 public Boolean getUniqueItems() { 655 return uniqueItems; 656 } 657 658 /** 659 * Bean property setter: <property>uniqueItems</property>. 660 * 661 * @param value 662 * The new value for this property. 663 * <br>Can be <jk>null</jk> to unset the property. 664 * @return This object. 665 */ 666 public Items setUniqueItems(Boolean value) { 667 uniqueItems = value; 668 return this; 669 } 670 671 @Override /* Overridden from SwaggerElement */ 672 public <T> T get(String property, Class<T> type) { 673 assertArgNotNull("property", property); 674 return switch (property) { 675 case "collectionFormat" -> toType(getCollectionFormat(), type); 676 case "default" -> toType(getDefault(), type); 677 case "enum" -> toType(getEnum(), type); 678 case "exclusiveMaximum" -> toType(getExclusiveMaximum(), type); 679 case "exclusiveMinimum" -> toType(getExclusiveMinimum(), type); 680 case "format" -> toType(getFormat(), type); 681 case "items" -> toType(getItems(), type); 682 case "maximum" -> toType(getMaximum(), type); 683 case "maxItems" -> toType(getMaxItems(), type); 684 case "maxLength" -> toType(getMaxLength(), type); 685 case "minimum" -> toType(getMinimum(), type); 686 case "minItems" -> toType(getMinItems(), type); 687 case "minLength" -> toType(getMinLength(), type); 688 case "multipleOf" -> toType(getMultipleOf(), type); 689 case "pattern" -> toType(getPattern(), type); 690 case "$ref" -> toType(getRef(), type); 691 case "type" -> toType(getType(), type); 692 case "uniqueItems" -> toType(getUniqueItems(), type); 693 default -> super.get(property, type); 694 }; 695 } 696 697 @Override /* Overridden from SwaggerElement */ 698 public Items set(String property, Object value) { 699 assertArgNotNull("property", property); 700 return switch (property) { 701 case "collectionFormat" -> setCollectionFormat(Utils.s(value)); 702 case "default" -> setDefault(value); 703 case "enum" -> setEnum(listBuilder(Object.class).sparse().addAny(value).build()); 704 case "exclusiveMaximum" -> setExclusiveMaximum(toBoolean(value)); 705 case "exclusiveMinimum" -> setExclusiveMinimum(toBoolean(value)); 706 case "format" -> setFormat(Utils.s(value)); 707 case "items" -> setItems(toType(value,Items.class)); 708 case "maximum" -> setMaximum(toNumber(value)); 709 case "maxItems" -> setMaxItems(toInteger(value)); 710 case "maxLength" -> setMaxLength(toInteger(value)); 711 case "minimum" -> setMinimum(toNumber(value)); 712 case "minItems" -> setMinItems(toInteger(value)); 713 case "minLength" -> setMinLength(toInteger(value)); 714 case "multipleOf" -> setMultipleOf(toNumber(value)); 715 case "pattern" -> setPattern(Utils.s(value)); 716 case "$ref" -> setRef(Utils.s(value)); 717 case "type" -> setType(Utils.s(value)); 718 case "uniqueItems" -> setUniqueItems(toBoolean(value)); 719 default -> { 720 super.set(property, value); 721 yield this; 722 } 723 }; 724 } 725 726 @Override /* Overridden from SwaggerElement */ 727 public Set<String> keySet() { 728 var s = setBuilder(String.class) 729 .addIf(collectionFormat != null, "collectionFormat") 730 .addIf(_default != null, "default") 731 .addIf(_enum != null, "enum") 732 .addIf(exclusiveMaximum != null, "exclusiveMaximum") 733 .addIf(exclusiveMinimum != null, "exclusiveMinimum") 734 .addIf(format != null, "format") 735 .addIf(items != null, "items") 736 .addIf(maximum != null, "maximum") 737 .addIf(maxItems != null, "maxItems") 738 .addIf(maxLength != null, "maxLength") 739 .addIf(minimum != null, "minimum") 740 .addIf(minItems != null, "minItems") 741 .addIf(minLength != null, "minLength") 742 .addIf(multipleOf != null, "multipleOf") 743 .addIf(pattern != null, "pattern") 744 .addIf(ref != null, "$ref") 745 .addIf(type != null, "type") 746 .addIf(uniqueItems != null, "uniqueItems") 747 .build(); 748 return new MultiSet<>(s, super.keySet()); 749 } 750 751 /** 752 * Resolves any <js>"$ref"</js> attributes in this element. 753 * 754 * @param swagger The swagger document containing the definitions. 755 * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops. 756 * @param maxDepth 757 * The maximum depth to resolve references. 758 * <br>After that level is reached, <c>$ref</c> references will be left alone. 759 * <br>Useful if you have very complex models and you don't want your swagger page to be overly-complex. 760 * @return 761 * This object with references resolved. 762 * <br>May or may not be the same object. 763 */ 764 public Items resolveRefs(Swagger swagger, Deque<String> refStack, int maxDepth) { 765 766 if (ref != null) { 767 if (refStack.contains(ref) || refStack.size() >= maxDepth) 768 return this; 769 refStack.addLast(ref); 770 Items r = swagger.findRef(ref, Items.class).resolveRefs(swagger, refStack, maxDepth); 771 refStack.removeLast(); 772 return r; 773 } 774 775 if (items != null) 776 items = items.resolveRefs(swagger, refStack, maxDepth); 777 778 return this; 779 } 780}