From 7f34f8c919f5e60ba8aa34cb4fc805d09a33f9f4 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 16 Sep 2013 10:53:26 +0300 Subject: [PATCH] INT-2739: StoredProc: 'row-mapper' as a Bean Ref * Convert `row-mapper` attribute of stored procedure components to bean reference * Class name is also supported for backward compatibility JIRA: https://jira.springsource.org/browse/INT-2739 --- .../StoredProcOutboundGatewayParser.java | 8 +-- .../jdbc/config/StoredProcParserUtils.java | 25 +++++++-- ...StoredProcPollingChannelAdapterParser.java | 9 ++-- .../config/spring-integration-jdbc-3.0.xsd | 12 +++-- ...edProcPollingChannelAdapterParserTest2.xml | 51 ------------------- ...dProcPollingChannelAdapterParserTests.java | 19 +++++-- ...redProcPollingChannelAdapterParserTest.xml | 7 ++- src/reference/docbook/whats-new.xml | 12 ++++- 8 files changed, 70 insertions(+), 73 deletions(-) delete mode 100644 spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/Copy of storedProcPollingChannelAdapterParserTest2.xml diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParser.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParser.java index 2d72923c5b..ac8b2d29d5 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParser.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcOutboundGatewayParser.java @@ -13,7 +13,9 @@ package org.springframework.integration.jdbc.config; -import org.springframework.beans.factory.config.BeanDefinition; +import org.w3c.dom.Element; + +import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -23,7 +25,6 @@ import org.springframework.integration.config.xml.AbstractConsumerEndpointParser import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.jdbc.StoredProcOutboundGateway; import org.springframework.util.StringUtils; -import org.w3c.dom.Element; /** * @author Gunnar Hillert @@ -47,7 +48,8 @@ public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointPar IntegrationNamespaceUtils.setReferenceIfAttributeDefined(storedProcExecutorBuilder, element, "sql-parameter-source-factory"); IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "skip-undeclared-results"); - final ManagedMap returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext); + final ManagedMap returningResultsetMap = + StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext); if (!returningResultsetMap.isEmpty()) { storedProcExecutorBuilder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap); diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcParserUtils.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcParserUtils.java index 3591326382..8b5fbdf18f 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcParserUtils.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcParserUtils.java @@ -19,9 +19,14 @@ package org.springframework.integration.jdbc.config; import java.sql.Types; import java.util.List; +import org.w3c.dom.Element; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; @@ -36,9 +41,9 @@ import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; /** * @author Gunnar Hillert @@ -203,21 +208,31 @@ public final class StoredProcParserUtils { * @param storedProcComponent * @param parserContext */ - public static ManagedMap getReturningResultsetBeanDefinitions( + public static ManagedMap getReturningResultsetBeanDefinitions( Element storedProcComponent, ParserContext parserContext) { List returningResultsetChildElements = DomUtils.getChildElementsByTagName(storedProcComponent, "returning-resultset"); - ManagedMap returningResultsetMap = new ManagedMap(); + ManagedMap returningResultsetMap = new ManagedMap(); for (Element childElement : returningResultsetChildElements) { String name = childElement.getAttribute("name"); String rowMapperAsString = childElement.getAttribute("row-mapper"); - BeanDefinitionBuilder rowMapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(rowMapperAsString); + BeanMetadataElement rowMapperBeanDefinition = null; - returningResultsetMap.put(name, rowMapperBuilder.getBeanDefinition()); + try { + // Backward compatibility + ClassUtils.forName(rowMapperAsString, parserContext.getReaderContext().getBeanClassLoader()); + rowMapperBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(rowMapperAsString).getBeanDefinition(); + } + catch (ClassNotFoundException e) { + //Ignore it and fallback to bean reference + rowMapperBeanDefinition = new RuntimeBeanReference(rowMapperAsString); + } + + returningResultsetMap.put(name, rowMapperBeanDefinition); } return returningResultsetMap; diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParser.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParser.java index acabc93b57..086c629185 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParser.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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 @@ -13,8 +13,9 @@ package org.springframework.integration.jdbc.config; +import org.w3c.dom.Element; + import org.springframework.beans.BeanMetadataElement; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -23,7 +24,6 @@ import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.jdbc.StoredProcPollingChannelAdapter; -import org.w3c.dom.Element; /** * @author Gunnar Hillert @@ -51,7 +51,8 @@ public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboun IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "is-function"); IntegrationNamespaceUtils.setValueIfAttributeDefined(storedProcExecutorBuilder, element, "skip-undeclared-results"); - final ManagedMap returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext); + final ManagedMap returningResultsetMap = + StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext); if (!returningResultsetMap.isEmpty()) { storedProcExecutorBuilder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap); diff --git a/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-3.0.xsd b/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-3.0.xsd index 78007adeb0..d4900cf3ed 100644 --- a/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-3.0.xsd +++ b/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-3.0.xsd @@ -1274,9 +1274,15 @@ - + + + Reference to a row mapper to use to convert + JDBC result set rows to message payloads. + + + + + diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/Copy of storedProcPollingChannelAdapterParserTest2.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/Copy of storedProcPollingChannelAdapterParserTest2.xml deleted file mode 100644 index b7fffe2f6e..0000000000 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/Copy of storedProcPollingChannelAdapterParserTest2.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParserTests.java index 4f460500a9..852d5ecd1b 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcPollingChannelAdapterParserTests.java @@ -21,12 +21,14 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.sql.Types; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.junit.After; import org.junit.Test; + import org.springframework.beans.DirectFieldAccessor; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -40,10 +42,13 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; +import org.springframework.jdbc.core.simple.ParameterizedSingleColumnRowMapper; /** * @author Gunnar Hillert * @author Gary Russell + * @author Artem Bilan + * * @since 2.1 * */ @@ -200,12 +205,18 @@ public class StoredProcPollingChannelAdapterParserTests { Map> returningResultSetRowMappersAsMap = (Map>) returningResultSetRowMappers; - assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 1", returningResultSetRowMappersAsMap.size() == 1); + assertTrue("The rowmapper was not set. Expected returningResultSetRowMappersAsMap.size() == 2", + returningResultSetRowMappersAsMap.size() == 2); - Entry mapEntry1 = returningResultSetRowMappersAsMap.entrySet().iterator().next(); + Iterator>> iterator = returningResultSetRowMappersAsMap.entrySet().iterator(); - assertEquals("out", mapEntry1.getKey()); - assertTrue(mapEntry1.getValue() instanceof PrimeMapper); + Entry mapEntry = iterator.next(); + assertEquals("out", mapEntry.getKey()); + assertTrue(mapEntry.getValue() instanceof PrimeMapper); + + mapEntry = iterator.next(); + assertEquals("out2", mapEntry.getKey()); + assertTrue(mapEntry.getValue() instanceof ParameterizedSingleColumnRowMapper); } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/storedProcPollingChannelAdapterParserTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/storedProcPollingChannelAdapterParserTest.xml index 77413ec3c4..320988640f 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/storedProcPollingChannelAdapterParserTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/storedProcPollingChannelAdapterParserTest.xml @@ -26,9 +26,14 @@ - + + + + +
- SqlReturnType support for Stored Procedure components + Stored Procedure Components Improvements For more complex database-specific types, not supported by the standard CallableStatement.getObject method, 2 new additional @@ -270,7 +270,15 @@ return-type - For more information see . + + The row-mapper attribute of the Stored Procedure Inbound Channel Adapter + <returning-resultset/> sub-element + now supports a reference to a RowMapper bean + definition. Previously, it contained just a class name (which is still supported). + + + For more information see . +