org.solmix.runtime.support.spring.SpringBeanProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.solmix.runtime.support.spring.SpringBeanProvider.java

Source

/**
 *  Copyright 2012 The Solmix Project
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.gnu.org/licenses/ 
 * or see the FSF site: http://www.fsf.org. 
 */

package org.solmix.runtime.support.spring;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.solmix.runtime.Container;
import org.solmix.runtime.bean.ConfiguredBeanProvider;
import org.solmix.runtime.extension.ExtensionManagerImpl;
import org.springframework.beans.Mergeable;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 
 * @author solmix.f@gmail.com
 * @version $Id$ 2013-11-4
 */

public class SpringBeanProvider implements ConfiguredBeanProvider {

    private final ApplicationContext context;

    private ConfiguredBeanProvider original;

    private final Set<String> passThroughs = new HashSet<String>();

    public SpringBeanProvider(ApplicationContext context) {
        this(context, null);
    }

    /**
     * @param applicationContext
     * @param systemContext
     */
    public SpringBeanProvider(ApplicationContext applicationContext, Container system) {
        this.context = applicationContext;
        if (system != null) {
            original = system.getExtension(ConfiguredBeanProvider.class);
            if (original instanceof ExtensionManagerImpl) {
                List<String> names = new ArrayList<String>();
                for (String s : context.getBeanDefinitionNames()) {
                    names.add(s);
                    for (String s2 : context.getAliases(s)) {
                        names.add(s2);
                    }
                }
                ((ExtensionManagerImpl) original).removeBeansOfNames(names);
            }
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.solmix.api.bean.ConfiguredBeanProvider#getBeanNamesOfType(java.lang.Class)
     */
    @Override
    public List<String> getBeanNamesOfType(Class<?> type) {
        Set<String> s = new LinkedHashSet<String>(Arrays.asList(context.getBeanNamesForType(type, false, false)));
        if (context.getParent() != null) {
            s.addAll(doGetBeanNamesOfType0(context.getParent(), type));
        }
        s.removeAll(passThroughs);
        if (original != null) {
            List<String> origs = original.getBeanNamesOfType(type);
            if (origs != null)
                s.addAll(original.getBeanNamesOfType(type));
        }
        return new ArrayList<String>(s);
    }

    private Set<String> doGetBeanNamesOfType0(ApplicationContext context, Class<?> type) {

        Set<String> s = new LinkedHashSet<String>(Arrays.asList(context.getBeanNamesForType(type, false, false)));
        if (context.getParent() != null) {
            s.addAll(doGetBeanNamesOfType0(context.getParent(), type));
        }
        return s;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.solmix.api.bean.ConfiguredBeanProvider#getBeanOfType(java.lang.String, java.lang.Class)
     */
    @Override
    public <T> T getBeanOfType(String name, Class<T> type) {
        T t = null;
        try {
            t = type.cast(context.getBean(name, type));
        } catch (NoSuchBeanDefinitionException nsbde) {
            // ignore
        }
        if (t == null && context.getParent() != null) {
            t = dogetBeanOfType0(context.getParent(), name, type);
        }
        if (t == null && original != null) {
            t = original.getBeanOfType(name, type);
        }
        return t;
    }

    // get bean from parent;
    private <T> T dogetBeanOfType0(ApplicationContext context, String name, Class<T> type) {
        T t = null;
        if (context != null) {
            t = type.cast(context.getBean(name, type));
            if (t == null && context.getParent() != null)
                t = dogetBeanOfType0(context.getParent(), name, type);
        }
        return t;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.solmix.api.bean.ConfiguredBeanProvider#getBeansOfType(java.lang.Class)
     */
    @Override
    public <T> Collection<? extends T> getBeansOfType(Class<T> type) {
        Set<String> s = new LinkedHashSet<String>(Arrays.asList(context.getBeanNamesForType(type, false, false)));
        s.removeAll(passThroughs);
        List<T> lst = new LinkedList<T>();
        for (String n : s) {
            lst.add(type.cast(context.getBean(n, type)));
        }
        if (context.getParent() != null) {
            lst.addAll(_doGetBeansOfType(context.getParent(), type));
        }
        if (original != null) {
            Collection<? extends T> origs = original.getBeansOfType(type);
            if (origs != null)
                lst.addAll(origs);
        }
        return lst;
    }

    // get bean from parent;
    private <T> Collection<? extends T> _doGetBeansOfType(ApplicationContext context, Class<T> type) {
        if (context != null) {
            Set<String> s = new LinkedHashSet<String>(
                    Arrays.asList(context.getBeanNamesForType(type, false, false)));
            s.removeAll(passThroughs);
            List<T> lst = new LinkedList<T>();
            for (String n : s) {
                lst.add(type.cast(context.getBean(n, type)));
            }
            if (context.getParent() != null) {
                lst.addAll(_doGetBeansOfType(context.getParent(), type));
            }
            return lst;
        }
        return null;

    }

    /**
     * {@inheritDoc}
     * 
     * @see org.solmix.api.bean.ConfiguredBeanProvider#loadBeansOfType(java.lang.Class,
     *      org.solmix.api.bean.ConfiguredBeanProvider.BeanLoaderListener)
     */
    @Override
    public <T> boolean loadBeansOfType(Class<T> type, BeanLoaderListener<T> listener) {
        List<String> list = new ArrayList<String>(Arrays.asList(context.getBeanNamesForType(type, false, false)));
        list.removeAll(passThroughs);
        Collections.reverse(list);
        boolean loaded = false;
        for (String s : list) {
            Class<?> beanType = context.getType(s);
            Class<? extends T> t = beanType.asSubclass(type);
            if (listener.loadBean(s, t)) {
                Object o = context.getBean(s);
                if (listener.beanLoaded(s, type.cast(o))) {
                    return true;
                }
                loaded = true;
            }
        }
        return loaded || original.loadBeansOfType(type, listener);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.solmix.api.bean.ConfiguredBeanProvider#hasBeanOfName(java.lang.String)
     */
    @Override
    public boolean hasBeanOfName(String name) {
        if (context.containsBean(name)) {
            return true;
        }
        return original.hasBeanOfName(name);
    }

    public boolean hasConfiguredPropertyValue(String beanName, String propertyName, String searchValue) {
        if (context.containsBean(beanName) && !passThroughs.contains(beanName)) {
            ConfigurableApplicationContext ctxt = (ConfigurableApplicationContext) context;
            BeanDefinition def = ctxt.getBeanFactory().getBeanDefinition(beanName);
            if (!ctxt.getBeanFactory().isSingleton(beanName) || def.isAbstract()) {
                return false;
            }
            Collection<?> ids = null;
            PropertyValue pv = def.getPropertyValues().getPropertyValue(propertyName);

            if (pv != null) {
                Object value = pv.getValue();
                if (!(value instanceof Collection)) {
                    throw new RuntimeException("The property " + propertyName + " must be a collection!");
                }

                if (value instanceof Mergeable) {
                    if (!((Mergeable) value).isMergeEnabled()) {
                        ids = (Collection<?>) value;
                    }
                } else {
                    ids = (Collection<?>) value;
                }
            }

            if (ids != null) {
                for (Iterator<?> itr = ids.iterator(); itr.hasNext();) {
                    Object o = itr.next();
                    if (o instanceof TypedStringValue) {
                        if (searchValue.equals(((TypedStringValue) o).getValue())) {
                            return true;
                        }
                    } else {
                        if (searchValue.equals(o)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
        //        return orig.hasConfiguredPropertyValue(beanName, propertyName, searchValue);
    }

}