diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
index b20a55a7a9..8f9ff40168 100644
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -20,7 +20,7 @@
public class MavenWrapperDownloader {
- private static final String WRAPPER_VERSION = "0.5.3";
+ private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 84472b532a..6cbe900624 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,2 +1,2 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.6.jar
diff --git a/README.md b/README.md
index 5e2c27e118..bd0eae4810 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ You need the following installed and available in your $PATH:
* Jackson 2.4.5 or greater
-### To build from source (currently 2.1.14-SNAPSHOT)
+### To build from source (currently 2.2.0-SNAPSHOT)
```
# first time building locally
mvn -N
diff --git a/modules/swagger-annotations/pom.xml b/modules/swagger-annotations/pom.xml
index b7a51bdf7a..e145110fe9 100644
--- a/modules/swagger-annotations/pom.xml
+++ b/modules/swagger-annotations/pom.xml
@@ -3,7 +3,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
4.0.0
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Content.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Content.java
index c4468e26b1..583f53149b 100644
--- a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Content.java
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Content.java
@@ -62,6 +62,22 @@
**/
Schema schema() default @Schema();
+ /**
+ * The schema properties defined for schema provided in @Schema
+ *
+ * @since 2.2.0
+ * @return the schema properties
+ */
+ SchemaProperty[] schemaProperties() default {};
+
+ /**
+ * The schema properties defined for schema provided in @Schema
+ *
+ * @since 2.2.0
+ * @return the schema properties
+ */
+ Schema additionalPropertiesSchema() default @Schema();
+
/**
* The schema of the array that defines the type used for the content.
*
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperties.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperties.java
new file mode 100644
index 0000000000..4b93a3cb12
--- /dev/null
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperties.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2017 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations.media;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * Container for repeatable {@link PatternProperty} annotation
+ *
+ * @see PatternProperty
+ */
+@Target({FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface PatternProperties {
+ /**
+ * An array of PatternProperty annotations
+ *
+ * @return the array of the PatternProperty
+ **/
+ PatternProperty[] value() default {};
+
+}
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperty.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperty.java
new file mode 100644
index 0000000000..10ee8f1adf
--- /dev/null
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/PatternProperty.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2021 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations.media;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * The annotation may be used in OpenAPI 3.1 schemas / JSON Schema.
+ *
+ * @see JSON Schema section 10.3.2.2
+ * @see Schema
+ *
+ * @since 2.1.8
+ **/
+@Target({FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Repeatable(PatternProperties.class)
+public @interface PatternProperty {
+ /**
+ * The regex.
+ *
+ * @return the regex
+ **/
+ String regex() default "";
+
+ /**
+ * The schema to validate against for properties matching the regex.
+ *
+ * @return the schema
+ **/
+ Schema schema() default @Schema();
+
+ /**
+ * The schema of the array to validate against for properties matching the regex.
+ *
+ * @return the schema of the array
+ */
+ ArraySchema array() default @ArraySchema();
+
+}
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Schema.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Schema.java
index 244d3fe92c..3e6c989020 100644
--- a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Schema.java
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/Schema.java
@@ -23,7 +23,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import java.nio.file.AccessMode;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
@@ -329,10 +328,29 @@
*/
Extension[] extensions() default {};
+ /**
+ * Allows to specify the additionalProperties value
+ *
+ * AdditionalPropertiesValue.TRUE: set to TRUE
+ * AdditionalPropertiesValue.FALSE: set to FALSE
+ * AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION: resolve from @Content.additionalPropertiesSchema
+ *
+ * @since 2.2.0
+ * @return the accessMode for this schema (property)
+ *
+ */
+ AdditionalPropertiesValue additionalProperties() default AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION;
+
enum AccessMode {
AUTO,
READ_ONLY,
WRITE_ONLY,
READ_WRITE;
}
+
+ enum AdditionalPropertiesValue {
+ TRUE,
+ FALSE,
+ USE_ADDITIONAL_PROPERTIES_ANNOTATION;
+ }
}
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperties.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperties.java
new file mode 100644
index 0000000000..62ff05b84e
--- /dev/null
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperties.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2017 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations.media;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * Container for repeatable {@link SchemaProperty} annotation
+ *
+ * @see SchemaProperty
+ */
+@Target({FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface SchemaProperties {
+ /**
+ * An array of SchemaProperty annotations
+ *
+ * @return the array of the SchemaProperty
+ **/
+ SchemaProperty[] value() default {};
+
+}
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperty.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperty.java
new file mode 100644
index 0000000000..33dd07617c
--- /dev/null
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/media/SchemaProperty.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2021 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations.media;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * The annotation may be used to define properties for an Object Schema
+ *
+ * @see Schema
+ *
+ * @since 2.1.8
+ **/
+@Target({FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Repeatable(SchemaProperties.class)
+public @interface SchemaProperty {
+ /**
+ * The name.
+ *
+ * @return the name
+ **/
+ String name() default "";
+
+ /**
+ * The schema of the property.
+ *
+ * @return the schema
+ **/
+ Schema schema() default @Schema();
+
+ /**
+ * The schema of the array.
+ *
+ * @return the schema of the array
+ */
+ ArraySchema array() default @ArraySchema();
+
+}
diff --git a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/responses/ApiResponse.java b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/responses/ApiResponse.java
index 9a9ed97ba4..5a5af16036 100644
--- a/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/responses/ApiResponse.java
+++ b/modules/swagger-annotations/src/main/java/io/swagger/v3/oas/annotations/responses/ApiResponse.java
@@ -96,4 +96,11 @@
**/
String ref() default "";
+ /**
+ * Set to true to resolve the response schema from method return type
+ *
+ * @since 2.2.0
+ **/
+ boolean useReturnTypeSchema() default false;
+
}
diff --git a/modules/swagger-core/pom.xml b/modules/swagger-core/pom.xml
index f7de61f09f..1b67144d0a 100644
--- a/modules/swagger-core/pom.xml
+++ b/modules/swagger-core/pom.xml
@@ -3,7 +3,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
4.0.0
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverters.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverters.java
index ec479d7505..0cbb130b64 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverters.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverters.java
@@ -97,14 +97,7 @@ public ResolvedSchema readAllAsResolvedSchema(Type type) {
}
public ResolvedSchema readAllAsResolvedSchema(AnnotatedType type) {
if (shouldProcess(type.getType())) {
- ModelConverterContextImpl context = new ModelConverterContextImpl(
- converters);
-
- ResolvedSchema resolvedSchema = new ResolvedSchema();
- resolvedSchema.schema = context.resolve(type);
- resolvedSchema.referencedSchemas = context.getDefinedModels();
-
- return resolvedSchema;
+ return resolveAsResolvedSchema(type);
}
return null;
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/CallbackSerializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/CallbackSerializer.java
index 374f658bd1..9d3dd5757c 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/CallbackSerializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/CallbackSerializer.java
@@ -18,16 +18,19 @@ public void serialize(
Callback value, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
+ // has extensions
if (value != null && value.getExtensions() != null && !value.getExtensions().isEmpty()) {
jgen.writeStartObject();
+ // not a ref
if (StringUtils.isBlank(value.get$ref())) {
if (!value.isEmpty()) {
+ // write map
for (Entry entry: value.entrySet()) {
jgen.writeObjectField(entry.getKey() , entry.getValue());
}
}
- } else { // handle ref schema serialization skipping all other props
+ } else { // handle ref schema serialization skipping all other props ...
jgen.writeStringField("$ref", value.get$ref());
}
for (String ext: value.getExtensions().keySet()) {
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java
index 3884c6d418..3137167397 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java
@@ -39,6 +39,10 @@
import io.swagger.v3.core.util.ReflectionUtils;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
+import io.swagger.v3.oas.annotations.media.PatternProperties;
+import io.swagger.v3.oas.annotations.media.PatternProperty;
+import io.swagger.v3.oas.annotations.media.SchemaProperties;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.media.ArraySchema;
@@ -95,6 +99,7 @@
import static io.swagger.v3.core.util.RefUtils.constructRef;
public class ModelResolver extends AbstractModelConverter implements ModelConverter {
+
Logger LOGGER = LoggerFactory.getLogger(ModelResolver.class);
public static List NOT_NULL_ANNOTATIONS = Arrays.asList("NotNull", "NonNull", "NotBlank", "NotEmpty");
@@ -766,6 +771,25 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
}
}
+ Map patternProperties = resolvePatternProperties(type, annotatedType.getCtxAnnotations(), context);
+ if (model != null && patternProperties != null && !patternProperties.isEmpty()) {
+ if (model.getPatternProperties() == null) {
+ model.patternProperties(patternProperties);
+ } else {
+ model.getPatternProperties().putAll(patternProperties);
+ }
+ }
+
+
+ Map schemaProperties = resolveSchemaProperties(type, annotatedType.getCtxAnnotations(), context);
+ if (model != null && schemaProperties != null && !schemaProperties.isEmpty()) {
+ if (model.getProperties() == null) {
+ model.properties(schemaProperties);
+ } else {
+ model.getProperties().putAll(schemaProperties);
+ }
+ }
+
if (isComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) model;
@@ -1522,6 +1546,104 @@ protected String resolveFormat(Annotated a, Annotation[] annotations, io.swagger
return null;
}
+ protected Map resolvePatternProperties(JavaType a, Annotation[] annotations, ModelConverterContext context) {
+
+ final Map propList = new LinkedHashMap<>();
+
+ PatternProperties props = a.getRawClass().getAnnotation(PatternProperties.class);
+ if (props != null && props.value().length > 0) {
+ for (PatternProperty prop: props.value()) {
+ propList.put(prop.regex(), prop);
+ }
+ }
+ PatternProperty singleProp = a.getRawClass().getAnnotation(PatternProperty.class);
+ if (singleProp != null) {
+ propList.put(singleProp.regex(), singleProp);
+ }
+ props = AnnotationsUtils.getAnnotation(PatternProperties.class, annotations);
+ if (props != null && props.value().length > 0) {
+ for (PatternProperty prop: props.value()) {
+ propList.put(prop.regex(), prop);
+ }
+ }
+ singleProp = AnnotationsUtils.getAnnotation(PatternProperty.class, annotations);
+ if (singleProp != null) {
+ propList.put(singleProp.regex(), singleProp);
+ }
+
+ if (propList.isEmpty()) {
+ return null;
+ }
+
+ Map patternProperties = new LinkedHashMap<>();
+
+ for (PatternProperty prop: propList.values()) {
+ String key = prop.regex();
+ if (StringUtils.isBlank(key)) {
+ continue;
+ }
+ Annotation[] propAnnotations = new Annotation[]{prop.schema(), prop.array()};
+ AnnotatedType propType = new AnnotatedType()
+ .type(String.class)
+ .ctxAnnotations(propAnnotations)
+ .resolveAsRef(true);
+ Schema resolvedPropSchema = context.resolve(propType);
+ if (resolvedPropSchema != null) {
+ patternProperties.put(key, resolvedPropSchema);
+ }
+ }
+ return patternProperties;
+ }
+
+ protected Map resolveSchemaProperties(JavaType a, Annotation[] annotations, ModelConverterContext context) {
+
+ final Map propList = new LinkedHashMap<>();
+
+ SchemaProperties props = a.getRawClass().getAnnotation(SchemaProperties.class);
+ if (props != null && props.value().length > 0) {
+ for (SchemaProperty prop: props.value()) {
+ propList.put(prop.name(), prop);
+ }
+ }
+ SchemaProperty singleProp = a.getRawClass().getAnnotation(SchemaProperty.class);
+ if (singleProp != null) {
+ propList.put(singleProp.name(), singleProp);
+ }
+ props = AnnotationsUtils.getAnnotation(SchemaProperties.class, annotations);
+ if (props != null && props.value().length > 0) {
+ for (SchemaProperty prop: props.value()) {
+ propList.put(prop.name(), prop);
+ }
+ }
+ singleProp = AnnotationsUtils.getAnnotation(SchemaProperty.class, annotations);
+ if (singleProp != null) {
+ propList.put(singleProp.name(), singleProp);
+ }
+
+ if (propList.isEmpty()) {
+ return null;
+ }
+
+ Map schemaProperties = new LinkedHashMap<>();
+
+ for (SchemaProperty prop: propList.values()) {
+ String key = prop.name();
+ if (StringUtils.isBlank(key)) {
+ continue;
+ }
+ Annotation[] propAnnotations = new Annotation[]{prop.schema(), prop.array()};
+ AnnotatedType propType = new AnnotatedType()
+ .type(String.class)
+ .ctxAnnotations(propAnnotations)
+ .resolveAsRef(true);
+ Schema resolvedPropSchema = context.resolve(propType);
+ if (resolvedPropSchema != null) {
+ schemaProperties.put(key, resolvedPropSchema);
+ }
+ }
+ return schemaProperties;
+ }
+
protected Object resolveDefaultValue(Annotated a, Annotation[] annotations, io.swagger.v3.oas.annotations.media.Schema schema) {
if (schema != null) {
if (!schema.defaultValue().isEmpty()) {
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/Schema31Serializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/Schema31Serializer.java
new file mode 100644
index 0000000000..a582b5ce96
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/Schema31Serializer.java
@@ -0,0 +1,41 @@
+package io.swagger.v3.core.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.ResolvableSerializer;
+import io.swagger.v3.oas.models.media.Schema;
+
+import java.io.IOException;
+
+public class Schema31Serializer extends JsonSerializer implements ResolvableSerializer {
+
+ private JsonSerializer defaultSerializer;
+
+ public Schema31Serializer(JsonSerializer serializer) {
+ defaultSerializer = serializer;
+ }
+
+ @Override
+ public void resolve(SerializerProvider serializerProvider) throws JsonMappingException {
+ if (defaultSerializer instanceof ResolvableSerializer) {
+ ((ResolvableSerializer) defaultSerializer).resolve(serializerProvider);
+ }
+ }
+
+ @Override
+ public void serialize(
+ Schema value, JsonGenerator jgen, SerializerProvider provider)
+ throws IOException {
+
+ if (value.getExampleSetFlag() && value.getExample() == null) {
+ jgen.writeStartObject();
+ defaultSerializer.unwrappingSerializer(null).serialize(value, jgen, provider);
+ jgen.writeNullField("example");
+ jgen.writeEndObject();
+ } else {
+ defaultSerializer.serialize(value, jgen, provider);
+ }
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Components31Mixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Components31Mixin.java
new file mode 100644
index 0000000000..71945ebeec
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Components31Mixin.java
@@ -0,0 +1,22 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import io.swagger.v3.core.jackson.CallbackSerializer;
+import io.swagger.v3.oas.models.callbacks.Callback;
+
+import java.util.Map;
+
+public abstract class Components31Mixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonSerialize(contentUsing = CallbackSerializer.class)
+ public abstract Map getCallbacks();
+
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/ComponentsMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/ComponentsMixin.java
index 14b25b3c79..ec6423126b 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/ComponentsMixin.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/ComponentsMixin.java
@@ -2,8 +2,10 @@
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.core.jackson.CallbackSerializer;
+import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.callbacks.Callback;
import java.util.Map;
@@ -19,4 +21,7 @@ public abstract class ComponentsMixin {
@JsonSerialize(contentUsing = CallbackSerializer.class)
public abstract Map getCallbacks();
+ @JsonIgnore
+ public abstract Map getPathItems();
+
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DateSchemaMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DateSchemaMixin.java
index 86cf5ed899..ba044ad74d 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DateSchemaMixin.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DateSchemaMixin.java
@@ -1,9 +1,18 @@
package io.swagger.v3.core.jackson.mixin;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.Map;
public abstract class DateSchemaMixin {
@JsonFormat (shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
public abstract Object getExample();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+ @JsonIgnore
+ public abstract Map getJsonSchema();
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Discriminator31Mixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Discriminator31Mixin.java
new file mode 100644
index 0000000000..249452630f
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Discriminator31Mixin.java
@@ -0,0 +1,15 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+
+import java.util.Map;
+
+public abstract class Discriminator31Mixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DiscriminatorMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DiscriminatorMixin.java
new file mode 100644
index 0000000000..d633a651f5
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/DiscriminatorMixin.java
@@ -0,0 +1,11 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.Map;
+
+public abstract class DiscriminatorMixin {
+
+ @JsonIgnore
+ public abstract Map getExtensions();
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Info31Mixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Info31Mixin.java
new file mode 100644
index 0000000000..bd2265b22d
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Info31Mixin.java
@@ -0,0 +1,19 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.Map;
+
+public abstract class Info31Mixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract String getSummary();
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/InfoMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/InfoMixin.java
new file mode 100644
index 0000000000..0eb289d552
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/InfoMixin.java
@@ -0,0 +1,19 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.Map;
+
+public abstract class InfoMixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract String getSummary();
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/LicenseMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/LicenseMixin.java
new file mode 100644
index 0000000000..4b205a908e
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/LicenseMixin.java
@@ -0,0 +1,19 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.Map;
+
+public abstract class LicenseMixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract String getIdentifier();
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPI31Mixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPI31Mixin.java
new file mode 100644
index 0000000000..96add18b36
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPI31Mixin.java
@@ -0,0 +1,22 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import io.swagger.v3.core.jackson.PathsSerializer;
+import io.swagger.v3.oas.models.Paths;
+
+import java.util.Map;
+
+public abstract class OpenAPI31Mixin {
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonSerialize(using = PathsSerializer.class)
+ public abstract Paths getPaths();
+
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPIMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPIMixin.java
index e43b1b2152..b2296e8b39 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPIMixin.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/OpenAPIMixin.java
@@ -2,8 +2,10 @@
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.core.jackson.PathsSerializer;
+import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import java.util.Map;
@@ -17,4 +19,7 @@ public abstract class OpenAPIMixin {
@JsonSerialize(using = PathsSerializer.class)
public abstract Paths getPaths();
+
+ @JsonIgnore
+ public abstract Map getWebhooks();
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Schema31Mixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Schema31Mixin.java
new file mode 100644
index 0000000000..02170fc62e
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/Schema31Mixin.java
@@ -0,0 +1,77 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class Schema31Mixin {
+
+ //@JsonValue
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonIgnore
+ public abstract Boolean getNullable();
+
+ @JsonIgnore
+ public abstract Boolean getExclusiveMinimum();
+
+ @JsonIgnore
+ public abstract Boolean getExclusiveMaximum();
+
+ @JsonProperty("exclusiveMinimum")
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonProperty("exclusiveMaximum")
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract String getType();
+
+ @JsonProperty("type")
+ @JsonSerialize(using = TypeSerializer.class)
+ public abstract Set getTypes();
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract boolean getExampleSetFlag();
+
+ @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.ALWAYS)
+ public abstract Object getExample();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+ public static class TypeSerializer extends JsonSerializer> {
+
+ @Override
+ public void serialize(Set types, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+ if (types != null && types.size() == 1) {
+ jsonGenerator.writeString((String)types.toArray()[0]);
+ } else if (types != null && types.size() > 1){
+ jsonGenerator.writeStartArray();
+ for (String t: types) {
+ jsonGenerator.writeString(t);
+ }
+ jsonGenerator.writeEndArray();
+ }
+ }
+ }
+
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaConverterMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaConverterMixin.java
new file mode 100644
index 0000000000..b1b38ff4b6
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaConverterMixin.java
@@ -0,0 +1,112 @@
+package io.swagger.v3.core.jackson.mixin;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.v3.oas.models.media.Schema;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class SchemaConverterMixin {
+
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonAnyGetter
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract boolean getExampleSetFlag();
+
+ @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.ALWAYS)
+ public abstract Object getExample();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract Schema getContains();
+
+ @JsonIgnore
+ public abstract String get$id();
+
+ @JsonIgnore
+ public abstract String get$anchor();
+
+ @JsonIgnore
+ public abstract String get$schema();
+
+ @JsonIgnore
+ public abstract Set getTypes();
+
+ @JsonIgnore
+ public abstract Map getPatternProperties();
+
+ @JsonIgnore
+ public abstract List getPrefixItems();
+
+ @JsonIgnore
+ public abstract String getContentEncoding();
+
+ @JsonIgnore
+ public abstract String getContentMediaType();
+
+ @JsonIgnore
+ public abstract Schema getContentSchema();
+
+ @JsonIgnore
+ public abstract Schema getPropertyNames();
+
+ @JsonIgnore
+ public abstract Object getUnevaluatedProperties();
+
+ @JsonIgnore
+ public abstract Integer getMaxContains();
+
+ @JsonIgnore
+ public abstract Integer getMinContains();
+
+ @JsonIgnore
+ public abstract Schema getAdditionalItems();
+
+ @JsonIgnore
+ public abstract Schema getUnevaluatedItems();
+
+ @JsonIgnore
+ public abstract Schema getIf();
+
+ @JsonIgnore
+ public abstract Schema getElse();
+
+ @JsonIgnore
+ public abstract Schema getThen();
+
+ @JsonIgnore
+ public abstract Map getDependentSchemas();
+
+ @JsonIgnore
+ public abstract Map> getDependentRequired();
+
+ @JsonIgnore
+ public abstract String get$comment();
+
+ @JsonIgnore
+ public abstract List getExamples();
+
+ @JsonIgnore
+ public abstract Object getConst();
+
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaMixin.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaMixin.java
index f1bfb5c578..7c4637eddd 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaMixin.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/mixin/SchemaMixin.java
@@ -4,8 +4,12 @@
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.v3.oas.models.media.Schema;
+import java.math.BigDecimal;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
public abstract class SchemaMixin {
@@ -20,4 +24,88 @@ public abstract class SchemaMixin {
@JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.ALWAYS)
public abstract Object getExample();
+
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract Schema getContains();
+
+ @JsonIgnore
+ public abstract String get$id();
+
+ @JsonIgnore
+ public abstract String get$anchor();
+
+ @JsonIgnore
+ public abstract String get$schema();
+
+ @JsonIgnore
+ public abstract Set getTypes();
+
+ @JsonIgnore
+ public abstract Map getPatternProperties();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+ @JsonIgnore
+ public abstract List getPrefixItems();
+
+ @JsonIgnore
+ public abstract String getContentEncoding();
+
+ @JsonIgnore
+ public abstract String getContentMediaType();
+
+ @JsonIgnore
+ public abstract Schema getContentSchema();
+
+ @JsonIgnore
+ public abstract Schema getPropertyNames();
+
+ @JsonIgnore
+ public abstract Object getUnevaluatedProperties();
+
+ @JsonIgnore
+ public abstract Integer getMaxContains();
+
+ @JsonIgnore
+ public abstract Integer getMinContains();
+
+ @JsonIgnore
+ public abstract Schema getAdditionalItems();
+
+ @JsonIgnore
+ public abstract Schema getUnevaluatedItems();
+
+ @JsonIgnore
+ public abstract Schema getIf();
+
+ @JsonIgnore
+ public abstract Schema getElse();
+
+ @JsonIgnore
+ public abstract Schema getThen();
+
+ @JsonIgnore
+ public abstract Map getDependentSchemas();
+
+ @JsonIgnore
+ public abstract Map> getDependentRequired();
+
+ @JsonIgnore
+ public abstract String get$comment();
+
+ @JsonIgnore
+ public abstract List getExamples();
+
+ @JsonIgnore
+ public abstract Object getConst();
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java
index 10ecfe84a1..677ba11dfe 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java
@@ -13,6 +13,7 @@
import io.swagger.v3.oas.annotations.links.LinkParameter;
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.examples.Example;
@@ -97,6 +98,7 @@ public static boolean hasSchemaAnnotation(io.swagger.v3.oas.annotations.media.Sc
&& schema.extensions().length == 0
&& !schema.hidden()
&& !schema.enumAsRef()
+ && schema.additionalProperties().equals(io.swagger.v3.oas.annotations.media.Schema.AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION)
) {
return false;
}
@@ -284,6 +286,10 @@ else if (thisSchema == null || thatSchema == null) {
if (!Arrays.equals(thisSchema.extensions(), thatSchema.extensions())) {
return false;
}
+ if (!thisSchema.additionalProperties().equals(thatSchema.additionalProperties())) {
+ return false;
+ }
+
return true;
}
@@ -539,7 +545,11 @@ public static Optional getSchemaFromAnnotation(io.swagger.v3.oas.annotat
((ComposedSchema) schemaObject).addAllOfItem(allOfSchemaObject);
}
}
-
+ if (schema.additionalProperties().equals(io.swagger.v3.oas.annotations.media.Schema.AdditionalPropertiesValue.TRUE)) {
+ schemaObject.additionalProperties(true);
+ } else if (schema.additionalProperties().equals(io.swagger.v3.oas.annotations.media.Schema.AdditionalPropertiesValue.FALSE)) {
+ schemaObject.additionalProperties(false);
+ }
return Optional.of(schemaObject);
}
@@ -1044,6 +1054,46 @@ public static Optional getContent(io.swagger.v3.oas.annotations.media.C
MediaType mediaType = new MediaType();
if (components != null) {
getSchema(annotationContent, components, jsonViewAnnotation).ifPresent(mediaType::setSchema);
+ if (annotationContent.schemaProperties().length > 0) {
+ if (mediaType.getSchema() == null) {
+ mediaType.schema(new Schema().type("object"));
+ }
+ Schema oSchema = mediaType.getSchema();
+ for (SchemaProperty sp: annotationContent.schemaProperties()) {
+ Class> schemaImplementation = sp.schema().implementation();
+ boolean isArray = false;
+ if (schemaImplementation == Void.class) {
+ schemaImplementation = sp.array().schema().implementation();
+ if (schemaImplementation != Void.class) {
+ isArray = true;
+ }
+ }
+ getSchema(sp.schema(), sp.array(), isArray, schemaImplementation, components, jsonViewAnnotation)
+ .ifPresent(s -> {
+ if ("array".equals(oSchema.getType())) {
+ oSchema.getItems().addProperty(sp.name(), s);
+ } else {
+ oSchema.addProperty(sp.name(), s);
+ }
+ });
+
+ }
+ }
+ if (
+ hasSchemaAnnotation(annotationContent.additionalPropertiesSchema()) &&
+ mediaType.getSchema() != null &&
+ !Boolean.TRUE.equals(mediaType.getSchema().getAdditionalProperties()) &&
+ !Boolean.FALSE.equals(mediaType.getSchema().getAdditionalProperties())) {
+ getSchemaFromAnnotation(annotationContent.additionalPropertiesSchema(), components, jsonViewAnnotation)
+ .ifPresent(s -> {
+ if ("array".equals(mediaType.getSchema().getType())) {
+ mediaType.getSchema().getItems().additionalProperties(s);
+ } else {
+ mediaType.getSchema().additionalProperties(s);
+ }
+ }
+ );
+ }
} else {
mediaType.setSchema(schema);
}
@@ -1726,6 +1776,14 @@ public Extension[] extensions() {
public Class extends Annotation> annotationType() {
return io.swagger.v3.oas.annotations.media.Schema.class;
}
+
+ @Override
+ public AdditionalPropertiesValue additionalProperties() {
+ if (!master.additionalProperties().equals(AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION) || patch.additionalProperties().equals(AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION)) {
+ return master.additionalProperties();
+ }
+ return patch.additionalProperties();
+ }
};
return (io.swagger.v3.oas.annotations.media.Schema)schema;
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponses31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponses31Deserializer.java
new file mode 100644
index 0000000000..c1534dce31
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponses31Deserializer.java
@@ -0,0 +1,9 @@
+package io.swagger.v3.core.util;
+
+public class ApiResponses31Deserializer extends ApiResponsesDeserializer {
+
+ public ApiResponses31Deserializer() {
+ this.openapi31 = true;
+ }
+
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponsesDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponsesDeserializer.java
index 1fe6a2ef51..cbf21a1a9e 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponsesDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ApiResponsesDeserializer.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
@@ -14,21 +15,31 @@
import java.util.Map;
public class ApiResponsesDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31;
+
@Override
public ApiResponses deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
+
+ final ObjectMapper mapper;
+ if (openapi31) {
+ mapper = Json31.mapper();
+ } else {
+ mapper = Json.mapper();
+ }
ApiResponses result = new ApiResponses();
JsonNode node = jp.getCodec().readTree(jp);
- ObjectNode objectNode = (ObjectNode)node;
+ ObjectNode objectNode = (ObjectNode) node;
Map extensions = new LinkedHashMap<>();
for (Iterator it = objectNode.fieldNames(); it.hasNext(); ) {
String childName = it.next();
JsonNode child = objectNode.get(childName);
- // if name start with `x-` consider it an extesion
+ // if name start with `x-` consider it an extension
if (childName.startsWith("x-")) {
- extensions.put(childName, Json.mapper().convertValue(child, Object.class));
+ extensions.put(childName, mapper.convertValue(child, Object.class));
} else {
- result.put(childName, Json.mapper().convertValue(child, ApiResponse.class));
+ result.put(childName, mapper.convertValue(child, ApiResponse.class));
}
}
if (!extensions.isEmpty()) {
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Callback31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Callback31Deserializer.java
new file mode 100644
index 0000000000..aae9fd1bf1
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Callback31Deserializer.java
@@ -0,0 +1,21 @@
+package io.swagger.v3.core.util;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.oas.models.PathItem;
+
+import javax.security.auth.callback.Callback;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class Callback31Deserializer extends CallbackDeserializer {
+
+ public Callback31Deserializer() {
+ openapi31 = true;
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/CallbackDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/CallbackDeserializer.java
index f5a8668f20..1fc2c3ec92 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/CallbackDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/CallbackDeserializer.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.callbacks.Callback;
@@ -14,9 +15,19 @@
import java.util.Map;
public class CallbackDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31;
+
@Override
public Callback deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
+
+ final ObjectMapper mapper;
+ if (openapi31) {
+ mapper = Json31.mapper();
+ } else {
+ mapper = Json.mapper();
+ }
Callback result = new Callback();
JsonNode node = jp.getCodec().readTree(jp);
ObjectNode objectNode = (ObjectNode)node;
@@ -26,11 +37,11 @@ public Callback deserialize(JsonParser jp, DeserializationContext ctxt)
JsonNode child = objectNode.get(childName);
// if name start with `x-` consider it an extension
if (childName.startsWith("x-")) {
- extensions.put(childName, Json.mapper().convertValue(child, Object.class));
+ extensions.put(childName, mapper.convertValue(child, Object.class));
} else if (childName.equals("$ref")) {
result.$ref(child.asText());
} else {
- result.put(childName, Json.mapper().convertValue(child, PathItem.class));
+ result.put(childName, mapper.convertValue(child, PathItem.class));
}
}
if (!extensions.isEmpty()) {
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/DeserializationModule31.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/DeserializationModule31.java
new file mode 100644
index 0000000000..b9003784e4
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/DeserializationModule31.java
@@ -0,0 +1,30 @@
+package io.swagger.v3.core.util;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.callbacks.Callback;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.media.Encoding;
+import io.swagger.v3.oas.models.media.EncodingProperty;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+
+public class DeserializationModule31 extends SimpleModule {
+
+ public DeserializationModule31() {
+
+ this.addDeserializer(Schema.class, new Model31Deserializer());
+ this.addDeserializer(Parameter.class, new Parameter31Deserializer());
+ this.addDeserializer(Header.StyleEnum.class, new HeaderStyleEnumDeserializer());
+ this.addDeserializer(Encoding.StyleEnum.class, new EncodingStyleEnumDeserializer());
+ this.addDeserializer(EncodingProperty.StyleEnum.class, new EncodingPropertyStyleEnumDeserializer());
+
+ this.addDeserializer(SecurityScheme.class, new SecurityScheme31Deserializer());
+
+ this.addDeserializer(ApiResponses.class, new ApiResponses31Deserializer());
+ this.addDeserializer(Paths.class, new Paths31Deserializer());
+ this.addDeserializer(Callback.class, new Callback31Deserializer());
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Json31.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Json31.java
new file mode 100644
index 0000000000..16a883c090
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Json31.java
@@ -0,0 +1,82 @@
+package io.swagger.v3.core.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import io.swagger.v3.oas.models.media.Schema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class Json31 {
+
+ private static ObjectMapper mapper;
+ private static ObjectMapper converterMapper;
+
+ static Logger LOGGER = LoggerFactory.getLogger(Json31.class);
+
+ public static ObjectMapper mapper() {
+ if (mapper == null) {
+ mapper = ObjectMapperFactory.createJson31();
+ }
+ return mapper;
+ }
+
+ public static ObjectMapper converterMapper() {
+ if (converterMapper == null) {
+ converterMapper = ObjectMapperFactory.createJsonConverter();
+ }
+ return converterMapper;
+ }
+
+ public static ObjectWriter pretty() {
+ return mapper().writer(new DefaultPrettyPrinter());
+ }
+
+ public static String pretty(Object o) {
+ try {
+ return pretty().writeValueAsString(o);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static void prettyPrint(Object o) {
+ try {
+ System.out.println(pretty().writeValueAsString(o).replace("\r", ""));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Map jsonSchemaAsMap(String jsonSchema) {
+ try {
+ return mapper().readValue(jsonSchema, Map.class);
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Exception converting jsonSchema to Map", e);
+ return null;
+ }
+ }
+
+ public static Map jsonSchemaAsMap(Schema schema) {
+ try {
+ return mapper().readValue(mapper().writeValueAsString(schema), Map.class);
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Exception converting jsonSchema to Map", e);
+ return null;
+ }
+ }
+
+ public static Map jsonSchemaAsMap(JsonNode schema) {
+ try {
+ return mapper().readValue(mapper().writeValueAsString(schema), Map.class);
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Exception converting jsonSchema to Map", e);
+ return null;
+ }
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Model31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Model31Deserializer.java
new file mode 100644
index 0000000000..67cfa66799
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Model31Deserializer.java
@@ -0,0 +1,6 @@
+package io.swagger.v3.core.util;
+
+public class Model31Deserializer extends ModelDeserializer {
+
+ public Model31Deserializer() {this.openapi31 = true;}
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ModelDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ModelDeserializer.java
index 9c8941a936..7037a32bfe 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ModelDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ModelDeserializer.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import io.swagger.v3.oas.models.media.ArraySchema;
@@ -13,6 +14,7 @@
import io.swagger.v3.oas.models.media.DateTimeSchema;
import io.swagger.v3.oas.models.media.EmailSchema;
import io.swagger.v3.oas.models.media.IntegerSchema;
+import io.swagger.v3.oas.models.media.JsonSchema;
import io.swagger.v3.oas.models.media.MapSchema;
import io.swagger.v3.oas.models.media.NumberSchema;
import io.swagger.v3.oas.models.media.ObjectSchema;
@@ -23,61 +25,70 @@
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
public class ModelDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31 = false;
@Override
public Schema deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
- JsonNode allOf = node.get("allOf");
- JsonNode anyOf = node.get("anyOf");
- JsonNode oneOf = node.get("oneOf");
Schema schema = null;
- if (allOf != null || anyOf != null || oneOf != null) {
+ if (openapi31) {
+ schema = deserializeJsonSchema(node);
+ return schema;
+ }
- return Json.mapper().convertValue(node, ComposedSchema.class);
- } else {
+ List composed = Arrays.asList("allOf", "anyOf", "oneOf");
+ for (String field: composed) {
+ if (node.get(field) != null) {
+ return Json.mapper().convertValue(node, ComposedSchema.class);
+ }
+ }
+
+ JsonNode type = node.get("type");
+ String format = node.get("format") == null ? "" : node.get("format").textValue();
- JsonNode type = node.get("type");
- String format = node.get("format") == null ? "" : node.get("format").textValue();
-
- if (type != null && "array".equals(((TextNode) type).textValue())) {
- schema = Json.mapper().convertValue(node, ArraySchema.class);
- } else if (type != null) {
- if (type.textValue().equals("integer")) {
- schema = Json.mapper().convertValue(node, IntegerSchema.class);
- if (StringUtils.isBlank(format)) {
- schema.setFormat(null);
- }
- } else if (type.textValue().equals("number")) {
- schema = Json.mapper().convertValue(node, NumberSchema.class);
- } else if (type.textValue().equals("boolean")) {
- schema = Json.mapper().convertValue(node, BooleanSchema.class);
- } else if (type.textValue().equals("string")) {
- if ("date".equals(format)) {
- schema = Json.mapper().convertValue(node, DateSchema.class);
- } else if ("date-time".equals(format)) {
- schema = Json.mapper().convertValue(node, DateTimeSchema.class);
- } else if ("email".equals(format)) {
- schema = Json.mapper().convertValue(node, EmailSchema.class);
- } else if ("password".equals(format)) {
- schema = Json.mapper().convertValue(node, PasswordSchema.class);
- } else if ("uuid".equals(format)) {
- schema = Json.mapper().convertValue(node, UUIDSchema.class);
- } else {
- schema = Json.mapper().convertValue(node, StringSchema.class);
- }
- } else if (type.textValue().equals("object")) {
- schema = deserializeObjectSchema(node);
+ if (type != null && "array".equals(((TextNode) type).textValue())) {
+ schema = Json.mapper().convertValue(node, ArraySchema.class);
+ } else if (type != null) {
+ if (type.textValue().equals("integer")) {
+ schema = Json.mapper().convertValue(node, IntegerSchema.class);
+ if (StringUtils.isBlank(format)) {
+ schema.setFormat(null);
}
- } else if (node.get("$ref") != null) {
- schema = new Schema().$ref(node.get("$ref").asText());
- } else { // assume object
+ } else if (type.textValue().equals("number")) {
+ schema = Json.mapper().convertValue(node, NumberSchema.class);
+ } else if (type.textValue().equals("boolean")) {
+ schema = Json.mapper().convertValue(node, BooleanSchema.class);
+ } else if (type.textValue().equals("string")) {
+ if ("date".equals(format)) {
+ schema = Json.mapper().convertValue(node, DateSchema.class);
+ } else if ("date-time".equals(format)) {
+ schema = Json.mapper().convertValue(node, DateTimeSchema.class);
+ } else if ("email".equals(format)) {
+ schema = Json.mapper().convertValue(node, EmailSchema.class);
+ } else if ("password".equals(format)) {
+ schema = Json.mapper().convertValue(node, PasswordSchema.class);
+ } else if ("uuid".equals(format)) {
+ schema = Json.mapper().convertValue(node, UUIDSchema.class);
+ } else {
+ schema = Json.mapper().convertValue(node, StringSchema.class);
+ }
+ } else if (type.textValue().equals("object")) {
schema = deserializeObjectSchema(node);
}
+ } else if (node.get("$ref") != null) {
+ schema = new Schema().$ref(node.get("$ref").asText());
+ } else { // assume object
+ schema = deserializeObjectSchema(node);
}
return schema;
@@ -107,6 +118,47 @@ private Schema deserializeObjectSchema(JsonNode node) {
} else {
schema = Json.mapper().convertValue(node, ObjectSchema.class);
}
+ if (schema != null) {
+ schema.jsonSchema(Json31.jsonSchemaAsMap(node));
+ }
+ return schema;
+ }
+
+ private Schema deserializeJsonSchema(JsonNode node) {
+ JsonNode additionalProperties = node.get("additionalProperties");
+ JsonNode type = node.get("type");
+ Schema schema = null;
+
+ if (type != null || additionalProperties != null) {
+ if (type != null) {
+ ((ObjectNode)node).remove("type");
+ }
+ if (additionalProperties != null) {
+ ((ObjectNode)node).remove("additionalProperties");
+ }
+ schema = Json31.mapper().convertValue(node, JsonSchema.class);
+ if (type instanceof TextNode) {
+ schema.types(new LinkedHashSet<>(Arrays.asList(type.textValue())));
+ } else if (type instanceof ArrayNode){
+ Set types = new LinkedHashSet<>();
+ ((ArrayNode)type).elements().forEachRemaining( n -> {
+ types.add(n.textValue());
+ });
+ schema.types(types);
+ }
+ if (additionalProperties != null) {
+ try {
+ Schema innerSchema = Json31.mapper().convertValue(additionalProperties, JsonSchema.class);
+ schema.setAdditionalProperties(innerSchema);
+ } catch (Exception e) {
+ Boolean additionalPropsBoolean = Json31.mapper().convertValue(additionalProperties, Boolean.class);
+ schema.setAdditionalProperties(additionalPropsBoolean);
+ }
+ }
+
+ } else {
+ schema = Json31.mapper().convertValue(node, JsonSchema.class);
+ }
return schema;
}
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ObjectMapperFactory.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ObjectMapperFactory.java
index 561c8f70fd..a1d2937223 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ObjectMapperFactory.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ObjectMapperFactory.java
@@ -14,15 +14,24 @@
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import io.swagger.v3.core.jackson.Schema31Serializer;
import io.swagger.v3.core.jackson.MediaTypeSerializer;
import io.swagger.v3.core.jackson.SchemaSerializer;
+import io.swagger.v3.core.jackson.mixin.Components31Mixin;
import io.swagger.v3.core.jackson.mixin.ComponentsMixin;
import io.swagger.v3.core.jackson.mixin.DateSchemaMixin;
+import io.swagger.v3.core.jackson.mixin.Discriminator31Mixin;
+import io.swagger.v3.core.jackson.mixin.DiscriminatorMixin;
import io.swagger.v3.core.jackson.mixin.ExampleMixin;
import io.swagger.v3.core.jackson.mixin.ExtensionsMixin;
+import io.swagger.v3.core.jackson.mixin.InfoMixin;
+import io.swagger.v3.core.jackson.mixin.LicenseMixin;
import io.swagger.v3.core.jackson.mixin.MediaTypeMixin;
+import io.swagger.v3.core.jackson.mixin.OpenAPI31Mixin;
import io.swagger.v3.core.jackson.mixin.OpenAPIMixin;
import io.swagger.v3.core.jackson.mixin.OperationMixin;
+import io.swagger.v3.core.jackson.mixin.Schema31Mixin;
+import io.swagger.v3.core.jackson.mixin.SchemaConverterMixin;
import io.swagger.v3.core.jackson.mixin.SchemaMixin;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
@@ -39,6 +48,7 @@
import io.swagger.v3.oas.models.links.Link;
import io.swagger.v3.oas.models.links.LinkParameter;
import io.swagger.v3.oas.models.media.DateSchema;
+import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.Encoding;
import io.swagger.v3.oas.models.media.EncodingProperty;
import io.swagger.v3.oas.models.media.MediaType;
@@ -63,41 +73,147 @@
public class ObjectMapperFactory {
protected static ObjectMapper createJson() {
- return create(null);
+ return create(null, false);
}
- protected static ObjectMapper createYaml() {
+ protected static ObjectMapper createYaml(boolean openapi31) {
YAMLFactory factory = new YAMLFactory();
factory.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
factory.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES);
factory.enable(YAMLGenerator.Feature.SPLIT_LINES);
factory.enable(YAMLGenerator.Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS);
- return create(factory);
+ return create(factory, openapi31);
+ }
+
+ protected static ObjectMapper createYaml() {
+ return createYaml(false);
+ }
+
+ protected static ObjectMapper createJson31() {
+ return create(null, true);
+ }
+
+
+ protected static ObjectMapper createYaml31() {
+ return createYaml(true);
}
- private static ObjectMapper create(JsonFactory jsonFactory) {
+ private static ObjectMapper create(JsonFactory jsonFactory, boolean openapi31) {
ObjectMapper mapper = jsonFactory == null ? new ObjectMapper() : new ObjectMapper(jsonFactory);
- // handle ref schema serialization skipping all other props
- mapper.registerModule(new SimpleModule() {
- @Override
- public void setupModule(SetupContext context) {
- super.setupModule(context);
- context.addBeanSerializerModifier(new BeanSerializerModifier() {
- @Override
- public JsonSerializer> modifySerializer(
- SerializationConfig config, BeanDescription desc, JsonSerializer> serializer) {
- if (Schema.class.isAssignableFrom(desc.getBeanClass())) {
- return new SchemaSerializer((JsonSerializer) serializer);
- } else if (MediaType.class.isAssignableFrom(desc.getBeanClass())) {
- return new MediaTypeSerializer((JsonSerializer) serializer);
+ if (!openapi31) {
+ // handle ref schema serialization skipping all other props
+ mapper.registerModule(new SimpleModule() {
+ @Override
+ public void setupModule(SetupContext context) {
+ super.setupModule(context);
+ context.addBeanSerializerModifier(new BeanSerializerModifier() {
+ @Override
+ public JsonSerializer> modifySerializer(
+ SerializationConfig config, BeanDescription desc, JsonSerializer> serializer) {
+ if (Schema.class.isAssignableFrom(desc.getBeanClass())) {
+ return new SchemaSerializer((JsonSerializer) serializer);
+ } else if (MediaType.class.isAssignableFrom(desc.getBeanClass())) {
+ return new MediaTypeSerializer((JsonSerializer) serializer);
+ }
+ return serializer;
+ }
+ });
+ }
+ });
+ } else {
+ mapper.registerModule(new SimpleModule() {
+ @Override
+ public void setupModule(SetupContext context) {
+ super.setupModule(context);
+ context.addBeanSerializerModifier(new BeanSerializerModifier() {
+ @Override
+ public JsonSerializer> modifySerializer(
+ SerializationConfig config, BeanDescription desc, JsonSerializer> serializer) {
+ if (Schema.class.isAssignableFrom(desc.getBeanClass())) {
+ return new Schema31Serializer((JsonSerializer) serializer);
+ } else if (MediaType.class.isAssignableFrom(desc.getBeanClass())) {
+ return new MediaTypeSerializer((JsonSerializer) serializer);
+ }
+ return serializer;
}
- return serializer;
- }
- });
- }
- });
+ });
+ }
+ });
+ }
+
+ if (!openapi31) {
+ Module deserializerModule = new DeserializationModule();
+ mapper.registerModule(deserializerModule);
+ } else {
+ Module deserializerModule = new DeserializationModule31();
+ mapper.registerModule(deserializerModule);
+ }
+ mapper.registerModule(new JavaTimeModule());
+
+ Map, Class>> sourceMixins = new LinkedHashMap<>();
+
+ sourceMixins.put(ApiResponses.class, ExtensionsMixin.class);
+ sourceMixins.put(Contact.class, ExtensionsMixin.class);
+ sourceMixins.put(Encoding.class, ExtensionsMixin.class);
+ sourceMixins.put(EncodingProperty.class, ExtensionsMixin.class);
+ sourceMixins.put(Example.class, ExampleMixin.class);
+ sourceMixins.put(ExternalDocumentation.class, ExtensionsMixin.class);
+ sourceMixins.put(Link.class, ExtensionsMixin.class);
+ sourceMixins.put(LinkParameter.class, ExtensionsMixin.class);
+ sourceMixins.put(MediaType.class, MediaTypeMixin.class);
+ sourceMixins.put(OAuthFlow.class, ExtensionsMixin.class);
+ sourceMixins.put(OAuthFlows.class, ExtensionsMixin.class);
+ sourceMixins.put(Operation.class, OperationMixin.class);
+ sourceMixins.put(PathItem.class, ExtensionsMixin.class);
+ sourceMixins.put(Paths.class, ExtensionsMixin.class);
+ sourceMixins.put(Scopes.class, ExtensionsMixin.class);
+ sourceMixins.put(Server.class, ExtensionsMixin.class);
+ sourceMixins.put(ServerVariable.class, ExtensionsMixin.class);
+ sourceMixins.put(ServerVariables.class, ExtensionsMixin.class);
+ sourceMixins.put(Tag.class, ExtensionsMixin.class);
+ sourceMixins.put(XML.class, ExtensionsMixin.class);
+ sourceMixins.put(ApiResponse.class, ExtensionsMixin.class);
+ sourceMixins.put(Parameter.class, ExtensionsMixin.class);
+ sourceMixins.put(RequestBody.class, ExtensionsMixin.class);
+ sourceMixins.put(Header.class, ExtensionsMixin.class);
+ sourceMixins.put(SecurityScheme.class, ExtensionsMixin.class);
+ sourceMixins.put(Callback.class, ExtensionsMixin.class);
+
+
+ if (!openapi31) {
+ sourceMixins.put(Schema.class, SchemaMixin.class);
+ sourceMixins.put(DateSchema.class, DateSchemaMixin.class);
+ sourceMixins.put(Components.class, ComponentsMixin.class);
+ sourceMixins.put(Info.class, InfoMixin.class);
+ sourceMixins.put(License.class, LicenseMixin.class);
+ sourceMixins.put(OpenAPI.class, OpenAPIMixin.class);
+ sourceMixins.put(Discriminator.class, DiscriminatorMixin.class);
+ } else {
+ sourceMixins.put(Info.class, ExtensionsMixin.class);
+ sourceMixins.put(Schema.class, Schema31Mixin.class);
+ sourceMixins.put(Components.class, Components31Mixin.class);
+ sourceMixins.put(OpenAPI.class, OpenAPI31Mixin.class);
+ sourceMixins.put(DateSchema.class, DateSchemaMixin.class);
+ sourceMixins.put(Discriminator.class, Discriminator31Mixin.class);
+ }
+ mapper.setMixIns(sourceMixins);
+ mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
+ mapper.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ return mapper;
+ }
+
+ protected static ObjectMapper createJsonConverter() {
+
+ ObjectMapper mapper = new ObjectMapper();
+
Module deserializerModule = new DeserializationModule();
mapper.registerModule(deserializerModule);
@@ -135,9 +251,8 @@ public JsonSerializer> modifySerializer(
sourceMixins.put(ServerVariables.class, ExtensionsMixin.class);
sourceMixins.put(Tag.class, ExtensionsMixin.class);
sourceMixins.put(XML.class, ExtensionsMixin.class);
- sourceMixins.put(Schema.class, SchemaMixin.class);
- sourceMixins.put(DateSchema.class, DateSchemaMixin.class);
+ sourceMixins.put(Schema.class, SchemaConverterMixin.class);
mapper.setMixIns(sourceMixins);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
@@ -150,6 +265,7 @@ public JsonSerializer> modifySerializer(
return mapper;
}
+
public static ObjectMapper buildStrictGenericObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/OpenAPISchema2JsonSchema.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/OpenAPISchema2JsonSchema.java
new file mode 100644
index 0000000000..1d7405d7ec
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/OpenAPISchema2JsonSchema.java
@@ -0,0 +1,48 @@
+package io.swagger.v3.core.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.v3.oas.models.SpecVersion;
+import io.swagger.v3.oas.models.media.Schema;
+import java.util.LinkedHashSet;
+import java.util.Map;
+
+public class OpenAPISchema2JsonSchema {
+
+ protected final ObjectMapper converterMapper = Json31.converterMapper();
+
+ public void process(Schema> schema) {
+ schema.specVersion(SpecVersion.V31);
+ Map jsonSchema = converterMapper.convertValue(schema, Map.class);
+
+ // handle nullable
+ if (schema.getType() != null || Boolean.TRUE.equals(schema.getNullable())) {
+ schema.types(new LinkedHashSet<>());
+ }
+ if (schema.getType() != null) {
+ schema.getTypes().add(schema.getType());
+ }
+ schema.type(null);
+ if (Boolean.TRUE.equals(schema.getNullable())) {
+ schema.nullable(null);
+ schema.getTypes().add("null");
+ }
+
+ // TODO handle other differences
+
+ schema.jsonSchema(jsonSchema);
+
+ // TODO handle all nested schemas
+ if (schema.getAdditionalProperties() instanceof Schema) {
+ process((Schema>) schema.getAdditionalProperties());
+ }
+ if (schema.getAllOf() != null) {
+ schema.getAllOf().forEach(this::process);
+ }
+ if (schema.getProperties() != null) {
+ schema.getProperties().values().forEach(this::process);
+ }
+ if (schema.getItems() != null) {
+ process(schema.getItems());
+ }
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Parameter31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Parameter31Deserializer.java
new file mode 100644
index 0000000000..fc9d50a001
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Parameter31Deserializer.java
@@ -0,0 +1,8 @@
+package io.swagger.v3.core.util;
+
+public class Parameter31Deserializer extends ParameterDeserializer {
+
+ public Parameter31Deserializer() {
+ this.openapi31 = true;
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ParameterDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ParameterDeserializer.java
index 0b7a7dc9c6..14918e8858 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ParameterDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ParameterDeserializer.java
@@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import io.swagger.v3.oas.models.parameters.CookieParameter;
import io.swagger.v3.oas.models.parameters.HeaderParameter;
@@ -15,6 +16,9 @@
import java.io.IOException;
public class ParameterDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31;
+
@Override
public Parameter deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
@@ -23,22 +27,34 @@ public Parameter deserialize(JsonParser jp, DeserializationContext ctxt)
JsonNode node = jp.getCodec().readTree(jp);
JsonNode sub = node.get("$ref");
JsonNode inNode = node.get("in");
+ JsonNode desc = node.get("description");
if (sub != null) {
result = new Parameter().$ref(sub.asText());
+ if (desc != null && openapi31) {
+ result.description(desc.asText());
+ }
+
} else if (inNode != null) {
String in = inNode.asText();
ObjectReader reader = null;
+ ObjectMapper mapper = null;
+ if (openapi31) {
+ mapper = Json31.mapper();
+ } else {
+ mapper = Json.mapper();
+ }
+
if ("query".equals(in)) {
- reader = Json.mapper().readerFor(QueryParameter.class);
+ reader = mapper.readerFor(QueryParameter.class);
} else if ("header".equals(in)) {
- reader = Json.mapper().readerFor(HeaderParameter.class);
+ reader = mapper.readerFor(HeaderParameter.class);
} else if ("path".equals(in)) {
- reader = Json.mapper().readerFor(PathParameter.class);
+ reader = mapper.readerFor(PathParameter.class);
} else if ("cookie".equals(in)) {
- reader = Json.mapper().readerFor(CookieParameter.class);
+ reader = mapper.readerFor(CookieParameter.class);
}
if (reader != null) {
result = reader.with(DeserializationFeature.READ_ENUMS_USING_TO_STRING).readValue(node);
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Paths31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Paths31Deserializer.java
new file mode 100644
index 0000000000..5463b59e82
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Paths31Deserializer.java
@@ -0,0 +1,8 @@
+package io.swagger.v3.core.util;
+
+public class Paths31Deserializer extends PathsDeserializer {
+
+ public Paths31Deserializer() {
+ this.openapi31 = true;
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PathsDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PathsDeserializer.java
index 7b8e70b3fd..f1738165e7 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PathsDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PathsDeserializer.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
@@ -14,9 +15,20 @@
import java.util.Map;
public class PathsDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31;
+
@Override
public Paths deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
+
+ final ObjectMapper mapper;
+ if (openapi31) {
+ mapper = Json31.mapper();
+ } else {
+ mapper = Json.mapper();
+ }
+
Paths result = new Paths();
JsonNode node = jp.getCodec().readTree(jp);
ObjectNode objectNode = (ObjectNode)node;
@@ -26,9 +38,9 @@ public Paths deserialize(JsonParser jp, DeserializationContext ctxt)
JsonNode child = objectNode.get(childName);
// if name start with `x-` consider it an extesion
if (childName.startsWith("x-")) {
- extensions.put(childName, Json.mapper().convertValue(child, Object.class));
+ extensions.put(childName, mapper.convertValue(child, Object.class));
} else {
- result.put(childName, Json.mapper().convertValue(child, PathItem.class));
+ result.put(childName, mapper.convertValue(child, PathItem.class));
}
}
if (!extensions.isEmpty()) {
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecurityScheme31Deserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecurityScheme31Deserializer.java
new file mode 100644
index 0000000000..9a641f28e8
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecurityScheme31Deserializer.java
@@ -0,0 +1,8 @@
+package io.swagger.v3.core.util;
+
+public class SecurityScheme31Deserializer extends SecuritySchemeDeserializer {
+
+ public SecurityScheme31Deserializer() {
+ openapi31 = true;
+ }
+}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecuritySchemeDeserializer.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecuritySchemeDeserializer.java
index d773882adc..7921af0fce 100644
--- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecuritySchemeDeserializer.java
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/SecuritySchemeDeserializer.java
@@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.models.security.OAuthFlows;
import io.swagger.v3.oas.models.security.SecurityScheme;
@@ -12,9 +13,18 @@
import java.util.Arrays;
public class SecuritySchemeDeserializer extends JsonDeserializer {
+
+ protected boolean openapi31;
+
@Override
public SecurityScheme deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
+ ObjectMapper mapper = null;
+ if (openapi31) {
+ mapper = Json31.mapper();
+ } else {
+ mapper = Json.mapper();
+ }
SecurityScheme result = null;
JsonNode node = jp.getCodec().readTree(jp);
@@ -47,7 +57,10 @@ public SecurityScheme deserialize(JsonParser jp, DeserializationContext ctxt)
} else if ("oauth2".equals(type)) {
result
.type(SecurityScheme.Type.OAUTH2)
- .flows(Json.mapper().convertValue(node.get("flows"), OAuthFlows.class));
+ .flows(mapper.convertValue(node.get("flows"), OAuthFlows.class));
+ } else if ("mutualTLS".equals(type)) {
+ result
+ .type(SecurityScheme.Type.MUTUALTLS);
}
}
diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Yaml31.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Yaml31.java
new file mode 100644
index 0000000000..ba16433896
--- /dev/null
+++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/Yaml31.java
@@ -0,0 +1,62 @@
+package io.swagger.v3.core.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import io.swagger.v3.oas.models.media.Schema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class Yaml31 {
+ static ObjectMapper mapper;
+
+ static Logger LOGGER = LoggerFactory.getLogger(Yaml31.class);
+
+ public static ObjectMapper mapper() {
+ if (mapper == null) {
+ mapper = ObjectMapperFactory.createYaml31();
+ }
+ return mapper;
+ }
+
+ public static ObjectWriter pretty() {
+ return mapper().writer(new DefaultPrettyPrinter());
+ }
+
+ public static String pretty(Object o) {
+ try {
+ return pretty().writeValueAsString(o);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static void prettyPrint(Object o) {
+ try {
+ System.out.println(pretty().writeValueAsString(o));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Map jsonSchemaAsMap(String jsonSchema) {
+ try {
+ return mapper().readValue(jsonSchema, Map.class);
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Exception converting jsonSchema to Map", e);
+ return null;
+ }
+ }
+
+ public static Map jsonSchemaAsMap(Schema schema) {
+ try {
+ return mapper().readValue(mapper().writeValueAsString(schema), Map.class);
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Exception converting jsonSchema to Map", e);
+ return null;
+ }
+ }}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/SwaggerSerializerTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/SwaggerSerializerTest.java
index 40045ddc71..0a73bcfd03 100644
--- a/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/SwaggerSerializerTest.java
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/SwaggerSerializerTest.java
@@ -102,10 +102,10 @@ public void convertSpec() throws IOException {
final ApiResponse errorResponse = new ApiResponse()
.description("error response")
- .link("myLink", new Link()
+ .addLink("myLink", new Link()
.description("a link")
.operationId("theLinkedOperationId")
- .parameters("userId", "gah")
+ .addParameter("userId", "gah")
)
.content(new Content()
.addMediaType("application/json", new MediaType()
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/OpenAPI3_1DeserializationTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/OpenAPI3_1DeserializationTest.java
new file mode 100644
index 0000000000..9a0a299f40
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/OpenAPI3_1DeserializationTest.java
@@ -0,0 +1,225 @@
+package io.swagger.v3.core.deserialization;
+
+import io.swagger.v3.core.matchers.SerializationMatchers;
+import io.swagger.v3.core.util.ResourceUtils;
+import io.swagger.v3.core.util.Yaml;
+import io.swagger.v3.core.util.Yaml31;
+import io.swagger.v3.oas.models.OpenAPI;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+public class OpenAPI3_1DeserializationTest {
+
+ @Test
+ public void deserializePetstore3_1() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1.yaml");
+ final OpenAPI swagger = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(swagger);
+ assertEquals(swagger.getInfo().getLicense().getIdentifier(), "test");
+ }
+
+ @Test
+ public void deserializePetstore3_1More() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1_more.yaml");
+ final OpenAPI swagger = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(swagger);
+ assertEquals(swagger.getInfo().getLicense().getIdentifier(), "test");
+ }
+
+
+ @Test
+ public void deserializePetstore3_0() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/petstore-3.0.yaml");
+ final OpenAPI swagger = Yaml.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(swagger);
+ assertEquals(swagger.getInfo().getLicense().getIdentifier(), null);
+ }
+
+ @Test
+ public void deserializeChangelog3_1() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/changelog-3.1.yaml");
+ final OpenAPI swagger = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(swagger);
+ assertEquals(swagger.getInfo().getLicense().getIdentifier(), "test");
+ Yaml31.prettyPrint(swagger);
+ SerializationMatchers.assertEqualsToYaml31(swagger, jsonString);
+ }
+
+ @Test
+ public void testDeserializationOnOAS31() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1_sample.yaml");
+ OpenAPI openAPI = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(openAPI);
+
+ assertEquals(openAPI.getInfo().getTitle(), "Swagger Petstore");
+ assertEquals(openAPI.getInfo().getVersion(), "1.0.0");
+ assertEquals(openAPI.getInfo().getSummary(), "petstore sample for OAS 3.1.0");
+ assertEquals(openAPI.getInfo().getLicense().getName(), "MIT");
+ assertEquals(openAPI.getInfo().getLicense().getIdentifier(), "test");
+
+ assertNotNull(openAPI.getWebhooks());
+ assertFalse(openAPI.getWebhooks().isEmpty());
+ assertNotNull(openAPI.getWebhooks().get("newPet"));
+ assertNotNull(openAPI.getWebhooks().get("newPet").getPost());
+
+ assertNotNull(openAPI.getComponents().getPathItems());
+ assertNotNull(openAPI.getComponents().getPathItems().get("/pet"));
+ assertEquals(openAPI.getComponents().getPathItems().get("/pet").getDescription(), "get a pet");
+ assertNotNull(openAPI.getComponents().getPathItems().get("/pet").getGet());
+ assertEquals(openAPI.getComponents().getPathItems().get("/pet").getGet().getOperationId(), "getPet");
+
+ assertNotNull(openAPI.getComponents().getSchemas());
+ assertNotNull(openAPI.getComponents().getSchemas().get("Pet"));
+ assertNotNull(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator());
+ assertNotNull(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator().getExtensions());
+ assertEquals(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator().getExtensions().get("x-test-extension"), "extended");
+
+ assertNotNull(openAPI.getComponents().getResponses());
+ assertNotNull(openAPI.getComponents().getResponses().get("201"));
+ assertEquals(openAPI.getComponents().getResponses().get("201").getDescription(), "api response description");
+
+ assertNotNull(openAPI.getComponents().getParameters());
+ assertNotNull(openAPI.getComponents().getParameters().get("param"));
+ assertEquals(openAPI.getComponents().getParameters().get("param").getIn(), "query");
+ assertEquals(openAPI.getComponents().getParameters().get("param").getName(), "param0");
+ assertEquals(openAPI.getComponents().getParameters().get("param").getDescription(), "parameter description");
+
+ assertNotNull(openAPI.getComponents().getExamples());
+ assertNotNull(openAPI.getComponents().getExamples().get("example"));
+ assertEquals(openAPI.getComponents().getExamples().get("example").getDescription(), "example description");
+ assertEquals(openAPI.getComponents().getExamples().get("example").getSummary(), "example summary");
+ assertEquals(openAPI.getComponents().getExamples().get("example").getValue(), "This is an example");
+
+ assertNotNull(openAPI.getComponents().getRequestBodies());
+ assertNotNull(openAPI.getComponents().getRequestBodies().get("body"));
+
+ assertNotNull(openAPI.getComponents().getHeaders());
+ assertNotNull(openAPI.getComponents().getHeaders().get("test-head"));
+ assertEquals(openAPI.getComponents().getHeaders().get("test-head").getDescription(), "test header description");
+
+ assertNotNull(openAPI.getComponents().getSecuritySchemes());
+ assertNotNull(openAPI.getComponents().getSecuritySchemes().get("basic"));
+ assertEquals(openAPI.getComponents().getSecuritySchemes().get("basic").getDescription(), "security description");
+ assertEquals(openAPI.getComponents().getSecuritySchemes().get("basic").getType().toString(), "http");
+
+ assertNotNull(openAPI.getComponents().getLinks());
+ assertNotNull(openAPI.getComponents().getLinks().get("Link"));
+ assertEquals(openAPI.getComponents().getLinks().get("Link").getOperationRef(), "#/paths/~12.0~1repositories~1{username}/get");
+
+ assertNotNull(openAPI.getComponents().getCallbacks());
+ assertNotNull(openAPI.getComponents().getCallbacks().get("TestCallback"));
+
+ openAPI = Yaml.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(openAPI);
+
+ assertNull(openAPI.getInfo().getSummary());
+ assertNull(openAPI.getWebhooks());
+ assertNull(openAPI.getComponents().getPathItems());
+ assertNull(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator().getExtensions());
+
+ }
+
+ @Test
+ public void testDeserializationOnOAS30() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1_sample.yaml");
+ OpenAPI openAPI = Yaml.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(openAPI);
+
+ assertEquals(openAPI.getInfo().getTitle(), "Swagger Petstore");
+ assertEquals(openAPI.getInfo().getVersion(), "1.0.0");
+ assertNull(openAPI.getInfo().getSummary());
+ assertEquals(openAPI.getInfo().getLicense().getName(), "MIT");
+ assertNull(openAPI.getInfo().getLicense().getIdentifier());
+
+ assertNull(openAPI.getWebhooks());
+
+ assertNull(openAPI.getComponents().getPathItems());
+
+ assertNotNull(openAPI.getComponents().getSchemas());
+ assertNotNull(openAPI.getComponents().getSchemas().get("Pet"));
+ assertNotNull(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator());
+ assertNull(openAPI.getComponents().getSchemas().get("Pet").getDiscriminator().getExtensions());
+
+ assertNotNull(openAPI.getComponents().getResponses());
+ assertNotNull(openAPI.getComponents().getResponses().get("201"));
+ assertEquals(openAPI.getComponents().getResponses().get("201").getDescription(), "api response description");
+
+ assertNotNull(openAPI.getComponents().getParameters());
+ assertNotNull(openAPI.getComponents().getParameters().get("param"));
+ assertEquals(openAPI.getComponents().getParameters().get("param").getIn(), "query");
+ assertEquals(openAPI.getComponents().getParameters().get("param").getName(), "param0");
+ assertEquals(openAPI.getComponents().getParameters().get("param").getDescription(), "parameter description");
+
+ assertNotNull(openAPI.getComponents().getExamples());
+ assertNotNull(openAPI.getComponents().getExamples().get("example"));
+ assertEquals(openAPI.getComponents().getExamples().get("example").getDescription(), "example description");
+ assertEquals(openAPI.getComponents().getExamples().get("example").getSummary(), "example summary");
+ assertEquals(openAPI.getComponents().getExamples().get("example").getValue(), "This is an example");
+
+ assertNotNull(openAPI.getComponents().getRequestBodies());
+ assertNotNull(openAPI.getComponents().getRequestBodies().get("body"));
+
+ assertNotNull(openAPI.getComponents().getHeaders());
+ assertNotNull(openAPI.getComponents().getHeaders().get("test-head"));
+ assertEquals(openAPI.getComponents().getHeaders().get("test-head").getDescription(), "test header description");
+
+ assertNotNull(openAPI.getComponents().getSecuritySchemes());
+ assertNotNull(openAPI.getComponents().getSecuritySchemes().get("basic"));
+ assertEquals(openAPI.getComponents().getSecuritySchemes().get("basic").getDescription(), "security description");
+ assertEquals(openAPI.getComponents().getSecuritySchemes().get("basic").getType().toString(), "http");
+
+ assertNotNull(openAPI.getComponents().getLinks());
+ assertNotNull(openAPI.getComponents().getLinks().get("Link"));
+ assertEquals(openAPI.getComponents().getLinks().get("Link").getOperationRef(), "#/paths/~12.0~1repositories~1{username}/get");
+
+ assertNotNull(openAPI.getComponents().getCallbacks());
+ assertNotNull(openAPI.getComponents().getCallbacks().get("TestCallback"));
+
+ openAPI = Yaml.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(openAPI);
+ }
+
+ @Test
+ public void testRefDeserializationOnOAS31() throws IOException {
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1_refs_siblings.yaml");
+ OpenAPI openAPI = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+
+
+ assertEquals(openAPI.getPaths().get("/ref_pet").get$ref(), "#/components/pathItems/pet");
+ assertEquals(openAPI.getPaths().get("/ref_pet").getDescription(), "ref pathItem description");
+ assertEquals(openAPI.getPaths().get("/ref_pet").getSummary(), "ref pathItem summary");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(0).get$ref(), "#/components/parameters/testParameter");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(0).getDescription(), "ref parameter description");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(1).getName(), "randomParam");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(1).getIn(), "query");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(1).getExamples().get("refExample").get$ref(), "#/components/examples/testExample");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(1).getExamples().get("refExample").getDescription(), "ref example description");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getParameters().get(1).getExamples().get("refExample").getSummary(), "ref example summary");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getCallbacks().get("callIt").get$ref(), "#/components/callbacks/TestCallback");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getRequestBody().get$ref(), "#/components/requestBodies/body");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getRequestBody().getDescription(), "ref request body description");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getResponses().get("201").get$ref(), "#/components/responses/okResponse");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getResponses().get("201").getDescription(), "ref response description");
+
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getResponses().get("default").getHeaders().get("head").get$ref(), "#/components/headers/head");
+ assertEquals(openAPI.getPaths().get("/pets").getPost().getResponses().get("default").getHeaders().get("head").getDescription(), "ref header description");
+
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/SchemaDeserializationTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/SchemaDeserializationTest.java
new file mode 100644
index 0000000000..6f506b3cf5
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/deserialization/SchemaDeserializationTest.java
@@ -0,0 +1,31 @@
+package io.swagger.v3.core.deserialization;
+
+import io.swagger.v3.core.util.ResourceUtils;
+import io.swagger.v3.core.util.Yaml31;
+import io.swagger.v3.oas.models.OpenAPI;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class SchemaDeserializationTest {
+
+ @Test
+ public void deserializeRefSchema3_1() throws IOException {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1_refs_siblings.yaml");
+ final OpenAPI openAPI = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(openAPI);
+ assertNotNull(openAPI.getComponents());
+ assertNotNull(openAPI.getComponents().getSchemas());
+ assertNotNull(openAPI.getComponents().getSchemas().get("AnotherPet"));
+ assertEquals(openAPI.getComponents().getSchemas().get("AnotherPet").get$ref(), "#/components/schemas/Pet");
+ assertEquals(openAPI.getComponents().getSchemas().get("AnotherPet").getTitle(), "Another Pet");
+ assertEquals(openAPI.getComponents().getSchemas().get("AnotherPet").getDescription(), "Another Pet for petstore referencing Pet schema");
+ assertNotNull(openAPI.getComponents().getSchemas().get("AnotherPet").getProperties());
+ assertNotNull(openAPI.getComponents().getSchemas().get("AnotherPet").getProperties().get("category"));
+ assertNotNull(openAPI.getComponents().getSchemas().get("AnotherPet").getProperties().get("photoUrl"));
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/matchers/SerializationMatchers.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/matchers/SerializationMatchers.java
index 1ccb2f27b9..75771ba588 100644
--- a/modules/swagger-core/src/test/java/io/swagger/v3/core/matchers/SerializationMatchers.java
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/matchers/SerializationMatchers.java
@@ -1,11 +1,14 @@
package io.swagger.v3.core.matchers;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.core.util.Json;
+import io.swagger.v3.core.util.Json31;
import io.swagger.v3.core.util.Yaml;
+import io.swagger.v3.core.util.Yaml31;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,6 +28,14 @@ public static void assertEqualsToJson(Object objectToSerialize, String jsonStr)
apply(objectToSerialize, jsonStr, Json.mapper());
}
+ public static void assertEqualsToYaml31(Object objectToSerialize, String yamlStr) {
+ apply31(objectToSerialize, yamlStr, Yaml31.mapper());
+ }
+
+ public static void assertEqualsToJson31(Object objectToSerialize, String jsonStr) {
+ apply31(objectToSerialize, jsonStr, Json31.mapper());
+ }
+
private static void apply(Object objectToSerialize, String str, ObjectMapper mapper) {
final ObjectNode lhs = mapper.convertValue(objectToSerialize, ObjectNode.class);
ObjectNode rhs = null;
@@ -39,6 +50,20 @@ private static void apply(Object objectToSerialize, String str, ObjectMapper map
}
}
+ private static void apply31(Object objectToSerialize, String str, ObjectMapper mapper) {
+ final ObjectNode lhs = mapper.convertValue(objectToSerialize, ObjectNode.class);
+ ObjectNode rhs = null;
+ try {
+ rhs = mapper.readValue(str, ObjectNode.class);
+ } catch (IOException e) {
+ LOGGER.error("Failed to read value", e);
+ }
+ if (!lhs.equals(new ObjectNodeComparator(), rhs)) {
+ assertEquals(Yaml31.pretty(lhs), Yaml31.pretty(rhs));
+ //fail(String.format("Serialized object:\n%s\ndoes not equal to expected serialized string:\n%s", lhs, rhs));
+ }
+ }
+
static final class ObjectNodeComparator implements Comparator {
@Override
public int compare(JsonNode o1, JsonNode o2) {
@@ -57,4 +82,4 @@ public int compare(JsonNode o1, JsonNode o2) {
return comp;
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/PatternAndSchemaPropertiesTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/PatternAndSchemaPropertiesTest.java
new file mode 100644
index 0000000000..09a7195a94
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/PatternAndSchemaPropertiesTest.java
@@ -0,0 +1,184 @@
+package io.swagger.v3.core.resolving.v31;
+
+import io.swagger.v3.core.converter.AnnotatedType;
+import io.swagger.v3.core.converter.ModelConverterContextImpl;
+import io.swagger.v3.core.jackson.ModelResolver;
+import io.swagger.v3.core.matchers.SerializationMatchers;
+import io.swagger.v3.core.resolving.SwaggerTestBase;
+import io.swagger.v3.core.resolving.v31.model.AnnotatedPet;
+import io.swagger.v3.core.resolving.v31.model.AnnotatedPetSinglePatternProperty;
+import io.swagger.v3.core.util.OpenAPISchema2JsonSchema;
+import io.swagger.v3.oas.models.media.Schema;
+import org.testng.annotations.Test;
+
+
+import static org.testng.Assert.assertEquals;
+
+public class PatternAndSchemaPropertiesTest extends SwaggerTestBase {
+
+ @Test
+ public void testPatternAndSchemaProperties() throws Exception {
+
+ final ModelResolver modelResolver = new ModelResolver(mapper());
+
+ ModelConverterContextImpl context = new ModelConverterContextImpl(modelResolver);
+
+ Schema model = context
+ .resolve(new AnnotatedType(AnnotatedPet.class));
+
+ assertEquals(((Schema)model.getPatternProperties().get("what.*ever")).getFormat(), "int32");
+ assertEquals(((Schema)model.getPatternProperties().get("it.*takes")).get$ref(), "#/components/schemas/Category");
+
+ assertEquals(((Schema)model.getProperties().get("anotherCategory")).get$ref(), "#/components/schemas/Category");
+ assertEquals(((Schema)model.getProperties().get("anotherInteger")).getFormat(), "int32");
+
+ SerializationMatchers.assertEqualsToYaml(context.getDefinedModels(), "AnnotatedPet:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " category:\n" +
+ " $ref: '#/components/schemas/Category'\n" +
+ " name:\n" +
+ " type: string\n" +
+ " photoUrls:\n" +
+ " type: array\n" +
+ " xml:\n" +
+ " wrapped: true\n" +
+ " items:\n" +
+ " type: string\n" +
+ " xml:\n" +
+ " name: photoUrl\n" +
+ " tags:\n" +
+ " type: array\n" +
+ " xml:\n" +
+ " wrapped: true\n" +
+ " items:\n" +
+ " $ref: '#/components/schemas/Tag'\n" +
+ " status:\n" +
+ " type: string\n" +
+ " description: pet status in the store\n" +
+ " enum:\n" +
+ " - available\n" +
+ " - pending\n" +
+ " - sold\n" +
+ " anotherCategory:\n" +
+ " $ref: '#/components/schemas/Category'\n" +
+ " anotherInteger:\n" +
+ " maximum: 10\n" +
+ " type: integer\n" +
+ " description: prop schema 1\n" +
+ " format: int32\n" +
+ " description: Annotated Pet\n" +
+ " nullable: true\n" +
+ "Category:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " name:\n" +
+ " type: string\n" +
+ " description: prop schema 2\n" +
+ " xml:\n" +
+ " name: Category\n" +
+ "Tag:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " name:\n" +
+ " type: string\n" +
+ " xml:\n" +
+ " name: Tag");
+ context.getDefinedModels().values().forEach(s -> new OpenAPISchema2JsonSchema().process(s));
+
+ SerializationMatchers.assertEqualsToYaml31(context.getDefinedModels(), "AnnotatedPet:\n" +
+ " type:\n" +
+ " - object\n" +
+ " - \"null\"\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " category:\n" +
+ " $ref: '#/components/schemas/Category'\n" +
+ " name:\n" +
+ " type: string\n" +
+ " photoUrls:\n" +
+ " type: array\n" +
+ " xml:\n" +
+ " wrapped: true\n" +
+ " items:\n" +
+ " type: string\n" +
+ " xml:\n" +
+ " name: photoUrl\n" +
+ " tags:\n" +
+ " type: array\n" +
+ " xml:\n" +
+ " wrapped: true\n" +
+ " items:\n" +
+ " $ref: '#/components/schemas/Tag'\n" +
+ " status:\n" +
+ " type: string\n" +
+ " description: pet status in the store\n" +
+ " enum:\n" +
+ " - available\n" +
+ " - pending\n" +
+ " - sold\n" +
+ " anotherCategory:\n" +
+ " $ref: '#/components/schemas/Category'\n" +
+ " anotherInteger:\n" +
+ " maximum: 10\n" +
+ " type: integer\n" +
+ " description: prop schema 1\n" +
+ " format: int32\n" +
+ " patternProperties:\n" +
+ " what.*ever:\n" +
+ " maximum: 10\n" +
+ " type: integer\n" +
+ " description: prop schema 1\n" +
+ " format: int32\n" +
+ " it.*takes:\n" +
+ " $ref: '#/components/schemas/Category'\n" +
+ " description: Annotated Pet\n" +
+ "Category:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " name:\n" +
+ " type: string\n" +
+ " description: prop schema 2\n" +
+ " xml:\n" +
+ " name: Category\n" +
+ "Tag:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " name:\n" +
+ " type: string\n" +
+ " xml:\n" +
+ " name: Tag\n");
+ }
+
+ @Test
+ public void testSinglePatternAndSchemaProperties() throws Exception {
+
+ final ModelResolver modelResolver = new ModelResolver(mapper());
+
+ ModelConverterContextImpl context = new ModelConverterContextImpl(modelResolver);
+
+ Schema model = context
+ .resolve(new AnnotatedType(AnnotatedPetSinglePatternProperty.class));
+
+ assertEquals(((Schema)model.getPatternProperties().get("what.*ever")).getFormat(), "int32");
+ assertEquals(((Schema)model.getProperties().get("anotherCategory")).get$ref(), "#/components/schemas/Category");
+ }
+
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPet.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPet.java
new file mode 100644
index 0000000000..ac6f4e7e8f
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPet.java
@@ -0,0 +1,109 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import io.swagger.v3.oas.annotations.media.PatternProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import java.util.ArrayList;
+import java.util.List;
+
+@Schema(description = "Annotated Pet", nullable = true)
+@PatternProperty(
+ regex = "what.*ever",
+ schema = @Schema(
+ type = "integer",
+ description = "prop schema 1",
+ format = "int32",
+ maximum = "10"
+ )
+)
+@PatternProperty(
+ regex = "it.*takes",
+ schema = @Schema(
+ implementation = Category.class,
+ description = "prop schema 2"
+ )
+)
+@SchemaProperty(
+ name = "anotherCategory",
+ schema = @Schema(
+ implementation = Category.class,
+ description = "prop schema 2"
+ )
+)
+@SchemaProperty(
+ name = "anotherInteger",
+ schema = @Schema(
+ type = "integer",
+ description = "prop schema 1",
+ format = "int32",
+ maximum = "10"
+ )
+)
+public class AnnotatedPet {
+ private long id;
+ private Category category;
+ private String name;
+ private List photoUrls = new ArrayList();
+ private List tags = new ArrayList();
+ private String status;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "category")
+ public Category getCategory() {
+ return category;
+ }
+
+ public void setCategory(Category category) {
+ this.category = category;
+ }
+
+ @XmlElement(name = "name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @XmlElementWrapper(name = "photoUrls")
+ @XmlElement(name = "photoUrl")
+ public List getPhotoUrls() {
+ return photoUrls;
+ }
+
+ public void setPhotoUrls(List photoUrls) {
+ this.photoUrls = photoUrls;
+ }
+
+ @XmlElementWrapper(name = "tags")
+ @XmlElement(name = "tag")
+ public List getTags() {
+ return tags;
+ }
+
+ public void setTags(List tags) {
+ this.tags = tags;
+ }
+
+ @XmlElement(name = "status")
+ @Schema(description = "pet status in the store", allowableValues = {"available", "pending", "sold"})
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPetSinglePatternProperty.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPetSinglePatternProperty.java
new file mode 100644
index 0000000000..8e47b5586c
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/AnnotatedPetSinglePatternProperty.java
@@ -0,0 +1,93 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import io.swagger.v3.oas.annotations.media.PatternProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import java.util.ArrayList;
+import java.util.List;
+
+@Schema(description = "Annotated Pet", nullable = true)
+@PatternProperty(
+ regex = "what.*ever",
+ schema = @Schema(
+ type = "integer",
+ description = "prop schema 1",
+ format = "int32",
+ maximum = "10"
+ )
+)
+@SchemaProperty(
+ name = "anotherCategory",
+ schema = @Schema(
+ implementation = Category.class,
+ description = "prop schema 2"
+ )
+)
+public class AnnotatedPetSinglePatternProperty {
+ private long id;
+ private Category category;
+ private String name;
+ private List photoUrls = new ArrayList();
+ private List tags = new ArrayList();
+ private String status;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "category")
+ public Category getCategory() {
+ return category;
+ }
+
+ public void setCategory(Category category) {
+ this.category = category;
+ }
+
+ @XmlElement(name = "name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @XmlElementWrapper(name = "photoUrls")
+ @XmlElement(name = "photoUrl")
+ public List getPhotoUrls() {
+ return photoUrls;
+ }
+
+ public void setPhotoUrls(List photoUrls) {
+ this.photoUrls = photoUrls;
+ }
+
+ @XmlElementWrapper(name = "tags")
+ @XmlElement(name = "tag")
+ public List getTags() {
+ return tags;
+ }
+
+ public void setTags(List tags) {
+ this.tags = tags;
+ }
+
+ @XmlElement(name = "status")
+ @Schema(description = "pet status in the store", allowableValues = {"available", "pending", "sold"})
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Category.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Category.java
new file mode 100644
index 0000000000..df3c2a5ac0
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Category.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2016 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.core.resolving.v31.model;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Category")
+public class Category {
+ private long id;
+ private String name;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Category() {
+ }
+
+ public Category(String name) {
+ this.name = name;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/CustomGenerator.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/CustomGenerator.java
new file mode 100644
index 0000000000..240cc539de
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/CustomGenerator.java
@@ -0,0 +1,32 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import com.fasterxml.jackson.annotation.ObjectIdGenerator;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+public class CustomGenerator extends ObjectIdGenerators.PropertyGenerator {
+ private static final long serialVersionUID = 1L;
+
+ protected CustomGenerator(Class> scope) {
+ super(scope);
+ }
+
+ @Override
+ public ObjectIdGenerator forScope(Class> scope) {
+ return null;
+ }
+
+ @Override
+ public ObjectIdGenerator newForSerialization(Object context) {
+ return null;
+ }
+
+ @Override
+ public IdKey key(Object key) {
+ return null;
+ }
+
+ @Override
+ public Object generateId(Object forPojo) {
+ return null;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ExtensionUser.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ExtensionUser.java
new file mode 100644
index 0000000000..24647d7e82
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ExtensionUser.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright 2016 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.core.resolving.v31.model;
+
+import io.swagger.v3.oas.annotations.extensions.Extension;
+import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "User")
+@Schema(
+ description = "User",
+ extensions = {
+ @Extension(name = "x-user", properties = {
+ @ExtensionProperty(name = "name", value = "Josh")}),
+ @Extension(name = "user-extensions", properties = {
+ @ExtensionProperty(name = "lastName", value = "Hart"),
+ @ExtensionProperty(name = "address", value = "House")})
+ }
+)
+public class ExtensionUser {
+ private long id;
+ private String username;
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String password;
+ private String phone;
+ private int userStatus;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "firstName")
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ @XmlElement(name = "username")
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ @XmlElement(name = "lastName")
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @XmlElement(name = "email")
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ @XmlElement(name = "password")
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @XmlElement(name = "phone")
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ @XmlElement(name = "userStatus")
+ @Schema(
+ description = "User Status",
+ extensions = {
+ @Extension(name = "x-userStatus", properties = {
+ @ExtensionProperty(name = "name", value = "Josh")}),
+ @Extension(name = "userStatus-extensions", properties = {
+ @ExtensionProperty(name = "lastName", value = "Hart"),
+ @ExtensionProperty(name = "address", value = "House")})
+ }
+ )
+ public int getUserStatus() {
+ return userStatus;
+ }
+
+ public void setUserStatus(int userStatus) {
+ this.userStatus = userStatus;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/JacksonBean.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/JacksonBean.java
new file mode 100644
index 0000000000..fe8b341124
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/JacksonBean.java
@@ -0,0 +1,76 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonUnwrapped;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public class JacksonBean {
+
+ private String id;
+ private String ignored;
+ private StringValueBean bean;
+ private NotFoundModel model;
+ private NotFoundModel model2;
+
+ @JsonIgnore
+ public String getIgnored() {
+ return ignored;
+ }
+
+ public void setIgnored(String ignored) {
+ this.ignored = ignored;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setModel(NotFoundModel model) {
+ this.model = model;
+ }
+
+ public StringValueBean getBean() {
+ return bean;
+ }
+
+ public void setBean(StringValueBean bean) {
+ this.bean = bean;
+ }
+
+ @JsonProperty("identity")
+ public String getId() {
+ return id;
+ }
+
+ @JsonUnwrapped
+ public NotFoundModel getModel() {
+ return model;
+ }
+
+ @JsonUnwrapped(prefix = "pre", suffix = "suf")
+ public NotFoundModel getModel2() {
+ return model2;
+ }
+
+ public void setModel2(NotFoundModel model2) {
+ this.model2 = model2;
+ }
+
+ public static class StringValueBean {
+
+ private final String value;
+
+ @JsonCreator
+ public StringValueBean(String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+ }
+
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ListOfStringsBeanParam.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ListOfStringsBeanParam.java
new file mode 100644
index 0000000000..a5a8eb5fc5
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ListOfStringsBeanParam.java
@@ -0,0 +1,17 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import javax.ws.rs.QueryParam;
+import java.util.List;
+
+public class ListOfStringsBeanParam {
+ @QueryParam(value = "listOfStrings")
+ private List list;
+
+ public List getList() {
+ return list;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentity.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentity.java
new file mode 100644
index 0000000000..ff00051313
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentity.java
@@ -0,0 +1,145 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+public class ModelWithJsonIdentity {
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name")
+ @JsonProperty("PropertyGeneratorAsId")
+ public SourceDefinition1 testPropertyGeneratorAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name")
+ @JsonProperty("PropertyGeneratorAsProperty")
+ public SourceDefinition1 testPropertyGeneratorAsProperty;
+
+ public class SourceDefinition1 {
+ public String driver;
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "driverId")
+ @JsonProperty("ChangedPropertyName")
+ public SourceDefinition2 testChangedPropertyName;
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "driverId")
+ @JsonProperty("ChangedPropertyName2")
+ public SourceDefinition2 testChangedPropertyName2;
+
+ static public class SourceDefinition2 {
+ @JsonProperty("driverId")
+ public String driver;
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class)
+ @JsonProperty("SourceWithoutPropertyAsId")
+ public SourceDefinition3 testWithoutPropertyAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class)
+ @JsonProperty("SourceWithoutPropertyAsProperty")
+ public SourceDefinition3 testWithoutPropertyAsProperty;
+
+ public class SourceDefinition3 {
+ @JsonProperty("driverId")
+ public String driver;
+ public String name;
+
+ @JsonProperty("@id")
+ public String id;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "testName1")
+ @JsonProperty("IntSequenceGeneratorAsId")
+ public SourceDefinition4 testIntSequenceGeneratorAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "testName2")
+ @JsonProperty("IntSequenceGeneratorAsProperty")
+ public SourceDefinition4 testIntSequenceGeneratorAsProperty;
+
+ public class SourceDefinition4 {
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
+ @JsonProperty("IntSequenceWithoutPropertyAsId")
+ public SourceDefinition5 testIntSequenceWithoutPropertyAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
+ @JsonProperty("IntSequenceWithoutPropertyAsProperty")
+ public SourceDefinition5 testIntSequenceWithoutPropertyAsProperty;
+
+ public class SourceDefinition5 {
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "UUID1")
+ @JsonProperty("UUIDGeneratorAsId")
+ public SourceDefinition6 testUUIDGeneratorAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "UUID2")
+ @JsonProperty("UUIDGeneratorAsProperty")
+ public SourceDefinition6 testUUIDGeneratorAsProperty;
+
+ public class SourceDefinition6 {
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
+ @JsonProperty("UUIDGeneratorWithoutPropertyAsId")
+ public SourceDefinition7 testUUIDGeneratorWithoutPropertyAsId;
+
+ @JsonIdentityReference(alwaysAsId = false)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
+ @JsonProperty("UUIDGeneratorWithoutPropertyAsProperty")
+ public SourceDefinition7 testUUIDGeneratorWithoutPropertyAsProperty;
+
+ public class SourceDefinition7 {
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = ObjectIdGenerators.None.class, property = "testGeneratorsNone")
+ @JsonProperty("GeneratorsNone")
+ public SourceDefinition8 testGeneratorsNone;
+
+ public class SourceDefinition8 {
+ @JsonProperty("driverId")
+ public String driver;
+ public String name;
+ }
+
+ @JsonIdentityReference(alwaysAsId = true)
+ @JsonIdentityInfo(generator = CustomGenerator.class, property = "name")
+ @JsonProperty("CustomGenerator")
+ public SourceDefinition9 testCustomGenerator;
+
+ public class SourceDefinition9 {
+ public String driver;
+ public String name;
+ }
+
+ @JsonIdentityInfo(generator = CustomGenerator.class, property = "name")
+ @JsonProperty("WithoutJsonIdentityReference")
+ public SourceDefinition10 testWithoutJsonIdentityReference;
+
+ public class SourceDefinition10 {
+ public String driver;
+ public String name;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentityCyclic.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentityCyclic.java
new file mode 100644
index 0000000000..381c2716f7
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/ModelWithJsonIdentityCyclic.java
@@ -0,0 +1,29 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+import java.util.List;
+
+public class ModelWithJsonIdentityCyclic {
+
+ public Long id;
+
+ public List sourceDefinitions;
+
+ @JsonIdentityInfo(
+ generator = ObjectIdGenerators.PropertyGenerator.class,
+ property = "name")
+ public static class SourceDefinition {
+ public String driver;
+ public String name;
+
+ @JsonIdentityReference(alwaysAsId=true)
+ @JsonIdentityInfo(
+ generator = ObjectIdGenerators.PropertyGenerator.class,
+ property = "id")
+ public ModelWithJsonIdentityCyclic model;
+ }
+
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleBaseBean.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleBaseBean.java
new file mode 100644
index 0000000000..8d79b293e5
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleBaseBean.java
@@ -0,0 +1,11 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+@io.swagger.v3.oas.annotations.media.Schema(
+ description = "MultipleBaseBean",
+ subTypes = { MultipleSub1Bean.class, MultipleSub2Bean.class }
+)
+public class MultipleBaseBean {
+ public String beanType;
+ public int a;
+ public String b;
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub1Bean.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub1Bean.java
new file mode 100644
index 0000000000..7637d22609
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub1Bean.java
@@ -0,0 +1,8 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+@io.swagger.v3.oas.annotations.media.Schema(
+ description = "MultipleSub1Bean"
+)
+public class MultipleSub1Bean extends MultipleBaseBean {
+ public int c;
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub2Bean.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub2Bean.java
new file mode 100644
index 0000000000..044320bde9
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/MultipleSub2Bean.java
@@ -0,0 +1,8 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+@io.swagger.v3.oas.annotations.media.Schema(
+ description = "MultipleSub2Bean"
+)
+public class MultipleSub2Bean extends MultipleBaseBean {
+ public int d;
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/NotFoundModel.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/NotFoundModel.java
new file mode 100644
index 0000000000..27619e95f4
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/NotFoundModel.java
@@ -0,0 +1,30 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+public class NotFoundModel {
+ int code;
+ String message;
+
+ public NotFoundModel() {
+ }
+
+ public NotFoundModel(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Pet.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Pet.java
new file mode 100644
index 0000000000..1554a00ddb
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Pet.java
@@ -0,0 +1,76 @@
+package io.swagger.v3.core.resolving.v31.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement(name = "Pet")
+public class Pet {
+ private long id;
+ private Category category;
+ private String name;
+ private List photoUrls = new ArrayList();
+ private List tags = new ArrayList();
+ private String status;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "category")
+ public Category getCategory() {
+ return category;
+ }
+
+ public void setCategory(Category category) {
+ this.category = category;
+ }
+
+ @XmlElement(name = "name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @XmlElementWrapper(name = "photoUrls")
+ @XmlElement(name = "photoUrl")
+ public List getPhotoUrls() {
+ return photoUrls;
+ }
+
+ public void setPhotoUrls(List photoUrls) {
+ this.photoUrls = photoUrls;
+ }
+
+ @XmlElementWrapper(name = "tags")
+ @XmlElement(name = "tag")
+ public List getTags() {
+ return tags;
+ }
+
+ public void setTags(List tags) {
+ this.tags = tags;
+ }
+
+ @XmlElement(name = "status")
+ @Schema(description = "pet status in the store", allowableValues = {"available", "pending", "sold"})
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Tag.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Tag.java
new file mode 100644
index 0000000000..1d24a79c67
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/Tag.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2016 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.core.resolving.v31.model;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Tag")
+public class Tag {
+ private long id;
+ private String name;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/User.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/User.java
new file mode 100644
index 0000000000..27ce93f0d6
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/model/User.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2016 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.core.resolving.v31.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "User")
+public class User {
+ private long id;
+ private String username;
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String password;
+ private String phone;
+ private int userStatus;
+
+ @XmlElement(name = "id")
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @XmlElement(name = "firstName")
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ @XmlElement(name = "username")
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ @XmlElement(name = "lastName")
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @XmlElement(name = "email")
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ @XmlElement(name = "password")
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @XmlElement(name = "phone")
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ @XmlElement(name = "userStatus")
+ @Schema(description = "User Status") //, allowableValues = {"1","2","3"})
+ public int getUserStatus() {
+ return userStatus;
+ }
+
+ public void setUserStatus(int userStatus) {
+ this.userStatus = userStatus;
+ }
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/OpenAPI3_1SerializationTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/OpenAPI3_1SerializationTest.java
new file mode 100644
index 0000000000..ddd08549a3
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/OpenAPI3_1SerializationTest.java
@@ -0,0 +1,1361 @@
+package io.swagger.v3.core.serialization;
+
+import io.swagger.v3.core.matchers.SerializationMatchers;
+import io.swagger.v3.core.util.ResourceUtils;
+import io.swagger.v3.core.util.Yaml31;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.callbacks.Callback;
+import io.swagger.v3.oas.models.examples.Example;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.links.Link;
+import io.swagger.v3.oas.models.media.Content;
+import io.swagger.v3.oas.models.media.Discriminator;
+import io.swagger.v3.oas.models.media.MediaType;
+import io.swagger.v3.oas.models.media.ObjectSchema;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.media.StringSchema;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.parameters.RequestBody;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class OpenAPI3_1SerializationTest {
+
+ @Test
+ public void testSerializePetstore() throws Exception {
+
+ final String jsonString = ResourceUtils.loadClassResource(getClass(), "specFiles/3.1.0/petstore-3.1.yaml");
+ final OpenAPI swagger = Yaml31.mapper().readValue(jsonString, OpenAPI.class);
+ assertNotNull(swagger);
+ assertEquals(swagger.getInfo().getLicense().getIdentifier(), "test");
+ SerializationMatchers.assertEqualsToYaml31(swagger, "openapi: 3.1.0\n" +
+ "info:\n" +
+ " title: Swagger Petstore\n" +
+ " license:\n" +
+ " name: MIT\n" +
+ " identifier: test\n" +
+ " version: 1.0.0\n" +
+ "servers:\n" +
+ "- url: http://petstore.swagger.io/v1\n" +
+ "paths:\n" +
+ " /pets:\n" +
+ " get:\n" +
+ " tags:\n" +
+ " - pets\n" +
+ " summary: List all pets\n" +
+ " operationId: listPets\n" +
+ " parameters:\n" +
+ " - name: limit\n" +
+ " in: query\n" +
+ " description: How many items to return at one time (max 100)\n" +
+ " required: false\n" +
+ " schema:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: An paged array of pets\n" +
+ " headers:\n" +
+ " x-next:\n" +
+ " description: A link to the next page of responses\n" +
+ " schema:\n" +
+ " type: string\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Pets'\n" +
+ " default:\n" +
+ " description: unexpected error\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Error'\n" +
+ " post:\n" +
+ " tags:\n" +
+ " - pets\n" +
+ " summary: Create a pet\n" +
+ " operationId: createPets\n" +
+ " responses:\n" +
+ " \"201\":\n" +
+ " description: Null response\n" +
+ " default:\n" +
+ " description: unexpected error\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Error'\n" +
+ " /pets/{petId}:\n" +
+ " get:\n" +
+ " tags:\n" +
+ " - pets\n" +
+ " summary: Info for a specific pet\n" +
+ " operationId: showPetById\n" +
+ " parameters:\n" +
+ " - name: petId\n" +
+ " in: path\n" +
+ " description: The id of the pet to retrieve\n" +
+ " required: true\n" +
+ " schema:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: Expected response to a valid request\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Pets'\n" +
+ " default:\n" +
+ " description: unexpected error\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Error'\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " Pet:\n" +
+ " required:\n" +
+ " - id\n" +
+ " - name\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " format: int64\n" +
+ " name:\n" +
+ " type:\n" +
+ " - string\n" +
+ " - integer\n" +
+ " tag:\n" +
+ " type: string\n" +
+ " Pets:\n" +
+ " type: array\n" +
+ " items:\n" +
+ " $ref: '#/components/schemas/Pet'\n" +
+ " Error:\n" +
+ " required:\n" +
+ " - code\n" +
+ " - message\n" +
+ " properties:\n" +
+ " code:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " message:\n" +
+ " type: string\n" +
+ "webhooks:\n" +
+ " newPet:\n" +
+ " post:\n" +
+ " requestBody:\n" +
+ " description: Information about a new pet in the system\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/Pet'\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: Return a 200 status to indicate that the data was received\n" +
+ " successfully");
+ SerializationMatchers.assertEqualsToJson31(swagger, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"info\" : {\n" +
+ " \"title\" : \"Swagger Petstore\",\n" +
+ " \"license\" : {\n" +
+ " \"name\" : \"MIT\",\n" +
+ " \"identifier\" : \"test\"\n" +
+ " },\n" +
+ " \"version\" : \"1.0.0\"\n" +
+ " },\n" +
+ " \"servers\" : [ {\n" +
+ " \"url\" : \"http://petstore.swagger.io/v1\"\n" +
+ " } ],\n" +
+ " \"paths\" : {\n" +
+ " \"/pets\" : {\n" +
+ " \"get\" : {\n" +
+ " \"tags\" : [ \"pets\" ],\n" +
+ " \"summary\" : \"List all pets\",\n" +
+ " \"operationId\" : \"listPets\",\n" +
+ " \"parameters\" : [ {\n" +
+ " \"name\" : \"limit\",\n" +
+ " \"in\" : \"query\",\n" +
+ " \"description\" : \"How many items to return at one time (max 100)\",\n" +
+ " \"required\" : false,\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"integer\",\n" +
+ " \"format\" : \"int32\"\n" +
+ " }\n" +
+ " } ],\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"An paged array of pets\",\n" +
+ " \"headers\" : {\n" +
+ " \"x-next\" : {\n" +
+ " \"description\" : \"A link to the next page of responses\",\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Pets\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"default\" : {\n" +
+ " \"description\" : \"unexpected error\",\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Error\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"post\" : {\n" +
+ " \"tags\" : [ \"pets\" ],\n" +
+ " \"summary\" : \"Create a pet\",\n" +
+ " \"operationId\" : \"createPets\",\n" +
+ " \"responses\" : {\n" +
+ " \"201\" : {\n" +
+ " \"description\" : \"Null response\"\n" +
+ " },\n" +
+ " \"default\" : {\n" +
+ " \"description\" : \"unexpected error\",\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Error\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"/pets/{petId}\" : {\n" +
+ " \"get\" : {\n" +
+ " \"tags\" : [ \"pets\" ],\n" +
+ " \"summary\" : \"Info for a specific pet\",\n" +
+ " \"operationId\" : \"showPetById\",\n" +
+ " \"parameters\" : [ {\n" +
+ " \"name\" : \"petId\",\n" +
+ " \"in\" : \"path\",\n" +
+ " \"description\" : \"The id of the pet to retrieve\",\n" +
+ " \"required\" : true,\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " } ],\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"Expected response to a valid request\",\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Pets\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"default\" : {\n" +
+ " \"description\" : \"unexpected error\",\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Error\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"Pet\" : {\n" +
+ " \"required\" : [ \"id\", \"name\" ],\n" +
+ " \"properties\" : {\n" +
+ " \"id\" : {\n" +
+ " \"type\" : \"integer\",\n" +
+ " \"format\" : \"int64\"\n" +
+ " },\n" +
+ " \"name\" : {\n" +
+ " \"type\" : [\"string\", \"integer\"]\n" +
+ " },\n" +
+ " \"tag\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"Pets\" : {\n" +
+ " \"type\" : \"array\",\n" +
+ " \"items\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Pet\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"Error\" : {\n" +
+ " \"required\" : [ \"code\", \"message\" ],\n" +
+ " \"properties\" : {\n" +
+ " \"code\" : {\n" +
+ " \"type\" : \"integer\",\n" +
+ " \"format\" : \"int32\"\n" +
+ " },\n" +
+ " \"message\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"webhooks\" : {\n" +
+ " \"newPet\" : {\n" +
+ " \"post\" : {\n" +
+ " \"requestBody\" : {\n" +
+ " \"description\" : \"Information about a new pet in the system\",\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"$ref\" : \"#/components/schemas/Pet\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"Return a 200 status to indicate that the data was received successfully\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+
+ }
+
+ @Test
+ public void testInfoSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .info(new Info()
+ .title("Title test")
+ .description("This is a description for test")
+ .summary("Test Summary")
+ .version("1.0.0")
+ .termsOfService("https://test.term.of.services")
+ .contact(new Contact()
+ .name("Test Contact")
+ .url("https://test.contact.url")
+ .email("test@email.com"))
+ .license(new License()
+ .name("test license")
+ .url("https://test.license.com")
+ .identifier("swagger")));
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "info:\n" +
+ " title: Title test\n" +
+ " description: This is a description for test\n" +
+ " summary: Test Summary\n" +
+ " termsOfService: https://test.term.of.services\n" +
+ " contact:\n" +
+ " name: Test Contact\n" +
+ " url: https://test.contact.url\n" +
+ " email: test@email.com\n" +
+ " license:\n" +
+ " name: test license\n" +
+ " url: https://test.license.com\n" +
+ " identifier: swagger\n" +
+ " version: 1.0.0");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"info\" : {\n" +
+ " \"title\" : \"Title test\",\n" +
+ " \"description\" : \"This is a description for test\",\n" +
+ " \"summary\" : \"Test Summary\",\n" +
+ " \"termsOfService\" : \"https://test.term.of.services\",\n" +
+ " \"contact\" : {\n" +
+ " \"name\" : \"Test Contact\",\n" +
+ " \"url\" : \"https://test.contact.url\",\n" +
+ " \"email\" : \"test@email.com\"\n" +
+ " },\n" +
+ " \"license\" : {\n" +
+ " \"name\" : \"test license\",\n" +
+ " \"url\" : \"https://test.license.com\",\n" +
+ " \"identifier\" : \"swagger\"\n" +
+ " },\n" +
+ " \"version\" : \"1.0.0\"\n" +
+ " }\n" +
+ "}");
+
+ openAPI.setOpenapi("3.0.3");
+ SerializationMatchers.assertEqualsToYaml(openAPI, "openapi: 3.0.3\n" +
+ "info:\n" +
+ " title: Title test\n" +
+ " description: This is a description for test\n" +
+ " termsOfService: https://test.term.of.services\n" +
+ " contact:\n" +
+ " name: Test Contact\n" +
+ " url: https://test.contact.url\n" +
+ " email: test@email.com\n" +
+ " license:\n" +
+ " name: test license\n" +
+ " url: https://test.license.com\n" +
+ " version: 1.0.0");
+
+ SerializationMatchers.assertEqualsToJson(openAPI, "{\n" +
+ " \"openapi\" : \"3.0.3\",\n" +
+ " \"info\" : {\n" +
+ " \"title\" : \"Title test\",\n" +
+ " \"description\" : \"This is a description for test\",\n" +
+ " \"termsOfService\" : \"https://test.term.of.services\",\n" +
+ " \"contact\" : {\n" +
+ " \"name\" : \"Test Contact\",\n" +
+ " \"url\" : \"https://test.contact.url\",\n" +
+ " \"email\" : \"test@email.com\"\n" +
+ " },\n" +
+ " \"license\" : {\n" +
+ " \"name\" : \"test license\",\n" +
+ " \"url\" : \"https://test.license.com\"\n" +
+ " },\n" +
+ " \"version\" : \"1.0.0\"\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testWebHooksSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .addWebhooks("hook", new PathItem()
+ .description("test path hook")
+ .get(new Operation()
+ .operationId("testHookOperation")
+ .responses(new ApiResponses()
+ .addApiResponse("200", new ApiResponse().description("test response description")))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "webhooks:\n" +
+ " hook:\n" +
+ " description: test path hook\n" +
+ " get:\n" +
+ " operationId: testHookOperation\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: test response description");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"webhooks\" : {\n" +
+ " \"hook\" : {\n" +
+ " \"description\" : \"test path hook\",\n" +
+ " \"get\" : {\n" +
+ " \"operationId\" : \"testHookOperation\",\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"test response description\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ openAPI.setOpenapi("3.0.3");
+ SerializationMatchers.assertEqualsToYaml(openAPI, "openapi: 3.0.3");
+ SerializationMatchers.assertEqualsToJson(openAPI, "{\n" +
+ " \"openapi\" : \"3.0.3\"\n}");
+
+ }
+
+ @Test
+ public void testComponentPathItemsSerialization() {
+ Schema schema = new StringSchema();
+ schema.addType(schema.getType());
+ OpenAPI openAPI = new OpenAPI().openapi("3.1.0").components(new Components()
+ .addSchemas("stringTest", schema)
+ .addPathItem("/pathTest", new PathItem()
+ .description("test path item")
+ .get(new Operation()
+ .operationId("testPathItem")
+ .responses(new ApiResponses()
+ .addApiResponse("200", new ApiResponse().description("response description")))))
+ .addResponses("201", new ApiResponse()
+ .description("api response description"))
+ .addParameters("param", new Parameter()
+ .in("query")
+ .description("parameter description")
+ .schema(schema))
+ .addExamples("example", new Example()
+ .summary("example summary")
+ .value("This is an example/")
+ .description("example description"))
+ .addRequestBodies("body", new RequestBody()
+ .content(new Content()
+ .addMediaType("application/json", new MediaType()
+ .schema(new ObjectSchema()))))
+ .addHeaders("test-head", new Header()
+ .description("test header description"))
+ .addSecuritySchemes("basic", new SecurityScheme()
+ .in(SecurityScheme.In.HEADER)
+ .scheme("http")
+ .description("ref security description"))
+ .addLinks("Link", new Link()
+ .operationRef("#/paths/~12.0~1repositories~1{username}/get"))
+ .addCallbacks("TestCallback", new Callback().addPathItem("{$request.query.queryUrl}", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " stringTest:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " \"201\":\n" +
+ " description: api response description\n" +
+ " parameters:\n" +
+ " param:\n" +
+ " in: query\n" +
+ " description: parameter description\n" +
+ " schema:\n" +
+ " type: string\n" +
+ " examples:\n" +
+ " example:\n" +
+ " summary: example summary\n" +
+ " description: example description\n" +
+ " value: This is an example/\n" +
+ " requestBodies:\n" +
+ " body:\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema: {}\n" +
+ " headers:\n" +
+ " test-head:\n" +
+ " description: test header description\n" +
+ " securitySchemes:\n" +
+ " basic:\n" +
+ " description: ref security description\n" +
+ " in: header\n" +
+ " scheme: http\n" +
+ " links:\n" +
+ " Link:\n" +
+ " operationRef: \"#/paths/~12.0~1repositories~1{username}/get\"\n" +
+ " callbacks:\n" +
+ " TestCallback:\n" +
+ " '{$request.query.queryUrl}':\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem\n" +
+ " pathItems:\n" +
+ " /pathTest:\n" +
+ " description: test path item\n" +
+ " get:\n" +
+ " operationId: testPathItem\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: response description");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"stringTest\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"responses\" : {\n" +
+ " \"201\" : {\n" +
+ " \"description\" : \"api response description\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"parameters\" : {\n" +
+ " \"param\" : {\n" +
+ " \"in\" : \"query\",\n" +
+ " \"description\" : \"parameter description\",\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"examples\" : {\n" +
+ " \"example\" : {\n" +
+ " \"summary\" : \"example summary\",\n" +
+ " \"description\" : \"example description\",\n" +
+ " \"value\" : \"This is an example/\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"requestBodies\" : {\n" +
+ " \"body\" : {\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : { }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"headers\" : {\n" +
+ " \"test-head\" : {\n" +
+ " \"description\" : \"test header description\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"securitySchemes\" : {\n" +
+ " \"basic\" : {\n" +
+ " \"description\" : \"ref security description\",\n" +
+ " \"in\" : \"header\",\n" +
+ " \"scheme\" : \"http\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"links\" : {\n" +
+ " \"Link\" : {\n" +
+ " \"operationRef\" : \"#/paths/~12.0~1repositories~1{username}/get\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"callbacks\" : {\n" +
+ " \"TestCallback\" : {\n" +
+ " \"{$request.query.queryUrl}\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"pathItems\" : {\n" +
+ " \"/pathTest\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"get\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"response description\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+
+ openAPI.openapi("3.0.3");
+ SerializationMatchers.assertEqualsToYaml(openAPI, "openapi: 3.0.3\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " stringTest:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " \"201\":\n" +
+ " description: api response description\n" +
+ " parameters:\n" +
+ " param:\n" +
+ " in: query\n" +
+ " description: parameter description\n" +
+ " schema:\n" +
+ " type: string\n" +
+ " examples:\n" +
+ " example:\n" +
+ " summary: example summary\n" +
+ " description: example description\n" +
+ " value: This is an example/\n" +
+ " requestBodies:\n" +
+ " body:\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " type: object\n" +
+ " headers:\n" +
+ " test-head:\n" +
+ " description: test header description\n" +
+ " securitySchemes:\n" +
+ " basic:\n" +
+ " description: ref security description\n" +
+ " in: header\n" +
+ " scheme: http\n" +
+ " links:\n" +
+ " Link:\n" +
+ " operationRef: \"#/paths/~12.0~1repositories~1{username}/get\"\n" +
+ " callbacks:\n" +
+ " TestCallback:\n" +
+ " '{$request.query.queryUrl}':\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem");
+
+ SerializationMatchers.assertEqualsToJson(openAPI, "{\n" +
+ " \"openapi\" : \"3.0.3\",\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"stringTest\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"responses\" : {\n" +
+ " \"201\" : {\n" +
+ " \"description\" : \"api response description\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"parameters\" : {\n" +
+ " \"param\" : {\n" +
+ " \"in\" : \"query\",\n" +
+ " \"description\" : \"parameter description\",\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"examples\" : {\n" +
+ " \"example\" : {\n" +
+ " \"summary\" : \"example summary\",\n" +
+ " \"description\" : \"example description\",\n" +
+ " \"value\" : \"This is an example/\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"requestBodies\" : {\n" +
+ " \"body\" : {\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"type\" : \"object\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"headers\" : {\n" +
+ " \"test-head\" : {\n" +
+ " \"description\" : \"test header description\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"securitySchemes\" : {\n" +
+ " \"basic\" : {\n" +
+ " \"description\" : \"ref security description\",\n" +
+ " \"in\" : \"header\",\n" +
+ " \"scheme\" : \"http\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"links\" : {\n" +
+ " \"Link\" : {\n" +
+ " \"operationRef\" : \"#/paths/~12.0~1repositories~1{username}/get\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"callbacks\" : {\n" +
+ " \"TestCallback\" : {\n" +
+ " \"{$request.query.queryUrl}\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testDiscriminatorSerialization() {
+ Schema propertySchema1 = new StringSchema();
+ propertySchema1.addType(propertySchema1.getType());
+
+ Schema propertySchema2 = new StringSchema();
+ propertySchema2.addType(propertySchema2.getType());
+
+ Discriminator discriminator = new Discriminator().propertyName("type");
+ discriminator.addExtension("x-otherName", "discriminationType");
+
+ Schema schema = new ObjectSchema()
+ .addProperties("name", propertySchema1)
+ .addProperties("type", propertySchema1)
+ .discriminator(discriminator);
+
+ schema.addType(schema.getType());
+ OpenAPI openAPI = new OpenAPI().openapi("3.1.0").components(new Components()
+ .addSchemas("pet", schema));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " pet:\n" +
+ " properties:\n" +
+ " name:\n" +
+ " type: string\n" +
+ " type:\n" +
+ " type: string\n" +
+ " discriminator:\n" +
+ " propertyName: type\n" +
+ " x-otherName: discriminationType\n" +
+ " type: object");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"pet\" : {\n" +
+ " \"properties\" : {\n" +
+ " \"name\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " },\n" +
+ " \"type\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"discriminator\" : {\n" +
+ " \"propertyName\" : \"type\",\n" +
+ " \"x-otherName\" : \"discriminationType\"\n" +
+ " },\n" +
+ " \"type\" : \"object\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+
+ openAPI.openapi("3.0.3");
+
+ SerializationMatchers.assertEqualsToYaml(openAPI, "openapi: 3.0.3\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " pet:\n" +
+ " properties:\n" +
+ " name:\n" +
+ " type: string\n" +
+ " type:\n" +
+ " type: string\n" +
+ " discriminator:\n" +
+ " propertyName: type\n" +
+ " type: object");
+
+ SerializationMatchers.assertEqualsToJson(openAPI, "{\n" +
+ " \"openapi\" : \"3.0.3\",\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"pet\" : {\n" +
+ " \"properties\" : {\n" +
+ " \"name\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " },\n" +
+ " \"type\" : {\n" +
+ " \"type\" : \"string\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"discriminator\" : {\n" +
+ " \"propertyName\" : \"type\"\n" +
+ " },\n" +
+ " \"type\" : \"object\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testPathItemsRefSerialization() {
+ OpenAPI openAPI = new OpenAPI().openapi("3.1.0")
+ .path("/pathTest", new PathItem()
+ .$ref("#/components/pathItems/pathTest")
+ .description("This is a ref path item")
+ .summary("ref path item")
+ )
+ .components(new Components()
+ .addPathItem("pathTest", new PathItem()
+ .description("test path item")
+ .get(new Operation()
+ .operationId("testPathItem")
+ .responses(new ApiResponses()
+ .addApiResponse("200", new ApiResponse().description("response description"))))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /pathTest:\n" +
+ " $ref: '#/components/pathItems/pathTest'\n" +
+ " description: This is a ref path item\n" +
+ " summary: ref path item\n" +
+ "components:\n" +
+ " pathItems:\n" +
+ " pathTest:\n" +
+ " description: test path item\n" +
+ " get:\n" +
+ " operationId: testPathItem\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: response description");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/pathTest\" : {\n" +
+ " \"summary\" : \"ref path item\",\n" +
+ " \"description\" : \"This is a ref path item\",\n" +
+ " \"$ref\" : \"#/components/pathItems/pathTest\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"pathItems\" : {\n" +
+ " \"pathTest\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"get\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"response description\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testResponseRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .path("/test", new PathItem()
+ .description("test path item")
+ .get(new Operation()
+ .operationId("testPathItem")
+ .responses(new ApiResponses()
+ .addApiResponse("200" , new ApiResponse()
+ .description("point to a $ref response")
+ .$ref("#/components/responses/okResponse")))))
+ .components(new Components()
+ .addResponses("okResponse", new ApiResponse().description("everything is good")));
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " get:\n" +
+ " operationId: testPathItem\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: point to a $ref response\n" +
+ " $ref: '#/components/responses/okResponse'\n" +
+ "components:\n" +
+ " responses:\n" +
+ " okResponse:\n" +
+ " description: everything is good");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"get\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"responses\" : {\n" +
+ " \"200\" : {\n" +
+ " \"description\" : \"point to a $ref response\",\n" +
+ " \"$ref\" : \"#/components/responses/okResponse\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"responses\" : {\n" +
+ " \"okResponse\" : {\n" +
+ " \"description\" : \"everything is good\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testParameterRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .components(new Components()
+ .addParameters("testParameter", new Parameter()
+ .in("query")))
+ .path("/test", new PathItem()
+ .description("test path item")
+ .get(new Operation()
+ .operationId("testPathItem")
+ .addParametersItem(new Parameter()
+ .$ref("#/components/parameters/testParameter")
+ .description("test parameter"))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " get:\n" +
+ " operationId: testPathItem\n" +
+ " parameters:\n" +
+ " - description: test parameter\n" +
+ " $ref: '#/components/parameters/testParameter'\n" +
+ "components:\n" +
+ " parameters:\n" +
+ " testParameter:\n" +
+ " in: query");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"get\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"parameters\" : [ {\n" +
+ " \"description\" : \"test parameter\",\n" +
+ " \"$ref\" : \"#/components/parameters/testParameter\"\n" +
+ " } ]\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"parameters\" : {\n" +
+ " \"testParameter\" : {\n" +
+ " \"in\" : \"query\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testExampleRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .components(new Components()
+ .addExamples("testExample", new Example()
+ .value("Example on test")
+ .description("this is a example desc")
+ .summary("this is a summary test"))
+ .addSchemas("schema", new Schema().example(new Example()
+ .$ref("#/components/examples/testExample")
+ .description("ref description")
+ .summary("ref summary"))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " schema:\n" +
+ " example:\n" +
+ " summary: ref summary\n" +
+ " description: ref description\n" +
+ " $ref: '#/components/examples/testExample'\n" +
+ " examples:\n" +
+ " testExample:\n" +
+ " summary: this is a summary test\n" +
+ " description: this is a example desc\n" +
+ " value: Example on test");
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"components\" : {\n" +
+ " \"schemas\" : {\n" +
+ " \"schema\" : {\n" +
+ " \"example\" : {\n" +
+ " \"summary\" : \"ref summary\",\n" +
+ " \"description\" : \"ref description\",\n" +
+ " \"$ref\" : \"#/components/examples/testExample\"\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"examples\" : {\n" +
+ " \"testExample\" : {\n" +
+ " \"summary\" : \"this is a summary test\",\n" +
+ " \"description\" : \"this is a example desc\",\n" +
+ " \"value\" : \"Example on test\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+ @Test
+ public void testRequestBodyRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .path("/test", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")
+ .requestBody(new RequestBody()
+ .$ref("#/components/requestBodies/body")
+ .description("ref request body"))))
+ .components(new Components()
+ .addRequestBodies("body", new RequestBody()
+ .content(new Content()
+ .addMediaType("application/json", new MediaType()
+ .schema(new ObjectSchema())))))
+ ;
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem\n" +
+ " requestBody:\n" +
+ " description: ref request body\n" +
+ " $ref: '#/components/requestBodies/body'\n" +
+ "components:\n" +
+ " requestBodies:\n" +
+ " body:\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema: {}");
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"requestBody\" : {\n" +
+ " \"description\" : \"ref request body\",\n" +
+ " \"$ref\" : \"#/components/requestBodies/body\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"requestBodies\" : {\n" +
+ " \"body\" : {\n" +
+ " \"content\" : {\n" +
+ " \"application/json\" : {\n" +
+ " \"schema\" : { }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testHeaderRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .path("/test", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")
+ .responses(new ApiResponses()
+ .addApiResponse("default", new ApiResponse()
+ .description("default response")
+ .addHeaderObject("header", new Header()
+ .$ref("#/components/responses/okResponse")
+ .description("ref header description"))))
+ ))
+ .components(new Components()
+ .addHeaders("test-head", new Header()
+ .description("test header description")));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " headers:\n" +
+ " header:\n" +
+ " description: ref header description\n" +
+ " $ref: '#/components/responses/okResponse'\n" +
+ "components:\n" +
+ " headers:\n" +
+ " test-head:\n" +
+ " description: test header description");
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"responses\" : {\n" +
+ " \"default\" : {\n" +
+ " \"description\" : \"default response\",\n" +
+ " \"headers\" : {\n" +
+ " \"header\" : {\n" +
+ " \"description\" : \"ref header description\",\n" +
+ " \"$ref\" : \"#/components/responses/okResponse\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"headers\" : {\n" +
+ " \"test-head\" : {\n" +
+ " \"description\" : \"test header description\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testSecuritySchemeRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .components(new Components().addSecuritySchemes("basic", new SecurityScheme()
+ .$ref("https://external.site.com/#components/securitySchemes/basic")
+ .description("ref security description")));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "components:\n" +
+ " securitySchemes:\n" +
+ " basic:\n" +
+ " description: ref security description\n" +
+ " $ref: https://external.site.com/#components/securitySchemes/basic");
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"components\" : {\n" +
+ " \"securitySchemes\" : {\n" +
+ " \"basic\" : {\n" +
+ " \"description\" : \"ref security description\",\n" +
+ " \"$ref\" : \"https://external.site.com/#components/securitySchemes/basic\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testLinkRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .path("/test", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")
+ .responses(new ApiResponses()
+ .addApiResponse("default", new ApiResponse()
+ .description("default response")
+ .addLink("link", new Link()
+ .$ref("#/components/links/Link")
+ .description("ref link description"))))))
+ .components(new Components().addLinks("Link", new Link()
+ .operationRef("#/paths/~12.0~1repositories~1{username}/get")));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " links:\n" +
+ " link:\n" +
+ " description: ref link description\n" +
+ " $ref: '#/components/links/Link'\n" +
+ "components:\n" +
+ " links:\n" +
+ " Link:\n" +
+ " operationRef: \"#/paths/~12.0~1repositories~1{username}/get\"");
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"responses\" : {\n" +
+ " \"default\" : {\n" +
+ " \"description\" : \"default response\",\n" +
+ " \"links\" : {\n" +
+ " \"link\" : {\n" +
+ " \"description\" : \"ref link description\",\n" +
+ " \"$ref\" : \"#/components/links/Link\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"links\" : {\n" +
+ " \"Link\" : {\n" +
+ " \"operationRef\" : \"#/paths/~12.0~1repositories~1{username}/get\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testCallRefSerialization() {
+ OpenAPI openAPI = new OpenAPI()
+ .openapi("3.1.0")
+ .path("/test", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")
+ .addCallback("callbackSample", new Callback()
+ .$ref("#/components/callbacks/TestCallback"))))
+ .components(new Components().addCallbacks("TestCallback", new Callback().addPathItem("{$request.query.queryUrl}", new PathItem()
+ .description("test path item")
+ .post(new Operation()
+ .operationId("testPathItem")))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.1.0\n" +
+ "paths:\n" +
+ " /test:\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem\n" +
+ " callbacks:\n" +
+ " callbackSample:\n" +
+ " $ref: '#/components/callbacks/TestCallback'\n" +
+ "components:\n" +
+ " callbacks:\n" +
+ " TestCallback:\n" +
+ " '{$request.query.queryUrl}':\n" +
+ " description: test path item\n" +
+ " post:\n" +
+ " operationId: testPathItem");
+
+ SerializationMatchers.assertEqualsToJson31(openAPI, "{\n" +
+ " \"openapi\" : \"3.1.0\",\n" +
+ " \"paths\" : {\n" +
+ " \"/test\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\",\n" +
+ " \"callbacks\" : {\n" +
+ " \"callbackSample\" : {\n" +
+ " \"$ref\" : \"#/components/callbacks/TestCallback\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " },\n" +
+ " \"components\" : {\n" +
+ " \"callbacks\" : {\n" +
+ " \"TestCallback\" : {\n" +
+ " \"{$request.query.queryUrl}\" : {\n" +
+ " \"description\" : \"test path item\",\n" +
+ " \"post\" : {\n" +
+ " \"operationId\" : \"testPathItem\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+ }
+
+
+}
diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/SchemaSerializationTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/SchemaSerializationTest.java
new file mode 100644
index 0000000000..00f63796ec
--- /dev/null
+++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/serialization/SchemaSerializationTest.java
@@ -0,0 +1,55 @@
+package io.swagger.v3.core.serialization;
+
+import io.swagger.v3.core.matchers.SerializationMatchers;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.media.Schema;
+import org.testng.annotations.Test;
+
+public class SchemaSerializationTest {
+
+ @Test
+ public void serializeRefSchema3_1() {
+ OpenAPI openAPI = new OpenAPI()
+ .components(new Components()
+ .addSchemas("Pet", new Schema()
+ .addProperties("id", new Schema().type("integer"))
+ .addProperties("name", new Schema().type("string"))
+ .addProperties("tag", new Schema().type("string")))
+ .addSchemas("AnotherPet", new Schema()
+ .title("Another Pet")
+ .description("Another Pet for petstore referencing Pet schema")
+ .$ref("#/components/schemas/Pet")
+ .addProperties("category", new Schema().type("string"))
+ .addProperties("photoUrl", new Schema().type("string"))));
+
+ SerializationMatchers.assertEqualsToYaml31(openAPI, "openapi: 3.0.1\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " Pet:\n" +
+ " properties:\n" +
+ " id: {}\n" +
+ " name: {}\n" +
+ " tag: {}\n" +
+ " AnotherPet:\n" +
+ " title: Another Pet\n" +
+ " properties:\n" +
+ " category: {}\n" +
+ " photoUrl: {}\n" +
+ " description: Another Pet for petstore referencing Pet schema\n" +
+ " $ref: '#/components/schemas/Pet'");
+ SerializationMatchers.assertEqualsToYaml(openAPI, "openapi: 3.0.1\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " Pet:\n" +
+ " properties:\n" +
+ " id:\n" +
+ " type: integer\n" +
+ " name:\n" +
+ " type: string\n" +
+ " tag:\n" +
+ " type: string\n" +
+ " AnotherPet:\n" +
+ " $ref: '#/components/schemas/Pet'");
+ }
+}
diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/changelog-3.1.yaml b/modules/swagger-core/src/test/resources/specFiles/3.1.0/changelog-3.1.yaml
new file mode 100644
index 0000000000..b241894e96
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/changelog-3.1.yaml
@@ -0,0 +1,137 @@
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+webhooks:
+ # Each webhook needs a name
+ newPet:
+ # This is a Path Item Object, the only difference is that the request is initiated by the API provider
+ post:
+ requestBody:
+ description: Information about a new pet in the system
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ responses:
+ "200":
+ description: Return a 200 status to indicate that the data was received successfully
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ type:
+ - object
+ - string
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ testenum:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ default: available
+ testconst:
+ type: string
+ const: pending
+ tag:
+ type: string
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1.yaml b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1.yaml
new file mode 100644
index 0000000000..e09ccbf97a
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1.yaml
@@ -0,0 +1,126 @@
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+webhooks:
+ # Each webhook needs a name
+ newPet:
+ # This is a Path Item Object, the only difference is that the request is initiated by the API provider
+ post:
+ requestBody:
+ description: Information about a new pet in the system
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ responses:
+ "200":
+ description: Return a 200 status to indicate that the data was received successfully
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type:
+ - string
+ - integer
+ tag:
+ type: string
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_more.yaml b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_more.yaml
new file mode 100644
index 0000000000..73bbdd7e2a
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_more.yaml
@@ -0,0 +1,130 @@
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+webhooks:
+ # Each webhook needs a name
+ newPet:
+ # This is a Path Item Object, the only difference is that the request is initiated by the API provider
+ post:
+ requestBody:
+ description: Information about a new pet in the system
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ responses:
+ "200":
+ description: Return a 200 status to indicate that the data was received successfully
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type:
+ - string
+ - integer
+ tag:
+ type: string
+ Pets:
+ $id: test
+ $anchor: test
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ description: desc
+ format: int32
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_refs_siblings.yaml b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_refs_siblings.yaml
new file mode 100644
index 0000000000..7d860352e3
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_refs_siblings.yaml
@@ -0,0 +1,149 @@
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ summary: petstore sample for OAS 3.1.0
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+paths:
+ /ref_pet:
+ $ref: '#/components/pathItems/pet'
+ description: "ref pathItem description"
+ summary: "ref pathItem summary"
+ /pets:
+ post:
+ tags:
+ - pets
+ summary: Create a pet
+ operationId: createPets
+ parameters:
+ - $ref: '#/components/parameters/testParameter'
+ description: "ref parameter description"
+ summary: "ref parameter summary"
+ - name: randomParam
+ in: query
+ schema:
+ type: string
+ examples:
+ refExample:
+ $ref: '#/components/examples/testExample'
+ description: "ref example description"
+ summary: "ref example summary"
+ callbacks:
+ callIt:
+ $ref: '#/components/callbacks/TestCallback'
+ requestBody:
+ $ref: '#/components/requestBodies/body'
+ description: "ref request body description"
+ summary: "ref request body summary"
+ responses:
+ "201":
+ $ref: '#/components/responses/okResponse'
+ description: "ref response description"
+ summary: "ref response summary"
+ default:
+ description: 'default response'
+ headers:
+ head:
+ $ref: '#/components/headers/head'
+ description: "ref header description"
+ summary: "ref header summary"
+
+
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ tag:
+ type: string
+ discriminator:
+ propertyName: tag
+ x-test-extension: extended
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ description: desc
+ format: int32
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
+ AnotherPet:
+ title: Another Pet
+ description: Another Pet for petstore referencing Pet schema
+ $ref: "#/components/schemas/Pet"
+ properties:
+ category:
+ type: string
+ photoUrl:
+ type: string
+ pathItems:
+ pet:
+ description: get a pet
+ get:
+ operationId: getPet
+ responses:
+ "200":
+ description: pet returned
+ links:
+ address:
+ operationId: getUserAddressByUUID
+ parameters:
+ # get the `uuid` field from the `uuid` field in the response body
+ userUuid: $response.body#/uuid
+ callbacks:
+ TestCallback:
+ '{$request.query.queryUrl}':
+ description: test path item
+ post:
+ operationId: testPathItem
+ responses:
+ default:
+ description: ok
+ securitySchemes:
+ basic:
+ $ref: "#/components/securitySchemes/http"
+ http:
+ type: http
+ scheme: basic
+ headers:
+ head:
+ schema:
+ type: string
+ requestBodies:
+ body:
+ description: client model
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ responses:
+ okResponse:
+ description: everything is good"
+ examples:
+ testExample:
+ value: Example on test
+ parameters:
+ testParameter:
+ name: param
+ in: query
+ schema:
+ type: string
diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_sample.yaml b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_sample.yaml
new file mode 100644
index 0000000000..ed7368dd6e
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/petstore-3.1_sample.yaml
@@ -0,0 +1,181 @@
+
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ summary: petstore sample for OAS 3.1.0
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+webhooks:
+ # Each webhook needs a name
+ newPet:
+ # This is a Path Item Object, the only difference is that the request is initiated by the API provider
+ post:
+ requestBody:
+ description: Information about a new pet in the system
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ responses:
+ "200":
+ description: Return a 200 status to indicate that the data was received successfully
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ tag:
+ type: string
+ discriminator:
+ propertyName: tag
+ x-test-extension: extended
+ Pets:
+ $id: test
+ $anchor: test
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ description: desc
+ format: int32
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
+ responses:
+ "201":
+ description: api response description
+ summary: api response summary
+ parameters:
+ param:
+ in: query
+ name: param0
+ description: parameter description
+ summary: parameter summary
+ schema:
+ type: string
+ examples:
+ example:
+ summary: example summary
+ description: example description
+ value: This is an example
+ requestBodies:
+ body:
+ content:
+ application/json:
+ schema: { }
+ headers:
+ test-head:
+ description: test header description
+ summary: test header summary
+ securitySchemes:
+ basic:
+ description: security description
+ summary: security summary
+ type: http
+ links:
+ Link:
+ operationRef: "#/paths/~12.0~1repositories~1{username}/get"
+ callbacks:
+ TestCallback:
+ '{$request.query.queryUrl}':
+ description: test path item
+ post:
+ operationId: testPathItem
+ pathItems:
+ /pet:
+ description: get a pet
+ get:
+ operationId: getPet
+ responses:
+ "200":
+ description: pet returned
diff --git a/modules/swagger-core/src/test/resources/specFiles/oas3.yaml b/modules/swagger-core/src/test/resources/specFiles/oas3.yaml
index 06496ed488..5dad635db6 100644
--- a/modules/swagger-core/src/test/resources/specFiles/oas3.yaml
+++ b/modules/swagger-core/src/test/resources/specFiles/oas3.yaml
@@ -37,7 +37,6 @@ security:
- tokenAuth: []
info:
description: 'This is a sample server Petstore'
- version: 1.0.0
title: Sample Pet Store App
termsOfService: http://swagger.io/terms/
x-info: info extension
diff --git a/modules/swagger-core/src/test/resources/specFiles/oas3_2.yaml b/modules/swagger-core/src/test/resources/specFiles/oas3_2.yaml
index 14e8040dc5..26812c6681 100644
--- a/modules/swagger-core/src/test/resources/specFiles/oas3_2.yaml
+++ b/modules/swagger-core/src/test/resources/specFiles/oas3_2.yaml
@@ -1,4 +1,4 @@
-openapi: 3.0
+openapi: 3.0.0
servers:
- url: http://petstore.swagger.io/api
- url: https://development.gigantic-server.com/api
@@ -49,7 +49,6 @@ info:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
x-license: license extension
- version: 1.0.1
tags:
- name: pet
description: Everything about your Pets
@@ -1112,31 +1111,6 @@ components:
default: false
xml:
name: Order
- properties:
- id:
- type: integer
- format: int64
- petId:
- type: integer
- format: int64
- quantity:
- type: integer
- format: int32
- shipDate:
- type: string
- format: date-time
- status:
- type: string
- description: Order Status
- enum:
- - placed
- - approved
- - delivered
- complete:
- type: boolean
- default: false
- xml:
- name: Order
Category:
type: object
properties:
@@ -1386,4 +1360,4 @@ components:
converter:
url: https://github.com/mermade/oas3
version: 1.2.3
- x-api-title: pet store test api in components
\ No newline at end of file
+ x-api-title: pet store test api in components
diff --git a/modules/swagger-core/src/test/resources/testOAS31/basicOAS31.yaml b/modules/swagger-core/src/test/resources/testOAS31/basicOAS31.yaml
new file mode 100644
index 0000000000..7a7e631695
--- /dev/null
+++ b/modules/swagger-core/src/test/resources/testOAS31/basicOAS31.yaml
@@ -0,0 +1,164 @@
+openapi: "3.1.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+ identifier: test
+servers:
+ - url: http://petstore.swagger.io/v1
+webhooks:
+ # Each webhook needs a name
+ newPet:
+ # This is a Path Item Object, the only difference is that the request is initiated by the API provider
+ post:
+ requestBody:
+ description: Information about a new pet in the system
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ description: pet
+ responses:
+ "200":
+ description: Return a 200 status to indicate that the data was received successfully
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ description: error
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Tag"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ - $ref: "#/components/parameters/User"
+ description: user
+ summary: user
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ parameters:
+ User:
+ in: query
+ description: user
+ name: user
+ schema:
+ type: string
+ schemas:
+ Pet:
+ type:
+ - object
+ - string
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ testenum:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ default: available
+ testconst:
+ type: string
+ const: pending
+ tag:
+ type: string
+ arbitraryKeyword: test
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
+ tag:
+ $ref: "#/components/schemas/Tag"
+ Tag:
+ type:
+ - object
+ - string
+ - string
+ - foo
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
diff --git a/modules/swagger-eclipse-transformer-maven-plugin/pom.xml b/modules/swagger-eclipse-transformer-maven-plugin/pom.xml
index b4097e22ca..a544b2e64d 100644
--- a/modules/swagger-eclipse-transformer-maven-plugin/pom.xml
+++ b/modules/swagger-eclipse-transformer-maven-plugin/pom.xml
@@ -4,7 +4,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
4.0.0
@@ -13,7 +13,7 @@
swagger-eclipse-transformer-maven-plugin
maven-plugin
- 3.6.3
+ 3.8.4
0.20
3.3.0
1.2.6
@@ -39,7 +39,7 @@
org.apache.maven.plugins
maven-plugin-plugin
- 3.6.0
+ 3.6.4
transform
@@ -94,7 +94,7 @@
org.apache.maven.plugin-tools
maven-plugin-annotations
- 3.6.0
+ 3.6.4
provided
diff --git a/modules/swagger-gradle-plugin/gradle.properties b/modules/swagger-gradle-plugin/gradle.properties
index d31f621c50..479185eef5 100644
--- a/modules/swagger-gradle-plugin/gradle.properties
+++ b/modules/swagger-gradle-plugin/gradle.properties
@@ -1,2 +1,2 @@
-version=2.1.14-SNAPSHOT
+version=2.2.0-SNAPSHOT
jettyVersion=9.4.43.v20210629
diff --git a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java
index bc4d96f75b..6c6adc7707 100644
--- a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java
+++ b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java
@@ -16,7 +16,7 @@ public void apply(Project project) {
config.defaultDependencies(new Action() {
public void execute(DependencySet dependencies) {
dependencies.add(project.getDependencies().create("org.apache.commons:commons-lang3:3.7"));
- dependencies.add(project.getDependencies().create("io.swagger.core.v3:swagger-jaxrs2:2.1.14-SNAPSHOT"));
+ dependencies.add(project.getDependencies().create("io.swagger.core.v3:swagger-jaxrs2:2.2.0-SNAPSHOT"));
dependencies.add(project.getDependencies().create("javax.ws.rs:javax.ws.rs-api:2.1"));
dependencies.add(project.getDependencies().create("javax.servlet:javax.servlet-api:3.1.0"));
}
diff --git a/modules/swagger-gradle-plugin/src/test/java/io/swagger/v3/plugins/gradle/SwaggerResolveTest.java b/modules/swagger-gradle-plugin/src/test/java/io/swagger/v3/plugins/gradle/SwaggerResolveTest.java
index 387b887aaf..8f7638253b 100644
--- a/modules/swagger-gradle-plugin/src/test/java/io/swagger/v3/plugins/gradle/SwaggerResolveTest.java
+++ b/modules/swagger-gradle-plugin/src/test/java/io/swagger/v3/plugins/gradle/SwaggerResolveTest.java
@@ -81,7 +81,7 @@ public void testSwaggerResolveTask() throws IOException {
" mavenCentral()\n" +
"}\n" +
"dependencies { \n" +
- " compile group: 'io.swagger.core.v3', name: 'swagger-jaxrs2', version:'2.1.14-SNAPSHOT'\n" +
+ " compile group: 'io.swagger.core.v3', name: 'swagger-jaxrs2', version:'2.2.0-SNAPSHOT'\n" +
" compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version:'2.1'\n" +
" compile group: 'javax.servlet', name: 'javax.servlet-api', version:'3.1.0'\n" +
" testCompile group: 'com.github.tomakehurst', name: 'wiremock', version:'2.27.2'\n" +
diff --git a/modules/swagger-integration/pom.xml b/modules/swagger-integration/pom.xml
index 39796cb272..d9c49a2622 100644
--- a/modules/swagger-integration/pom.xml
+++ b/modules/swagger-integration/pom.xml
@@ -6,7 +6,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
swagger-integration
diff --git a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/GenericOpenApiContext.java b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/GenericOpenApiContext.java
index 1147189d62..a62b20c3e7 100644
--- a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/GenericOpenApiContext.java
+++ b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/GenericOpenApiContext.java
@@ -4,7 +4,9 @@
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -14,7 +16,9 @@
import io.swagger.v3.core.jackson.ModelResolver;
import io.swagger.v3.core.jackson.PathsSerializer;
import io.swagger.v3.core.util.Json;
+import io.swagger.v3.core.util.Json31;
import io.swagger.v3.core.util.Yaml;
+import io.swagger.v3.core.util.Yaml31;
import io.swagger.v3.oas.integration.api.ObjectMapperProcessor;
import io.swagger.v3.oas.integration.api.OpenAPIConfiguration;
import io.swagger.v3.oas.integration.api.OpenApiConfigurationLoader;
@@ -30,6 +34,7 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -65,6 +70,8 @@ public class GenericOpenApiContext implements O
// -1 perpetual
private long cacheTTL = -1;
+ private Boolean openAPI31;
+
public long getCacheTTL() {
return cacheTTL;
}
@@ -272,6 +279,28 @@ public final T outputYamlMapper(ObjectMapper outputYamlMapper) {
return (T) this;
}
+ /**
+ * @since 2.1.8
+ */
+ public Boolean isOpenAPI31() {
+ return openAPI31;
+ }
+
+ /**
+ * @since 2.1.8
+ */
+ public void setOpenAPI31(Boolean v) {
+ this.openAPI31 = openAPI31;
+ }
+
+ /**
+ * @since 2.1.8
+ */
+ public T openAPI31(Boolean openAPI31) {
+ this.openAPI31 = openAPI31;
+ return (T) this;
+ }
+
protected void register() {
OpenApiContextLocator.getInstance().putOpenApiContext(id, this);
@@ -408,6 +437,7 @@ public T init() throws OpenApiConfigurationException {
if (openApiConfiguration == null) {
openApiConfiguration = new SwaggerConfiguration().resourcePackages(resourcePackages).resourceClasses(resourceClasses);
((SwaggerConfiguration) openApiConfiguration).setId(id);
+ ((SwaggerConfiguration) openApiConfiguration).setOpenAPI31(openAPI31);
}
openApiConfiguration = mergeParentConfiguration(openApiConfiguration, parent);
@@ -426,20 +456,35 @@ public T init() throws OpenApiConfigurationException {
modelConverters = buildModelConverters(ContextUtils.deepCopy(openApiConfiguration));
}
if (outputJsonMapper == null) {
- outputJsonMapper = Json.mapper().copy();
+ if (Boolean.TRUE.equals(openApiConfiguration.isOpenAPI31())) {
+ outputJsonMapper = Json31.mapper().copy();
+ } else {
+ outputJsonMapper = Json.mapper().copy();
+ }
}
if (outputYamlMapper == null) {
- outputYamlMapper = Yaml.mapper().copy();
+ if (Boolean.TRUE.equals(openApiConfiguration.isOpenAPI31())) {
+ outputYamlMapper = Yaml31.mapper().copy();
+ } else {
+ outputYamlMapper = Yaml.mapper().copy();
+ }
}
if (openApiConfiguration.isSortOutput() != null && openApiConfiguration.isSortOutput()) {
outputJsonMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
outputJsonMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
outputYamlMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
outputYamlMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
- outputJsonMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin.class);
- outputJsonMapper.addMixIn(Schema.class, SortedSchemaMixin.class);
- outputYamlMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin.class);
- outputYamlMapper.addMixIn(Schema.class, SortedSchemaMixin.class);
+ if (Boolean.TRUE.equals(openApiConfiguration.isOpenAPI31())) {
+ outputJsonMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin31.class);
+ outputJsonMapper.addMixIn(Schema.class, SortedSchemaMixin31.class);
+ outputYamlMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin31.class);
+ outputYamlMapper.addMixIn(Schema.class, SortedSchemaMixin31.class);
+ } else {
+ outputJsonMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin.class);
+ outputJsonMapper.addMixIn(Schema.class, SortedSchemaMixin.class);
+ outputYamlMapper.addMixIn(OpenAPI.class, SortedOpenAPIMixin.class);
+ outputYamlMapper.addMixIn(Schema.class, SortedSchemaMixin.class);
+ }
}
} catch (Exception e) {
LOGGER.error("error initializing context: " + e.getMessage(), e);
@@ -539,6 +584,9 @@ private OpenAPIConfiguration mergeParentConfiguration(OpenAPIConfiguration confi
if (merged.getModelConverterClasses() == null) {
merged.setModelConverterClassess(parentConfig.getModelConverterClasses());
}
+ if (merged.isOpenAPI31() == null) {
+ merged.setOpenAPI31(parentConfig.isOpenAPI31());
+ }
return merged;
}
@@ -611,6 +659,93 @@ static abstract class SortedSchemaMixin {
@JsonInclude(JsonInclude.Include.CUSTOM)
public abstract Object getExample();
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract Map getPatternProperties();
+
+ @JsonIgnore
+ public abstract Schema getContains();
+ @JsonIgnore
+ public abstract String get$id();
+ @JsonIgnore
+ public abstract String get$anchor();
+ @JsonIgnore
+ public abstract String get$schema();
+ @JsonIgnore
+ public abstract Set getTypes();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+
+ }
+
+ @JsonPropertyOrder(value = {"openapi", "info", "externalDocs", "servers", "security", "tags", "paths", "components", "webhooks"}, alphabetic = true)
+ static abstract class SortedOpenAPIMixin31 {
+
+ @JsonAnyGetter
+ @JsonPropertyOrder(alphabetic = true)
+ public abstract Map getExtensions();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonSerialize(using = PathsSerializer.class)
+ public abstract Paths getPaths();
+ }
+
+ @JsonPropertyOrder(value = {"type", "format"}, alphabetic = true)
+ static abstract class SortedSchemaMixin31 {
+
+ @JsonAnyGetter
+ @JsonPropertyOrder(alphabetic = true)
+ public abstract Map getExtensions();
+
+ //@JsonValue
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonIgnore
+ public abstract Boolean getNullable();
+
+ @JsonIgnore
+ public abstract Boolean getExclusiveMinimum();
+
+ @JsonIgnore
+ public abstract Boolean getExclusiveMaximum();
+
+ @JsonProperty("exclusiveMinimum")
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonProperty("exclusiveMaximum")
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract String getType();
+
+ @JsonProperty("type")
+ public abstract Set getTypes();
+
+ @JsonAnySetter
+ public abstract void addExtension(String name, Object value);
+
+ @JsonIgnore
+ public abstract boolean getExampleSetFlag();
+
+ @JsonInclude(JsonInclude.Include.CUSTOM)
+ public abstract Object getExample();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
}
}
diff --git a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/IntegrationObjectMapperFactory.java b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/IntegrationObjectMapperFactory.java
index c3ea9d516f..b4a481b911 100644
--- a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/IntegrationObjectMapperFactory.java
+++ b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/IntegrationObjectMapperFactory.java
@@ -8,4 +8,8 @@ public class IntegrationObjectMapperFactory extends ObjectMapperFactory {
public static ObjectMapper createJson() {
return ObjectMapperFactory.createJson();
}
+
+ public static ObjectMapper createJson31() {
+ return ObjectMapperFactory.createJson31();
+ }
}
diff --git a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/SwaggerConfiguration.java b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/SwaggerConfiguration.java
index 7091574270..ce48045b82 100644
--- a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/SwaggerConfiguration.java
+++ b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/SwaggerConfiguration.java
@@ -34,6 +34,8 @@ public class SwaggerConfiguration implements OpenAPIConfiguration {
private Boolean alwaysResolveAppPath;
+ private Boolean openAPI31;
+
public Long getCacheTTL() {
return cacheTTL;
}
@@ -281,4 +283,26 @@ public SwaggerConfiguration alwaysResolveAppPath(Boolean alwaysResolveAppPath) {
setAlwaysResolveAppPath(alwaysResolveAppPath);
return this;
}
+
+ /**
+ * @since 2.1.9
+ */
+ public Boolean isOpenAPI31() {
+ return openAPI31;
+ }
+
+ /**
+ * @since 2.1.9
+ */
+ public void setOpenAPI31(Boolean v) {
+ this.openAPI31 = openAPI31;
+ }
+
+ /**
+ * @since 2.1.9
+ */
+ public SwaggerConfiguration openAPI31(Boolean openAPI31) {
+ this.openAPI31 = openAPI31;
+ return this;
+ }
}
diff --git a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/api/OpenAPIConfiguration.java b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/api/OpenAPIConfiguration.java
index 8b88cb0541..780923280f 100644
--- a/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/api/OpenAPIConfiguration.java
+++ b/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/api/OpenAPIConfiguration.java
@@ -49,4 +49,8 @@ public interface OpenAPIConfiguration {
*/
Boolean isAlwaysResolveAppPath();
+ /**
+ * @since 3.0.0
+ */
+ Boolean isOpenAPI31();
}
diff --git a/modules/swagger-jaxrs2-servlet-initializer-v2/pom.xml b/modules/swagger-jaxrs2-servlet-initializer-v2/pom.xml
index 365b1dbfbd..c7b862df26 100644
--- a/modules/swagger-jaxrs2-servlet-initializer-v2/pom.xml
+++ b/modules/swagger-jaxrs2-servlet-initializer-v2/pom.xml
@@ -5,7 +5,7 @@
swagger-project
io.swagger.core.v3
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../../
4.0.0
diff --git a/modules/swagger-jaxrs2-servlet-initializer/pom.xml b/modules/swagger-jaxrs2-servlet-initializer/pom.xml
index b400fd90fd..dd8acf4698 100644
--- a/modules/swagger-jaxrs2-servlet-initializer/pom.xml
+++ b/modules/swagger-jaxrs2-servlet-initializer/pom.xml
@@ -5,7 +5,7 @@
swagger-project
io.swagger.core.v3
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../../
4.0.0
diff --git a/modules/swagger-jaxrs2/pom.xml b/modules/swagger-jaxrs2/pom.xml
index 1baaf29c4f..11f8a11dd5 100644
--- a/modules/swagger-jaxrs2/pom.xml
+++ b/modules/swagger-jaxrs2/pom.xml
@@ -5,7 +5,7 @@
swagger-project
io.swagger.core.v3
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../../
4.0.0
diff --git a/modules/swagger-jaxrs2/src/main/java/io/swagger/v3/jaxrs2/Reader.java b/modules/swagger-jaxrs2/src/main/java/io/swagger/v3/jaxrs2/Reader.java
index e48ff1cb12..95098f0427 100644
--- a/modules/swagger-jaxrs2/src/main/java/io/swagger/v3/jaxrs2/Reader.java
+++ b/modules/swagger-jaxrs2/src/main/java/io/swagger/v3/jaxrs2/Reader.java
@@ -1076,10 +1076,11 @@ protected Operation parseMethod(
}
final Class> subResource = getSubResourceWithJaxRsSubresourceLocatorSpecs(method);
+ Schema returnTypeSchema = null;
if (!shouldIgnoreClass(returnType.getTypeName()) && !method.getGenericReturnType().equals(subResource)) {
ResolvedSchema resolvedSchema = ModelConverters.getInstance().resolveAsResolvedSchema(new AnnotatedType(returnType).resolveAsRef(true).jsonViewAnnotation(jsonViewAnnotation));
if (resolvedSchema.schema != null) {
- Schema returnTypeSchema = resolvedSchema.schema;
+ returnTypeSchema = resolvedSchema.schema;
Content content = new Content();
MediaType mediaType = new MediaType().schema(returnTypeSchema);
AnnotationsUtils.applyTypes(classProduces == null ? new String[0] : classProduces.value(),
@@ -1112,18 +1113,62 @@ protected Operation parseMethod(
}
}
if (operation.getResponses() == null || operation.getResponses().isEmpty()) {
- Content content = new Content();
- MediaType mediaType = new MediaType();
- AnnotationsUtils.applyTypes(classProduces == null ? new String[0] : classProduces.value(),
- methodProduces == null ? new String[0] : methodProduces.value(), content, mediaType);
+ Content content = resolveEmptyContent(classProduces, methodProduces);
ApiResponse apiResponseObject = new ApiResponse().description(DEFAULT_DESCRIPTION).content(content);
operation.setResponses(new ApiResponses()._default(apiResponseObject));
}
+ if (returnTypeSchema != null) {
+ resolveResponseSchemaFromReturnType(operation, classResponses, returnTypeSchema, classProduces, methodProduces);
+ if (apiResponses != null) {
+ resolveResponseSchemaFromReturnType(
+ operation,
+ apiResponses.stream().toArray(io.swagger.v3.oas.annotations.responses.ApiResponse[]::new),
+ returnTypeSchema,
+ classProduces,
+ methodProduces);
+ }
+ }
+
return operation;
}
+ protected Content resolveEmptyContent(Produces classProduces, Produces methodProduces) {
+ Content content = new Content();
+ MediaType mediaType = new MediaType();
+ AnnotationsUtils.applyTypes(classProduces == null ? new String[0] : classProduces.value(),
+ methodProduces == null ? new String[0] : methodProduces.value(), content, mediaType);
+ return content;
+ }
+
+ protected void resolveResponseSchemaFromReturnType(
+ Operation operation,
+ io.swagger.v3.oas.annotations.responses.ApiResponse[] responses,
+ Schema schema,
+ Produces classProduces, Produces methodProduces) {
+ if (responses != null) {
+ for (io.swagger.v3.oas.annotations.responses.ApiResponse response: responses) {
+ if (response.useReturnTypeSchema()) {
+ ApiResponse opResponse = operation.getResponses().get(response.responseCode());
+ if (opResponse != null) {
+ if (opResponse.getContent() != null) {
+ for (MediaType mediaType : opResponse.getContent().values()) {
+ mediaType.schema(schema);
+ }
+ } else {
+ Content content = resolveEmptyContent(classProduces, methodProduces);
+ for (MediaType mediaType : content.values()) {
+ mediaType.schema(schema);
+ }
+ opResponse.content(content);
+ }
+ }
+ }
+ }
+ }
+ }
+
private boolean shouldIgnoreClass(String className) {
if (StringUtils.isBlank(className)) {
return true;
diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java
index 65b33fa195..742141b118 100644
--- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java
+++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/ReaderTest.java
@@ -13,6 +13,8 @@
import io.swagger.v3.core.model.ApiDescription;
import io.swagger.v3.core.util.PrimitiveType;
import io.swagger.v3.jaxrs2.matchers.SerializationMatchers;
+import io.swagger.v3.jaxrs2.resources.ResponseReturnTypeResource;
+import io.swagger.v3.jaxrs2.resources.SchemaPropertiesResource;
import io.swagger.v3.jaxrs2.resources.SingleExampleResource;
import io.swagger.v3.jaxrs2.resources.BasicFieldsResource;
import io.swagger.v3.jaxrs2.resources.BookStoreTicket2646;
@@ -2811,4 +2813,221 @@ public void testTicket3731() {
openAPI = reader.read(Ticket3731BisResource.class);
SerializationMatchers.assertEqualsToYaml(openAPI, yaml);
}
+
+ @Test(description = "Test SchemaProperties and additionalProperties annotations")
+ public void testSchemaProperties() {
+ Reader reader = new Reader(new OpenAPI());
+
+ OpenAPI openAPI = reader.read(SchemaPropertiesResource.class);
+ String yaml = "openapi: 3.0.1\n" +
+ "paths:\n" +
+ " /:\n" +
+ " get:\n" +
+ " summary: Simple get operation\n" +
+ " description: Defines a simple get operation with no inputs and a complex output\n" +
+ " object\n" +
+ " operationId: getWithPayloadResponse\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: voila!\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " maximum: 1\n" +
+ " type: integer\n" +
+ " default:\n" +
+ " description: boo\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " maxProperties: 3\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " maximum: 1\n" +
+ " type: integer\n" +
+ " description: various properties\n" +
+ " \"400\":\n" +
+ " description: additionalProperties schema\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " maxProperties: 2\n" +
+ " type: object\n" +
+ " additionalProperties:\n" +
+ " type: string\n" +
+ " \"401\":\n" +
+ " description: additionalProperties boolean\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " maxProperties: 2\n" +
+ " type: object\n" +
+ " additionalProperties: false\n" +
+ " deprecated: true\n" +
+ " /one:\n" +
+ " get:\n" +
+ " operationId: requestBodySchemaPropertyNoSchema\n" +
+ " requestBody:\n" +
+ " content:\n" +
+ " application/yaml:\n" +
+ " schema:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/MultipleBaseBean'\n" +
+ " /two:\n" +
+ " get:\n" +
+ " operationId: requestBodySchemaPropertySchema\n" +
+ " requestBody:\n" +
+ " content:\n" +
+ " application/yaml:\n" +
+ " schema:\n" +
+ " required:\n" +
+ " - foo\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/MultipleBaseBean'\n" +
+ " /three:\n" +
+ " get:\n" +
+ " operationId: requestBodySchemaPropertySchemaArray\n" +
+ " requestBody:\n" +
+ " content:\n" +
+ " application/yaml:\n" +
+ " schema:\n" +
+ " type: array\n" +
+ " items:\n" +
+ " required:\n" +
+ " - foo\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " type: string\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/MultipleBaseBean'\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " MultipleBaseBean:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " beanType:\n" +
+ " type: string\n" +
+ " a:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " b:\n" +
+ " type: string\n" +
+ " description: MultipleBaseBean\n" +
+ " MultipleSub1Bean:\n" +
+ " type: object\n" +
+ " description: MultipleSub1Bean\n" +
+ " allOf:\n" +
+ " - $ref: '#/components/schemas/MultipleBaseBean'\n" +
+ " - type: object\n" +
+ " properties:\n" +
+ " c:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " MultipleSub2Bean:\n" +
+ " type: object\n" +
+ " description: MultipleSub2Bean\n" +
+ " allOf:\n" +
+ " - $ref: '#/components/schemas/MultipleBaseBean'\n" +
+ " - type: object\n" +
+ " properties:\n" +
+ " d:\n" +
+ " type: integer\n" +
+ " format: int32\n";
+ SerializationMatchers.assertEqualsToYaml(openAPI, yaml);
+ }
+
+ @Test(description = "Responses schema resolved from return type")
+ public void testResponseReturnType() {
+ Reader reader = new Reader(new OpenAPI());
+
+ OpenAPI openAPI = reader.read(ResponseReturnTypeResource.class);
+ String yaml = "openapi: 3.0.1\n" +
+ "paths:\n" +
+ " /sample/{id}:\n" +
+ " get:\n" +
+ " summary: Find by id\n" +
+ " description: Find by id operation\n" +
+ " operationId: find\n" +
+ " parameters:\n" +
+ " - name: id\n" +
+ " in: path\n" +
+ " description: ID\n" +
+ " required: true\n" +
+ " schema:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " responses:\n" +
+ " \"200\":\n" +
+ " description: Ok\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/TestDTO'\n" +
+ " \"201\":\n" +
+ " description: \"201\"\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/TestDTO'\n" +
+ " \"204\":\n" +
+ " description: No Content\n" +
+ " content:\n" +
+ " application/json: {}\n" +
+ " /sample/{id}/default:\n" +
+ " get:\n" +
+ " summary: Find by id (default)\n" +
+ " description: Find by id operation (default)\n" +
+ " operationId: findDefault\n" +
+ " parameters:\n" +
+ " - name: id\n" +
+ " in: path\n" +
+ " description: ID\n" +
+ " required: true\n" +
+ " schema:\n" +
+ " type: integer\n" +
+ " format: int32\n" +
+ " responses:\n" +
+ " default:\n" +
+ " description: default response\n" +
+ " content:\n" +
+ " application/json:\n" +
+ " schema:\n" +
+ " $ref: '#/components/schemas/TestDTO'\n" +
+ "components:\n" +
+ " schemas:\n" +
+ " TestDTO:\n" +
+ " type: object\n" +
+ " properties:\n" +
+ " foo:\n" +
+ " type: string";
+ SerializationMatchers.assertEqualsToYaml(openAPI, yaml);
+ }
}
diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/integration/SortedOutputTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/integration/SortedOutputTest.java
index 2bf08c51dd..7c8074e5f7 100644
--- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/integration/SortedOutputTest.java
+++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/integration/SortedOutputTest.java
@@ -27,6 +27,7 @@
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
@@ -118,6 +119,33 @@ public static abstract class SortedSchemaMixin {
@JsonInclude(JsonInclude.Include.CUSTOM)
public abstract Object getExample();
+ @JsonIgnore
+ public abstract Map getJsonSchema();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMinimumValue();
+
+ @JsonIgnore
+ public abstract BigDecimal getExclusiveMaximumValue();
+
+ @JsonIgnore
+ public abstract Map getPatternProperties();
+
+ @JsonIgnore
+ public abstract Schema getContains();
+ @JsonIgnore
+ public abstract String get$id();
+ @JsonIgnore
+ public abstract String get$anchor();
+ @JsonIgnore
+ public abstract String get$schema();
+ @JsonIgnore
+ public abstract Set getTypes();
+
+ @JsonIgnore
+ public abstract Object getJsonSchemaImpl();
+
+
}
public static class SortedProcessor implements ObjectMapperProcessor {
diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/ResponseReturnTypeResource.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/ResponseReturnTypeResource.java
new file mode 100644
index 0000000000..1bb16211fc
--- /dev/null
+++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/ResponseReturnTypeResource.java
@@ -0,0 +1,42 @@
+package io.swagger.v3.jaxrs2.resources;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Path("/sample")
+public interface ResponseReturnTypeResource {
+
+ @GET
+ @Path("/{id}")
+ @Operation(summary = "Find by id", description = "Find by id operation")
+ @ApiResponse(responseCode = "200", description = "Ok", useReturnTypeSchema = true)
+ @ApiResponse(responseCode = "201",
+ description = "201",
+ useReturnTypeSchema = true,
+ content = @Content(mediaType = "application/json"))
+ @ApiResponse(responseCode = "204",
+ description = "No Content",
+ content = @Content(mediaType = "application/json", schema = @Schema(implementation = Void.class)))
+ TestDTO find(@Parameter(description = "ID") @PathParam("id") Integer id);
+
+ @GET
+ @Path("/{id}/default")
+ @Operation(summary = "Find by id (default)", description = "Find by id operation (default)")
+ TestDTO findDefault(@Parameter(description = "ID") @PathParam("id") Integer id);
+
+ class TestDTO {
+ public String foo;
+ }
+}
diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/SchemaPropertiesResource.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/SchemaPropertiesResource.java
new file mode 100644
index 0000000000..761e35fd1c
--- /dev/null
+++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/resources/SchemaPropertiesResource.java
@@ -0,0 +1,167 @@
+package io.swagger.v3.jaxrs2.resources;
+
+import io.swagger.v3.jaxrs2.resources.model.MultipleBaseBean;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+public class SchemaPropertiesResource {
+
+ @GET
+ @Path("/")
+ @Operation(
+ summary = "Simple get operation",
+ description = "Defines a simple get operation with no inputs and a complex output object",
+ operationId = "getWithPayloadResponse",
+ deprecated = true,
+ responses = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "voila!",
+ content = @Content(
+ mediaType = "application/json",
+ schemaProperties = {
+ @SchemaProperty(
+ name = "foo",
+ schema = @Schema(
+ type = "integer",
+ maximum = "1"
+ )
+ )
+ }
+ )
+ ),
+ @ApiResponse(
+ description = "boo",
+ content = @Content(
+ schema = @Schema(
+ type = "object",
+ description = "various properties",
+ maxProperties = 3
+ ),
+ mediaType = "application/json",
+ schemaProperties = {
+ @SchemaProperty(
+ name = "foo",
+ schema = @Schema(
+ type = "integer",
+ maximum = "1"
+ )
+ )
+ }
+ )
+ ),
+ @ApiResponse(
+ responseCode = "400",
+ description = "additionalProperties schema",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(
+ type = "object",
+ maxProperties = 2
+ ),
+ additionalPropertiesSchema = @Schema(
+ type = "string"
+ )
+ )
+ ),
+ @ApiResponse(
+ responseCode = "401",
+ description = "additionalProperties boolean",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(
+ type = "object",
+ maxProperties = 2,
+ additionalProperties = Schema.AdditionalPropertiesValue.FALSE
+ )
+ )
+ )
+ }
+ )
+ public void getResponses() {
+ }
+
+ @GET
+ @Path("/one")
+ @Produces({MediaType.APPLICATION_JSON})
+ public MultipleBaseBean requestBodySchemaPropertyNoSchema(
+ @RequestBody(
+ content = @Content(
+ mediaType = "application/yaml",
+ schemaProperties = {
+ @SchemaProperty(
+ name = "foo",
+ schema = @Schema(
+ type = "string"
+ )
+ )
+ }
+ )
+ ) Object body) {
+ return null;
+ }
+
+ @GET
+ @Path("/two")
+ @Produces({MediaType.APPLICATION_JSON})
+ public MultipleBaseBean requestBodySchemaPropertySchema(
+ @RequestBody(
+ content = @Content(
+ mediaType = "application/yaml",
+ schema = @Schema(
+ type = "object",
+ requiredProperties = {
+ "foo"
+ }
+ ),
+ schemaProperties= {
+ @SchemaProperty(
+ name = "foo",
+ schema = @Schema(
+ type = "string"
+ )
+ )
+ }
+ )
+ ) Object body) {
+ return null;
+ }
+
+ @GET
+ @Path("/three")
+ @Produces({MediaType.APPLICATION_JSON})
+ public MultipleBaseBean requestBodySchemaPropertySchemaArray(
+ @RequestBody(
+ content = @Content(
+ mediaType = "application/yaml",
+ array = @ArraySchema(
+ schema = @Schema(
+ type = "object",
+ requiredProperties = {
+ "foo"
+ }
+ )
+ ),
+ schemaProperties = {
+ @SchemaProperty(
+ name = "foo",
+ schema = @Schema(
+ type = "string"
+ )
+ )
+ }
+ )
+ ) Object body) {
+ return null;
+ }
+}
diff --git a/modules/swagger-maven-plugin/pom.xml b/modules/swagger-maven-plugin/pom.xml
index 50d097d346..eb9de0d632 100644
--- a/modules/swagger-maven-plugin/pom.xml
+++ b/modules/swagger-maven-plugin/pom.xml
@@ -4,7 +4,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
4.0.0
@@ -29,7 +29,7 @@
org.apache.maven.plugins
maven-plugin-plugin
- 3.6.0
+ 3.6.4
io.swagger.core.v3
@@ -88,7 +88,7 @@
org.apache.maven.plugin-tools
maven-plugin-annotations
- 3.6.0
+ 3.6.4
provided
@@ -290,7 +290,7 @@
UTF-8
- 3.6.3
+ 3.8.4
4.13.1
9.4.43.v20210629
1.21
diff --git a/modules/swagger-models/pom.xml b/modules/swagger-models/pom.xml
index 3fcf82074d..531d371a7a 100644
--- a/modules/swagger-models/pom.xml
+++ b/modules/swagger-models/pom.xml
@@ -4,7 +4,7 @@
io.swagger.core.v3
swagger-project
- 2.1.14-SNAPSHOT
+ 2.2.0-SNAPSHOT
../..
4.0.0
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI30.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI30.java
new file mode 100644
index 0000000000..e1c7d63e98
--- /dev/null
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI30.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2017 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations;
+
+import java.lang.annotation.Inherited;
+
+@Inherited
+public @interface OpenAPI30 {
+}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI31.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI31.java
new file mode 100644
index 0000000000..35cec47814
--- /dev/null
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/annotations/OpenAPI31.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2017 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.annotations;
+
+import java.lang.annotation.Inherited;
+
+@Inherited
+public @interface OpenAPI31 {
+}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Components.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Components.java
index 97355fe914..662d6e54cd 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Components.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Components.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.callbacks.Callback;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.headers.Header;
@@ -53,6 +54,12 @@ public class Components {
private Map callbacks = null;
private java.util.Map extensions = null;
+ /**
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ private Map pathItems;
+
/**
* returns the schemas property from a Components instance.
*
@@ -296,6 +303,37 @@ public Components addCallbacks(String key, Callback callbacksItem) {
return this;
}
+ /**
+ * returns the path items property from a Components instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return Map<String, PathItem> pathItems
+ **/
+ @OpenAPI31
+ public Map getPathItems() {
+ return pathItems;
+ }
+
+ @OpenAPI31
+ public void setPathItems(Map pathItems) {
+ this.pathItems = pathItems;
+ }
+
+ @OpenAPI31
+ public Components pathItems(Map pathItems) {
+ this.pathItems = pathItems;
+ return this;
+ }
+
+ @OpenAPI31
+ public Components addPathItem(String key, PathItem pathItem) {
+ if (this.pathItems == null) {
+ this.pathItems = new LinkedHashMap<>();
+ }
+ this.pathItems.put(key, pathItem);
+ return this;
+ }
+
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
@@ -314,12 +352,13 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.securitySchemes, components.securitySchemes) &&
Objects.equals(this.links, components.links) &&
Objects.equals(this.callbacks, components.callbacks) &&
- Objects.equals(this.extensions, components.extensions);
+ Objects.equals(this.extensions, components.extensions) &&
+ Objects.equals(this.pathItems, components.pathItems);
}
@Override
public int hashCode() {
- return Objects.hash(schemas, responses, parameters, examples, requestBodies, headers, securitySchemes, links, callbacks, extensions);
+ return Objects.hash(schemas, responses, parameters, examples, requestBodies, headers, securitySchemes, links, callbacks, extensions, pathItems);
}
public java.util.Map getExtensions() {
@@ -336,6 +375,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
@@ -359,6 +406,7 @@ public String toString() {
sb.append(" securitySchemes: ").append(toIndentedString(securitySchemes)).append("\n");
sb.append(" links: ").append(toIndentedString(links)).append("\n");
sb.append(" callbacks: ").append(toIndentedString(callbacks)).append("\n");
+ sb.append(" pathItems: ").append(toIndentedString(pathItems)).append("\n");
sb.append("}");
return sb.toString();
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/ExternalDocumentation.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/ExternalDocumentation.java
index 24a0fbfecf..e1fe227a12 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/ExternalDocumentation.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/ExternalDocumentation.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -100,6 +102,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/OpenAPI.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/OpenAPI.java
index 21054ba4d9..76e21d5b59 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/OpenAPI.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/OpenAPI.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityRequirement;
@@ -24,7 +26,9 @@
import io.swagger.v3.oas.models.tags.Tag;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -44,6 +48,33 @@ public class OpenAPI {
private Components components = null;
private java.util.Map extensions = null;
+ @OpenAPI31
+ private String jsonSchemaDialect;
+
+ public OpenAPI() {}
+ public OpenAPI(SpecVersion specVersion) { this.specVersion = specVersion;}
+ private SpecVersion specVersion = SpecVersion.V30;
+
+ @JsonIgnore
+ public SpecVersion getSpecVersion() {
+ return this.specVersion;
+ }
+
+ public void setSpecVersion(SpecVersion specVersion) {
+ this.specVersion = specVersion;
+ }
+
+ public OpenAPI specVersion(SpecVersion specVersion) {
+ this.setSpecVersion(specVersion);
+ return this;
+ }
+
+ /**
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ private java.util.Map webhooks = null;
+
/**
* returns the openapi property from a OpenAPI instance.
*
@@ -249,6 +280,55 @@ public OpenAPI schemaRequirement(String name, SecurityScheme securityScheme) {
return this;
}
+ /**
+ * returns the webhooks property from a OpenAPI instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return Map<String, PathItem> webhooks
+ **/
+
+ @OpenAPI31
+ public Map getWebhooks() {
+ return webhooks;
+ }
+
+ @OpenAPI31
+ public void setWebhooks(Map webhooks) {
+ this.webhooks = webhooks;
+ }
+
+ @OpenAPI31
+ public OpenAPI webhooks(Map webhooks) {
+ this.webhooks = webhooks;
+ return this;
+ }
+
+ @OpenAPI31
+ public OpenAPI addWebhooks(String key, PathItem pathItem) {
+ if (this.webhooks == null) {
+ this.webhooks = new LinkedHashMap<>();
+ }
+ this.webhooks.put(key, pathItem);
+ return this;
+ }
+
+ @OpenAPI31
+ public String getJsonSchemaDialect() {
+ return jsonSchemaDialect;
+ }
+
+ @OpenAPI31
+ public void setJsonSchemaDialect(String jsonSchemaDialect) {
+ this.jsonSchemaDialect = jsonSchemaDialect;
+ }
+
+ @OpenAPI31
+ public OpenAPI jsonSchemaDialect(String jsonSchemaDialect) {
+ this.jsonSchemaDialect = jsonSchemaDialect;
+ return this;
+ }
+
+
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
@@ -266,12 +346,14 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.tags, openAPI.tags) &&
Objects.equals(this.paths, openAPI.paths) &&
Objects.equals(this.components, openAPI.components) &&
- Objects.equals(this.extensions, openAPI.extensions);
+ Objects.equals(this.webhooks, openAPI.webhooks) &&
+ Objects.equals(this.extensions, openAPI.extensions) &&
+ Objects.equals(this.jsonSchemaDialect, openAPI.jsonSchemaDialect);
}
@Override
public int hashCode() {
- return Objects.hash(openapi, info, externalDocs, servers, security, tags, paths, components, extensions);
+ return Objects.hash(openapi, info, externalDocs, servers, security, tags, paths, components, webhooks, extensions, jsonSchemaDialect);
}
public java.util.Map getExtensions() {
@@ -288,6 +370,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
@@ -310,6 +400,8 @@ public String toString() {
sb.append(" tags: ").append(toIndentedString(tags)).append("\n");
sb.append(" paths: ").append(toIndentedString(paths)).append("\n");
sb.append(" components: ").append(toIndentedString(components)).append("\n");
+ if (specVersion == SpecVersion.V31) sb.append(" webhooks: ").append(toIndentedString(webhooks)).append("\n");
+ if (specVersion == SpecVersion.V31) sb.append(" jsonSchemaDialect: ").append(toIndentedString(jsonSchemaDialect)).append("\n");
sb.append("}");
return sb.toString();
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Operation.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Operation.java
index fbcce358c0..e7e641e1a0 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Operation.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Operation.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.callbacks.Callback;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
@@ -24,6 +25,7 @@
import io.swagger.v3.oas.models.servers.Server;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -236,6 +238,14 @@ public Operation callbacks(Map callbacks) {
return this;
}
+ public Operation addCallback(String key, Callback callback) {
+ if (this.callbacks == null) {
+ this.callbacks = new LinkedHashMap<>();
+ }
+ this.callbacks.put(key, callback);
+ return this;
+ }
+
/**
* returns the deprecated property from a Operation instance.
*
@@ -352,6 +362,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/PathItem.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/PathItem.java
index 799d2dfc3d..b44d1c1b40 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/PathItem.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/PathItem.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.servers.Server;
@@ -406,6 +407,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Paths.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Paths.java
index df58dc90a3..af9e45a209 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Paths.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/Paths.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.LinkedHashMap;
import java.util.Objects;
@@ -68,6 +70,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/SpecVersion.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/SpecVersion.java
new file mode 100644
index 0000000000..cea82fd5ce
--- /dev/null
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/SpecVersion.java
@@ -0,0 +1,6 @@
+package io.swagger.v3.oas.models;
+
+public enum SpecVersion {
+ V30,
+ V31
+}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/callbacks/Callback.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/callbacks/Callback.java
index 53e6e0e076..cda3eb83e6 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/callbacks/Callback.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/callbacks/Callback.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.callbacks;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.PathItem;
import java.util.LinkedHashMap;
@@ -100,6 +101,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
@@ -113,6 +122,7 @@ public Callback extensions(java.util.Map extensions) {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Callback {\n");
+ sb.append(" $ref: ").append(toIndentedString($ref)).append("\n");
sb.append(" ").append(toIndentedString(super.toString())).append("\n");
sb.append("}");
return sb.toString();
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/examples/Example.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/examples/Example.java
index d6c5765cb4..211ddbabf9 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/examples/Example.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/examples/Example.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.examples;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
/**
* Example
*/
@@ -137,6 +139,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Contact.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Contact.java
index bc20f57d66..172988ade2 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Contact.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Contact.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.info;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -121,6 +123,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Info.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Info.java
index 9c6f5e3021..31193b8590 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Info.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/Info.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.info;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -31,6 +33,12 @@ public class Info {
private String version = null;
private java.util.Map extensions = null;
+ /**
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ private String summary = null;
+
/**
* returns the title property from a Info instance.
*
@@ -145,6 +153,28 @@ public Info version(String version) {
return this;
}
+ /**
+ * returns the summary property from a Info instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return String
+ **/
+ @OpenAPI31
+ public String getSummary() {
+ return summary;
+ }
+
+ @OpenAPI31
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ @OpenAPI31
+ public Info summary(String summary) {
+ this.summary = summary;
+ return this;
+ }
+
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
@@ -160,12 +190,13 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.contact, info.contact) &&
Objects.equals(this.license, info.license) &&
Objects.equals(this.version, info.version) &&
- Objects.equals(this.extensions, info.extensions);
+ Objects.equals(this.extensions, info.extensions) &&
+ Objects.equals(this.summary, info.summary);
}
@Override
public int hashCode() {
- return Objects.hash(title, description, termsOfService, contact, license, version, extensions);
+ return Objects.hash(title, description, termsOfService, contact, license, version, extensions, summary);
}
public java.util.Map getExtensions() {
@@ -182,6 +213,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
@@ -198,6 +237,7 @@ public String toString() {
sb.append(" title: ").append(toIndentedString(title)).append("\n");
sb.append(" description: ").append(toIndentedString(description)).append("\n");
+ sb.append(" summary: ").append(toIndentedString(summary)).append("\n");
sb.append(" termsOfService: ").append(toIndentedString(termsOfService)).append("\n");
sb.append(" contact: ").append(toIndentedString(contact)).append("\n");
sb.append(" license: ").append(toIndentedString(license)).append("\n");
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/License.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/License.java
index 0bc59fc0f2..f403e54e50 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/License.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/info/License.java
@@ -16,17 +16,26 @@
package io.swagger.v3.oas.models.info;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
* License
*
* @see "https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#licenseObject"
+ * @see "https://github.com/OAI/OpenAPI-Specification/blob/3.1.0/versions/3.1.0.md#licenseObject"
*/
public class License {
private String name = null;
private String url = null;
+
+ /**
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ private String identifier = null;
private java.util.Map extensions = null;
/**
@@ -67,8 +76,28 @@ public License url(String url) {
return this;
}
+ /**
+ * returns the identifier property from a License instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return String identifier
+ **/
+ @OpenAPI31
+ public String getIdentifier() {
+ return identifier;
+ }
+ @OpenAPI31
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+ @OpenAPI31
+ public License identifier(String identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
@Override
- public boolean equals(java.lang.Object o) {
+ public boolean equals(Object o) {
if (this == o) {
return true;
}
@@ -78,12 +107,13 @@ public boolean equals(java.lang.Object o) {
License license = (License) o;
return Objects.equals(this.name, license.name) &&
Objects.equals(this.url, license.url) &&
+ Objects.equals(this.identifier, license.identifier) &&
Objects.equals(this.extensions, license.extensions);
}
@Override
public int hashCode() {
- return Objects.hash(name, url, extensions);
+ return Objects.hash(name, url, identifier, extensions);
}
public java.util.Map getExtensions() {
@@ -100,6 +130,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
@@ -116,6 +154,7 @@ public String toString() {
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" url: ").append(toIndentedString(url)).append("\n");
+ sb.append(" identifier: ").append(toIndentedString(identifier)).append("\n");
sb.append("}");
return sb.toString();
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/Link.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/Link.java
index 15287b7d3f..aa2f75430c 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/Link.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/Link.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.links;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.servers.Server;
@@ -123,12 +124,16 @@ public void setParameters(Map parameters) {
this.parameters = parameters;
}
+ @Deprecated
public Link parameters(String name, String parameter) {
+ return this.addParameter(name, parameter);
+ }
+
+ public Link addParameter(String name, String parameter) {
if (this.parameters == null) {
this.parameters = new LinkedHashMap<>();
}
this.parameters.put(name, parameter);
-
return this;
}
@@ -261,6 +266,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/LinkParameter.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/LinkParameter.java
index 1689386a29..0b61f15a80 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/LinkParameter.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/links/LinkParameter.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.links;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -77,6 +79,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ArraySchema.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ArraySchema.java
index 5dacdb04a7..9ef004bee7 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ArraySchema.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ArraySchema.java
@@ -16,14 +16,11 @@
package io.swagger.v3.oas.models.media;
-import java.util.Objects;
-
/**
* ArraySchema
*/
public class ArraySchema extends Schema {
- private Schema> items = null;
public ArraySchema() {
super("array", null);
@@ -35,41 +32,10 @@ public ArraySchema type(String type) {
return this;
}
- /**
- * returns the items property from a ArraySchema instance.
- *
- * @return Schema items
- **/
-
- public Schema> getItems() {
- return items;
- }
-
- public void setItems(Schema> items) {
- this.items = items;
- }
-
- public ArraySchema items(Schema> items) {
- this.items = items;
- return this;
- }
-
- @Override
- public boolean equals(java.lang.Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- ArraySchema arraySchema = (ArraySchema) o;
- return Objects.equals(this.items, arraySchema.items) &&
- super.equals(o);
- }
-
@Override
- public int hashCode() {
- return Objects.hash(items, super.hashCode());
+ public ArraySchema items(Schema items) {
+ super.setItems(items);
+ return this;
}
@Override
@@ -77,7 +43,6 @@ public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ArraySchema {\n");
sb.append(" ").append(toIndentedString(super.toString())).append("\n");
- sb.append(" items: ").append(toIndentedString(items)).append("\n");
sb.append("}");
return sb.toString();
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/BooleanSchema.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/BooleanSchema.java
index 6aa319a557..9d226b6cee 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/BooleanSchema.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/BooleanSchema.java
@@ -19,6 +19,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* BooleanSchema
@@ -36,6 +37,13 @@ public BooleanSchema type(String type) {
return this;
}
+ @Override
+ public BooleanSchema types(Set types) {
+ super.setTypes(types);
+ return this;
+ }
+
+
public BooleanSchema _default(Boolean _default) {
super.setDefault(_default);
return this;
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ComposedSchema.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ComposedSchema.java
index 530a7700d3..164a90866a 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ComposedSchema.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/ComposedSchema.java
@@ -16,128 +16,18 @@
package io.swagger.v3.oas.models.media;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
/**
* ComposedSchema
*/
public class ComposedSchema extends Schema {
- private List allOf = null;
- private List anyOf = null;
- private List oneOf = null;
-
- /**
- * returns the allOf property from a ComposedSchema instance.
- *
- * @return List<Schema> allOf
- **/
-
- public List getAllOf() {
- return allOf;
- }
-
- public void setAllOf(List allOf) {
- this.allOf = allOf;
- }
-
- public ComposedSchema allOf(List allOf) {
- this.allOf = allOf;
- return this;
- }
-
- public ComposedSchema addAllOfItem(Schema allOfItem) {
- if (this.allOf == null) {
- this.allOf = new ArrayList<>();
- }
- this.allOf.add(allOfItem);
- return this;
- }
-
- /**
- * returns the anyOf property from a ComposedSchema instance.
- *
- * @return List<Schema> anyOf
- **/
-
- public List getAnyOf() {
- return anyOf;
- }
-
- public void setAnyOf(List anyOf) {
- this.anyOf = anyOf;
- }
-
- public ComposedSchema anyOf(List anyOf) {
- this.anyOf = anyOf;
- return this;
- }
- public ComposedSchema addAnyOfItem(Schema anyOfItem) {
- if (this.anyOf == null) {
- this.anyOf = new ArrayList<>();
- }
- this.anyOf.add(anyOfItem);
- return this;
- }
-
- /**
- * returns the oneOf property from a ComposedSchema instance.
- *
- * @return List<Schema> oneOf
- **/
-
- public List getOneOf() {
- return oneOf;
- }
-
- public void setOneOf(List oneOf) {
- this.oneOf = oneOf;
- }
-
- public ComposedSchema oneOf(List oneOf) {
- this.oneOf = oneOf;
- return this;
- }
-
- public ComposedSchema addOneOfItem(Schema oneOfItem) {
- if (this.oneOf == null) {
- this.oneOf = new ArrayList<>();
- }
- this.oneOf.add(oneOfItem);
- return this;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- ComposedSchema allOfSchema = (ComposedSchema) o;
- return Objects.equals(this.allOf, allOfSchema.allOf) &&
- Objects.equals(this.anyOf, allOfSchema.anyOf) &&
- Objects.equals(this.oneOf, allOfSchema.oneOf) &&
- super.equals(o);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(allOf, anyOf, oneOf, super.hashCode());
- }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ComposedSchema {\n");
sb.append(" ").append(toIndentedString(super.toString())).append("\n");
- sb.append(" allOf: ").append(toIndentedString(allOf)).append("\n");
- sb.append(" anyOf: ").append(toIndentedString(anyOf)).append("\n");
- sb.append(" oneOf: ").append(toIndentedString(oneOf)).append("\n");
sb.append("}");
return sb.toString();
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Discriminator.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Discriminator.java
index cda3f65f2c..b3b09ef4c2 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Discriminator.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Discriminator.java
@@ -1,12 +1,21 @@
package io.swagger.v3.oas.models.media;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Objects;
public class Discriminator {
private String propertyName;
private Map mapping;
+ /**
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ private Map extensions;
+
public Discriminator propertyName(String propertyName) {
this.propertyName = propertyName;
return this;
@@ -41,6 +50,36 @@ public void setMapping(Map mapping) {
this.mapping = mapping;
}
+ /**
+ * returns the specific extensions from a Discriminator instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return Map<String, Object> extensions
+ **/
+ @OpenAPI31
+ public Map getExtensions() {
+ return extensions;
+ }
+
+ @OpenAPI31
+ public void setExtensions(Map extensions) {
+ this.extensions = extensions;
+ }
+
+ @OpenAPI31
+ public void addExtension(String name, Object value) {
+ if (name == null || name.isEmpty() || !name.startsWith("x-")) {
+ return;
+ }
+ if (name.startsWith("x-oas-") || name.startsWith("x-oai-")) {
+ return;
+ }
+ if (this.extensions == null) {
+ this.extensions = new java.util.LinkedHashMap<>();
+ }
+ this.extensions.put(name, value);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -55,15 +94,16 @@ public boolean equals(Object o) {
if (propertyName != null ? !propertyName.equals(that.propertyName) : that.propertyName != null) {
return false;
}
+ if (extensions != null ? !extensions.equals(that.extensions) : that.extensions != null) {
+ return false;
+ }
return mapping != null ? mapping.equals(that.mapping) : that.mapping == null;
}
@Override
public int hashCode() {
- int result = propertyName != null ? propertyName.hashCode() : 0;
- result = 31 * result + (mapping != null ? mapping.hashCode() : 0);
- return result;
+ return Objects.hash(propertyName, mapping, extensions);
}
@Override
@@ -71,6 +111,7 @@ public String toString() {
return "Discriminator{" +
"propertyName='" + propertyName + '\'' +
", mapping=" + mapping +
+ ", extensions=" + extensions +
'}';
}
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Encoding.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Encoding.java
index 110b169f1c..5ca9e45d47 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Encoding.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Encoding.java
@@ -16,8 +16,10 @@
package io.swagger.v3.oas.models.media;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.headers.Header;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
@@ -91,6 +93,14 @@ public void setHeaders(Map headers) {
this.headers = headers;
}
+ public Encoding addHeader(String name, Header header) {
+ if (this.headers == null) {
+ this.headers = new LinkedHashMap<>();
+ }
+ this.headers.put(name, header);
+ return this;
+ }
+
public Encoding style(StyleEnum style) {
this.style = style;
return this;
@@ -144,6 +154,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/EncodingProperty.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/EncodingProperty.java
index ba7fd89c89..ad45604a64 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/EncodingProperty.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/EncodingProperty.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.media;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.headers.Header;
import java.util.LinkedHashMap;
@@ -200,6 +201,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/JsonSchema.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/JsonSchema.java
new file mode 100644
index 0000000000..065a3becdb
--- /dev/null
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/JsonSchema.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2017 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.swagger.v3.oas.models.media;
+
+import io.swagger.v3.oas.models.SpecVersion;
+
+/**
+ * JsonSchema
+ */
+
+public class JsonSchema extends Schema {
+
+ public JsonSchema (){
+ specVersion(SpecVersion.V31);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class JsonSchema {\n");
+ sb.append(" ").append(toIndentedString(super.toString())).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/MediaType.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/MediaType.java
index 3d7b8aa1b1..0b3800e45d 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/MediaType.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/MediaType.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.media;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.examples.Example;
import java.util.LinkedHashMap;
@@ -180,6 +181,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Schema.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Schema.java
index e3d9097578..626a2dfd98 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Schema.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Schema.java
@@ -17,32 +17,41 @@
package io.swagger.v3.oas.models.media;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.OpenAPI30;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
+import io.swagger.v3.oas.models.SpecVersion;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
/**
* Schema
*
* @see "https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#schemaObject"
+ * @see "https://github.com/OAI/OpenAPI-Specification/blob/3.1.0/versions/3.1.0.md#schemaObject"
*/
public class Schema {
+
protected T _default;
private String name;
private String title = null;
private BigDecimal multipleOf = null;
private BigDecimal maximum = null;
+ @OpenAPI30
private Boolean exclusiveMaximum = null;
private BigDecimal minimum = null;
+ @OpenAPI30
private Boolean exclusiveMinimum = null;
private Integer maxLength = null;
private Integer minLength = null;
@@ -60,6 +69,7 @@ public class Schema {
private String description = null;
private String format = null;
private String $ref = null;
+ @OpenAPI30
private Boolean nullable = null;
private Boolean readOnly = null;
private Boolean writeOnly = null;
@@ -72,6 +82,394 @@ public class Schema {
private Discriminator discriminator = null;
private boolean exampleSetFlag;
+ @OpenAPI31
+ private List prefixItems = null;
+ private List allOf = null;
+ private List anyOf = null;
+ private List oneOf = null;
+
+ private Schema> items = null;
+
+ protected T _const;
+
+ private SpecVersion specVersion = SpecVersion.V30;
+
+ @JsonIgnore
+ public SpecVersion getSpecVersion() {
+ return this.specVersion;
+ }
+
+ public void setSpecVersion(SpecVersion specVersion) {
+ this.specVersion = specVersion;
+ }
+
+ public Schema specVersion(SpecVersion specVersion) {
+ this.setSpecVersion(specVersion);
+ return this;
+ }
+
+
+ /*
+ @OpenAPI31 fields and accessors
+ */
+
+
+ @OpenAPI31
+ private Set types;
+
+ @OpenAPI31
+ private Map patternProperties = null;
+ @OpenAPI31
+ private BigDecimal exclusiveMaximumValue = null;
+ @OpenAPI31
+ private BigDecimal exclusiveMinimumValue = null;
+
+
+ @OpenAPI31
+ private Schema contains = null;
+ @OpenAPI31
+ private String $id;
+ @OpenAPI31
+ private String $schema;
+ @OpenAPI31
+ private String $anchor;
+
+ @OpenAPI31
+ private String contentEncoding;
+ @OpenAPI31
+ private String contentMediaType;
+ @OpenAPI31
+ private Schema contentSchema;
+ @OpenAPI31
+ private Schema propertyNames;
+ @OpenAPI31
+ private Object unevaluatedProperties;
+ @OpenAPI31
+ private Integer maxContains;
+ @OpenAPI31
+ private Integer minContains;
+ @OpenAPI31
+ private Schema additionalItems;
+ @OpenAPI31
+ private Schema unevaluatedItems;
+ @OpenAPI31
+ private Schema _if;
+ @OpenAPI31
+ private Schema _else;
+ @OpenAPI31
+ private Schema then;
+ @OpenAPI31
+ private Map dependentSchemas;
+ @OpenAPI31
+ private Map> dependentRequired;
+ @OpenAPI31
+ private String $comment;
+ @OpenAPI31
+ private List examples;
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getContains() {
+ return contains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setContains(Schema contains) {
+ this.contains = contains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String get$id() {
+ return $id;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void set$id(String $id) {
+ this.$id = $id;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String get$schema() {
+ return $schema;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void set$schema(String $schema) {
+ this.$schema = $schema;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String get$anchor() {
+ return $anchor;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void set$anchor(String $anchor) {
+ this.$anchor = $anchor;
+ }
+
+ /**
+ * returns the exclusiveMaximumValue property from a Schema instance for OpenAPI 3.1.x
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return BigDecimal exclusiveMaximumValue
+ *
+ **/
+ @OpenAPI31
+ public BigDecimal getExclusiveMaximumValue() {
+ return exclusiveMaximumValue;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setExclusiveMaximumValue(BigDecimal exclusiveMaximumValue) {
+ this.exclusiveMaximumValue = exclusiveMaximumValue;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema exclusiveMaximumValue(BigDecimal exclusiveMaximumValue) {
+ this.exclusiveMaximumValue = exclusiveMaximumValue;
+ return this;
+ }
+
+ /**
+ * returns the exclusiveMinimumValue property from a Schema instance for OpenAPI 3.1.x
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return BigDecimal exclusiveMinimumValue
+ *
+ **/
+ @OpenAPI31
+ public BigDecimal getExclusiveMinimumValue() {
+ return exclusiveMinimumValue;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setExclusiveMinimumValue(BigDecimal exclusiveMinimumValue) {
+ this.exclusiveMinimumValue = exclusiveMinimumValue;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema exclusiveMinimumValue(BigDecimal exclusiveMinimumValue) {
+ this.exclusiveMinimumValue = exclusiveMinimumValue;
+ return this;
+ }
+
+ /**
+ * returns the patternProperties property from a Schema instance.
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ * @return Map<String, Schema> patternProperties
+ **/
+ @OpenAPI31
+ public Map getPatternProperties() {
+ return patternProperties;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setPatternProperties(Map patternProperties) {
+ this.patternProperties = patternProperties;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema patternProperties(Map patternProperties) {
+ this.patternProperties = patternProperties;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema addPatternProperty(String key, Schema patternPropertiesItem) {
+ if (this.patternProperties == null) {
+ this.patternProperties = new LinkedHashMap<>();
+ }
+ this.patternProperties.put(key, patternPropertiesItem);
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema contains(Schema contains) {
+ this.contains = contains;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema $id(String $id) {
+ this.$id = $id;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Set getTypes() {
+ return types;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setTypes(Set types) {
+ this.types = types;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public boolean addType(String type) {
+ if (types == null) {
+ types = new LinkedHashSet<>();
+ }
+ return types.add(type);
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema $schema(String $schema) {
+ this.$schema = $schema;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema $anchor(String $anchor) {
+ this.$anchor = $anchor;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema types(Set types) {
+ this.types = types;
+ return this;
+ }
+
+ /*
+ INTERNAL MEMBERS @OpenAPI31
+ */
+
+ @OpenAPI31
+ protected Map jsonSchema = null;
+
+ @OpenAPI31
+ public Map getJsonSchema() {
+ return jsonSchema;
+ }
+
+ @OpenAPI31
+ public void setJsonSchema(Map jsonSchema) {
+ this.jsonSchema = jsonSchema;
+ }
+
+ @OpenAPI31
+ public Schema jsonSchema(Map jsonSchema) {
+ this.jsonSchema = jsonSchema;
+ return this;
+ }
+
+ @OpenAPI31
+ protected transient Object jsonSchemaImpl = null;
+
+ @OpenAPI31
+ public Object getJsonSchemaImpl() {
+ return jsonSchemaImpl;
+ }
+
+ @OpenAPI31
+ public void setJsonSchemaImpl(Object jsonSchemaImpl) {
+ this.jsonSchemaImpl = jsonSchemaImpl;
+ }
+
+ @OpenAPI31
+ public Schema jsonSchemaImpl(Object jsonSchemaImpl) {
+ setJsonSchemaImpl(jsonSchemaImpl);
+ return this;
+ }
+
+ /*
+ CONSTRUCTORS
+ */
+
public Schema() {
}
@@ -81,6 +479,122 @@ protected Schema(String type, String format) {
this.format = format;
}
+ public Schema(SpecVersion specVersion) {
+ this.specVersion = specVersion;
+ }
+
+ protected Schema(String type, String format, SpecVersion specVersion) {
+ this.type = type;
+ this.format = format;
+ this.specVersion = specVersion;
+ }
+
+ /*
+ ACCESSORS
+ */
+
+ /**
+ * returns the allOf property from a ComposedSchema instance.
+ *
+ * @return List<Schema> allOf
+ **/
+
+ public List getAllOf() {
+ return allOf;
+ }
+
+ public void setAllOf(List allOf) {
+ this.allOf = allOf;
+ }
+
+ public Schema allOf(List allOf) {
+ this.allOf = allOf;
+ return this;
+ }
+
+ public Schema addAllOfItem(Schema allOfItem) {
+ if (this.allOf == null) {
+ this.allOf = new ArrayList<>();
+ }
+ this.allOf.add(allOfItem);
+ return this;
+ }
+
+ /**
+ * returns the anyOf property from a ComposedSchema instance.
+ *
+ * @return List<Schema> anyOf
+ **/
+
+ public List getAnyOf() {
+ return anyOf;
+ }
+
+ public void setAnyOf(List anyOf) {
+ this.anyOf = anyOf;
+ }
+
+ public Schema anyOf(List anyOf) {
+ this.anyOf = anyOf;
+ return this;
+ }
+
+ public Schema addAnyOfItem(Schema anyOfItem) {
+ if (this.anyOf == null) {
+ this.anyOf = new ArrayList<>();
+ }
+ this.anyOf.add(anyOfItem);
+ return this;
+ }
+
+ /**
+ * returns the oneOf property from a ComposedSchema instance.
+ *
+ * @return List<Schema> oneOf
+ **/
+
+ public List getOneOf() {
+ return oneOf;
+ }
+
+ public void setOneOf(List oneOf) {
+ this.oneOf = oneOf;
+ }
+
+ public Schema oneOf(List oneOf) {
+ this.oneOf = oneOf;
+ return this;
+ }
+
+ public Schema addOneOfItem(Schema oneOfItem) {
+ if (this.oneOf == null) {
+ this.oneOf = new ArrayList<>();
+ }
+ this.oneOf.add(oneOfItem);
+ return this;
+ }
+
+
+ /**
+ * returns the items property from a ArraySchema instance.
+ *
+ * @return Schema items
+ **/
+
+ public Schema> getItems() {
+ return items;
+ }
+
+ public void setItems(Schema> items) {
+ this.items = items;
+ }
+
+ public Schema items(Schema> items) {
+ this.items = items;
+ return this;
+ }
+
+
/**
* returns the name property from a from a Schema instance. Ignored in serialization.
*
@@ -139,7 +653,7 @@ public Schema title(String title) {
}
/**
- * returns the _default property from a StringSchema instance.
+ * returns the _default property from a Schema instance.
*
* @return String _default
**/
@@ -213,19 +727,21 @@ public Schema maximum(BigDecimal maximum) {
}
/**
- * returns the exclusiveMaximum property from a Schema instance.
+ * returns the exclusiveMaximum property from a Schema instance for OpenAPI 3.0.x
*
* @return Boolean exclusiveMaximum
**/
-
+ @OpenAPI30
public Boolean getExclusiveMaximum() {
return exclusiveMaximum;
}
+ @OpenAPI30
public void setExclusiveMaximum(Boolean exclusiveMaximum) {
this.exclusiveMaximum = exclusiveMaximum;
}
+ @OpenAPI30
public Schema exclusiveMaximum(Boolean exclusiveMaximum) {
this.exclusiveMaximum = exclusiveMaximum;
return this;
@@ -250,8 +766,9 @@ public Schema minimum(BigDecimal minimum) {
return this;
}
+
/**
- * returns the exclusiveMinimum property from a Schema instance.
+ * returns the exclusiveMinimum property from a Schema instance for OpenAPI 3.0.x
*
* @return Boolean exclusiveMinimum
**/
@@ -269,6 +786,7 @@ public Schema exclusiveMinimum(Boolean exclusiveMinimum) {
return this;
}
+
/**
* returns the maxLength property from a Schema instance.
*
@@ -530,11 +1048,20 @@ public Schema properties(Map properties) {
return this;
}
- public Schema addProperties(String key, Schema propertiesItem) {
+ @Deprecated
+ public Schema addProperties(String key, Schema property) {
+ return addProperty(key, property);
+ }
+
+ /**
+ *
+ * @since 2.2.0
+ */
+ public Schema addProperty(String key, Schema property) {
if (this.properties == null) {
this.properties = new LinkedHashMap<>();
}
- this.properties.put(key, propertiesItem);
+ this.properties.put(key, property);
return this;
}
@@ -625,15 +1152,17 @@ public Schema format(String format) {
*
* @return Boolean nullable
**/
-
+ @OpenAPI30
public Boolean getNullable() {
return nullable;
}
+ @OpenAPI30
public void setNullable(Boolean nullable) {
this.nullable = nullable;
}
+ @OpenAPI30
public Schema nullable(Boolean nullable) {
this.nullable = nullable;
return this;
@@ -771,9 +1300,497 @@ public void setExampleSetFlag(boolean exampleSetFlag) {
this.exampleSetFlag = exampleSetFlag;
}
- @Override
- public boolean equals(java.lang.Object o) {
- if (this == o) {
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public List getPrefixItems() {
+ return prefixItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setPrefixItems(List prefixItems) {
+ this.prefixItems = prefixItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema prefixItems(List prefixItems) {
+ this.prefixItems = prefixItems;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String getContentEncoding() {
+ return contentEncoding;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setContentEncoding(String contentEncoding) {
+ this.contentEncoding = contentEncoding;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema contentEncoding(String contentEncoding) {
+ this.contentEncoding = contentEncoding;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String getContentMediaType() {
+ return contentMediaType;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setContentMediaType(String contentMediaType) {
+ this.contentMediaType = contentMediaType;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema contentMediaType(String contentMediaType) {
+ this.contentMediaType = contentMediaType;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getContentSchema() {
+ return contentSchema;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setContentSchema(Schema contentSchema) {
+ this.contentSchema = contentSchema;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema contentSchema(Schema contentSchema) {
+ this.contentSchema = contentSchema;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getPropertyNames() {
+ return propertyNames;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setPropertyNames(Schema propertyNames) {
+ this.propertyNames = propertyNames;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema propertyNames(Schema propertyNames) {
+ this.propertyNames = propertyNames;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Object getUnevaluatedProperties() {
+ return unevaluatedProperties;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setUnevaluatedProperties(Object unevaluatedProperties) {
+ this.unevaluatedProperties = unevaluatedProperties;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema unevaluatedProperties(Object unevaluatedProperties) {
+ this.unevaluatedProperties = unevaluatedProperties;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Integer getMaxContains() {
+ return maxContains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setMaxContains(Integer maxContains) {
+ this.maxContains = maxContains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema maxContains(Integer maxContains) {
+ this.maxContains = maxContains;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Integer getMinContains() {
+ return minContains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setMinContains(Integer minContains) {
+ this.minContains = minContains;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema minContains(Integer minContains) {
+ this.minContains = minContains;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getAdditionalItems() {
+ return additionalItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setAdditionalItems(Schema additionalItems) {
+ this.additionalItems = additionalItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema additionalItems(Schema additionalItems) {
+ this.additionalItems = additionalItems;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getUnevaluatedItems() {
+ return unevaluatedItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setUnevaluatedItems(Schema unevaluatedItems) {
+ this.unevaluatedItems = unevaluatedItems;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema unevaluatedItems(Schema unevaluatedItems) {
+ this.unevaluatedItems = unevaluatedItems;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getIf() {
+ return _if;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setIf(Schema _if) {
+ this._if = _if;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema _if(Schema _if) {
+ this._if = _if;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getElse() {
+ return _else;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setElse(Schema _else) {
+ this._else = _else;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema _else(Schema _else) {
+ this._else = _else;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema getThen() {
+ return then;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setThen(Schema then) {
+ this.then = then;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema then(Schema then) {
+ this.then = then;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Map getDependentSchemas() {
+ return dependentSchemas;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setDependentSchemas(Map dependentSchemas) {
+ this.dependentSchemas = dependentSchemas;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema dependentSchemas(Map dependentSchemas) {
+ this.dependentSchemas = dependentSchemas;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Map> getDependentRequired() {
+ return dependentRequired;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setDependentRequired(Map> dependentRequired) {
+ this.dependentRequired = dependentRequired;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema dependentRequired(Map> dependentRequired) {
+ this.dependentRequired = dependentRequired;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public String get$comment() {
+ return $comment;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void set$comment(String $comment) {
+ this.$comment = $comment;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema $comment(String $comment) {
+ this.$comment = $comment;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public List getExamples() {
+ return examples;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void setExamples(List examples) {
+ this.examples = examples;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public Schema examples(List examples) {
+ this.examples = examples;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ @OpenAPI31
+ public void addExample(T example) {
+ if (this.examples == null) {
+ this.examples = new ArrayList<>();
+ }
+ this.examples.add(example);
+ }
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
@@ -784,8 +1801,10 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.multipleOf, schema.multipleOf) &&
Objects.equals(this.maximum, schema.maximum) &&
Objects.equals(this.exclusiveMaximum, schema.exclusiveMaximum) &&
+ Objects.equals(this.exclusiveMaximumValue, schema.exclusiveMaximumValue) &&
Objects.equals(this.minimum, schema.minimum) &&
Objects.equals(this.exclusiveMinimum, schema.exclusiveMinimum) &&
+ Objects.equals(this.exclusiveMinimumValue, schema.exclusiveMinimumValue) &&
Objects.equals(this.maxLength, schema.maxLength) &&
Objects.equals(this.minLength, schema.minLength) &&
Objects.equals(this.pattern, schema.pattern) &&
@@ -812,14 +1831,48 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.extensions, schema.extensions) &&
Objects.equals(this.discriminator, schema.discriminator) &&
Objects.equals(this._enum, schema._enum) &&
- Objects.equals(this._default, schema._default);
+ Objects.equals(this.contains, schema.contains) &&
+ Objects.equals(this.patternProperties, schema.patternProperties) &&
+ Objects.equals(this.$id, schema.$id) &&
+ Objects.equals(this.$anchor, schema.$anchor) &&
+ Objects.equals(this.$schema, schema.$schema) &&
+ Objects.equals(this.types, schema.types) &&
+ Objects.equals(this.allOf, schema.allOf) &&
+ Objects.equals(this.anyOf, schema.anyOf) &&
+ Objects.equals(this.oneOf, schema.oneOf) &&
+ Objects.equals(this._const, schema._const) &&
+ Objects.equals(this._default, schema._default) &&
+ Objects.equals(this.contentEncoding, schema.contentEncoding) &&
+ Objects.equals(this.contentMediaType, schema.contentMediaType) &&
+ Objects.equals(this.contentSchema, schema.contentSchema) &&
+ Objects.equals(this.propertyNames, schema.propertyNames) &&
+ Objects.equals(this.unevaluatedProperties, schema.unevaluatedProperties) &&
+ Objects.equals(this.maxContains, schema.maxContains) &&
+ Objects.equals(this.minContains, schema.minContains) &&
+ Objects.equals(this.additionalItems, schema.additionalItems) &&
+ Objects.equals(this.unevaluatedItems, schema.unevaluatedItems) &&
+ Objects.equals(this._if, schema._if) &&
+ Objects.equals(this._else, schema._else) &&
+ Objects.equals(this.then, schema.then) &&
+ Objects.equals(this.dependentRequired, schema.dependentRequired) &&
+ Objects.equals(this.dependentSchemas, schema.dependentSchemas) &&
+ Objects.equals(this.$comment, schema.$comment) &&
+ Objects.equals(this.examples, schema.examples) &&
+ Objects.equals(this.prefixItems, schema.prefixItems)
+
+ ;
}
@Override
public int hashCode() {
- return Objects.hash(title, multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern, maxItems,
- minItems, uniqueItems, maxProperties, minProperties, required, type, not, properties, additionalProperties, description, format, $ref,
- nullable, readOnly, writeOnly, example, externalDocs, deprecated, xml, extensions, discriminator, _enum, _default);
+ return Objects.hash(title, multipleOf, maximum, exclusiveMaximum, exclusiveMaximumValue, minimum,
+ exclusiveMinimum, exclusiveMinimumValue, maxLength, minLength, pattern, maxItems, minItems, uniqueItems,
+ maxProperties, minProperties, required, type, not, properties, additionalProperties, description,
+ format, $ref, nullable, readOnly, writeOnly, example, externalDocs, deprecated, xml, extensions,
+ discriminator, _enum, _default, patternProperties, $id, $anchor, $schema, types, allOf, anyOf, oneOf, _const,
+ contentEncoding, contentMediaType, contentSchema, propertyNames, unevaluatedProperties, maxContains,
+ minContains, additionalItems, unevaluatedItems, _if, _else, then, dependentRequired, dependentSchemas,
+ $comment, examples, prefixItems);
}
public java.util.Map getExtensions() {
@@ -827,7 +1880,7 @@ public java.util.Map getExtensions() {
}
public void addExtension(String name, Object value) {
- if (name == null || name.isEmpty() || !name.startsWith("x-")) {
+ if (name == null || name.isEmpty() || (specVersion == SpecVersion.V30 && !name.startsWith("x-"))) {
return;
}
if (this.extensions == null) {
@@ -849,16 +1902,19 @@ public Schema extensions(java.util.Map extensions) {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Schema {\n");
- sb.append(" type: ").append(toIndentedString(type)).append("\n");
+ Object typeStr = specVersion == SpecVersion.V30 ? type : types;
+ sb.append(" type: ").append(toIndentedString(typeStr)).append("\n");
sb.append(" format: ").append(toIndentedString(format)).append("\n");
sb.append(" $ref: ").append(toIndentedString($ref)).append("\n");
sb.append(" description: ").append(toIndentedString(description)).append("\n");
sb.append(" title: ").append(toIndentedString(title)).append("\n");
sb.append(" multipleOf: ").append(toIndentedString(multipleOf)).append("\n");
sb.append(" maximum: ").append(toIndentedString(maximum)).append("\n");
- sb.append(" exclusiveMaximum: ").append(toIndentedString(exclusiveMaximum)).append("\n");
+ Object exclusiveMaximumStr = specVersion == SpecVersion.V30 ? exclusiveMaximum : exclusiveMaximumValue;
+ sb.append(" exclusiveMaximum: ").append(toIndentedString(exclusiveMaximumStr)).append("\n");
sb.append(" minimum: ").append(toIndentedString(minimum)).append("\n");
- sb.append(" exclusiveMinimum: ").append(toIndentedString(exclusiveMinimum)).append("\n");
+ Object exclusiveMinimumStr = specVersion == SpecVersion.V30 ? exclusiveMinimum : exclusiveMinimumValue;
+ sb.append(" exclusiveMinimum: ").append(toIndentedString(exclusiveMinimumStr)).append("\n");
sb.append(" maxLength: ").append(toIndentedString(maxLength)).append("\n");
sb.append(" minLength: ").append(toIndentedString(minLength)).append("\n");
sb.append(" pattern: ").append(toIndentedString(pattern)).append("\n");
@@ -879,6 +1935,30 @@ public String toString() {
sb.append(" deprecated: ").append(toIndentedString(deprecated)).append("\n");
sb.append(" discriminator: ").append(toIndentedString(discriminator)).append("\n");
sb.append(" xml: ").append(toIndentedString(xml)).append("\n");
+ if (specVersion == SpecVersion.V31) {
+ sb.append(" patternProperties: ").append(toIndentedString(patternProperties)).append("\n");
+ sb.append(" contains: ").append(toIndentedString(contains)).append("\n");
+ sb.append(" $id: ").append(toIndentedString($id)).append("\n");
+ sb.append(" $anchor: ").append(toIndentedString($anchor)).append("\n");
+ sb.append(" $schema: ").append(toIndentedString($schema)).append("\n");
+ sb.append(" const: ").append(toIndentedString(_const)).append("\n");
+ sb.append(" contentEncoding: ").append(toIndentedString(contentEncoding)).append("\n");
+ sb.append(" contentMediaType: ").append(toIndentedString(contentMediaType)).append("\n");
+ sb.append(" contentSchema: ").append(toIndentedString(contentSchema)).append("\n");
+ sb.append(" propertyNames: ").append(toIndentedString(propertyNames)).append("\n");
+ sb.append(" unevaluatedProperties: ").append(toIndentedString(unevaluatedProperties)).append("\n");
+ sb.append(" maxContains: ").append(toIndentedString(maxContains)).append("\n");
+ sb.append(" minContains: ").append(toIndentedString(minContains)).append("\n");
+ sb.append(" additionalItems: ").append(toIndentedString(additionalItems)).append("\n");
+ sb.append(" unevaluatedItems: ").append(toIndentedString(unevaluatedItems)).append("\n");
+ sb.append(" _if: ").append(toIndentedString(_if)).append("\n");
+ sb.append(" _else: ").append(toIndentedString(_else)).append("\n");
+ sb.append(" then: ").append(toIndentedString(then)).append("\n");
+ sb.append(" dependentRequired: ").append(toIndentedString(dependentRequired)).append("\n");
+ sb.append(" dependentSchemas: ").append(toIndentedString(dependentSchemas)).append("\n");
+ sb.append(" $comment: ").append(toIndentedString($comment)).append("\n");
+ sb.append(" prefixItems: ").append(toIndentedString(prefixItems)).append("\n");
+ }
sb.append("}");
return sb.toString();
}
@@ -894,5 +1974,44 @@ protected String toIndentedString(java.lang.Object o) {
return o.toString().replace("\n", "\n ");
}
+ public Schema _default(T _default) {
+ this._default = _default;
+ return this;
+ }
+
+ public Schema _enum(List _enum) {
+ this._enum = _enum;
+ return this;
+ }
+
+ public Schema exampleSetFlag(boolean exampleSetFlag) {
+ this.exampleSetFlag = exampleSetFlag;
+ return this;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ public T getConst() {
+ return _const;
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ public void setConst(Object _const) {
+ this._const = cast(_const);
+ }
+
+ /**
+ *
+ * @since 2.2.0 (OpenAPI 3.1.0)
+ */
+ public Schema _const(Object _const) {
+ this._const = cast(_const);
+ return this;
+ }
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/XML.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/XML.java
index a9c646b793..5cb50938a5 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/XML.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/XML.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.media;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -163,6 +165,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/Parameter.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/Parameter.java
index 1f62a98c66..b6d56a3566 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/Parameter.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/Parameter.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.parameters;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.Schema;
@@ -391,6 +392,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/RequestBody.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/RequestBody.java
index 03ea392fdd..947eaabf9a 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/RequestBody.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/parameters/RequestBody.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.parameters;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.media.Content;
/**
@@ -102,6 +103,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponse.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponse.java
index 072820b7c0..cc6087a0a3 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponse.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponse.java
@@ -16,6 +16,7 @@
package io.swagger.v3.oas.models.responses;
+import io.swagger.v3.oas.annotations.OpenAPI31;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.links.Link;
import io.swagger.v3.oas.models.media.Content;
@@ -109,15 +110,20 @@ public ApiResponse content(Content content) {
* @return Link links
**/
- public java.util.Map getLinks() {
+ public Map getLinks() {
return links;
}
- public void setLinks(java.util.Map links) {
+ public void setLinks(Map links) {
this.links = links;
}
- public ApiResponse link(String name, Link link) {
+ public ApiResponse links(Map links) {
+ this.links = links;
+ return this;
+ }
+
+ public ApiResponse addLink(String name, Link link) {
if (this.links == null) {
this.links = new LinkedHashMap<>();
}
@@ -125,6 +131,10 @@ public ApiResponse link(String name, Link link) {
return this;
}
+ public ApiResponse link(String name, Link link) {
+ return this.addLink(name, link);
+ }
+
/**
* returns the $ref property from an ApiResponse instance.
*
@@ -182,6 +192,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponses.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponses.java
index 4a4a807e13..03c2a4c18e 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponses.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/responses/ApiResponses.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.responses;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.LinkedHashMap;
import java.util.Objects;
@@ -69,6 +71,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlow.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlow.java
index 30802c6b7d..0c2329e730 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlow.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlow.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.security;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -142,6 +144,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlows.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlows.java
index a9d5b9470b..7d31965273 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlows.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/OAuthFlows.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.security;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -142,6 +144,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map extensions) {
this.extensions = extensions;
}
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/SecurityScheme.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/SecurityScheme.java
index 184ce97ba4..55c2aae5c7 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/SecurityScheme.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/security/SecurityScheme.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.security;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
/**
* SecurityScheme
*
@@ -30,7 +32,8 @@ public enum Type {
APIKEY("apiKey"),
HTTP("http"),
OAUTH2("oauth2"),
- OPENIDCONNECT("openIdConnect");
+ OPENIDCONNECT("openIdConnect"),
+ MUTUALTLS("mutualTLS");
private String value;
@@ -234,6 +237,14 @@ public java.util.Map getExtensions() {
return extensions;
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void addExtension(String name, Object value) {
if (name == null || name.isEmpty() || !name.startsWith("x-")) {
return;
diff --git a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/servers/Server.java b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/servers/Server.java
index c6bc0da7a8..5ada32920c 100644
--- a/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/servers/Server.java
+++ b/modules/swagger-models/src/main/java/io/swagger/v3/oas/models/servers/Server.java
@@ -16,6 +16,8 @@
package io.swagger.v3.oas.models.servers;
+import io.swagger.v3.oas.annotations.OpenAPI31;
+
import java.util.Objects;
/**
@@ -121,6 +123,14 @@ public void addExtension(String name, Object value) {
this.extensions.put(name, value);
}
+ @OpenAPI31
+ public void addExtension31(String name, Object value) {
+ if (name != null && (name.startsWith("x-oas-") || name.startsWith("x-oai-"))) {
+ return;
+ }
+ addExtension(name, value);
+ }
+
public void setExtensions(java.util.Map