diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java index a971901e4..cf758c229 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/ModelIO.java @@ -219,10 +219,15 @@ public T read(AnnotationValue annotation) { .orElse(null); } - @SuppressWarnings("unchecked") public T read(Class type, AnnotationInstance annotation) { + return read(type, annotation, new String[0]); + } + + @SuppressWarnings("unchecked") + public T read(Class type, AnnotationInstance annotation, String... ignoredProperties) { IoLogging.logger.singleAnnotation(annotation.name().toString()); BaseModel model = (BaseModel) OASFactory.createObject(type); + Set ignoredNames = Set.of(ignoredProperties); for (AnnotationValue annotationValue : annotation.values()) { Object value = scannerContext().annotations().value(annotation, annotationValue); @@ -234,7 +239,7 @@ public T read(Class type, AnnotationInstance annota model.setRef(annotationValue.asString()); } else if ("extensions".equals(name) && Extensible.class.isAssignableFrom(type)) { ((BaseExtensibleModel) model).setExtensions(extensionIO().readExtensible(annotation)); - } else { + } else if (!ignoredNames.contains(name)) { model.setProperty(name, value); } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java index 9deb301af..edc70cc36 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/headers/HeaderIO.java @@ -1,12 +1,10 @@ package io.smallrye.openapi.runtime.io.headers; -import org.eclipse.microprofile.openapi.OASFactory; import org.eclipse.microprofile.openapi.models.headers.Header; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; -import io.smallrye.openapi.model.ReferenceType; import io.smallrye.openapi.runtime.io.IOContext; -import io.smallrye.openapi.runtime.io.IoLogging; import io.smallrye.openapi.runtime.io.MapModelIO; import io.smallrye.openapi.runtime.io.Names; import io.smallrye.openapi.runtime.io.ReferenceIO; @@ -14,11 +12,9 @@ public class HeaderIO extends MapModelIO implements ReferenceIO { - private static final String PROP_DESCRIPTION = "description"; private static final String PROP_SCHEMA = "schema"; - private static final String PROP_ALLOW_EMPTY_VALUE = "allowEmptyValue"; - private static final String PROP_REQUIRED = "required"; - private static final String PROP_DEPRECATED = "deprecated"; + private static final String PROP_EXAMPLE = "example"; + private static final String PROP_EXAMPLES = "examples"; public HeaderIO(IOContext context) { super(context, Names.HEADER, Names.create(Header.class)); @@ -26,15 +22,35 @@ public HeaderIO(IOContext context) { @Override public Header read(AnnotationInstance annotation) { - IoLogging.logger.singleAnnotation("@Header"); - Header header = OASFactory.createHeader(); - header.setRef(ReferenceType.HEADER.refValue(annotation)); - header.setDescription(value(annotation, PROP_DESCRIPTION)); - header.setSchema(schemaIO().read(annotation.value(PROP_SCHEMA))); - header.setRequired(value(annotation, PROP_REQUIRED)); - header.setDeprecated(value(annotation, PROP_DEPRECATED)); - header.setAllowEmptyValue(value(annotation, PROP_ALLOW_EMPTY_VALUE)); - header.setExtensions(extensionIO().readExtensible(annotation)); + Header header = read(Header.class, annotation, "name"); + + if (header.getExample() != null || header.getExamples() != null) { + /* + * Save the header for later parsing. The schema may not yet be set + * so we do not know if it should be parsed. + */ + scannerContext().getUnparsedExamples().add(header); + } + return header; } + + @Override + protected boolean setProperty(Header model, AnnotationValue value) { + switch (value.name()) { + case PROP_SCHEMA: + model.setSchema(schemaIO().read(value)); + return true; + case PROP_EXAMPLES: + model.setExamples(exampleObjectIO().readMap(value)); + return true; + case PROP_EXAMPLE: + model.setExample(value.asString()); + return true; + default: + break; + } + + return false; + } } diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java index 419322b84..b7f1a930f 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/OpenApiAnnotationScanner.java @@ -23,6 +23,7 @@ import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.Paths; import org.eclipse.microprofile.openapi.models.examples.Example; +import org.eclipse.microprofile.openapi.models.headers.Header; import org.eclipse.microprofile.openapi.models.media.MediaType; import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; import org.eclipse.microprofile.openapi.models.parameters.Parameter; @@ -417,6 +418,10 @@ private void parseExamples() { MediaType mediaType = (MediaType) model; parseExample(mediaType.getExample(), mediaType::setExample); examples = mediaType.getExamples(); + } else if (model instanceof Header) { + Header header = (Header) model; + parseExample(header.getExample(), header::setExample); + examples = header.getExamples(); } if (examples != null) { diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java index 741773477..174be2ee8 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/spi/AnnotationScanner.java @@ -18,6 +18,7 @@ import java.util.stream.Stream; import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.ExternalDocumentation; import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.Operation; import org.eclipse.microprofile.openapi.models.callbacks.Callback; @@ -313,6 +314,11 @@ default Optional processOperation(final AnnotationScannerContext cont saveOperationId(context, resourceClass, method, operationId); } + ExternalDocumentation externalDocs = context.io().extDocIO().read(method); + if (externalDocs != null) { + operation.setExternalDocs(externalDocs); + } + return Optional.of(operation); } diff --git a/pom.xml b/pom.xml index f145e1384..b5e7686ba 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ 3.5.3 3.16.0 2.17.0 - 4.1.1 + 4.2-SNAPSHOT 0.9.0 1.3 2.0.0.0 @@ -78,6 +78,19 @@ HEAD + + + microprofile-snapshots + https://repo.eclipse.org/content/repositories/microprofile-snapshots/ + + false + + + true + + + + core extension-jaxrs diff --git a/testsuite/data/pom.xml b/testsuite/data/pom.xml index 624437154..0d033daeb 100644 --- a/testsuite/data/pom.xml +++ b/testsuite/data/pom.xml @@ -13,7 +13,7 @@ SmallRye: OpenAPI Test Data - 4.1.1 + 4.2-SNAPSHOT 2.2.0 17 ${java.version} @@ -24,6 +24,19 @@ 3.32.3 + + + microprofile-snapshots + https://repo.eclipse.org/content/repositories/microprofile-snapshots/ + + false + + + true + + + +