View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.bean.openapi3;
18  
19  import static org.apache.juneau.commons.utils.AssertionUtils.*;
20  import static org.apache.juneau.commons.utils.CollectionUtils.*;
21  import static org.apache.juneau.commons.utils.Utils.*;
22  import static org.apache.juneau.internal.ConverterUtils.*;
23  
24  import java.util.*;
25  
26  import org.apache.juneau.annotation.*;
27  import org.apache.juneau.commons.collections.*;
28  
29  /**
30   * Allows the definition of input and output data types.
31   *
32   * <p>
33   * The Schema Object allows the definition of input and output data types, including objects, primitives, and arrays.
34   * This object is an extended subset of the JSON Schema Specification Draft 4, with additional extensions provided
35   * by the OpenAPI Specification to allow for more complete documentation.
36   *
37   * <h5 class='section'>OpenAPI Specification:</h5>
38   * <p>
39   * The Schema Object supports all properties from JSON Schema Draft 4, including but not limited to:
40   * <ul class='spaced-list'>
41   * 	<li><c>type</c> (string) - The data type. Values: <js>"string"</js>, <js>"number"</js>, <js>"integer"</js>, <js>"boolean"</js>, <js>"array"</js>, <js>"object"</js>
42   * 	<li><c>format</c> (string) - The format modifier (e.g., <js>"int32"</js>, <js>"int64"</js>, <js>"float"</js>, <js>"double"</js>, <js>"date"</js>, <js>"date-time"</js>)
43   * 	<li><c>title</c> (string) - A short title for the schema
44   * 	<li><c>description</c> (string) - A description of the schema (CommonMark syntax may be used)
45   * 	<li><c>default</c> (any) - The default value
46   * 	<li><c>multipleOf</c> (number) - Must be a multiple of this value
47   * 	<li><c>maximum</c> (number) - Maximum value (inclusive by default)
48   * 	<li><c>exclusiveMaximum</c> (boolean) - If true, maximum is exclusive
49   * 	<li><c>minimum</c> (number) - Minimum value (inclusive by default)
50   * 	<li><c>exclusiveMinimum</c> (boolean) - If true, minimum is exclusive
51   * 	<li><c>maxLength</c> (integer) - Maximum string length
52   * 	<li><c>minLength</c> (integer) - Minimum string length
53   * 	<li><c>pattern</c> (string) - Regular expression pattern the string must match
54   * 	<li><c>maxItems</c> (integer) - Maximum array length
55   * 	<li><c>minItems</c> (integer) - Minimum array length
56   * 	<li><c>uniqueItems</c> (boolean) - If true, array items must be unique
57   * 	<li><c>maxProperties</c> (integer) - Maximum number of object properties
58   * 	<li><c>minProperties</c> (integer) - Minimum number of object properties
59   * 	<li><c>required</c> (array of string) - Required property names
60   * 	<li><c>enum</c> (array) - Possible values for this schema
61   * 	<li><c>properties</c> (map of {@link SchemaInfo}) - Object property definitions
62   * 	<li><c>items</c> ({@link Items}) - Schema for array items
63   * 	<li><c>allOf</c> (array of {@link SchemaInfo}) - Must validate against all schemas
64   * 	<li><c>oneOf</c> (array of {@link SchemaInfo}) - Must validate against exactly one schema
65   * 	<li><c>anyOf</c> (array of {@link SchemaInfo}) - Must validate against any schema
66   * 	<li><c>not</c> ({@link SchemaInfo}) - Must not validate against this schema
67   * 	<li><c>nullable</c> (boolean) - Allows the value to be null (OpenAPI 3.0 extension)
68   * 	<li><c>discriminator</c> ({@link Discriminator}) - Discriminator for polymorphism (OpenAPI extension)
69   * 	<li><c>readOnly</c> (boolean) - Relevant only for Schema properties (OpenAPI extension)
70   * 	<li><c>writeOnly</c> (boolean) - Relevant only for Schema properties (OpenAPI extension)
71   * 	<li><c>xml</c> ({@link Xml}) - XML representation details (OpenAPI extension)
72   * 	<li><c>externalDocs</c> ({@link ExternalDocumentation}) - Additional external documentation (OpenAPI extension)
73   * 	<li><c>example</c> (any) - Example value (OpenAPI extension)
74   * 	<li><c>deprecated</c> (boolean) - Specifies that the schema is deprecated (OpenAPI extension)
75   * </ul>
76   *
77   * <h5 class='section'>Example:</h5>
78   * <p class='bjava'>
79   * 	<jc>// Create a schema for a Pet object</jc>
80   * 	SchemaInfo <jv>schema</jv> = <jk>new</jk> SchemaInfo()
81   * 		.setType(<js>"object"</js>)
82   * 		.setRequired(<js>"id"</js>, <js>"name"</js>)
83   * 		.setProperties(
84   * 			JsonMap.<jsm>of</jsm>(
85   * 				<js>"id"</js>, <jk>new</jk> SchemaInfo().setType(<js>"integer"</js>).setFormat(<js>"int64"</js>),
86   * 				<js>"name"</js>, <jk>new</jk> SchemaInfo().setType(<js>"string"</js>),
87   * 				<js>"tag"</js>, <jk>new</jk> SchemaInfo().setType(<js>"string"</js>)
88   * 			)
89   * 		);
90   * </p>
91   *
92   * <h5 class='section'>See Also:</h5><ul>
93   * 	<li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#schema-object">OpenAPI Specification &gt; Schema Object</a>
94   * 	<li class='link'><a class="doclink" href="https://swagger.io/docs/specification/data-models/">OpenAPI Data Models</a>
95   * 	<li class='link'><a class="doclink" href="https://json-schema.org/">JSON Schema Specification</a>
96   * 	<li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
97   * </ul>
98   */
99  public class SchemaInfo extends OpenApiElement {
100 
101 	private String format, title, description, pattern, ref, type;
102 	private Number multipleOf, maximum, minimum;
103 	private Integer maxLength, minLength, maxItems, minItems, maxProperties, minProperties;
104 	private Boolean exclusiveMaximum, exclusiveMinimum, uniqueItems, nullable, writeOnly, readOnly, deprecated;
105 	private Object default_,
106 		example;
107 	private Items items;
108 	private Xml xml;
109 	private ExternalDocumentation externalDocs;
110 	private List<Object> allOf = list(), oneOf = list(), anyOf = list(), enum_ = list();
111 	private List<String> required = list();
112 	private Discriminator discriminator;
113 	private Map<String,SchemaInfo> properties;
114 	private SchemaInfo additionalProperties;
115 	private SchemaInfo not;
116 
117 	/**
118 	 * Default constructor.
119 	 */
120 	public SchemaInfo() {}
121 
122 	/**
123 	 * Copy constructor.
124 	 *
125 	 * @param copyFrom The object to copy.
126 	 */
127 	public SchemaInfo(SchemaInfo copyFrom) {
128 		super(copyFrom);
129 
130 		this.format = copyFrom.format;
131 		this.title = copyFrom.title;
132 		this.description = copyFrom.description;
133 		this.ref = copyFrom.ref;
134 		this.nullable = copyFrom.nullable;
135 		this.writeOnly = copyFrom.writeOnly;
136 		this.deprecated = copyFrom.deprecated;
137 		this.pattern = copyFrom.pattern;
138 		this.type = copyFrom.type;
139 		this.discriminator = copyFrom.discriminator;
140 		this.multipleOf = copyFrom.multipleOf;
141 		this.maximum = copyFrom.maximum;
142 		this.minimum = copyFrom.minimum;
143 		this.maxLength = copyFrom.maxLength;
144 		this.minLength = copyFrom.minLength;
145 		this.maxItems = copyFrom.maxItems;
146 		this.minItems = copyFrom.minItems;
147 		this.maxProperties = copyFrom.maxProperties;
148 		this.minProperties = copyFrom.minProperties;
149 		this.exclusiveMaximum = copyFrom.exclusiveMaximum;
150 		this.exclusiveMinimum = copyFrom.exclusiveMinimum;
151 		this.uniqueItems = copyFrom.uniqueItems;
152 		this.readOnly = copyFrom.readOnly;
153 		this.default_ = copyFrom.default_;
154 		this.example = copyFrom.example;
155 		this.items = copyFrom.items == null ? null : copyFrom.items.copy();
156 		this.xml = copyFrom.xml == null ? null : copyFrom.xml.copy();
157 		this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
158 		if (nn(copyFrom.enum_))
159 			enum_.addAll(copyFrom.enum_);
160 		if (nn(copyFrom.allOf))
161 			allOf.addAll(copyFrom.allOf);
162 		if (nn(copyFrom.required))
163 			required.addAll(copyFrom.required);
164 		if (nn(copyFrom.anyOf))
165 			anyOf.addAll(copyFrom.anyOf);
166 		if (nn(copyFrom.oneOf))
167 			oneOf.addAll(copyFrom.oneOf);
168 		this.properties = copyOf(copyFrom.properties, SchemaInfo::copy);
169 		this.additionalProperties = copyFrom.additionalProperties == null ? null : copyFrom.additionalProperties.copy();
170 		this.not = copyFrom.not == null ? null : copyFrom.not.copy();
171 	}
172 
173 	/**
174 	 * Adds one or more values to the <property>allOf</property> property.
175 	 *
176 	 * @param values
177 	 * 	The values to add to this property.
178 	 * 	<br>Valid types:
179 	 * 	<ul>
180 	 * 		<li><code>Object</code>
181 	 * 		<li><code>Collection&lt;Object&gt;</code>
182 	 * 		<li><code>String</code> - JSON array representation of <code>Collection&lt;Object&gt;</code>
183 	 * 			<h5 class='figure'>Example:</h5>
184 	 * 			<p class='bcode'>
185 	 * 	allOf(<js>"['foo','bar']"</js>);
186 	 * 			</p>
187 	 * 		<li><code>String</code> - Individual values
188 	 * 			<h5 class='figure'>Example:</h5>
189 	 * 			<p class='bcode'>
190 	 * 	allOf(<js>"foo"</js>, <js>"bar"</js>);
191 	 * 			</p>
192 	 * 	</ul>
193 	 * 	<br>Ignored if <jk>null</jk>.
194 	 * @return This object
195 	 */
196 	public SchemaInfo addAllOf(Object...values) {
197 		if (nn(values))
198 			for (var v : values)
199 				if (nn(v))
200 					allOf.add(v);
201 		return this;
202 	}
203 
204 	/**
205 	 * Adds one or more values to the <property>allOf</property> property.
206 	 *
207 	 * @param values
208 	 * 	The values to add to this property.
209 	 * 	<br>Valid types:
210 	 * 	<ul>
211 	 * 		<li><code>Object</code>
212 	 * 		<li><code>Collection&lt;Object&gt;</code>
213 	 * 		<li><code>String</code> - JSON array representation of <code>Collection&lt;Object&gt;</code>
214 	 * 			<h5 class='figure'>Example:</h5>
215 	 * 			<p class='bcode'>
216 	 * 	allOf(<js>"['foo','bar']"</js>);
217 	 * 			</p>
218 	 * 		<li><code>String</code> - Individual values
219 	 * 			<h5 class='figure'>Example:</h5>
220 	 * 			<p class='bcode'>
221 	 * 	allOf(<js>"foo"</js>, <js>"bar"</js>);
222 	 * 			</p>
223 	 * 	</ul>
224 	 * 	<br>Ignored if <jk>null</jk>.
225 	 * @return This object
226 	 */
227 	public SchemaInfo addAnyOf(Object...values) {
228 		if (nn(values))
229 			for (var v : values)
230 				if (nn(v))
231 					anyOf.add(v);
232 		return this;
233 	}
234 
235 	/**
236 	 * Adds one or more values to the <property>enum</property> property.
237 	 *
238 	 * @param values
239 	 * 	The values to add to this property.
240 	 * 	<br>Valid types:
241 	 * 	<ul>
242 	 * 		<li><code>Object</code>
243 	 * 		<li><code>Collection&lt;Object&gt;</code>
244 	 * 		<li><code>String</code> - JSON array representation of <code>Collection&lt;Object&gt;</code>
245 	 * 			<h5 class='figure'>Example:</h5>
246 	 * 			<p class='bcode'>
247 	 * 	enum_(<js>"['foo','bar']"</js>);
248 	 * 			</p>
249 	 * 		<li><code>String</code> - Individual values
250 	 * 			<h5 class='figure'>Example:</h5>
251 	 * 			<p class='bcode'>
252 	 * 	enum_(<js>"foo"</js>, <js>"bar"</js>);
253 	 * 			</p>
254 	 * 	</ul>
255 	 * 	<br>Ignored if <jk>null</jk>.
256 	 * @return This object
257 	 */
258 	public SchemaInfo addEnum(Object...values) {
259 		if (nn(values))
260 			for (var v : values)
261 				if (nn(v))
262 					enum_.add(v);
263 		return this;
264 	}
265 
266 	/**
267 	 * Adds one or more values to the <property>allOf</property> property.
268 	 *
269 	 * @param values
270 	 * 	The values to add to this property.
271 	 * 	<br>Valid types:
272 	 * 	<ul>
273 	 * 		<li><code>Object</code>
274 	 * 		<li><code>Collection&lt;Object&gt;</code>
275 	 * 		<li><code>String</code> - JSON array representation of <code>Collection&lt;Object&gt;</code>
276 	 * 			<h5 class='figure'>Example:</h5>
277 	 * 			<p class='bcode'>
278 	 * 	allOf(<js>"['foo','bar']"</js>);
279 	 * 			</p>
280 	 * 		<li><code>String</code> - Individual values
281 	 * 			<h5 class='figure'>Example:</h5>
282 	 * 			<p class='bcode'>
283 	 * 	allOf(<js>"foo"</js>, <js>"bar"</js>);
284 	 * 			</p>
285 	 * 	</ul>
286 	 * 	<br>Ignored if <jk>null</jk>.
287 	 * @return This object
288 	 */
289 	public SchemaInfo addOneOf(Object...values) {
290 		if (nn(values))
291 			for (var v : values)
292 				if (nn(v))
293 					oneOf.add(v);
294 		return this;
295 	}
296 
297 	/**
298 	 * Same as {@link #addRequired(String...)}.
299 	 *
300 	 * @param values
301 	 * 	The new value for this property.
302 	 * 	<br>Valid types:
303 	 * 	<ul>
304 	 * 		<li><code>Collection&lt;String&gt;</code>
305 	 * 		<li><code>String</code> - JSON array representation of <code>Collection&lt;String&gt;</code>
306 	 * 			<h5 class='figure'>Example:</h5>
307 	 * 			<p class='bcode'>
308 	 * 	schemes(<js>"['scheme1','scheme2']"</js>);
309 	 * 			</p>
310 	 * 		<li><code>String</code> - Individual values
311 	 * 			<h5 class='figure'>Example:</h5>
312 	 * 			<p class='bcode'>
313 	 * 	schemes(<js>"scheme1</js>, <js>"scheme2"</js>);
314 	 * 			</p>
315 	 * 	</ul>
316 	 * @return This object
317 	 */
318 	public SchemaInfo addRequired(String...values) {
319 		if (nn(values))
320 			for (var v : values)
321 				if (nn(v))
322 					required.add(v);
323 		return this;
324 	}
325 
326 	/**
327 	 * Make a deep copy of this object.
328 	 *
329 	 * @return A deep copy of this object.
330 	 */
331 	public SchemaInfo copy() {
332 		return new SchemaInfo(this);
333 	}
334 
335 	@Override /* Overridden from SwaggerElement */
336 	public <T> T get(String property, Class<T> type) {
337 		assertArgNotNull("property", property);
338 		return switch (property) {  // NOSONAR
339 			case "format" -> toType(getFormat(), type);
340 			case "title" -> toType(getTitle(), type);
341 			case "description" -> toType(getDescription(), type);
342 			case "default" -> toType(getDefault(), type);
343 			case "multipleOf" -> toType(getMultipleOf(), type);
344 			case "maximum" -> toType(getMaximum(), type);
345 			case "exclusiveMaximum" -> toType(getExclusiveMaximum(), type);
346 			case "minimum" -> toType(getMinimum(), type);
347 			case "exclusiveMinimum" -> toType(getExclusiveMinimum(), type);
348 			case "maxLength" -> toType(getMaxLength(), type);
349 			case "minLength" -> toType(getMinLength(), type);
350 			case "pattern" -> toType(getPattern(), type);
351 			case "maxItems" -> toType(getMaxItems(), type);
352 			case "minItems" -> toType(getMinItems(), type);
353 			case "uniqueItems" -> toType(getUniqueItems(), type);
354 			case "maxProperties" -> toType(getMaxProperties(), type);
355 			case "minProperties" -> toType(getMinProperties(), type);
356 			case "required" -> toType(getRequired(), type);
357 			case "enum" -> toType(getEnum(), type);
358 			case "type" -> toType(getType(), type);
359 			case "items" -> toType(getItems(), type);
360 			case "allOf" -> toType(getAllOf(), type);
361 			case "oneOf" -> toType(getOneOf(), type);
362 			case "anyOf" -> toType(getAnyOf(), type);
363 			case "properties" -> toType(getProperties(), type);
364 			case "additionalProperties" -> toType(getAdditionalProperties(), type);
365 			case "not" -> toType(getNot(), type);
366 			case "nullable" -> toType(getNullable(), type);
367 			case "deprecated" -> toType(getDeprecated(), type);
368 			case "discriminator" -> toType(getDiscriminator(), type);
369 			case "readOnly" -> toType(getReadOnly(), type);
370 			case "writeOnly" -> toType(getWriteOnly(), type);
371 			case "xml" -> toType(getXml(), type);
372 			case "externalDocs" -> toType(getExternalDocs(), type);
373 			case "example" -> toType(getExample(), type);
374 			case "$ref" -> toType(getRef(), type);
375 			default -> super.get(property, type);
376 		};
377 	}
378 
379 	/**
380 	 * Bean property getter:  <property>additionalProperties</property>.
381 	 *
382 	 * @return The property value, or <jk>null</jk> if it is not set.
383 	 */
384 	public SchemaInfo getAdditionalProperties() { return additionalProperties; }
385 
386 	/**
387 	 * Bean property getter:  <property>allOf</property>.
388 	 *
389 	 * @return The property value, or <jk>null</jk> if it is not set.
390 	 */
391 	public List<Object> getAllOf() { return nullIfEmpty(allOf); }
392 
393 	/**
394 	 * Bean property getter:  <property>allOf</property>.
395 	 *
396 	 * @return The property value, or <jk>null</jk> if it is not set.
397 	 */
398 	public List<Object> getAnyOf() { return nullIfEmpty(anyOf); }
399 
400 	/**
401 	 * Bean property getter:  <property>default</property>.
402 	 *
403 	 * <p>
404 	 * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object.
405 	 *
406 	 * @return The property value, or <jk>null</jk> if it is not set.
407 	 */
408 	public Object getDefault() { return default_; }
409 
410 	/**
411 	 * Bean property getter:  <property>deprecated</property>.
412 	 *
413 	 * @return The property value, or <jk>null</jk> if it is not set.
414 	 */
415 	public Boolean getDeprecated() { return deprecated; }
416 
417 	/**
418 	 * Bean property getter:  <property>description</property>.
419 	 *
420 	 * @return The property value, or <jk>null</jk> if it is not set.
421 	 */
422 	public String getDescription() { return description; }
423 
424 	/**
425 	 * Bean property getter:  <property>discriminator</property>.
426 	 *
427 	 * @return The property value, or <jk>null</jk> if it is not set.
428 	 */
429 	public Discriminator getDiscriminator() { return discriminator; }
430 
431 	/**
432 	 * Bean property getter:  <property>enum</property>.
433 	 *
434 	 * @return The property value, or <jk>null</jk> if it is not set.
435 	 */
436 	public List<Object> getEnum() { return nullIfEmpty(enum_); }
437 
438 	/**
439 	 * Bean property getter:  <property>example</property>.
440 	 *
441 	 * @return The property value, or <jk>null</jk> if it is not set.
442 	 */
443 	public Object getExample() { return example; }
444 
445 	/**
446 	 * Bean property getter:  <property>exclusiveMaximum</property>.
447 	 *
448 	 * @return The property value, or <jk>null</jk> if it is not set.
449 	 */
450 	public Boolean getExclusiveMaximum() { return exclusiveMaximum; }
451 
452 	/**
453 	 * Bean property getter:  <property>exclusiveMinimum</property>.
454 	 *
455 	 * @return The property value, or <jk>null</jk> if it is not set.
456 	 */
457 	public Boolean getExclusiveMinimum() { return exclusiveMinimum; }
458 
459 	/**
460 	 * Bean property getter:  <property>externalDocs</property>.
461 	 *
462 	 * @return The property value, or <jk>null</jk> if it is not set.
463 	 */
464 	public ExternalDocumentation getExternalDocs() { return externalDocs; }
465 
466 	/**
467 	 * Bean property getter:  <property>format</property>.
468 	 *
469 	 * @return The property value, or <jk>null</jk> if it is not set.
470 	 */
471 	public String getFormat() { return format; }
472 
473 	/**
474 	 * Bean property getter:  <property>items</property>.
475 	 *
476 	 * @return The property value, or <jk>null</jk> if it is not set.
477 	 */
478 	public Items getItems() { return items; }
479 
480 	/**
481 	 * Bean property getter:  <property>maximum</property>.
482 	 *
483 	 * @return The property value, or <jk>null</jk> if it is not set.
484 	 */
485 	public Number getMaximum() { return maximum; }
486 
487 	/**
488 	 * Bean property getter:  <property>maxItems</property>.
489 	 *
490 	 * @return The property value, or <jk>null</jk> if it is not set.
491 	 */
492 	public Integer getMaxItems() { return maxItems; }
493 
494 	/**
495 	 * Bean property getter:  <property>maxLength</property>.
496 	 *
497 	 * @return The property value, or <jk>null</jk> if it is not set.
498 	 */
499 	public Integer getMaxLength() { return maxLength; }
500 
501 	/**
502 	 * Bean property getter:  <property>maxProperties</property>.
503 	 *
504 	 * @return The property value, or <jk>null</jk> if it is not set.
505 	 */
506 	public Integer getMaxProperties() { return maxProperties; }
507 
508 	/**
509 	 * Bean property getter:  <property>minimum</property>.
510 	 *
511 	 * @return The property value, or <jk>null</jk> if it is not set.
512 	 */
513 	public Number getMinimum() { return minimum; }
514 
515 	/**
516 	 * Bean property getter:  <property>minItems</property>.
517 	 *
518 	 * @return The property value, or <jk>null</jk> if it is not set.
519 	 */
520 	public Integer getMinItems() { return minItems; }
521 
522 	/**
523 	 * Bean property getter:  <property>minLength</property>.
524 	 *
525 	 * @return The property value, or <jk>null</jk> if it is not set.
526 	 */
527 	public Integer getMinLength() { return minLength; }
528 
529 	/**
530 	 * Bean property getter:  <property>minProperties</property>.
531 	 *
532 	 * @return The property value, or <jk>null</jk> if it is not set.
533 	 */
534 	public Integer getMinProperties() { return minProperties; }
535 
536 	/**
537 	 * Bean property getter:  <property>multipleOf</property>.
538 	 *
539 	 * @return The property value, or <jk>null</jk> if it is not set.
540 	 */
541 	public Number getMultipleOf() { return multipleOf; }
542 
543 	/**
544 	 * Bean property getter:  <property>not</property>.
545 	 *
546 	 * @return The property value, or <jk>null</jk> if it is not set.
547 	 */
548 	public SchemaInfo getNot() { return not; }
549 
550 	/**
551 	 * Bean property getter:  <property>uniqueItems</property>.
552 	 *
553 	 * @return The property value, or <jk>null</jk> if it is not set.
554 	 */
555 	public Boolean getNullable() { return nullable; }
556 
557 	/**
558 	 * Bean property getter:  <property>allOf</property>.
559 	 *
560 	 * @return The property value, or <jk>null</jk> if it is not set.
561 	 */
562 	public List<Object> getOneOf() { return nullIfEmpty(oneOf); }
563 
564 	/**
565 	 * Bean property getter:  <property>pattern</property>.
566 	 *
567 	 * @return The property value, or <jk>null</jk> if it is not set.
568 	 */
569 	public String getPattern() { return pattern; }
570 
571 	/**
572 	 * Bean property getter:  <property>properties</property>.
573 	 *
574 	 * @return The property value, or <jk>null</jk> if it is not set.
575 	 */
576 	public Map<String,SchemaInfo> getProperties() { return properties; }
577 
578 	/**
579 	 * Bean property getter:  <property>readOnly</property>.
580 	 *
581 	 * @return The property value, or <jk>null</jk> if it is not set.
582 	 */
583 	public Boolean getReadOnly() { return readOnly; }
584 
585 	/**
586 	 * Bean property getter:  <property>$ref</property>.
587 	 *
588 	 * @return The property value, or <jk>null</jk> if it is not set.
589 	 */
590 	@Beanp("$ref")
591 	public String getRef() { return ref; }
592 
593 	/**
594 	 * Bean property getter:  <property>required</property>.
595 	 *
596 	 * <p>
597 	 * The list of required properties.
598 	 *
599 	 * @return The property value, or <jk>null</jk> if it is not set.
600 	 */
601 	public List<String> getRequired() { return nullIfEmpty(required); }
602 
603 	/**
604 	 * Bean property getter:  <property>title</property>.
605 	 *
606 	 * @return The property value, or <jk>null</jk> if it is not set.
607 	 */
608 	public String getTitle() { return title; }
609 
610 	/**
611 	 * Bean property getter:  <property>type</property>.
612 	 *
613 	 * @return The property value, or <jk>null</jk> if it is not set.
614 	 */
615 	public String getType() { return type; }
616 
617 	/**
618 	 * Bean property getter:  <property>uniqueItems</property>.
619 	 *
620 	 * @return The property value, or <jk>null</jk> if it is not set.
621 	 */
622 	public Boolean getUniqueItems() { return uniqueItems; }
623 
624 	/**
625 	 * Bean property getter:  <property>WriteOnly</property>.
626 	 *
627 	 * @return The property value, or <jk>null</jk> if it is not set.
628 	 */
629 	public Boolean getWriteOnly() { return writeOnly; }
630 
631 	/**
632 	 * Bean property getter:  <property>xml</property>.
633 	 *
634 	 * @return The property value, or <jk>null</jk> if it is not set.
635 	 */
636 	public Xml getXml() { return xml; }
637 
638 	@Override /* Overridden from SwaggerElement */
639 	public Set<String> keySet() {
640 		// @formatter:off
641 		var s = setb(String.class)
642 			.addIf(nn(ref), "$ref")
643 			.addIf(nn(additionalProperties), "additionalProperties")
644 			.addIf(ne(allOf), "allOf")
645 			.addIf(ne(anyOf), "anyOf")
646 			.addIf(nn(default_), "default")
647 			.addIf(nn(deprecated), "deprecated")
648 			.addIf(nn(description), "description")
649 			.addIf(nn(discriminator), "discriminator")
650 			.addIf(ne(enum_), "enum")
651 			.addIf(nn(example), "example")
652 			.addIf(nn(exclusiveMaximum), "exclusiveMaximum")
653 			.addIf(nn(exclusiveMinimum), "exclusiveMinimum")
654 			.addIf(nn(externalDocs), "externalDocs")
655 			.addIf(nn(format), "format")
656 			.addIf(nn(items), "items")
657 			.addIf(nn(maxItems), "maxItems")
658 			.addIf(nn(maxLength), "maxLength")
659 			.addIf(nn(maxProperties), "maxProperties")
660 			.addIf(nn(maximum), "maximum")
661 			.addIf(nn(minItems), "minItems")
662 			.addIf(nn(minLength), "minLength")
663 			.addIf(nn(minProperties), "minProperties")
664 			.addIf(nn(minimum), "minimum")
665 			.addIf(nn(multipleOf), "multipleOf")
666 			.addIf(nn(not), "not")
667 			.addIf(nn(nullable), "nullable")
668 			.addIf(ne(oneOf), "oneOf")
669 			.addIf(nn(pattern), "pattern")
670 			.addIf(nn(properties), "properties")
671 			.addIf(nn(readOnly), "readOnly")
672 			.addIf(ne(required), "required")
673 			.addIf(nn(title), "title")
674 			.addIf(nn(type), "type")
675 			.addIf(nn(uniqueItems), "uniqueItems")
676 			.addIf(nn(writeOnly), "writeOnly")
677 			.addIf(nn(xml), "xml")
678 			.build();
679 		// @formatter:on
680 		return new MultiSet<>(s, super.keySet());
681 	}
682 
683 	/**
684 	 * Resolves any <js>"$ref"</js> attributes in this element.
685 	 *
686 	 * @param openApi The swagger document containing the definitions.
687 	 * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops.
688 	 * @param maxDepth
689 	 * 	The maximum depth to resolve references.
690 	 * 	<br>After that level is reached, <code>$ref</code> references will be left alone.
691 	 * 	<br>Useful if you have very complex models and you don't want your swagger page to be overly-complex.
692 	 * @return
693 	 * 	This object with references resolved.
694 	 * 	<br>May or may not be the same object.
695 	 */
696 	public SchemaInfo resolveRefs(OpenApi openApi, Deque<String> refStack, int maxDepth) {
697 
698 		if (nn(ref)) {
699 			if (refStack.contains(ref) || refStack.size() >= maxDepth)
700 				return this;
701 			refStack.addLast(ref);
702 			var r = openApi.findRef(ref, SchemaInfo.class);
703 			r = r.resolveRefs(openApi, refStack, maxDepth);
704 			refStack.removeLast();
705 			return r;
706 		}
707 
708 		if (nn(items))
709 			items = items.resolveRefs(openApi, refStack, maxDepth);
710 
711 		if (nn(properties))
712 			for (var e : properties.entrySet())
713 				e.setValue(e.getValue().resolveRefs(openApi, refStack, maxDepth));
714 
715 		if (nn(additionalProperties))
716 			additionalProperties = additionalProperties.resolveRefs(openApi, refStack, maxDepth);
717 
718 		this.example = null;
719 
720 		return this;
721 	}
722 
723 	@Override /* Overridden from SwaggerElement */
724 	public SchemaInfo set(String property, Object value) {
725 		assertArgNotNull("property", property);
726 		return switch (property) {  // NOSONAR
727 			case "$ref" -> setRef(value);
728 			case "additionalProperties" -> setAdditionalProperties(toType(value, SchemaInfo.class));
729 			case "allOf" -> setAllOf(listb(Object.class).addAny(value).sparse().build());
730 			case "anyOf" -> setAnyOf(listb(Object.class).addAny(value).sparse().build());
731 			case "default" -> setDefault(value);
732 			case "deprecated" -> setDeprecated(toBoolean(value));
733 			case "description" -> setDescription(s(value));
734 			case "discriminator" -> setDiscriminator(toType(value, Discriminator.class));
735 			case "enum" -> setEnum(listb(Object.class).addAny(value).sparse().build());
736 			case "example" -> setExample(value);
737 			case "exclusiveMaximum" -> setExclusiveMaximum(toBoolean(value));
738 			case "exclusiveMinimum" -> setExclusiveMinimum(toBoolean(value));
739 			case "externalDocs" -> setExternalDocs(toType(value, ExternalDocumentation.class));
740 			case "format" -> setFormat(s(value));
741 			case "items" -> setItems(toType(value, Items.class));
742 			case "maxItems" -> setMaxItems(toInteger(value));
743 			case "maxLength" -> setMaxLength(toInteger(value));
744 			case "maxProperties" -> setMaxProperties(toInteger(value));
745 			case "maximum" -> setMaximum(toNumber(value));
746 			case "minItems" -> setMinItems(toInteger(value));
747 			case "minLength" -> setMinLength(toInteger(value));
748 			case "minProperties" -> setMinProperties(toInteger(value));
749 			case "minimum" -> setMinimum(toNumber(value));
750 			case "multipleOf" -> setMultipleOf(toNumber(value));
751 			case "not" -> setNot(toType(value, SchemaInfo.class));
752 			case "nullable" -> setNullable(toBoolean(value));
753 			case "oneOf" -> setOneOf(listb(Object.class).addAny(value).sparse().build());
754 			case "pattern" -> setPattern(s(value));
755 			case "properties" -> setProperties(toMapBuilder(value, String.class, SchemaInfo.class).sparse().build());
756 			case "readOnly" -> setReadOnly(toBoolean(value));
757 			case "required" -> setRequired(listb(String.class).addAny(value).sparse().build());
758 			case "title" -> setTitle(s(value));
759 			case "type" -> setType(s(value));
760 			case "uniqueItems" -> setUniqueItems(toBoolean(value));
761 			case "writeOnly" -> setWriteOnly(toBoolean(value));
762 			case "xml" -> setXml(toType(value, Xml.class));
763 			default -> {
764 				super.set(property, value);
765 				yield this;
766 			}
767 		};
768 	}
769 
770 	/**
771 	 * Bean property setter:  <property>additionalProperties</property>.
772 	 *
773 	 * @param value
774 	 * 	The new value for this property.
775 	 * 	<br>Can be <jk>null</jk> to unset the property.
776 	 * @return This object
777 	 */
778 	public SchemaInfo setAdditionalProperties(SchemaInfo value) {
779 		additionalProperties = value;
780 		return this;
781 	}
782 
783 	/**
784 	 * Bean property setter:  <property>allOf</property>.
785 	 *
786 	 * @param value
787 	 * 	The new value for this property.
788 	 * 	<br>Can be <jk>null</jk> to unset the property.
789 	 * @return This object
790 	 */
791 	public SchemaInfo setAllOf(Collection<Object> value) {
792 		allOf.clear();
793 		if (nn(value))
794 			allOf.addAll(value);
795 		return this;
796 	}
797 
798 	/**
799 	 * Bean property setter:  <property>allOf</property>.
800 	 *
801 	 * @param value
802 	 * 	The new value for this property.
803 	 * 	<br>Can be <jk>null</jk> to unset the property.
804 	 * @return This object
805 	 */
806 	public SchemaInfo setAnyOf(Collection<Object> value) {
807 		anyOf.clear();
808 		if (nn(value))
809 			anyOf.addAll(value);
810 		return this;
811 	}
812 
813 	/**
814 	 * Bean property setter:  <property>default</property>.
815 	 *
816 	 * <p>
817 	 * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object.
818 	 *
819 	 * @param value
820 	 * 	The new value for this property.
821 	 * 	<br>Can be <jk>null</jk> to unset the property.
822 	 * @return This object
823 	 */
824 	public SchemaInfo setDefault(Object value) {
825 		default_ = value;
826 		return this;
827 	}
828 
829 	/**
830 	 * Bean property setter:  <property>deprecated</property>.
831 	 *
832 	 * @param value
833 	 * 	The new value for this property.
834 	 * 	<br>Can be <jk>null</jk> to unset the property.
835 	 * @return This object
836 	 */
837 	public SchemaInfo setDeprecated(Boolean value) {
838 		deprecated = value;
839 		return this;
840 	}
841 
842 	/**
843 	 * Bean property setter:  <property>description</property>.
844 	 *
845 	 * @param value
846 	 * 	The new value for this property.
847 	 * 	<br>Can be <jk>null</jk> to unset the property.
848 	 * @return This object
849 	 */
850 	public SchemaInfo setDescription(String value) {
851 		description = value;
852 		return this;
853 	}
854 
855 	/**
856 	 * Bean property setter:  <property>discriminator</property>.
857 	 *
858 	 * @param value
859 	 * 	The new value for this property.
860 	 * 	<br>Can be <jk>null</jk> to unset the property.
861 	 * @return This object
862 	 */
863 	public SchemaInfo setDiscriminator(Discriminator value) {
864 		discriminator = value;
865 		return this;
866 	}
867 
868 	/**
869 	 * Bean property setter:  <property>enum</property>.
870 	 *
871 	 * @param value
872 	 * 	The new value for this property.
873 	 * 	<br>Can be <jk>null</jk> to unset the property.
874 	 * @return This object
875 	 */
876 	public SchemaInfo setEnum(Collection<Object> value) {
877 		enum_.clear();
878 		if (nn(value))
879 			enum_.addAll(value);
880 		return this;
881 	}
882 
883 	/**
884 	 * Bean property setter:  <property>example</property>.
885 	 *
886 	 * @param value
887 	 * 	The new value for this property.
888 	 * 	<br>Can be <jk>null</jk> to unset the property.
889 	 * @return This object
890 	 */
891 	public SchemaInfo setExample(Object value) {
892 		example = value;
893 		return this;
894 	}
895 
896 	/**
897 	 * Bean property setter:  <property>exclusiveMaximum</property>.
898 	 *
899 	 * @param value
900 	 * 	The new value for this property.
901 	 * 	<br>Can be <jk>null</jk> to unset the property.
902 	 * @return This object
903 	 */
904 	public SchemaInfo setExclusiveMaximum(Boolean value) {
905 		exclusiveMaximum = value;
906 		return this;
907 	}
908 
909 	/**
910 	 * Bean property setter:  <property>exclusiveMinimum</property>.
911 	 *
912 	 * @param value
913 	 * 	The new value for this property.
914 	 * 	<br>Can be <jk>null</jk> to unset the property.
915 	 * @return This object
916 	 */
917 	public SchemaInfo setExclusiveMinimum(Boolean value) {
918 		exclusiveMinimum = value;
919 		return this;
920 	}
921 
922 	/**
923 	 * Bean property setter:  <property>externalDocs</property>.
924 	 *
925 	 * @param value
926 	 * 	The new value for this property.
927 	 * 	<br>Can be <jk>null</jk> to unset the property.
928 	 * @return This object
929 	 */
930 	public SchemaInfo setExternalDocs(ExternalDocumentation value) {
931 		externalDocs = value;
932 		return this;
933 	}
934 
935 	/**
936 	 * Bean property setter:  <property>format</property>.
937 	 *
938 	 * @param value
939 	 * 	The new value for this property.
940 	 * 	<br>Can be <jk>null</jk> to unset the property.
941 	 * 	<br>Formats defined by the OAS include:
942 	 * 	<ul>
943 	 * 		<li><js>"int32"</js>
944 	 * 		<li><js>"int64"</js>
945 	 * 		<li><js>"float"</js>
946 	 * 		<li><js>"double"</js>
947 	 * 		<li><js>"byte"</js>
948 	 * 		<li><js>"binary"</js>
949 	 * 		<li><js>"date"</js>
950 	 * 		<li><js>"date-time"</js>
951 	 * 		<li><js>"password"</js>
952 	 * 	</ul>
953 	 * @return This object
954 	 */
955 	public SchemaInfo setFormat(String value) {
956 		format = value;
957 		return this;
958 	}
959 
960 	/**
961 	 * Bean property setter:  <property>items</property>.
962 	 *
963 	 * @param value
964 	 * 	The new value for this property.
965 	 * 	<br>Can be <jk>null</jk> to unset the property.
966 	 * @return This object
967 	 */
968 	public SchemaInfo setItems(Items value) {
969 		items = value;
970 		return this;
971 	}
972 
973 	/**
974 	 * Bean property setter:  <property>maximum</property>.
975 	 *
976 	 * @param value
977 	 * 	The new value for this property.
978 	 * 	<br>Can be <jk>null</jk> to unset the property.
979 	 * @return This object
980 	 */
981 	public SchemaInfo setMaximum(Number value) {
982 		maximum = value;
983 		return this;
984 	}
985 
986 	/**
987 	 * Bean property setter:  <property>maxItems</property>.
988 	 *
989 	 * @param value
990 	 * 	The new value for this property.
991 	 * 	<br>Can be <jk>null</jk> to unset the property.
992 	 * @return This object
993 	 */
994 	public SchemaInfo setMaxItems(Integer value) {
995 		maxItems = value;
996 		return this;
997 	}
998 
999 	/**
1000 	 * Bean property setter:  <property>maxLength</property>.
1001 	 *
1002 	 * @param value
1003 	 * 	The new value for this property.
1004 	 * 	<br>Can be <jk>null</jk> to unset the property.
1005 	 * @return This object
1006 	 */
1007 	public SchemaInfo setMaxLength(Integer value) {
1008 		maxLength = value;
1009 		return this;
1010 	}
1011 
1012 	/**
1013 	 * Bean property setter:  <property>maxProperties</property>.
1014 	 *
1015 	 * @param value
1016 	 * 	The new value for this property.
1017 	 * 	<br>Can be <jk>null</jk> to unset the property.
1018 	 * @return This object
1019 	 */
1020 	public SchemaInfo setMaxProperties(Integer value) {
1021 		maxProperties = value;
1022 		return this;
1023 	}
1024 
1025 	/**
1026 	 * Bean property setter:  <property>minimum</property>.
1027 	 *
1028 	 * @param value
1029 	 * 	The new value for this property.
1030 	 * 	<br>Can be <jk>null</jk> to unset the property.
1031 	 * @return This object
1032 	 */
1033 	public SchemaInfo setMinimum(Number value) {
1034 		minimum = value;
1035 		return this;
1036 	}
1037 
1038 	/**
1039 	 * Bean property setter:  <property>minItems</property>.
1040 	 *
1041 	 * @param value
1042 	 * 	The new value for this property.
1043 	 * 	<br>Can be <jk>null</jk> to unset the property.
1044 	 * @return This object
1045 	 */
1046 	public SchemaInfo setMinItems(Integer value) {
1047 		minItems = value;
1048 		return this;
1049 	}
1050 
1051 	/**
1052 	 * Bean property setter:  <property>minLength</property>.
1053 	 *
1054 	 * @param value
1055 	 * 	The new value for this property.
1056 	 * 	<br>Can be <jk>null</jk> to unset the property.
1057 	 * @return This object
1058 	 */
1059 	public SchemaInfo setMinLength(Integer value) {
1060 		minLength = value;
1061 		return this;
1062 	}
1063 
1064 	/**
1065 	 * Bean property setter:  <property>minProperties</property>.
1066 	 *
1067 	 * @param value
1068 	 * 	The new value for this property.
1069 	 * 	<br>Can be <jk>null</jk> to unset the property.
1070 	 * @return This object
1071 	 */
1072 	public SchemaInfo setMinProperties(Integer value) {
1073 		minProperties = value;
1074 		return this;
1075 	}
1076 
1077 	/**
1078 	 * Bean property setter:  <property>multipleOf</property>.
1079 	 *
1080 	 * @param value
1081 	 * 	The new value for this property.
1082 	 * 	<br>Can be <jk>null</jk> to unset the property.
1083 	 * @return This object
1084 	 */
1085 	public SchemaInfo setMultipleOf(Number value) {
1086 		multipleOf = value;
1087 		return this;
1088 	}
1089 
1090 	/**
1091 	 * Bean property setter:  <property>not</property>.
1092 	 *
1093 	 * @param value
1094 	 * 	The new value for this property.
1095 	 * 	<br>Can be <jk>null</jk> to unset the property.
1096 	 * @return This object
1097 	 */
1098 	public SchemaInfo setNot(SchemaInfo value) {
1099 		not = value;
1100 		return this;
1101 	}
1102 
1103 	/**
1104 	 * Bean property setter:  <property>nullable</property>.
1105 	 *
1106 	 * @param value
1107 	 * 	The new value for this property.
1108 	 * 	<br>Can be <jk>null</jk> to unset the property.
1109 	 * @return This object
1110 	 */
1111 	public SchemaInfo setNullable(Boolean value) {
1112 		nullable = value;
1113 		return this;
1114 	}
1115 
1116 	/**
1117 	 * Bean property setter:  <property>allOf</property>.
1118 	 *
1119 	 * @param value
1120 	 * 	The new value for this property.
1121 	 * 	<br>Can be <jk>null</jk> to unset the property.
1122 	 * @return This object
1123 	 */
1124 	public SchemaInfo setOneOf(Collection<Object> value) {
1125 		oneOf.clear();
1126 		if (nn(value))
1127 			oneOf.addAll(value);
1128 		return this;
1129 	}
1130 
1131 	/**
1132 	 * Bean property setter:  <property>pattern</property>.
1133 	 *
1134 	 * <p>
1135 	 * This string SHOULD be a valid regular expression.
1136 	 *
1137 	 * @param value
1138 	 * 	The new value for this property.
1139 	 * 	<br>Can be <jk>null</jk> to unset the property.
1140 	 * @return This object
1141 	 */
1142 	public SchemaInfo setPattern(String value) {
1143 		pattern = value;
1144 		return this;
1145 	}
1146 
1147 	/**
1148 	 * Bean property setter:  <property>properties</property>.
1149 	 *
1150 	 * @param value
1151 	 * 	The new value for this property.
1152 	 * 	<br>Can be <jk>null</jk> to unset the property.
1153 	 * @return This object
1154 	 */
1155 	public SchemaInfo setProperties(Map<String,SchemaInfo> value) {
1156 		properties = copyOf(value);
1157 		return this;
1158 	}
1159 
1160 	/**
1161 	 * Bean property setter:  <property>readOnly</property>.
1162 	 *
1163 	 * @param value
1164 	 * 	The new value for this property.
1165 	 * 	<br>Can be <jk>null</jk> to unset the property.
1166 	 * @return This object
1167 	 */
1168 	public SchemaInfo setReadOnly(Boolean value) {
1169 		readOnly = value;
1170 		return this;
1171 	}
1172 
1173 	/**
1174 	 * Bean property setter:  <property>$ref</property>.
1175 	 *
1176 	 * @param value
1177 	 * 	The new value for this property.
1178 	 * 	<br>Can be <jk>null</jk> to unset the property.
1179 	 * @return This object
1180 	 */
1181 	@Beanp("$ref")
1182 	public SchemaInfo setRef(Object value) {
1183 		ref = s(value);
1184 		return this;
1185 	}
1186 
1187 	/**
1188 	 * Bean property setter:  <property>required</property>.
1189 	 *
1190 	 * <p>
1191 	 * The list of required properties.
1192 	 *
1193 	 * @param value
1194 	 * 	The new value for this property.
1195 	 * 	<br>Valid values:
1196 	 * 	<ul>
1197 	 * 		<li><js>"http"</js>
1198 	 * 		<li><js>"https"</js>
1199 	 * 		<li><js>"ws"</js>
1200 	 * 		<li><js>"wss"</js>
1201 	 * 	</ul>
1202 	 * 	<br>Can be <jk>null</jk> to unset the property.
1203 	 * @return This object
1204 	 */
1205 	public SchemaInfo setRequired(Collection<String> value) {
1206 		required.clear();
1207 		if (nn(value))
1208 			required.addAll(value);
1209 		return this;
1210 	}
1211 
1212 	/**
1213 	 * Bean property setter:  <property>title</property>.
1214 	 *
1215 	 * @param value
1216 	 * 	The new value for this property.
1217 	 * 	<br>Can be <jk>null</jk> to unset the property.
1218 	 * @return This object
1219 	 */
1220 	public SchemaInfo setTitle(String value) {
1221 		title = value;
1222 		return this;
1223 	}
1224 
1225 	/**
1226 	 * Bean property setter:  <property>type</property>.
1227 	 *
1228 	 * @param value
1229 	 * 	The new value for this property.
1230 	 * 	<br>Can be <jk>null</jk> to unset the property.
1231 	 * 	<br>Possible values include:
1232 	 * 	<ul>
1233 	 * 		<li><js>"object"</js>
1234 	 * 		<li><js>"string"</js>
1235 	 * 		<li><js>"number"</js>
1236 	 * 		<li><js>"integer"</js>
1237 	 * 		<li><js>"boolean"</js>
1238 	 * 		<li><js>"array"</js>
1239 	 * 		<li><js>"file"</js>
1240 	 * 	</ul>
1241 	 * @return This object
1242 	 */
1243 	public SchemaInfo setType(String value) {
1244 		type = value;
1245 		return this;
1246 	}
1247 
1248 	/**
1249 	 * Bean property setter:  <property>uniqueItems</property>.
1250 	 *
1251 	 * @param value
1252 	 * 	The new value for this property.
1253 	 * 	<br>Can be <jk>null</jk> to unset the property.
1254 	 * @return This object
1255 	 */
1256 	public SchemaInfo setUniqueItems(Boolean value) {
1257 		uniqueItems = value;
1258 		return this;
1259 	}
1260 
1261 	/**
1262 	 * Bean property setter:  <property>WriteOnly</property>.
1263 	 *
1264 	 * @param value
1265 	 * 	The new value for this property.
1266 	 * 	<br>Can be <jk>null</jk> to unset the property.
1267 	 * @return This object
1268 	 */
1269 	public SchemaInfo setWriteOnly(Boolean value) {
1270 		writeOnly = value;
1271 		return this;
1272 	}
1273 
1274 	/**
1275 	 * Bean property setter:  <property>xml</property>.
1276 	 *
1277 	 * @param value
1278 	 * 	The new value for this property.
1279 	 * 	<br>Can be <jk>null</jk> to unset the property.
1280 	 * @return This object
1281 	 */
1282 	public SchemaInfo setXml(Xml value) {
1283 		xml = value;
1284 		return this;
1285 	}
1286 
1287 	@Override /* Overridden from OpenApiElement */
1288 	public SchemaInfo strict() {
1289 		super.strict();
1290 		return this;
1291 	}
1292 
1293 	@Override /* Overridden from OpenApiElement */
1294 	public SchemaInfo strict(Object value) {
1295 		super.strict(value);
1296 		return this;
1297 	}
1298 }