BATCH 144 and BATCH 150: create Hibernate and iBatis input sources with sample jobs.

This commit is contained in:
lucasward
2007-10-15 05:23:00 +00:00
parent 30302f3d1f
commit ba7490b452
23 changed files with 935 additions and 417 deletions

View File

@@ -20,7 +20,12 @@
<config>src/main/resources/jobs/infiniteLoopJob.xml</config>
<config>src/main/resources/data-source-context-init.xml</config>
<config>src/main/resources/jobs/xmlStaxJob.xml</config>
<config>src/main/resources/jobs/hibernateJob.xml</config>
<config>src/main/resources/jobs/ibatisJob.xml</config>
<config>src/main/resources/jobs/compositeProcessorSampleJob.xml</config>
<config>src/main/resources/jobs/nflJob.xml</config>
<config>src/main/resources/jobs/simpleTaskletJob.xml</config>
<config>src/main/resources/beanRefContext.xml</config>
</configs>
<configSets>
<configSet>

View File

@@ -1,153 +1,171 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-batch-samples</artifactId>
<packaging>jar</packaging>
<name>Samples</name>
<description>
Example batch jobs using Spring Batch Core and Execution.
</description>
<parent>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch</artifactId>
<version>1.0-m3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-execution</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-validation</artifactId>
<version>0.8</version>
<exclusions>
<exclusion>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
</exclusion>
<exclusion>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-all</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-oxm</artifactId>
<version>1.0.0</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-j2ee</artifactId>
<version>1.4-rc4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<scope>test</scope>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>stax</groupId>
<artifactId>stax</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.3</version>
<configuration>
<!--forkMode>pertest</forkMode-->
<includes>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
<exclude>**/NflJobFunctionalTests.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-batch-samples</artifactId>
<packaging>jar</packaging>
<name>Samples</name>
<description>
Example batch jobs using Spring Batch Core and Execution.
</description>
<parent>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch</artifactId>
<version>1.0-m3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-execution</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-validation</artifactId>
<version>0.8</version>
<exclusions>
<exclusion>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
</exclusion>
<exclusion>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-all</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-oxm</artifactId>
<version>1.0.0</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-j2ee</artifactId>
<version>1.4-rc4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<scope>test</scope>
</dependency>
<!-- optional dependency from infrastructure -->
<dependency>
<groupId>stax</groupId>
<artifactId>stax</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<!-- Needed by Hibernate if JTA is excluded -->
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<!-- Force Hibernate to use a particular nodep version of cglib in case of clash with Spring AOP -->
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.3</version>
<configuration>
<!--forkMode>pertest</forkMode-->
<includes>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
<exclude>**/NflJobFunctionalTests.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -16,16 +16,17 @@
package org.springframework.batch.sample.dao;
import org.springframework.batch.io.OutputSource;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.sample.domain.CustomerCredit;
/**
* Interface for writing customer's credit information to output.
*
*
* @author Robert Kasanicky
*/
public interface CustomerCreditWriter extends ResourceLifecycle {
public interface CustomerCreditWriter extends OutputSource {
void write(CustomerCredit customerCredit);
}

View File

@@ -23,7 +23,7 @@ import org.springframework.beans.factory.DisposableBean;
/**
* Writes customer's credit information in a file.
*
*
* @see CustomerCreditWriter
* @author Robert Kasanicky
*/
@@ -71,10 +71,14 @@ public class FlatFileCustomerCreditWriter implements CustomerCreditWriter,
/*
* (non-Javadoc)
*
*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
public void write(Object output) {
write((CustomerCredit)output);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2006-2007 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.batch.sample.dao;
import org.springframework.batch.io.OutputSource;
import org.springframework.batch.sample.domain.CustomerCredit;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* @author Lucas Ward
*
*/
public class HibernateCreditWriter extends HibernateDaoSupport implements
CustomerCreditWriter {
/* (non-Javadoc)
* @see org.springframework.batch.sample.dao.CustomerCreditWriter#write(org.springframework.batch.sample.domain.CustomerCredit)
*/
public void write(CustomerCredit customerCredit) {
getHibernateTemplate().update(customerCredit);
}
/* (non-Javadoc)
* @see org.springframework.batch.io.OutputSource#write(java.lang.Object)
*/
public void write(Object output) {
write((CustomerCredit)output);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2006-2007 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.batch.sample.dao;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.OutputSource;
import org.springframework.batch.sample.domain.CustomerCredit;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
/**
* @author Lucas Ward
*
*/
public class IbatisCustomerCreditWriter extends SqlMapClientDaoSupport
implements CustomerCreditWriter, OutputSource {
String statementId;
/* (non-Javadoc)
* @see org.springframework.batch.sample.dao.CustomerCreditWriter#write(org.springframework.batch.sample.domain.CustomerCredit)
*/
public void write(CustomerCredit customerCredit) {
getSqlMapClientTemplate().update(statementId, customerCredit);
}
/* (non-Javadoc)
* @see org.springframework.batch.item.ResourceLifecycle#close()
*/
public void close() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.springframework.batch.item.ResourceLifecycle#open()
*/
public void open() {
// TODO Auto-generated method stub
}
public void setStatementId(String statementId) {
this.statementId = statementId;
}
public void write(Object output) {
write((CustomerCredit)output);
}
}

View File

@@ -1,57 +1,70 @@
/*
* Copyright 2006-2007 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.batch.sample.domain;
import java.math.BigDecimal;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class CustomerCredit {
private String name;
private BigDecimal credit;
public String toString() {
return "CustomerCredit [name=" + name + ", credit=" + credit + "]";
}
public BigDecimal getCredit() {
return credit;
}
public void setCredit(BigDecimal credit) {
this.credit = credit;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
/*
* Copyright 2006-2007 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.batch.sample.domain;
import java.math.BigDecimal;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class CustomerCredit {
private int id;
private String name;
private BigDecimal credit;
public String toString() {
return "CustomerCredit [id=" + id +",name=" + name + ", credit=" + credit + "]";
}
public BigDecimal getCredit() {
return credit;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setCredit(BigDecimal credit) {
this.credit = credit;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void increaseCreditBy(BigDecimal sum) {
this.credit = this.credit.add(sum);
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}

View File

@@ -0,0 +1,30 @@
package org.springframework.batch.sample.item.processor;
import java.math.BigDecimal;
import org.springframework.batch.io.OutputSource;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.sample.domain.CustomerCredit;
/**
* Increases customer's credit by fixed amount.
*
* @author Robert Kasanicky
*/
public class CustomerCreditIncreaseProcessor implements ItemProcessor{
public static final BigDecimal FIXED_AMOUNT = new BigDecimal(1000);
private OutputSource outputSource;
public void process(Object data) throws Exception {
CustomerCredit customerCredit = (CustomerCredit) data;
customerCredit.increaseCreditBy(FIXED_AMOUNT);
outputSource.write(customerCredit);
}
public void setOutputSource(OutputSource outputSource) {
this.outputSource = outputSource;
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.springframework.batch.sample.domain.CustomerCredit" table="CUSTOMER">
<id name="id" column="ID">
<generator class="native"/>
</id>
<property name="id" />
<property name="name" />
<property name="credit" />
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="ibatis-customer-credit.xml"/>
</sqlMapConfig>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Customer">
<resultMap id="result" class="org.springframework.batch.sample.domain.CustomerCredit">
<result property="name" column="NAME" />
<result property="credit" column="CREDIT" />
</resultMap>
<select id="getAllCustomerCreditIds" resultClass="int">
select ID from CUSTOMER
</select>
<select id="getCustomerCreditById" parameterClass="int" resultMap="result">
select NAME, CREDIT from CUSTOMER where ID = #value#
</select>
<update id="updateCredit" parameterClass="org.springframework.batch.sample.domain.CustomerCredit" >
update CUSTOMER set CREDIT = #credit# where NAME = #name#
</update>
</sqlMap>

View File

@@ -52,7 +52,7 @@
<bean id="fixedFileDescriptor" class="org.springframework.batch.io.file.support.transform.FixedLengthTokenizer">
<property name="names" value="ISIN, Quantity, Price, Customer" />
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />
</bean>
<bean id="fixedValidator" class="org.springframework.batch.item.validator.SpringValidator">

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<description>
Example for Hibernate integration.
</description>
<bean class="org.springframework.batch.execution.configuration.JobConfigurationRegistryBeanPostProcessor">
<property name="jobConfigurationRegistry" ref="jobConfigurationRegistry"/>
</bean>
<bean id="jobConfiguration" parent="simpleJob">
<property name="steps">
<bean id="step1" parent="simpleStep">
<property name="tasklet">
<bean
class="org.springframework.batch.execution.tasklet.RestartableItemProviderTasklet">
<property name="itemProvider">
<bean class="org.springframework.batch.item.provider.InputSourceItemProvider">
<property name="inputSource" ref="hibernateInputSource" />
</bean>
</property>
<property name="itemProcessor">
<bean class="org.springframework.batch.sample.item.processor.CustomerCreditIncreaseProcessor">
<property name="outputSource">
<bean class="org.springframework.batch.sample.dao.HibernateCreditWriter"
scope="step">
<aop:scoped-proxy />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="hibernateInputSource" class="org.springframework.batch.io.orm.hibernate.HibernateInputSource"
scope="step" >
<aop:scoped-proxy />
<property name="queryString" value="from CustomerCredit" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>CustomerCredit.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean parent="customEditorConfigurer"/>
<!-- register the step scope with the application context -->
<bean class="org.springframework.batch.execution.scope.StepScope" />
</beans>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<description>
Example for iBATIS integration.
</description>
<bean class="org.springframework.batch.execution.configuration.JobConfigurationRegistryBeanPostProcessor">
<property name="jobConfigurationRegistry" ref="jobConfigurationRegistry"/>
</bean>
<bean id="jobConfiguration" parent="simpleJob">
<property name="steps">
<bean id="step1" parent="simpleStep">
<property name="tasklet">
<bean
class="org.springframework.batch.execution.tasklet.RestartableItemProviderTasklet">
<property name="itemProvider">
<bean class="org.springframework.batch.item.provider.InputSourceItemProvider">
<property name="inputSource" ref="ibatisInputSource" />
</bean>
</property>
<property name="itemProcessor">
<bean class="org.springframework.batch.sample.item.processor.CustomerCreditIncreaseProcessor">
<property name="outputSource">
<bean class="org.springframework.batch.sample.dao.IbatisCustomerCreditWriter"
scope="step">
<aop:scoped-proxy />
<property name="sqlMapClient" ref="sqlMapClient" />
<property name="statementId" value="updateCredit" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="ibatisInputSource" class="org.springframework.batch.io.orm.ibatis.IbatisInputSource"
scope="step" >
<aop:scoped-proxy />
<property name="drivingQueryId" value="getAllCustomerCreditIds" />
<property name="detailsQueryId" value="getCustomerCreditById" />
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="ibatis-config.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean parent="customEditorConfigurer"/>
<!-- register the step scope with the application context -->
<bean class="org.springframework.batch.execution.scope.StepScope" />
</beans>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="orderFileDescriptor"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">

View File

@@ -89,4 +89,4 @@
<!-- register the step scope with the application context -->
<bean class="org.springframework.batch.execution.scope.StepScope" />
</beans>
</beans>

View File

@@ -23,7 +23,7 @@
</bean>
<bean id="jobConfigurationRegistry" class="org.springframework.batch.execution.configuration.MapJobConfigurationRegistry"/>
<aop:config>
<aop:advisor pointcut="execution(* org.springframework.batch.execution..*Repository+.*(..))"
advice-ref="txAdvice" />
@@ -73,7 +73,7 @@
<property name="scheduleDate" value="20070505" />
<property name="jobRun" value="1" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
@@ -119,7 +119,7 @@
</map>
</property>
</bean>
<bean id="itemProcessorLogAdvice" class="org.springframework.batch.sample.advice.ProcessorLogAdvice" />
<aop:config>

View File

@@ -0,0 +1,66 @@
package org.springframework.batch.sample;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
/**
* Test case for jobs that are expected to update customer credit value by fixed amount.
*
* @author Robert Kasanicky
*/
public abstract class AbstractCustomerCreditIncreaseTests extends AbstractLifecycleSpringContextTests {
private JdbcOperations jdbcTemplate;
private static final BigDecimal CREDIT_INCREASE = new BigDecimal(1000);
private static final String ALL_CUSTOMERS = "select * from CUSTOMER";
private static final String CREDIT_COLUMN = "CREDIT";
private List creditsBeforeUpdate;
public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* All customers have the same credit
*/
protected void validatePreConditions() throws Exception {
super.validatePreConditions();
creditsBeforeUpdate = jdbcTemplate.queryForList(ALL_CUSTOMERS);
jdbcTemplate.query(ALL_CUSTOMERS, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
creditsBeforeUpdate.set(rowNum, rs.getBigDecimal(CREDIT_COLUMN));
return null;
}
});
}
/**
* Credit was increased by REDIT_INCREASE
*/
protected void validatePostConditions() throws Exception {
jdbcTemplate.query(ALL_CUSTOMERS, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
final BigDecimal CREDIT_BEFORE_UPDATE = (BigDecimal) creditsBeforeUpdate.get(rowNum);
final BigDecimal EXPECTED_CREDIT = CREDIT_BEFORE_UPDATE.add(CREDIT_INCREASE);
assertTrue(EXPECTED_CREDIT.compareTo(rs.getBigDecimal(CREDIT_COLUMN)) == 0);
return null;
}
});
}
}

View File

@@ -0,0 +1,13 @@
package org.springframework.batch.sample;
/**
* Test for HibernateJob - checks that customer credit has been updated to expected value.
*
* @author Robert Kasanicky
*/
public class HibernateJobFunctionalTests extends AbstractCustomerCreditIncreaseTests {
protected String[] getConfigLocations() {
return new String[] {"jobs/hibernateJob.xml"};
}
}

View File

@@ -0,0 +1,15 @@
package org.springframework.batch.sample;
/**
* Test for IbatisJob - checks that customer credit has been updated to expected value.
*
* @author Robert Kasanicky
*/
public class IbatisJobFunctionalTests extends AbstractCustomerCreditIncreaseTests{
protected String[] getConfigLocations() {
return new String[] {"jobs/ibatisJob.xml"};
}
}

View File

@@ -1,196 +1,197 @@
/*
* Copyright 2006-2007 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.batch.sample;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.springframework.batch.sample.domain.Trade;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
public class TradeJobFunctionalTests extends AbstractLifecycleSpringContextTests {
private static final String GET_TRADES = "SELECT isin, quantity, price, customer FROM trade";
private static final String GET_CUSTOMERS = "SELECT name, credit FROM customer";
private ArrayList customers;
private ArrayList trades;
private int activeRow = 0;
private JdbcTemplate jdbcTemplate;
/**
* @param jdbcTemplate the jdbcTemplate to set
*/
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected String[] getConfigLocations() {
return new String[] {"jobs/tradeJob.xml"};
}
/* (non-Javadoc)
* @see org.springframework.test.AbstractSingleSpringContextTests#onSetUp()
*/
protected void onSetUp() throws Exception {
super.onSetUp();
jdbcTemplate.update("delete from TRADE");
}
public void testLifecycle() throws Exception{
super.testLifecycle();
}
protected void validatePostConditions() {
// assertTrue(((Resource)applicationContext.getBean("customerFileLocator")).exists());
customers = new ArrayList() {{add(new Customer("customer1", (100000 - 98.34)));
add(new Customer("customer2", (100000 - 18.12 - 12.78)));
add(new Customer("customer3", (100000 - 109.25)));
add(new Customer("customer4", (100000 - 123.39)));}};
trades = new ArrayList() {{add(new Trade("UK21341EAH45", 978, new BigDecimal("98.34"), "customer1"));
add(new Trade("UK21341EAH46", 112, new BigDecimal("18.12"), "customer2"));
add(new Trade("UK21341EAH47", 245, new BigDecimal("12.78"), "customer2"));
add(new Trade("UK21341EAH48", 108, new BigDecimal("109.25"), "customer3"));
add(new Trade("UK21341EAH49", 854, new BigDecimal("123.39"), "customer4"));}};
// check content of the trade table
jdbcTemplate.query(GET_TRADES, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Trade trade = (Trade)trades.get(activeRow++);
assertTrue(trade.getIsin().equals(rs.getString(1)));
assertTrue(trade.getQuantity() == rs.getLong(2));
assertTrue(trade.getPrice().equals(rs.getBigDecimal(3)));
assertTrue(trade.getCustomer().equals(rs.getString(4)));
}
});
assertTrue(trades.size() == activeRow);
// check content of the customer table
activeRow = 0;
jdbcTemplate.query(GET_CUSTOMERS, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Customer customer = (Customer)customers.get(activeRow++);
assertTrue(customer.getName().equals(rs.getString(1)));
assertTrue(customer.getCredit() == rs.getDouble(2));
}
});
assertTrue(customers.size() == activeRow);
// check content of the output file
// Clean up
((FileSystemResource)applicationContext.getBean("customerFileLocator")).getFile().delete();
}
protected void validatePreConditions() {
assertTrue(((Resource)applicationContext.getBean("fileLocator")).exists());
}
private class Customer {
private String name;
private double credit;
public Customer(String name, double credit) {
this.name = name;
this.credit = credit;
}
public Customer(){
}
/**
* @return the credit
*/
public double getCredit() {
return credit;
}
/**
* @param credit the credit to set
*/
public void setCredit(double credit) {
this.credit = credit;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final int PRIME = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(credit);
result = PRIME * result + (int) (temp ^ (temp >>> 32));
result = PRIME * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Customer other = (Customer) obj;
if (Double.doubleToLongBits(credit) != Double.doubleToLongBits(other.credit))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
}
/*
* Copyright 2006-2007 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.batch.sample;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.sample.domain.Trade;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowCallbackHandler;
public class TradeJobFunctionalTests extends AbstractLifecycleSpringContextTests {
private static final String GET_TRADES = "SELECT isin, quantity, price, customer FROM trade";
private static final String GET_CUSTOMERS = "SELECT name, credit FROM customer";
private List customers;
private List trades;
private int activeRow = 0;
private JdbcOperations jdbcTemplate;
/**
* @param jdbcTemplate the jdbcTemplate to set
*/
public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected String[] getConfigLocations() {
return new String[] {"jobs/tradeJob.xml"};
}
/* (non-Javadoc)
* @see org.springframework.test.AbstractSingleSpringContextTests#onSetUp()
*/
protected void onSetUp() throws Exception {
super.onSetUp();
jdbcTemplate.update("delete from TRADE");
}
public void testLifecycle() throws Exception{
super.testLifecycle();
}
protected void validatePostConditions() {
// assertTrue(((Resource)applicationContext.getBean("customerFileLocator")).exists());
customers = new ArrayList() {{add(new Customer("customer1", (100000 - 98.34)));
add(new Customer("customer2", (100000 - 18.12 - 12.78)));
add(new Customer("customer3", (100000 - 109.25)));
add(new Customer("customer4", (100000 - 123.39)));}};
trades = new ArrayList() {{add(new Trade("UK21341EAH45", 978, new BigDecimal("98.34"), "customer1"));
add(new Trade("UK21341EAH46", 112, new BigDecimal("18.12"), "customer2"));
add(new Trade("UK21341EAH47", 245, new BigDecimal("12.78"), "customer2"));
add(new Trade("UK21341EAH48", 108, new BigDecimal("109.25"), "customer3"));
add(new Trade("UK21341EAH49", 854, new BigDecimal("123.39"), "customer4"));}};
// check content of the trade table
jdbcTemplate.query(GET_TRADES, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Trade trade = (Trade)trades.get(activeRow++);
assertTrue(trade.getIsin().equals(rs.getString(1)));
assertTrue(trade.getQuantity() == rs.getLong(2));
assertTrue(trade.getPrice().equals(rs.getBigDecimal(3)));
assertTrue(trade.getCustomer().equals(rs.getString(4)));
}
});
assertTrue(trades.size() == activeRow);
// check content of the customer table
activeRow = 0;
jdbcTemplate.query(GET_CUSTOMERS, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Customer customer = (Customer)customers.get(activeRow++);
assertTrue(customer.getName().equals(rs.getString(1)));
assertTrue(customer.getCredit() == rs.getDouble(2));
}
});
assertTrue(customers.size() == activeRow);
// check content of the output file
// Clean up
((FileSystemResource)applicationContext.getBean("customerFileLocator")).getFile().delete();
}
protected void validatePreConditions() {
assertTrue(((Resource)applicationContext.getBean("fileLocator")).exists());
}
private class Customer {
private String name;
private double credit;
public Customer(String name, double credit) {
this.name = name;
this.credit = credit;
}
public Customer(){
}
/**
* @return the credit
*/
public double getCredit() {
return credit;
}
/**
* @param credit the credit to set
*/
public void setCredit(double credit) {
this.credit = credit;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final int PRIME = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(credit);
result = PRIME * result + (int) (temp ^ (temp >>> 32));
result = PRIME * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Customer other = (Customer) obj;
if (Double.doubleToLongBits(credit) != Double.doubleToLongBits(other.credit))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
}

View File

@@ -0,0 +1,53 @@
package org.springframework.batch.sample.item.processor;
import java.math.BigDecimal;
import org.easymock.MockControl;
import org.springframework.batch.io.OutputSource;
import org.springframework.batch.sample.domain.CustomerCredit;
import junit.framework.TestCase;
/**
* Tests for {@link CustomerCreditIncreaseProcessor}.
*
* @author Robert Kasanicky
*/
public class CustomerCreditIncreaseProcessorTests extends TestCase{
private CustomerCreditIncreaseProcessor processor = new CustomerCreditIncreaseProcessor();
private OutputSource outputSource;
private MockControl outputSourceControl = MockControl.createStrictControl(OutputSource.class);
private CustomerCredit customerCredit = new CustomerCredit();
protected void setUp() throws Exception {
customerCredit.setId(1);
customerCredit.setName("testCustomer");
outputSource = (OutputSource) outputSourceControl.getMock();
processor.setOutputSource(outputSource);
}
/**
* Increases customer's credit by fixed value
*/
public void testProcess() throws Exception {
BigDecimal oldCredit = new BigDecimal(10.54);
customerCredit.setCredit(oldCredit);
outputSource.write(customerCredit);
outputSourceControl.setVoidCallable();
outputSourceControl.replay();
processor.process(customerCredit);
BigDecimal newCredit = customerCredit.getCredit();
BigDecimal expectedCredit = oldCredit.add(CustomerCreditIncreaseProcessor.FIXED_AMOUNT);
assertTrue(newCredit.compareTo(expectedCredit) == 0);
outputSourceControl.verify();
}
}