diff --git a/implementation/src/main/java/io/smallrye/config/ConfigMappingClass.java b/implementation/src/main/java/io/smallrye/config/ConfigMappingClass.java deleted file mode 100644 index 746a3c34f..000000000 --- a/implementation/src/main/java/io/smallrye/config/ConfigMappingClass.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.smallrye.config; - -import java.lang.reflect.Modifier; - -import io.smallrye.common.constraint.Assert; - -final class ConfigMappingClass implements ConfigMappingMetadata { - private static final ClassValue cv = new ClassValue() { - @Override - protected ConfigMappingClass computeValue(final Class classType) { - return createConfigurationClass(classType); - } - }; - - static ConfigMappingClass getConfigurationClass(Class classType) { - Assert.checkNotNullParam("classType", classType); - return cv.get(classType); - } - - private static ConfigMappingClass createConfigurationClass(final Class classType) { - if (classType.isInterface() && classType.getTypeParameters().length == 0 || - Modifier.isAbstract(classType.getModifiers()) || - classType.isEnum()) { - return null; - } - - return new ConfigMappingClass(classType); - } - - private static String generateInterfaceName(final Class classType) { - if (classType.isInterface() && classType.getTypeParameters().length == 0 || - Modifier.isAbstract(classType.getModifiers()) || - classType.isEnum()) { - throw new IllegalArgumentException(); - } - - return classType.getPackage().getName() + - "." + - classType.getSimpleName() + - classType.getName().hashCode() + - "I"; - } - - private final Class classType; - private final String interfaceName; - - public ConfigMappingClass(final Class classType) { - this.classType = classType; - this.interfaceName = generateInterfaceName(classType); - } - - @Override - public Class getInterfaceType() { - return classType; - } - - @Override - public String getClassName() { - return interfaceName; - } - - @Override - public byte[] getClassBytes() { - return ConfigMappingGenerator.generate(classType, interfaceName); - } -} diff --git a/implementation/src/main/java/io/smallrye/config/ConfigMappingLoader.java b/implementation/src/main/java/io/smallrye/config/ConfigMappingLoader.java index bbbde4079..da2cd1425 100644 --- a/implementation/src/main/java/io/smallrye/config/ConfigMappingLoader.java +++ b/implementation/src/main/java/io/smallrye/config/ConfigMappingLoader.java @@ -4,6 +4,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.List; @@ -14,6 +15,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperties; import io.smallrye.common.classloader.ClassDefiner; +import io.smallrye.common.constraint.Assert; import io.smallrye.config._private.ConfigMessages; public final class ConfigMappingLoader { @@ -181,7 +183,7 @@ static void validateAnnotations(Class type) { /** * Do not remove this method or inline it. It is keep separate on purpose, so it is easier to substitute it with * the GraalVM API for native image compilation. - * + *

* We cannot keep dynamic references to LOOKUP, so this method may be replaced. This is not a problem, since for * native image we can generate the mapping class bytes in the binary so we don't need to dynamically load them. */ @@ -204,4 +206,68 @@ public Class getImplementationClass() { return implementationClass; } } + + /** + * Implementation of {@link ConfigMappingMetadata} for MicroProfile {@link ConfigProperties}. + */ + static final class ConfigMappingClass implements ConfigMappingMetadata { + private static final ClassValue cv = new ClassValue<>() { + @Override + protected ConfigMappingClass computeValue(final Class classType) { + return createConfigurationClass(classType); + } + }; + + static ConfigMappingClass getConfigurationClass(Class classType) { + Assert.checkNotNullParam("classType", classType); + return cv.get(classType); + } + + private static ConfigMappingClass createConfigurationClass(final Class classType) { + if (classType.isInterface() && classType.getTypeParameters().length == 0 || + Modifier.isAbstract(classType.getModifiers()) || + classType.isEnum()) { + return null; + } + + return new ConfigMappingClass(classType); + } + + private static String generateInterfaceName(final Class classType) { + if (classType.isInterface() && classType.getTypeParameters().length == 0 || + Modifier.isAbstract(classType.getModifiers()) || + classType.isEnum()) { + throw new IllegalArgumentException(); + } + + return classType.getPackage().getName() + + "." + + classType.getSimpleName() + + classType.getName().hashCode() + + "I"; + } + + private final Class classType; + private final String interfaceName; + + public ConfigMappingClass(final Class classType) { + this.classType = classType; + this.interfaceName = generateInterfaceName(classType); + } + + @Override + public Class getInterfaceType() { + return classType; + } + + @Override + public String getClassName() { + return interfaceName; + } + + @Override + public byte[] getClassBytes() { + return ConfigMappingGenerator.generate(classType, interfaceName); + } + } } diff --git a/implementation/src/main/java/io/smallrye/config/Converters.java b/implementation/src/main/java/io/smallrye/config/Converters.java index 969e05042..f6985d58f 100644 --- a/implementation/src/main/java/io/smallrye/config/Converters.java +++ b/implementation/src/main/java/io/smallrye/config/Converters.java @@ -21,6 +21,11 @@ import java.io.ObjectStreamException; import java.io.Serializable; import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.InetAddress; @@ -281,7 +286,7 @@ public static Type getConverterType(Class clazz) { * @return the implicit converter for the given type class, or {@code null} if none exists */ public static Converter getImplicitConverter(Class type) { - return ImplicitConverters.getConverter(type); + return Implicit.getConverter(type); } /** @@ -1128,4 +1133,205 @@ private void processEntry(Map map, String key, String value) { map.put(keyConverter.convert(key), valueConverter.convert(value)); } } + + static class Implicit { + + @SuppressWarnings("unchecked") + static Converter getConverter(Class clazz) { + if (clazz.isEnum()) { + return new HyphenateEnumConverter(clazz); + } + + // implicit converters required by the specification + Converter converter = getConverterFromStaticMethod(clazz, "of", String.class); + if (converter == null) { + converter = getConverterFromStaticMethod(clazz, "of", CharSequence.class); + if (converter == null) { + converter = getConverterFromStaticMethod(clazz, "valueOf", String.class); + if (converter == null) { + converter = getConverterFromStaticMethod(clazz, "valueOf", CharSequence.class); + if (converter == null) { + converter = getConverterFromStaticMethod(clazz, "parse", String.class); + if (converter == null) { + converter = getConverterFromStaticMethod(clazz, "parse", CharSequence.class); + if (converter == null) { + converter = getConverterFromConstructor(clazz, String.class); + if (converter == null) { + converter = getConverterFromConstructor(clazz, CharSequence.class); + } + } + } + } + } + } + } + return converter; + } + + private static Converter getConverterFromConstructor(Class clazz, Class paramType) { + try { + final Constructor declaredConstructor = SecuritySupport.getDeclaredConstructor(clazz, paramType); + if (!isAccessible(declaredConstructor)) { + SecuritySupport.setAccessible(declaredConstructor, true); + } + return new ConstructorConverter<>(declaredConstructor); + } catch (NoSuchMethodException e) { + return null; + } + } + + private static Converter getConverterFromStaticMethod(Class clazz, String methodName, + Class paramType) { + try { + final Method method = clazz.getMethod(methodName, paramType); + if (clazz != method.getReturnType()) { + // doesn't meet requirements of the spec + return null; + } + if (!Modifier.isStatic(method.getModifiers())) { + return null; + } + if (!isAccessible(method)) { + SecuritySupport.setAccessible(method, true); + } + return new StaticMethodConverter<>(clazz, method); + } catch (NoSuchMethodException e) { + return null; + } + } + + private static boolean isAccessible(Executable e) { + return Modifier.isPublic(e.getModifiers()) && Modifier.isPublic(e.getDeclaringClass().getModifiers()) || + e.isAccessible(); + } + + static class StaticMethodConverter implements Converter, Serializable { + + private static final long serialVersionUID = 3350265927359848883L; + + private final Class clazz; + private final Method method; + + StaticMethodConverter(Class clazz, Method method) { + assert clazz == method.getReturnType(); + this.clazz = clazz; + this.method = method; + } + + @Override + public T convert(String value) { + if (value.isEmpty()) { + return null; + } + try { + return clazz.cast(method.invoke(null, value)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw ConfigMessages.msg.staticMethodConverterFailure(e); + } + } + + Object writeReplace() { + return new Serialized(method.getDeclaringClass(), method.getName(), method.getParameterTypes()[0]); + } + + static final class Serialized implements Serializable { + private static final long serialVersionUID = -6334004040897615452L; + + private final Class c; + @SuppressWarnings("unused") + private final String m; + @SuppressWarnings("unused") + private final Class p; + + Serialized(final Class c, final String m, final Class p) { + this.c = c; + this.m = m; + this.p = p; + } + + Object readResolve() throws ObjectStreamException { + return getConverter(c); + } + } + } + + static class ConstructorConverter implements Converter, Serializable { + + private static final long serialVersionUID = 3350265927359848883L; + + private final Constructor ctor; + + public ConstructorConverter(final Constructor ctor) { + this.ctor = ctor; + } + + @Override + public T convert(String value) { + if (value.isEmpty()) { + return null; + } + try { + return ctor.newInstance(value); + } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { + throw ConfigMessages.msg.constructorConverterFailure(e); + } + } + + Object writeReplace() { + return new Serialized(ctor.getDeclaringClass(), ctor.getParameterTypes()[0]); + } + + static final class Serialized implements Serializable { + private static final long serialVersionUID = -2903564775826815453L; + + private final Class c; + @SuppressWarnings("unused") + private final Class p; + + Serialized(final Class c, final Class p) { + this.c = c; + this.p = p; + } + + Object readResolve() throws ObjectStreamException { + return getConverter(c); + } + } + } + + static class HyphenateEnumConverter> implements Converter, Serializable { + private static final long serialVersionUID = -8298320652413719873L; + + private final Class enumType; + private final Map values = new HashMap<>(); + + public HyphenateEnumConverter(final Class enumType) { + this.enumType = enumType; + for (E enumValue : this.enumType.getEnumConstants()) { + values.put(hyphenate(enumValue.name()), enumValue); + } + } + + @Override + public E convert(final String value) throws IllegalArgumentException, NullPointerException { + final String trimmedValue = value.trim(); + if (trimmedValue.isEmpty()) { + return null; + } + + final String hyphenatedValue = hyphenate(trimmedValue); + final Enum enumValue = values.get(hyphenatedValue); + + if (enumValue != null) { + return enumType.cast(enumValue); + } + + throw ConfigMessages.msg.cannotConvertEnum(value, enumType, String.join(",", values.keySet())); + } + + private static String hyphenate(String value) { + return StringUtil.skewer(value); + } + } + } } diff --git a/implementation/src/main/java/io/smallrye/config/ImplicitConverters.java b/implementation/src/main/java/io/smallrye/config/ImplicitConverters.java deleted file mode 100644 index a3fc35339..000000000 --- a/implementation/src/main/java/io/smallrye/config/ImplicitConverters.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2017 Red Hat, Inc. - * - * 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.smallrye.config; - -import java.io.ObjectStreamException; -import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.microprofile.config.spi.Converter; - -import io.smallrye.config._private.ConfigMessages; -import io.smallrye.config.common.utils.StringUtil; - -/** - * Based on GERONIMO-6595 support implicit converters. - * - * @author Jeff Mesnil (c) 2017 Red Hat inc. - */ -class ImplicitConverters { - - private ImplicitConverters() { - } - - @SuppressWarnings("unchecked") - static Converter getConverter(Class clazz) { - if (clazz.isEnum()) { - return new HyphenateEnumConverter(clazz); - } - - // implicit converters required by the specification - Converter converter = getConverterFromStaticMethod(clazz, "of", String.class); - if (converter == null) { - converter = getConverterFromStaticMethod(clazz, "of", CharSequence.class); - if (converter == null) { - converter = getConverterFromStaticMethod(clazz, "valueOf", String.class); - if (converter == null) { - converter = getConverterFromStaticMethod(clazz, "valueOf", CharSequence.class); - if (converter == null) { - converter = getConverterFromStaticMethod(clazz, "parse", String.class); - if (converter == null) { - converter = getConverterFromStaticMethod(clazz, "parse", CharSequence.class); - if (converter == null) { - converter = getConverterFromConstructor(clazz, String.class); - if (converter == null) { - converter = getConverterFromConstructor(clazz, CharSequence.class); - } - } - } - } - } - } - } - return converter; - } - - private static Converter getConverterFromConstructor(Class clazz, Class paramType) { - try { - final Constructor declaredConstructor = SecuritySupport.getDeclaredConstructor(clazz, paramType); - if (!isAccessible(declaredConstructor)) { - SecuritySupport.setAccessible(declaredConstructor, true); - } - return new ConstructorConverter<>(declaredConstructor); - } catch (NoSuchMethodException e) { - return null; - } - } - - private static Converter getConverterFromStaticMethod(Class clazz, String methodName, - Class paramType) { - try { - final Method method = clazz.getMethod(methodName, paramType); - if (clazz != method.getReturnType()) { - // doesn't meet requirements of the spec - return null; - } - if (!Modifier.isStatic(method.getModifiers())) { - return null; - } - if (!isAccessible(method)) { - SecuritySupport.setAccessible(method, true); - } - return new StaticMethodConverter<>(clazz, method); - } catch (NoSuchMethodException e) { - return null; - } - } - - private static boolean isAccessible(Executable e) { - return Modifier.isPublic(e.getModifiers()) && Modifier.isPublic(e.getDeclaringClass().getModifiers()) || - e.isAccessible(); - } - - static class StaticMethodConverter implements Converter, Serializable { - - private static final long serialVersionUID = 3350265927359848883L; - - private final Class clazz; - private final Method method; - - StaticMethodConverter(Class clazz, Method method) { - assert clazz == method.getReturnType(); - this.clazz = clazz; - this.method = method; - } - - @Override - public T convert(String value) { - if (value.isEmpty()) { - return null; - } - try { - return clazz.cast(method.invoke(null, value)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw ConfigMessages.msg.staticMethodConverterFailure(e); - } - } - - Object writeReplace() { - return new Serialized(method.getDeclaringClass(), method.getName(), method.getParameterTypes()[0]); - } - - static final class Serialized implements Serializable { - private static final long serialVersionUID = -6334004040897615452L; - - private final Class c; - @SuppressWarnings("unused") - private final String m; - @SuppressWarnings("unused") - private final Class p; - - Serialized(final Class c, final String m, final Class p) { - this.c = c; - this.m = m; - this.p = p; - } - - Object readResolve() throws ObjectStreamException { - return getConverter(c); - } - } - } - - static class ConstructorConverter implements Converter, Serializable { - - private static final long serialVersionUID = 3350265927359848883L; - - private final Constructor ctor; - - public ConstructorConverter(final Constructor ctor) { - this.ctor = ctor; - } - - @Override - public T convert(String value) { - if (value.isEmpty()) { - return null; - } - try { - return ctor.newInstance(value); - } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { - throw ConfigMessages.msg.constructorConverterFailure(e); - } - } - - Object writeReplace() { - return new Serialized(ctor.getDeclaringClass(), ctor.getParameterTypes()[0]); - } - - static final class Serialized implements Serializable { - private static final long serialVersionUID = -2903564775826815453L; - - private final Class c; - @SuppressWarnings("unused") - private final Class p; - - Serialized(final Class c, final Class p) { - this.c = c; - this.p = p; - } - - Object readResolve() throws ObjectStreamException { - return getConverter(c); - } - } - } - - static class HyphenateEnumConverter> implements Converter, Serializable { - private static final long serialVersionUID = -8298320652413719873L; - - private final Class enumType; - private final Map values = new HashMap<>(); - - public HyphenateEnumConverter(final Class enumType) { - this.enumType = enumType; - for (E enumValue : this.enumType.getEnumConstants()) { - values.put(hyphenate(enumValue.name()), enumValue); - } - } - - @Override - public E convert(final String value) throws IllegalArgumentException, NullPointerException { - final String trimmedValue = value.trim(); - if (trimmedValue.isEmpty()) { - return null; - } - - final String hyphenatedValue = hyphenate(trimmedValue); - final Enum enumValue = values.get(hyphenatedValue); - - if (enumValue != null) { - return enumType.cast(enumValue); - } - - throw ConfigMessages.msg.cannotConvertEnum(value, enumType, String.join(",", values.keySet())); - } - - private static String hyphenate(String value) { - return StringUtil.skewer(value); - } - } -} diff --git a/implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java b/implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java index 92559d2d9..1a4b2a56a 100644 --- a/implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java +++ b/implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java @@ -58,7 +58,6 @@ import io.smallrye.common.annotation.Experimental; import io.smallrye.config.SmallRyeConfigBuilder.InterceptorWithPriority; -import io.smallrye.config.SmallRyeConfigSourceInterceptorContext.InterceptorChain; import io.smallrye.config._private.ConfigLogging; import io.smallrye.config._private.ConfigMessages; import io.smallrye.config.common.utils.StringUtil; @@ -772,7 +771,7 @@ Converter getConverterOrNull(Class asType) { final Converter conv = getConverterOrNull(asType.getComponentType()); return conv == null ? null : Converters.newArrayConverter(conv, asType); } - return (Converter) converters.computeIfAbsent(asType, clazz -> ImplicitConverters.getConverter((Class) clazz)); + return (Converter) converters.computeIfAbsent(asType, clazz -> Converters.Implicit.getConverter((Class) clazz)); } @Override @@ -817,7 +816,7 @@ private static class ConfigSources implements Serializable { List interceptorWithPriorities = buildInterceptors(builder); // Create the initial chain with initial sources and all interceptors - InterceptorChain chain = new InterceptorChain(); + SmallRyeConfigSourceInterceptorContext.InterceptorChain chain = new SmallRyeConfigSourceInterceptorContext.InterceptorChain(); SmallRyeConfigSourceInterceptorContext current = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, chain); current = new SmallRyeConfigSourceInterceptorContext(negativeSources, current, chain); @@ -952,7 +951,7 @@ private static List mapLateSources( Collections.reverse(currentSources); // Rebuild the chain with the profiles sources, so profiles values are also available in factories - InterceptorChain chain = new InterceptorChain(); + SmallRyeConfigSourceInterceptorContext.InterceptorChain chain = new SmallRyeConfigSourceInterceptorContext.InterceptorChain(); ConfigSourceInterceptorContext context = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, chain); context = new SmallRyeConfigSourceInterceptorContext(new SmallRyeConfigSources(currentSources, true), context, chain); @@ -1132,6 +1131,81 @@ public Iterator iterateNames() { } } + private static class SmallRyeConfigSourceInterceptorContext implements ConfigSourceInterceptorContext { + private static final long serialVersionUID = 6654406739008729337L; + + private final ConfigSourceInterceptor interceptor; + private final ConfigSourceInterceptorContext next; + private final InterceptorChain chain; + + private static final ThreadLocal rcHolder = ThreadLocal.withInitial(RecursionCount::new); + + SmallRyeConfigSourceInterceptorContext( + final ConfigSourceInterceptor interceptor, + final ConfigSourceInterceptorContext next, + final InterceptorChain chain) { + this.interceptor = interceptor; + this.next = next; + this.chain = chain.setChain(this); + } + + @Override + public ConfigValue proceed(final String name) { + return interceptor.getValue(next, name); + } + + @Override + public ConfigValue restart(final String name) { + RecursionCount rc = rcHolder.get(); + rc.increment(); + try { + return chain.get().proceed(name); + } finally { + if (rc.decrement()) { + // avoid leaking if the thread is cached + rcHolder.remove(); + } + } + } + + @Override + public Iterator iterateNames() { + return interceptor.iterateNames(next); + } + + static class InterceptorChain implements Supplier, Serializable { + private static final long serialVersionUID = 7387475787257736307L; + + private ConfigSourceInterceptorContext chain; + + @Override + public ConfigSourceInterceptorContext get() { + return chain; + } + + public InterceptorChain setChain(final ConfigSourceInterceptorContext chain) { + this.chain = chain; + return this; + } + } + + static final class RecursionCount { + int count; + + void increment() { + int old = count; + if (old == 20) { + throw new IllegalStateException("Too many recursive interceptor actions"); + } + count = old + 1; + } + + boolean decrement() { + return --count == 0; + } + } + } + private Object writeReplace() throws ObjectStreamException { return RegisteredConfig.instance; } diff --git a/implementation/src/main/java/io/smallrye/config/SmallRyeConfigBuilder.java b/implementation/src/main/java/io/smallrye/config/SmallRyeConfigBuilder.java index b9676398f..a155c1a19 100644 --- a/implementation/src/main/java/io/smallrye/config/SmallRyeConfigBuilder.java +++ b/implementation/src/main/java/io/smallrye/config/SmallRyeConfigBuilder.java @@ -770,7 +770,7 @@ MappingBuilder mapping(Class type, String prefix) { Assert.checkNotNullParam("path", prefix); Class mappingClass = getConfigMappingClass(type); // It is an MP ConfigProperties, so ignore unmapped properties - if (ConfigMappingClass.getConfigurationClass(type) != null) { + if (ConfigMappingLoader.ConfigMappingClass.getConfigurationClass(type) != null) { ignoredPaths.add(prefix.isEmpty() ? "*" : prefix + ".**"); } mappings.computeIfAbsent(mappingClass, k -> new HashSet<>(4)).add(prefix); diff --git a/implementation/src/main/java/io/smallrye/config/SmallRyeConfigSourceInterceptorContext.java b/implementation/src/main/java/io/smallrye/config/SmallRyeConfigSourceInterceptorContext.java deleted file mode 100644 index bcd5c567d..000000000 --- a/implementation/src/main/java/io/smallrye/config/SmallRyeConfigSourceInterceptorContext.java +++ /dev/null @@ -1,80 +0,0 @@ -package io.smallrye.config; - -import java.io.Serializable; -import java.util.Iterator; -import java.util.function.Supplier; - -class SmallRyeConfigSourceInterceptorContext implements ConfigSourceInterceptorContext { - private static final long serialVersionUID = 6654406739008729337L; - - private final ConfigSourceInterceptor interceptor; - private final ConfigSourceInterceptorContext next; - private final InterceptorChain chain; - - private static final ThreadLocal rcHolder = ThreadLocal.withInitial(RecursionCount::new); - - SmallRyeConfigSourceInterceptorContext( - final ConfigSourceInterceptor interceptor, - final ConfigSourceInterceptorContext next, - final InterceptorChain chain) { - this.interceptor = interceptor; - this.next = next; - this.chain = chain.setChain(this); - } - - @Override - public ConfigValue proceed(final String name) { - return interceptor.getValue(next, name); - } - - @Override - public ConfigValue restart(final String name) { - RecursionCount rc = rcHolder.get(); - rc.increment(); - try { - return chain.get().proceed(name); - } finally { - if (rc.decrement()) { - // avoid leaking if the thread is cached - rcHolder.remove(); - } - } - } - - @Override - public Iterator iterateNames() { - return interceptor.iterateNames(next); - } - - static class InterceptorChain implements Supplier, Serializable { - private static final long serialVersionUID = 7387475787257736307L; - - private ConfigSourceInterceptorContext chain; - - @Override - public ConfigSourceInterceptorContext get() { - return chain; - } - - public InterceptorChain setChain(final ConfigSourceInterceptorContext chain) { - this.chain = chain; - return this; - } - } - - static final class RecursionCount { - int count; - - void increment() { - int old = count; - if (old == 20) { - throw new IllegalStateException("Too many recursive interceptor actions"); - } - count = old + 1; - } - - boolean decrement() { - return --count == 0; - } - } -} diff --git a/implementation/src/test/java/io/smallrye/config/ImplicitConverterTest.java b/implementation/src/test/java/io/smallrye/config/ImplicitConverterTest.java index 792f1365f..a4ea94470 100644 --- a/implementation/src/test/java/io/smallrye/config/ImplicitConverterTest.java +++ b/implementation/src/test/java/io/smallrye/config/ImplicitConverterTest.java @@ -17,7 +17,7 @@ import org.eclipse.microprofile.config.spi.Converter; import org.junit.jupiter.api.Test; -import io.smallrye.config.ImplicitConverters.HyphenateEnumConverter; +import io.smallrye.config.Converters.Implicit.HyphenateEnumConverter; class ImplicitConverterTest { @Test @@ -46,7 +46,7 @@ void implicitLocalDateConverter() { @Test void serializationOfConstructorConverter() { - Converter converter = ImplicitConverters.getConverter(File.class); + Converter converter = Converters.Implicit.getConverter(File.class); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try (ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream)) {