You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jo...@apache.org on 2017/12/24 03:52:02 UTC
svn commit: r1819198 - in
/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config:
ConfigImpl.java ConfigValueImpl.java DefaultConfigBuilder.java
converters/MicroProfileTypedConverter.java
Author: johndament
Date: Sun Dec 24 03:52:02 2017
New Revision: 1819198
URL: http://svn.apache.org/viewvc?rev=1819198&view=rev
Log:
GERONIMO-6597 Adding support for programmatic registration of converters
Added:
geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java
Modified:
geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java Sun Dec 24 03:52:02 2017
@@ -16,17 +16,16 @@
*/
package org.apache.geronimo.config;
+import org.apache.geronimo.config.converters.ImplicitConverter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.Converter;
+
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
import java.lang.reflect.Array;
-import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.net.URL;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -40,30 +39,6 @@ import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import org.apache.geronimo.config.converters.BooleanConverter;
-import org.apache.geronimo.config.converters.ClassConverter;
-import org.apache.geronimo.config.converters.DoubleConverter;
-import org.apache.geronimo.config.converters.DurationConverter;
-import org.apache.geronimo.config.converters.FloatConverter;
-import org.apache.geronimo.config.converters.ImplicitConverter;
-import org.apache.geronimo.config.converters.InstantConverter;
-import org.apache.geronimo.config.converters.IntegerConverter;
-import org.apache.geronimo.config.converters.LocalDateConverter;
-import org.apache.geronimo.config.converters.LocalDateTimeConverter;
-import org.apache.geronimo.config.converters.LocalTimeConverter;
-import org.apache.geronimo.config.converters.LongConverter;
-import org.apache.geronimo.config.converters.OffsetDateTimeConverter;
-import org.apache.geronimo.config.converters.OffsetTimeConverter;
-import org.apache.geronimo.config.converters.StringConverter;
-import org.apache.geronimo.config.converters.URLConverter;
-import org.eclipse.microprofile.config.Config;
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.eclipse.microprofile.config.spi.Converter;
-
-import javax.annotation.Priority;
-import javax.enterprise.inject.Typed;
-import javax.enterprise.inject.Vetoed;
-
/**
* @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
* @author <a href="mailto:johndament@apache.org">John D. Ament</a>
@@ -74,40 +49,10 @@ public class ConfigImpl implements Confi
protected Logger logger = Logger.getLogger(ConfigImpl.class.getName());
protected final List<ConfigSource> configSources = new ArrayList<>();
- protected final Map<Type, Converter> converters = new HashMap<>();
+ protected final Map<Type, MicroProfileTypedConverter> converters = new HashMap<>();
protected final Map<Type, Converter> implicitConverters = new ConcurrentHashMap<>();
private static final String ARRAY_SEPARATOR_REGEX = "(?<!\\\\)" + Pattern.quote(",");
- public ConfigImpl() {
- registerDefaultConverter();
- }
-
- private void registerDefaultConverter() {
- converters.put(String.class, StringConverter.INSTANCE);
- converters.put(Boolean.class, BooleanConverter.INSTANCE);
- converters.put(boolean.class, BooleanConverter.INSTANCE);
- converters.put(Double.class, DoubleConverter.INSTANCE);
- converters.put(double.class, DoubleConverter.INSTANCE);
- converters.put(Float.class, FloatConverter.INSTANCE);
- converters.put(float.class, FloatConverter.INSTANCE);
- converters.put(Integer.class, IntegerConverter.INSTANCE);
- converters.put(int.class, IntegerConverter.INSTANCE);
- converters.put(Long.class, LongConverter.INSTANCE);
- converters.put(long.class, LongConverter.INSTANCE);
-
- converters.put(Duration.class, DurationConverter.INSTANCE);
- converters.put(LocalTime.class, LocalTimeConverter.INSTANCE);
- converters.put(LocalDate.class, LocalDateConverter.INSTANCE);
- converters.put(LocalDateTime.class, LocalDateTimeConverter.INSTANCE);
- converters.put(OffsetTime.class, OffsetTimeConverter.INSTANCE);
- converters.put(OffsetDateTime.class, OffsetDateTimeConverter.INSTANCE);
- converters.put(Instant.class, InstantConverter.INSTANCE);
-
- converters.put(URL.class, URLConverter.INSTANCE);
- converters.put(Class.class, ClassConverter.INSTANCE);
- }
-
-
@Override
public <T> Optional<T> getOptionalValue(String propertyName, Class<T> asType) {
String value = getValue(propertyName);
@@ -179,7 +124,11 @@ public class ConfigImpl implements Confi
}
private <T> Converter getConverter(Class<T> asType) {
- Converter converter = converters.get(asType);
+ MicroProfileTypedConverter microProfileTypedConverter = converters.get(asType);
+ Converter converter = null;
+ if(microProfileTypedConverter != null) {
+ converter = microProfileTypedConverter.getDelegate();
+ }
if (converter == null) {
converter = getImplicitConverter(asType);
}
@@ -231,34 +180,7 @@ public class ConfigImpl implements Confi
}
}
-
- public synchronized void addConverter(Converter<?> converter) {
- if (converter == null) {
- return;
- }
-
- Type targetType = getTypeOfConverter(converter.getClass());
- if (targetType == null ) {
- throw new IllegalStateException("Converter " + converter.getClass() + " must be a ParameterisedType");
- }
-
- Converter oldConverter = converters.get(targetType);
- if (oldConverter == null || getPriority(converter) > getPriority(oldConverter)) {
- converters.put(targetType, converter);
- }
- }
-
- private int getPriority(Converter<?> converter) {
- int priority = 100;
- Priority priorityAnnotation = converter.getClass().getAnnotation(Priority.class);
- if (priorityAnnotation != null) {
- priority = priorityAnnotation.value();
- }
- return priority;
- }
-
-
- public Map<Type, Converter> getConverters() {
+ public Map<Type, MicroProfileTypedConverter> getConverters() {
return converters;
}
@@ -270,25 +192,7 @@ public class ConfigImpl implements Confi
}
- private Type getTypeOfConverter(Class clazz) {
- if (clazz.equals(Object.class)) {
- return null;
- }
-
- Type[] genericInterfaces = clazz.getGenericInterfaces();
- for (Type genericInterface : genericInterfaces) {
- if (genericInterface instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) genericInterface;
- if (pt.getRawType().equals(Converter.class)) {
- Type[] typeArguments = pt.getActualTypeArguments();
- if (typeArguments.length != 1) {
- throw new IllegalStateException("Converter " + clazz + " must be a ParameterisedType");
- }
- return typeArguments[0];
- }
- }
- }
-
- return getTypeOfConverter(clazz.getSuperclass());
+ public void addConverter(Type type, MicroProfileTypedConverter<?> converter) {
+ converters.put(type, converter);
}
}
\ No newline at end of file
Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java Sun Dec 24 03:52:02 2017
@@ -16,8 +16,9 @@
*/
package org.apache.geronimo.config;
-import org.eclipse.microprofile.config.spi.Converter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
+import javax.enterprise.inject.Typed;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
@@ -25,8 +26,6 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
-import javax.enterprise.inject.Typed;
-
/**
* @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
*/
@@ -219,7 +218,7 @@ public class ConfigValueImpl<T> {
return (T) value;
}
- Converter converter = config.getConverters().get(configEntryType);
+ MicroProfileTypedConverter converter = config.getConverters().get(configEntryType);
if (converter == null) {
throw new IllegalStateException("No Converter for type " + configEntryType);
}
Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java Sun Dec 24 03:52:02 2017
@@ -16,6 +16,22 @@
*/
package org.apache.geronimo.config;
+import org.apache.geronimo.config.converters.BooleanConverter;
+import org.apache.geronimo.config.converters.ClassConverter;
+import org.apache.geronimo.config.converters.DoubleConverter;
+import org.apache.geronimo.config.converters.DurationConverter;
+import org.apache.geronimo.config.converters.FloatConverter;
+import org.apache.geronimo.config.converters.InstantConverter;
+import org.apache.geronimo.config.converters.IntegerConverter;
+import org.apache.geronimo.config.converters.LocalDateConverter;
+import org.apache.geronimo.config.converters.LocalDateTimeConverter;
+import org.apache.geronimo.config.converters.LocalTimeConverter;
+import org.apache.geronimo.config.converters.LongConverter;
+import org.apache.geronimo.config.converters.OffsetDateTimeConverter;
+import org.apache.geronimo.config.converters.OffsetTimeConverter;
+import org.apache.geronimo.config.converters.StringConverter;
+import org.apache.geronimo.config.converters.URLConverter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
import org.eclipse.microprofile.config.spi.ConfigSource;
@@ -25,9 +41,21 @@ import org.apache.geronimo.config.config
import org.apache.geronimo.config.configsource.SystemEnvConfigSource;
import org.apache.geronimo.config.configsource.SystemPropertyConfigSource;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.ServiceLoader;
import javax.enterprise.inject.Typed;
@@ -42,12 +70,16 @@ import static java.util.Arrays.asList;
@Typed
@Vetoed
public class DefaultConfigBuilder implements ConfigBuilder {
- protected ClassLoader forClassLoader;
+ private ClassLoader forClassLoader;
private final List<ConfigSource> sources = new ArrayList<>();
- private final List<Converter<?>> converters = new ArrayList<>();
private boolean ignoreDefaultSources = true;
private boolean ignoreDiscoveredSources = true;
private boolean ignoreDiscoveredConverters = true;
+ private final Map<Type, MicroProfileTypedConverter<?>> wrappedConverters = new HashMap<>();
+
+ public DefaultConfigBuilder() {
+ this.registerDefaultConverters();
+ }
@Override
public ConfigBuilder addDefaultSources() {
@@ -75,12 +107,24 @@ public class DefaultConfigBuilder implem
@Override
public ConfigBuilder withConverters(Converter<?>... converters) {
- this.converters.addAll(asList(converters));
+ for(Converter<?> converter : converters) {
+ Type typeOfConverter = getTypeOfConverter(converter.getClass());
+ registerConverter(typeOfConverter, new MicroProfileTypedConverter<>(converter));
+ }
return this;
}
@Override
public <T> ConfigBuilder withConverter(Class<T> type, int priority, Converter<T> converter) {
+ MicroProfileTypedConverter<T> microProfileTypedConverter = new MicroProfileTypedConverter<T>(converter, priority);
+ return registerConverter(type, microProfileTypedConverter);
+ }
+
+ private <T> ConfigBuilder registerConverter(Type type, MicroProfileTypedConverter<T> microProfileTypedConverter) {
+ MicroProfileTypedConverter<?> existing = wrappedConverters.get(type);
+ if(existing == null || microProfileTypedConverter.getPriority() > existing.getPriority()) {
+ wrappedConverters.put(type, microProfileTypedConverter);
+ }
return this;
}
@@ -119,14 +163,14 @@ public class DefaultConfigBuilder implem
if (!ignoreDiscoveredConverters) {
ServiceLoader<Converter> converterLoader = ServiceLoader.load(Converter.class, forClassLoader);
- converterLoader.forEach(converters::add);
+ converterLoader.forEach(this::withConverters);
}
ConfigImpl config = new ConfigImpl();
config.addConfigSources(configSources);
- for (Converter<?> converter : converters) {
- config.addConverter(converter);
+ for (Map.Entry<Type, MicroProfileTypedConverter<?>> entry : wrappedConverters.entrySet()) {
+ config.addConverter(entry.getKey(), entry.getValue());
}
return config;
@@ -141,4 +185,51 @@ public class DefaultConfigBuilder implem
return configSources;
}
+
+ private void registerDefaultConverters() {
+ wrappedConverters.put(String.class, new MicroProfileTypedConverter<>(StringConverter.INSTANCE));
+ wrappedConverters.put(Boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+ wrappedConverters.put(boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+ wrappedConverters.put(Double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+ wrappedConverters.put(double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+ wrappedConverters.put(Float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+ wrappedConverters.put(float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+ wrappedConverters.put(Integer.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+ wrappedConverters.put(int.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+ wrappedConverters.put(Long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+ wrappedConverters.put(long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+
+ wrappedConverters.put(Duration.class, new MicroProfileTypedConverter<>(DurationConverter.INSTANCE));
+ wrappedConverters.put(LocalTime.class, new MicroProfileTypedConverter<>(LocalTimeConverter.INSTANCE));
+ wrappedConverters.put(LocalDate.class, new MicroProfileTypedConverter<>(LocalDateConverter.INSTANCE));
+ wrappedConverters.put(LocalDateTime.class, new MicroProfileTypedConverter<>(LocalDateTimeConverter.INSTANCE));
+ wrappedConverters.put(OffsetTime.class, new MicroProfileTypedConverter<>(OffsetTimeConverter.INSTANCE));
+ wrappedConverters.put(OffsetDateTime.class, new MicroProfileTypedConverter<>(OffsetDateTimeConverter.INSTANCE));
+ wrappedConverters.put(Instant.class, new MicroProfileTypedConverter<>(InstantConverter.INSTANCE));
+
+ wrappedConverters.put(URL.class, new MicroProfileTypedConverter<>(URLConverter.INSTANCE));
+ wrappedConverters.put(Class.class, new MicroProfileTypedConverter<>(ClassConverter.INSTANCE));
+ }
+
+ private Type getTypeOfConverter(Class clazz) {
+ if (clazz.equals(Object.class)) {
+ return null;
+ }
+
+ Type[] genericInterfaces = clazz.getGenericInterfaces();
+ for (Type genericInterface : genericInterfaces) {
+ if (genericInterface instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) genericInterface;
+ if (pt.getRawType().equals(Converter.class)) {
+ Type[] typeArguments = pt.getActualTypeArguments();
+ if (typeArguments.length != 1) {
+ throw new IllegalStateException("Converter " + clazz + " must be a ParameterisedType");
+ }
+ return typeArguments[0];
+ }
+ }
+ }
+
+ return getTypeOfConverter(clazz.getSuperclass());
+ }
}
Added: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java?rev=1819198&view=auto
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java (added)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java Sun Dec 24 03:52:02 2017
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.geronimo.config.converters;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+import javax.annotation.Priority;
+
+public class MicroProfileTypedConverter<T> {
+ private final Converter<T> delegate;
+ private final int priority;
+
+ public MicroProfileTypedConverter(Converter<T> delegate) {
+ this(delegate, readPriority(delegate));
+ }
+
+ public MicroProfileTypedConverter(Converter<T> delegate, int priority) {
+ this.delegate = delegate;
+ this.priority = priority;
+ }
+
+ public Converter<T> getDelegate() {
+ return delegate;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ private static <T> int readPriority(Converter<T> delegate) {
+ Priority priority = delegate.getClass().getAnnotation(Priority.class);
+ if(priority != null) {
+ return priority.value();
+ } else {
+ return 100;
+ }
+ }
+
+ public T convert(String value) {
+ return delegate.convert(value);
+ }
+}