Skip to content

Commit 747b38d

Browse files
fix: handle default values for LocalDate
1 parent 3e7b337 commit 747b38d

File tree

3 files changed

+49
-32
lines changed

3 files changed

+49
-32
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,13 @@
3636
import java.lang.reflect.Method;
3737
import java.security.Principal;
3838
import java.time.ZoneId;
39-
import java.util.ArrayList;
40-
import java.util.Arrays;
41-
import java.util.Collection;
42-
import java.util.Collections;
43-
import java.util.HashMap;
44-
import java.util.Iterator;
45-
import java.util.LinkedHashMap;
46-
import java.util.List;
47-
import java.util.Locale;
48-
import java.util.Map;
39+
import java.util.*;
4940
import java.util.Map.Entry;
50-
import java.util.Objects;
51-
import java.util.Optional;
52-
import java.util.Set;
53-
import java.util.TimeZone;
5441
import java.util.stream.Collectors;
5542
import java.util.stream.Stream;
5643

5744
import com.fasterxml.jackson.annotation.JsonView;
5845
import io.swagger.v3.core.converter.AnnotatedType;
59-
import io.swagger.v3.core.util.PrimitiveType;
6046
import io.swagger.v3.oas.annotations.Parameters;
6147
import io.swagger.v3.oas.annotations.enums.ParameterIn;
6248
import io.swagger.v3.oas.models.Components;
@@ -416,8 +402,12 @@ else if (!RequestMethod.GET.equals(requestMethod) || OpenApiVersion.OPENAPI_3_1.
416402
* @param parametersDocMap the parameters doc map
417403
* @return the parameter linked hash map
418404
*/
419-
private LinkedHashMap<ParameterId, Parameter> getParameterLinkedHashMap(Components components, MethodAttributes methodAttributes, List<Parameter> operationParameters, Map<ParameterId, io.swagger.v3.oas.annotations.Parameter> parametersDocMap) {
420-
LinkedHashMap<ParameterId, Parameter> map = operationParameters.stream().collect(Collectors.toMap(ParameterId::new, parameter -> parameter, (u, v) -> {
405+
private LinkedHashMap<ParameterId, Parameter> getParameterLinkedHashMap(Components components,
406+
MethodAttributes methodAttributes,
407+
List<Parameter> operationParameters,
408+
Map<ParameterId, io.swagger.v3.oas.annotations.Parameter> parametersDocMap) {
409+
LinkedHashMap<ParameterId, Parameter> map = operationParameters.stream()
410+
.collect(Collectors.toMap(ParameterId::new, parameter -> parameter, (u, v) -> {
421411
LOGGER.warn(
422412
"Duplicate OpenAPI parameter detected: name='{}', in='{}'. Keeping the first found and ignoring the rest. " +
423413
"Declare the parameter only once.",
@@ -439,7 +429,8 @@ private LinkedHashMap<ParameterId, Parameter> getParameterLinkedHashMap(Componen
439429
long mumParamsWithName = map.keySet().stream().filter(parameterId1 -> parameterId.getpName().equals(parameterId1.getpName())).count();
440430
long mumParamsDocWithName = parametersDocMap.keySet().stream().filter(parameterId1 -> parameterId.getpName().equals(parameterId1.getpName())).count();
441431
if (mumParamsWithName == 1 && mumParamsDocWithName == 1) {
442-
Optional<ParameterId> parameterIdWithSameNameOptional = map.keySet().stream().filter(parameterId1 -> parameterId.getpName().equals(parameterId1.getpName())).findAny();
432+
Optional<ParameterId> parameterIdWithSameNameOptional = map.keySet().stream()
433+
.filter(parameterId1 -> parameterId.getpName().equals(parameterId1.getpName())).findAny();
443434
parameterIdWithSameNameOptional.ifPresent(parameterIdWithSameName -> {
444435
GenericParameterService.mergeParameter(map.get(parameterIdWithSameName), parameter);
445436
map.put(parameterIdWithSameName, parameter);
@@ -574,7 +565,8 @@ private void setParams(Operation operation, List<Parameter> operationParameters,
574565
* @return the boolean
575566
*/
576567
public boolean isValidParameter(Parameter parameter, MethodAttributes methodAttributes) {
577-
return parameter != null && (parameter.getName() != null || parameter.get$ref() != null) && !(ArrayUtils.contains(methodAttributes.getMethodConsumes(), APPLICATION_FORM_URLENCODED_VALUE) && ParameterIn.QUERY.toString().equals(parameter.getIn()));
568+
return parameter != null && (parameter.getName() != null || parameter.get$ref() != null) &&
569+
!(ArrayUtils.contains(methodAttributes.getMethodConsumes(), APPLICATION_FORM_URLENCODED_VALUE) && ParameterIn.QUERY.toString().equals(parameter.getIn()));
578570
}
579571

580572
/**
@@ -639,14 +631,7 @@ public Parameter buildParam(ParameterInfo parameterInfo, Components components,
639631
Schema<?> schema = parameterBuilder.calculateSchema(components, parameterInfo, null,
640632
jsonView);
641633
if (parameterInfo.getDefaultValue() != null && schema != null) {
642-
Object defaultValue = parameterInfo.getDefaultValue();
643-
// Cast default value
644-
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(schema.getType(), schema.getFormat());
645-
if (primitiveType != null) {
646-
Schema<?> primitiveSchema = primitiveType.createProperty();
647-
primitiveSchema.setDefault(parameterInfo.getDefaultValue());
648-
defaultValue = primitiveSchema.getDefault();
649-
}
634+
Object defaultValue = SpringDocAnnotationsUtils.castDefaultValue(schema, parameterInfo.getDefaultValue());
650635
schema.setDefault(defaultValue);
651636
}
652637
parameter.setSchema(schema);
@@ -759,18 +744,22 @@ private Map<ParameterId, io.swagger.v3.oas.annotations.Parameter> getApiParamete
759744
Class<?> declaringClass = method.getDeclaringClass();
760745

761746
Set<Parameters> apiParametersDoc = AnnotatedElementUtils.findAllMergedAnnotations(method, Parameters.class);
762-
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersMap = apiParametersDoc.stream().flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
747+
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersMap = apiParametersDoc.stream()
748+
.flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
763749

764750
Set<Parameters> apiParametersDocDeclaringClass = AnnotatedElementUtils.findAllMergedAnnotations(declaringClass, Parameters.class);
765-
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersDocDeclaringClassMap = apiParametersDocDeclaringClass.stream().flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
751+
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParametersDocDeclaringClassMap = apiParametersDocDeclaringClass.stream()
752+
.flatMap(x -> Stream.of(x.value())).collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
766753
apiParametersMap.putAll(apiParametersDocDeclaringClassMap);
767754

768755
Set<io.swagger.v3.oas.annotations.Parameter> apiParameterDoc = AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.Parameter.class);
769-
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParameterDocMap = apiParameterDoc.stream().collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
756+
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParameterDocMap = apiParameterDoc.stream()
757+
.collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
770758
apiParametersMap.putAll(apiParameterDocMap);
771759

772760
Set<io.swagger.v3.oas.annotations.Parameter> apiParameterDocDeclaringClass = AnnotatedElementUtils.findAllMergedAnnotations(declaringClass, io.swagger.v3.oas.annotations.Parameter.class);
773-
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParameterDocDeclaringClassMap = apiParameterDocDeclaringClass.stream().collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
761+
LinkedHashMap<ParameterId, io.swagger.v3.oas.annotations.Parameter> apiParameterDocDeclaringClassMap = apiParameterDocDeclaringClass.stream()
762+
.collect(Collectors.toMap(ParameterId::new, x -> x, (e1, e2) -> e2, LinkedHashMap::new));
774763
apiParametersMap.putAll(apiParameterDocDeclaringClassMap);
775764

776765
return apiParametersMap;

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.io.IOException;
3030
import java.lang.annotation.Annotation;
3131
import java.lang.reflect.Type;
32+
import java.time.LocalDate;
3233
import java.util.ArrayList;
3334
import java.util.Arrays;
3435
import java.util.Collections;
@@ -50,6 +51,7 @@
5051
import io.swagger.v3.core.converter.ModelConverters;
5152
import io.swagger.v3.core.converter.ResolvedSchema;
5253
import io.swagger.v3.core.util.AnnotationsUtils;
54+
import io.swagger.v3.core.util.PrimitiveType;
5355
import io.swagger.v3.oas.annotations.Hidden;
5456
import io.swagger.v3.oas.annotations.media.Encoding;
5557
import io.swagger.v3.oas.annotations.media.ExampleObject;
@@ -468,6 +470,31 @@ private static boolean isArray(io.swagger.v3.oas.annotations.media.Content annot
468470
return isArray;
469471
}
470472

473+
/**
474+
* Attempt to cast the default value so that it matches the {@link Schema} type.
475+
* If the value cannot be cast then the provided default value is returned as-is.
476+
*
477+
* @param schema the schema that will have the default value
478+
* @param defaultValue the default value
479+
* @return the cast default value
480+
*/
481+
public static Object castDefaultValue(Schema schema, Object defaultValue) {
482+
if (schema != null && defaultValue != null) {
483+
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(schema.getType(), schema.getFormat());
484+
if (primitiveType != null) {
485+
Schema<?> primitiveSchema = primitiveType.createProperty();
486+
if (primitiveType.equals(PrimitiveType.DATE) && defaultValue instanceof LocalDate localDate) {
487+
defaultValue = localDate.toString();
488+
}
489+
primitiveSchema.setDefault(defaultValue);
490+
if (primitiveSchema.getDefault() != null) {
491+
defaultValue = primitiveSchema.getDefault();
492+
}
493+
}
494+
}
495+
return defaultValue;
496+
}
497+
471498
/**
472499
* Resolve default value object.
473500
*

springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app150.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"required": false,
2525
"schema": {
2626
"type": "string",
27-
"format": "date"
27+
"format": "date",
28+
"default" : "2021-03-08"
2829
}
2930
}
3031
],

0 commit comments

Comments
 (0)