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