Java tutorial
/** * 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); } }