Search in sources :

Example 71 with RuntimeBeanReference

use of org.springframework.beans.factory.config.RuntimeBeanReference in project spring-framework by spring-projects.

the class PropertiesBeanDefinitionReader method registerBeanDefinition.

/**
	 * Get all property values, given a prefix (which will be stripped)
	 * and add the bean they define to the factory with the given name
	 * @param beanName name of the bean to define
	 * @param map Map containing string pairs
	 * @param prefix prefix of each entry, which will be stripped
	 * @param resourceDescription description of the resource that the
	 * Map came from (for logging purposes)
	 * @throws BeansException if the bean definition could not be parsed or registered
	 */
protected void registerBeanDefinition(String beanName, Map<?, ?> map, String prefix, String resourceDescription) throws BeansException {
    String className = null;
    String parent = null;
    String scope = GenericBeanDefinition.SCOPE_SINGLETON;
    boolean isAbstract = false;
    boolean lazyInit = false;
    ConstructorArgumentValues cas = new ConstructorArgumentValues();
    MutablePropertyValues pvs = new MutablePropertyValues();
    for (Map.Entry<?, ?> entry : map.entrySet()) {
        String key = StringUtils.trimWhitespace((String) entry.getKey());
        if (key.startsWith(prefix + SEPARATOR)) {
            String property = key.substring(prefix.length() + SEPARATOR.length());
            if (CLASS_KEY.equals(property)) {
                className = StringUtils.trimWhitespace((String) entry.getValue());
            } else if (PARENT_KEY.equals(property)) {
                parent = StringUtils.trimWhitespace((String) entry.getValue());
            } else if (ABSTRACT_KEY.equals(property)) {
                String val = StringUtils.trimWhitespace((String) entry.getValue());
                isAbstract = TRUE_VALUE.equals(val);
            } else if (SCOPE_KEY.equals(property)) {
                // Spring 2.0 style
                scope = StringUtils.trimWhitespace((String) entry.getValue());
            } else if (SINGLETON_KEY.equals(property)) {
                // Spring 1.2 style
                String val = StringUtils.trimWhitespace((String) entry.getValue());
                scope = ((val == null || TRUE_VALUE.equals(val) ? GenericBeanDefinition.SCOPE_SINGLETON : GenericBeanDefinition.SCOPE_PROTOTYPE));
            } else if (LAZY_INIT_KEY.equals(property)) {
                String val = StringUtils.trimWhitespace((String) entry.getValue());
                lazyInit = TRUE_VALUE.equals(val);
            } else if (property.startsWith(CONSTRUCTOR_ARG_PREFIX)) {
                if (property.endsWith(REF_SUFFIX)) {
                    int index = Integer.parseInt(property.substring(1, property.length() - REF_SUFFIX.length()));
                    cas.addIndexedArgumentValue(index, new RuntimeBeanReference(entry.getValue().toString()));
                } else {
                    int index = Integer.parseInt(property.substring(1));
                    cas.addIndexedArgumentValue(index, readValue(entry));
                }
            } else if (property.endsWith(REF_SUFFIX)) {
                // This isn't a real property, but a reference to another prototype
                // Extract property name: property is of form dog(ref)
                property = property.substring(0, property.length() - REF_SUFFIX.length());
                String ref = StringUtils.trimWhitespace((String) entry.getValue());
                // It doesn't matter if the referenced bean hasn't yet been registered:
                // this will ensure that the reference is resolved at runtime.
                Object val = new RuntimeBeanReference(ref);
                pvs.add(property, val);
            } else {
                // It's a normal bean property.
                pvs.add(property, readValue(entry));
            }
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Registering bean definition for bean name '" + beanName + "' with " + pvs);
    }
    // backwards compatibility reasons.
    if (parent == null && className == null && !beanName.equals(this.defaultParentBean)) {
        parent = this.defaultParentBean;
    }
    try {
        AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(parent, className, getBeanClassLoader());
        bd.setScope(scope);
        bd.setAbstract(isAbstract);
        bd.setLazyInit(lazyInit);
        bd.setConstructorArgumentValues(cas);
        bd.setPropertyValues(pvs);
        getRegistry().registerBeanDefinition(beanName, bd);
    } catch (ClassNotFoundException ex) {
        throw new CannotLoadBeanClassException(resourceDescription, beanName, className, ex);
    } catch (LinkageError err) {
        throw new CannotLoadBeanClassException(resourceDescription, beanName, className, err);
    }
}
Also used : ConstructorArgumentValues(org.springframework.beans.factory.config.ConstructorArgumentValues) MutablePropertyValues(org.springframework.beans.MutablePropertyValues) CannotLoadBeanClassException(org.springframework.beans.factory.CannotLoadBeanClassException) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) HashMap(java.util.HashMap) Map(java.util.Map)

Example 72 with RuntimeBeanReference

use of org.springframework.beans.factory.config.RuntimeBeanReference in project spring-framework by spring-projects.

the class SimpleConstructorNamespaceHandler method decorate.

@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
    if (node instanceof Attr) {
        Attr attr = (Attr) node;
        String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
        String argValue = StringUtils.trimWhitespace(attr.getValue());
        ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
        boolean ref = false;
        // handle -ref arguments
        if (argName.endsWith(REF_SUFFIX)) {
            ref = true;
            argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
        }
        ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
        valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
        // handle "escaped"/"_" arguments
        if (argName.startsWith(DELIMITER_PREFIX)) {
            String arg = argName.substring(1).trim();
            // fast default check
            if (!StringUtils.hasText(arg)) {
                cvs.addGenericArgumentValue(valueHolder);
            } else // assume an index otherwise
            {
                int index = -1;
                try {
                    index = Integer.parseInt(arg);
                } catch (NumberFormatException ex) {
                    parserContext.getReaderContext().error("Constructor argument '" + argName + "' specifies an invalid integer", attr);
                }
                if (index < 0) {
                    parserContext.getReaderContext().error("Constructor argument '" + argName + "' specifies a negative index", attr);
                }
                if (cvs.hasIndexedArgumentValue(index)) {
                    parserContext.getReaderContext().error("Constructor argument '" + argName + "' with index " + index + " already defined using <constructor-arg>." + " Only one approach may be used per argument.", attr);
                }
                cvs.addIndexedArgumentValue(index, valueHolder);
            }
        } else // no escaping -> ctr name
        {
            String name = Conventions.attributeNameToPropertyName(argName);
            if (containsArgWithName(name, cvs)) {
                parserContext.getReaderContext().error("Constructor argument '" + argName + "' already defined using <constructor-arg>." + " Only one approach may be used per argument.", attr);
            }
            valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
            cvs.addGenericArgumentValue(valueHolder);
        }
    }
    return definition;
}
Also used : ValueHolder(org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) Attr(org.w3c.dom.Attr) ConstructorArgumentValues(org.springframework.beans.factory.config.ConstructorArgumentValues)

Example 73 with RuntimeBeanReference

use of org.springframework.beans.factory.config.RuntimeBeanReference in project spring-framework by spring-projects.

the class SimplePropertyNamespaceHandler method decorate.

@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
    if (node instanceof Attr) {
        Attr attr = (Attr) node;
        String propertyName = parserContext.getDelegate().getLocalName(attr);
        String propertyValue = attr.getValue();
        MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues();
        if (pvs.contains(propertyName)) {
            parserContext.getReaderContext().error("Property '" + propertyName + "' is already defined using " + "both <property> and inline syntax. Only one approach may be used per property.", attr);
        }
        if (propertyName.endsWith(REF_SUFFIX)) {
            propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length());
            pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
        } else {
            pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
        }
    }
    return definition;
}
Also used : MutablePropertyValues(org.springframework.beans.MutablePropertyValues) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) Attr(org.w3c.dom.Attr)

Example 74 with RuntimeBeanReference

use of org.springframework.beans.factory.config.RuntimeBeanReference in project spring-framework by spring-projects.

the class BeanDefinitionParserDelegate method parseMapElement.

/**
	 * Parse a map element.
	 */
public Map<Object, Object> parseMapElement(Element mapEle, BeanDefinition bd) {
    String defaultKeyType = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE);
    String defaultValueType = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
    List<Element> entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT);
    ManagedMap<Object, Object> map = new ManagedMap<>(entryEles.size());
    map.setSource(extractSource(mapEle));
    map.setKeyTypeName(defaultKeyType);
    map.setValueTypeName(defaultValueType);
    map.setMergeEnabled(parseMergeAttribute(mapEle));
    for (Element entryEle : entryEles) {
        // Should only have one value child element: ref, value, list, etc.
        // Optionally, there might be a key child element.
        NodeList entrySubNodes = entryEle.getChildNodes();
        Element keyEle = null;
        Element valueEle = null;
        for (int j = 0; j < entrySubNodes.getLength(); j++) {
            Node node = entrySubNodes.item(j);
            if (node instanceof Element) {
                Element candidateEle = (Element) node;
                if (nodeNameEquals(candidateEle, KEY_ELEMENT)) {
                    if (keyEle != null) {
                        error("<entry> element is only allowed to contain one <key> sub-element", entryEle);
                    } else {
                        keyEle = candidateEle;
                    }
                } else {
                    // Child element is what we're looking for.
                    if (nodeNameEquals(candidateEle, DESCRIPTION_ELEMENT)) {
                    // the element is a <description> -> ignore it
                    } else if (valueEle != null) {
                        error("<entry> element must not contain more than one value sub-element", entryEle);
                    } else {
                        valueEle = candidateEle;
                    }
                }
            }
        }
        // Extract key from attribute or sub-element.
        Object key = null;
        boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE);
        boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE);
        if ((hasKeyAttribute && hasKeyRefAttribute) || ((hasKeyAttribute || hasKeyRefAttribute)) && keyEle != null) {
            error("<entry> element is only allowed to contain either " + "a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle);
        }
        if (hasKeyAttribute) {
            key = buildTypedStringValueForMap(entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyType, entryEle);
        } else if (hasKeyRefAttribute) {
            String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE);
            if (!StringUtils.hasText(refName)) {
                error("<entry> element contains empty 'key-ref' attribute", entryEle);
            }
            RuntimeBeanReference ref = new RuntimeBeanReference(refName);
            ref.setSource(extractSource(entryEle));
            key = ref;
        } else if (keyEle != null) {
            key = parseKeyElement(keyEle, bd, defaultKeyType);
        } else {
            error("<entry> element must specify a key", entryEle);
        }
        // Extract value from attribute or sub-element.
        Object value = null;
        boolean hasValueAttribute = entryEle.hasAttribute(VALUE_ATTRIBUTE);
        boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE);
        boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE);
        if ((hasValueAttribute && hasValueRefAttribute) || ((hasValueAttribute || hasValueRefAttribute)) && valueEle != null) {
            error("<entry> element is only allowed to contain either " + "'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle);
        }
        if ((hasValueTypeAttribute && hasValueRefAttribute) || (hasValueTypeAttribute && !hasValueAttribute) || (hasValueTypeAttribute && valueEle != null)) {
            error("<entry> element is only allowed to contain a 'value-type' " + "attribute when it has a 'value' attribute", entryEle);
        }
        if (hasValueAttribute) {
            String valueType = entryEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
            if (!StringUtils.hasText(valueType)) {
                valueType = defaultValueType;
            }
            value = buildTypedStringValueForMap(entryEle.getAttribute(VALUE_ATTRIBUTE), valueType, entryEle);
        } else if (hasValueRefAttribute) {
            String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE);
            if (!StringUtils.hasText(refName)) {
                error("<entry> element contains empty 'value-ref' attribute", entryEle);
            }
            RuntimeBeanReference ref = new RuntimeBeanReference(refName);
            ref.setSource(extractSource(entryEle));
            value = ref;
        } else if (valueEle != null) {
            value = parsePropertySubElement(valueEle, bd, defaultValueType);
        } else {
            error("<entry> element must specify a value", entryEle);
        }
        // Add final key and value to the Map.
        map.put(key, value);
    }
    return map;
}
Also used : Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) ManagedMap(org.springframework.beans.factory.support.ManagedMap)

Example 75 with RuntimeBeanReference

use of org.springframework.beans.factory.config.RuntimeBeanReference in project spring-framework by spring-projects.

the class DefaultListableBeanFactoryTests method testCustomTypeConverterWithBeanReference.

@Test
public void testCustomTypeConverterWithBeanReference() {
    DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
    NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
    lbf.setTypeConverter(new CustomTypeConverter(nf));
    MutablePropertyValues pvs = new MutablePropertyValues();
    pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
    ConstructorArgumentValues cav = new ConstructorArgumentValues();
    cav.addIndexedArgumentValue(0, "myName");
    cav.addIndexedArgumentValue(1, "myAge");
    lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
    lbf.registerSingleton("myFloat", "1,1");
    TestBean testBean = (TestBean) lbf.getBean("testBean");
    assertEquals("myName", testBean.getName());
    assertEquals(5, testBean.getAge());
    assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
}
Also used : ITestBean(org.springframework.tests.sample.beans.ITestBean) DerivedTestBean(org.springframework.tests.sample.beans.DerivedTestBean) TestBean(org.springframework.tests.sample.beans.TestBean) NestedTestBean(org.springframework.tests.sample.beans.NestedTestBean) MutablePropertyValues(org.springframework.beans.MutablePropertyValues) DefaultListableBeanFactory(org.springframework.beans.factory.support.DefaultListableBeanFactory) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) NumberFormat(java.text.NumberFormat) ConstructorArgumentValues(org.springframework.beans.factory.config.ConstructorArgumentValues) Test(org.junit.Test)

Aggregations

RuntimeBeanReference (org.springframework.beans.factory.config.RuntimeBeanReference)156 RootBeanDefinition (org.springframework.beans.factory.support.RootBeanDefinition)86 Element (org.w3c.dom.Element)47 BeanDefinition (org.springframework.beans.factory.config.BeanDefinition)39 BeanComponentDefinition (org.springframework.beans.factory.parsing.BeanComponentDefinition)33 BeanDefinitionBuilder (org.springframework.beans.factory.support.BeanDefinitionBuilder)32 ManagedList (org.springframework.beans.factory.support.ManagedList)27 BeanMetadataElement (org.springframework.beans.BeanMetadataElement)24 Test (org.junit.Test)21 ManagedMap (org.springframework.beans.factory.support.ManagedMap)20 MutablePropertyValues (org.springframework.beans.MutablePropertyValues)16 ConstructorArgumentValues (org.springframework.beans.factory.config.ConstructorArgumentValues)15 GroovyObject (groovy.lang.GroovyObject)12 TestBean (org.springframework.tests.sample.beans.TestBean)12 DefaultListableBeanFactory (org.springframework.beans.factory.support.DefaultListableBeanFactory)11 Map (java.util.Map)10 Node (org.w3c.dom.Node)10 HashMap (java.util.HashMap)9 CompositeComponentDefinition (org.springframework.beans.factory.parsing.CompositeComponentDefinition)9 ITestBean (org.springframework.tests.sample.beans.ITestBean)8