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.httppart; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.lang.annotation.*; 018import java.lang.reflect.*; 019import java.util.*; 020import java.util.regex.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.http.annotation.*; 024import org.apache.juneau.httppart.HttpPartSchema.*; 025import org.apache.juneau.httppart.HttpPartSchema.Type; 026import org.apache.juneau.internal.*; 027import org.apache.juneau.utils.*; 028 029/** 030 * The builder class for creating {@link HttpPartSchema} objects. 031 * 032 */ 033public class HttpPartSchemaBuilder { 034 String name, _default; 035 Set<Integer> codes; 036 Set<String> _enum; 037 Boolean allowEmptyValue, exclusiveMaximum, exclusiveMinimum, required, uniqueItems, skipIfEmpty; 038 CollectionFormat collectionFormat = CollectionFormat.NO_COLLECTION_FORMAT; 039 Type type = Type.NO_TYPE; 040 Format format = Format.NO_FORMAT; 041 Pattern pattern; 042 Number maximum, minimum, multipleOf; 043 Long maxLength, minLength, maxItems, minItems, maxProperties, minProperties; 044 Map<String,HttpPartSchemaBuilder> properties; 045 HttpPartSchemaBuilder items, additionalProperties; 046 boolean noValidate; 047 Class<? extends HttpPartParser> parser; 048 Class<? extends HttpPartSerializer> serializer; 049 050 /** 051 * Instantiates a new {@link HttpPartSchema} object based on the configuration of this builder. 052 * 053 * <p> 054 * This method can be called multiple times to produce new schema objects. 055 * 056 * @return 057 * A new {@link HttpPartSchema} object. 058 * <br>Never <jk>null</jk>. 059 */ 060 public HttpPartSchema build() { 061 return new HttpPartSchema(this); 062 } 063 064 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, Method m, int index) { 065 apply(c, m.getGenericParameterTypes()[index]); 066 for (Annotation a : m.getParameterAnnotations()[index]) 067 if (c.isInstance(a)) 068 apply(a); 069 return this; 070 } 071 072 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, Method m) { 073 apply(c, m.getGenericReturnType()); 074 Annotation a = m.getAnnotation(c); 075 if (a != null) 076 return apply(a); 077 return this; 078 } 079 080 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, java.lang.reflect.Type t) { 081 if (t instanceof Class<?>) { 082 Class<?> tc = (Class<?>)t; 083 for (Annotation a : ClassUtils.getAnnotationsParentFirst(c, tc)) 084 apply(a); 085 } else if (Value.isType(t)) { 086 apply(c, Value.getParameterType(t)); 087 } 088 return this; 089 } 090 091 /** 092 * Apply the specified annotation to this schema. 093 * 094 * @param a The annotation to apply. 095 * @return This object (for method chaining). 096 */ 097 public HttpPartSchemaBuilder apply(Annotation a) { 098 if (a instanceof Body) 099 apply((Body)a); 100 else if (a instanceof Header) 101 apply((Header)a); 102 else if (a instanceof FormData) 103 apply((FormData)a); 104 else if (a instanceof Query) 105 apply((Query)a); 106 else if (a instanceof Path) 107 apply((Path)a); 108 else if (a instanceof Response) 109 apply((Response)a); 110 else if (a instanceof ResponseHeader) 111 apply((ResponseHeader)a); 112 else if (a instanceof HasQuery) 113 apply((HasQuery)a); 114 else if (a instanceof HasFormData) 115 apply((HasFormData)a); 116 else if (a instanceof Schema) 117 apply((Schema)a); 118 else 119 throw new RuntimeException("HttpPartSchemaBuilder.apply(@"+a.getClass().getSimpleName()+") not defined"); 120 return this; 121 } 122 123 HttpPartSchemaBuilder apply(Body a) { 124 required(a.required()); 125 allowEmptyValue(! a.required()); 126 apply(a.schema()); 127 return this; 128 } 129 130 HttpPartSchemaBuilder apply(Header a) { 131 name(a.value()); 132 name(a.name()); 133 required(a.required()); 134 type(a.type()); 135 format(a.format()); 136 allowEmptyValue(a.allowEmptyValue()); 137 items(a.items()); 138 collectionFormat(a.collectionFormat()); 139 _default(a._default().length == 0 ? null : joinnl(a._default())); 140 maximum(HttpPartSchema.toNumber(a.maximum())); 141 exclusiveMaximum(a.exclusiveMaximum()); 142 minimum(HttpPartSchema.toNumber(a.minimum())); 143 exclusiveMinimum(a.exclusiveMinimum()); 144 maxLength(a.maxLength()); 145 minLength(a.minLength()); 146 pattern(a.pattern()); 147 maxItems(a.maxItems()); 148 minItems(a.minItems()); 149 uniqueItems(a.uniqueItems()); 150 _enum(HttpPartSchema.toSet(a._enum())); 151 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 152 skipIfEmpty(a.skipIfEmpty()); 153 parser(a.parser()); 154 serializer(a.serializer()); 155 return this; 156 } 157 158 HttpPartSchemaBuilder apply(ResponseHeader a) { 159 name(a.value()); 160 name(a.name()); 161 codes(a.code()); 162 type(a.type()); 163 format(a.format()); 164 items(a.items()); 165 collectionFormat(a.collectionFormat()); 166 _default(a._default().length == 0 ? null : joinnl(a._default())); 167 maximum(HttpPartSchema.toNumber(a.maximum())); 168 exclusiveMaximum(a.exclusiveMaximum()); 169 minimum(HttpPartSchema.toNumber(a.minimum())); 170 exclusiveMinimum(a.exclusiveMinimum()); 171 maxLength(a.maxLength()); 172 minLength(a.minLength()); 173 pattern(a.pattern()); 174 maxItems(a.maxItems()); 175 minItems(a.minItems()); 176 uniqueItems(a.uniqueItems()); 177 _enum(HttpPartSchema.toSet(a._enum())); 178 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 179 allowEmptyValue(false); 180 serializer(a.serializer()); 181 return this; 182 } 183 184 HttpPartSchemaBuilder apply(FormData a) { 185 name(a.value()); 186 name(a.name()); 187 required(a.required()); 188 type(a.type()); 189 format(a.format()); 190 allowEmptyValue(a.allowEmptyValue()); 191 items(a.items()); 192 collectionFormat(a.collectionFormat()); 193 _default(a._default().length == 0 ? null : joinnl(a._default())); 194 maximum(HttpPartSchema.toNumber(a.maximum())); 195 exclusiveMaximum(a.exclusiveMaximum()); 196 minimum(HttpPartSchema.toNumber(a.minimum())); 197 exclusiveMinimum(a.exclusiveMinimum()); 198 maxLength(a.maxLength()); 199 minLength(a.minLength()); 200 pattern(a.pattern()); 201 maxItems(a.maxItems()); 202 minItems(a.minItems()); 203 uniqueItems(a.uniqueItems()); 204 _enum(HttpPartSchema.toSet(a._enum())); 205 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 206 skipIfEmpty(a.skipIfEmpty()); 207 parser(a.parser()); 208 serializer(a.serializer()); 209 return this; 210 } 211 212 HttpPartSchemaBuilder apply(Query a) { 213 name(a.value()); 214 name(a.name()); 215 required(a.required()); 216 type(a.type()); 217 format(a.format()); 218 allowEmptyValue(a.allowEmptyValue()); 219 items(a.items()); 220 collectionFormat(a.collectionFormat()); 221 _default(a._default().length == 0 ? null : joinnl(a._default())); 222 maximum(HttpPartSchema.toNumber(a.maximum())); 223 exclusiveMaximum(a.exclusiveMaximum()); 224 minimum(HttpPartSchema.toNumber(a.minimum())); 225 exclusiveMinimum(a.exclusiveMinimum()); 226 maxLength(a.maxLength()); 227 minLength(a.minLength()); 228 pattern(a.pattern()); 229 maxItems(a.maxItems()); 230 minItems(a.minItems()); 231 uniqueItems(a.uniqueItems()); 232 _enum(HttpPartSchema.toSet(a._enum())); 233 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 234 skipIfEmpty(a.skipIfEmpty()); 235 parser(a.parser()); 236 serializer(a.serializer()); 237 return this; 238 } 239 240 HttpPartSchemaBuilder apply(Path a) { 241 name(a.value()); 242 name(a.name()); 243 type(a.type()); 244 format(a.format()); 245 items(a.items()); 246 allowEmptyValue(a.allowEmptyValue()); 247 collectionFormat(a.collectionFormat()); 248 maximum(HttpPartSchema.toNumber(a.maximum())); 249 exclusiveMaximum(a.exclusiveMaximum()); 250 minimum(HttpPartSchema.toNumber(a.minimum())); 251 exclusiveMinimum(a.exclusiveMinimum()); 252 maxLength(a.maxLength()); 253 minLength(a.minLength()); 254 pattern(a.pattern()); 255 maxItems(a.maxItems()); 256 minItems(a.minItems()); 257 uniqueItems(a.uniqueItems()); 258 _enum(HttpPartSchema.toSet(a._enum())); 259 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 260 parser(a.parser()); 261 serializer(a.serializer()); 262 263 // Path remainder always allows empty value. 264 if (startsWith(name, '/')) 265 allowEmptyValue(); 266 else 267 required(true); 268 269 return this; 270 } 271 272 HttpPartSchemaBuilder apply(Response a) { 273 codes(a.value()); 274 codes(a.code()); 275 required(false); 276 allowEmptyValue(true); 277 serializer(a.partSerializer()); 278 parser(a.partParser()); 279 apply(a.schema()); 280 return this; 281 } 282 283 HttpPartSchemaBuilder apply(Items a) { 284 type(a.type()); 285 format(a.format()); 286 items(a.items()); 287 collectionFormat(a.collectionFormat()); 288 _default(a._default().length == 0 ? null : joinnl(a._default())); 289 maximum(HttpPartSchema.toNumber(a.maximum())); 290 exclusiveMaximum(a.exclusiveMaximum()); 291 minimum(HttpPartSchema.toNumber(a.minimum())); 292 exclusiveMinimum(a.exclusiveMinimum()); 293 maxLength(a.maxLength()); 294 minLength(a.minLength()); 295 pattern(a.pattern()); 296 maxItems(a.maxItems()); 297 minItems(a.minItems()); 298 uniqueItems(a.uniqueItems()); 299 _enum(HttpPartSchema.toSet(a._enum())); 300 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 301 return this; 302 } 303 304 HttpPartSchemaBuilder apply(SubItems a) { 305 type(a.type()); 306 format(a.format()); 307 items(HttpPartSchema.toObjectMap(a.items())); 308 collectionFormat(a.collectionFormat()); 309 _default(a._default().length == 0 ? null : joinnl(a._default())); 310 maximum(HttpPartSchema.toNumber(a.maximum())); 311 exclusiveMaximum(a.exclusiveMaximum()); 312 minimum(HttpPartSchema.toNumber(a.minimum())); 313 exclusiveMinimum(a.exclusiveMinimum()); 314 maxLength(a.maxLength()); 315 minLength(a.minLength()); 316 pattern(a.pattern()); 317 maxItems(a.maxItems()); 318 minItems(a.minItems()); 319 uniqueItems(a.uniqueItems()); 320 _enum(HttpPartSchema.toSet(a._enum())); 321 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 322 return this; 323 } 324 325 HttpPartSchemaBuilder apply(Schema a) { 326 type(a.type()); 327 format(a.format()); 328 items(a.items()); 329 collectionFormat(a.collectionFormat()); 330 _default(a._default().length == 0 ? null : joinnl(a._default())); 331 maximum(HttpPartSchema.toNumber(a.maximum())); 332 exclusiveMaximum(a.exclusiveMaximum()); 333 minimum(HttpPartSchema.toNumber(a.minimum())); 334 exclusiveMinimum(a.exclusiveMinimum()); 335 maxLength(a.maxLength()); 336 minLength(a.minLength()); 337 pattern(a.pattern()); 338 maxItems(a.maxItems()); 339 minItems(a.minItems()); 340 uniqueItems(a.uniqueItems()); 341 _enum(HttpPartSchema.toSet(a._enum())); 342 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 343 maxProperties(a.maxProperties()); 344 minProperties(a.minProperties()); 345 properties(HttpPartSchema.toObjectMap(a.properties())); 346 additionalProperties(HttpPartSchema.toObjectMap(a.additionalProperties())); 347 return this; 348 } 349 350 HttpPartSchemaBuilder apply(HasQuery a) { 351 name(a.value()); 352 name(a.name()); 353 return this; 354 } 355 356 HttpPartSchemaBuilder apply(HasFormData a) { 357 name(a.value()); 358 name(a.name()); 359 return this; 360 } 361 362 HttpPartSchemaBuilder apply(ObjectMap m) { 363 if (m != null && ! m.isEmpty()) { 364 _default(m.getString("default")); 365 _enum(HttpPartSchema.toSet(m.getString("enum"))); 366 allowEmptyValue(m.getBoolean("allowEmptyValue")); 367 exclusiveMaximum(m.getBoolean("exclusiveMaximum")); 368 exclusiveMinimum(m.getBoolean("exclusiveMinimum")); 369 required(m.getBoolean("required")); 370 uniqueItems(m.getBoolean("uniqueItems")); 371 collectionFormat(m.getString("collectionFormat")); 372 type(m.getString("type")); 373 format(m.getString("format")); 374 pattern(m.getString("pattern")); 375 maximum(m.get("maximum", Number.class)); 376 minimum(m.get("minimum", Number.class)); 377 multipleOf(m.get("multipleOf", Number.class)); 378 maxItems(m.get("maxItems", Long.class)); 379 maxLength(m.get("maxLength", Long.class)); 380 maxProperties(m.get("maxProperties", Long.class)); 381 minItems(m.get("minItems", Long.class)); 382 minLength(m.get("minLength", Long.class)); 383 minProperties(m.get("minProperties", Long.class)); 384 385 items(m.getObjectMap("items")); 386 properties(m.getObjectMap("properties")); 387 additionalProperties(m.getObjectMap("additionalProperties")); 388 389 apply(m.getObjectMap("schema", null)); 390 } 391 return this; 392 } 393 394 /** 395 * <mk>name</mk> field. 396 * 397 * <p> 398 * Applicable to the following Swagger schema objects: 399 * <ul> 400 * <li>{@doc SwaggerParameterObject Parameter} 401 * <li>{@doc SwaggerHeaderObject Header} 402 * </ul> 403 * 404 * @param value 405 * The new value for this property. 406 * @return This object (for method chaining). 407 */ 408 public HttpPartSchemaBuilder name(String value) { 409 if (isNotEmpty(value)) 410 name = value; 411 return this; 412 } 413 414 /** 415 * <mk>httpStatusCode</mk> key. 416 * 417 * <p> 418 * Applicable to the following Swagger schema objects: 419 * <ul> 420 * <li>{@doc SwaggerResponsesObject Responses} 421 * </ul> 422 * 423 * @param value 424 * The new value for this property. 425 * <br>Ignored if <jk>null</jk> or an empty array. 426 * @return This object (for method chaining). 427 */ 428 public HttpPartSchemaBuilder codes(int[] value) { 429 if (value != null && value.length != 0) 430 for (int v : value) 431 code(v); 432 return this; 433 } 434 435 /** 436 * <mk>httpStatusCode</mk> key. 437 * 438 * <p> 439 * Applicable to the following Swagger schema objects: 440 * <ul> 441 * <li>{@doc SwaggerResponsesObject Responses} 442 * </ul> 443 * 444 * @param value 445 * The new value for this property. 446 * <br>Ignored if value is <code>0</code>. 447 * @return This object (for method chaining). 448 */ 449 public HttpPartSchemaBuilder code(int value) { 450 if (value != 0) { 451 if (codes == null) 452 codes = new TreeSet<>(); 453 codes.add(value); 454 } 455 return this; 456 } 457 458 /** 459 * <mk>required</mk> field. 460 * 461 * <p> 462 * Determines whether the parameter is mandatory. 463 * 464 * <p> 465 * Applicable to the following Swagger schema objects: 466 * <ul> 467 * <li>{@doc SwaggerParameterObject Parameter} 468 * <li>{@doc SwaggerSchemaObject Schema} 469 * </ul> 470 * 471 * @param value 472 * The new value for this property. 473 * <br>Ignored if value is <jk>null</jk>. 474 * @return This object (for method chaining). 475 */ 476 public HttpPartSchemaBuilder required(Boolean value) { 477 required = resolve(value, required); 478 return this; 479 } 480 481 /** 482 * <mk>required</mk> field. 483 * 484 * <p> 485 * Determines whether the parameter is mandatory. 486 * 487 * <p> 488 * Same as {@link #required(Boolean)} but takes in a boolean value as a string. 489 * 490 * @param value 491 * The new value for this property. 492 * <br>Ignored if value is <jk>null</jk> or empty. 493 * @return This object (for method chaining). 494 */ 495 public HttpPartSchemaBuilder required(String value) { 496 required = resolve(value, required); 497 return this; 498 } 499 500 /** 501 * <mk>required</mk> field. 502 * 503 * <p> 504 * Shortcut for calling <code>required(<jk>true</jk>);</code>. 505 * 506 * @return This object (for method chaining). 507 */ 508 public HttpPartSchemaBuilder required() { 509 return required(true); 510 } 511 512 /** 513 * <mk>type</mk> field. 514 * 515 * <p> 516 * The type of the parameter. 517 * 518 * <p> 519 * The possible values are: 520 * <ul class='spaced-list'> 521 * <li> 522 * <js>"string"</js> 523 * <br>Parameter must be a string or a POJO convertible from a string. 524 * <li> 525 * <js>"number"</js> 526 * <br>Parameter must be a number primitive or number object. 527 * <br>If parameter is <code>Object</code>, creates either a <code>Float</code> or <code>Double</code> depending on the size of the number. 528 * <li> 529 * <js>"integer"</js> 530 * <br>Parameter must be a integer/long primitive or integer/long object. 531 * <br>If parameter is <code>Object</code>, creates either a <code>Short</code>, <code>Integer</code>, or <code>Long</code> depending on the size of the number. 532 * <li> 533 * <js>"boolean"</js> 534 * <br>Parameter must be a boolean primitive or object. 535 * <li> 536 * <js>"array"</js> 537 * <br>Parameter must be an array or collection. 538 * <br>Elements must be strings or POJOs convertible from strings. 539 * <br>If parameter is <code>Object</code>, creates an {@link ObjectList}. 540 * <li> 541 * <js>"object"</js> 542 * <br>Parameter must be a map or bean. 543 * <br>If parameter is <code>Object</code>, creates an {@link ObjectMap}. 544 * <br>Note that this is an extension of the OpenAPI schema as Juneau allows for arbitrarily-complex POJOs to be serialized as HTTP parts. 545 * <li> 546 * <js>"file"</js> 547 * <br>This type is currently not supported. 548 * </ul> 549 * 550 * <p> 551 * If the type is not specified, it will be auto-detected based on the parameter class type. 552 * 553 * <p> 554 * Applicable to the following Swagger schema objects: 555 * <ul> 556 * <li>{@doc SwaggerParameterObject Parameter} 557 * <li>{@doc SwaggerSchemaObject Schema} 558 * <li>{@doc SwaggerItemsObject Items} 559 * <li>{@doc SwaggerSecuritySchemeObject SecurityScheme} 560 * </ul> 561 * 562 * <h5 class='section'>See Also:</h5> 563 * <ul class='doctree'> 564 * <li class='extlink'>{@doc SwaggerDataTypes} 565 * </ul> 566 * 567 * @param value 568 * The new value for this property. 569 * <br>Ignored if value is <jk>null</jk> or empty. 570 * @return This object (for method chaining). 571 */ 572 public HttpPartSchemaBuilder type(String value) { 573 try { 574 if (isNotEmpty(value)) 575 type = Type.fromString(value); 576 } catch (Exception e) { 577 throw new ContextRuntimeException("Invalid value ''{0}'' passed in as type value. Valid values: {1}", value, Type.values()); 578 } 579 return this; 580 } 581 582 /** 583 * <mk>format</mk> field. 584 * 585 * <p> 586 * The extending format for the previously mentioned {@doc SwaggerParameterTypes parameter type}. 587 * 588 * <p> 589 * The possible values are: 590 * <ul class='spaced-list'> 591 * <li> 592 * <js>"int32"</js> - Signed 32 bits. 593 * <br>Only valid with type <js>"integer"</js>. 594 * <li> 595 * <js>"int64"</js> - Signed 64 bits. 596 * <br>Only valid with type <js>"integer"</js>. 597 * <li> 598 * <js>"float"</js> - 32-bit floating point number. 599 * <br>Only valid with type <js>"number"</js>. 600 * <li> 601 * <js>"double"</js> - 64-bit floating point number. 602 * <br>Only valid with type <js>"number"</js>. 603 * <li> 604 * <js>"byte"</js> - BASE-64 encoded characters. 605 * <br>Only valid with type <js>"string"</js>. 606 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 607 * <li> 608 * <js>"binary"</js> - Hexadecimal encoded octets (e.g. <js>"00FF"</js>). 609 * <br>Only valid with type <js>"string"</js>. 610 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 611 * <li> 612 * <js>"binary-spaced"</js> - Hexadecimal encoded octets, spaced (e.g. <js>"00 FF"</js>). 613 * <br>Only valid with type <js>"string"</js>. 614 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 615 * <li> 616 * <js>"date"</js> - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>. 617 * <br>Only valid with type <js>"string"</js>. 618 * <li> 619 * <js>"date-time"</js> - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>. 620 * <br>Only valid with type <js>"string"</js>. 621 * <li> 622 * <js>"password"</js> - Used to hint UIs the input needs to be obscured. 623 * <br>This format does not affect the serialization or parsing of the parameter. 624 * <li> 625 * <js>"uon"</js> - UON notation (e.g. <js>"(foo=bar,baz=@(qux,123))"</js>). 626 * <br>Only valid with type <js>"object"</js>. 627 * <br>If not specified, then the input is interpreted as plain-text and is converted to a POJO directly. 628 * </ul> 629 * 630 * <p> 631 * Applicable to the following Swagger schema objects: 632 * <ul> 633 * <li>{@doc SwaggerParameterObject Parameter} 634 * <li>{@doc SwaggerSchemaObject Schema} 635 * <li>{@doc SwaggerItemsObject Items} 636 * <li>{@doc SwaggerHeaderObject Header} 637 * </ul> 638 * 639 * <h5 class='section'>See Also:</h5> 640 * <ul class='doctree'> 641 * <li class='extlink'>{@doc SwaggerDataTypeFormats} 642 * </ul> 643 * 644 * @param value 645 * The new value for this property. 646 * <br>Ignored if value is <jk>null</jk> or empty. 647 * @return This object (for method chaining). 648 */ 649 public HttpPartSchemaBuilder format(String value) { 650 try { 651 if (isNotEmpty(value)) 652 format = Format.fromString(value); 653 } catch (Exception e) { 654 throw new ContextRuntimeException("Invalid value ''{0}'' passed in as format value. Valid values: {1}", value, Format.values()); 655 } 656 return this; 657 } 658 659 /** 660 * <mk>allowEmptyValue</mk> field. 661 * 662 * <p> 663 * Sets the ability to pass empty-valued parameters. 664 * <br>This is valid only for either query or formData parameters and allows you to send a parameter with a name only or an empty value. 665 * <br>The default value is <jk>false</jk>. 666 * 667 * <p> 668 * Applicable to the following Swagger schema objects: 669 * <ul> 670 * <li>{@doc SwaggerParameterObject Parameter} 671 * </ul> 672 * 673 * @param value 674 * The new value for this property. 675 * <br>Ignored if value is <jk>null</jk>. 676 * @return This object (for method chaining). 677 */ 678 public HttpPartSchemaBuilder allowEmptyValue(Boolean value) { 679 allowEmptyValue = resolve(value, allowEmptyValue); 680 return this; 681 } 682 683 /** 684 * <mk>allowEmptyValue</mk> field. 685 * 686 * <p> 687 * Same as {@link #allowEmptyValue(Boolean)} but takes in a string boolean value. 688 * 689 * @param value 690 * The new value for this property. 691 * <br>Ignored if value is <jk>null</jk> or empty. 692 * @return This object (for method chaining). 693 */ 694 public HttpPartSchemaBuilder allowEmptyValue(String value) { 695 allowEmptyValue = resolve(value, allowEmptyValue); 696 return this; 697 } 698 699 /** 700 * <mk>allowEmptyValue</mk> field. 701 * 702 * <p> 703 * Shortcut for calling <code>allowEmptyValue(<jk>true</jk>);</code>. 704 * 705 * @return This object (for method chaining). 706 */ 707 public HttpPartSchemaBuilder allowEmptyValue() { 708 return allowEmptyValue(true); 709 } 710 711 /** 712 * <mk>items</mk> field. 713 * 714 * <p> 715 * Describes the type of items in the array. 716 * <p> 717 * Required if <code>type</code> is <js>"array"</js>. 718 * <br>Can only be used if <code>type</code> is <js>"array"</js>. 719 * 720 * <p> 721 * Applicable to the following Swagger schema objects: 722 * <ul> 723 * <li>{@doc SwaggerParameterObject Parameter} 724 * <li>{@doc SwaggerSchemaObject Schema} 725 * <li>{@doc SwaggerItemsObject Items} 726 * <li>{@doc SwaggerHeaderObject Header} 727 * </ul> 728 * 729 * @param value 730 * The new value for this property. 731 * <br>Ignored if value is <jk>null</jk> or empty. 732 * @return This object (for method chaining). 733 */ 734 public HttpPartSchemaBuilder items(HttpPartSchemaBuilder value) { 735 if (value != null) 736 this.items = value; 737 return this; 738 } 739 740 HttpPartSchemaBuilder items(ObjectMap value) { 741 if (value != null && ! value.isEmpty()) 742 items = HttpPartSchema.create().apply(value); 743 return this; 744 } 745 746 HttpPartSchemaBuilder items(Items value) { 747 if (! AnnotationUtils.empty(value)) 748 items = HttpPartSchema.create().apply(value); 749 return this; 750 } 751 752 HttpPartSchemaBuilder items(SubItems value) { 753 if (! AnnotationUtils.empty(value)) 754 items = HttpPartSchema.create().apply(value); 755 return this; 756 } 757 758 759 /** 760 * <mk>collectionFormat</mk> field. 761 * 762 * <p> 763 * Determines the format of the array if <code>type</code> <js>"array"</js> is used. 764 * <br>Can only be used if <code>type</code> is <js>"array"</js>. 765 * 766 * <br>Possible values are: 767 * <ul class='spaced-list'> 768 * <li> 769 * <js>"csv"</js> (default) - Comma-separated values (e.g. <js>"foo,bar"</js>). 770 * <li> 771 * <js>"ssv"</js> - Space-separated values (e.g. <js>"foo bar"</js>). 772 * <li> 773 * <js>"tsv"</js> - Tab-separated values (e.g. <js>"foo\tbar"</js>). 774 * <li> 775 * <js>"pipes</js> - Pipe-separated values (e.g. <js>"foo|bar"</js>). 776 * <li> 777 * <js>"multi"</js> - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). 778 * <li> 779 * <js>"uon"</js> - UON notation (e.g. <js>"@(foo,bar)"</js>). 780 * <li> 781 * </ul> 782 * 783 * <p> 784 * Applicable to the following Swagger schema objects: 785 * <ul> 786 * <li>{@doc SwaggerParameterObject Parameter} 787 * <li>{@doc SwaggerItemsObject Items} 788 * <li>{@doc SwaggerHeaderObject Header} 789 * </ul> 790 * 791 * <p> 792 * Note that for collections/arrays parameters with POJO element types, the input is broken into a string array before being converted into POJO elements. 793 * 794 * @param value 795 * The new value for this property. 796 * <br>Ignored if value is <jk>null</jk> or empty. 797 * @return This object (for method chaining). 798 */ 799 public HttpPartSchemaBuilder collectionFormat(String value) { 800 try { 801 if (isNotEmpty(value)) 802 this.collectionFormat = CollectionFormat.fromString(value); 803 } catch (Exception e) { 804 throw new ContextRuntimeException("Invalid value ''{0}'' passed in as collectionFormat value. Valid values: {1}", value, CollectionFormat.values()); 805 } 806 return this; 807 } 808 809 /** 810 * <mk>default</mk> field. 811 * 812 * <p> 813 * Declares the value of the parameter that the server will use if none is provided, for example a "count" to control the number of results per page might default to 100 if not supplied by the client in the request. 814 * <br>(Note: "default" has no meaning for required parameters.) 815 * 816 * <p> 817 * Applicable to the following Swagger schema objects: 818 * <ul> 819 * <li>{@doc SwaggerParameterObject Parameter} 820 * <li>{@doc SwaggerSchemaObject Schema} 821 * <li>{@doc SwaggerItemsObject Items} 822 * <li>{@doc SwaggerHeaderObject Header} 823 * </ul> 824 * 825 * @param value 826 * The new value for this property. 827 * <br>Ignored if value is <jk>null</jk>. 828 * @return This object (for method chaining). 829 */ 830 public HttpPartSchemaBuilder _default(String value) { 831 if (value != null) 832 this._default = value; 833 return this; 834 } 835 836 /** 837 * <mk>maximum</mk> field. 838 * 839 * <p> 840 * Defines the maximum value for a parameter of numeric types. 841 * 842 * <p> 843 * Only allowed for the following types: <js>"integer"</js>, <js>"number"</js>. 844 * 845 * <p> 846 * Applicable to the following Swagger schema objects: 847 * <ul> 848 * <li>{@doc SwaggerParameterObject Parameter} 849 * <li>{@doc SwaggerSchemaObject Schema} 850 * <li>{@doc SwaggerItemsObject Items} 851 * <li>{@doc SwaggerHeaderObject Header} 852 * </ul> 853 * 854 * @param value 855 * The new value for this property. 856 * <br>Ignored if value is <jk>null</jk>. 857 * @return This object (for method chaining). 858 */ 859 public HttpPartSchemaBuilder maximum(Number value) { 860 if (value != null) 861 this.maximum = value; 862 return this; 863 } 864 865 /** 866 * <mk>exclusiveMaximum</mk> field. 867 * 868 * <p> 869 * Defines whether the maximum is matched exclusively. 870 * 871 * <p> 872 * Only allowed for the following types: <js>"integer"</js>, <js>"number"</js>. 873 * <br>If <jk>true</jk>, must be accompanied with <code>maximum</code>. 874 * 875 * <p> 876 * Applicable to the following Swagger schema objects: 877 * <ul> 878 * <li>{@doc SwaggerParameterObject Parameter} 879 * <li>{@doc SwaggerSchemaObject Schema} 880 * <li>{@doc SwaggerItemsObject Items} 881 * <li>{@doc SwaggerHeaderObject Header} 882 * </ul> 883 * 884 * @param value 885 * The new value for this property. 886 * <br>Ignored if value is <jk>null</jk>. 887 * @return This object (for method chaining). 888 */ 889 public HttpPartSchemaBuilder exclusiveMaximum(Boolean value) { 890 exclusiveMaximum = resolve(value, exclusiveMaximum); 891 return this; 892 } 893 894 /** 895 * <mk>exclusiveMaximum</mk> field. 896 * 897 * <p> 898 * Same as {@link #exclusiveMaximum(Boolean)} but takes in a string boolean value. 899 * 900 * @param value 901 * The new value for this property. 902 * <br>Ignored if value is <jk>null</jk> or empty. 903 * @return This object (for method chaining). 904 */ 905 public HttpPartSchemaBuilder exclusiveMaximum(String value) { 906 exclusiveMaximum = resolve(value, exclusiveMaximum); 907 return this; 908 } 909 910 /** 911 * <mk>exclusiveMaximum</mk> field. 912 * 913 * <p> 914 * Shortcut for calling <code>exclusiveMaximum(<jk>true</jk>);</code>. 915 * 916 * @return This object (for method chaining). 917 */ 918 public HttpPartSchemaBuilder exclusiveMaximum() { 919 return exclusiveMaximum(true); 920 } 921 922 /** 923 * <mk>minimum</mk> field. 924 * 925 * <p> 926 * Defines the minimum value for a parameter of numeric types. 927 * 928 * <p> 929 * Only allowed for the following types: <js>"integer"</js>, <js>"number"</js>. 930 * 931 * <p> 932 * Applicable to the following Swagger schema objects: 933 * <ul> 934 * <li>{@doc SwaggerParameterObject Parameter} 935 * <li>{@doc SwaggerSchemaObject Schema} 936 * <li>{@doc SwaggerItemsObject Items} 937 * <li>{@doc SwaggerHeaderObject Header} 938 * </ul> 939 * 940 * @param value 941 * The new value for this property. 942 * <br>Ignored if value is <jk>null</jk>. 943 * @return This object (for method chaining). 944 */ 945 public HttpPartSchemaBuilder minimum(Number value) { 946 if (value != null) 947 this.minimum = value; 948 return this; 949 } 950 951 /** 952 * <mk>exclusiveMinimum</mk> field. 953 * 954 * <p> 955 * Defines whether the minimum is matched exclusively. 956 * 957 * <p> 958 * Only allowed for the following types: <js>"integer"</js>, <js>"number"</js>. 959 * <br>If <jk>true</jk>, must be accompanied with <code>minimum</code>. 960 * 961 * <p> 962 * Applicable to the following Swagger schema objects: 963 * <ul> 964 * <li>{@doc SwaggerParameterObject Parameter} 965 * <li>{@doc SwaggerSchemaObject Schema} 966 * <li>{@doc SwaggerItemsObject Items} 967 * <li>{@doc SwaggerHeaderObject Header} 968 * </ul> 969 * 970 * @param value 971 * The new value for this property. 972 * <br>Ignored if value is <jk>null</jk>. 973 * @return This object (for method chaining). 974 */ 975 public HttpPartSchemaBuilder exclusiveMinimum(Boolean value) { 976 exclusiveMinimum = resolve(value, exclusiveMinimum); 977 return this; 978 } 979 980 /** 981 * <mk>exclusiveMinimum</mk> field. 982 * 983 * <p> 984 * Same as {@link #exclusiveMinimum(Boolean)} but takes in a string boolean value. 985 * 986 * @param value 987 * The new value for this property. 988 * <br>Ignored if value is <jk>null</jk> or empty. 989 * @return This object (for method chaining). 990 */ 991 public HttpPartSchemaBuilder exclusiveMinimum(String value) { 992 exclusiveMinimum = resolve(value, exclusiveMinimum); 993 return this; 994 } 995 996 /** 997 * <mk>exclusiveMinimum</mk> field. 998 * 999 * <p> 1000 * Shortcut for calling <code>exclusiveMinimum(<jk>true</jk>);</code>. 1001 * 1002 * @return This object (for method chaining). 1003 */ 1004 public HttpPartSchemaBuilder exclusiveMinimum() { 1005 return exclusiveMinimum(true); 1006 } 1007 1008 /** 1009 * <mk>maxLength</mk> field. 1010 * 1011 * <p> 1012 * A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. 1013 * <br>The length of a string instance is defined as the number of its characters as defined by <a href='https://tools.ietf.org/html/rfc4627'>RFC 4627</a>. 1014 * 1015 * <p> 1016 * Only allowed for the following types: <js>"string"</js>. 1017 * 1018 * <p> 1019 * Applicable to the following Swagger schema objects: 1020 * <ul> 1021 * <li>{@doc SwaggerParameterObject Parameter} 1022 * <li>{@doc SwaggerSchemaObject Schema} 1023 * <li>{@doc SwaggerItemsObject Items} 1024 * <li>{@doc SwaggerHeaderObject Header} 1025 * </ul> 1026 * 1027 * @param value 1028 * The new value for this property. 1029 * <br>Ignored if value is <jk>null</jk> or <code>-1</code>. 1030 * @return This object (for method chaining). 1031 */ 1032 public HttpPartSchemaBuilder maxLength(Long value) { 1033 maxLength = resolve(value, maxLength); 1034 return this; 1035 } 1036 1037 /** 1038 * <mk>maxLength</mk> field. 1039 * 1040 * <p> 1041 * Same as {@link #maxLength(Long)} but takes in a string number. 1042 * 1043 * @param value 1044 * The new value for this property. 1045 * <br>Ignored if value is <jk>null</jk> or empty. 1046 * @return This object (for method chaining). 1047 */ 1048 public HttpPartSchemaBuilder maxLength(String value) { 1049 maxLength = resolve(value, maxLength); 1050 return this; 1051 } 1052 1053 /** 1054 * <mk>minLength</mk> field. 1055 * 1056 * <p> 1057 * A string instance is valid against this keyword if its length is greater than, or equal to, the value of this keyword. 1058 * <br>The length of a string instance is defined as the number of its characters as defined by <a href='https://tools.ietf.org/html/rfc4627'>RFC 4627</a>. 1059 * 1060 * <p> 1061 * Only allowed for the following types: <js>"string"</js>. 1062 * 1063 * <p> 1064 * Applicable to the following Swagger schema objects: 1065 * <ul> 1066 * <li>{@doc SwaggerParameterObject Parameter} 1067 * <li>{@doc SwaggerSchemaObject Schema} 1068 * <li>{@doc SwaggerItemsObject Items} 1069 * <li>{@doc SwaggerHeaderObject Header} 1070 * </ul> 1071 * 1072 * @param value 1073 * The new value for this property. 1074 * <br>Ignored if value is <jk>null</jk> or <code>-1</code>. 1075 * @return This object (for method chaining). 1076 */ 1077 public HttpPartSchemaBuilder minLength(Long value) { 1078 minLength = resolve(value, minLength); 1079 return this; 1080 } 1081 1082 /** 1083 * <mk>minLength</mk> field. 1084 * 1085 * <p> 1086 * Same as {@link #minLength(Long)} but takes in a string number. 1087 * 1088 * @param value 1089 * The new value for this property. 1090 * <br>Ignored if value is <jk>null</jk> or empty. 1091 * @return This object (for method chaining). 1092 */ 1093 public HttpPartSchemaBuilder minLength(String value) { 1094 minLength = resolve(value, minLength); 1095 return this; 1096 } 1097 1098 /** 1099 * <mk>pattern</mk> field. 1100 * 1101 * <p> 1102 * A string input is valid if it matches the specified regular expression pattern. 1103 * 1104 * <p> 1105 * Only allowed for the following types: <js>"string"</js>. 1106 * 1107 * <p> 1108 * Applicable to the following Swagger schema objects: 1109 * <ul> 1110 * <li>{@doc SwaggerParameterObject Parameter} 1111 * <li>{@doc SwaggerSchemaObject Schema} 1112 * <li>{@doc SwaggerItemsObject Items} 1113 * <li>{@doc SwaggerHeaderObject Header} 1114 * </ul> 1115 * 1116 * @param value 1117 * The new value for this property. 1118 * <br>Ignored if value is <jk>null</jk> or empty. 1119 * @return This object (for method chaining). 1120 */ 1121 public HttpPartSchemaBuilder pattern(String value) { 1122 try { 1123 if (isNotEmpty(value)) 1124 this.pattern = Pattern.compile(value); 1125 } catch (Exception e) { 1126 throw new ContextRuntimeException(e, "Invalid value {0} passed in as pattern value. Must be a valid regular expression.", value); 1127 } 1128 return this; 1129 } 1130 1131 /** 1132 * <mk>maxItems</mk> field. 1133 * 1134 * <p> 1135 * An array or collection is valid if its size is less than, or equal to, the value of this keyword. 1136 * 1137 * <p> 1138 * Only allowed for the following types: <js>"array"</js>. 1139 * 1140 * <p> 1141 * Applicable to the following Swagger schema objects: 1142 * <ul> 1143 * <li>{@doc SwaggerParameterObject Parameter} 1144 * <li>{@doc SwaggerSchemaObject Schema} 1145 * <li>{@doc SwaggerItemsObject Items} 1146 * <li>{@doc SwaggerHeaderObject Header} 1147 * </ul> 1148 * 1149 * @param value 1150 * The new value for this property. 1151 * <br>Ignored if value is <jk>null</jk> or <code>-1</code>. 1152 * @return This object (for method chaining). 1153 */ 1154 public HttpPartSchemaBuilder maxItems(Long value) { 1155 maxItems = resolve(value, maxItems); 1156 return this; 1157 } 1158 1159 /** 1160 * <mk>maxItems</mk> field. 1161 * 1162 * <p> 1163 * Same as {@link #maxItems(Long)} but takes in a string number. 1164 * 1165 * @param value 1166 * The new value for this property. 1167 * <br>Ignored if value is <jk>null</jk> or empty. 1168 * @return This object (for method chaining). 1169 */ 1170 public HttpPartSchemaBuilder maxItems(String value) { 1171 maxItems = resolve(value, maxItems); 1172 return this; 1173 } 1174 1175 /** 1176 * <mk>minItems</mk> field. 1177 * 1178 * <p> 1179 * An array or collection is valid if its size is greater than, or equal to, the value of this keyword. 1180 * 1181 * <p> 1182 * Only allowed for the following types: <js>"array"</js>. 1183 * 1184 * <p> 1185 * Applicable to the following Swagger schema objects: 1186 * <ul> 1187 * <li>{@doc SwaggerParameterObject Parameter} 1188 * <li>{@doc SwaggerSchemaObject Schema} 1189 * <li>{@doc SwaggerItemsObject Items} 1190 * <li>{@doc SwaggerHeaderObject Header} 1191 * </ul> 1192 * 1193 * @param value 1194 * The new value for this property. 1195 * <br>Ignored if value is <jk>null</jk> or <code>-1<code>. 1196 * @return This object (for method chaining). 1197 */ 1198 public HttpPartSchemaBuilder minItems(Long value) { 1199 minItems = resolve(value, minItems); 1200 return this; 1201 } 1202 1203 /** 1204 * <mk>minItems</mk> field. 1205 * 1206 * <p> 1207 * Same as {@link #minItems(Long)} but takes in a string number. 1208 * 1209 * @param value 1210 * The new value for this property. 1211 * <br>Ignored if value is <jk>null</jk> or empty. 1212 * @return This object (for method chaining). 1213 */ 1214 public HttpPartSchemaBuilder minItems(String value) { 1215 minItems = resolve(value, minItems); 1216 return this; 1217 } 1218 1219 /** 1220 * <mk>uniqueItems</mk> field. 1221 * 1222 * <p> 1223 * If <jk>true</jk>, the input validates successfully if all of its elements are unique. 1224 * 1225 * <p> 1226 * <br>If the parameter type is a subclass of {@link Set}, this validation is skipped (since a set can only contain unique items anyway). 1227 * <br>Otherwise, the collection or array is checked for duplicate items. 1228 * 1229 * <p> 1230 * Only allowed for the following types: <js>"array"</js>. 1231 * 1232 * <p> 1233 * Applicable to the following Swagger schema objects: 1234 * <ul> 1235 * <li>{@doc SwaggerParameterObject Parameter} 1236 * <li>{@doc SwaggerSchemaObject Schema} 1237 * <li>{@doc SwaggerItemsObject Items} 1238 * <li>{@doc SwaggerHeaderObject Header} 1239 * </ul> 1240 * 1241 * @param value 1242 * The new value for this property. 1243 * <br>Ignored if value is <jk>null</jk>. 1244 * @return This object (for method chaining). 1245 */ 1246 public HttpPartSchemaBuilder uniqueItems(Boolean value) { 1247 uniqueItems = resolve(value, uniqueItems); 1248 return this; 1249 } 1250 1251 /** 1252 * <mk>uniqueItems</mk> field. 1253 * 1254 * <p> 1255 * Same as {@link #uniqueItems(Boolean)} but takes in a string boolean. 1256 * 1257 * @param value 1258 * The new value for this property. 1259 * <br>Ignored if value is <jk>null</jk> or empty.. 1260 * @return This object (for method chaining). 1261 */ 1262 public HttpPartSchemaBuilder uniqueItems(String value) { 1263 uniqueItems = resolve(value, uniqueItems); 1264 return this; 1265 } 1266 1267 /** 1268 * <mk>uniqueItems</mk> field. 1269 * 1270 * <p> 1271 * Shortcut for calling <code>uniqueItems(<jk>true</jk>);</code>. 1272 * 1273 * @return This object (for method chaining). 1274 */ 1275 public HttpPartSchemaBuilder uniqueItems() { 1276 return uniqueItems(true); 1277 } 1278 1279 /** 1280 * <mk>skipIfEmpty</mk> field. 1281 * 1282 * <p> 1283 * Identifies whether an item should be skipped during serialization if it's empty. 1284 * 1285 * @param value 1286 * The new value for this property. 1287 * <br>Ignored if value is <jk>null</jk>. 1288 * @return This object (for method chaining). 1289 */ 1290 public HttpPartSchemaBuilder skipIfEmpty(Boolean value) { 1291 skipIfEmpty = resolve(value, skipIfEmpty); 1292 return this; 1293 } 1294 1295 /** 1296 * <mk>skipIfEmpty</mk> field. 1297 * 1298 * <p> 1299 * Same as {@link #skipIfEmpty(Boolean)} but takes in a string boolean. 1300 * 1301 * @param value 1302 * The new value for this property. 1303 * <br>Ignored if value is <jk>null</jk> or empty. 1304 * @return This object (for method chaining). 1305 */ 1306 public HttpPartSchemaBuilder skipIfEmpty(String value) { 1307 skipIfEmpty = resolve(value, skipIfEmpty); 1308 return this; 1309 } 1310 1311 /** 1312 * Identifies whether an item should be skipped if it's empty. 1313 * 1314 * <p> 1315 * Shortcut for calling <code>skipIfEmpty(<jk>true</jk>);</code>. 1316 * 1317 * @return This object (for method chaining). 1318 */ 1319 public HttpPartSchemaBuilder skipIfEmpty() { 1320 return skipIfEmpty(true); 1321 } 1322 1323 /** 1324 * <mk>enum</mk> field. 1325 * 1326 * <p> 1327 * If specified, the input validates successfully if it is equal to one of the elements in this array. 1328 * 1329 * <p> 1330 * Applicable to the following Swagger schema objects: 1331 * <ul> 1332 * <li>{@doc SwaggerParameterObject Parameter} 1333 * <li>{@doc SwaggerSchemaObject Schema} 1334 * <li>{@doc SwaggerItemsObject Items} 1335 * <li>{@doc SwaggerHeaderObject Header} 1336 * </ul> 1337 * 1338 * @param value 1339 * The new value for this property. 1340 * <br>Ignored if value is <jk>null</jk> or an empty set. 1341 * @return This object (for method chaining). 1342 */ 1343 public HttpPartSchemaBuilder _enum(Set<String> value) { 1344 if (value != null && ! value.isEmpty()) 1345 this._enum = value; 1346 return this; 1347 } 1348 1349 /** 1350 * <mk>_enum</mk> field. 1351 * 1352 * <p> 1353 * Same as {@link #_enum(Set)} but takes in a var-args array. 1354 * 1355 * @param values 1356 * The new values for this property. 1357 * <br>Ignored if value is empty. 1358 * @return This object (for method chaining). 1359 */ 1360 public HttpPartSchemaBuilder _enum(String...values) { 1361 return _enum(new ASet<String>().appendAll(values)); 1362 } 1363 1364 /** 1365 * <mk>multipleOf</mk> field. 1366 * 1367 * <p> 1368 * A numeric instance is valid if the result of the division of the instance by this keyword's value is an integer. 1369 * 1370 * <p> 1371 * Only allowed for the following types: <js>"integer"</js>, <js>"number"</js>. 1372 * 1373 * <p> 1374 * Applicable to the following Swagger schema objects: 1375 * <ul> 1376 * <li>{@doc SwaggerParameterObject Parameter} 1377 * <li>{@doc SwaggerSchemaObject Schema} 1378 * <li>{@doc SwaggerItemsObject Items} 1379 * <li>{@doc SwaggerHeaderObject Header} 1380 * </ul> 1381 * 1382 * @param value 1383 * The new value for this property. 1384 * <br>Ignored if value is <jk>null</jk>. 1385 * @return This object (for method chaining). 1386 */ 1387 public HttpPartSchemaBuilder multipleOf(Number value) { 1388 if (value != null) 1389 this.multipleOf = value; 1390 return this; 1391 } 1392 1393 /** 1394 * <mk>mapProperties</mk> field. 1395 * 1396 * <p> 1397 * Applicable to the following Swagger schema objects: 1398 * <ul> 1399 * <li>{@doc SwaggerSchemaObject Schema} 1400 * </ul> 1401 * 1402 * @param value 1403 * The new value for this property. 1404 * <br>Ignored if value is <jk>null</jk> or <code>-1</code>. 1405 * @return This object (for method chaining). 1406 */ 1407 public HttpPartSchemaBuilder maxProperties(Long value) { 1408 maxProperties = resolve(value, maxProperties); 1409 return this; 1410 } 1411 1412 /** 1413 * <mk>mapProperties</mk> field. 1414 * 1415 * <p> 1416 * Same as {@link #maxProperties(Long)} but takes in a string number. 1417 * 1418 * @param value 1419 * The new value for this property. 1420 * <br>Ignored if value is <jk>null</jk> or empty. 1421 * @return This object (for method chaining). 1422 */ 1423 public HttpPartSchemaBuilder maxProperties(String value) { 1424 maxProperties = resolve(value, maxProperties); 1425 return this; 1426 } 1427 1428 /** 1429 * <mk>minProperties</mk> field. 1430 * 1431 * <p> 1432 * Applicable to the following Swagger schema objects: 1433 * <ul> 1434 * <li>{@doc SwaggerSchemaObject Schema} 1435 * </ul> 1436 * 1437 * @param value 1438 * The new value for this property. 1439 * <br>Ignored if value is <jk>null</jk>. 1440 * @return This object (for method chaining). 1441 */ 1442 public HttpPartSchemaBuilder minProperties(Long value) { 1443 minProperties = resolve(value, minProperties); 1444 return this; 1445 } 1446 1447 /** 1448 * <mk>minProperties</mk> field. 1449 * 1450 * <p> 1451 * Same as {@link #minProperties(Long)} but takes in a string boolean. 1452 * 1453 * @param value 1454 * The new value for this property. 1455 * <br>Ignored if value is <jk>null</jk> or empty. 1456 * @return This object (for method chaining). 1457 */ 1458 public HttpPartSchemaBuilder minProperties(String value) { 1459 minProperties = resolve(value, minProperties); 1460 return this; 1461 } 1462 1463 /** 1464 * <mk>properties</mk> field. 1465 * 1466 * <p> 1467 * Applicable to the following Swagger schema objects: 1468 * <ul> 1469 * <li>{@doc SwaggerSchemaObject Schema} 1470 * </ul> 1471 * 1472 * @param key 1473 * The property name. 1474 * @param value 1475 * The new value for this property. 1476 * <br>Ignored if value is <jk>null</jk>. 1477 * @return This object (for method chaining). 1478 */ 1479 public HttpPartSchemaBuilder property(String key, HttpPartSchemaBuilder value) { 1480 if ( key != null && value != null) { 1481 if (properties == null) 1482 properties = new LinkedHashMap<>(); 1483 properties.put(key, value); 1484 } 1485 return this; 1486 } 1487 1488 private HttpPartSchemaBuilder properties(ObjectMap value) { 1489 if (value != null && ! value.isEmpty()) 1490 for (Map.Entry<String,Object> e : value.entrySet()) 1491 property(e.getKey(), HttpPartSchema.create().apply((ObjectMap)e.getValue())); 1492 return this; 1493 } 1494 1495 /** 1496 * <mk>additionalProperties</mk> field. 1497 * 1498 * <p> 1499 * Applicable to the following Swagger schema objects: 1500 * <ul> 1501 * <li>{@doc SwaggerSchemaObject Schema} 1502 * </ul> 1503 * 1504 * @param value 1505 * The new value for this property. 1506 * <br>Ignored if value is <jk>null</jk> or empty. 1507 * @return This object (for method chaining). 1508 */ 1509 public HttpPartSchemaBuilder additionalProperties(HttpPartSchemaBuilder value) { 1510 if (value != null) 1511 additionalProperties = value; 1512 return this; 1513 } 1514 1515 private HttpPartSchemaBuilder additionalProperties(ObjectMap value) { 1516 if (value != null && ! value.isEmpty()) 1517 additionalProperties = HttpPartSchema.create().apply(value); 1518 return this; 1519 } 1520 1521 /** 1522 * Identifies the part serializer to use for serializing this part. 1523 * 1524 * @param value 1525 * The new value for this property. 1526 * <br>Ignored if value is <jk>null</jk> or {@link HttpPartSerializer.Null}. 1527 * @return This object (for method chaining). 1528 */ 1529 public HttpPartSchemaBuilder serializer(Class<? extends HttpPartSerializer> value) { 1530 if (value != null && value != HttpPartSerializer.Null.class) 1531 serializer = value; 1532 return this; 1533 } 1534 1535 /** 1536 * Identifies the part parser to use for parsing this part. 1537 * 1538 * @param value 1539 * The new value for this property. 1540 * <br>Ignored if value is <jk>null</jk> or {@link HttpPartParser.Null}. 1541 * @return This object (for method chaining). 1542 */ 1543 public HttpPartSchemaBuilder parser(Class<? extends HttpPartParser> value) { 1544 if (value != null && value != HttpPartParser.Null.class) 1545 parser = value; 1546 return this; 1547 } 1548 1549 /** 1550 * Disables Swagger schema usage validation checking. 1551 * 1552 * @param value Specify <jk>true</jk> to prevent {@link ContextRuntimeException} from being thrown if invalid Swagger usage was detected. 1553 * @return This object (for method chaining). 1554 */ 1555 public HttpPartSchemaBuilder noValidate(Boolean value) { 1556 if (value != null) 1557 this.noValidate = value; 1558 return this; 1559 } 1560 1561 /** 1562 * Disables Swagger schema usage validation checking. 1563 * 1564 * <p> 1565 * Shortcut for calling <code>noValidate(<jk>true</jk>);</code>. 1566 * 1567 * @return This object (for method chaining). 1568 */ 1569 public HttpPartSchemaBuilder noValidate() { 1570 return noValidate(true); 1571 } 1572 1573 private Boolean resolve(String newValue, Boolean oldValue) { 1574 return isEmpty(newValue) ? oldValue : Boolean.valueOf(newValue); 1575 } 1576 1577 private Boolean resolve(Boolean newValue, Boolean oldValue) { 1578 return newValue == null ? oldValue : newValue; 1579 } 1580 1581 private Long resolve(String newValue, Long oldValue) { 1582 return isEmpty(newValue) ? oldValue : Long.parseLong(newValue); 1583 } 1584 1585 private Long resolve(Long newValue, Long oldValue) { 1586 return (newValue == null || newValue == -1) ? oldValue : newValue; 1587 } 1588}