From cf71070de6060d24d72aa575a8b2ad4e34e7e696 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 18 Jul 2012 23:14:28 +0200 Subject: [PATCH] DATACMNS-202 - Move helper classes for BeanDefinitionParses into Commons. --- .../BeanComponentDefinitionBuilder.java | 115 ++++++++++++++++ .../data/config/ParsingUtils.java | 130 ++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 spring-data-commons-core/src/main/java/org/springframework/data/config/BeanComponentDefinitionBuilder.java create mode 100644 spring-data-commons-core/src/main/java/org/springframework/data/config/ParsingUtils.java diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/config/BeanComponentDefinitionBuilder.java b/spring-data-commons-core/src/main/java/org/springframework/data/config/BeanComponentDefinitionBuilder.java new file mode 100644 index 000000000..755dc231b --- /dev/null +++ b/spring-data-commons-core/src/main/java/org/springframework/data/config/BeanComponentDefinitionBuilder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012 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.data.config; + +import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Helper to create {@link BeanComponentDefinition} more easily. + * + * @author Oliver Gierke + */ +public class BeanComponentDefinitionBuilder { + + private final Element defaultSource; + private final ParserContext context; + + /** + * Creates a new {@link BeanComponentDefinitionBuilder} using the given {@link Element} as default source and the + * given {@link ParserContext}. + * + * @param defaultSource must not be {@literal null}. + * @param context must not be {@literal null}. + */ + public BeanComponentDefinitionBuilder(Element defaultSource, ParserContext context) { + + Assert.notNull(defaultSource); + Assert.notNull(context); + + this.defaultSource = defaultSource; + this.context = context; + } + + /** + * Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder}. Will generate a bean name. + * + * @param builder must not be {@literal null}. + * @return + */ + public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder) { + + Assert.notNull(builder); + + AbstractBeanDefinition definition = builder.getRawBeanDefinition(); + String name = BeanDefinitionReaderUtils.generateBeanName(definition, context.getRegistry(), context.isNested()); + + return getComponent(builder, name); + } + + /** + * Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} and inspects the backing + * {@link Element}s id attribute for a name. It will use this one if found or the given fallback if not. + * + * @param builder must not be {@literal null}. + * @param fallback must not be {@literal null} or empty. + * @return + */ + public BeanComponentDefinition getComponentIdButFallback(BeanDefinitionBuilder builder, String fallback) { + + Assert.hasText(fallback); + + String id = defaultSource.getAttribute("id"); + return getComponent(builder, StringUtils.hasText(id) ? id : fallback); + } + + /** + * Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} using the given name. + * + * @param builder must not be {@literal null}. + * @param name must not be {@literal null} or empty. + * @return + */ + public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder, String name) { + return getComponent(builder, name, defaultSource); + } + + /** + * Creates a new {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} using the given name and + * raw source object. + * + * @param builder must not be {@literal null}. + * @param name must not be {@literal null}. + * @param rawSource + * @return + */ + public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder, String name, Object rawSource) { + + Assert.notNull(builder); + Assert.hasText(name); + + AbstractBeanDefinition definition = builder.getRawBeanDefinition(); + definition.setSource(context.extractSource(rawSource)); + + return new BeanComponentDefinition(definition, name); + } +} diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/config/ParsingUtils.java b/spring-data-commons-core/src/main/java/org/springframework/data/config/ParsingUtils.java new file mode 100644 index 000000000..dc2aaba51 --- /dev/null +++ b/spring-data-commons-core/src/main/java/org/springframework/data/config/ParsingUtils.java @@ -0,0 +1,130 @@ +/* + * Copyright 2011-2012 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.data.config; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Utility methods for {@link BeanDefinitionParser} implementations. + * + * @author Oliver Gierke + */ +public abstract class ParsingUtils { + + private ParsingUtils() { + + } + + /** + * Configures a property value for the given property name reading the attribute of the given name from the given + * {@link Element} if the attribute is configured. + * + * @param builder must not be {@literal null}. + * @param element must not be {@literal null}. + * @param attrName must not be {@literal null} or empty. + * @param propertyName must not be {@literal null} or empty. + */ + public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attrName, + String propertyName) { + + Assert.notNull(builder, "BeanDefinitionBuilder must not be null!"); + Assert.notNull(element, "Element must not be null!"); + Assert.hasText(attrName, "Attribute name must not be null!"); + Assert.hasText(propertyName, "Property name must not be null!"); + + String attr = element.getAttribute(attrName); + + if (StringUtils.hasText(attr)) { + builder.addPropertyValue(propertyName, attr); + } + } + + /** + * Sets the property with the given attribute name on the given {@link BeanDefinitionBuilder} to the value of the + * attribute with the given name if the attribute is configured. + * + * @param builder must not be {@literal null}. + * @param element must not be {@literal null}. + * @param attribute must not be {@literal null} or empty. + */ + public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attribute) { + setPropertyValue(builder, element, attribute, attribute); + } + + /** + * Configures a bean property reference with the value of the attribute of the given name if it is configured. + * + * @param builder must not be {@literal null}. + * @param element must not be {@literal null}. + * @param attribute must not be {@literal null} or empty. + * @param property must not be {@literal null}or empty. + */ + public static void setPropertyReference(BeanDefinitionBuilder builder, Element element, String attribute, + String property) { + + Assert.notNull(builder, "BeanDefinitionBuilder must not be null!"); + Assert.notNull(element, "Element must not be null!"); + Assert.hasText(attribute, "Attribute name must not be null!"); + Assert.hasText(property, "Property name must not be null!"); + + String value = element.getAttribute(attribute); + + if (StringUtils.hasText(value)) { + builder.addPropertyReference(property, value); + } + } + + /** + * Returns the {@link BeanDefinition} built by the given {@link BeanDefinitionBuilder} enriched with source + * information derived from the given {@link Element}. + * + * @param builder must not be {@literal null}. + * @param context must not be {@literal null}. + * @param element must not be {@literal null}. + * @return + */ + public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, ParserContext context, + Element element) { + + Assert.notNull(element, "Element must not be null!"); + Assert.notNull(context, "ParserContext must not be null!"); + + return getSourceBeanDefinition(builder, context.extractSource(element)); + } + + /** + * Returns the {@link AbstractBeanDefinition} built by the given builder with the given extracted source applied. + * + * @param builder must not be {@literal null}. + * @param source + * @return + */ + public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, Object source) { + + Assert.notNull(builder, "Builder must not be null!"); + + AbstractBeanDefinition definition = builder.getRawBeanDefinition(); + definition.setSource(source); + return definition; + } +}