/* * Copyright 2002-2016 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.integration.jpa.config.xml; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.jpa.core.JpaExecutor; import org.springframework.integration.jpa.support.JpaParameter; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; /** * Contains various utility methods for parsing JPA Adapter specific namesspace * elements and generation the respective {@link BeanDefinition}s. * * @author Amol Nayak * @author Gunnar Hillert * * @since 2.2 * */ public final class JpaParserUtils { private static final Log logger = LogFactory.getLog(JpaParserUtils.class); /** Prevent instantiation. */ private JpaParserUtils() { throw new AssertionError(); } /** * Create a new {@link BeanDefinitionBuilder} for the class {@link JpaExecutor}. * Initialize the wrapped {@link JpaExecutor} with common properties. * * @param element Must not be null * @param parserContext Must not be null * @return The BeanDefinitionBuilder for the JpaExecutor */ public static BeanDefinitionBuilder getJpaExecutorBuilder(final Element element, final ParserContext parserContext) { Assert.notNull(element, "The provided element must not be null."); Assert.notNull(parserContext, "The provided parserContext must not be null."); final Object source = parserContext.extractSource(element); final BeanDefinitionBuilder jpaExecutorBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaExecutor.class); int attributeCount = 0; final String entityManagerRef = element.getAttribute("entity-manager"); final String entityManagerFactoryRef = element.getAttribute("entity-manager-factory"); final String jpaOperationsRef = element.getAttribute("jpa-operations"); if (StringUtils.hasText(jpaOperationsRef)) { attributeCount++; jpaExecutorBuilder.addConstructorArgReference(jpaOperationsRef); } if (StringUtils.hasText(entityManagerRef)) { if (attributeCount > 0) { parserContext.getReaderContext().error("Exactly only one of the attributes 'entity-manager' or " + "'entity-manager-factory' or 'jpa-operations' must be be set.", source); } attributeCount++; jpaExecutorBuilder.addConstructorArgReference(entityManagerRef); } if (StringUtils.hasText(entityManagerFactoryRef)) { if (attributeCount > 0) { parserContext.getReaderContext().error("Exactly only one of the attributes 'entity-manager' or " + "'entity-manager-factory' or 'jpa-operations' must be be set.", source); } attributeCount++; jpaExecutorBuilder.addConstructorArgReference(entityManagerFactoryRef); } if (attributeCount == 0) { parserContext.getReaderContext().error("Exactly one of the attributes 'entity-manager' or " + "'entity-manager-factory' or 'jpa-operations' must be be set.", source); } final ManagedList<BeanDefinition> jpaParameterList = JpaParserUtils.getJpaParameterBeanDefinitions(element, parserContext); if (!jpaParameterList.isEmpty()) { jpaExecutorBuilder.addPropertyValue("jpaParameters", jpaParameterList); } IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "entity-class"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "jpa-query"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "native-query"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "named-query"); return jpaExecutorBuilder; } /** * Create a new {@link BeanDefinitionBuilder} for the class {@link JpaExecutor} * that is specific for JPA Outbound Gateways. * * Initializes the wrapped {@link JpaExecutor} with common properties. * Delegates to {@link JpaParserUtils#getJpaExecutorBuilder(Element, ParserContext)} * * @param gatewayElement Must not be null * @param parserContext Must not be null * * @return The BeanDefinitionBuilder for the JpaExecutor */ public static BeanDefinitionBuilder getOutboundGatewayJpaExecutorBuilder(final Element gatewayElement, final ParserContext parserContext) { final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getJpaExecutorBuilder(gatewayElement, parserContext); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "parameter-source-factory"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "use-payload-as-parameter-source"); return jpaExecutorBuilder; } /** * Create a {@link ManagedList} of {@link BeanDefinition}s containing parsed * JPA Parameters. * * @param jpaComponent Must not be null * @param parserContext Must not be null * * @return {@link ManagedList} of {@link BeanDefinition}s */ public static ManagedList<BeanDefinition> getJpaParameterBeanDefinitions( Element jpaComponent, ParserContext parserContext) { Assert.notNull(jpaComponent, "The provided element must not be null."); Assert.notNull(parserContext, "The provided parserContext must not be null."); final ManagedList<BeanDefinition> parameterList = new ManagedList<BeanDefinition>(); final List<Element> parameterChildElements = DomUtils .getChildElementsByTagName(jpaComponent, "parameter"); for (Element childElement : parameterChildElements) { final BeanDefinitionBuilder parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaParameter.class); String name = childElement.getAttribute("name"); String expression = childElement.getAttribute("expression"); String value = childElement.getAttribute("value"); String type = childElement.getAttribute("type"); if (StringUtils.hasText(name)) { parameterBuilder.addPropertyValue("name", name); } if (StringUtils.hasText(expression)) { parameterBuilder.addPropertyValue("expression", expression); } if (StringUtils.hasText(value)) { if (!StringUtils.hasText(type)) { if (logger.isInfoEnabled()) { logger.info(String .format("Type attribute not set for parameter '%s'. Defaulting to " + "'java.lang.String'.", value)); } parameterBuilder.addPropertyValue("value", new TypedStringValue(value, String.class)); } else { parameterBuilder.addPropertyValue("value", new TypedStringValue(value, type)); } } parameterList.add(parameterBuilder.getBeanDefinition()); } return parameterList; } }