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.*; 016import java.lang.annotation.*; 017import java.lang.reflect.*; 018import java.util.*; 019import java.util.regex.*; 020 021import org.apache.juneau.*; 022import org.apache.juneau.http.annotation.*; 023import org.apache.juneau.jsonschema.annotation.Schema; 024import org.apache.juneau.jsonschema.annotation.Items; 025import org.apache.juneau.jsonschema.annotation.SubItems; 026import org.apache.juneau.reflect.*; 027import org.apache.juneau.httppart.HttpPartSchema.*; 028import org.apache.juneau.httppart.HttpPartSchema.Type; 029import org.apache.juneau.utils.*; 030 031/** 032 * The builder class for creating {@link HttpPartSchema} objects. 033 * 034 */ 035public class HttpPartSchemaBuilder { 036 String name, _default; 037 Set<Integer> codes; 038 Set<String> _enum; 039 Boolean allowEmptyValue, exclusiveMaximum, exclusiveMinimum, required, uniqueItems, skipIfEmpty; 040 CollectionFormat collectionFormat = CollectionFormat.NO_COLLECTION_FORMAT; 041 Type type = Type.NO_TYPE; 042 Format format = Format.NO_FORMAT; 043 Pattern pattern; 044 Number maximum, minimum, multipleOf; 045 Long maxLength, minLength, maxItems, minItems, maxProperties, minProperties; 046 Map<String,HttpPartSchemaBuilder> properties; 047 HttpPartSchemaBuilder items, additionalProperties; 048 boolean noValidate; 049 Class<? extends HttpPartParser> parser; 050 Class<? extends HttpPartSerializer> serializer; 051 052 /** 053 * Instantiates a new {@link HttpPartSchema} object based on the configuration of this builder. 054 * 055 * <p> 056 * This method can be called multiple times to produce new schema objects. 057 * 058 * @return 059 * A new {@link HttpPartSchema} object. 060 * <br>Never <jk>null</jk>. 061 */ 062 public HttpPartSchema build() { 063 return new HttpPartSchema(this); 064 } 065 066 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, ParamInfo mpi) { 067 apply(c, mpi.getParameterType().innerType()); 068 for (Annotation a : mpi.getDeclaredAnnotations()) 069 if (c.isInstance(a)) 070 apply(a); 071 return this; 072 } 073 074 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, Method m) { 075 apply(c, m.getGenericReturnType()); 076 Annotation a = m.getAnnotation(c); 077 if (a != null) 078 return apply(a); 079 return this; 080 } 081 082 HttpPartSchemaBuilder apply(Class<? extends Annotation> c, java.lang.reflect.Type t) { 083 if (t instanceof Class<?>) { 084 ClassInfo ci = ClassInfo.of((Class<?>)t); 085 for (Annotation a : ci.getAnnotationsParentFirst(c)) 086 apply(a); 087 } else if (Value.isType(t)) { 088 apply(c, Value.getParameterType(t)); 089 } 090 return this; 091 } 092 093 /** 094 * Apply the specified annotation to this schema. 095 * 096 * @param a The annotation to apply. 097 * @return This object (for method chaining). 098 */ 099 public HttpPartSchemaBuilder apply(Annotation a) { 100 if (a instanceof Body) 101 apply((Body)a); 102 else if (a instanceof Header) 103 apply((Header)a); 104 else if (a instanceof FormData) 105 apply((FormData)a); 106 else if (a instanceof Query) 107 apply((Query)a); 108 else if (a instanceof Path) 109 apply((Path)a); 110 else if (a instanceof Response) 111 apply((Response)a); 112 else if (a instanceof ResponseHeader) 113 apply((ResponseHeader)a); 114 else if (a instanceof HasQuery) 115 apply((HasQuery)a); 116 else if (a instanceof HasFormData) 117 apply((HasFormData)a); 118 else if (a instanceof Schema) 119 apply((Schema)a); 120 else 121 throw new RuntimeException("HttpPartSchemaBuilder.apply(@"+a.getClass().getSimpleName()+") not defined"); 122 return this; 123 } 124 125 HttpPartSchemaBuilder apply(Body a) { 126 required(a.required()); 127 allowEmptyValue(! a.required()); 128 apply(a.schema()); 129 return this; 130 } 131 132 HttpPartSchemaBuilder apply(Header a) { 133 name(a.value()); 134 name(a.name()); 135 required(a.required()); 136 type(a.type()); 137 format(a.format()); 138 allowEmptyValue(a.allowEmptyValue()); 139 items(a.items()); 140 collectionFormat(a.collectionFormat()); 141 _default(a._default().length == 0 ? null : joinnl(a._default())); 142 maximum(HttpPartSchema.toNumber(a.maximum())); 143 exclusiveMaximum(a.exclusiveMaximum()); 144 minimum(HttpPartSchema.toNumber(a.minimum())); 145 exclusiveMinimum(a.exclusiveMinimum()); 146 maxLength(a.maxLength()); 147 minLength(a.minLength()); 148 pattern(a.pattern()); 149 maxItems(a.maxItems()); 150 minItems(a.minItems()); 151 uniqueItems(a.uniqueItems()); 152 _enum(HttpPartSchema.toSet(a._enum())); 153 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 154 skipIfEmpty(a.skipIfEmpty()); 155 parser(a.parser()); 156 serializer(a.serializer()); 157 return this; 158 } 159 160 HttpPartSchemaBuilder apply(ResponseHeader a) { 161 name(a.value()); 162 name(a.name()); 163 codes(a.code()); 164 type(a.type()); 165 format(a.format()); 166 items(a.items()); 167 collectionFormat(a.collectionFormat()); 168 _default(a._default().length == 0 ? null : joinnl(a._default())); 169 maximum(HttpPartSchema.toNumber(a.maximum())); 170 exclusiveMaximum(a.exclusiveMaximum()); 171 minimum(HttpPartSchema.toNumber(a.minimum())); 172 exclusiveMinimum(a.exclusiveMinimum()); 173 maxLength(a.maxLength()); 174 minLength(a.minLength()); 175 pattern(a.pattern()); 176 maxItems(a.maxItems()); 177 minItems(a.minItems()); 178 uniqueItems(a.uniqueItems()); 179 _enum(HttpPartSchema.toSet(a._enum())); 180 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 181 allowEmptyValue(false); 182 serializer(a.serializer()); 183 return this; 184 } 185 186 HttpPartSchemaBuilder apply(FormData a) { 187 name(a.value()); 188 name(a.name()); 189 required(a.required()); 190 type(a.type()); 191 format(a.format()); 192 allowEmptyValue(a.allowEmptyValue()); 193 items(a.items()); 194 collectionFormat(a.collectionFormat()); 195 _default(a._default().length == 0 ? null : joinnl(a._default())); 196 maximum(HttpPartSchema.toNumber(a.maximum())); 197 exclusiveMaximum(a.exclusiveMaximum()); 198 minimum(HttpPartSchema.toNumber(a.minimum())); 199 exclusiveMinimum(a.exclusiveMinimum()); 200 maxLength(a.maxLength()); 201 minLength(a.minLength()); 202 pattern(a.pattern()); 203 maxItems(a.maxItems()); 204 minItems(a.minItems()); 205 uniqueItems(a.uniqueItems()); 206 _enum(HttpPartSchema.toSet(a._enum())); 207 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 208 skipIfEmpty(a.skipIfEmpty()); 209 parser(a.parser()); 210 serializer(a.serializer()); 211 return this; 212 } 213 214 HttpPartSchemaBuilder apply(Query a) { 215 name(a.value()); 216 name(a.name()); 217 required(a.required()); 218 type(a.type()); 219 format(a.format()); 220 allowEmptyValue(a.allowEmptyValue()); 221 items(a.items()); 222 collectionFormat(a.collectionFormat()); 223 _default(a._default().length == 0 ? null : joinnl(a._default())); 224 maximum(HttpPartSchema.toNumber(a.maximum())); 225 exclusiveMaximum(a.exclusiveMaximum()); 226 minimum(HttpPartSchema.toNumber(a.minimum())); 227 exclusiveMinimum(a.exclusiveMinimum()); 228 maxLength(a.maxLength()); 229 minLength(a.minLength()); 230 pattern(a.pattern()); 231 maxItems(a.maxItems()); 232 minItems(a.minItems()); 233 uniqueItems(a.uniqueItems()); 234 _enum(HttpPartSchema.toSet(a._enum())); 235 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 236 skipIfEmpty(a.skipIfEmpty()); 237 parser(a.parser()); 238 serializer(a.serializer()); 239 return this; 240 } 241 242 HttpPartSchemaBuilder apply(Path a) { 243 name(a.value()); 244 name(a.name()); 245 type(a.type()); 246 format(a.format()); 247 items(a.items()); 248 allowEmptyValue(a.allowEmptyValue()); 249 collectionFormat(a.collectionFormat()); 250 maximum(HttpPartSchema.toNumber(a.maximum())); 251 exclusiveMaximum(a.exclusiveMaximum()); 252 minimum(HttpPartSchema.toNumber(a.minimum())); 253 exclusiveMinimum(a.exclusiveMinimum()); 254 maxLength(a.maxLength()); 255 minLength(a.minLength()); 256 pattern(a.pattern()); 257 maxItems(a.maxItems()); 258 minItems(a.minItems()); 259 uniqueItems(a.uniqueItems()); 260 _enum(HttpPartSchema.toSet(a._enum())); 261 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 262 parser(a.parser()); 263 serializer(a.serializer()); 264 265 // Path remainder always allows empty value. 266 if (startsWith(name, '/')) 267 allowEmptyValue(); 268 else 269 required(true); 270 271 return this; 272 } 273 274 HttpPartSchemaBuilder apply(Response a) { 275 codes(a.value()); 276 codes(a.code()); 277 required(false); 278 allowEmptyValue(true); 279 serializer(a.partSerializer()); 280 parser(a.partParser()); 281 apply(a.schema()); 282 return this; 283 } 284 285 HttpPartSchemaBuilder apply(Items a) { 286 type(a.type()); 287 format(a.format()); 288 items(a.items()); 289 collectionFormat(a.collectionFormat()); 290 _default(a._default().length == 0 ? null : joinnl(a._default())); 291 maximum(HttpPartSchema.toNumber(a.maximum())); 292 exclusiveMaximum(a.exclusiveMaximum()); 293 minimum(HttpPartSchema.toNumber(a.minimum())); 294 exclusiveMinimum(a.exclusiveMinimum()); 295 maxLength(a.maxLength()); 296 minLength(a.minLength()); 297 pattern(a.pattern()); 298 maxItems(a.maxItems()); 299 minItems(a.minItems()); 300 uniqueItems(a.uniqueItems()); 301 _enum(HttpPartSchema.toSet(a._enum())); 302 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 303 return this; 304 } 305 306 HttpPartSchemaBuilder apply(SubItems a) { 307 type(a.type()); 308 format(a.format()); 309 items(HttpPartSchema.toObjectMap(a.items())); 310 collectionFormat(a.collectionFormat()); 311 _default(a._default().length == 0 ? null : joinnl(a._default())); 312 maximum(HttpPartSchema.toNumber(a.maximum())); 313 exclusiveMaximum(a.exclusiveMaximum()); 314 minimum(HttpPartSchema.toNumber(a.minimum())); 315 exclusiveMinimum(a.exclusiveMinimum()); 316 maxLength(a.maxLength()); 317 minLength(a.minLength()); 318 pattern(a.pattern()); 319 maxItems(a.maxItems()); 320 minItems(a.minItems()); 321 uniqueItems(a.uniqueItems()); 322 _enum(HttpPartSchema.toSet(a._enum())); 323 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 324 return this; 325 } 326 327 HttpPartSchemaBuilder apply(Schema a) { 328 type(a.type()); 329 format(a.format()); 330 items(a.items()); 331 collectionFormat(a.collectionFormat()); 332 _default(a._default().length == 0 ? null : joinnl(a._default())); 333 maximum(HttpPartSchema.toNumber(a.maximum())); 334 exclusiveMaximum(a.exclusiveMaximum()); 335 minimum(HttpPartSchema.toNumber(a.minimum())); 336 exclusiveMinimum(a.exclusiveMinimum()); 337 maxLength(a.maxLength()); 338 minLength(a.minLength()); 339 pattern(a.pattern()); 340 maxItems(a.maxItems()); 341 minItems(a.minItems()); 342 uniqueItems(a.uniqueItems()); 343 _enum(HttpPartSchema.toSet(a._enum())); 344 multipleOf(HttpPartSchema.toNumber(a.multipleOf())); 345 maxProperties(a.maxProperties()); 346 minProperties(a.minProperties()); 347 properties(HttpPartSchema.toObjectMap(a.properties())); 348 additionalProperties(HttpPartSchema.toObjectMap(a.additionalProperties())); 349 return this; 350 } 351 352 HttpPartSchemaBuilder apply(HasQuery a) { 353 name(a.value()); 354 name(a.name()); 355 return this; 356 } 357 358 HttpPartSchemaBuilder apply(HasFormData a) { 359 name(a.value()); 360 name(a.name()); 361 return this; 362 } 363 364 HttpPartSchemaBuilder apply(ObjectMap m) { 365 if (m != null && ! m.isEmpty()) { 366 _default(m.getString("default")); 367 _enum(HttpPartSchema.toSet(m.getString("enum"))); 368 allowEmptyValue(m.getBoolean("allowEmptyValue")); 369 exclusiveMaximum(m.getBoolean("exclusiveMaximum")); 370 exclusiveMinimum(m.getBoolean("exclusiveMinimum")); 371 required(m.getBoolean("required")); 372 uniqueItems(m.getBoolean("uniqueItems")); 373 collectionFormat(m.getString("collectionFormat")); 374 type(m.getString("type")); 375 format(m.getString("format")); 376 pattern(m.getString("pattern")); 377 maximum(m.get("maximum", Number.class)); 378 minimum(m.get("minimum", Number.class)); 379 multipleOf(m.get("multipleOf", Number.class)); 380 maxItems(m.get("maxItems", Long.class)); 381 maxLength(m.get("maxLength", Long.class)); 382 maxProperties(m.get("maxProperties", Long.class)); 383 minItems(m.get("minItems", Long.class)); 384 minLength(m.get("minLength", Long.class)); 385 minProperties(m.get("minProperties", Long.class)); 386 387 items(m.getObjectMap("items")); 388 properties(m.getObjectMap("properties")); 389 additionalProperties(m.getObjectMap("additionalProperties")); 390 391 apply(m.getObjectMap("schema", null)); 392 } 393 return this; 394 } 395 396 /** 397 * <mk>name</mk> field. 398 * 399 * <p> 400 * Applicable to the following Swagger schema objects: 401 * <ul> 402 * <li>{@doc SwaggerParameterObject Parameter} 403 * <li>{@doc SwaggerHeaderObject Header} 404 * </ul> 405 * 406 * @param value 407 * The new value for this property. 408 * @return This object (for method chaining). 409 */ 410 public HttpPartSchemaBuilder name(String value) { 411 if (isNotEmpty(value)) 412 name = value; 413 return this; 414 } 415 416 /** 417 * <mk>httpStatusCode</mk> key. 418 * 419 * <p> 420 * Applicable to the following Swagger schema objects: 421 * <ul> 422 * <li>{@doc SwaggerResponsesObject Responses} 423 * </ul> 424 * 425 * @param value 426 * The new value for this property. 427 * <br>Ignored if <jk>null</jk> or an empty array. 428 * @return This object (for method chaining). 429 */ 430 public HttpPartSchemaBuilder codes(int[] value) { 431 if (value != null && value.length != 0) 432 for (int v : value) 433 code(v); 434 return this; 435 } 436 437 /** 438 * <mk>httpStatusCode</mk> key. 439 * 440 * <p> 441 * Applicable to the following Swagger schema objects: 442 * <ul> 443 * <li>{@doc SwaggerResponsesObject Responses} 444 * </ul> 445 * 446 * @param value 447 * The new value for this property. 448 * <br>Ignored if value is <c>0</c>. 449 * @return This object (for method chaining). 450 */ 451 public HttpPartSchemaBuilder code(int value) { 452 if (value != 0) { 453 if (codes == null) 454 codes = new TreeSet<>(); 455 codes.add(value); 456 } 457 return this; 458 } 459 460 /** 461 * <mk>required</mk> field. 462 * 463 * <p> 464 * Determines whether the parameter is mandatory. 465 * 466 * <p> 467 * Applicable to the following Swagger schema objects: 468 * <ul> 469 * <li>{@doc SwaggerParameterObject Parameter} 470 * <li>{@doc SwaggerSchemaObject Schema} 471 * </ul> 472 * 473 * @param value 474 * The new value for this property. 475 * <br>Ignored if value is <jk>null</jk>. 476 * @return This object (for method chaining). 477 */ 478 public HttpPartSchemaBuilder required(Boolean value) { 479 required = resolve(value, required); 480 return this; 481 } 482 483 /** 484 * <mk>required</mk> field. 485 * 486 * <p> 487 * Determines whether the parameter is mandatory. 488 * 489 * <p> 490 * Same as {@link #required(Boolean)} but takes in a boolean value as a string. 491 * 492 * @param value 493 * The new value for this property. 494 * <br>Ignored if value is <jk>null</jk> or empty. 495 * @return This object (for method chaining). 496 */ 497 public HttpPartSchemaBuilder required(String value) { 498 required = resolve(value, required); 499 return this; 500 } 501 502 /** 503 * <mk>required</mk> field. 504 * 505 * <p> 506 * Shortcut for calling <code>required(<jk>true</jk>);</code>. 507 * 508 * @return This object (for method chaining). 509 */ 510 public HttpPartSchemaBuilder required() { 511 return required(true); 512 } 513 514 /** 515 * <mk>type</mk> field. 516 * 517 * <p> 518 * The type of the parameter. 519 * 520 * <p> 521 * The possible values are: 522 * <ul class='spaced-list'> 523 * <li> 524 * <js>"string"</js> 525 * <br>Parameter must be a string or a POJO convertible from a string. 526 * <li> 527 * <js>"number"</js> 528 * <br>Parameter must be a number primitive or number object. 529 * <br>If parameter is <c>Object</c>, creates either a <c>Float</c> or <c>Double</c> depending on the size of the number. 530 * <li> 531 * <js>"integer"</js> 532 * <br>Parameter must be a integer/long primitive or integer/long object. 533 * <br>If parameter is <c>Object</c>, creates either a <c>Short</c>, <c>Integer</c>, or <c>Long</c> depending on the size of the number. 534 * <li> 535 * <js>"boolean"</js> 536 * <br>Parameter must be a boolean primitive or object. 537 * <li> 538 * <js>"array"</js> 539 * <br>Parameter must be an array or collection. 540 * <br>Elements must be strings or POJOs convertible from strings. 541 * <br>If parameter is <c>Object</c>, creates an {@link ObjectList}. 542 * <li> 543 * <js>"object"</js> 544 * <br>Parameter must be a map or bean. 545 * <br>If parameter is <c>Object</c>, creates an {@link ObjectMap}. 546 * <br>Note that this is an extension of the OpenAPI schema as Juneau allows for arbitrarily-complex POJOs to be serialized as HTTP parts. 547 * <li> 548 * <js>"file"</js> 549 * <br>This type is currently not supported. 550 * </ul> 551 * 552 * <p> 553 * If the type is not specified, it will be auto-detected based on the parameter class type. 554 * 555 * <p> 556 * Applicable to the following Swagger schema objects: 557 * <ul> 558 * <li>{@doc SwaggerParameterObject Parameter} 559 * <li>{@doc SwaggerSchemaObject Schema} 560 * <li>{@doc SwaggerItemsObject Items} 561 * <li>{@doc SwaggerSecuritySchemeObject SecurityScheme} 562 * </ul> 563 * 564 * <ul class='seealso'> 565 * <li class='extlink'>{@doc SwaggerDataTypes} 566 * </ul> 567 * 568 * @param value 569 * The new value for this property. 570 * <br>Ignored if value is <jk>null</jk> or empty. 571 * @return This object (for method chaining). 572 */ 573 public HttpPartSchemaBuilder type(String value) { 574 try { 575 if (isNotEmpty(value)) 576 type = Type.fromString(value); 577 } catch (Exception e) { 578 throw new ContextRuntimeException("Invalid value ''{0}'' passed in as type value. Valid values: {1}", value, Type.values()); 579 } 580 return this; 581 } 582 583 /** 584 * <mk>format</mk> field. 585 * 586 * <p> 587 * The extending format for the previously mentioned {@doc SwaggerParameterTypes parameter type}. 588 * 589 * <p> 590 * The possible values are: 591 * <ul class='spaced-list'> 592 * <li> 593 * <js>"int32"</js> - Signed 32 bits. 594 * <br>Only valid with type <js>"integer"</js>. 595 * <li> 596 * <js>"int64"</js> - Signed 64 bits. 597 * <br>Only valid with type <js>"integer"</js>. 598 * <li> 599 * <js>"float"</js> - 32-bit floating point number. 600 * <br>Only valid with type <js>"number"</js>. 601 * <li> 602 * <js>"double"</js> - 64-bit floating point number. 603 * <br>Only valid with type <js>"number"</js>. 604 * <li> 605 * <js>"byte"</js> - BASE-64 encoded characters. 606 * <br>Only valid with type <js>"string"</js>. 607 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 608 * <li> 609 * <js>"binary"</js> - Hexadecimal encoded octets (e.g. <js>"00FF"</js>). 610 * <br>Only valid with type <js>"string"</js>. 611 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 612 * <li> 613 * <js>"binary-spaced"</js> - Hexadecimal encoded octets, spaced (e.g. <js>"00 FF"</js>). 614 * <br>Only valid with type <js>"string"</js>. 615 * <br>Parameters of type POJO convertible from string are converted after the string has been decoded. 616 * <li> 617 * <js>"date"</js> - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>. 618 * <br>Only valid with type <js>"string"</js>. 619 * <li> 620 * <js>"date-time"</js> - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>. 621 * <br>Only valid with type <js>"string"</js>. 622 * <li> 623 * <js>"password"</js> - Used to hint UIs the input needs to be obscured. 624 * <br>This format does not affect the serialization or parsing of the parameter. 625 * <li> 626 * <js>"uon"</js> - UON notation (e.g. <js>"(foo=bar,baz=@(qux,123))"</js>). 627 * <br>Only valid with type <js>"object"</js>. 628 * <br>If not specified, then the input is interpreted as plain-text and is converted to a POJO directly. 629 * </ul> 630 * 631 * <p> 632 * Applicable to the following Swagger schema objects: 633 * <ul> 634 * <li>{@doc SwaggerParameterObject Parameter} 635 * <li>{@doc SwaggerSchemaObject Schema} 636 * <li>{@doc SwaggerItemsObject Items} 637 * <li>{@doc SwaggerHeaderObject Header} 638 * </ul> 639 * 640 * <ul class='seealso'> 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 <c>type</c> is <js>"array"</js>. 718 * <br>Can only be used if <c>type</c> 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 <c>type</c> <js>"array"</js> is used. 764 * <br>Can only be used if <c>type</c> 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 <c>maximum</c>. 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 <c>minimum</c>. 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 <c>-1</c>. 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 <c>-1</c>. 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 <c>-1</c>. 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 <c>-1</c>. 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 <c>-1</c>. 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}