ren.crux.common.util.ConfigurationParser Maven / Gradle / Ivy
/*
*
* Copyright 2018 The Crux 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
*
* 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 ren.crux.common.util;
import lombok.NonNull;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.*;
import org.springframework.boot.context.properties.bind.handler.IgnoreErrorsBindHandler;
import org.springframework.boot.context.properties.bind.handler.IgnoreTopLevelConverterNotFoundBindHandler;
import org.springframework.boot.context.properties.bind.handler.NoUnboundElementsBindHandler;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.boot.context.properties.source.UnboundElementsSourceFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.validation.annotation.Validated;
import ren.crux.common.CommonConstants;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Properties;
/**
* Parse sources with Spring Boot Relaxed Binding 2.0
*
* Warning : Not support {@link Validated}
*
* {@link Binder}
* Relaxed-Binding-2.0
*
* @author wangzhihui
*/
public class ConfigurationParser {
private final ApplicationContext applicationContext;
public ConfigurationParser(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public Properties yamlResources2Properties(Resource... resources) {
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resources);
return yamlPropertiesFactoryBean.getObject();
}
public Properties yamlBytes2Properties(byte[] bytes) {
return yamlResources2Properties(new ByteArrayResource(bytes));
}
public Properties bytes2Properties(byte[] bytes) throws IOException {
Properties properties = new Properties();
Reader reader = new StringReader(new String(bytes, CommonConstants.UTF_8_CHARSET));
properties.load(reader);
return properties;
}
public T bind(@NonNull T instance, PlaceholdersResolver placeholdersResolver, ConfigurationPropertySource... sources) {
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(instance.getClass(), ConfigurationProperties.class);
Binder binder = new Binder(Arrays.asList(sources), placeholdersResolver);
return binder.bind(annotation.prefix(), Bindable.ofInstance(instance)).get();
}
public T bind(@NonNull T instance, Properties properties) {
PropertySourcesPlaceholdersResolver placeholdersResolver = new PropertySourcesPlaceholdersResolver(applicationContext.getEnvironment());
MapConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
return bind(instance, placeholdersResolver, source);
}
public T parse(@NonNull Class cls, PlaceholdersResolver placeholdersResolver, ConfigurationPropertySource... sources) {
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(cls, ConfigurationProperties.class);
Binder binder = new Binder(Arrays.asList(sources), placeholdersResolver);
return binder.bind(annotation.prefix(), Bindable.of(cls), getBindHandler(annotation)).get();
}
public T parse(@NonNull Class cls, Properties properties) {
MapConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
PropertySourcesPlaceholdersResolver placeholdersResolver = new PropertySourcesPlaceholdersResolver(applicationContext.getEnvironment());
return parse(cls, placeholdersResolver, source);
}
private BindHandler getBindHandler(ConfigurationProperties annotation) {
BindHandler handler = new IgnoreTopLevelConverterNotFoundBindHandler();
if (annotation.ignoreInvalidFields()) {
handler = new IgnoreErrorsBindHandler(handler);
}
if (!annotation.ignoreUnknownFields()) {
UnboundElementsSourceFilter filter = new UnboundElementsSourceFilter();
handler = new NoUnboundElementsBindHandler(handler, filter);
}
return handler;
}
}