io.helidon.config.objectmapping.ObjectConfigMapperProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of helidon-config-object-mapping Show documentation
Show all versions of helidon-config-object-mapping Show documentation
Support for loading java pojos from configuration.
The newest version!
/*
* Copyright (c) 2018, 2022 Oracle and/or its affiliates.
*
* 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.helidon.config.objectmapping;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import io.helidon.common.Weight;
import io.helidon.config.Config;
import io.helidon.config.objectmapping.ObjectConfigMappers.BuilderConfigMapper;
import io.helidon.config.objectmapping.ObjectConfigMappers.ConfigMethodHandleConfigMapper;
import io.helidon.config.objectmapping.ObjectConfigMappers.FactoryMethodConfigMapper;
import io.helidon.config.objectmapping.ObjectConfigMappers.GenericConfigMapper;
import io.helidon.config.objectmapping.ObjectConfigMappers.StringMethodHandleConfigMapper;
import io.helidon.config.spi.ConfigMapperProvider;
import static io.helidon.config.objectmapping.ReflectionUtil.findBuilderConstructor;
import static io.helidon.config.objectmapping.ReflectionUtil.findBuilderMethod;
import static io.helidon.config.objectmapping.ReflectionUtil.findConstructor;
import static io.helidon.config.objectmapping.ReflectionUtil.findConstructorWithParameters;
import static io.helidon.config.objectmapping.ReflectionUtil.findStaticMethod;
import static io.helidon.config.objectmapping.ReflectionUtil.findStaticMethodWithParameters;
/**
* Java beans support for configuration.
*/
@Weight(0) // priority should be low to be one of the last ones used
public class ObjectConfigMapperProvider implements ConfigMapperProvider {
private static final String METHOD_FROM = "from";
private static final String METHOD_OF = "of";
private static final String METHOD_VALUE_OF = "valueOf";
private static final String METHOD_FROM_CONFIG = "fromConfig";
private static final String METHOD_FROM_STRING = "fromString";
private static final String METHOD_PARSE = "parse";
private static final String METHOD_CREATE = "create";
@Override
public Map, Function> mappers() {
return Map.of();
}
@Override
public Optional> mapper(Class type) {
return // T create(Config)
findStaticConfigMethodMapper(type, METHOD_CREATE)
// T from(Config)
.or(() -> findStaticConfigMethodMapper(type, METHOD_FROM))
// Config constructor
.or(() -> findConfigConstructorMapper(type))
// T of(Config)
.or(() -> findStaticConfigMethodMapper(type, METHOD_OF))
// T valueOf(Config)
.or(() -> findStaticConfigMethodMapper(type, METHOD_VALUE_OF))
// T fromConfig(Config)
.or(() -> findStaticConfigMethodMapper(type, METHOD_FROM_CONFIG))
// T from(String)
.or(() -> findStaticStringMethodMapper(type, METHOD_FROM))
// T parse(String)
.or(() -> findStaticStringMethodMapper(type, METHOD_PARSE))
// T parse(CharSequence)
.or(() -> findParseCharSequenceMethodMapper(type))
// String constructor
.or(() -> findStringConstructorMapper(type))
// T of(String)
.or(() -> findStaticStringMethodMapper(type, METHOD_OF))
// T valueOf(String)
.or(() -> findStaticStringMethodMapper(type, METHOD_VALUE_OF))
// T fromString(String)
.or(() -> findStaticStringMethodMapper(type, METHOD_FROM_STRING))
// static Builder builder()
.or(() -> findBuilderMethodMapper(type))
// new T.Builder()
.or(() -> findBuilderClassMapper(type))
// static T from(param, params...)
.or(() -> findStaticMethodWithParamsMapper(type, METHOD_FROM))
// static T create(param, params...)
.or(() -> findStaticMethodWithParamsMapper(type, METHOD_CREATE))
// constructor(param, params...)
.or(() -> findConstructorWithParamsMapper(type))
// generic mapping support
.or(() -> findGenericMapper(type));
// we could not find anything, let config decide what to do
}
private static Optional> findStaticConfigMethodMapper(Class type,
String methodName) {
return findStaticMethod(type, methodName, Config.class)
.map(handle -> new ConfigMethodHandleConfigMapper<>(
type,
methodName + "(Config) method",
handle));
}
private static Optional> findStaticStringMethodMapper(Class type,
String methodName) {
Optional method = findStaticMethod(type,
methodName,
String.class);
if (method.isEmpty()) {
method = findStaticMethod(type,
methodName,
CharSequence.class);
}
return method.map(handle -> new StringMethodHandleConfigMapper<>(
type,
methodName + "(String) method",
handle));
}
private static Optional> findParseCharSequenceMethodMapper(Class type) {
return findStaticMethod(type, METHOD_PARSE, CharSequence.class)
.map(handle -> new StringMethodHandleConfigMapper<>(
type,
"parse(CharSequence) method",
handle));
}
private static Optional> findConfigConstructorMapper(Class type) {
return findConstructor(type, Config.class)
.map(handle -> new ConfigMethodHandleConfigMapper<>(type, "Config constructor", handle));
}
private static Optional> findStringConstructorMapper(Class type) {
return findConstructor(type, String.class)
.map(handle -> new StringMethodHandleConfigMapper<>(type, "String constructor", handle));
}
private static Optional> findBuilderMethodMapper(Class type) {
return findBuilderMethod(type)
.map(BuilderConfigMapper::new);
}
private static Optional> findBuilderClassMapper(Class type) {
return findBuilderConstructor(type)
.map(BuilderConfigMapper::new);
}
private static Optional> findStaticMethodWithParamsMapper(Class type, String methodName) {
return findStaticMethodWithParameters(type, methodName)
.map(FactoryMethodConfigMapper::new);
}
private static Optional> findConstructorWithParamsMapper(Class type) {
return findConstructorWithParameters(type)
.map(FactoryMethodConfigMapper::new);
}
private static Optional> findGenericMapper(Class type) {
try {
return findConstructor(type)
.map(methodHandle -> new GenericConfigMapper<>(type, methodHandle));
} catch (IllegalArgumentException e) {
return Optional.empty();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy