Skip to content

Commit

Permalink
Added ConfigBuilder implementation, enabled all tests
Browse files Browse the repository at this point in the history
  • Loading branch information
urbim committed Jul 31, 2018
1 parent 139fd7e commit 14d2352
Show file tree
Hide file tree
Showing 12 changed files with 509 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2014-2017 Kumuluz and/or its affiliates
* and other contributors as indicated by the @author tags and
* the contributor list.
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*
* The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. in no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the software or the use or other dealings in the
* software. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.kumuluz.ee.config.microprofile;

import com.kumuluz.ee.config.microprofile.adapters.ConfigSourceAdapter;
import com.kumuluz.ee.config.microprofile.converters.*;
import com.kumuluz.ee.config.microprofile.utils.ConverterWithOrdinal;
import com.kumuluz.ee.configuration.sources.EnvironmentConfigurationSource;
import com.kumuluz.ee.configuration.sources.FileConfigurationSource;
import com.kumuluz.ee.configuration.sources.SystemPropertyConfigurationSource;
import com.kumuluz.ee.configuration.utils.ConfigurationUtil;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.config.spi.Converter;

import javax.annotation.Priority;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
* Implementation of {@link ConfigBuilder}.
*
* @author Urban Malc
* @since 1.3
*/
public class ConfigBuilderImpl implements ConfigBuilder {

private static final List<Class> defaultSources = Arrays.asList(new Class[] {
SystemPropertyConfigurationSource.class,
EnvironmentConfigurationSource.class,
FileConfigurationSource.class
});
private static final ConfigurationUtil configurationUtil = ConfigurationUtil.getInstance();

private Map<Type, ConverterWithOrdinal> converters;
private List<ConfigSource> configSources;

public ConfigBuilderImpl() {
this.configSources = new ArrayList<>();
this.converters = new HashMap<>();
converters.put(Boolean.class, getConverterWithOrdinalAnnotation(BooleanConverter.INSTANCE));
converters.put(Integer.class, getConverterWithOrdinalAnnotation(IntegerConverter.INSTANCE));
converters.put(Long.class, getConverterWithOrdinalAnnotation(LongConverter.INSTANCE));
converters.put(Float.class, getConverterWithOrdinalAnnotation(FloatConverter.INSTANCE));
converters.put(Double.class, getConverterWithOrdinalAnnotation(DoubleConverter.INSTANCE));
converters.put(Class.class, getConverterWithOrdinalAnnotation(ClassConverter.INSTANCE));
}

@Override
public ConfigBuilder addDefaultSources() {
configurationUtil.getConfigurationSources().stream()
.filter((cs) -> defaultSources.contains(cs.getClass()))
.map(ConfigSourceAdapter::new)
.forEach((cs) -> configSources.add(cs));

return this;
}

@Override
public ConfigBuilder addDiscoveredSources() {
configurationUtil.getConfigurationSources().stream()
.filter((cs) -> !defaultSources.contains(cs.getClass()))
.map(ConfigSourceAdapter::new)
.forEach((cs) -> configSources.add(cs));

return this;
}

@Override
public ConfigBuilder addDiscoveredConverters() {
// load Converters
ServiceLoader<Converter> serviceLoader = ServiceLoader.load(Converter.class);

for (Converter converter : serviceLoader) {
withConverters(converter);
}

return this;
}

@Override
public ConfigBuilder forClassLoader(ClassLoader classLoader) {
return this;
}

@Override
public ConfigBuilder withSources(ConfigSource... configSources) {
this.configSources.addAll(Arrays.asList(configSources));

return this;
}

@Override
public ConfigBuilder withConverters(Converter<?>... converters) {
for (Converter converter : converters) {
Type types[] = converter.getClass().getGenericInterfaces();
for (Type type : types) {
if (type instanceof ParameterizedType) {
Type args[] = ((ParameterizedType) type).getActualTypeArguments();
if (args.length == 1) {
Type cType = args[0];
int ordinal = getConverterOrdinal(converter);
withConverter((Class)cType, ordinal, converter);
}
}
}
}

return this;
}

@Override
public <T> ConfigBuilder withConverter(Class<T> cType, int newOrdinal, Converter<T> converter) {
ConverterWithOrdinal old = converters.get(cType);
if (old == null || newOrdinal > old.getOrdinal()) {
this.converters.put(cType, new ConverterWithOrdinal(converter, newOrdinal));
}

return this;
}

@Override
public Config build() {
this.configSources.sort(Comparator.comparingInt(ConfigSource::getOrdinal).reversed());
Map<Type, Converter> actualConverters = new HashMap<>();
this.converters.forEach((key, value) -> actualConverters.put(key, value.getConverter()));

return new ConfigImpl(this.configSources, actualConverters);
}

private ConverterWithOrdinal getConverterWithOrdinalAnnotation(Converter converter) {
return new ConverterWithOrdinal(converter, getConverterOrdinal(converter));
}

private int getConverterOrdinal(Converter converter) {

int result = 100;
Priority annotation = converter.getClass().getAnnotation(Priority.class);
if (annotation != null) {
result = annotation.value();
}
return result;
}
}
85 changes: 17 additions & 68 deletions src/main/java/com/kumuluz/ee/config/microprofile/ConfigImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@
*/
package com.kumuluz.ee.config.microprofile;

import com.kumuluz.ee.config.microprofile.converters.*;
import com.kumuluz.ee.configuration.utils.ConfigurationUtil;
import com.kumuluz.ee.config.microprofile.converters.ImplicitConverter;
import com.kumuluz.ee.config.microprofile.utils.AlternativeTypesUtil;
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 java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.regex.Pattern;
Expand All @@ -43,67 +41,28 @@
*/
public class ConfigImpl implements Config, Serializable {

private Map<Type, Converter> converters = new HashMap<>();
private ConfigurationUtil configurationUtil = ConfigurationUtil.getInstance();
private Map<Type, Converter> converters;
private List<ConfigSource> configSources;

private static final String ARRAY_SEPARATOR_REGEX = "(?<!\\\\)" + Pattern.quote(",");

public ConfigImpl() {
registerDefaultConverters();
registerDiscoveredConverters();
public ConfigImpl(List<ConfigSource> configSources, Map<Type, Converter> converters) {
this.configSources = configSources;
this.converters = converters;
}

private void registerDefaultConverters() {
@Override
public <T> Optional<T> getOptionalValue(String propertyName, Class<T> asType) {

// build-in converters according to specification
converters.put(Boolean.class, BooleanConverter.INSTANCE);
converters.put(Integer.class, IntegerConverter.INSTANCE);
converters.put(Long.class, LongConverter.INSTANCE);
converters.put(Float.class, FloatConverter.INSTANCE);
converters.put(Double.class, DoubleConverter.INSTANCE);
converters.put(Class.class, ClassConverter.INSTANCE);
}
String value = null;

for (ConfigSource cs : this.configSources) {
value = cs.getValue(propertyName);

private void registerDiscoveredConverters() {

// load Converters
ServiceLoader<Converter> serviceLoader = ServiceLoader.load(Converter.class);

for (Converter converter : serviceLoader) {
Type types[] = converter.getClass().getGenericInterfaces();
for (Type type : types) {
if (type instanceof ParameterizedType) {
Type args[] = ((ParameterizedType) type).getActualTypeArguments();
if (args.length == 1) {
Type cType = args[0];
Converter old = converters.get(cType);
if (old != null) {
if (getPriority(converter) > getPriority(old)) {
this.converters.put(cType, converter);
}
} else {
this.converters.put(cType, converter);
}
}
}
if (value != null) {
break;
}
}
}

private int getPriority(Converter converter) {

int result = 100;
Priority annotation = converter.getClass().getAnnotation(Priority.class);
if (annotation != null) {
result = annotation.value();
}
return result;
}

@Override
public <T> Optional<T> getOptionalValue(String propertyName, Class<T> asType) {

String value = configurationUtil.get(propertyName).orElse(null);

T convertedValue;
try {
Expand Down Expand Up @@ -168,17 +127,7 @@ public <T> List<T> convertList(String value, Class<T> listType) {
@SuppressWarnings("unchecked")
private <T> Converter<T> getConverter(Class asType) {

if (asType.equals(boolean.class)) {
asType = Boolean.class;
} else if (asType.equals(double.class)) {
asType = Double.class;
} else if (asType.equals(float.class)) {
asType = Float.class;
} else if (asType.equals(int.class)) {
asType = Integer.class;
} else if (asType.equals(long.class)) {
asType = Long.class;
}
asType = (Class) AlternativeTypesUtil.getTypeFromPrimitive(asType).orElse(asType);

Converter converter = converters.get(asType);

Expand All @@ -202,6 +151,6 @@ public Iterable<String> getPropertyNames() {

@Override
public Iterable<ConfigSource> getConfigSources() {
return null;
return this.configSources;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public Config getConfig() {
public Config getConfig(ClassLoader forClassLoader) {

if (instance == null) {
instance = new ConfigImpl();
instance = getBuilder().addDefaultSources().addDiscoveredSources().addDiscoveredConverters().build();
}

return instance;
Expand All @@ -59,7 +59,7 @@ public void registerConfig(Config config, ClassLoader forClassLoader) {

@Override
public ConfigBuilder getBuilder() {
return null;
return new ConfigBuilderImpl();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.kumuluz.ee.common.dependencies.EeExtensionDef;
import com.kumuluz.ee.common.dependencies.EeExtensionGroup;
import com.kumuluz.ee.common.wrapper.KumuluzServerWrapper;
import com.kumuluz.ee.config.microprofile.adapters.ConfigurationSourceAdapter;
import com.kumuluz.ee.configuration.ConfigurationSource;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
Expand Down
Loading

0 comments on commit 14d2352

Please sign in to comment.