org.springframework.cloud.stream.config.BinderFactoryConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.cloud.stream.config.BinderFactoryConfiguration.java

Source

/*
 * Copyright 2015-2018 the original author or 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 org.springframework.cloud.stream.config;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.stream.binder.BinderType;
import org.springframework.cloud.stream.binder.BinderTypeRegistry;
import org.springframework.cloud.stream.binder.DefaultBinderTypeRegistry;
import org.springframework.cloud.stream.binding.CompositeMessageChannelConfigurer;
import org.springframework.cloud.stream.binding.MessageChannelConfigurer;
import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
import org.springframework.cloud.stream.binding.MessageSourceBindingTargetFactory;
import org.springframework.cloud.stream.binding.SubscribableChannelBindingTargetFactory;
import org.springframework.cloud.stream.converter.CompositeMessageConverterFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Role;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.handler.support.HandlerMethodArgumentResolversHolder;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * @author Marius Bogoevici
 * @author Ilayaperumal Gopinathan
 * @author Oleg Zhurakousky
 * @author Soby Chacko
 *
 * @deprecated since it really represents 'auto-configuration' it will be renamed/restructured in the next release.
 */
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@EnableConfigurationProperties({ BindingServiceProperties.class })
@Import({ ContentTypeConfiguration.class })
@Deprecated
public class BinderFactoryConfiguration {

    protected final Log logger = LogFactory.getLog(getClass());

    private static final String SPRING_CLOUD_STREAM_INTERNAL_PREFIX = "spring.cloud.stream.internal";

    private static final String SELF_CONTAINED_APP_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX
            + ".selfContained";

    @Value("${" + SELF_CONTAINED_APP_PROPERTY_NAME + ":}")
    private String selfContained;

    static Collection<BinderType> parseBinderConfigurations(ClassLoader classLoader, Resource resource)
            throws IOException, ClassNotFoundException {
        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
        Collection<BinderType> parsedBinderConfigurations = new ArrayList<>();
        for (Map.Entry<?, ?> entry : properties.entrySet()) {
            String binderType = (String) entry.getKey();
            String[] binderConfigurationClassNames = StringUtils
                    .commaDelimitedListToStringArray((String) entry.getValue());
            Class<?>[] binderConfigurationClasses = new Class[binderConfigurationClassNames.length];
            int i = 0;
            for (String binderConfigurationClassName : binderConfigurationClassNames) {
                binderConfigurationClasses[i++] = ClassUtils.forName(binderConfigurationClassName, classLoader);
            }
            parsedBinderConfigurations.add(new BinderType(binderType, binderConfigurationClasses));
        }
        return parsedBinderConfigurations;
    }

    @Bean
    public BinderTypeRegistry binderTypeRegistry(ConfigurableApplicationContext configurableApplicationContext) {
        Map<String, BinderType> binderTypes = new HashMap<>();
        ClassLoader classLoader = configurableApplicationContext.getClassLoader();
        // the above can never be null since it will default to ClassUtils.getDefaultClassLoader(..)
        try {
            Enumeration<URL> resources = classLoader.getResources("META-INF/spring.binders");
            if (!Boolean.valueOf(this.selfContained) && (resources == null || !resources.hasMoreElements())) {
                this.logger.debug("Failed to locate 'META-INF/spring.binders' resources on the classpath."
                        + " Assuming standard boot 'META-INF/spring.factories' configuration is used");
            } else {
                while (resources.hasMoreElements()) {
                    URL url = resources.nextElement();
                    UrlResource resource = new UrlResource(url);
                    for (BinderType binderType : parseBinderConfigurations(classLoader, resource)) {
                        binderTypes.put(binderType.getDefaultName(), binderType);
                    }
                }
            }

        } catch (IOException | ClassNotFoundException e) {
            throw new BeanCreationException("Cannot create binder factory:", e);
        }
        return new DefaultBinderTypeRegistry(binderTypes);
    }

    @Bean
    public MessageConverterConfigurer messageConverterConfigurer(BindingServiceProperties bindingServiceProperties,
            CompositeMessageConverterFactory compositeMessageConverterFactory) {
        return new MessageConverterConfigurer(bindingServiceProperties, compositeMessageConverterFactory);
    }

    @Bean
    public SubscribableChannelBindingTargetFactory channelFactory(
            CompositeMessageChannelConfigurer compositeMessageChannelConfigurer) {
        return new SubscribableChannelBindingTargetFactory(compositeMessageChannelConfigurer);
    }

    @Bean
    public MessageSourceBindingTargetFactory messageSourceFactory(
            CompositeMessageConverterFactory compositeMessageConverterFactory,
            CompositeMessageChannelConfigurer compositeMessageChannelConfigurer) {
        return new MessageSourceBindingTargetFactory(
                compositeMessageConverterFactory.getMessageConverterForAllRegistered(),
                compositeMessageChannelConfigurer);
    }

    @Bean
    public CompositeMessageChannelConfigurer compositeMessageChannelConfigurer(
            MessageConverterConfigurer messageConverterConfigurer) {
        List<MessageChannelConfigurer> configurerList = new ArrayList<>();
        configurerList.add(messageConverterConfigurer);
        return new CompositeMessageChannelConfigurer(configurerList);
    }

    @Bean
    public static MessageHandlerMethodFactory messageHandlerMethodFactory(
            CompositeMessageConverterFactory compositeMessageConverterFactory,
            @Qualifier(IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME) HandlerMethodArgumentResolversHolder ahmar) {
        DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
        messageHandlerMethodFactory
                .setMessageConverter(compositeMessageConverterFactory.getMessageConverterForAllRegistered());
        messageHandlerMethodFactory.setCustomArgumentResolvers(ahmar.getResolvers());
        return messageHandlerMethodFactory;
    }

}