diff --git a/core/src/main/java/io/micronaut/core/convert/ConversionContext.java b/core/src/main/java/io/micronaut/core/convert/ConversionContext.java index 0a088325030..d06f0289ea6 100644 --- a/core/src/main/java/io/micronaut/core/convert/ConversionContext.java +++ b/core/src/main/java/io/micronaut/core/convert/ConversionContext.java @@ -44,32 +44,32 @@ public interface ConversionContext extends AnnotationMetadataProvider, TypeVaria /** * Constant for Boolean argument. */ - ArgumentConversionContext BOOLEAN = ConversionContext.of(Argument.BOOLEAN); + ArgumentConversionContext BOOLEAN = ImmutableArgumentConversionContext.of(Argument.BOOLEAN); /** * Constant for Integer argument. */ - ArgumentConversionContext INT = ConversionContext.of(Argument.INT); + ArgumentConversionContext INT = ImmutableArgumentConversionContext.of(Argument.INT); /** * Constant for Long argument. */ - ArgumentConversionContext LONG = ConversionContext.of(Argument.LONG); + ArgumentConversionContext LONG = ImmutableArgumentConversionContext.of(Argument.LONG); /** * Constant for String argument. */ - ArgumentConversionContext STRING = ConversionContext.of(Argument.STRING); + ArgumentConversionContext STRING = ImmutableArgumentConversionContext.of(Argument.STRING); /** * Constant for List argument. */ - ArgumentConversionContext> LIST_OF_STRING = ConversionContext.of(Argument.LIST_OF_STRING); + ArgumentConversionContext> LIST_OF_STRING = ImmutableArgumentConversionContext.of(Argument.LIST_OF_STRING); /** * Constant for List argument. */ - ArgumentConversionContext MAP = ConversionContext.of(Argument.of(Map.class)); + ArgumentConversionContext MAP = ImmutableArgumentConversionContext.of(Argument.of(Map.class)); /** * In the case where the type to be converted contains generic type arguments this map will return @@ -168,7 +168,10 @@ public Map> getTypeVariables() { } /** - * Create a simple {@link ConversionContext} for the given generic type variables. + * Create a new simple {@link ConversionContext} for the given generic type variables. + * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads. Consider using {@link io.micronaut.core.convert.ImmutableArgumentConversionContext} for this case.

* * @param type Generic * @param argument The argument @@ -181,6 +184,9 @@ static ArgumentConversionContext of(Argument argument) { /** * Create a simple {@link ConversionContext} for the given generic type variables. * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads. Consider using {@link io.micronaut.core.convert.ImmutableArgumentConversionContext} for this case.

+ * * @param type Generic * @param argument The argument * @return The conversion context @@ -193,6 +199,9 @@ static ArgumentConversionContext of(Class argument) { /** * Create a simple {@link ConversionContext} for the given generic type variables. * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads. Consider using {@link io.micronaut.core.convert.ImmutableArgumentConversionContext} for this case.

+ * * @param type Generic * @param argument The argument * @param locale The locale @@ -205,6 +214,9 @@ static ArgumentConversionContext of(Argument argument, @Nullable Locale l /** * Create a simple {@link ConversionContext} for the given generic type variables. * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads. Consider using {@link io.micronaut.core.convert.ImmutableArgumentConversionContext} for this case.

+ * * @param type Generic * @param argument The argument * @param locale The locale diff --git a/core/src/main/java/io/micronaut/core/convert/DefaultArgumentConversionContext.java b/core/src/main/java/io/micronaut/core/convert/DefaultArgumentConversionContext.java index b2bc3712947..05f8b59f11a 100644 --- a/core/src/main/java/io/micronaut/core/convert/DefaultArgumentConversionContext.java +++ b/core/src/main/java/io/micronaut/core/convert/DefaultArgumentConversionContext.java @@ -20,6 +20,7 @@ import java.nio.charset.Charset; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * Default implementation of the {@link ConversionContext} interface. diff --git a/core/src/main/java/io/micronaut/core/convert/ImmutableArgumentConversionContext.java b/core/src/main/java/io/micronaut/core/convert/ImmutableArgumentConversionContext.java new file mode 100644 index 00000000000..e0bb83d7619 --- /dev/null +++ b/core/src/main/java/io/micronaut/core/convert/ImmutableArgumentConversionContext.java @@ -0,0 +1,60 @@ +/* + * Copyright 2017-2022 original authors + * + * 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 + * + * https://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.micronaut.core.convert; + +import io.micronaut.core.type.Argument; +import io.micronaut.core.util.ArgumentUtils; + +/** + * Immutable variant of {@link io.micronaut.core.convert.ArgumentConversionContext} that can be used as a constant + * in cases where conversion error handling and rejection is not required. + * + * @param The generic type + * @since 3.2.7 + * @author graemerocher + */ +public interface ImmutableArgumentConversionContext extends ArgumentConversionContext { + /** + * Create a new simple {@link ConversionContext} for the given generic type variables. + * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads.

+ * + * @param type Generic + * @param argument The argument + * @return The conversion context + * @since 3.2.7 + */ + static ImmutableArgumentConversionContext of(Argument argument) { + ArgumentUtils.requireNonNull("argument", argument); + return () -> argument; + } + + /** + * Create a simple {@link ConversionContext} for the given generic type variables. + * + *

NOTE: The instance returned by this method is NOT thread safe and should be shared + * via static state or between threads.

+ * + * @param type Generic + * @param type The argument + * @return The conversion context + * @since 3.2.7 + */ + static ImmutableArgumentConversionContext of(Class type) { + return of(Argument.of(type)); + } +} diff --git a/http-client-core/src/main/java/io/micronaut/http/client/interceptor/HttpClientIntroductionAdvice.java b/http-client-core/src/main/java/io/micronaut/http/client/interceptor/HttpClientIntroductionAdvice.java index 25590a614d7..d1f8b0af110 100644 --- a/http-client-core/src/main/java/io/micronaut/http/client/interceptor/HttpClientIntroductionAdvice.java +++ b/http-client-core/src/main/java/io/micronaut/http/client/interceptor/HttpClientIntroductionAdvice.java @@ -195,7 +195,7 @@ public Object intercept(MethodInvocationContext context) { // Convert and put as path param if (argument.getAnnotationMetadata().hasStereotype(Format.class)) { ConversionService.SHARED.convert(value, - ConversionContext.of(String.class).with(argument.getAnnotationMetadata())) + ConversionContext.STRING.with(argument.getAnnotationMetadata())) .ifPresent(v -> pathParams.put(name, v)); } else { pathParams.put(name, value); diff --git a/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java b/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java index 5552e5f0b43..63a19ae45e5 100644 --- a/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java +++ b/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java @@ -18,6 +18,7 @@ import io.micronaut.core.async.publisher.Publishers; import io.micronaut.core.convert.ArgumentConversionContext; import io.micronaut.core.convert.ConversionContext; +import io.micronaut.core.convert.ImmutableArgumentConversionContext; import io.micronaut.core.util.StringUtils; import io.micronaut.http.HttpHeaders; import io.micronaut.http.HttpMethod; @@ -51,7 +52,7 @@ @Filter("/**") public class CorsFilter implements HttpServerFilter { - private static final ArgumentConversionContext CONVERSION_CONTEXT_HTTP_METHOD = ConversionContext.of(HttpMethod.class); + private static final ArgumentConversionContext CONVERSION_CONTEXT_HTTP_METHOD = ImmutableArgumentConversionContext.of(HttpMethod.class); protected final HttpServerConfiguration.CorsConfiguration corsConfiguration; diff --git a/http-server/src/main/java/io/micronaut/http/server/cors/CorsOriginConverter.java b/http-server/src/main/java/io/micronaut/http/server/cors/CorsOriginConverter.java index fb08a18bc19..a5b4da4112b 100644 --- a/http-server/src/main/java/io/micronaut/http/server/cors/CorsOriginConverter.java +++ b/http-server/src/main/java/io/micronaut/http/server/cors/CorsOriginConverter.java @@ -17,6 +17,7 @@ import io.micronaut.core.convert.ArgumentConversionContext; import io.micronaut.core.convert.ConversionContext; +import io.micronaut.core.convert.ImmutableArgumentConversionContext; import io.micronaut.core.convert.TypeConverter; import io.micronaut.core.convert.value.ConvertibleValues; import io.micronaut.core.convert.value.ConvertibleValuesMap; @@ -45,7 +46,7 @@ public class CorsOriginConverter implements TypeConverter, C private static final String ALLOW_CREDENTIALS = "allow-credentials"; private static final String MAX_AGE = "max-age"; - private static final ArgumentConversionContext> CONVERSION_CONTEXT_LIST_OF_HTTP_METHOD = ConversionContext.of(Argument.listOf(HttpMethod.class)); + private static final ArgumentConversionContext> CONVERSION_CONTEXT_LIST_OF_HTTP_METHOD = ImmutableArgumentConversionContext.of(Argument.listOf(HttpMethod.class)); @Override public Optional convert(Map object, Class targetType, ConversionContext context) { diff --git a/http/src/main/java/io/micronaut/http/MediaType.java b/http/src/main/java/io/micronaut/http/MediaType.java index e9e3935e7a8..386e2d8e53f 100644 --- a/http/src/main/java/io/micronaut/http/MediaType.java +++ b/http/src/main/java/io/micronaut/http/MediaType.java @@ -19,8 +19,8 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.core.annotation.TypeHint; import io.micronaut.core.convert.ArgumentConversionContext; -import io.micronaut.core.convert.ConversionContext; import io.micronaut.core.convert.ConversionService; +import io.micronaut.core.convert.ImmutableArgumentConversionContext; import io.micronaut.core.naming.NameUtils; import io.micronaut.core.type.Argument; import io.micronaut.core.util.CollectionUtils; @@ -374,7 +374,7 @@ public class MediaType implements CharSequence { static final Argument ARGUMENT = Argument.of(MediaType.class); @Internal - static final ArgumentConversionContext CONVERSION_CONTEXT = ConversionContext.of(ARGUMENT); + static final ArgumentConversionContext CONVERSION_CONTEXT = ImmutableArgumentConversionContext.of(ARGUMENT); private static final char SEMICOLON = ';';