001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.autoconfigure.gson;
018
019import java.util.List;
020
021import com.google.gson.Gson;
022import com.google.gson.GsonBuilder;
023
024import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
025import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
026import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
027import org.springframework.boot.context.properties.EnableConfigurationProperties;
028import org.springframework.boot.context.properties.PropertyMapper;
029import org.springframework.context.annotation.Bean;
030import org.springframework.context.annotation.Configuration;
031import org.springframework.core.Ordered;
032
033/**
034 * {@link EnableAutoConfiguration Auto-configuration} for Gson.
035 *
036 * @author David Liu
037 * @author Ivan Golovko
038 * @since 1.2.0
039 */
040@Configuration
041@ConditionalOnClass(Gson.class)
042@EnableConfigurationProperties(GsonProperties.class)
043public class GsonAutoConfiguration {
044
045        @Bean
046        @ConditionalOnMissingBean
047        public GsonBuilder gsonBuilder(List<GsonBuilderCustomizer> customizers) {
048                GsonBuilder builder = new GsonBuilder();
049                customizers.forEach((c) -> c.customize(builder));
050                return builder;
051        }
052
053        @Bean
054        @ConditionalOnMissingBean
055        public Gson gson(GsonBuilder gsonBuilder) {
056                return gsonBuilder.create();
057        }
058
059        @Bean
060        public StandardGsonBuilderCustomizer standardGsonBuilderCustomizer(
061                        GsonProperties gsonProperties) {
062                return new StandardGsonBuilderCustomizer(gsonProperties);
063        }
064
065        static final class StandardGsonBuilderCustomizer
066                        implements GsonBuilderCustomizer, Ordered {
067
068                private final GsonProperties properties;
069
070                StandardGsonBuilderCustomizer(GsonProperties properties) {
071                        this.properties = properties;
072                }
073
074                @Override
075                public int getOrder() {
076                        return 0;
077                }
078
079                @Override
080                public void customize(GsonBuilder builder) {
081                        GsonProperties properties = this.properties;
082                        PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
083                        map.from(properties::getGenerateNonExecutableJson)
084                                        .toCall(builder::generateNonExecutableJson);
085                        map.from(properties::getExcludeFieldsWithoutExposeAnnotation)
086                                        .toCall(builder::excludeFieldsWithoutExposeAnnotation);
087                        map.from(properties::getSerializeNulls).toCall(builder::serializeNulls);
088                        map.from(properties::getEnableComplexMapKeySerialization)
089                                        .toCall(builder::enableComplexMapKeySerialization);
090                        map.from(properties::getDisableInnerClassSerialization)
091                                        .toCall(builder::disableInnerClassSerialization);
092                        map.from(properties::getLongSerializationPolicy)
093                                        .to(builder::setLongSerializationPolicy);
094                        map.from(properties::getFieldNamingPolicy).to(builder::setFieldNamingPolicy);
095                        map.from(properties::getPrettyPrinting).toCall(builder::setPrettyPrinting);
096                        map.from(properties::getLenient).toCall(builder::setLenient);
097                        map.from(properties::getDisableHtmlEscaping)
098                                        .toCall(builder::disableHtmlEscaping);
099                        map.from(properties::getDateFormat).to(builder::setDateFormat);
100                }
101
102        }
103
104}