Skip to content

Commit

Permalink
refs #4474 - fix NPE while resolving container types
Browse files Browse the repository at this point in the history
  • Loading branch information
frantuma committed Mar 26, 2024
1 parent 194b1dd commit d5c3728
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import io.swagger.v3.core.util.AnnotationsUtils;
import io.swagger.v3.core.util.Constants;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.core.util.Json31;
import io.swagger.v3.core.util.ObjectMapperFactory;
import io.swagger.v3.core.util.ReferenceTypeUtils;
import io.swagger.v3.core.util.PrimitiveType;
Expand Down Expand Up @@ -438,7 +437,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context


if (keyType != null && valueType != null) {
if (ReflectionUtils.isSystemType(type) && !annotatedType.isSchemaProperty() && !annotatedType.isResolveAsRef()) {
if (ReflectionUtils.isSystemTypeNotArray(type) && !annotatedType.isSchemaProperty() && !annotatedType.isResolveAsRef()) {
context.resolve(new AnnotatedType().components(annotatedType.getComponents()).type(valueType).jsonViewAnnotation(annotatedType.getJsonViewAnnotation()));
return null;
}
Expand Down Expand Up @@ -470,7 +469,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
mapModel.name(name);
model = mapModel;
} else if (valueType != null) {
if (ReflectionUtils.isSystemType(type) && !annotatedType.isSchemaProperty() && !annotatedType.isResolveAsRef()) {
if (ReflectionUtils.isSystemTypeNotArray(type) && !annotatedType.isSchemaProperty() && !annotatedType.isResolveAsRef()) {
context.resolve(new AnnotatedType().components(annotatedType.getComponents()).type(valueType).jsonViewAnnotation(annotatedType.getJsonViewAnnotation()));
return null;
}
Expand Down Expand Up @@ -924,10 +923,12 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
.collect(Collectors.toList());
anyOfFiltered.forEach(c -> {
Schema anyOfRef = context.resolve(new AnnotatedType().components(annotatedType.getComponents()).type(c).jsonViewAnnotation(annotatedType.getJsonViewAnnotation()));
if (StringUtils.isNotBlank(anyOfRef.getName())) {
composedSchema.addAnyOfItem(new Schema().$ref(Components.COMPONENTS_SCHEMAS_REF + anyOfRef.getName()));
} else {
composedSchema.addAnyOfItem(anyOfRef);
if (anyOfRef != null) {
if (StringUtils.isNotBlank(anyOfRef.getName())) {
composedSchema.addAnyOfItem(new Schema().$ref(Components.COMPONENTS_SCHEMAS_REF + anyOfRef.getName()));
} else {
composedSchema.addAnyOfItem(anyOfRef);
}
}
// remove shared properties defined in the parent
if (isSubtype(beanDesc.getClassInfo(), c)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ public static boolean isVoid(Type type) {
}

public static boolean isSystemType(JavaType type) {
return isSystemTypeNotArray(type) ? true : type.isArrayType();
}

public static boolean isSystemTypeNotArray(JavaType type) {
// used while resolving container types to skip resolving system types; possibly extend by checking classloader
// and/or other packages
for (String systemPrefix: PrimitiveType.systemPrefixes()) {
Expand All @@ -450,7 +454,7 @@ public static boolean isSystemType(JavaType type) {
}
}
}
return type.isArrayType();
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package io.swagger.v3.core.resolving;

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.oas.models.media.Schema;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Ticket4474Test extends SwaggerTestBase {

@AfterMethod
public void afterTest() {
ModelResolver.enumsAsRef = false;
}

@Test
public void testAnyOf() throws Exception {
ModelResolver.enumsAsRef = true;

final ModelResolver modelResolver = new ModelResolver(mapper());

final ModelConverterContextImpl context = new ModelConverterContextImpl(modelResolver);

final Schema model = context
.resolve(new AnnotatedType(Document.class));

SerializationMatchers.assertEqualsToYaml(context.getDefinedModels(), "Document:\n" +
" type: object\n" +
" properties:\n" +
" data:\n" +
" type: object\n" +
" additionalProperties:\n" +
" type: object\n" +
" anyOf:\n" +
" - type: array\n" +
" items:\n" +
" type: boolean\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int32\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int64\n" +
" - type: array\n" +
" items:\n" +
" type: number\n" +
" format: double\n" +
" - type: array\n" +
" items:\n" +
" type: string\n" +
" - type: boolean\n" +
" - type: integer\n" +
" format: int32\n" +
" - type: integer\n" +
" format: int64\n" +
" listData:\n" +
" type: array\n" +
" items:\n" +
" type: object\n" +
" anyOf:\n" +
" - type: array\n" +
" items:\n" +
" type: boolean\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int32\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int64\n" +
" - type: array\n" +
" items:\n" +
" type: number\n" +
" format: double\n" +
" - type: array\n" +
" items:\n" +
" type: string\n" +
" - type: boolean\n" +
" - type: integer\n" +
" format: int32\n" +
" - type: integer\n" +
" format: int64\n" +
" itemData:\n" +
" type: object\n" +
" anyOf:\n" +
" - type: array\n" +
" items:\n" +
" type: boolean\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int32\n" +
" - type: array\n" +
" items:\n" +
" type: integer\n" +
" format: int64\n" +
" - type: array\n" +
" items:\n" +
" type: number\n" +
" format: double\n" +
" - type: array\n" +
" items:\n" +
" type: string\n" +
" - type: boolean\n" +
" - type: integer\n" +
" format: int32\n" +
" - type: integer\n" +
" format: int64");
}

static class Document {
@io.swagger.v3.oas.annotations.media.Schema(
anyOf = {
Boolean[].class,
Integer[].class,
Long[].class,
Double[].class,
String[].class,
Boolean.class,
Integer.class,
Long.class,
Map.class,
})
public Map<String, Object> data = new HashMap<>();

@io.swagger.v3.oas.annotations.media.Schema(
anyOf = {
Boolean[].class,
Integer[].class,
Long[].class,
Double[].class,
String[].class,
Boolean.class,
Integer.class,
Long.class,
Map.class,
})
public List<Object> listData = new ArrayList<>();

@io.swagger.v3.oas.annotations.media.Schema(
anyOf = {
Boolean[].class,
Integer[].class,
Long[].class,
Double[].class,
String[].class,
Boolean.class,
Integer.class,
Long.class,
Map.class,
})
public Object itemData = new Object();
}
}

0 comments on commit d5c3728

Please sign in to comment.