/******************************************************************************* * Copyright (c) 2005, 2013 Spring IDE Developers * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.core; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader; /** * Default implementation of the {@link BeanDefinitionRegistry} interface: a full-fledged bean factory based on bean * definitions. * <p> * Typical usage is registering all bean definitions first (possibly read from a bean definition file), before accessing * beans. Bean definition lookup is therefore an inexpensive operation in a local bean definition table. * <p> * Can be used as a standalone bean factory, or as a superclass for custom bean factories. Note that readers for * specific bean definition formats are typically implemented separately rather than as bean factory subclasses. * <p> * <b>Creation of bean instances is not supported!!!</b> * * @author Torsten Juergeleit * @author Christian Dupuis */ public class DefaultBeanDefinitionRegistry extends AbstractBeanFactory implements BeanDefinitionRegistry { /** * Whether to allow re-registration of a different definition with the same name */ private boolean allowBeanDefinitionOverriding = true; /** * Whether to allow re-registration of a different alias with the same name */ private boolean allowAliasOverriding = true; /** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<String, BeanDefinition>(); /** List of bean definition names, in registration order */ private final List<String> beanDefinitionNames = new ArrayList<String>(); /** * Create a new DefaultBeanDefinitionRegistry. */ public DefaultBeanDefinitionRegistry() { super(); } /** * Create a new DefaultBeanDefinitionRegistry with the given parent. * @param parentBeanFactory parent bean factory, or null if none * @see #getBean */ public DefaultBeanDefinitionRegistry(BeanFactory parentBeanFactory) { super(parentBeanFactory); } /** * Set if it should be allowed to override bean definitions by registering a different definition with the same * name, automatically replacing the former. If not, an exception will be thrown. Default is true. */ public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) { this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding; } /** * Set if it should be allowed to override aliases by registering a different alias with the same name, * automatically replacing the former. If not, an exception will be thrown. Default is true. */ public void setAllowAliasOverriding(boolean allowAliasOverriding) { this.allowAliasOverriding = allowAliasOverriding; } public int getBeanDefinitionCount() { return beanDefinitionMap.size(); } public String[] getBeanDefinitionNames() { return beanDefinitionNames.toArray(new String[beanDefinitionNames.size()]); } @Override public boolean containsBeanDefinition(String beanName) { String transformedBeanName = transformedBeanName(beanName); return beanDefinitionNames.contains(transformedBeanName); } /** * Return a RootBeanDefinition for the given bean name, by merging with the parent if the given original bean * definition is a child bean definition. * * @param beanName the name of the bean definition * @return a merged RootBeanDefinition with overridden properties */ @Override public BeanDefinition getBeanDefinition(String beanName) throws BeansException { String transformedBeanName = transformedBeanName(beanName); BeanDefinition bd = beanDefinitionMap.get(transformedBeanName); if (bd == null) { throw new NoSuchBeanDefinitionException(beanName, toString()); } return getMergedBeanDefinition(transformedBeanName, bd); } public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Object oldBeanDefinition = beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!allowBeanDefinitionOverriding) { throw new BeanDefinitionStoreException("Overrides bean '" + oldBeanDefinition + "'"); } } else { beanDefinitionNames.add(beanName); } beanDefinitionMap.put(beanName, beanDefinition); } @Override public void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException { try { super.registerAlias(beanName, alias); } catch (IllegalArgumentException e) { throw new BeanDefinitionStoreException(DefaultBeanDefinitionDocumentReader.ALIAS_ELEMENT, beanName, e .getMessage()); } catch (BeanDefinitionStoreException e) { if (!allowAliasOverriding) { throw e; } } } @Override public Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args) throws BeansException { throw new BeanCreationException(beanName, "Not implemented"); } @Override public String toString() { StringBuffer text = new StringBuffer(); Iterator<String> bdNames = beanDefinitionNames.iterator(); while (bdNames.hasNext()) { text.append(bdNames.next()); if (bdNames.hasNext()) { text.append(", "); } } return text.toString(); } public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { if (beanDefinitionMap.containsKey(beanName)) { beanDefinitionMap.remove(beanName); beanDefinitionNames.remove(beanName); } } public void registerQualifierType(Class<?> cls) { } public <T> T getBean(Class<T> requiredType) throws BeansException { return null; } public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException { return null; } }