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