BATCH-2110: Updated batch to support Spring 4
* Refactored iBatis based readers and writers to not utilize SqlMapClientTemplate. * Depricated all iBatis based readers and writers in favor of MyBatis's native Spring support. * Updated XStream support to 1.4.4 and Jettison to 1.2 to be in alignment with Spring 4. * Added the PooledEmbeddedDataSource to address the issue outlined in SPR-11372.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
The ./bin/runJob.(sh|bat) script from the extracted deployment archive can be invoked to run the job.
|
||||
</description>
|
||||
<properties>
|
||||
<spring.framework.version>3.2.0.RELEASE</spring.framework.version>
|
||||
<spring.framework.version>3.2.7.RELEASE</spring.framework.version>
|
||||
<spring.batch.version>3.0.0.BUILD-SNAPSHOT</spring.batch.version>
|
||||
<dependency.locations.enabled>false</dependency.locations.enabled>
|
||||
<junit.version>4.10</junit.version>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
The ./bin/runJob.(sh|bat) script from the extracted deployment archive can be invoked to run the job.
|
||||
</description>
|
||||
<properties>
|
||||
<spring.framework.version>3.2.0.RELEASE</spring.framework.version>
|
||||
<spring.framework.version>3.2.7.RELEASE</spring.framework.version>
|
||||
<spring.batch.version>3.0.0.BUILD-SNAPSHOT</spring.batch.version>
|
||||
<dependency.locations.enabled>false</dependency.locations.enabled>
|
||||
<junit.version>4.10</junit.version>
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2014 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.core;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
|
||||
/**
|
||||
* As of Spring 3.2, when a context is closed, the shutdown method is
|
||||
* called on any beans that are registered. With an embedded database
|
||||
* that uses a connection pool, this can leave the connection pool open
|
||||
* with stale connections. This wraps an {@link EmbeddedDatabase} and
|
||||
* ignores calls to {@link EmbeddedDatabase#shutdown()}.
|
||||
*
|
||||
* @author Phil Webb
|
||||
* @since 3.0
|
||||
*/
|
||||
public class PooledEmbeddedDataSource implements EmbeddedDatabase {
|
||||
|
||||
private final EmbeddedDatabase dataSource;
|
||||
|
||||
/**
|
||||
* @param dataSource The database to be wrapped
|
||||
*/
|
||||
public PooledEmbeddedDataSource(EmbeddedDatabase dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.DataSource#getConnection()
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return this.dataSource.getConnection();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
return this.dataSource.getConnection(username, password);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.CommonDataSource#getLogWriter()
|
||||
*/
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return this.dataSource.getLogWriter();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
|
||||
*/
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
this.dataSource.setLogWriter(out);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.CommonDataSource#getLoginTimeout()
|
||||
*/
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return this.dataSource.getLoginTimeout();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.sql.CommonDataSource#setLoginTimeout(int)
|
||||
*/
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
this.dataSource.setLoginTimeout(seconds);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.sql.Wrapper#unwrap(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return this.dataSource.unwrap(iface);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return this.dataSource.isWrapperFor(iface);
|
||||
}
|
||||
|
||||
public Logger getParentLogger() {
|
||||
return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.jdbc.datasource.embedded.EmbeddedDatabase#shutdown()
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.springframework.batch.core;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.job.JobSupport;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.support.ChildBeanDefinition;
|
||||
@@ -25,34 +27,42 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
|
||||
public class SpringBeanJobTests extends TestCase {
|
||||
public class SpringBeanJobTests {
|
||||
|
||||
@Test
|
||||
public void testBeanName() throws Exception {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
JobSupport configuration = new JobSupport();
|
||||
context.getAutowireCapableBeanFactory().initializeBean(configuration,
|
||||
"bean");
|
||||
context.refresh();
|
||||
assertNotNull(configuration.getName());
|
||||
configuration.setBeanName("foo");
|
||||
context.getAutowireCapableBeanFactory().initializeBean(configuration,
|
||||
"bean");
|
||||
assertEquals("bean", configuration.getName());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanNameWithBeanDefinition() throws Exception {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
ConstructorArgumentValues args = new ConstructorArgumentValues();
|
||||
args.addGenericArgumentValue("foo");
|
||||
context.registerBeanDefinition("bean", new RootBeanDefinition(
|
||||
JobSupport.class, args, null));
|
||||
|
||||
context.refresh();
|
||||
JobSupport configuration = (JobSupport) context
|
||||
.getBean("bean");
|
||||
assertNotNull(configuration.getName());
|
||||
assertEquals("foo", configuration.getName());
|
||||
configuration.setBeanName("bar");
|
||||
assertEquals("foo", configuration.getName());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanNameWithParentBeanDefinition() throws Exception {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
ConstructorArgumentValues args = new ConstructorArgumentValues();
|
||||
@@ -60,6 +70,7 @@ public class SpringBeanJobTests extends TestCase {
|
||||
context.registerBeanDefinition("parent", new RootBeanDefinition(
|
||||
JobSupport.class, args, null));
|
||||
context.registerBeanDefinition("bean", new ChildBeanDefinition("parent"));
|
||||
context.refresh();
|
||||
JobSupport configuration = (JobSupport) context
|
||||
.getBean("bean");
|
||||
assertNotNull(configuration.getName());
|
||||
@@ -68,5 +79,6 @@ public class SpringBeanJobTests extends TestCase {
|
||||
assertEquals("bar", configuration.getName());
|
||||
configuration.setName("foo");
|
||||
assertEquals("foo", configuration.getName());
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.core.configuration.annotation;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.core.PooledEmbeddedDataSource;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -31,13 +32,13 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
@Configuration
|
||||
public class DataSourceConfiguration {
|
||||
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
protected void initialize() {
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||
@@ -45,10 +46,10 @@ public class DataSourceConfiguration {
|
||||
populator.setContinueOnError(true);
|
||||
DatabasePopulatorUtils.execute(populator, dataSource());
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseFactory().getDatabase();
|
||||
return new PooledEmbeddedDataSource(new EmbeddedDatabaseFactory().getDatabase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JobBuilderConfigurationTests {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.PooledEmbeddedDataSource;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
|
||||
public class JsrJobParametersConverterTests {
|
||||
@@ -24,10 +25,10 @@ public class JsrJobParametersConverterTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void setupDatabase() {
|
||||
dataSource = new EmbeddedDatabaseBuilder().
|
||||
dataSource = new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
|
||||
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
|
||||
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
|
||||
build();
|
||||
build());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.sql.DataSource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.PooledEmbeddedDataSource;
|
||||
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.xml.DummyItemProcessor;
|
||||
@@ -101,10 +102,10 @@ public class BatchParserTests {
|
||||
|
||||
@Bean
|
||||
DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder().
|
||||
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
|
||||
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
|
||||
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
|
||||
build();
|
||||
build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,22 +10,22 @@ public class JdbcExecutionContextDaoTests extends AbstractExecutionContextDaoTes
|
||||
|
||||
@Override
|
||||
protected JobInstanceDao getJobInstanceDao() {
|
||||
return (JobInstanceDao) applicationContext.getBean("jobInstanceDao", JobInstanceDao.class);
|
||||
return applicationContext.getBean("jobInstanceDao", JobInstanceDao.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JobExecutionDao getJobExecutionDao() {
|
||||
return (JobExecutionDao) applicationContext.getBean("jobExecutionDao", JdbcJobExecutionDao.class);
|
||||
return applicationContext.getBean("jobExecutionDao", JdbcJobExecutionDao.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StepExecutionDao getStepExecutionDao() {
|
||||
return (StepExecutionDao) applicationContext.getBean("stepExecutionDao", StepExecutionDao.class);
|
||||
return applicationContext.getBean("stepExecutionDao", StepExecutionDao.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExecutionContextDao getExecutionContextDao() {
|
||||
return (ExecutionContextDao) applicationContext.getBean("executionContextDao", JdbcExecutionContextDao.class);
|
||||
return applicationContext.getBean("executionContextDao", JdbcExecutionContextDao.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package org.springframework.batch.core.repository.dao;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -30,6 +31,15 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
serializer = serializerDeserializer;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializePropertiesArrayContainer() throws Exception {
|
||||
PropertiesArrayContainer container = new PropertiesArrayContainer();
|
||||
container.setProps(new Properties[3]);
|
||||
|
||||
PropertiesArrayContainer result = (PropertiesArrayContainer) serializationRoundTrip(container);
|
||||
assertEquals(3, result.getProps().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAMap() throws Exception {
|
||||
Map<String, Object> m1 = new HashMap<String, Object>();
|
||||
@@ -39,7 +49,7 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
m1.put("object3", new Date(123456790123L));
|
||||
m1.put("object4", new Double(1234567.1234D));
|
||||
|
||||
Map<String, Object> m2 = serializationRoundTrip(m1);
|
||||
Map<String, Object> m2 = (Map<String, Object>) serializationRoundTrip(m1);
|
||||
|
||||
compareContexts(m1, m2);
|
||||
}
|
||||
@@ -61,7 +71,7 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
o1.setObj(o2);
|
||||
m1.put("co", o1);
|
||||
|
||||
Map<String, Object> m2 = serializationRoundTrip(m1);
|
||||
Map<String, Object> m2 = (Map<String, Object>) serializationRoundTrip(m1);
|
||||
|
||||
compareContexts(m1, m2);
|
||||
}
|
||||
@@ -80,14 +90,14 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> serializationRoundTrip(Map<String, Object> m1) throws IOException {
|
||||
private Object serializationRoundTrip(Object m1) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
serializer.serialize(m1, out);
|
||||
|
||||
String s = out.toString();
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
|
||||
Map<String, Object> m2 = (Map<String, Object>) serializer.deserialize(in);
|
||||
Object m2 = serializer.deserialize(in);
|
||||
return m2;
|
||||
}
|
||||
|
||||
@@ -133,15 +143,27 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ComplexObject that = (ComplexObject) o;
|
||||
|
||||
if (map != null ? !map.equals(that.map) : that.map != null) return false;
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
||||
if (number != null ? !number.equals(that.number) : that.number != null) return false;
|
||||
if (obj != null ? !obj.equals(that.obj) : that.obj != null) return false;
|
||||
if (map != null ? !map.equals(that.map) : that.map != null) {
|
||||
return false;
|
||||
}
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) {
|
||||
return false;
|
||||
}
|
||||
if (number != null ? !number.equals(that.number) : that.number != null) {
|
||||
return false;
|
||||
}
|
||||
if (obj != null ? !obj.equals(that.obj) : that.obj != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -160,6 +182,17 @@ public class XStreamExecutionContextStringSerializerTests {
|
||||
public String toString() {
|
||||
return "ComplexObject [name=" + name + ", number=" + number + "]";
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertiesArrayContainer {
|
||||
private Properties[] props;
|
||||
|
||||
public Properties[] getProps() {
|
||||
return props;
|
||||
}
|
||||
|
||||
public void setProps(Properties[] props) {
|
||||
this.props = props;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Repository tests using JDBC DAOs (rather than mocks).
|
||||
*
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -186,4 +186,4 @@ public class SimpleJobRepositoryIntegrationTests {
|
||||
assertEquals(jobExecution, jobRepository.getLastJobExecution(job.getName(), jobParameters));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.batch.core.ItemWriteListener;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.PooledEmbeddedDataSource;
|
||||
import org.springframework.batch.core.SkipListener;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
@@ -184,11 +185,11 @@ public class RegisterMultiListenerTests {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource(){
|
||||
return new EmbeddedDatabaseBuilder()
|
||||
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder()
|
||||
.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
|
||||
.addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
.build();
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,11 +215,11 @@ public class RegisterMultiListenerTests {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource(){
|
||||
return new EmbeddedDatabaseBuilder()
|
||||
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder()
|
||||
.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
|
||||
.addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
.build();
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,7 +53,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "/org/springframework/batch/core/repository/dao/sql-dao-test.xml")
|
||||
@@ -138,12 +138,12 @@ public class AsyncChunkOrientedStepIntegrationTests {
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
// Need a transaction so one connection is enough to get job execution and its parameters
|
||||
StepExecution lastStepExecution = new TransactionTemplate(transactionManager)
|
||||
.execute(new TransactionCallback<StepExecution>() {
|
||||
@Override
|
||||
public StepExecution doInTransaction(TransactionStatus status) {
|
||||
return jobRepository.getLastStepExecution(jobExecution.getJobInstance(), step.getName());
|
||||
}
|
||||
});
|
||||
.execute(new TransactionCallback<StepExecution>() {
|
||||
@Override
|
||||
public StepExecution doInTransaction(TransactionStatus status) {
|
||||
return jobRepository.getLastStepExecution(jobExecution.getJobInstance(), step.getName());
|
||||
}
|
||||
});
|
||||
assertEquals(lastStepExecution, stepExecution);
|
||||
assertFalse(lastStepExecution == stepExecution);
|
||||
}
|
||||
|
||||
@@ -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 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
<bean class="test.jdbc.datasource.DataSourceInitializer">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="initScripts">
|
||||
@@ -37,4 +37,4 @@
|
||||
<bean id="stepExecutionIncrementer" parent="incrementerParent">
|
||||
<property name="incrementerName" value="BATCH_STEP_EXECUTION_SEQ" />
|
||||
</bean>
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -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 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<import resource="data-source-context.xml" />
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
</bean>
|
||||
|
||||
<bean id="serializer" class="org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer"/>
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
<version>2.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<scope>test</scope>
|
||||
|
||||
@@ -22,15 +22,15 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
|
||||
@@ -55,7 +55,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
maxId = jdbcTemplate.queryForInt("SELECT MAX(ID) from T_FOOS");
|
||||
for (int i = ITEM_COUNT; i > maxId; i--) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
|
||||
@@ -65,7 +65,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
.newFixedThreadPool(THREAD_COUNT));
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
completionService.submit(new Callable<List<Foo>>() {
|
||||
@Override
|
||||
public List<Foo> call() throws Exception {
|
||||
List<Foo> list = new ArrayList<Foo>();
|
||||
Foo next = null;
|
||||
@@ -130,17 +131,13 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
}
|
||||
|
||||
private IbatisPagingItemReader<Foo> getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = createSqlMapClient();
|
||||
SqlMapClient sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
|
||||
|
||||
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
|
||||
if ("postgres".equals(System.getProperty("ENVIRONMENT"))) {
|
||||
reader.setQueryId("getPagedFoosPostgres");
|
||||
reader.setQueryId("getPagedFoosPostgres");
|
||||
} else if ("oracle".equals(System.getProperty("ENVIRONMENT"))) {
|
||||
reader.setQueryId("getPagedFoosOracle");
|
||||
reader.setQueryId("getPagedFoosOracle");
|
||||
} else {
|
||||
reader.setQueryId("getPagedFoos");
|
||||
}
|
||||
@@ -154,11 +151,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
}
|
||||
|
||||
private SqlMapClient createSqlMapClient() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
return (SqlMapClient) factory.getObject();
|
||||
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2013 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -15,27 +15,34 @@
|
||||
*/
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.orm.ibatis.SqlMapClientCallback;
|
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapExecutor;
|
||||
import com.ibatis.sqlmap.client.SqlMapSession;
|
||||
import com.ibatis.sqlmap.engine.execution.BatchException;
|
||||
import com.ibatis.sqlmap.engine.execution.BatchResult;
|
||||
|
||||
/**
|
||||
* {@link ItemWriter} that uses the batching features from
|
||||
* SqlMapClientTemplate to execute a batch of statements for all items
|
||||
* SqlMapClient to execute a batch of statements for all items
|
||||
* provided.<br/>
|
||||
*
|
||||
* The user must provide an iBATIS statement id that points to the SQL statement defined
|
||||
@@ -44,21 +51,35 @@ import com.ibatis.sqlmap.engine.execution.BatchResult;
|
||||
* It is expected that {@link #write(List)} is called inside a transaction.<br/>
|
||||
*
|
||||
* The writer is thread safe after its properties are set (normal singleton
|
||||
* behavior), so it can be used to write in multiple concurrent transactions.
|
||||
* behavior), so it can be used to write in multiple concurrent transactions.<br/>
|
||||
*
|
||||
* <em>Note:</em> This reader was refactored as part of Spring Batch 3.0 to use the iBatis
|
||||
* APIs directly instead of using Spring's SqlMapClientTemplate as part of the upgrade to
|
||||
* support Spring 4.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
* @deprecated as of Spring Batch 3.0, in favor of the native Spring Batch support
|
||||
* in the MyBatis follow-up project (http://mybatis.github.io/spring/)
|
||||
*/
|
||||
@Deprecated
|
||||
public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(IbatisBatchItemWriter.class);
|
||||
|
||||
private SqlMapClientTemplate sqlMapClientTemplate;
|
||||
|
||||
private String statementId;
|
||||
|
||||
private boolean assertUpdates = true;
|
||||
|
||||
private SqlMapClient sqlMapClient;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the flag that determines whether an assertion is made
|
||||
* that all items cause at least one row to be updated.
|
||||
@@ -75,18 +96,7 @@ public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean
|
||||
* @param sqlMapClient the SqlMapClient
|
||||
*/
|
||||
public void setSqlMapClient(SqlMapClient sqlMapClient) {
|
||||
if (sqlMapClientTemplate == null) {
|
||||
this.sqlMapClientTemplate = new SqlMapClientTemplate(sqlMapClient);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the SqlMapClientTemplate.
|
||||
*
|
||||
* @param sqlMapClientTemplate the SqlMapClientTemplate
|
||||
*/
|
||||
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
|
||||
this.sqlMapClientTemplate = sqlMapClientTemplate;
|
||||
this.sqlMapClient = sqlMapClient;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +114,7 @@ public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(sqlMapClientTemplate, "A SqlMapClient or a SqlMapClientTemplate is required.");
|
||||
Assert.notNull(sqlMapClient, "A SqlMapClient is required.");
|
||||
Assert.notNull(statementId, "A statementId is required.");
|
||||
}
|
||||
|
||||
@@ -120,23 +130,7 @@ public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean
|
||||
logger.debug("Executing batch with " + items.size() + " items.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<BatchResult> results = (List<BatchResult>) sqlMapClientTemplate.execute(
|
||||
new SqlMapClientCallback() {
|
||||
@Override
|
||||
public Object doInSqlMapClient(SqlMapExecutor executor)
|
||||
throws SQLException {
|
||||
executor.startBatch();
|
||||
for (T item : items) {
|
||||
executor.update(statementId, item);
|
||||
}
|
||||
try {
|
||||
return executor.executeBatchDetailed();
|
||||
} catch (BatchException e) {
|
||||
throw e.getBatchUpdateException();
|
||||
}
|
||||
}
|
||||
});
|
||||
List<BatchResult> results = execute(items);
|
||||
|
||||
if (assertUpdates) {
|
||||
if (results.size() != 1) {
|
||||
@@ -154,9 +148,81 @@ public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<BatchResult> execute(final List<? extends T> items) {
|
||||
// We always need to use a SqlMapSession, as we need to pass a Spring-managed
|
||||
// Connection (potentially transactional) in. This shouldn't be necessary if
|
||||
// we run against a TransactionAwareDataSourceProxy underneath, but unfortunately
|
||||
// we still need it to make iBATIS batch execution work properly: If iBATIS
|
||||
// doesn't recognize an existing transaction, it automatically executes the
|
||||
// batch for every single statement...
|
||||
|
||||
SqlMapSession session = this.sqlMapClient.openSession();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation");
|
||||
}
|
||||
Connection ibatisCon = null;
|
||||
|
||||
try {
|
||||
Connection springCon = null;
|
||||
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
|
||||
|
||||
// Obtain JDBC Connection to operate on...
|
||||
try {
|
||||
ibatisCon = session.getCurrentConnection();
|
||||
if (ibatisCon == null) {
|
||||
springCon = (transactionAware ?
|
||||
dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
|
||||
session.setUserConnection(springCon);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
|
||||
}
|
||||
|
||||
// Execute given callback...
|
||||
try {
|
||||
session.startBatch();
|
||||
for (T item : items) {
|
||||
session.update(statementId, item);
|
||||
}
|
||||
try {
|
||||
return session.executeBatchDetailed();
|
||||
} catch (BatchException e) {
|
||||
throw e.getBatchUpdateException();
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
SQLExceptionTranslator sqlStateSQLExceptionTranslator;
|
||||
|
||||
if(dataSource != null) {
|
||||
sqlStateSQLExceptionTranslator = new SQLStateSQLExceptionTranslator();
|
||||
} else {
|
||||
sqlStateSQLExceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
|
||||
}
|
||||
|
||||
throw sqlStateSQLExceptionTranslator.translate("SqlMapClient operation", null, ex);
|
||||
}
|
||||
|
||||
// Processing finished - potentially session still to be closed.
|
||||
}
|
||||
finally {
|
||||
// Only close SqlMapSession if we know we've actually opened it
|
||||
// at the present level.
|
||||
if (ibatisCon == null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2013 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -16,16 +16,27 @@
|
||||
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapSession;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -67,24 +78,36 @@ import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
* available).
|
||||
* </p>
|
||||
*
|
||||
* <p><em>Note:</em> This reader was refactored as part of Spring Batch 3.0 to use the iBatis
|
||||
* APIs directly instead of using Spring's SqlMapClientTemplate as part of the upgrade to
|
||||
* support Spring 4.</p>
|
||||
|
||||
* @author Thomas Risberg
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
* @deprecated as of Spring Batch 3.0, in favor of the native Spring Batch support
|
||||
* in the MyBatis follow-up project (http://mybatis.github.io/spring/)
|
||||
*/
|
||||
@Deprecated
|
||||
public class IbatisPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
|
||||
private SqlMapClient sqlMapClient;
|
||||
|
||||
private String queryId;
|
||||
|
||||
private SqlMapClientTemplate sqlMapClientTemplate;
|
||||
|
||||
private Map<String, Object> parameterValues;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
public IbatisPagingItemReader() {
|
||||
setName(ClassUtils.getShortName(IbatisPagingItemReader.class));
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public void setSqlMapClient(SqlMapClient sqlMapClient) {
|
||||
this.sqlMapClient = sqlMapClient;
|
||||
}
|
||||
@@ -111,12 +134,10 @@ public class IbatisPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(sqlMapClient);
|
||||
sqlMapClientTemplate = new SqlMapClientTemplate(sqlMapClient);
|
||||
Assert.notNull(queryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void doReadPage() {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>();
|
||||
if (parameterValues != null) {
|
||||
@@ -131,7 +152,89 @@ public class IbatisPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
else {
|
||||
results.clear();
|
||||
}
|
||||
results.addAll(sqlMapClientTemplate.queryForList(queryId, parameters));
|
||||
results.addAll(execute(parameters));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<T> execute(Map<String, Object> parameters) {
|
||||
// We always need to use a SqlMapSession, as we need to pass a Spring-managed
|
||||
// Connection (potentially transactional) in. This shouldn't be necessary if
|
||||
// we run against a TransactionAwareDataSourceProxy underneath, but unfortunately
|
||||
// we still need it to make iBATIS batch execution work properly: If iBATIS
|
||||
// doesn't recognize an existing transaction, it automatically executes the
|
||||
// batch for every single statement...
|
||||
|
||||
SqlMapSession session = this.sqlMapClient.openSession();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation");
|
||||
}
|
||||
Connection ibatisCon = null;
|
||||
|
||||
try {
|
||||
Connection springCon = null;
|
||||
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
|
||||
|
||||
// Obtain JDBC Connection to operate on...
|
||||
try {
|
||||
ibatisCon = session.getCurrentConnection();
|
||||
if (ibatisCon == null) {
|
||||
springCon = (transactionAware ?
|
||||
dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
|
||||
session.setUserConnection(springCon);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
|
||||
}
|
||||
|
||||
// Execute given callback...
|
||||
try {
|
||||
return session.queryForList(queryId, parameters);
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
SQLExceptionTranslator sqlStateSQLExceptionTranslator;
|
||||
|
||||
if(dataSource != null) {
|
||||
sqlStateSQLExceptionTranslator = new SQLStateSQLExceptionTranslator();
|
||||
} else {
|
||||
sqlStateSQLExceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
|
||||
}
|
||||
|
||||
throw sqlStateSQLExceptionTranslator.translate("SqlMapClient operation", null, ex);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (springCon != null) {
|
||||
if (transactionAware) {
|
||||
springCon.close();
|
||||
}
|
||||
else {
|
||||
DataSourceUtils.doReleaseConnection(springCon, dataSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Could not close JDBC Connection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Processing finished - potentially session still to be closed.
|
||||
}
|
||||
finally {
|
||||
// Only close SqlMapSession if we know we've actually opened it
|
||||
// at the present level.
|
||||
if (ibatisCon == null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -27,7 +29,6 @@ import javax.sql.DataSource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapSession;
|
||||
@@ -42,11 +43,9 @@ public class IbatisBatchItemWriterTests {
|
||||
private IbatisBatchItemWriter<Foo> writer = new IbatisBatchItemWriter<Foo>();
|
||||
|
||||
private DataSource ds;
|
||||
|
||||
private SqlMapClientTemplate smct;
|
||||
|
||||
|
||||
private SqlMapClient smc;
|
||||
|
||||
|
||||
private String statementId = "updateFoo";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -58,7 +57,7 @@ public class IbatisBatchItemWriterTests {
|
||||
this.id = 1L;
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -91,16 +90,16 @@ public class IbatisBatchItemWriterTests {
|
||||
public int hashCode() {
|
||||
return bar.hashCode();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
smc = mock(SqlMapClient.class);
|
||||
ds = mock(DataSource.class);
|
||||
smct = new SqlMapClientTemplate(ds, smc);
|
||||
writer.setStatementId(statementId);
|
||||
writer.setSqlMapClientTemplate(smct);
|
||||
writer.setSqlMapClient(smc);
|
||||
writer.setDataSource(ds);
|
||||
writer.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@@ -122,7 +121,7 @@ public class IbatisBatchItemWriterTests {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'SqlMapClient'.", message.indexOf("SqlMapClient") >= 0);
|
||||
}
|
||||
writer.setSqlMapClientTemplate(smct);
|
||||
writer.setSqlMapClient(smc);
|
||||
try {
|
||||
writer.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
@@ -138,7 +137,7 @@ public class IbatisBatchItemWriterTests {
|
||||
|
||||
@Test
|
||||
public void testWriteAndFlush() throws Exception {
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
when(smc.openSession()).thenReturn(sms);
|
||||
sms.close();
|
||||
when(sms.getCurrentConnection()).thenReturn(null);
|
||||
@@ -153,7 +152,7 @@ public class IbatisBatchItemWriterTests {
|
||||
|
||||
@Test
|
||||
public void testWriteAndFlushWithEmptyUpdate() throws Exception {
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
when(smc.openSession()).thenReturn(sms);
|
||||
sms.close();
|
||||
when(sms.getCurrentConnection()).thenReturn(null);
|
||||
@@ -177,7 +176,7 @@ public class IbatisBatchItemWriterTests {
|
||||
@Test
|
||||
public void testWriteAndFlushWithFailure() throws Exception {
|
||||
final RuntimeException ex = new RuntimeException("ERROR");
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
SqlMapSession sms = mock(SqlMapSession.class);
|
||||
when(smc.openSession()).thenReturn(sms);
|
||||
sms.close();
|
||||
when(sms.getCurrentConnection()).thenReturn(null);
|
||||
|
||||
@@ -25,12 +25,12 @@ import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
|
||||
@@ -98,7 +98,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
.newFixedThreadPool(THREAD_COUNT));
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
completionService.submit(new Callable<List<Foo>>() {
|
||||
@Override
|
||||
@Override
|
||||
public List<Foo> call() throws Exception {
|
||||
List<Foo> list = new ArrayList<Foo>();
|
||||
Foo next = null;
|
||||
@@ -130,10 +130,6 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
}
|
||||
|
||||
private IbatisPagingItemReader<Foo> getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = createSqlMapClient();
|
||||
|
||||
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
|
||||
@@ -141,6 +137,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
reader.setPageSize(2);
|
||||
reader.setSqlMapClient(sqlMapClient);
|
||||
reader.setSaveState(true);
|
||||
reader.setDataSource(dataSource);
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
@@ -148,11 +145,7 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
}
|
||||
|
||||
private SqlMapClient createSqlMapClient() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
return (SqlMapClient) factory.getObject();
|
||||
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class IbatisPagingItemReaderCommonTests extends AbstractDatabaseItemStreamItemReaderTests {
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
protected ItemReader<Foo> getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(getDataSource());
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = createSqlMapClient();
|
||||
|
||||
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
|
||||
reader.setQueryId("getPagedFoos");
|
||||
reader.setPageSize(2);
|
||||
reader.setSqlMapClient(sqlMapClient);
|
||||
reader.setDataSource(getDataSource());
|
||||
reader.setSaveState(true);
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
@@ -33,14 +30,10 @@ public class IbatisPagingItemReaderCommonTests extends AbstractDatabaseItemStrea
|
||||
}
|
||||
|
||||
private SqlMapClient createSqlMapClient() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(getDataSource());
|
||||
factory.afterPropertiesSet();
|
||||
return (SqlMapClient) factory.getObject();
|
||||
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void pointToEmptyInput(ItemReader<Foo> tested) throws Exception {
|
||||
IbatisPagingItemReader<Foo> reader = (IbatisPagingItemReader<Foo>) tested;
|
||||
reader.close();
|
||||
|
||||
@@ -5,28 +5,26 @@ import java.util.Collections;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "/org/springframework/batch/item/database/data-source-context.xml")
|
||||
public class IbatisPagingItemReaderParameterTests extends AbstractPagingItemReaderParameterTests {
|
||||
|
||||
@Override
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected AbstractPagingItemReader<Foo> getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = createSqlMapClient();
|
||||
|
||||
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
|
||||
reader.setQueryId("getPagedFoos3AndUp");
|
||||
reader.setParameterValues(Collections.<String, Object>singletonMap("limit", 3));
|
||||
reader.setSqlMapClient(sqlMapClient);
|
||||
reader.setDataSource(dataSource);
|
||||
reader.setSaveState(true);
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
@@ -35,11 +33,7 @@ public class IbatisPagingItemReaderParameterTests extends AbstractPagingItemRead
|
||||
}
|
||||
|
||||
private SqlMapClient createSqlMapClient() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
return (SqlMapClient) factory.getObject();
|
||||
SqlMapClient client = SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</developer>
|
||||
</developers>
|
||||
<properties>
|
||||
<spring.framework.version>3.2.0.RELEASE</spring.framework.version>
|
||||
<spring.framework.version>3.2.7.RELEASE</spring.framework.version>
|
||||
<spring.amqp.version>1.1.2.RELEASE</spring.amqp.version>
|
||||
<junit.version>4.10</junit.version>
|
||||
<bundlor.version>1.0.0.RELEASE</bundlor.version>
|
||||
@@ -552,12 +552,12 @@
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.3</version>
|
||||
<version>1.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jettison</groupId>
|
||||
<artifactId>jettison</artifactId>
|
||||
<version>1.1</version>
|
||||
<version>1.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>stax</groupId>
|
||||
@@ -565,10 +565,10 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ibatis</groupId>
|
||||
<artifactId>ibatis-sqlmap</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>2.3.4.726</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>org.springmodules</groupId>
|
||||
<artifactId>spring-modules-validation</artifactId>
|
||||
<version>0.8</version>
|
||||
<version>0.8a</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>rhino</groupId>
|
||||
@@ -119,7 +119,7 @@
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
</dependency>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* Returns Boolean.TRUE if given value is future date, else it returns Boolean.FALSE
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class FutureDateFunction extends AbstractFunction {
|
||||
|
||||
public FutureDateFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
protected Object doGetResult(final Object target) throws Exception {
|
||||
//get argument
|
||||
final Object value = getArguments()[0].getResult(target);
|
||||
|
||||
Boolean result;
|
||||
|
||||
if (value instanceof Date) {
|
||||
final Date now = new Date(System.currentTimeMillis());
|
||||
final Date date = (Date) value;
|
||||
result = (now.compareTo(date) < 0) ? Boolean.TRUE : Boolean.FALSE;
|
||||
} else {
|
||||
throw new Exception("No Date value for validation");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* Validates total items count in Order.
|
||||
*
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class TotalOrderItemsFunction extends AbstractFunction {
|
||||
public TotalOrderItemsFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
//get arguments
|
||||
int count = (Integer) getArguments()[0].getResult(target);
|
||||
Object value = getArguments()[1].getResult(target);
|
||||
|
||||
Boolean result;
|
||||
|
||||
//count items in list of order lines
|
||||
if (value instanceof List) {
|
||||
int totalItems = 0;
|
||||
|
||||
for (LineItem lineItem : ((List<LineItem>) value)) {
|
||||
totalItems += lineItem.getQuantity();
|
||||
}
|
||||
|
||||
result = (totalItems == count) ? Boolean.TRUE : Boolean.FALSE;
|
||||
} else {
|
||||
throw new Exception("No list for validation");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateDiscountsFunction extends AbstractFunction {
|
||||
private static final BigDecimal BD_0 = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_PERC_MAX = new BigDecimal(100.0);
|
||||
|
||||
public ValidateDiscountsFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if (BD_0.compareTo(item.getDiscountPerc()) != 0) {
|
||||
//DiscountPerc must be between 0.0 and 100.0
|
||||
if ((BD_0.compareTo(item.getDiscountPerc()) > 0)
|
||||
|| (BD_PERC_MAX.compareTo(item.getDiscountPerc()) < 0)
|
||||
|| (BD_0.compareTo(item.getDiscountAmount()) != 0)) { //only one of DiscountAmount and DiscountPerc should be non-zero
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
} else {
|
||||
//DiscountAmount must be between 0.0 and item.price
|
||||
if ((BD_0.compareTo(item.getDiscountAmount()) > 0)
|
||||
|| (item.getPrice().compareTo(item.getDiscountAmount()) < 0)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateHandlingPricesFunction extends AbstractFunction {
|
||||
private static final BigDecimal BD_MIN = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_MAX = new BigDecimal(99999999.99);
|
||||
|
||||
public ValidateHandlingPricesFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((BD_MIN.compareTo(item.getHandlingPrice()) > 0)
|
||||
|| (BD_MAX.compareTo(item.getHandlingPrice()) < 0)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateIdsFunction extends AbstractFunction {
|
||||
private static final long MAX_ID = 9999999999L;
|
||||
|
||||
public ValidateIdsFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((item.getItemId() <= 0) || (item.getItemId() > MAX_ID)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidatePricesFunction extends AbstractFunction {
|
||||
private static final BigDecimal BD_MIN = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_MAX = new BigDecimal(99999999.99);
|
||||
|
||||
public ValidatePricesFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((BD_MIN.compareTo(item.getPrice()) > 0) || (BD_MAX.compareTo(item.getPrice()) < 0)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateQuantitiesFunction extends AbstractFunction {
|
||||
private static final int MAX_QUANTITY = 9999;
|
||||
|
||||
public ValidateQuantitiesFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((item.getQuantity() <= 0) || (item.getQuantity() > MAX_QUANTITY)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateShippingPricesFunction extends AbstractFunction {
|
||||
private static final BigDecimal BD_MIN = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_MAX = new BigDecimal(99999999.99);
|
||||
|
||||
public ValidateShippingPricesFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((BD_MIN.compareTo(item.getShippingPrice()) > 0)
|
||||
|| (BD_MAX.compareTo(item.getShippingPrice()) < 0)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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.order.internal.valang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.AbstractFunction;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
|
||||
/**
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class ValidateTotalPricesFunction extends AbstractFunction {
|
||||
private static final BigDecimal BD_MIN = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_MAX = new BigDecimal(99999999.99);
|
||||
private static final BigDecimal BD_100 = new BigDecimal(100.00);
|
||||
|
||||
public ValidateTotalPricesFunction(Function[] arguments, int line, int column) {
|
||||
super(arguments, line, column);
|
||||
definedExactNumberOfArguments(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springmodules.validation.valang.functions.AbstractFunction#doGetResult(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doGetResult(Object target) throws Exception {
|
||||
List<LineItem> lineItems = (List<LineItem>) getArguments()[0].getResult(target);
|
||||
|
||||
for (LineItem item : lineItems) {
|
||||
|
||||
if ((BD_MIN.compareTo(item.getTotalPrice()) > 0)
|
||||
|| (BD_MAX.compareTo(item.getTotalPrice()) < 0)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
//calculate total price
|
||||
|
||||
//discount coeficient = (100.00 - discountPerc) / 100.00
|
||||
BigDecimal coef = BD_100.subtract(item.getDiscountPerc())
|
||||
.divide(BD_100, 4, BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
//discountedPrice = (price * coef) - discountAmount
|
||||
//at least one of discountPerc and discountAmount is 0 - this is validated by ValidateDiscountsFunction
|
||||
BigDecimal discountedPrice = item.getPrice().multiply(coef)
|
||||
.subtract(item.getDiscountAmount());
|
||||
|
||||
//price for single item = discountedPrice + shipping + handling
|
||||
BigDecimal singleItemPrice = discountedPrice.add(item.getShippingPrice())
|
||||
.add(item.getHandlingPrice());
|
||||
|
||||
//total price = singleItemPrice * quantity
|
||||
BigDecimal quantity = new BigDecimal(item.getQuantity());
|
||||
BigDecimal totalPrice = singleItemPrice.multiply(quantity)
|
||||
.setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
//calculatedPrice should equal to item.totalPrice
|
||||
if (totalPrice.compareTo(item.getTotalPrice()) != 0) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.validator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.sample.domain.order.Address;
|
||||
import org.springframework.batch.sample.domain.order.BillingInfo;
|
||||
import org.springframework.batch.sample.domain.order.Customer;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springframework.batch.sample.domain.order.Order;
|
||||
import org.springframework.batch.sample.domain.order.ShippingInfo;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
public class OrderValidator implements Validator {
|
||||
|
||||
private static final List<String> CARD_TYPES = new ArrayList<String>();
|
||||
private static final List<String> SHIPPER_IDS = new ArrayList<String>();
|
||||
private static final List<String> SHIPPER_TYPES = new ArrayList<String>();
|
||||
private static final long MAX_ID = 9999999999L;
|
||||
private static final BigDecimal BD_MIN = new BigDecimal(0.0);
|
||||
private static final BigDecimal BD_MAX = new BigDecimal(99999999.99);
|
||||
private static final BigDecimal BD_PERC_MAX = new BigDecimal(100.0);
|
||||
private static final int MAX_QUANTITY = 9999;
|
||||
private static final BigDecimal BD_100 = new BigDecimal(100.00);
|
||||
|
||||
static {
|
||||
CARD_TYPES.add("VISA");
|
||||
CARD_TYPES.add("AMEX");
|
||||
CARD_TYPES.add("ECMC");
|
||||
CARD_TYPES.add("DCIN");
|
||||
CARD_TYPES.add("PAYP");
|
||||
|
||||
SHIPPER_IDS.add("FEDX");
|
||||
SHIPPER_IDS.add("UPS");
|
||||
SHIPPER_IDS.add("DHL");
|
||||
SHIPPER_IDS.add("DPD");
|
||||
|
||||
SHIPPER_TYPES.add("STD");
|
||||
SHIPPER_TYPES.add("EXP");
|
||||
SHIPPER_TYPES.add("AMS");
|
||||
SHIPPER_TYPES.add("AME");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> arg0) {
|
||||
return arg0.isAssignableFrom(Order.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object arg0, Errors errors) {
|
||||
Order item = null;
|
||||
try {
|
||||
item = (Order) arg0;
|
||||
} catch (ClassCastException cce) {
|
||||
errors.reject("Incorrect type");
|
||||
}
|
||||
|
||||
if(item != null) {
|
||||
validateOrder(item, errors);
|
||||
validateCustomer(item.getCustomer(), errors);
|
||||
validateAddress(item.getBillingAddress(), errors, "billingAddress");
|
||||
validateAddress(item.getShippingAddress(), errors, "shippingAddress");
|
||||
validatePayment(item.getBilling(), errors);
|
||||
validateShipping(item.getShipping(), errors);
|
||||
validateLineItems(item.getLineItems(), errors);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateLineItems(List<LineItem> lineItems, Errors errors) {
|
||||
boolean ids = true;
|
||||
boolean prices = true;
|
||||
boolean discounts = true;
|
||||
boolean shippingPrices = true;
|
||||
boolean handlingPrices = true;
|
||||
boolean quantities = true;
|
||||
boolean totalPrices = true;
|
||||
|
||||
for (LineItem lineItem : lineItems) {
|
||||
if(lineItem.getItemId() <= 0 || lineItem.getItemId() > MAX_ID) {
|
||||
ids = false;
|
||||
}
|
||||
|
||||
if((BD_MIN.compareTo(lineItem.getPrice()) > 0) || (BD_MAX.compareTo(lineItem.getPrice()) < 0)) {
|
||||
prices = false;
|
||||
}
|
||||
|
||||
if (BD_MIN.compareTo(lineItem.getDiscountPerc()) != 0) {
|
||||
//DiscountPerc must be between 0.0 and 100.0
|
||||
if ((BD_MIN.compareTo(lineItem.getDiscountPerc()) > 0)
|
||||
|| (BD_PERC_MAX.compareTo(lineItem.getDiscountPerc()) < 0)
|
||||
|| (BD_MIN.compareTo(lineItem.getDiscountAmount()) != 0)) { //only one of DiscountAmount and DiscountPerc should be non-zero
|
||||
discounts = false;
|
||||
}
|
||||
} else {
|
||||
//DiscountAmount must be between 0.0 and item.price
|
||||
if ((BD_MIN.compareTo(lineItem.getDiscountAmount()) > 0)
|
||||
|| (lineItem.getPrice().compareTo(lineItem.getDiscountAmount()) < 0)) {
|
||||
discounts = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((BD_MIN.compareTo(lineItem.getShippingPrice()) > 0) || (BD_MAX.compareTo(lineItem.getShippingPrice()) < 0)) {
|
||||
shippingPrices = false;
|
||||
}
|
||||
|
||||
if ((BD_MIN.compareTo(lineItem.getHandlingPrice()) > 0) || (BD_MAX.compareTo(lineItem.getHandlingPrice()) < 0)) {
|
||||
handlingPrices = false;
|
||||
}
|
||||
|
||||
if ((lineItem.getQuantity() <= 0) || (lineItem.getQuantity() > MAX_QUANTITY)) {
|
||||
quantities = false;
|
||||
}
|
||||
|
||||
|
||||
if ((BD_MIN.compareTo(lineItem.getTotalPrice()) > 0)
|
||||
|| (BD_MAX.compareTo(lineItem.getTotalPrice()) < 0)) {
|
||||
totalPrices = false;
|
||||
}
|
||||
|
||||
//calculate total price
|
||||
|
||||
//discount coeficient = (100.00 - discountPerc) / 100.00
|
||||
BigDecimal coef = BD_100.subtract(lineItem.getDiscountPerc())
|
||||
.divide(BD_100, 4, BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
//discountedPrice = (price * coef) - discountAmount
|
||||
//at least one of discountPerc and discountAmount is 0 - this is validated by ValidateDiscountsFunction
|
||||
BigDecimal discountedPrice = lineItem.getPrice().multiply(coef)
|
||||
.subtract(lineItem.getDiscountAmount());
|
||||
|
||||
//price for single item = discountedPrice + shipping + handling
|
||||
BigDecimal singleItemPrice = discountedPrice.add(lineItem.getShippingPrice())
|
||||
.add(lineItem.getHandlingPrice());
|
||||
|
||||
//total price = singleItemPrice * quantity
|
||||
BigDecimal quantity = new BigDecimal(lineItem.getQuantity());
|
||||
BigDecimal totalPrice = singleItemPrice.multiply(quantity)
|
||||
.setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
//calculatedPrice should equal to item.totalPrice
|
||||
if (totalPrice.compareTo(lineItem.getTotalPrice()) != 0) {
|
||||
totalPrices = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ids) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.id");
|
||||
}
|
||||
|
||||
if(!prices) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.price");
|
||||
}
|
||||
|
||||
if(!discounts) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.discount");
|
||||
}
|
||||
|
||||
if(!shippingPrices) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.shipping");
|
||||
}
|
||||
|
||||
if(!handlingPrices) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.handling");
|
||||
}
|
||||
|
||||
if(!quantities) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.quantity");
|
||||
}
|
||||
|
||||
if(!totalPrices) {
|
||||
errors.rejectValue("lineItems", "error.lineitems.totalprice");
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateShipping(ShippingInfo shipping, Errors errors) {
|
||||
if(!SHIPPER_IDS.contains(shipping.getShipperId())) {
|
||||
errors.rejectValue("shipping.shipperId", "error.shipping.shipper");
|
||||
}
|
||||
|
||||
if(!SHIPPER_TYPES.contains(shipping.getShippingTypeId())) {
|
||||
errors.rejectValue("shipping.shippingTypeId", "error.shipping.type");
|
||||
}
|
||||
|
||||
if(StringUtils.hasText(shipping.getShippingInfo())) {
|
||||
validateStringLength(shipping.getShippingInfo(), errors, "shipping.shippingInfo", "error.shipping.shippinginfo.length", 100);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validatePayment(BillingInfo billing, Errors errors) {
|
||||
if(!CARD_TYPES.contains(billing.getPaymentId())) {
|
||||
errors.rejectValue("billing.paymentId", "error.billing.type");
|
||||
}
|
||||
|
||||
if(!billing.getPaymentDesc().matches("[A-Z]{4}-[0-9]{10,11}")) {
|
||||
errors.rejectValue("billing.paymentDesc", "error.billing.desc");
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateAddress(Address address, Errors errors,
|
||||
String prefix) {
|
||||
if(address != null) {
|
||||
if(StringUtils.hasText(address.getAddressee())) {
|
||||
validateStringLength(address.getAddressee(), errors, prefix + ".addressee", "error.baddress.addresse.length", 60);
|
||||
}
|
||||
|
||||
validateStringLength(address.getAddrLine1(), errors, prefix + ".addrLine1", "error.baddress.addrline1.length", 50);
|
||||
|
||||
if(StringUtils.hasText(address.getAddrLine2())) {
|
||||
validateStringLength(address.getAddrLine2(), errors, prefix + ".addrLine2", "error.baddress.addrline2.length", 50);
|
||||
}
|
||||
validateStringLength(address.getCity(), errors, prefix + ".city", "error.baddress.city.length", 30);
|
||||
validateStringLength(address.getZipCode(), errors, prefix + ".zipCode", "error.baddress.zipcode.length", 5);
|
||||
|
||||
if(StringUtils.hasText(address.getZipCode()) && !address.getZipCode().matches("[0-9]{5}")) {
|
||||
errors.rejectValue(prefix + ".zipCode", "error.baddress.zipcode.format");
|
||||
}
|
||||
|
||||
if((!StringUtils.hasText(address.getState()) && ("United States".equals(address.getCountry())) || StringUtils.hasText(address.getState()) && address.getState().length() != 2)) {
|
||||
errors.rejectValue(prefix + ".state", "error.baddress.state.length");
|
||||
}
|
||||
|
||||
validateStringLength(address.getCountry(), errors, prefix + ".country", "error.baddress.country.length", 50);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateStringLength(String string, Errors errors,
|
||||
String field, String message, int length) {
|
||||
if(!StringUtils.hasText(string) || string.length() > length) {
|
||||
errors.rejectValue(field, message);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateCustomer(Customer customer, Errors errors) {
|
||||
if(!customer.isRegistered() && customer.isBusinessCustomer()) {
|
||||
errors.rejectValue("customer.registered", "error.customer.registration");
|
||||
}
|
||||
|
||||
if(!StringUtils.hasText(customer.getCompanyName()) && customer.isBusinessCustomer()) {
|
||||
errors.rejectValue("customer.companyName", "error.customer.companyname");
|
||||
}
|
||||
|
||||
if(!StringUtils.hasText(customer.getFirstName()) && !customer.isBusinessCustomer()) {
|
||||
errors.rejectValue("customer.firstName", "error.customer.firstname");
|
||||
}
|
||||
|
||||
if(!StringUtils.hasText(customer.getLastName()) && !customer.isBusinessCustomer()) {
|
||||
errors.rejectValue("customer.lastName", "error.customer.lastname");
|
||||
}
|
||||
|
||||
if(customer.isRegistered() && (customer.getRegistrationId() < 0 || customer.getRegistrationId() >= 99999999l)) {
|
||||
errors.rejectValue("customer.registrationId", "error.customer.registrationid");
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateOrder(Order item, Errors errors) {
|
||||
if(item.getOrderId() < 0 || item.getOrderId() > 9999999999l) {
|
||||
errors.rejectValue("orderId", "error.order.id");
|
||||
}
|
||||
|
||||
if(new Date().compareTo(item.getOrderDate()) < 0) {
|
||||
errors.rejectValue("orderDate", "error.order.date.future");
|
||||
}
|
||||
|
||||
if(item.getLineItems() != null && item.getTotalLines() != item.getLineItems().size()) {
|
||||
errors.rejectValue("totalLines", "error.order.lines.badcount");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,25 +15,35 @@
|
||||
*/
|
||||
package org.springframework.batch.sample.domain.trade.internal;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.batch.sample.domain.trade.CustomerCredit;
|
||||
import org.springframework.batch.sample.domain.trade.CustomerCreditDao;
|
||||
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class IbatisCustomerCreditDao extends SqlMapClientDaoSupport
|
||||
implements CustomerCreditDao {
|
||||
public class IbatisCustomerCreditDao implements CustomerCreditDao {
|
||||
|
||||
SqlMapClient sqlMapClient;
|
||||
|
||||
String statementId;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.sample.domain.trade.internal.CustomerCreditWriter#write(org.springframework.batch.sample.domain.CustomerCredit)
|
||||
*/
|
||||
@Override
|
||||
public void writeCredit(CustomerCredit customerCredit) {
|
||||
|
||||
getSqlMapClientTemplate().update(statementId, customerCredit);
|
||||
try {
|
||||
sqlMapClient.update(statementId, customerCredit);
|
||||
} catch (SQLException e) {
|
||||
throw new SQLStateSQLExceptionTranslator().translate("SqlMapClient operation", null, e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -8,17 +8,18 @@
|
||||
class="org.springframework.batch.item.database.IbatisPagingItemReader">
|
||||
<property name="queryId" value="getAllCustomerCredits" />
|
||||
<property name="sqlMapClient" ref="sqlMapClient" />
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="itemWriter"
|
||||
class="org.springframework.batch.item.database.IbatisBatchItemWriter">
|
||||
<property name="statementId" value="updateCredit" />
|
||||
<property name="sqlMapClient" ref="sqlMapClient" />
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="configLocation" value="ibatis-config.xml" />
|
||||
|
||||
<bean id="sqlMapClient" class="com.ibatis.sqlmap.client.SqlMapClientBuilder" factory-method="buildSqlMapClient">
|
||||
<constructor-arg value="ibatis-config.xml"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/batch
|
||||
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
|
||||
http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
<bean id="processor" class="org.springframework.batch.item.validator.ValidatingItemProcessor">
|
||||
<constructor-arg ref="validator" />
|
||||
<property name="filter" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean id="fileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
|
||||
@@ -67,4 +68,4 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -1,76 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<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
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="validator" class="org.springframework.batch.item.validator.SpringValidator">
|
||||
<property name="validator">
|
||||
<bean id="orderValidator" class="org.springmodules.validation.valang.ValangValidator">
|
||||
<property name="valang">
|
||||
<value>
|
||||
<!-- "{" <key> : <rule> : <message> : [ <error_code> [ : <error_parameters> ] ] "}" -->
|
||||
<![CDATA[
|
||||
{ orderId : ? > 0 AND ? <= 9999999999 : 'Incorrect order ID' : 'error.order.id' }
|
||||
{ orderDate : isFutureDate(?) = FALSE : 'Future date is not allowed' : 'error.order.date.future' }
|
||||
{ totalLines : ? = size(lineItems) : 'Bad count of order lines' : 'error.order.lines.badcount'}
|
||||
|
||||
{ customer.registered : customer.businessCustomer = FALSE OR ? = TRUE : 'Business customer must be registered' : 'error.customer.registration'}
|
||||
{ customer.companyName : customer.businessCustomer = FALSE OR ? HAS TEXT : 'Company name for business customer is mandatory' : 'error.customer.companyname'}
|
||||
{ customer.firstName : customer.businessCustomer = TRUE OR ? HAS TEXT : 'Firstname for non-business customer is mandatory' : 'error.customer.firstname'}
|
||||
{ customer.lastName : customer.businessCustomer = TRUE OR ? HAS TEXT : 'Lastname name for non-business customer is mandatory' : 'error.customer.lastname'}
|
||||
{ customer.registrationId : customer.registered = FALSE OR (? > 0 AND ? < 99999999) : 'Incorrect registration ID' : 'error.customer.registrationid'}
|
||||
|
||||
{ billingAddress.addressee : ? HAS NO TEXT OR length(?) <= 60 : 'Maximum length for Addressee is 60 characters' : 'error.baddress.addresse.length'}
|
||||
{ billingAddress.addrLine1 : ? HAS TEXT AND length(?) <= 50 : 'Address line1 is mandatory and maximum length for address line1 is 50 characters' : 'error.baddress.addrline1.length'}
|
||||
{ billingAddress.addrLine2 : ? HAS NO TEXT OR length(?) <= 50 : 'Maximum length for address line2 is 50 characters' : 'error.baddress.addrline2.length'}
|
||||
{ billingAddress.city : ? HAS TEXT AND length(?) <= 30 : 'City is mandatory and maximum length for city is 30 characters' : 'error.baddress.city.length'}
|
||||
{ billingAddress.zipCode : ? HAS TEXT AND length(?) <= 50 : 'Zipcode is mandatory and maximum length for zipcode is 5 characters' : 'error.baddress.zipcode.length'}
|
||||
{ billingAddress.zipCode : match('[0-9]{5}',?) = TRUE : 'ZipCode must contain exactly 5 digits' : 'error.baddress.zipcode.format'}
|
||||
{ billingAddress.state : (? HAS NO TEXT AND billingAddress.country != 'United States') OR (? HAS TEXT AND length(?) <= 2) : 'Maximum length for state is 2 characters' : 'error.baddress.state.length'}
|
||||
{ billingAddress.country : ? HAS TEXT AND length(?) <= 50 : 'Country is mandatory and maximum length for country is 50 characters' : 'error.baddress.country.length'}
|
||||
|
||||
{ shippingAddress.addressee : shippingAddress IS NULL OR (? HAS TEXT AND length(?) <= 60) : 'Addressee is mandatory and maximum length for addressee is 60 characters' : 'error.saddress.addresse.length'}
|
||||
{ shippingAddress.addrLine1 : shippingAddress IS NULL OR (? HAS TEXT AND length(?) <= 50) : 'Address line1 is mandatory and maximum length for address line1 is 50 characters' : 'error.baddress.addrline1.length'}
|
||||
{ shippingAddress.addrLine2 : shippingAddress IS NULL OR (? HAS NO TEXT OR length(?) <= 50) : 'Maximum length for address line2 is 50 characters' : 'error.baddress.addrline2.length'}
|
||||
{ shippingAddress.city : shippingAddress IS NULL OR (? HAS TEXT AND length(?) <= 30) : 'City is mandatory and maximum length for city is 30 characters' : 'error.baddress.city.length'}
|
||||
{ shippingAddress.zipCode : shippingAddress IS NULL OR (? HAS TEXT AND length(?) <= 50) : 'Zipcode is mandatory and maximum length for zipcode is 5 characters' : 'error.baddress.zipcode.length'}
|
||||
{ shippingAddress.zipCode : shippingAddress IS NULL OR (match('[0-9]{5}',?) = TRUE) : 'Zipcode must contain exactly 5 digits' : 'error.baddress.zipcode.format'}
|
||||
{ shippingAddress.state : shippingAddress IS NULL OR ((? HAS NO TEXT AND billingAddress.country != 'United States') OR (? HAS TEXT AND length(?) <= 2)) : 'Maximum length for state is 2 characters' : 'error.baddress.state.length'}
|
||||
{ shippingAddress.country : shippingAddress IS NULL OR (? HAS TEXT AND length(?) <= 50) : 'Country is mandatory and maximum length for country is 50 characters' : 'error.baddress.country.length'}
|
||||
|
||||
{ billing.paymentId : ? IN 'VISA','AMEX','ECMC','DCIN','PAYP' : 'Invalid payment type' : 'error.billing.type' }
|
||||
{ billing.paymentDesc : match('[A-Z]{4}-[0-9]{10,11}',?) = TRUE : 'Invalid format of payment description' : 'error.billing.desc' }
|
||||
|
||||
{ shipping.shipperId : ? IN 'FEDX', 'UPS', 'DHL', 'DPD' : 'Invalid shipper ID' : 'error.shipping.shipper'}
|
||||
{ shipping.shippingTypeId : ? IN 'STD', 'EXP', 'AMS', 'AME' : 'Invalid shipping type' : 'error.shipping.type' }
|
||||
{ shipping.shippingInfo : ? HAS NO TEXT OR length(?) <= 100 : 'Maximum length for additional shipping info is 100 characters' }
|
||||
|
||||
{ lineItems : validateTotalItemsCount(totalItems,?) = TRUE : 'Bad count of total line items' : 'error.lineitems.badcount' }
|
||||
{ lineItems : validateIds(?) = TRUE : 'One or more invalid item IDs' : 'error.lineitems.id' }
|
||||
{ lineItems : validatePrices(?) = TRUE : 'One or more invalid item prices' : 'error.lineitems.price' }
|
||||
{ lineItems : validateDiscounts(?) = TRUE : 'One or more invalid item discounts' : 'error.lineitems.discount' }
|
||||
{ lineItems : validateShippingPrices(?) = TRUE : 'One or more invalid item shipping prices' : 'error.lineitems.shipping' }
|
||||
{ lineItems : validateHandlingPrices(?) = TRUE : 'One or more invalid item handling prices' : 'error.lineitems.handling' }
|
||||
{ lineItems : validateQuantities(?) = TRUE : 'One or more invalid item quantities' : 'error.lineitems.quantity' }
|
||||
{ lineItems : validateTotalPrices(?) = TRUE : 'One or more invalid item total prices' : 'error.lineitems.totalprice' }
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
<property name="customFunctions">
|
||||
<map>
|
||||
<entry key="isFutureDate" value="org.springframework.batch.sample.domain.order.internal.valang.FutureDateFunction" />
|
||||
<entry key="validateTotalItemsCount" value="org.springframework.batch.sample.domain.order.internal.valang.TotalOrderItemsFunction" />
|
||||
<entry key="validateIds" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateIdsFunction" />
|
||||
<entry key="validatePrices" value="org.springframework.batch.sample.domain.order.internal.valang.ValidatePricesFunction" />
|
||||
<entry key="validateDiscounts" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateDiscountsFunction" />
|
||||
<entry key="validateShippingPrices" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateShippingPricesFunction" />
|
||||
<entry key="validateHandlingPrices" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateHandlingPricesFunction" />
|
||||
<entry key="validateQuantities" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateQuantitiesFunction" />
|
||||
<entry key="validateTotalPrices" value="org.springframework.batch.sample.domain.order.internal.valang.ValidateTotalPricesFunction" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="orderValidator" class="org.springframework.batch.sample.domain.order.internal.validator.OrderValidator"/>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
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-3.1.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
<import resource="data-source-context.xml" />
|
||||
<import
|
||||
resource="classpath:/org/springframework/batch/sample/config/common-context.xml" />
|
||||
@@ -19,7 +19,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository"
|
||||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
p:isolationLevelForCreate = "${batch.isolationlevel}"
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" p:lobHandler-ref="lobHandler"/>
|
||||
|
||||
@@ -48,4 +48,4 @@
|
||||
<bean id="eventAdvice"
|
||||
class="org.springframework.batch.sample.jmx.StepExecutionApplicationEventAdvice" />
|
||||
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class FutureDateFunctionTests {
|
||||
|
||||
private FutureDateFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new FutureDateFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithNonDateValue() {
|
||||
|
||||
//set-up mock argument - set return value to non Date value
|
||||
when(argument.getResult(null)).thenReturn(this);
|
||||
|
||||
//call tested method - exception is expected because non date value
|
||||
try {
|
||||
function.doGetResult(null);
|
||||
fail("Exception was expected.");
|
||||
} catch (Exception e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithFutureDate() throws Exception {
|
||||
|
||||
//set-up mock argument - set return value to future Date
|
||||
when(argument.getResult(null)).thenReturn(new Date(Long.MAX_VALUE));
|
||||
|
||||
//vefify result - should be true because of future date
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithPastDate() throws Exception {
|
||||
|
||||
//set-up mock argument - set return value to future Date
|
||||
when(argument.getResult(null)).thenReturn(new Date(0));
|
||||
|
||||
//vefify result - should be false because of past date
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class TotalOrderItemsFunctionTests {
|
||||
|
||||
private TotalOrderItemsFunction function;
|
||||
private Function argument2;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
//create mock for first argument - set count to 3
|
||||
Function argument1 = mock(Function.class);
|
||||
when(argument1.getResult(null)).thenReturn(3);
|
||||
|
||||
|
||||
argument2 = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new TotalOrderItemsFunction(new Function[] {argument1, argument2}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithNonListValue() {
|
||||
|
||||
when(argument2.getResult(null)).thenReturn(this);
|
||||
|
||||
//call tested method - exception is expected because non list value
|
||||
try {
|
||||
function.doGetResult(null);
|
||||
fail("Exception was expected.");
|
||||
} catch (Exception e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithCorrectItemCount() throws Exception {
|
||||
|
||||
//create list with correct item count
|
||||
LineItem item = new LineItem();
|
||||
item.setQuantity(3);
|
||||
List<LineItem> list = new ArrayList<LineItem>();
|
||||
list.add(item);
|
||||
|
||||
when(argument2.getResult(null)).thenReturn(list);
|
||||
|
||||
//vefify result
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionWithIncorrectItemCount() throws Exception {
|
||||
|
||||
//create list with incorrect item count
|
||||
LineItem item = new LineItem();
|
||||
item.setQuantity(99);
|
||||
List<LineItem> list = new ArrayList<LineItem>();
|
||||
list.add(item);
|
||||
|
||||
when(argument2.getResult(null)).thenReturn(list);
|
||||
|
||||
//vefify result
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateDiscountsFunctionTests {
|
||||
|
||||
private ValidateDiscountsFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateDiscountsFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscountPercentageMin() throws Exception {
|
||||
|
||||
//create line item with correct discount percentage and zero discount amount
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(1.0));
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all discount percentages are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative percentage
|
||||
item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(-1.0));
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid discount percentage
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscountPercentageMax() throws Exception {
|
||||
|
||||
//create line item with correct discount percentage and zero discount amount
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(99.0));
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all discount percentages are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with discount percentage above 100
|
||||
item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(101.0));
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid discount percentage
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscountPriceMin() throws Exception {
|
||||
|
||||
//create line item with correct discount amount and zero discount percentage
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setDiscountAmount(new BigDecimal(10.0));
|
||||
item.setPrice(new BigDecimal(100.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all discount amounts are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative discount amount
|
||||
item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setDiscountAmount(new BigDecimal(-1.0));
|
||||
item.setPrice(new BigDecimal(100.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid discount amount
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscountPriceMax() throws Exception {
|
||||
|
||||
//create line item with correct discount amount and zero discount percentage
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setDiscountAmount(new BigDecimal(99.0));
|
||||
item.setPrice(new BigDecimal(100.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all discount amounts are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with discount amount above item price
|
||||
item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setDiscountAmount(new BigDecimal(101.0));
|
||||
item.setPrice(new BigDecimal(100.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid discount amount
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBothDiscountValuesNonZero() throws Exception {
|
||||
|
||||
//create line item with non-zero discount amount and non-zero discount percentage
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountPerc(new BigDecimal(10.0));
|
||||
item.setDiscountAmount(new BigDecimal(99.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be false - only one of the discount values is empty
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateHandlingPricesFunctionTests {
|
||||
|
||||
private ValidateHandlingPricesFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateHandlingPricesFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandlingPriceMin() throws Exception {
|
||||
|
||||
//create line item with correct handling price
|
||||
LineItem item = new LineItem();
|
||||
item.setHandlingPrice(new BigDecimal(1.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all handling prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative handling price
|
||||
item = new LineItem();
|
||||
item.setHandlingPrice(new BigDecimal(-1.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid handling price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandlingPriceMax() throws Exception {
|
||||
|
||||
//create line item with correct handling price
|
||||
LineItem item = new LineItem();
|
||||
item.setHandlingPrice(new BigDecimal(99999999.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all handling prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with handling price above allowed max
|
||||
item = new LineItem();
|
||||
item.setHandlingPrice(new BigDecimal(100000000.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid handling price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateIdsFunctionTests {
|
||||
|
||||
private ValidateIdsFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateIdsFunction(new Function[] {argument}, 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdMin() throws Exception {
|
||||
|
||||
//create line item with correct item id
|
||||
LineItem item = new LineItem();
|
||||
item.setItemId(1);
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all ids are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative id
|
||||
item = new LineItem();
|
||||
item.setItemId(-1);
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid id
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdMax() throws Exception {
|
||||
|
||||
//create line item with correct item id
|
||||
LineItem item = new LineItem();
|
||||
item.setItemId(9999999999L);
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all item ids are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with item id above allowed max
|
||||
item = new LineItem();
|
||||
item.setItemId(10000000000L);
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid item id
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidatePricesFunctionTests {
|
||||
|
||||
private ValidatePricesFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidatePricesFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemPriceMin() throws Exception {
|
||||
|
||||
//create line item with correct item price
|
||||
LineItem item = new LineItem();
|
||||
item.setPrice(new BigDecimal(1.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all item prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative item price
|
||||
item = new LineItem();
|
||||
item.setPrice(new BigDecimal(-1.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid item price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemPriceMax() throws Exception {
|
||||
|
||||
//create line item with correct item price
|
||||
LineItem item = new LineItem();
|
||||
item.setPrice(new BigDecimal(99999999.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all item prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with item price above allowed max
|
||||
item = new LineItem();
|
||||
item.setPrice(new BigDecimal(100000000.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid item price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateQuantitiesFunctionTests {
|
||||
|
||||
private ValidateQuantitiesFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateQuantitiesFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuantityMin() throws Exception {
|
||||
|
||||
//create line item with correct item quantity
|
||||
LineItem item = new LineItem();
|
||||
item.setQuantity(1);
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all quantities are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative quantity
|
||||
item = new LineItem();
|
||||
item.setQuantity(-1);
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid quantity
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuantityMax() throws Exception {
|
||||
|
||||
//create line item with correct item quantity
|
||||
LineItem item = new LineItem();
|
||||
item.setQuantity(9999);
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all item quantities are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with item quantity above allowed max
|
||||
item = new LineItem();
|
||||
item.setQuantity(10000);
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid item quantity
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateShippingPricesFunctionTests {
|
||||
|
||||
private ValidateShippingPricesFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateShippingPricesFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShippingPriceMin() throws Exception {
|
||||
|
||||
//create line item with correct shipping price
|
||||
LineItem item = new LineItem();
|
||||
item.setShippingPrice(new BigDecimal(1.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all shipping prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative shipping price
|
||||
item = new LineItem();
|
||||
item.setShippingPrice(new BigDecimal(-1.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid shipping price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShippingPriceMax() throws Exception {
|
||||
|
||||
//create line item with correct shipping price
|
||||
LineItem item = new LineItem();
|
||||
item.setShippingPrice(new BigDecimal(99999999.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all shipping prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with shipping price above allowed max
|
||||
item = new LineItem();
|
||||
item.setShippingPrice(new BigDecimal(100000000.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid shipping price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.valang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springmodules.validation.valang.functions.Function;
|
||||
|
||||
public class ValidateTotalPricesFunctionTests {
|
||||
|
||||
private ValidateTotalPricesFunction function;
|
||||
private Function argument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
argument = mock(Function.class);
|
||||
|
||||
//create function
|
||||
function = new ValidateTotalPricesFunction(new Function[] {argument}, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTotalPriceMin() throws Exception {
|
||||
|
||||
//create line item with correct total price
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setHandlingPrice(new BigDecimal(0.0));
|
||||
item.setShippingPrice(new BigDecimal(0.0));
|
||||
item.setPrice(new BigDecimal(1.0));
|
||||
item.setQuantity(1);
|
||||
item.setTotalPrice(new BigDecimal(1.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all total prices are correct
|
||||
assertTrue((Boolean) function.doGetResult(null));
|
||||
|
||||
//now add line item with negative item price
|
||||
item = new LineItem();
|
||||
item.setTotalPrice(new BigDecimal(-1.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid total price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTotalPriceMax() throws Exception {
|
||||
|
||||
//create line item with correct total price
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountAmount(new BigDecimal(0.0));
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setHandlingPrice(new BigDecimal(0.0));
|
||||
item.setShippingPrice(new BigDecimal(0.0));
|
||||
item.setPrice(new BigDecimal(99999999.0));
|
||||
item.setQuantity(1);
|
||||
item.setTotalPrice(new BigDecimal(99999999.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all total prices are correct
|
||||
assertEquals(true, function.doGetResult(null));
|
||||
|
||||
//now add line item with total price above allowed max
|
||||
item = new LineItem();
|
||||
item.setTotalPrice(new BigDecimal(100000000.0));
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has invalid total price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTotalPriceCalculation() throws Exception {
|
||||
|
||||
//create line item
|
||||
LineItem item = new LineItem();
|
||||
item.setDiscountAmount(new BigDecimal(5.0));
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setHandlingPrice(new BigDecimal(1.0));
|
||||
item.setShippingPrice(new BigDecimal(2.0));
|
||||
item.setPrice(new BigDecimal(250.0));
|
||||
item.setQuantity(1);
|
||||
item.setTotalPrice(new BigDecimal(248.0));
|
||||
|
||||
//add it to line items list
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(item);
|
||||
|
||||
//set return value for mock argument
|
||||
when(argument.getResult(null)).thenReturn(items);
|
||||
|
||||
//verify result - should be true - all total prices are correct
|
||||
assertEquals(true, function.doGetResult(null));
|
||||
|
||||
//now add line item with incorrect total price
|
||||
item = new LineItem();
|
||||
item.setDiscountAmount(new BigDecimal(5.0));
|
||||
item.setDiscountPerc(new BigDecimal(0.0));
|
||||
item.setHandlingPrice(new BigDecimal(1.0));
|
||||
item.setShippingPrice(new BigDecimal(2.0));
|
||||
item.setPrice(new BigDecimal(250.0));
|
||||
item.setQuantity(1);
|
||||
item.setTotalPrice(new BigDecimal(253.0));
|
||||
|
||||
items.add(item);
|
||||
|
||||
//verify result - should be false - second item has incorrect total price
|
||||
assertFalse((Boolean) function.doGetResult(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
package org.springframework.batch.sample.domain.order.internal.validator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.sample.domain.order.Address;
|
||||
import org.springframework.batch.sample.domain.order.BillingInfo;
|
||||
import org.springframework.batch.sample.domain.order.Customer;
|
||||
import org.springframework.batch.sample.domain.order.LineItem;
|
||||
import org.springframework.batch.sample.domain.order.Order;
|
||||
import org.springframework.batch.sample.domain.order.ShippingInfo;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
public class OrderValidatorTests {
|
||||
|
||||
private OrderValidator orderValidator;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
orderValidator = new OrderValidator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupports() {
|
||||
assertTrue(orderValidator.supports(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotAnOrder() {
|
||||
String notAnOrder = "order";
|
||||
Errors errors = new BeanPropertyBindingResult(notAnOrder, "validOrder");
|
||||
|
||||
orderValidator.validate(notAnOrder, errors);
|
||||
|
||||
assertEquals(1, errors.getAllErrors().size());
|
||||
assertEquals("Incorrect type", errors.getAllErrors().get(0).getCode());
|
||||
|
||||
errors = new BeanPropertyBindingResult(notAnOrder, "validOrder");
|
||||
|
||||
orderValidator.validate(null, errors);
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidOrder() {
|
||||
Order order = new Order();
|
||||
order.setOrderId(-5);
|
||||
order.setOrderDate(new Date(new Date().getTime() + 1000000000l));
|
||||
order.setTotalLines(10);
|
||||
order.setLineItems(new ArrayList<LineItem>());
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
|
||||
orderValidator.validateOrder(order, errors);
|
||||
|
||||
assertEquals(3, errors.getAllErrors().size());
|
||||
assertEquals("error.order.id", errors.getFieldError("orderId").getCode());
|
||||
assertEquals("error.order.date.future", errors.getFieldError("orderDate").getCode());
|
||||
assertEquals("error.order.lines.badcount", errors.getFieldError("totalLines").getCode());
|
||||
|
||||
order = new Order();
|
||||
order.setOrderId(Long.MAX_VALUE);
|
||||
order.setOrderDate(new Date(new Date().getTime() - 1000));
|
||||
order.setTotalLines(0);
|
||||
List<LineItem> items = new ArrayList<LineItem>();
|
||||
items.add(new LineItem());
|
||||
order.setLineItems(items);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
|
||||
orderValidator.validateOrder(order, errors);
|
||||
|
||||
assertEquals(2, errors.getAllErrors().size());
|
||||
assertEquals("error.order.id", errors.getFieldError("orderId").getCode());
|
||||
assertEquals("error.order.lines.badcount", errors.getFieldError("totalLines").getCode());
|
||||
|
||||
order = new Order();
|
||||
order.setOrderId(5l);
|
||||
order.setOrderDate(new Date(new Date().getTime() - 1000));
|
||||
order.setTotalLines(1);
|
||||
items = new ArrayList<LineItem>();
|
||||
items.add(new LineItem());
|
||||
order.setLineItems(items);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
|
||||
orderValidator.validateOrder(order, errors);
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidCustomer() {
|
||||
Order order = new Order();
|
||||
Customer customer = new Customer();
|
||||
customer.setRegistered(false);
|
||||
customer.setBusinessCustomer(true);
|
||||
order.setCustomer(customer);
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateCustomer(customer, errors);
|
||||
|
||||
assertEquals(2, errors.getAllErrors().size());
|
||||
assertEquals("error.customer.registration", errors.getFieldError("customer.registered").getCode());
|
||||
assertEquals("error.customer.companyname", errors.getFieldError("customer.companyName").getCode());
|
||||
|
||||
customer = new Customer();
|
||||
customer.setRegistered(true);
|
||||
customer.setBusinessCustomer(false);
|
||||
customer.setRegistrationId(Long.MIN_VALUE);
|
||||
order.setCustomer(customer);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateCustomer(customer, errors);
|
||||
|
||||
assertEquals(3, errors.getAllErrors().size());
|
||||
assertEquals("error.customer.firstname", errors.getFieldError("customer.firstName").getCode());
|
||||
assertEquals("error.customer.lastname", errors.getFieldError("customer.lastName").getCode());
|
||||
assertEquals("error.customer.registrationid", errors.getFieldError("customer.registrationId").getCode());
|
||||
|
||||
customer = new Customer();
|
||||
customer.setRegistered(true);
|
||||
customer.setBusinessCustomer(false);
|
||||
customer.setRegistrationId(Long.MAX_VALUE);
|
||||
order.setCustomer(customer);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateCustomer(customer, errors);
|
||||
|
||||
assertEquals(3, errors.getAllErrors().size());
|
||||
assertEquals("error.customer.firstname", errors.getFieldError("customer.firstName").getCode());
|
||||
assertEquals("error.customer.lastname", errors.getFieldError("customer.lastName").getCode());
|
||||
assertEquals("error.customer.registrationid", errors.getFieldError("customer.registrationId").getCode());
|
||||
|
||||
customer = new Customer();
|
||||
customer.setRegistered(true);
|
||||
customer.setBusinessCustomer(true);
|
||||
customer.setCompanyName("Acme Inc");
|
||||
customer.setRegistrationId(5l);
|
||||
order.setCustomer(customer);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateCustomer(customer, errors);
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
|
||||
customer = new Customer();
|
||||
customer.setRegistered(true);
|
||||
customer.setBusinessCustomer(false);
|
||||
customer.setFirstName("John");
|
||||
customer.setLastName("Doe");
|
||||
customer.setRegistrationId(5l);
|
||||
order.setCustomer(customer);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateCustomer(customer, errors);
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAddress() {
|
||||
Order order = new Order();
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateAddress(null, errors, "billingAddress");
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
|
||||
Address address = new Address();
|
||||
order.setBillingAddress(address);
|
||||
|
||||
orderValidator.validateAddress(address, errors, "billingAddress");
|
||||
|
||||
assertEquals(4, errors.getAllErrors().size());
|
||||
assertEquals("error.baddress.addrline1.length", errors.getFieldError("billingAddress.addrLine1").getCode());
|
||||
assertEquals("error.baddress.city.length", errors.getFieldError("billingAddress.city").getCode());
|
||||
assertEquals("error.baddress.zipcode.length", errors.getFieldError("billingAddress.zipCode").getCode());
|
||||
assertEquals("error.baddress.country.length", errors.getFieldError("billingAddress.country").getCode());
|
||||
|
||||
address = new Address();
|
||||
address.setAddressee("1234567890123456789012345678901234567890123456789012345678901234567890");
|
||||
address.setAddrLine1("123456789012345678901234567890123456789012345678901234567890");
|
||||
address.setAddrLine2("123456789012345678901234567890123456789012345678901234567890");
|
||||
address.setCity("1234567890123456789012345678901234567890");
|
||||
address.setZipCode("1234567890");
|
||||
address.setState("1234567890");
|
||||
address.setCountry("123456789012345678901234567890123456789012345678901234567890");
|
||||
order.setBillingAddress(address);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateAddress(address, errors, "billingAddress");
|
||||
|
||||
assertEquals(8, errors.getAllErrors().size());
|
||||
assertEquals("error.baddress.addresse.length", errors.getFieldError("billingAddress.addressee").getCode());
|
||||
assertEquals("error.baddress.addrline1.length", errors.getFieldError("billingAddress.addrLine1").getCode());
|
||||
assertEquals("error.baddress.addrline2.length", errors.getFieldError("billingAddress.addrLine2").getCode());
|
||||
assertEquals("error.baddress.city.length", errors.getFieldError("billingAddress.city").getCode());
|
||||
assertEquals("error.baddress.state.length", errors.getFieldError("billingAddress.state").getCode());
|
||||
assertEquals("error.baddress.zipcode.length", errors.getFieldErrors("billingAddress.zipCode").get(0).getCode());
|
||||
assertEquals("error.baddress.zipcode.format", errors.getFieldErrors("billingAddress.zipCode").get(1).getCode());
|
||||
assertEquals("error.baddress.country.length", errors.getFieldError("billingAddress.country").getCode());
|
||||
|
||||
address = new Address();
|
||||
address.setAddressee("John Doe");
|
||||
address.setAddrLine1("123 4th Street");
|
||||
address.setCity("Chicago");
|
||||
address.setState("IL");
|
||||
address.setZipCode("60606");
|
||||
address.setCountry("United States");
|
||||
order.setBillingAddress(address);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateAddress(address, errors, "billingAddress");
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidPayment() {
|
||||
Order order = new Order();
|
||||
BillingInfo info = new BillingInfo();
|
||||
info.setPaymentId("INVALID");
|
||||
info.setPaymentDesc("INVALID");
|
||||
order.setBilling(info);
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validatePayment(info, errors);
|
||||
|
||||
assertEquals(2, errors.getAllErrors().size());
|
||||
assertEquals("error.billing.type", errors.getFieldError("billing.paymentId").getCode());
|
||||
assertEquals("error.billing.desc", errors.getFieldError("billing.paymentDesc").getCode());
|
||||
|
||||
info = new BillingInfo();
|
||||
info.setPaymentId("VISA");
|
||||
info.setPaymentDesc("ADFI-1234567890");
|
||||
order.setBilling(info);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validatePayment(info, errors);
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidShipping() {
|
||||
Order order = new Order();
|
||||
ShippingInfo info = new ShippingInfo();
|
||||
info.setShipperId("INVALID");
|
||||
info.setShippingTypeId("INVALID");
|
||||
order.setShipping(info);
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateShipping(info, errors);
|
||||
|
||||
assertEquals(2, errors.getAllErrors().size());
|
||||
assertEquals("error.shipping.shipper", errors.getFieldError("shipping.shipperId").getCode());
|
||||
assertEquals("error.shipping.type", errors.getFieldError("shipping.shippingTypeId").getCode());
|
||||
|
||||
info = new ShippingInfo();
|
||||
info.setShipperId("FEDX");
|
||||
info.setShippingTypeId("EXP");
|
||||
info.setShippingInfo("12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
|
||||
order.setShipping(info);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateShipping(info, errors);
|
||||
|
||||
assertEquals(1, errors.getAllErrors().size());
|
||||
assertEquals("error.shipping.shippinginfo.length", errors.getFieldError("shipping.shippingInfo").getCode());
|
||||
|
||||
info = new ShippingInfo();
|
||||
info.setShipperId("FEDX");
|
||||
info.setShippingTypeId("EXP");
|
||||
info.setShippingInfo("Info");
|
||||
order.setShipping(info);
|
||||
|
||||
errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateShipping(info, errors);
|
||||
|
||||
assertEquals(0, errors.getAllErrors().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidLineItems() {
|
||||
Order order = new Order();
|
||||
List<LineItem> lineItems = new ArrayList<LineItem>();
|
||||
lineItems.add(buildLineItem(-5, 5.00, 0, 0, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(Long.MAX_VALUE, 5.00, 0, 0, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, -5.00, 0, 0, 2, 3, 3, 0));
|
||||
lineItems.add(buildLineItem(6, Integer.MAX_VALUE, 0, 0, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 900, 0, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, -90, 0, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 10, 20, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, -10, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 50, 2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, -2, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, Long.MAX_VALUE, 3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, -3, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, Long.MAX_VALUE, 3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, 3, -3, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, 3, Integer.MAX_VALUE, 30));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, 3, 3, -5));
|
||||
lineItems.add(buildLineItem(6, 5.00, 0, 0, 2, 3, 3, Integer.MAX_VALUE));
|
||||
order.setLineItems(lineItems);
|
||||
|
||||
Errors errors = new BeanPropertyBindingResult(order, "validOrder");
|
||||
orderValidator.validateLineItems(lineItems, errors);
|
||||
|
||||
assertEquals(7, errors.getAllErrors().size());
|
||||
assertEquals("error.lineitems.id", errors.getFieldErrors("lineItems").get(0).getCode());
|
||||
assertEquals("error.lineitems.price", errors.getFieldErrors("lineItems").get(1).getCode());
|
||||
assertEquals("error.lineitems.discount", errors.getFieldErrors("lineItems").get(2).getCode());
|
||||
assertEquals("error.lineitems.shipping", errors.getFieldErrors("lineItems").get(3).getCode());
|
||||
assertEquals("error.lineitems.handling", errors.getFieldErrors("lineItems").get(4).getCode());
|
||||
assertEquals("error.lineitems.quantity", errors.getFieldErrors("lineItems").get(5).getCode());
|
||||
assertEquals("error.lineitems.totalprice", errors.getFieldErrors("lineItems").get(6).getCode());
|
||||
}
|
||||
|
||||
private LineItem buildLineItem(long itemId, double price, int discountPercentage, int discountAmount, long shippingPrice, long handlingPrice, int qty, int totalPrice) {
|
||||
LineItem invalidId = new LineItem();
|
||||
invalidId.setItemId(itemId);
|
||||
invalidId.setPrice(new BigDecimal(price));
|
||||
invalidId.setDiscountPerc(new BigDecimal(discountPercentage));
|
||||
invalidId.setDiscountAmount(new BigDecimal(discountAmount));
|
||||
invalidId.setShippingPrice(new BigDecimal(shippingPrice));
|
||||
invalidId.setHandlingPrice(new BigDecimal(handlingPrice));
|
||||
invalidId.setQuantity(qty);
|
||||
invalidId.setTotalPrice(new BigDecimal(totalPrice));
|
||||
return invalidId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user