Package org.springframework.ws.support

Source Code of org.springframework.ws.support.DefaultStrategiesHelper

/*
* Copyright 2005-2010 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.ws.support;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import javax.servlet.ServletContext;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.OrderComparator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;

/**
* Helper class for for loading default implementations of an interface. Encapsulates a properties object, which
* contains strategy interface names as keys, and comma-separated class names as values.
*
* <p>Simulates the {@link BeanFactory normal lifecycle} for beans, by calling {@link
* BeanFactoryAware#setBeanFactory(BeanFactory)}, {@link ApplicationContextAware#setApplicationContext(ApplicationContext)},
* etc.
*
* @author Arjen Poutsma
* @since 1.0.0
*/
public class DefaultStrategiesHelper {

    /** Keys are strategy interface names, values are implementation class names. */
    private Properties defaultStrategies;

    /** Initializes a new instance of the {@code DefaultStrategiesHelper} based on the given set of properties. */
    public DefaultStrategiesHelper(Properties defaultStrategies) {
        Assert.notNull(defaultStrategies, "defaultStrategies must not be null");
        this.defaultStrategies = defaultStrategies;
    }

    /** Initializes a new instance of the {@code DefaultStrategiesHelper} based on the given resource. */
    public DefaultStrategiesHelper(Resource resource) throws IllegalStateException {
        try {
            defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        }
        catch (IOException ex) {
            throw new IllegalStateException("Could not load '" + resource + "': " + ex.getMessage());
        }
    }

    /**
     * Initializes a new instance of the {@code DefaultStrategiesHelper} based on the given type.
     *
     * <p>This constructor will attempt to load a 'typeName'.properties file in the same package as the given type.
     */
    public DefaultStrategiesHelper(Class<?> type) {
        this(new ClassPathResource(ClassUtils.getShortName(type) + ".properties", type));
    }

    /**
     * Create a list of strategy objects for the given strategy interface. Strategies are retrieved from the
     * {@code Properties} object given at construction-time.
     *
     * @param strategyInterface the strategy interface
     * @return a list of corresponding strategy objects
     * @throws BeansException if initialization failed
     */
    public <T> List<T> getDefaultStrategies(Class<T> strategyInterface) throws BeanInitializationException {
        return getDefaultStrategies(strategyInterface, null);
    }

    /**
     * Create a list of strategy objects for the given strategy interface. Strategies are retrieved from the
     * {@code Properties} object given at construction-time. It instantiates the strategy objects and satisfies
     * {@code ApplicationContextAware} with the supplied context if necessary.
     *
     * @param strategyInterface  the strategy interface
     * @param applicationContext used to satisfy strategies that are application context aware, may be
     *                           {@code null}
     * @return a list of corresponding strategy objects
     * @throws BeansException if initialization failed
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> getDefaultStrategies(Class<T> strategyInterface, ApplicationContext applicationContext)
            throws BeanInitializationException {
        String key = strategyInterface.getName();
        try {
            List<T> result;
            String value = defaultStrategies.getProperty(key);
            if (value != null) {
                String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
                result = new ArrayList<T>(classNames.length);
                ClassLoader classLoader = null;
                if (applicationContext != null) {
                    classLoader = applicationContext.getClassLoader();
                }
                if (classLoader == null) {
                    classLoader = DefaultStrategiesHelper.class.getClassLoader();
                }
                for (String className : classNames) {
                    Class<T> clazz = (Class<T>) ClassUtils.forName(className, classLoader);
                    Assert.isTrue(strategyInterface.isAssignableFrom(clazz), clazz.getName() + " is not a " + strategyInterface.getName());
                    T strategy = instantiateBean(clazz, applicationContext);
                    result.add(strategy);
                }
            }
            else {
                result = Collections.emptyList();
            }
            Collections.sort(result, new OrderComparator());
            return result;
        }
        catch (ClassNotFoundException ex) {
            throw new BeanInitializationException("Could not find default strategy class for interface [" + key + "]",
                    ex);
        }
    }

    /** Instantiates the given bean, simulating the standard bean life cycle. */
    private <T> T instantiateBean(Class<T> clazz, ApplicationContext applicationContext) {
        T strategy = BeanUtils.instantiateClass(clazz);
        if (strategy instanceof BeanNameAware) {
            BeanNameAware beanNameAware = (BeanNameAware) strategy;
            beanNameAware.setBeanName(clazz.getName());
        }
        if (applicationContext != null) {
            if (strategy instanceof BeanClassLoaderAware) {
                ((BeanClassLoaderAware) strategy).setBeanClassLoader(applicationContext.getClassLoader());
            }
            if (strategy instanceof BeanFactoryAware) {
                ((BeanFactoryAware) strategy).setBeanFactory(applicationContext);
            }
            if (strategy instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware) strategy).setResourceLoader(applicationContext);
            }
            if (strategy instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware) strategy).setApplicationEventPublisher(applicationContext);
            }
            if (strategy instanceof MessageSourceAware) {
                ((MessageSourceAware) strategy).setMessageSource(applicationContext);
            }
            if (strategy instanceof ApplicationContextAware) {
                ApplicationContextAware applicationContextAware = (ApplicationContextAware) strategy;
                applicationContextAware.setApplicationContext(applicationContext);
            }
            if (applicationContext instanceof WebApplicationContext && strategy instanceof ServletContextAware) {
                ServletContext servletContext = ((WebApplicationContext) applicationContext).getServletContext();
                ((ServletContextAware) strategy).setServletContext(servletContext);
            }
        }
        if (strategy instanceof InitializingBean) {
            InitializingBean initializingBean = (InitializingBean) strategy;
            try {
                initializingBean.afterPropertiesSet();
            }
            catch (Throwable ex) {
                throw new BeanCreationException("Invocation of init method failed", ex);
            }
        }
        return strategy;
    }

    /**
     * Return the default strategy object for the given strategy interface.
     *
     * @param strategyInterface the strategy interface
     * @return the corresponding strategy object
     * @throws BeansException if initialization failed
     * @see #getDefaultStrategies
     */
    public <T> T getDefaultStrategy(Class<T> strategyInterface) throws BeanInitializationException {
        return getDefaultStrategy(strategyInterface, null);
    }

    /**
     * Return the default strategy object for the given strategy interface.
     *
     * <p>Delegates to {@link #getDefaultStrategies(Class,ApplicationContext)}, expecting a single object in the list.
     *
     * @param strategyInterface  the strategy interface
     * @param applicationContext used to satisfy strategies that are application context aware, may be
     *                           {@code null}
     * @return the corresponding strategy object
     * @throws BeansException if initialization failed
     */
    public <T> T getDefaultStrategy(Class<T> strategyInterface, ApplicationContext applicationContext)
            throws BeanInitializationException {
        List<T> result = getDefaultStrategies(strategyInterface, applicationContext);
        if (result.size() != 1) {
            throw new BeanInitializationException(
                    "Could not find exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
        }
        return result.get(0);
    }

}
TOP

Related Classes of org.springframework.ws.support.DefaultStrategiesHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.