Add spring-batch- to module directory names (so folks can use mvn eclipse:eclipse if they want to).

BATCH-238: Remove hibernate support for the Daos.
This commit is contained in:
dsyer
2007-12-10 21:23:48 +00:00
parent 17705f27ab
commit 8ea331bfc7
884 changed files with 956 additions and 2352 deletions

View File

@@ -0,0 +1,38 @@
/*
* 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.common;
import junit.framework.TestCase;
public class BinaryExceptionClassifierTests extends TestCase {
BinaryExceptionClassifier classifier = new BinaryExceptionClassifier();
public void testClassifyNullIsDefault() {
assertTrue(classifier.isDefault(null));
}
public void testClassifyRandomException() {
assertTrue(classifier.isDefault(new IllegalStateException("foo")));
}
public void testClassifyExactMatch() {
classifier.setExceptionClasses(new Class[] {IllegalStateException.class});
assertEquals(false, classifier.isDefault(new IllegalStateException("Foo")));
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.common;
import junit.framework.TestCase;
public class ExceptionClassifierSupportTests extends TestCase {
public void testClassifyNullIsDefault() {
ExceptionClassifierSupport classifier = new ExceptionClassifierSupport();
assertEquals(classifier.classify(null), classifier.getDefault());
}
public void testClassifyRandomException() {
ExceptionClassifierSupport classifier = new ExceptionClassifierSupport();
assertEquals(classifier.classify(new IllegalStateException("Foo")), classifier.getDefault());
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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.common;
import java.util.Collections;
import java.util.LinkedHashMap;
import junit.framework.TestCase;
public class SubclassExceptionClassifierTests extends TestCase {
SubclassExceptionClassifier classifier = new SubclassExceptionClassifier();
public void testClassifyNullIsDefault() {
assertEquals(classifier.classify(null), classifier.getDefault());
}
public void testClassifyRandomException() {
assertEquals(classifier.classify(new IllegalStateException("Foo")), classifier.getDefault());
}
public void testIllegalMapWithNonClass() {
try {
classifier.setTypeMap(Collections.singletonMap("bar", "foo"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
public void testIllegalMapWithClass() {
try {
classifier.setTypeMap(Collections.singletonMap(String.class, "foo"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
public void testClassifyExactMatch() {
classifier.setTypeMap(Collections.singletonMap(IllegalStateException.class, "foo"));
assertEquals("foo", classifier.classify(new IllegalStateException("Foo")));
}
public void testClassifySubclassMatch() {
classifier.setTypeMap(Collections.singletonMap(RuntimeException.class, "foo"));
assertEquals("foo", classifier.classify(new IllegalStateException("Foo")));
}
public void testClassifySuperclassDoesNotMatch() {
classifier.setTypeMap(Collections.singletonMap(IllegalStateException.class, "foo"));
assertEquals(classifier.getDefault(), classifier.classify(new RuntimeException("Foo")));
}
public void testClassifyAncestorMatch() {
classifier.setTypeMap(new LinkedHashMap() {{
put(Exception.class, "bar");
put(IllegalArgumentException.class, "foo");
put(RuntimeException.class, "bucket");
}});
assertEquals("bucket", classifier.classify(new IllegalStateException("Foo")));
}
}

View File

@@ -0,0 +1,61 @@
package org.springframework.batch.io.cursor;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.support.AbstractDataSourceInputSourceIntegrationTests;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
/**
* Tests for {@link HibernateCursorInputSource} using {@link StatelessSession}.
*
* @author Robert Kasanicky
*/
public class HibernateCursorInputSourceIntegrationTests extends AbstractDataSourceInputSourceIntegrationTests {
protected InputSource createInputSource() throws Exception {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(super.getJdbcTemplate().getDataSource());
factoryBean.setMappingLocations(new Resource[] { new ClassPathResource("Foo.hbm.xml", getClass()) });
factoryBean.afterPropertiesSet();
SessionFactory sessionFactory = (SessionFactory) factoryBean.getObject();
String hsqlQuery = "from Foo";
HibernateCursorInputSource inputSource = new HibernateCursorInputSource();
inputSource.setQueryString(hsqlQuery);
inputSource.setSessionFactory(sessionFactory);
inputSource.setUseStatelessSession(isUseStatelessSession());
inputSource.afterPropertiesSet();
return inputSource;
}
protected boolean isUseStatelessSession() {
return true;
}
/**
* Exception scenario.
*
* {@link HibernateCursorInputSource#setUseStatelessSession(boolean)} can be
* called only in uninitialized state.
*/
public void testSetUseStatelessSession() {
HibernateCursorInputSource inputSource = ((HibernateCursorInputSource) source);
// initialize and call setter => error
inputSource.open();
try {
inputSource.setUseStatelessSession(false);
fail();
}
catch (IllegalStateException e) {
// expected
}
}
}

View File

@@ -0,0 +1,16 @@
package org.springframework.batch.io.cursor;
import org.hibernate.Session;
/**
* Tests for {@link HibernateCursorInputSource} using standard hibernate {@link Session}.
*
* @author Robert Kasanicky
*/
public class HibernateCursorInputSourceStatefulIntegrationTests extends HibernateCursorInputSourceIntegrationTests {
protected boolean isUseStatelessSession() {
return false;
}
}

View File

@@ -0,0 +1,29 @@
package org.springframework.batch.io.cursor;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.driving.FooRowMapper;
import org.springframework.batch.io.support.AbstractDataSourceInputSourceIntegrationTests;
/**
* Tests for {@link JdbcCursorInputSource}
*
* @author Robert Kasanicky
*/
public class JdbcCursorInputSourceIntegrationTests extends AbstractDataSourceInputSourceIntegrationTests {
protected InputSource createInputSource() throws Exception {
JdbcCursorInputSource result = new JdbcCursorInputSource();
result.setDataSource(super.getJdbcTemplate().getDataSource());
result.setSql("select ID, NAME, VALUE from T_FOOS");
result.setIgnoreWarnings(true);
result.setVerifyCursorPosition(true);
result.setMapper(new FooRowMapper());
result.setFetchSize(10);
result.setMaxRows(100);
result.setQueryTimeout(1000);
return result;
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.io.driving;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
/**
* @author Lucas Ward
*
*/
public class CompositeKeyFooDao extends JdbcDaoSupport implements FooDao {
public CompositeKeyFooDao(JdbcTemplate jdbcTemplate) {
this.setJdbcTemplate(jdbcTemplate);
}
/* (non-Javadoc)
* @see org.springframework.batch.io.sql.scratch.FooDao#getFoo(java.lang.Object)
*/
public Foo getFoo(Object key) {
Map keys = (Map)key;
Object[] args = keys.values().toArray();
RowMapper fooMapper = new RowMapper(){
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Foo foo = new Foo();
foo.setId(rs.getInt(1));
foo.setName(rs.getString(2));
foo.setValue(rs.getInt(3));
return foo;
}
};
return (Foo)getJdbcTemplate().query("SELECT ID, NAME, VALUE from T_FOOS where ID = ? and VALUE = ?",
args, fooMapper).get(0);
}
}

View File

@@ -0,0 +1,215 @@
package org.springframework.batch.io.driving;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
import org.springframework.util.Assert;
public class DrivingQueryInputSourceTests extends TestCase {
InputSource source;
static {
TransactionSynchronizationManager.initSynchronization();
}
protected void setUp() throws Exception {
super.setUp();
source = createInputSource();
}
private InputSource createInputSource() throws Exception{
DrivingQueryInputSource inputSource = new DrivingQueryInputSource();
inputSource.setKeyGenerator(new MockKeyGenerator());
return inputSource;
}
/**
* Regular scenario - read all rows and eventually return null.
*/
public void testNormalProcessing() throws Exception {
getAsInitializingBean(source).afterPropertiesSet();
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
Foo foo3 = (Foo) source.read();
assertEquals(3, foo3.getValue());
Foo foo4 = (Foo) source.read();
assertEquals(4, foo4.getValue());
Foo foo5 = (Foo) source.read();
assertEquals(5, foo5.getValue());
assertNull(source.read());
}
/**
* Restart scenario.
* @throws Exception
*/
public void testRestart() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
getAsRestartable(source).restoreFrom(restartData);
Foo fooAfterRestart = (Foo) source.read();
assertEquals(3, fooAfterRestart.getValue());
}
/**
* Reading from an input source and then trying to restore causes an error.
*/
public void testInvalidRestore() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
try {
getAsRestartable(source).restoreFrom(restartData);
fail();
}
catch (IllegalStateException ex) {
// expected
}
}
/**
* Empty restart data should be handled gracefully.
*/
public void testRestoreFromEmptyData() {
RestartData restartData = new GenericRestartData(new Properties());
getAsRestartable(source).restoreFrom(restartData);
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
}
/**
* Rollback scenario.
*/
public void testRollback() {
Foo foo1 = (Foo) source.read();
commit();
Foo foo2 = (Foo) source.read();
Assert.state(!foo2.equals(foo1));
Foo foo3 = (Foo) source.read();
Assert.state(!foo2.equals(foo3));
rollback();
assertEquals(foo2, source.read());
}
private void commit() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_COMMITTED);
}
private void rollback() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_ROLLED_BACK);
}
private InitializingBean getAsInitializingBean(InputSource source) {
return (InitializingBean) source;
}
private Restartable getAsRestartable(InputSource source) {
return (Restartable) source;
}
private static class MockKeyGenerator implements KeyGenerator{
static RestartData restartData;
List keys;
List restartKeys;
static{
Properties props = new Properties();
//restart data properties cannot be empty.
props.setProperty("", "");
restartData = new GenericRestartData(props);
}
public MockKeyGenerator() {
keys = new ArrayList();
keys.add(new Foo(1, "1", 1));
keys.add(new Foo(2, "2", 2));
keys.add(new Foo(3, "3", 3));
keys.add(new Foo(4, "4", 4));
keys.add(new Foo(5, "5", 5));
restartKeys = new ArrayList();
restartKeys.add(new Foo(3, "3", 3));
restartKeys.add(new Foo(4, "4", 4));
restartKeys.add(new Foo(5, "5", 5));
}
public RestartData getKeyAsRestartData(Object key) {
return restartData;
}
public List restoreKeys(RestartData restartData) {
assertEquals(MockKeyGenerator.restartData, restartData);
return restartKeys;
}
public List retrieveKeys() {
return keys;
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.io.driving;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @author Lucas Ward
*
*/
public interface FooDao {
Foo getFoo(Object key);
void setJdbcTemplate(JdbcTemplate jdbcTemplate);
}

View File

@@ -0,0 +1,47 @@
package org.springframework.batch.io.driving;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
class FooInputSource implements InputSource, Restartable, DisposableBean, InitializingBean{
DrivingQueryInputSource inputSource;
FooDao fooDao = new SingleKeyFooDao();
public FooInputSource(DrivingQueryInputSource inputSource, JdbcTemplate jdbcTemplate) {
this.inputSource = inputSource;
fooDao.setJdbcTemplate(jdbcTemplate);
}
public Object read() {
Object key = inputSource.read();
if(key != null){
return fooDao.getFoo(key);
}else{
return null;
}
}
public RestartData getRestartData() {
return inputSource.getRestartData();
}
public void restoreFrom(RestartData data) {
inputSource.restoreFrom(data);
}
public void destroy() throws Exception {
inputSource.destroy();
}
public void setFooDao(FooDao fooDao) {
this.fooDao = fooDao;
}
public void afterPropertiesSet() throws Exception {
};
}

View File

@@ -0,0 +1,21 @@
package org.springframework.batch.io.driving;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.jdbc.core.RowMapper;
public class FooRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Foo foo = new Foo();
foo.setId(rs.getInt(1));
foo.setName(rs.getString(2));
foo.setValue(rs.getInt(3));
return foo;
}
}

View File

@@ -0,0 +1,39 @@
package org.springframework.batch.io.driving;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.driving.support.IbatisKeyGenerator;
import org.springframework.batch.io.support.AbstractDataSourceInputSourceIntegrationTests;
import org.springframework.core.io.ClassPathResource;
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
import com.ibatis.sqlmap.client.SqlMapClient;
/**
* Tests for {@link IbatisDrivingQueryInputSource}
*
* @author Robert Kasanicky
*/
public class IbatisInputSourceIntegrationTests extends AbstractDataSourceInputSourceIntegrationTests {
protected InputSource createInputSource() throws Exception {
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
factory.setDataSource(super.getJdbcTemplate().getDataSource());
factory.afterPropertiesSet();
SqlMapClient sqlMapClient = (SqlMapClient) factory.getObject();
IbatisDrivingQueryInputSource inputSource = new IbatisDrivingQueryInputSource();
IbatisKeyGenerator keyGenerator = new IbatisKeyGenerator();
keyGenerator.setDrivingQueryId("getAllFooIds");
inputSource.setDetailsQueryId("getFooById");
keyGenerator.setRestartQueryId("getAllFooIdsRestart");
keyGenerator.setSqlMapClient(sqlMapClient);
inputSource.setSqlMapClient(sqlMapClient);
inputSource.setKeyGenerator(keyGenerator);
return inputSource;
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.io.driving;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.driving.support.MultipleColumnJdbcKeyGenerator;
import org.springframework.batch.io.sql.AbstractJdbcInputSourceIntegrationTests;
/**
* @author Lucas Ward
*
*/
public class MultipleColumnJdbcDrivingQueryInputSourceIntegrationTests extends
AbstractJdbcInputSourceIntegrationTests {
protected InputSource createInputSource() throws Exception {
MultipleColumnJdbcKeyGenerator keyGenerator =
new MultipleColumnJdbcKeyGenerator(getJdbcTemplate(),
"SELECT ID, VALUE from T_FOOS order by ID, VALUE");
keyGenerator.setRestartQuery("SELECT ID, VALUE from T_FOOS where ID > ? and VALUE > ? order by ID");
DrivingQueryInputSource inputSource = new DrivingQueryInputSource();
inputSource.setKeyGenerator(keyGenerator);
FooInputSource fooInputSource = new FooInputSource(inputSource, getJdbcTemplate());
fooInputSource.setFooDao(new CompositeKeyFooDao(getJdbcTemplate()));
return fooInputSource;
}
// private static class FooRestartDataConverter implements RestartDataRowMapper{
//
// private static final String ID_RESTART_KEY = "FooRestartDataConverter.id";
// private static final String VALUE_RESTART_KEY = "FooRestartDataConverter.value";
//
// public RestartData createRestartData(Object compositeKey) {
//
// List values = (List)compositeKey;
// Properties data = new Properties();
// data.setProperty(ID_RESTART_KEY, values.get(0).toString());
// data.setProperty(VALUE_RESTART_KEY, values.get(1).toString());
// return new GenericRestartData(data);
// }
//
// public Object[] createSetter(RestartData restartData) {
// Object[] args = new Object[2];
// args[0] = restartData.getProperties().get(ID_RESTART_KEY);
// args[1] = restartData.getProperties().getProperty(VALUE_RESTART_KEY);
// return args;
// }
// }
//
// private static class FooCompositeKeyMapper implements RowMapper{
// public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
// List key = new ArrayList();
// key.add(new Long(rs.getLong(1)));
// key.add(new Long(rs.getLong(2)));
// return key;
// }
// }
}

View File

@@ -0,0 +1,26 @@
package org.springframework.batch.io.driving;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.driving.support.SingleColumnJdbcKeyGenerator;
import org.springframework.batch.io.sql.AbstractJdbcInputSourceIntegrationTests;
public class SingleColumnJdbcDrivingQueryInputSourceIntegrationTests extends AbstractJdbcInputSourceIntegrationTests {
protected InputSource source;
/**
* @return input source with all necessary dependencies set
*/
protected InputSource createInputSource() throws Exception {
SingleColumnJdbcKeyGenerator keyStrategy = new SingleColumnJdbcKeyGenerator(getJdbcTemplate(),
"SELECT ID from T_FOOS order by ID");
keyStrategy.setRestartSql("SELECT ID from T_FOOS where ID > ? order by ID");
DrivingQueryInputSource inputSource = new DrivingQueryInputSource();
inputSource.setKeyGenerator(keyStrategy);
return new FooInputSource(inputSource, getJdbcTemplate());
}
}

View File

@@ -0,0 +1,28 @@
package org.springframework.batch.io.driving;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class SingleKeyFooDao extends JdbcDaoSupport implements FooDao {
public Foo getFoo(Object key){
RowMapper fooMapper = new RowMapper(){
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Foo foo = new Foo();
foo.setId(rs.getInt(1));
foo.setName(rs.getString(2));
foo.setValue(rs.getInt(3));
return foo;
}
};
return (Foo)getJdbcTemplate().query("SELECT ID, NAME, VALUE from T_FOOS where ID = ?",
new Object[] {key}, fooMapper).get(0);
}
}

View File

@@ -0,0 +1,96 @@
/**
*
*/
package org.springframework.batch.io.driving.support;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.CollectionFactory;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.util.ClassUtils;
/**
* @author Lucas Ward
*/
public class ColumnMapRestartDataRowMapperTests extends TestCase {
private static final String KEY = ClassUtils.getQualifiedName(ColumnMapRestartDataRowMapper.class) + ".KEY.";
ColumnMapRestartDataRowMapper mapper;
Map key;
MockControl psControl = MockControl.createControl(PreparedStatement.class);
PreparedStatement ps;
protected void setUp() throws Exception {
super.setUp();
mapper = new ColumnMapRestartDataRowMapper();
key = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(2);
key.put("1", new Integer(1));
key.put("2", new Integer(2));
}
public void testCreateRestartDataWithInvalidType() throws Exception {
try{
mapper.createRestartData(new Object());
fail();
}catch(IllegalArgumentException ex){
//expected
}
}
public void testCreateRestartDataWithNull(){
try{
mapper.createRestartData(null);
fail();
}catch(IllegalArgumentException ex){
//expected
}
}
public void testCreateRestartData() throws Exception {
RestartData restartData = mapper.createRestartData(key);
Properties props = restartData.getProperties();
assertEquals("1", props.getProperty(KEY + "0"));
assertEquals("2", props.getProperty(KEY + "1"));
}
public void testCreateRestartDataFromEmptyKeys() throws Exception {
RestartData restartData = mapper.createRestartData(new HashMap());
assertEquals(0, restartData.getProperties().size());
}
public void testCreateSetter() throws Exception {
Properties props = new Properties();
props.setProperty(KEY + "0", "1");
props.setProperty(KEY + "1", "2");
RestartData restartData = new GenericRestartData(props);
PreparedStatementSetter setter = mapper.createSetter(restartData);
ps = (PreparedStatement)psControl.getMock();
ps.setString(1, "1");
ps.setString(2, "2");
psControl.replay();
setter.setValues(ps);
psControl.verify();
}
}

View File

@@ -0,0 +1,97 @@
/**
*
*/
package org.springframework.batch.io.driving.support;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.CollectionFactory;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
/**
* @author Lucas Ward
*
*/
public class MultipleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTransactionalDataSourceSpringContextTests {
MultipleColumnJdbcKeyGenerator keyStrategy;
protected String[] getConfigLocations(){
return new String[] { "org/springframework/batch/io/sql/data-source-context.xml"};
}
protected void onSetUpBeforeTransaction() throws Exception {
super.onSetUpBeforeTransaction();
keyStrategy = new MultipleColumnJdbcKeyGenerator(getJdbcTemplate(),
"SELECT ID, VALUE from T_FOOS order by ID");
keyStrategy.setRestartSql("SELECT ID, VALUE from T_FOOS where ID > ? and VALUE > ? order by ID");
}
public void testRetrieveKeys(){
List keys = keyStrategy.retrieveKeys();
for (int i = 0; i < keys.size(); i++) {
Map id = (Map)keys.get(i);
assertEquals(id.get("ID"), new Long(i + 1));
assertEquals(id.get("VALUE"), new Integer(i + 1));
}
}
public void testRestoreKeys(){
Properties props = new Properties();
props.setProperty(ColumnMapRestartDataRowMapper.KEY + "0", "3");
props.setProperty(ColumnMapRestartDataRowMapper.KEY + "1", "3");
RestartData restartData = new GenericRestartData(props);
List keys = keyStrategy.restoreKeys(restartData);
assertEquals(2, keys.size());
Map key = (Map)keys.get(0);
assertEquals(new Long(4), key.get("ID"));
assertEquals(new Integer(4), key.get("VALUE"));
key = (Map)keys.get(1);
assertEquals(new Long(5), key.get("ID"));
assertEquals(new Integer(5), key.get("VALUE"));
}
public void testGetKeyAsRestartData(){
Map key = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(1);
key.put("ID", new Long(3));
key.put("VALUE", new Integer(3));
RestartData restartData = keyStrategy.getKeyAsRestartData(key);
Properties props = restartData.getProperties();
assertEquals(2, props.size());
assertEquals("3", props.get(ColumnMapRestartDataRowMapper.KEY + "0"));
assertEquals("3", props.get(ColumnMapRestartDataRowMapper.KEY + "1"));
}
public void testGetNullKeyAsRestartData(){
try{
keyStrategy.getKeyAsRestartData(null);
fail();
}catch(IllegalArgumentException ex){
//expected
}
}
public void testRestoreKeysFromNull(){
try{
keyStrategy.getKeyAsRestartData(null);
}catch(IllegalArgumentException ex){
//expected
}
}
}

View File

@@ -0,0 +1,83 @@
package org.springframework.batch.io.driving.support;
import java.util.List;
import java.util.Properties;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
/**
*
* @author Lucas Ward
*
*/
public class SingleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTransactionalDataSourceSpringContextTests {
SingleColumnJdbcKeyGenerator keyStrategy;
protected String[] getConfigLocations(){
return new String[] { "org/springframework/batch/io/sql/data-source-context.xml"};
}
protected void onSetUpBeforeTransaction() throws Exception {
super.onSetUpBeforeTransaction();
keyStrategy = new SingleColumnJdbcKeyGenerator(getJdbcTemplate(),
"SELECT ID from T_FOOS order by ID");
keyStrategy.setRestartSql("SELECT ID from T_FOOS where ID > ? order by ID");
}
public void testRetrieveKeys(){
List keys = keyStrategy.retrieveKeys();
for (int i = 0; i < keys.size(); i++) {
Long id = (Long)keys.get(i);
assertEquals(new Long(i + 1), id);
}
}
public void testRestoreKeys(){
Properties props = new Properties();
props.setProperty(SingleColumnJdbcKeyGenerator.RESTART_KEY, "3");
RestartData restartData = new GenericRestartData(props);
List keys = keyStrategy.restoreKeys(restartData);
assertEquals(2, keys.size());
assertEquals(new Long(4), keys.get(0));
assertEquals(new Long(5), keys.get(1));
}
public void testGetKeyAsRestartData(){
RestartData restartData = keyStrategy.getKeyAsRestartData(new Long(3));
Properties props = restartData.getProperties();
assertEquals(1, props.size());
assertEquals("3", props.get(SingleColumnJdbcKeyGenerator.RESTART_KEY));
}
public void testGetNullKeyAsRestartData(){
try{
keyStrategy.getKeyAsRestartData(null);
fail();
}catch(IllegalArgumentException ex){
//expected
}
}
public void testRestoreKeysFromNull(){
try{
keyStrategy.getKeyAsRestartData(null);
}catch(IllegalArgumentException ex){
//expected
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.io.exception;
import junit.framework.TestCase;
public abstract class AbstractBatchCriticalExceptionTests extends TestCase {
public void testExceptionString() throws Exception {
Exception exception = getException("foo");
assertEquals("foo", exception.getMessage());
}
public void testExceptionThrowable() throws Exception {
Exception exception = getException(new RuntimeException("foo"));
assertEquals("foo", exception.getCause().getMessage().substring(0, 3));
}
public void testExceptionStringThrowable() throws Exception {
Exception exception = getException("foo", new IllegalStateException());
assertEquals("foo", exception.getMessage().substring(0, 3));
}
public abstract Exception getException(String msg) throws Exception;
public abstract Exception getException(Throwable exception) throws Exception;
public abstract Exception getException(String msg, Throwable t) throws Exception;
}

View File

@@ -0,0 +1,44 @@
/*
* 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.io.exception;
import junit.framework.TestCase;
public abstract class AbstractExceptionTests extends TestCase {
public void testExceptionString() throws Exception {
Exception exception = getException("foo");
assertEquals("foo", exception.getMessage());
}
public void testExceptionThrowable() throws Exception {
Exception exception = getException(new RuntimeException("foo"));
assertEquals("foo", exception.getCause().getMessage());
}
public void testExceptionStringThrowable() throws Exception {
Exception exception = getException("foo", new IllegalStateException());
assertEquals("foo", exception.getMessage().substring(0, 3));
}
public abstract Exception getException(String msg) throws Exception;
public abstract Exception getException(Throwable t) throws Exception;
public abstract Exception getException(String msg, Throwable t) throws Exception;
}

View File

@@ -0,0 +1,35 @@
/*
* 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.io.exception;
import org.springframework.batch.io.exception.BatchConfigurationException;
public class BatchConfigurationExceptionTests extends AbstractBatchCriticalExceptionTests {
public Exception getException(String msg) throws Exception {
return new BatchConfigurationException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new BatchConfigurationException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new BatchConfigurationException(msg, t);
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.io.exception;
public class BatchCriticalExceptionTests extends AbstractBatchCriticalExceptionTests {
public Exception getException(String msg) throws Exception {
return new BatchCriticalException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new BatchCriticalException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new BatchCriticalException(msg, t);
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.io.exception;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.io.exception.BatchEnvironmentException;
public class BatchEnvironmentExceptionTests extends AbstractBatchCriticalExceptionTests {
public Exception getException(String msg) throws Exception {
return new BatchEnvironmentException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new BatchCriticalException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new BatchEnvironmentException(msg, t);
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.io.exception;
public class TransactionInvalidExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new TransactionInvalidException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new TransactionInvalidException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new TransactionInvalidException(msg, t);
}
public void testNothing() throws Exception {
// fool coverage tools...
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.io.exception;
public class TransactionValidExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new TransactionValidException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new TransactionValidException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new TransactionValidException(msg, t);
}
public void testNothing() throws Exception {
// fool coverage tools...
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.io.exception;
import org.springframework.batch.repeat.exception.AbstractExceptionTests;
public class ValidationExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new ValidationException(msg);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new ValidationException(msg, t);
}
public void testNothing() throws Exception {
// fool coverage tools...
}
}

View File

@@ -0,0 +1,431 @@
/*
* 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.io.file;
import java.math.BigDecimal;
import java.text.ParseException;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
public class FieldSetTests extends TestCase {
FieldSet fieldSet;
String[] tokens;
String[] names;
protected void setUp() throws Exception {
super.setUp();
tokens = new String[] { "TestString", "true", "C", "10", "-472", "354224", "543", "124.3", "424.3", "324",
null, "2007-10-12", "12-10-2007", "" };
names = new String[] { "String", "Boolean", "Char", "Byte", "Short", "Integer", "Long", "Float", "Double",
"BigDecimal", "Null", "Date", "DatePattern", "BlankInput" };
fieldSet = new FieldSet(tokens, names);
assertEquals(14, fieldSet.getFieldCount());
}
public void testNames() throws Exception {
assertEquals(fieldSet.getFieldCount(), fieldSet.getNames().length);
}
public void testNamesNotKnown() throws Exception {
fieldSet = new FieldSet(new String[]{"foo"});
try {
fieldSet.getNames();
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
// expected
}
}
public void testReadString() throws ParseException {
assertEquals(fieldSet.readString(0), "TestString");
assertEquals(fieldSet.readString("String"), "TestString");
}
public void testReadChar() throws Exception {
assertTrue(fieldSet.readChar(2) == 'C');
assertTrue(fieldSet.readChar("Char") == 'C');
}
public void testReadBooleanTrue() throws Exception {
assertTrue(fieldSet.readBoolean(1));
assertTrue(fieldSet.readBoolean("Boolean"));
}
public void testReadByte() throws Exception {
assertTrue(fieldSet.readByte(3) == 10);
assertTrue(fieldSet.readByte("Byte") == 10);
}
public void testReadShort() throws Exception {
assertTrue(fieldSet.readShort(4) == -472);
assertTrue(fieldSet.readShort("Short") == -472);
}
public void testReadFloat() throws Exception {
assertTrue(fieldSet.readFloat(7) == 124.3F);
assertTrue(fieldSet.readFloat("Float") == 124.3F);
}
public void testReadDouble() throws Exception {
assertTrue(fieldSet.readDouble(8) == 424.3);
assertTrue(fieldSet.readDouble("Double") == 424.3);
}
public void testReadBigDecimal() throws Exception {
BigDecimal bd = new BigDecimal(324);
assertEquals(fieldSet.readBigDecimal(9), bd);
assertEquals(fieldSet.readBigDecimal("BigDecimal"), bd);
}
public void testReadBigDecimalWithDefaultvalue() throws Exception {
BigDecimal bd = new BigDecimal(324);
assertEquals(bd, fieldSet.readBigDecimal(10, bd));
assertEquals(bd, fieldSet.readBigDecimal("Null", bd));
}
public void testReadNonExistentField() throws Exception {
try {
fieldSet.readString("something");
fail("field set returns value even value was never put in!");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("something") > 0);
}
}
public void testReadIndexOutOfRange() throws Exception {
try {
fieldSet.readShort(-1);
fail("field set returns value even index is out of range!");
}
catch (IndexOutOfBoundsException e) {
assertTrue(true);
}
try {
fieldSet.readShort(99);
fail("field set returns value even index is out of range!");
}
catch (Exception e) {
assertTrue(true);
}
}
public void testReadBooleanWithTrueValue() {
assertTrue(fieldSet.readBoolean(1, "true"));
assertFalse(fieldSet.readBoolean(1, "incorrect trueValue"));
assertTrue(fieldSet.readBoolean("Boolean", "true"));
assertFalse(fieldSet.readBoolean("Boolean", "incorrect trueValue"));
}
public void testReadBooleanFalse() {
fieldSet = new FieldSet(new String[] { "false" });
assertFalse(fieldSet.readBoolean(0));
}
public void testReadCharException() {
try {
fieldSet.readChar(1);
fail("the value read was not a character, exception expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
fieldSet.readChar("Boolean");
fail("the value read was not a character, exception expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testReadInt() throws Exception {
assertEquals(354224, fieldSet.readInt(5));
assertEquals(354224, fieldSet.readInt("Integer"));
}
public void testReadBlankInt(){
//Trying to parse a blank field as an integer, but without a default
//value should throw a NumberFormatException
try{
fieldSet.readInt(13);
fail();
}
catch(NumberFormatException ex){
//expected
}
try{
fieldSet.readInt("BlankInput");
fail();
}
catch(NumberFormatException ex){
//expected
}
}
public void testReadLong() throws Exception {
assertEquals(543, fieldSet.readLong(6));
assertEquals(543, fieldSet.readLong("Long"));
}
public void testReadIntWithNullValue() {
assertEquals(5, fieldSet.readInt(10, 5));
assertEquals(5, fieldSet.readInt("Null", 5));
}
public void testReadIntWithDefaultAndNotNull() throws Exception {
assertEquals(354224, fieldSet.readInt(5, 5));
assertEquals(354224, fieldSet.readInt("Integer", 5));
}
public void testReadLongWithNullValue() {
int defaultValue = 5;
int indexOfNull = 10;
int indexNotNull = 6;
String nameNull = "Null";
String nameNotNull = "Long";
long longValueAtIndex = 543;
assertEquals(fieldSet.readLong(indexOfNull, defaultValue), defaultValue);
assertEquals(fieldSet.readLong(indexNotNull, defaultValue), longValueAtIndex);
assertEquals(fieldSet.readLong(nameNull, defaultValue), defaultValue);
assertEquals(fieldSet.readLong(nameNotNull, defaultValue), longValueAtIndex);
}
public void testReadBigDecimalInvalid() {
int index = 0;
try {
fieldSet.readBigDecimal(index);
fail("field value is not a number, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("TestString") > 0);
}
}
public void testReadBigDecimalByNameInvalid() throws Exception {
try {
fieldSet.readBigDecimal("String");
fail("field value is not a number, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("TestString") > 0);
assertTrue(e.getMessage().indexOf("name: [String]") > 0);
}
}
public void testReadDate() throws Exception {
assertNotNull(fieldSet.readDate(11));
assertNotNull(fieldSet.readDate("Date"));
}
public void testReadDateInvalid() throws Exception {
try {
fieldSet.readDate(0);
fail("field value is not a date, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("TestString") > 0);
}
}
public void testReadDateInvalidByName() throws Exception {
try {
fieldSet.readDate("String");
fail("field value is not a date, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("name: [String]") > 0);
}
}
public void testReadDateInvalidWithPattern() throws Exception {
try {
fieldSet.readDate(0, "dd-MM-yyyy");
fail("field value is not a date, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("dd-MM-yyyy") > 0);
}
}
public void testReadDateByNameInvalidWithPattern() throws Exception {
try {
fieldSet.readDate("String", "dd-MM-yyyy");
fail("field value is not a date, exception expected");
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().indexOf("dd-MM-yyyy") > 0);
assertTrue(e.getMessage().indexOf("String") > 0);
}
}
public void testEquals() {
assertEquals(fieldSet, fieldSet);
assertEquals(fieldSet, new FieldSet(tokens));
String[] tokens1 = new String[] { "token1" };
String[] tokens2 = new String[] { "token1" };
FieldSet fs1 = new FieldSet(tokens1);
FieldSet fs2 = new FieldSet(tokens2);
assertEquals(fs1, fs2);
}
public void testNullField() {
assertEquals(null, fieldSet.readString(10));
}
public void testEqualsNull() {
assertFalse(fieldSet.equals(null));
}
public void testEqualsNullTokens() {
assertFalse(new FieldSet(null).equals(fieldSet));
}
public void testEqualsNotEqual() throws Exception {
String[] tokens1 = new String[] { "token1" };
String[] tokens2 = new String[] { "token1", "token2" };
FieldSet fs1 = new FieldSet(tokens1);
FieldSet fs2 = new FieldSet(tokens2);
assertFalse(fs1.equals(fs2));
}
public void testHashCode() throws Exception {
assertEquals(fieldSet.hashCode(), new FieldSet(tokens).hashCode());
}
public void testHashCodeWithNullTokens() throws Exception {
assertEquals(0, new FieldSet(null).hashCode());
}
public void testConstructor() throws Exception {
try {
new FieldSet(new String[] { "1", "2" }, new String[] { "a" });
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testToStringWithNames() throws Exception {
fieldSet = new FieldSet(new String[] { "foo", "bar" }, new String[] { "Foo", "Bar" });
assertTrue(fieldSet.toString().indexOf("Foo=foo") >= 0);
}
public void testToStringWithoutNames() throws Exception {
fieldSet = new FieldSet(new String[] { "foo", "bar" });
assertTrue(fieldSet.toString().indexOf("foo") >= 0);
}
public void testToStringNullTokens() throws Exception {
fieldSet = new FieldSet(null);
assertEquals("", fieldSet.toString());
}
public void testProperties() throws Exception {
assertEquals("foo", new FieldSet(new String[] { "foo", "bar" }, new String[] { "Foo", "Bar" }).getProperties()
.getProperty("Foo"));
}
public void testPropertiesWithNoNames() throws Exception {
try {
new FieldSet(new String[] { "foo", "bar" }).getProperties();
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
}
public void testPropertiesWithWhiteSpace() throws Exception{
assertEquals("bar", new FieldSet(new String[] { "foo", "bar " }, new String[] { "Foo", "Bar"}).getProperties().getProperty("Bar"));
}
public void testPropertiesWithNullValues() throws Exception{
fieldSet = new FieldSet(new String[] { null, "bar" }, new String[] { "Foo", "Bar"});
assertEquals("bar", fieldSet.getProperties().getProperty("Bar"));
assertEquals(null, fieldSet.getProperties().getProperty("Foo"));
}
public void testAccessByNameWhenNamesMissing() throws Exception {
try {
new FieldSet(new String[] { "1", "2" }).readInt("a");
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testGetValues() {
String[] values = fieldSet.getValues();
assertEquals(tokens.length, values.length);
for (int i = 0; i < tokens.length; i++) {
assertEquals(tokens[i], values[i]);
}
}
}

View File

@@ -0,0 +1,205 @@
/*
* 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.io.file.support;
import java.io.IOException;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.DefaultFlatFileInputSource;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.transaction.support.TransactionSynchronization;
/**
* Tests for {@link DefaultFlatFileInputSource}
*
* @author robert.kasanicky
*
* TODO only regular reading is tested currently, add exception cases, restart,
* skip, validation...
*/
public class DefaultFlatFileInputSourceTests extends TestCase {
// object under test
private DefaultFlatFileInputSource inputSource = new DefaultFlatFileInputSource();
// common value used for writing to a file
private String TEST_STRING = "FlatFileInputTemplate-TestData";
// simple stub instead of a realistic tokenizer
private LineTokenizer tokenizer = new LineTokenizer() {
public FieldSet tokenize(String line) {
return new FieldSet(new String[]{line});
}
};
private FieldSetMapper fieldSetMapper = new FieldSetMapper(){
public Object mapLine(FieldSet fs) {
return fs;
}
};
/**
* Create inputFile, inject mock/stub dependencies for tested object,
* initialize the tested object
*/
protected void setUp() throws Exception {
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setTokenizer(tokenizer);
inputSource.setFieldSetMapper(fieldSetMapper);
// context argument is necessary only for the FileLocator, which
// is mocked
inputSource.open();
}
/**
* Release resources and delete the temporary file
*/
protected void tearDown() throws Exception {
inputSource.close();
}
private Resource getInputResource(String input) {
return new ByteArrayResource(input.getBytes());
}
/**
* Test skip and skipRollback functionality
* @throws IOException
*/
public void testSkip() throws IOException {
inputSource.close();
inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
inputSource.open();
// read some records
inputSource.read(); // #1
inputSource.read(); // #2
// commit them
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
// read next record
inputSource.read(); // # 3
// mark record as skipped
inputSource.skip();
// read next records
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
// we should now process all records after first commit point, that are
// not marked as skipped
assertEquals("[testLine4]", inputSource.read().toString());
// TODO update
// Map statistics = template.getStatistics();
// assertEquals("6",
// statistics.get(FlatFileInputTemplate.READ_STATISTICS_NAME));
// assertEquals("2",
// statistics.get(FlatFileInputTemplate.SKIPPED_STATISTICS_NAME));
}
/**
* Test skip and skipRollback functionality
* @throws IOException
*/
public void testTransactionSynchronizationUnknown() throws IOException {
inputSource.close();
inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
inputSource.open();
// read some records
inputSource.read();
inputSource.skip();
inputSource.read();
// TODO
// statistics = template.getStatistics();
// skipped = (String)
// statistics.get(FlatFileInputTemplate.SKIPPED_STATISTICS_NAME);
// read = (String)
// statistics.get(FlatFileInputTemplate.READ_STATISTICS_NAME);
// call unknown, which has no influence and therefore statistics should
// be the same
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
// TODO
// statistics = template.getStatistics();
// assertEquals(skipped, (String)
// statistics.get(FlatFileInputTemplate.SKIPPED_STATISTICS_NAME));
// assertEquals(read, (String)
// statistics.get(FlatFileInputTemplate.READ_STATISTICS_NAME));
}
public void testRestartFromNullData() throws Exception {
inputSource.restoreFrom(null);
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testRestartWithNullReader() throws Exception {
inputSource = new DefaultFlatFileInputSource();
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setFieldSetMapper(fieldSetMapper);
// do not open the template...
inputSource.restoreFrom(inputSource.getRestartData());
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testRestart() throws IOException {
inputSource.close();
inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
inputSource.open();
// read some records
inputSource.read();
inputSource.read();
// commit them
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
// read next two records
inputSource.read();
inputSource.read();
// get restart data
RestartData restartData = inputSource.getRestartData();
// TODO
// assertEquals("4", (String) restartData);
// close input
inputSource.close();
inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
// init for restart
inputSource.open();
inputSource.restoreFrom(restartData);
// read remaining records
assertEquals("[testLine5]", inputSource.read().toString());
assertEquals("[testLine6]", inputSource.read().toString());
// TODO
// Map statistics = template.getStatistics();
// assertEquals("6",
// statistics.get(FlatFileInputTemplate.READ_STATISTICS_NAME));
}
}

View File

@@ -0,0 +1,30 @@
package org.springframework.batch.io.file.support;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
* Helper methods for working with XML Events.
*
* @author Robert Kasanicky
*/
public class EventHelper {
//utility class
private EventHelper() {}
/**
* @return element name assuming the event is instance of StartElement
*/
public static String startElementName(XMLEvent event) {
return ((StartElement) event).getName().getLocalPart();
}
/**
* @return element name assuming the event is instance of EndElement
*/
public static String endElementName(XMLEvent event) {
return ((EndElement) event).getName().getLocalPart();
}
}

View File

@@ -0,0 +1,389 @@
/*
* 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.io.file.support;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import junit.framework.TestCase;
import org.springframework.batch.io.file.support.transform.Converter;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.io.FileSystemResource;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
/**
* Tests of regular usage for {@link FlatFileItemWriter} Exception cases will
* be in separate TestCase classes with different <code>setUp</code> and
* <code>tearDown</code> methods
*
* @author robert.kasanicky
* @author Dave Syer
*
*/
public class FlatFileItemWriterTests extends TestCase {
// object under test
private FlatFileItemWriter inputSource = new FlatFileItemWriter();
// String to be written into file by the FlatFileInputTemplate
private static final String TEST_STRING = "FlatFileOutputTemplateTest-OutputData";
// temporary output file
private File outputFile;
// reads the output file to check the result
private BufferedReader reader;
/**
* Create temporary output file, define mock behaviour, set dependencies
* and initialize the object under test
*/
protected void setUp() throws Exception {
if(TransactionSynchronizationManager.isSynchronizationActive()){
TransactionSynchronizationManager.clearSynchronization();
}
TransactionSynchronizationManager.initSynchronization();
outputFile = File.createTempFile("flatfile-output-", ".tmp");
inputSource.setResource(new FileSystemResource(outputFile));
inputSource.afterPropertiesSet();
inputSource.open();
}
/**
* Release resources and delete the temporary output file
*/
protected void tearDown() throws Exception {
if( reader != null){
reader.close();
}
inputSource.close();
outputFile.delete();
}
/*
* Read a line from the output file, if the reader has not been
* created, recreate. This method is only necessary because
* running the tests in a UNIX environment locks the file
* if it's open for writing.
*/
private String readLine() throws IOException{
if(reader == null){
reader = new BufferedReader(new FileReader(outputFile));
}
return reader.readLine();
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteString() throws IOException {
inputSource.write(TEST_STRING);
inputSource.close();
String lineFromFile = readLine();
assertEquals(TEST_STRING, lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteCollection() throws IOException {
inputSource.write(Collections.singleton(TEST_STRING));
inputSource.close();
String lineFromFile = readLine();
assertEquals(TEST_STRING, lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverter() throws IOException {
inputSource.setConverter(new Converter() {
public Object convert(Object input) {
return "FOO:" + input;
}
});
Object data = new Object();
inputSource.write(data);
inputSource.close();
String lineFromFile = readLine();
// converter not used if input is String
assertEquals("FOO:" + data.toString(), lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverterAndInfiniteLoop() throws IOException {
inputSource.setConverter(new Converter() {
public Object convert(Object input) {
return "FOO:" + input;
}
});
Object data = new Object();
inputSource.write(data);
inputSource.close();
String lineFromFile = readLine();
// converter not used if input is String
assertEquals("FOO:" + data.toString(), lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverterAndInfiniteLoopInCollection() throws IOException {
inputSource.setConverter(new Converter() {
public Object convert(Object input) {
return "FOO:" + input;
}
});
Object data = new Object();
inputSource.write(new Object[] {data, data});
inputSource.close();
String lineFromFile = readLine();
assertEquals("FOO:" + data.toString(), lineFromFile);
lineFromFile = readLine();
assertEquals("FOO:" + data.toString(), lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverterAndInfiniteLoopInConvertedCollection() throws IOException {
inputSource.setConverter(new Converter() {
boolean converted = false;
public Object convert(Object input) {
if (converted) {
return input;
}
converted = true;
return new Object[] { input, input };
}
});
Object data = new Object();
try {
inputSource.write(data);
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
// expected
assertTrue("Wrong message: "+e, e.getMessage().toLowerCase().indexOf("infinite")>=0);
}
inputSource.close();
String lineFromFile = readLine();
assertNull(lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverterAndString() throws IOException {
inputSource.setConverter(new Converter() {
public Object convert(Object input) {
return "FOO:" + input;
}
});
inputSource.write(Collections.singleton(TEST_STRING));
inputSource.close();
String lineFromFile = readLine();
// converter not used if input is String
assertEquals(TEST_STRING, lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteWithConverterAndCollectionOfString() throws IOException {
inputSource.setConverter(new Converter() {
public Object convert(Object input) {
return "FOO:" + input;
}
});
inputSource.write(TEST_STRING);
inputSource.close();
String lineFromFile = readLine();
// converter not used if input is String
assertEquals(TEST_STRING, lineFromFile);
}
/**
* Regular usage of <code>write(String)</code> method
*/
public void testWriteArray() throws IOException {
inputSource.write(new String[] { TEST_STRING, TEST_STRING });
inputSource.close();
String lineFromFile = readLine();
assertEquals(TEST_STRING, lineFromFile);
lineFromFile = readLine();
assertEquals(TEST_STRING, lineFromFile);
}
/**
* Regular usage of <code>write(String[], LineDescriptor)</code> method
*/
public void testWriteRecord() throws IOException {
String args = "1";
// AggregatorStub ignores the LineDescriptor, so we pass null
inputSource.write(args);
inputSource.close();
String lineFromFile = readLine();
assertEquals(args, lineFromFile);
}
public void testRollback() throws Exception {
inputSource.write("testLine1");
// rollback
rollback();
inputSource.close();
String lineFromFile = readLine();
assertEquals(null, lineFromFile);
}
public void testCommit() throws Exception {
inputSource.write("testLine1");
// rollback
commit();
inputSource.close();
String lineFromFile = readLine();
assertEquals("testLine1", lineFromFile);
}
public void testUnknown() throws Exception {
inputSource.write("testLine1");
// rollback
unknown();
inputSource.close();
String lineFromFile = readLine();
assertEquals("testLine1", lineFromFile);
}
public void testRestart() throws IOException {
// write some lines
inputSource.write("testLine1");
inputSource.write("testLine2");
inputSource.write("testLine3");
// commit
commit();
// this will be rolled back...
inputSource.write("this will be rolled back");
// rollback
rollback();
// write more lines
inputSource.write("testLine4");
inputSource.write("testLine5");
// commit
commit();
// get restart data
RestartData restartData = inputSource.getRestartData();
// close template
inputSource.close();
// init for restart
inputSource.setBufferSize(0);
inputSource.open();
// try empty restart data...
try {
inputSource.restoreFrom(null);
assertTrue(true);
}
catch (IllegalArgumentException iae) {
fail("null restart data should be handled gracefully");
}
// init with correct data
inputSource.restoreFrom(restartData);
// write more lines
inputSource.write("testLine6");
inputSource.write("testLine7");
inputSource.write("testLine8");
// close template
inputSource.close();
// verify what was written to the file
for (int i = 1; i < 9; i++) {
assertEquals("testLine" + i, readLine());
}
// get statistics
// Statistics statistics = template.getStatistics();
// 3 lines were written to the file after restart
// TODO
// assertEquals("3",
// statistics.get(FlatFileOutputTemplate.WRITTEN_STATISTICS_NAME));
}
public void testAfterPropertiesSetChecksMandatory() throws Exception {
inputSource = new FlatFileItemWriter();
try {
inputSource.afterPropertiesSet();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testDefaultRestartData() throws Exception {
inputSource = new FlatFileItemWriter();
RestartData restartData = inputSource.getRestartData();
assertNotNull(restartData);
// TODO: assert the properties of the default restart data
assertEquals(1, restartData.getProperties().size());
}
private void commit() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_COMMITTED);
}
private void rollback() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_ROLLED_BACK);
}
private void unknown() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_UNKNOWN);
}
}

View File

@@ -0,0 +1,173 @@
/*
* 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.io.file.support;
import java.io.IOException;
import java.io.InputStream;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.BatchEnvironmentException;
import org.springframework.batch.io.file.support.ResourceLineReader;
import org.springframework.batch.io.file.support.separator.SuffixRecordSeparatorPolicy;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
/**
* @author Rob Harrop
*/
public class ResourceLineReaderTests extends TestCase {
public void testBadResource() throws Exception {
ResourceLineReader reader = new ResourceLineReader(new InputStreamResource(new InputStream() {
public int read() throws IOException {
throw new IOException("Foo");
}
}));
try {
reader.read();
fail("Expected InputException");
}
catch (BatchEnvironmentException e) {
// expected
assertTrue(e.getMessage().startsWith("Unable to read"));
}
}
public void testRead() throws Exception {
Resource resource = new ByteArrayResource("a,b,c\n1,2,3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
int count = 0;
String line;
while ((line = (String) reader.read()) != null) {
count++;
assertNotNull(line);
}
assertEquals(2, count);
}
public void testCloseTwice() throws Exception {
Resource resource = new ByteArrayResource("a,b,c\n1,2,3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.open();
reader.close();
try {
reader.close(); // just closing a BufferedReader twice should be fine
} catch (Exception e) {
fail("Unexpected Exception "+e);
}
assertEquals("a,b,c", reader.read());
}
public void testEncoding() throws Exception {
Resource resource = new ByteArrayResource("a,b,c\n1,2,3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource, "UTF-8");
int count = 0;
String line;
while ((line = (String) reader.read()) != null) {
count++;
assertNotNull(line);
}
assertEquals(2, count);
}
public void testLineCount() throws Exception {
Resource resource = new ByteArrayResource("1,2,\"3\n4\"\n5,6,7".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
assertEquals(2, reader.getCurrentLineCount());
}
public void testLineEndings() throws Exception {
Resource resource = new ByteArrayResource("1\n2\r\n3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
String line = (String) reader.read();
assertEquals("2", line);
assertEquals(2, reader.getCurrentLineCount());
line = (String) reader.read();
assertEquals("3", line);
assertEquals(3, reader.getCurrentLineCount());
}
public void testDefaultComments() throws Exception {
Resource resource = new ByteArrayResource("1\n# 2\n3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
String line = (String) reader.read();
assertEquals("3", line);
}
public void testComments() throws Exception {
Resource resource = new ByteArrayResource("1\n-- 2\n3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.setComments(new String[] {"//", "--"});
reader.read();
String line = (String) reader.read();
assertEquals("3", line);
}
public void testCommentOnTheLastLine() throws Exception {
Resource resource = new ByteArrayResource("1\n#last line".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
String line = (String) reader.read();
assertNull(line);
}
public void testResetNewReader() throws Exception {
Resource resource = new ByteArrayResource("1\n4\n5".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.reset();
assertEquals(0, reader.getCurrentLineCount());
}
public void testMarkReset() throws Exception {
Resource resource = new ByteArrayResource("1\n4\n5".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
assertEquals(1, reader.getCurrentLineCount());
reader.mark();
reader.read();
assertEquals(2, reader.getCurrentLineCount());
reader.reset();
reader.read();
assertEquals(2, reader.getCurrentLineCount());
}
public void testMarkOnFirstRead() throws Exception {
Resource resource = new ByteArrayResource("1\n# 2\n3".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.read();
// The first read should do a mark() so the reset goes back to the beginning.
reader.reset();
String line = (String) reader.read();
assertEquals("1", line);
}
public void testNonDefaultRecordSeparatorPolicy() throws Exception {
Resource resource = new ByteArrayResource("1\n\"4\n5\"; \n6".getBytes());
ResourceLineReader reader = new ResourceLineReader(resource);
reader.setRecordSeparatorPolicy(new SuffixRecordSeparatorPolicy());
assertEquals(0, reader.getCurrentLineCount());
String line = (String) reader.read();
assertEquals("1\"4\n5\"", line);
}
}

View File

@@ -0,0 +1,293 @@
/*
* 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.io.file.support;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.BatchEnvironmentException;
import org.springframework.batch.io.exception.FlatFileParsingException;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.io.file.support.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
/**
* Tests for {@link SimpleFlatFileInputSourceTests}
*
* @author Dave Syer
*
*/
public class SimpleFlatFileInputSourceTests extends TestCase {
// object under test
private SimpleFlatFileInputSource inputSource = new SimpleFlatFileInputSource();
// common value used for writing to a file
private String TEST_STRING = "FlatFileInputTemplate-TestData";
// simple stub instead of a realistic tokenizer
private LineTokenizer tokenizer = new LineTokenizer() {
public FieldSet tokenize(String line) {
return new FieldSet(new String[] { line });
}
};
private FieldSetMapper fieldSetMapper = new FieldSetMapper(){
public Object mapLine(FieldSet fs) {
return fs;
}
};
/**
* Create inputFile, inject mock/stub dependencies for tested object,
* initialize the tested object
*/
protected void setUp() throws Exception {
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setTokenizer(tokenizer);
inputSource.setFieldSetMapper(fieldSetMapper);
inputSource.afterPropertiesSet();
inputSource.open();
}
/**
* Release resources.
*/
protected void tearDown() throws Exception {
inputSource.close();
}
private Resource getInputResource(String input) {
return new ByteArrayResource(input.getBytes());
}
/**
* Regular usage of <code>read</code> method
*/
public void testRead() throws IOException {
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
/**
* Regular usage of <code>read</code> method
*/
public void testReadExhausted() throws IOException {
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
assertEquals(null, inputSource.read());
}
/**
* Regular usage of <code>read</code> method
*/
public void testReadWithTokenizerError() throws IOException {
inputSource.setTokenizer(new LineTokenizer() {
public FieldSet tokenize(String line) {
throw new RuntimeException("foo");
}
});
try {
inputSource.read();
fail("Expected ParsingException");
} catch (FlatFileParsingException e) {
assertEquals(e.getInput(), TEST_STRING);
assertEquals(e.getLineNumber(), 1);
}
}
public void testReadWithMapperError() throws IOException {
inputSource.setFieldSetMapper(new FieldSetMapper(){
public Object mapLine(FieldSet fs) {
throw new RuntimeException("foo");
}
});
try {
inputSource.read();
fail("Expected ParsingException");
} catch (FlatFileParsingException e) {
assertEquals(e.getInput(), TEST_STRING);
assertEquals(e.getLineNumber(), 1);
}
}
public void testReadBeforeOpen() throws Exception {
inputSource = new SimpleFlatFileInputSource();
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setFieldSetMapper(fieldSetMapper);
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testCloseBeforeOpen() throws Exception {
inputSource = new SimpleFlatFileInputSource();
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setFieldSetMapper(fieldSetMapper);
inputSource.close();
// The open still happens automatically on a read...
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testCloseOnDestroy() throws Exception {
final List list = new ArrayList();
inputSource = new SimpleFlatFileInputSource() {
public void close() {
list.add("close");
}
};
inputSource.destroy();
assertEquals(1, list.size());
}
public void testInitializationWithNullResource() throws Exception {
inputSource = new SimpleFlatFileInputSource();
try {
inputSource.afterPropertiesSet();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testOpenTwiceHasNoEffect() throws Exception {
inputSource.open();
testRead();
}
public void testSetValidEncoding() throws Exception {
inputSource = new SimpleFlatFileInputSource();
inputSource.setEncoding("UTF-8");
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setFieldSetMapper(fieldSetMapper);
testRead();
}
public void testSetNullEncoding() throws Exception {
inputSource = new SimpleFlatFileInputSource();
inputSource.setEncoding(null);
inputSource.setResource(getInputResource(TEST_STRING));
try {
inputSource.open();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testSetInvalidEncoding() throws Exception {
inputSource = new SimpleFlatFileInputSource();
inputSource.setEncoding("foo");
inputSource.setResource(getInputResource(TEST_STRING));
try {
inputSource.open();
fail("Expected BatchEnvironmentException");
}
catch (BatchEnvironmentException e) {
// expected
assertEquals("foo", e.getCause().getMessage());
}
}
public void testEncoding() throws Exception {
inputSource.setEncoding("UTF-8");
testRead();
}
public void testRecordSeparator() throws Exception {
inputSource.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy());
testRead();
}
public void testComments() throws Exception {
inputSource.setResource(getInputResource("% Comment\n"+TEST_STRING));
inputSource.setComments(new String[] {"%"});
testRead();
}
public void testInvalidFile() throws IOException {
DefaultFlatFileInputSource ffit = new DefaultFlatFileInputSource();
FileSystemResource resource = new FileSystemResource("FooDummy.txt");
assertTrue(!resource.exists());
ffit.setResource(resource);
try {
ffit.open();
fail("File is not existing but exception was not thrown.");
}
catch (BatchEnvironmentException e) {
assertEquals("FooDummy", e.getCause().getMessage().substring(0,8));
}
}
/**
* Header line is skipped and used to setup fieldSet column names.
*/
public void testColumnNamesInHeader() throws Exception {
final String INPUT = "name1|name2\nvalue1|value2\nvalue3|value4";
inputSource = new SimpleFlatFileInputSource();
inputSource.setResource(getInputResource(INPUT));
inputSource.setTokenizer(new DelimitedLineTokenizer('|'));
inputSource.setFieldSetMapper(fieldSetMapper);
inputSource.setFirstLineIsHeader(true);
inputSource.afterPropertiesSet();
inputSource.open();
FieldSet fs = (FieldSet) inputSource.read();
assertEquals("value1", fs.readString("name1"));
assertEquals("value2", fs.readString("name2"));
fs = (FieldSet) inputSource.read();
assertEquals("value3", fs.readString("name1"));
assertEquals("value4", fs.readString("name2"));
}
/**
* Header line is skipped and used to setup fieldSet column names.
*/
public void testLinesToSkip() throws Exception {
final String INPUT = "foo bar spam\none two\nthree four";
inputSource = new SimpleFlatFileInputSource();
inputSource.setResource(getInputResource(INPUT));
inputSource.setTokenizer(new DelimitedLineTokenizer(' '));
inputSource.setFieldSetMapper(fieldSetMapper);
inputSource.setLinesToSkip(1);
inputSource.afterPropertiesSet();
inputSource.open();
FieldSet fs = (FieldSet) inputSource.read();
assertEquals("one", fs.readString(0));
assertEquals("two", fs.readString(1));
fs = (FieldSet) inputSource.read();
assertEquals("three", fs.readString(0));
assertEquals("four", fs.readString(1));
}
}

View File

@@ -0,0 +1,369 @@
package org.springframework.batch.io.file.support;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.springframework.batch.io.file.support.StaxEventReaderInputSource;
import org.springframework.batch.io.file.support.stax.FragmentDeserializer;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.transaction.support.TransactionSynchronization;
/**
* Tests for {@link StaxEventReaderInputSource}.
*
* @author Robert Kasanicky
*/
public class StaxEventReaderInputSourceTests extends TestCase {
// object under test
private StaxEventReaderInputSource source;
// test xml input
private String xml = "<root> <fragment> <misc1/> </fragment> <misc2/> <fragment> testString </fragment> </root>";
private FragmentDeserializer deserializer = new MockFragmentDeserializer();
private static final String FRAGMENT_ROOT_ELEMENT = "fragment";
protected void setUp() throws Exception {
source = createNewInputSouce();
}
public void testAfterPropertiesSet() throws Exception{
source.afterPropertiesSet();
}
public void testAfterPropertesSetException() throws Exception{
source.setResource(null);
try {
source.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e){
//expected;
}
source = createNewInputSouce();
source.setFragmentRootElementName("");
try {
source.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
source = createNewInputSouce();
source.setFragmentDeserializer(null);
try {
source.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
/**
* Regular usage scenario.
* InputSource should pass XML fragments to deserializer wrapped with
* StartDocument and EndDocument events.
*/
public void testFragmentWrapping() throws Exception {
source.afterPropertiesSet();
// see asserts in the mock deserializer
assertNotNull(source.read());
assertNotNull(source.read());
assertNull(source.read()); // there are only two fragments
source.destroy();
}
/**
* Cursor is moved before beginning of next fragment.
*/
public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(xml.getBytes());
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
final int EXPECTED_NUMBER_OF_FRAGMENTS = 2;
for (int i = 0; i < EXPECTED_NUMBER_OF_FRAGMENTS; i++) {
assertTrue(source.moveCursorToNextFragment(reader));
assertTrue(EventHelper.startElementName(reader.peek()).equals("fragment"));
reader.nextEvent(); // move away from beginning of fragment
}
assertFalse(source.moveCursorToNextFragment(reader));
}
/**
* Save restart data and restore from it.
*/
public void testRestart() {
source.read();
RestartData restartData = source.getRestartData();
assertEquals("1", restartData.getProperties().
getProperty("StaxEventReaderInputSource.recordcount"));
List expectedAfterRestart = (List) source.read();
source = createNewInputSouce();
source.restoreFrom(restartData);
List afterRestart = (List) source.read();
assertEquals(expectedAfterRestart.size(), afterRestart.size());
}
/**
* Restore point must not exceed end of file,
* input source must not be already initialized when restoring.
*/
public void testInvalidRestore() {
Properties props = new Properties() {{
final String MORE_RECORDS_THAN_INPUT_CONTAINS = "100000";
setProperty("StaxEventReaderInputSource.recordcount", MORE_RECORDS_THAN_INPUT_CONTAINS);
}};
try {
source.restoreFrom(new GenericRestartData(props));
fail();
}
catch (IllegalStateException e) {
// expected
}
source = createNewInputSouce();
source.open();
try {
source.restoreFrom(new GenericRestartData(new Properties()));
fail();
}
catch (IllegalStateException e) {
// expected
}
}
/**
* Skipping marked records after rollback.
*/
public void testSkip() {
List first = (List) source.read();
source.skip();
List second = (List) source.read();
assertFalse(first.equals(second));
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
assertEquals(second, source.read());
}
/**
* Rollback to last commited record.
*/
public void testRollback() {
//rollback between deserializing records
List first = (List) source.read();
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
List second = (List) source.read();
assertFalse(first.equals(second));
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
assertEquals(second, source.read());
//rollback while deserializing record
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
source.setFragmentDeserializer(new ExceptionFragmentDeserializer());
try {
source.read();
}
catch (Exception expected) {
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
}
source.setFragmentDeserializer(deserializer);
assertEquals(second, source.read());
}
/**
* Statistics return the current record count. Calling read after end of
* input does not increase the counter.
*/
public void testStatistics() {
final int NUMBER_OF_RECORDS = 2;
for (int i = 0; i < NUMBER_OF_RECORDS; i++) {
int recordCount = extractRecordCountFrom(source.getStatistics());
assertEquals(i, recordCount);
source.read();
}
assertEquals(NUMBER_OF_RECORDS, extractRecordCountFrom(source.getStatistics()));
source.read();
assertEquals(NUMBER_OF_RECORDS, extractRecordCountFrom(source.getStatistics()));
}
public void testClose() throws Exception{
MockStaxEventReaderInputSource newSource = new MockStaxEventReaderInputSource();
Resource resource = new ByteArrayResource(xml.getBytes());
newSource.setResource(resource);
newSource.setFragmentRootElementName(FRAGMENT_ROOT_ELEMENT);
newSource.setFragmentDeserializer(deserializer);
Object item = newSource.read();
assertNotNull(item);
assertTrue(newSource.isOpenCalled());
newSource.destroy();
newSource.setOpenCalled(false);
//calling read again should require re-initialization because of close
item = newSource.read();
assertNotNull(item);
assertTrue(newSource.isOpenCalled());
}
public void testOpenBadIOInput(){
source.setResource(new AbstractResource(){
public String getDescription() { return null; }
public InputStream getInputStream() throws IOException {
throw new IOException();
}
});
try{
source.open();
}catch(DataAccessResourceFailureException ex){
assertTrue(ex.getCause() instanceof IOException);
}
}
private int extractRecordCountFrom(Properties statistics) {
return Integer.valueOf(
source.getStatistics().getProperty(StaxEventReaderInputSource.READ_COUNT_STATISTICS_NAME)).intValue();
}
private StaxEventReaderInputSource createNewInputSouce() {
Resource resource = new ByteArrayResource(xml.getBytes());
StaxEventReaderInputSource newSource = new StaxEventReaderInputSource();
newSource.setResource(resource);
newSource.setFragmentRootElementName(FRAGMENT_ROOT_ELEMENT);
newSource.setFragmentDeserializer(deserializer);
return newSource;
}
/**
* A simple XMLEvent deserializer mock - check for the start and end
* document events for the fragment root & end tags + skips the fragment
* contents.
*/
private static class MockFragmentDeserializer implements FragmentDeserializer {
/**
* A simple mapFragment implementation checking the
* StaxEventReaderInputSource basic read functionality.
* @param eventReader
* @return list of the events from fragment body
*/
public Object deserializeFragment(XMLEventReader eventReader) {
List fragmentContent;
try {
// first event should be StartDocument
XMLEvent event1 = eventReader.nextEvent();
assertTrue(event1.isStartDocument());
// second should be StartElement of the fragment
XMLEvent event2 = eventReader.nextEvent();
assertTrue(event2.isStartElement());
assertTrue(EventHelper.startElementName(event2).equals(FRAGMENT_ROOT_ELEMENT));
// jump before the end of fragment
fragmentContent = readRecordsInsideFragment(eventReader);
// end of fragment
XMLEvent event3 = eventReader.nextEvent();
assertTrue(event3.isEndElement());
assertTrue(EventHelper.endElementName(event3).equals(FRAGMENT_ROOT_ELEMENT));
// EndDocument should follow the end of fragment
XMLEvent event4 = eventReader.nextEvent();
assertTrue(event4.isEndDocument());
}
catch (XMLStreamException e) {
throw new RuntimeException("Error occured in FragmentDeserializer", e);
}
return fragmentContent;
}
/**
* Skips the XML fragment contents.
*/
private List readRecordsInsideFragment(XMLEventReader eventReader) throws XMLStreamException {
XMLEvent eventInsideFragment;
List events = new ArrayList();
do {
eventInsideFragment = eventReader.peek();
if (eventInsideFragment instanceof EndElement
&& ((EndElement) eventInsideFragment).getName().getLocalPart().equals(FRAGMENT_ROOT_ELEMENT)) {
break;
}
events.add(eventReader.nextEvent());
} while (eventInsideFragment != null);
return events;
}
}
/**
* Moves cursor inside the fragment body and causes rollback.
*/
private static class ExceptionFragmentDeserializer implements FragmentDeserializer {
public Object deserializeFragment(XMLEventReader eventReader) {
eventReader.next();
throw new RuntimeException();
}
}
private static class MockStaxEventReaderInputSource extends StaxEventReaderInputSource {
private boolean openCalled = false;
public void open() {
super.open();
openCalled = true;
}
public boolean isOpenCalled() {
return openCalled;
}
public void setOpenCalled(boolean openCalled) {
this.openCalled = openCalled;
}
}
}

View File

@@ -0,0 +1,208 @@
package org.springframework.batch.io.file.support;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import junit.framework.TestCase;
import org.apache.commons.io.FileUtils;
import org.springframework.batch.io.file.support.StaxEventWriterItemWriter;
import org.springframework.batch.io.file.support.oxm.MarshallingObjectToXmlSerializer;
import org.springframework.batch.restart.RestartData;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.util.Assert;
import org.springframework.xml.transform.StaxResult;
/**
* Tests for {@link StaxStreamWriterOutputSource}.
*/
public class StaxEventWriterItemWriterTests extends TestCase {
// object under test
private StaxEventWriterItemWriter writer;
// output file
private Resource resource;
// test record for writing to output
private Object record = new Object() {
public String toString() {
return TEST_STRING;
}
};
private static final String TEST_STRING = "StaxEventWriterOutputSourceTests-testString";
private static final int NOT_FOUND = -1;
protected void setUp() throws Exception {
resource = new FileSystemResource(File.createTempFile("StaxEventWriterOutputSourceTests", "xml"));
writer = createItemWriter();
}
/**
* Write should pass its argument and StaxResult object to Serializer
*/
public void testWrite() throws Exception {
Marshaller marshaller = new InputCheckMarshaller();
MarshallingObjectToXmlSerializer serializer = new MarshallingObjectToXmlSerializer(marshaller);
writer.setSerializer(serializer);
// see asserts in the marshaller
writer.write(record);
}
/**
* Rolled back records should not be written to output file.
*/
public void testRollback() throws Exception {
writer.write(record);
// rollback
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
assertEquals("", outputFileContent());
}
/**
* Commited output is written to the output file.
*/
public void testCommit() throws Exception {
writer.write(record);
// commit
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
assertTrue(outputFileContent().indexOf(TEST_STRING) != NOT_FOUND);
}
/**
* Restart scenario - content is appended to the output file after restart.
*/
public void testRestart() throws Exception {
// write records
writer.write(record);
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
RestartData restartData = writer.getRestartData();
// create new writer from saved restart data and continue writing
writer = createItemWriter();
writer.restoreFrom(restartData);
writer.write(record);
writer.destroy();
// check the output is concatenation of 'before restart' and 'after restart' writes.
String outputFile = outputFileContent();
int firstRecord = outputFile.indexOf(TEST_STRING);
int secondRecord = outputFile.indexOf(TEST_STRING, firstRecord + TEST_STRING.length());
int thirdRecord = outputFile.indexOf(TEST_STRING, secondRecord + TEST_STRING.length());
// (two records should be written)
assertTrue(firstRecord != NOT_FOUND);
assertTrue(secondRecord != NOT_FOUND);
assertEquals(NOT_FOUND, thirdRecord);
}
/**
* Count of 'records written so far' is returned as statistics.
*/
public void testStatistics() throws Exception {
final int NUMBER_OF_RECORDS = 10;
for (int i = 0; i < NUMBER_OF_RECORDS; i++) {
String writeStatistics =
writer.getStatistics().getProperty(StaxEventWriterItemWriter.WRITE_STATISTICS_NAME);
assertEquals(String.valueOf(i), writeStatistics);
writer.write(record);
}
}
/**
* Open method writes the root tag, close method adds corresponding end tag.
*/
public void testOpenAndClose() throws IOException {
writer.setRootTagName("testroot");
writer.setRootElementAttributes(new HashMap() {{
put("attribute", "value");
}});
writer.open();
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
assertTrue(outputFileContent().indexOf("<testroot attribute=\"value\"") != NOT_FOUND);
writer.close();
assertTrue(outputFileContent().endsWith("</testroot>"));
}
/**
* Checks the received parameters.
*/
private class InputCheckMarshaller implements Marshaller {
public void marshal(Object graph, Result result) {
assertTrue(result instanceof StaxResult);
assertSame(record, graph);
}
public boolean supports(Class clazz) {
return true;
}
}
/**
* Writes object's toString representation as XML comment.
*/
private static class SimpleMarshaller implements Marshaller {
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
Assert.isInstanceOf(StaxResult.class, result);
StaxResult staxResult = (StaxResult) result;
try {
staxResult.getXMLEventWriter().add(XMLEventFactory.newInstance().createComment(graph.toString()));
}
catch (XMLStreamException e) {
throw new RuntimeException("Exception while writing to output file", e);
}
}
public boolean supports(Class clazz) {
return true;
}
}
/**
* @return output file content as String
*/
private String outputFileContent() throws IOException {
return FileUtils.readFileToString(resource.getFile(), null);
}
/**
* @return new instance of fully configured writer
*/
private StaxEventWriterItemWriter createItemWriter() throws Exception {
StaxEventWriterItemWriter source = new StaxEventWriterItemWriter();
source.setResource(resource);
Marshaller marshaller = new SimpleMarshaller();
MarshallingObjectToXmlSerializer serializer = new MarshallingObjectToXmlSerializer(marshaller);
source.setSerializer(serializer);
source.setEncoding("UTF-8");
source.setRootTagName("root");
source.setVersion("1.0");
source.setOverwriteOutput(true);
source.afterPropertiesSet();
return source;
}
}

View File

@@ -0,0 +1,380 @@
/*
* 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.io.file.support.mapping;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.support.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.support.IntArrayPropertyEditor;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
public class BeanWrapperFieldSetMapperTests extends TestCase {
public void testNameAndTypeSpecified() throws Exception {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
mapper.setTargetType(TestObject.class);
mapper.setPrototypeBeanName("foo");
try {
mapper.afterPropertiesSet();
} catch (IllegalStateException e) {
// expected
}
}
public void testNameNorTypeSpecified() throws Exception {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
try {
mapper.afterPropertiesSet();
} catch (IllegalStateException e) {
// expected
}
}
public void testVanillaBeanCreatedFromType() throws Exception {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
mapper.setTargetType(TestObject.class);
mapper.afterPropertiesSet();
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
"varString", "varBoolean", "varChar" });
TestObject result = (TestObject) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getVarString());
assertEquals(true, result.isVarBoolean());
assertEquals('C', result.getVarChar());
}
public void testMapperWithSingleton() throws Exception {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", new TestObject());
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
"varString", "varBoolean", "varChar" });
TestObject result = (TestObject) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getVarString());
assertEquals(true, result.isVarBoolean());
assertEquals('C', result.getVarChar());
}
public void testPropertyNameMatching() throws Exception {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", new TestObject());
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
"VarString", "VAR_BOOLEAN", "VAR_CHAR" });
TestObject result = (TestObject) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getVarString());
assertEquals(true, result.isVarBoolean());
assertEquals('C', result.getVarChar());
}
public void testMapperWithPrototype() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("bean-wrapper.xml", getClass());
BeanWrapperFieldSetMapper mapper = (BeanWrapperFieldSetMapper) context.getBean("fieldSetMapper");
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
"varString", "varBoolean", "varChar" });
TestObject result = (TestObject) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getVarString());
assertEquals(true, result.isVarBoolean());
assertEquals('C', result.getVarChar());
}
public void testMapperWithNestedBeanPaths() throws Exception {
TestNestedA testNestedA = new TestNestedA();
TestNestedB testNestedB = new TestNestedB();
testNestedA.setTestObjectB(testNestedB);
testNestedB.setTestObjectC(new TestNestedC());
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedA);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "1", "Another dummy", "2" },
new String[] { "valueA", "valueB", "testObjectB.valueA", "testObjectB.testObjectC.value" });
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getValueA());
assertEquals(1, result.getValueB());
assertEquals("Another dummy", result.getTestObjectB().getValueA());
assertEquals(2, result.getTestObjectB().getTestObjectC().getValue());
}
public void testMapperWithSimilarNamePropertyMatches() throws Exception {
TestNestedA testNestedA = new TestNestedA();
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedA);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "This is some dummy string", "1" }, new String[] { "VALUE_A",
"VALUE_B" });
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
assertEquals("This is some dummy string", result.getValueA());
assertEquals(1, result.getValueB());
}
public void testMapperWithNotVerySimilarNamePropertyMatches() throws Exception {
TestNestedC testNestedC = new TestNestedC();
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedC);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "1" }, new String[] {
"foo" });
TestNestedC result = (TestNestedC) mapper.mapLine(fieldSet);
// "foo" is similar enough to "value" that it matches - but only because
// nothing else does...
assertEquals(1, result.getValue());
}
public void testMapperWithNestedBeanPathsAndPropertyMatches() throws Exception {
TestNestedA testNestedA = new TestNestedA();
TestNestedB testNestedB = new TestNestedB();
testNestedA.setTestObjectB(testNestedB);
testNestedB.setTestObjectC(new TestNestedC());
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedA);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "Another dummy", "2" }, new String[] { "TestObjectB.ValueA",
"TestObjectB.TestObjectC.Value" });
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
assertEquals("Another dummy", result.getTestObjectB().getValueA());
assertEquals(2, result.getTestObjectB().getTestObjectC().getValue());
}
public void testMapperWithNestedBeanPathsAndPropertyMisMatches() throws Exception {
TestNestedA testNestedA = new TestNestedA();
TestNestedB testNestedB = new TestNestedB();
testNestedA.setTestObjectB(testNestedB);
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedA);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "Another dummy" }, new String[] { "TestObjectB.foo" });
try {
mapper.mapLine(fieldSet);
fail("Expected NotWritablePropertyException");
}
catch (NotWritablePropertyException e) {
// expected
}
}
public void testMapperWithNestedBeanPathsAndPropertyPrefixMisMatches() throws Exception {
TestNestedA testNestedA = new TestNestedA();
TestNestedB testNestedB = new TestNestedB();
testNestedA.setTestObjectB(testNestedB);
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", testNestedA);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[] { "2" }, new String[] { "TestObjectA.garbage" });
try {
mapper.mapLine(fieldSet);
fail("Expected NotWritablePropertyException");
}
catch (NotWritablePropertyException e) {
// expected
}
}
public void testPlainBeanWrapper() throws Exception {
TestObject result = new TestObject();
BeanWrapperImpl wrapper = new BeanWrapperImpl(result);
PropertiesEditor editor = new PropertiesEditor();
editor.setAsText("varString=This is some dummy string\nvarBoolean=true\nvarChar=C");
Properties props = (Properties) editor.getValue();
wrapper.setPropertyValues(props);
assertEquals("This is some dummy string", result.getVarString());
assertEquals(true, result.isVarBoolean());
assertEquals('C', result.getVarChar());
}
public void testIntArray() throws Exception {
BeanWithIntArray result = new BeanWithIntArray();
BeanWrapperImpl wrapper = new BeanWrapperImpl(result);
wrapper.registerCustomEditor(int[].class, new IntArrayPropertyEditor());
PropertiesEditor editor = new PropertiesEditor();
editor.setAsText("numbers=1,2,3, 4");
Properties props = (Properties) editor.getValue();
wrapper.setPropertyValues(props);
assertEquals(4, result.numbers[3]);
}
//BeanWrapperFieldSetMapper doesn't currently support nesting with collections.
public void testNestedList(){
TestNestedList nestedList = new TestNestedList();
List nestedC = new ArrayList();
nestedC.add(new TestNestedC());
nestedC.add(new TestNestedC());
nestedC.add(new TestNestedC());
nestedList.setNestedC(nestedC);
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper();
StaticApplicationContext context = new StaticApplicationContext();
mapper.setBeanFactory(context);
context.getBeanFactory().registerSingleton("bean", nestedList);
mapper.setPrototypeBeanName("bean");
FieldSet fieldSet = new FieldSet(new String[]{ "1", "2", "3"}, new String[]{"NestedC[0].Value", "NestedC[1].Value", "NestedC[2].Value"});
mapper.mapLine(fieldSet);
assertEquals(((TestNestedC) nestedList.getNestedC().get(0)).getValue(), 1);
assertEquals(((TestNestedC) nestedList.getNestedC().get(1)).getValue(), 2);
assertEquals(((TestNestedC) nestedList.getNestedC().get(2)).getValue(), 3);
}
private static class BeanWithIntArray {
private int[] numbers;
public void setNumbers(int[] numbers) {
this.numbers = numbers;
}
}
private static class TestNestedList {
List nestedC;
public List getNestedC() {
return nestedC;
}
public void setNestedC(List nestedC) {
this.nestedC = nestedC;
}
}
private static class TestNestedA {
private String valueA;
private int valueB;
TestNestedB testObjectB;
public TestNestedB getTestObjectB() {
return testObjectB;
}
public void setTestObjectB(TestNestedB testObjectB) {
this.testObjectB = testObjectB;
}
public String getValueA() {
return valueA;
}
public void setValueA(String valueA) {
this.valueA = valueA;
}
public int getValueB() {
return valueB;
}
public void setValueB(int valueB) {
this.valueB = valueB;
}
}
private static class TestNestedB {
private String valueA;
private TestNestedC testObjectC;
public TestNestedC getTestObjectC() {
return testObjectC;
}
public void setTestObjectC(TestNestedC testObjectC) {
this.testObjectC = testObjectC;
}
public String getValueA() {
return valueA;
}
public void setValueA(String valueA) {
this.valueA = valueA;
}
}
private static class TestNestedC {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.io.file.support.mapping;
import org.springframework.batch.io.file.support.mapping.PropertyMatches;
import junit.framework.TestCase;
public class PropertyMatchesTests extends TestCase {
public void setDuckSoup(String duckSoup) {
}
public void setDuckPate(String duckPate) {
}
public void setDuckBreast(String duckBreast) {
}
public void testPropertyMatchesWithMaxDistance() throws Exception {
String[] matches = PropertyMatches.forProperty("DUCK_SOUP", getClass(), 2).getPossibleMatches();
assertEquals(1, matches.length);
}
public void testPropertyMatchesWithDefault() throws Exception {
String[] matches = PropertyMatches.forProperty("DUCK_SOUP", getClass()).getPossibleMatches();
assertEquals(1, matches.length);
}
public void testBuildErrorMessageNoMatches() throws Exception {
String msg = PropertyMatches.forProperty("foo", getClass(), 2).buildErrorMessage();
assertTrue(msg.indexOf("foo")>=0);
}
public void testBuildErrorMessagePossibleMatch() throws Exception {
String msg = PropertyMatches.forProperty("DUCKSOUP", getClass(), 1).buildErrorMessage();
// the message contains the close match
assertTrue(msg.indexOf("duckSoup")>=0);
}
public void testBuildErrorMessageMultiplePossibleMatches() throws Exception {
String msg = PropertyMatches.forProperty("DUCKCRAP", getClass(), 4).buildErrorMessage();
// the message contains the close matches
assertTrue(msg.indexOf("duckSoup")>=0);
assertTrue(msg.indexOf("duckPate")>=0);
}
public void testEmptyString() throws Exception {
String[] matches = PropertyMatches.forProperty("", getClass(), 4).getPossibleMatches();
// TestCase base class has a name property
assertEquals("name", matches[0]);
}
}

View File

@@ -0,0 +1,135 @@
/*
* 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.io.file.support.mapping;
import java.math.BigDecimal;
import java.util.Date;
public class TestObject {
String varString;
boolean varBoolean;
char varChar;
byte varByte;
short varShort;
int varInt;
long varLong;
float varFloat;
double varDouble;
BigDecimal varBigDecimal;
Date varDate;
public Date getVarDate() {
return (Date)varDate.clone();
}
public void setVarDate(Date varDate) {
this.varDate = varDate == null ? null : (Date)varDate.clone();
}
public TestObject() {
}
public BigDecimal getVarBigDecimal() {
return varBigDecimal;
}
public void setVarBigDecimal(BigDecimal varBigDecimal) {
this.varBigDecimal = varBigDecimal;
}
public boolean isVarBoolean() {
return varBoolean;
}
public void setVarBoolean(boolean varBoolean) {
this.varBoolean = varBoolean;
}
public byte getVarByte() {
return varByte;
}
public void setVarByte(byte varByte) {
this.varByte = varByte;
}
public char getVarChar() {
return varChar;
}
public void setVarChar(char varChar) {
this.varChar = varChar;
}
public double getVarDouble() {
return varDouble;
}
public void setVarDouble(double varDouble) {
this.varDouble = varDouble;
}
public float getVarFloat() {
return varFloat;
}
public void setVarFloat(float varFloat) {
this.varFloat = varFloat;
}
public long getVarLong() {
return varLong;
}
public void setVarLong(long varLong) {
this.varLong = varLong;
}
public short getVarShort() {
return varShort;
}
public void setVarShort(short varShort) {
this.varShort = varShort;
}
public String getVarString() {
return varString;
}
public void setVarString(String varString) {
this.varString = varString;
}
public int getVarInt() {
return varInt;
}
public void setVarInt(int varInt) {
this.varInt = varInt;
}
}

View File

@@ -0,0 +1,130 @@
/*
* 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.io.file.support.oxm;
import java.io.IOException;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Result;
import junit.framework.TestCase;
import org.springframework.batch.io.file.support.oxm.MarshallingObjectToXmlSerializer;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.XmlMappingException;
/**
*
*
* @author Lucas Ward
*
*/
public class MarshallingObjectToXmlSerializerTests extends TestCase {
MarshallingObjectToXmlSerializer xmlSerializer;
MockMarshaller mockMarshaller = new MockMarshaller();
protected void setUp() throws Exception {
super.setUp();
xmlSerializer = new MarshallingObjectToXmlSerializer(mockMarshaller);
xmlSerializer.setEventWriter(new StubXmlEventWriter());
}
public void testSuccessfulWrite(){
Object objectToOutput = new Object();
xmlSerializer.serializeObject(objectToOutput);
assertEquals(objectToOutput, mockMarshaller.getMarshalledObject());
}
public void testUnsucessfulWrite(){
mockMarshaller.setThrowException(true);
try{
xmlSerializer.serializeObject(new Object());
fail("Exception expected");
}catch(DataAccessResourceFailureException ex){
//expected
}
}
private static class MockMarshaller implements Marshaller{
private Object marshalledObject;
private boolean throwException = false;
public void marshal(Object arg0, Result arg1)
throws XmlMappingException, IOException {
if(throwException){
throw new IOException();
}
marshalledObject = arg0;
}
public boolean supports(Class arg0) {
return false;
}
public Object getMarshalledObject() {
return marshalledObject;
}
public void setThrowException(boolean throwException) {
this.throwException = throwException;
}
}
private static class StubXmlEventWriter implements XMLEventWriter{
public void add(XMLEvent arg0) throws XMLStreamException { }
public void add(XMLEventReader arg0) throws XMLStreamException { }
public void close() throws XMLStreamException {
}
public void flush() throws XMLStreamException {
}
public NamespaceContext getNamespaceContext() {
return null;
}
public String getPrefix(String arg0) throws XMLStreamException {
return null;
}
public void setDefaultNamespace(String arg0) throws XMLStreamException {
}
public void setNamespaceContext(NamespaceContext arg0)
throws XMLStreamException {
}
public void setPrefix(String arg0, String arg1)
throws XMLStreamException {
}
}
}

View File

@@ -0,0 +1,92 @@
package org.springframework.batch.io.file.support.oxm;
import java.io.IOException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.file.support.oxm.UnmarshallingFragmentDeserializer;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.oxm.Unmarshaller;
/**
* Tests for {@link UnmarshallingFragmentDeserializer}
*
* @author Robert Kasanicky
*/
public class UnmarshallingFragmentDeserializerTests extends TestCase {
// object under test
private UnmarshallingFragmentDeserializer deserializer;
private XMLEventReader eventReader;
private String xml = "<root> </root>";
private Unmarshaller unmarshaller;
private MockControl unmarshallerControl = MockControl.createStrictControl(Unmarshaller.class);
protected void setUp() throws Exception {
Resource input = new ByteArrayResource(xml.getBytes());
eventReader = XMLInputFactory.newInstance().createXMLEventReader(input.getInputStream());
unmarshaller = (Unmarshaller) unmarshallerControl.getMock();
unmarshallerControl.setDefaultMatcher(MockControl.ALWAYS_MATCHER);
deserializer = new UnmarshallingFragmentDeserializer(unmarshaller);
}
/**
* Regular scenario when deserializer returns the object provided by Unmarshaller
*/
public void testSuccessfulDeserialization() throws Exception {
Object expectedResult = new Object();
unmarshaller.unmarshal(null);
unmarshallerControl.setReturnValue(expectedResult);
unmarshallerControl.replay();
Object result = deserializer.deserializeFragment(eventReader);
assertEquals(expectedResult, result);
unmarshallerControl.verify();
}
/**
* Appropriate exception rethrown in case of failure.
*/
public void testFailedDeserialization() throws Exception {
unmarshaller.unmarshal(null);
unmarshallerControl.setThrowable(new IOException());
unmarshallerControl.replay();
try {
deserializer.deserializeFragment(eventReader);
fail("Exception expected");
}
catch (DataAccessException e) {
// expected
}
unmarshallerControl.verify();
}
/**
* It makes no sense to create UnmarshallingFragmentDeserializer with null Unmarshaller,
* therefore it should cause exception.
*/
public void testExceptionOnNullUnmarshaller() {
try {
deserializer = new UnmarshallingFragmentDeserializer(null);
fail("Exception expected");
}
catch (IllegalArgumentException e) {
// expected
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.io.file.support.separator;
import org.springframework.batch.io.file.support.separator.DefaultRecordSeparatorPolicy;
import junit.framework.TestCase;
public class DefaultRecordSeparatorPolicyTests extends TestCase {
DefaultRecordSeparatorPolicy policy = new DefaultRecordSeparatorPolicy();
public void testNormalLine() throws Exception {
assertTrue(policy.isEndOfRecord("a string"));
}
public void testQuoteUnterminatedLine() throws Exception {
assertFalse(policy.isEndOfRecord("a string\"one"));
}
public void testEmptyLine() throws Exception {
assertTrue(policy.isEndOfRecord(""));
}
public void testNullLine() throws Exception {
assertTrue(policy.isEndOfRecord(null));
}
public void testPostProcess() throws Exception {
String line = "foo\nbar";
assertEquals(line, policy.postProcess(line));
}
public void testPreProcessWithQuote() throws Exception {
String line = "foo\"bar";
assertEquals(line+"\n", policy.preProcess(line));
}
public void testPreProcessWithNotDefaultQuote() throws Exception {
String line = "foo'bar";
policy.setQuoteCharacter("'");
assertEquals(line+"\n", policy.preProcess(line));
}
public void testPreProcessWithoutQuote() throws Exception {
String line = "foo";
assertEquals(line, policy.preProcess(line));
}
public void testContinuationMarkerNotEnd() throws Exception {
String line = "foo\\";
assertFalse(policy.isEndOfRecord(line));
}
public void testNotDefaultContinuationMarkerNotEnd() throws Exception {
String line = "foo bar";
policy.setContinuation("bar");
assertFalse(policy.isEndOfRecord(line));
}
public void testContinuationMarkerRemoved() throws Exception {
String line = "foo\\";
assertEquals("foo", policy.preProcess(line));
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.io.file.support.separator;
import org.springframework.batch.io.file.support.separator.SimpleRecordSeparatorPolicy;
import junit.framework.TestCase;
public class SimpleRecordSeparatorPolicyTests extends TestCase {
SimpleRecordSeparatorPolicy policy = new SimpleRecordSeparatorPolicy();
public void testNormalLine() throws Exception {
assertTrue(policy.isEndOfRecord("a string"));
}
public void testEmptyLine() throws Exception {
assertTrue(policy.isEndOfRecord(""));
}
public void testNullLine() throws Exception {
assertTrue(policy.isEndOfRecord(null));
}
public void testPostProcess() throws Exception {
String line = "foo\nbar";
assertEquals(line, policy.postProcess(line));
}
public void testPreProcess() throws Exception {
String line = "foo\nbar";
assertEquals(line, policy.preProcess(line));
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.io.file.support.separator;
import org.springframework.batch.io.file.support.separator.SuffixRecordSeparatorPolicy;
import junit.framework.TestCase;
public class SuffixRecordSeparatorPolicyTests extends TestCase {
private static final String LINE = "a string";
SuffixRecordSeparatorPolicy policy = new SuffixRecordSeparatorPolicy();
public void testNormalLine() throws Exception {
assertFalse(policy.isEndOfRecord(LINE));
}
public void testNormalLineWithDefaultSuffix() throws Exception {
assertTrue(policy.isEndOfRecord(LINE+SuffixRecordSeparatorPolicy.DEFAULT_SUFFIX));
}
public void testNormalLineWithNonDefaultSuffix() throws Exception {
policy.setSuffix(":foo");
assertTrue(policy.isEndOfRecord(LINE+ ":foo"));
}
public void testNormalLineWithDefaultSuffixAndWhitespace() throws Exception {
assertTrue(policy.isEndOfRecord(LINE+SuffixRecordSeparatorPolicy.DEFAULT_SUFFIX+" "));
}
public void testNormalLineWithDefaultSuffixWithIgnoreWhitespace() throws Exception {
policy.setIgnoreWhitespace(false);
assertFalse(policy.isEndOfRecord(LINE+SuffixRecordSeparatorPolicy.DEFAULT_SUFFIX+" "));
}
public void testEmptyLine() throws Exception {
assertFalse(policy.isEndOfRecord(""));
}
public void testNullLineIsEndOfRecord() throws Exception {
assertTrue(policy.isEndOfRecord(null));
}
public void testPostProcessSunnyDay() throws Exception {
String line = LINE;
String record = line+SuffixRecordSeparatorPolicy.DEFAULT_SUFFIX;
assertEquals(line, policy.postProcess(record));
}
public void testPostProcessNullLine() throws Exception {
String line = null;
assertEquals(null, policy.postProcess(line));
}
}

View File

@@ -0,0 +1,135 @@
/*
* 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.io.file.support.stax;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.file.support.stax.AbstractEventReaderWrapper;
import com.bea.xml.stream.events.StartDocumentEvent;
/**
* @author Lucas Ward
*
*/
public class AbstractEventReaderWrapperTests extends TestCase {
AbstractEventReaderWrapper eventReaderWrapper;
MockControl mockEventReaderControl = MockControl.createControl(XMLEventReader.class);
XMLEventReader xmlEventReader;
protected void setUp() throws Exception {
super.setUp();
xmlEventReader = (XMLEventReader)mockEventReaderControl.getMock();
eventReaderWrapper = new StubEventReader(xmlEventReader);
}
public void testClose() throws XMLStreamException {
xmlEventReader.close();
mockEventReaderControl.replay();
eventReaderWrapper.close();
mockEventReaderControl.verify();
}
public void testGetElementText() throws XMLStreamException {
String text = "text";
xmlEventReader.getElementText();
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.getElementText(), text);
mockEventReaderControl.verify();
}
public void testGetProperty() throws IllegalArgumentException {
String text = "text";
xmlEventReader.getProperty("name");
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.getProperty("name"), text);
mockEventReaderControl.verify();
}
public void testHasNext() {
xmlEventReader.hasNext();
mockEventReaderControl.setReturnValue(true);
mockEventReaderControl.replay();
assertTrue(eventReaderWrapper.hasNext());
mockEventReaderControl.verify();
}
public void testNext() {
String text = "text";
xmlEventReader.next();
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.next(), text);
mockEventReaderControl.verify();
}
public void testNextEvent() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.nextEvent();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.nextEvent(), event);
mockEventReaderControl.verify();
}
public void testNextTag() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.nextTag();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.nextTag(), event);
mockEventReaderControl.verify();
}
public void testPeek() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.peek();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.peek(), event);
mockEventReaderControl.verify();
}
public void testRemove() {
xmlEventReader.remove();
mockEventReaderControl.replay();
eventReaderWrapper.remove();
mockEventReaderControl.verify();
}
private static class StubEventReader extends AbstractEventReaderWrapper{
public StubEventReader(XMLEventReader wrappedEventReader) {
super(wrappedEventReader);
}
}
}

View File

@@ -0,0 +1,135 @@
/*
* 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.io.file.support.stax;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.file.support.stax.AbstractEventWriterWrapper;
import com.bea.xml.stream.events.StartDocumentEvent;
import com.bea.xml.stream.util.NamespaceContextImpl;
/**
* @author Lucas Ward
*
*/
public class AbstractEventWriterWrapperTests extends TestCase {
AbstractEventWriterWrapper eventWriterWrapper;
MockControl mockEventWriterControl = MockControl.createControl(XMLEventWriter.class);
XMLEventWriter xmlEventWriter;
protected void setUp() throws Exception {
super.setUp();
xmlEventWriter = (XMLEventWriter)mockEventWriterControl.getMock();
eventWriterWrapper = new StubEventWriter(xmlEventWriter);
}
public void testAdd() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventWriter.add(event);
mockEventWriterControl.replay();
eventWriterWrapper.add(event);
mockEventWriterControl.verify();
}
public void testAddReader() throws XMLStreamException {
MockControl readerControl = MockControl.createControl(XMLEventReader.class);
XMLEventReader reader = (XMLEventReader)readerControl.getMock();
xmlEventWriter.add(reader);
mockEventWriterControl.replay();
eventWriterWrapper.add(reader);
mockEventWriterControl.verify();
}
public void testClose() throws XMLStreamException {
xmlEventWriter.close();
mockEventWriterControl.replay();
eventWriterWrapper.close();
mockEventWriterControl.verify();
}
public void testFlush() throws XMLStreamException {
xmlEventWriter.flush();
mockEventWriterControl.replay();
eventWriterWrapper.flush();
mockEventWriterControl.verify();
}
public void testGetNamespaceContext() {
NamespaceContext context = new NamespaceContextImpl();
xmlEventWriter.getNamespaceContext();
mockEventWriterControl.setReturnValue(context);
mockEventWriterControl.replay();
assertEquals(eventWriterWrapper.getNamespaceContext(), context);
mockEventWriterControl.verify();
}
public void testGetPrefix() throws XMLStreamException {
String uri = "uri";
xmlEventWriter.getPrefix(uri);
mockEventWriterControl.setReturnValue(uri);
mockEventWriterControl.replay();
assertEquals(eventWriterWrapper.getPrefix(uri), uri);
mockEventWriterControl.verify();
}
public void testSetDefaultNamespace() throws XMLStreamException {
String uri = "uri";
xmlEventWriter.setDefaultNamespace(uri);
mockEventWriterControl.replay();
eventWriterWrapper.setDefaultNamespace(uri);
mockEventWriterControl.verify();
}
public void testSetNamespaceContext()
throws XMLStreamException {
NamespaceContext context = new NamespaceContextImpl();
xmlEventWriter.setNamespaceContext(context);
mockEventWriterControl.replay();
eventWriterWrapper.setNamespaceContext(context);
mockEventWriterControl.verify();
}
public void testSetPrefix() throws XMLStreamException {
String uri = "uri";
String prefix = "prefix";
xmlEventWriter.setPrefix(prefix, uri);
mockEventWriterControl.replay();
eventWriterWrapper.setPrefix(prefix, uri);
mockEventWriterControl.verify();
}
private static class StubEventWriter extends AbstractEventWriterWrapper{
public StubEventWriter(XMLEventWriter wrappedEventWriter) {
super(wrappedEventWriter);
}
}
}

View File

@@ -0,0 +1,145 @@
package org.springframework.batch.io.file.support.stax;
import java.util.NoSuchElementException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.springframework.batch.io.file.support.EventHelper;
import org.springframework.batch.io.file.support.stax.DefaultFragmentEventReader;
import org.springframework.batch.io.file.support.stax.DefaultTransactionalEventReader;
import org.springframework.batch.io.file.support.stax.FragmentEventReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
/**
* Tests for {@link DefaultFragmentEventReader}.
*
* @author Robert Kasanicky
*/
public class DefaultFragmentEventReaderTests extends TestCase {
// object under test
private FragmentEventReader fragmentReader;
// wrapped event fragmentReader
private XMLEventReader eventReader;
// test xml input
private String xml = "<root> <fragment> <misc1/> </fragment> <misc2/> <fragment> </fragment> </root>";
/**
* Setup the fragmentReader to read the test input.
*/
protected void setUp() throws Exception {
Resource input = new ByteArrayResource(xml.getBytes());
eventReader = new DefaultTransactionalEventReader(XMLInputFactory.newInstance().createXMLEventReader(
input.getInputStream()));
fragmentReader = new DefaultFragmentEventReader(eventReader);
}
/**
* Marked element should be wrapped with StartDocument and EndDocument
* events.
* Test uses redundant peek() calls before nextEvent() in important moments to assure
* peek() has no side effects on the inner state of reader.
*/
public void testFragmentWrapping() throws XMLStreamException {
assertTrue(fragmentReader.hasNext());
moveCursorBeforeFragmentStart();
fragmentReader.markStartFragment(); // mark the fragment
assertTrue(EventHelper.startElementName(eventReader.peek()).equals("fragment"));
// StartDocument inserted before StartElement
assertTrue(fragmentReader.peek().isStartDocument());
assertTrue(fragmentReader.nextEvent().isStartDocument());
// StartElement follows in the next step
assertTrue(EventHelper.startElementName(fragmentReader.nextEvent()).equals("fragment"));
moveCursorToNextElementEvent(); // misc1 start
fragmentReader.nextEvent(); // skip it
moveCursorToNextElementEvent(); // misc1 end
fragmentReader.nextEvent(); // skip it
moveCursorToNextElementEvent(); // move to end of fragment
// expected EndElement, peek first which should have no side effect
assertTrue(EventHelper.endElementName(fragmentReader.nextEvent()).equals("fragment"));
// inserted EndDocument
assertTrue(fragmentReader.peek().isEndDocument());
assertTrue(fragmentReader.nextEvent().isEndDocument());
// now the reader should behave like the document has finished
assertTrue(fragmentReader.peek() == null);
assertFalse(fragmentReader.hasNext());
try{
fragmentReader.nextEvent();
fail("nextEvent should simulate behavior as if document ended");
}
catch (NoSuchElementException expected) {
//expected
}
}
/**
* When fragment is marked as processed the cursor is moved after the end of
* the fragment.
*/
public void testMarkFragmentProcessed() throws XMLStreamException {
moveCursorBeforeFragmentStart();
fragmentReader.markStartFragment(); // mark the fragment start
// read only one event to move inside the fragment
XMLEvent startFragment = fragmentReader.nextEvent();
assertTrue(startFragment.isStartDocument());
fragmentReader.markFragmentProcessed(); // mark fragment as processed
fragmentReader.nextEvent(); // skip whitespace
// the next element after fragment end is <misc2/>
XMLEvent misc2 = fragmentReader.nextEvent();
assertTrue(EventHelper.startElementName(misc2).equals("misc2"));
}
/**
* Cursor is moved to the end of the fragment as usually even
* if nothing was read from the event reader after beginning
* of fragment was marked.
*/
public void testMarkFragmentProcessedImmediatelyAfterMarkFragmentStart() throws Exception {
moveCursorBeforeFragmentStart();
fragmentReader.markStartFragment();
fragmentReader.markFragmentProcessed();
fragmentReader.nextEvent(); // skip whitespace
// the next element after fragment end is <misc2/>
XMLEvent misc2 = fragmentReader.nextEvent();
assertTrue(EventHelper.startElementName(misc2).equals("misc2"));
}
private void moveCursorToNextElementEvent() throws XMLStreamException {
XMLEvent event = eventReader.peek();
while (!event.isStartElement() && !event.isEndElement()) {
eventReader.nextEvent();
event = eventReader.peek();
}
}
private void moveCursorBeforeFragmentStart() throws XMLStreamException {
XMLEvent event = eventReader.peek();
while (!event.isStartElement() || !EventHelper.startElementName(event).equals("fragment")) {
eventReader.nextEvent();
event = eventReader.peek();
}
}
}

View File

@@ -0,0 +1,69 @@
package org.springframework.batch.io.file.support.stax;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import junit.framework.TestCase;
import org.springframework.batch.io.file.support.EventHelper;
import org.springframework.batch.io.file.support.stax.DefaultTransactionalEventReader;
import org.springframework.batch.io.file.support.stax.TransactionalEventReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
/**
* Tests for {@link DefaultTransactionalEventReader}.
*
* @author Robert Kasanicky
*/
public class DefaultTransactionalEventReaderTests extends TestCase {
// object under test
private TransactionalEventReader reader;
// test xml input
private String xml = "<root> <fragment> <misc1/> </fragment> <misc2/> <fragment> </fragment> </root>";
protected void setUp() throws Exception {
Resource resource = new ByteArrayResource(xml.getBytes());
XMLEventReader wrappedReader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
reader = new DefaultTransactionalEventReader(wrappedReader);
}
/**
* Rollback scenario.
*/
public void testRollback() throws Exception {
assertTrue(reader.hasNext());
reader.nextEvent(); //start document
reader.nextEvent(); //start root element
reader.nextEvent(); //whitespace
reader.onCommit(); // commit point
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("fragment"));
reader.nextEvent(); //whitespace
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("misc1"));
assertTrue(EventHelper.endElementName(reader.peek()).equals("misc1"));
reader.onRollback(); // now we should be at the last commit point
assertTrue(reader.hasNext());
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("fragment"));
reader.nextEvent();
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("misc1"));
}
/**
* Remove operation is not supported
*/
public void testRemove() {
try {
reader.remove();
fail("UnsupportedOperationException expected on calling remove()");
}
catch (UnsupportedOperationException e) {
// expected
}
}
}

View File

@@ -0,0 +1,39 @@
package org.springframework.batch.io.file.support.stax;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.events.XMLEvent;
import org.springframework.batch.io.file.support.stax.EventSequence;
import junit.framework.TestCase;
/**
* Tests for {@link EventSequence}
*
* @author Robert Kasanicky
*/
public class EventSequenceTests extends TestCase {
// object under test
private EventSequence seq = new EventSequence();
private XMLEventFactory factory = XMLEventFactory.newInstance();
/**
* Common usage scenario.
*/
public void testCommonUse() {
XMLEvent event1 = factory.createComment("testString1");
XMLEvent event2 = factory.createCData("testString2");
seq.addEvent(event1);
seq.addEvent(event2);
assertTrue(seq.hasNext());
assertSame(event1, seq.nextEvent());
assertTrue(seq.hasNext());
assertSame(event2, seq.nextEvent());
assertFalse(seq.hasNext());
assertNull(seq.nextEvent());
}
}

View File

@@ -0,0 +1,51 @@
package org.springframework.batch.io.file.support.stax;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.file.support.stax.NoStartEndDocumentStreamWriter;
/**
* Tests for {@link NoStartEndDocumentStreamWriter}
*
* @author Robert Kasanicky
*/
public class NoStartEndDocumentWriterTests extends TestCase {
// object under test
private NoStartEndDocumentStreamWriter writer;
private XMLEventWriter wrappedWriter;
private MockControl wrappedWriterControl = MockControl.createStrictControl(XMLEventWriter.class);
private XMLEventFactory eventFactory = XMLEventFactory.newInstance();
protected void setUp() throws Exception {
wrappedWriter = (XMLEventWriter) wrappedWriterControl.getMock();
writer = new NoStartEndDocumentStreamWriter(wrappedWriter);
}
/**
* StartDocument and EndDocument events are not passed to the wrapped writer.
*/
public void testNoStartEnd() throws Exception {
XMLEvent event = eventFactory.createComment("testEvent");
//mock expects only a single event
wrappedWriter.add(event);
wrappedWriterControl.setVoidCallable();
wrappedWriterControl.replay();
writer.add(eventFactory.createStartDocument());
writer.add(event);
writer.add(eventFactory.createEndDocument());
wrappedWriterControl.verify();
}
}

View File

@@ -0,0 +1,37 @@
package org.springframework.batch.io.file.support.transform;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests for {@link AbstractLineTokenizer}.
*
* @author Robert Kasanicky
* @author Dave Syer
*/
public class CommonLineTokenizerTests extends TestCase {
/**
* Columns names are considered to be specified if they are not <code>null</code> or empty.
*/
public void testHasNames() {
AbstractLineTokenizer tokenizer = new AbstractLineTokenizer() {
protected List doTokenize(String line) {
return null;
}
};
assertFalse(tokenizer.hasNames());
tokenizer.setNames(null);
assertFalse(tokenizer.hasNames());
tokenizer.setNames(new String[0]);
assertFalse(tokenizer.hasNames());
tokenizer.setNames(new String[]{"name1", "name2"});
assertTrue(tokenizer.hasNames());
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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.io.file.support.transform;
import org.springframework.batch.io.file.support.transform.DelimitedLineAggregator;
import junit.framework.TestCase;
/**
* Unit tests for {@link DelimitedLineAggregator}
*
* @author robert.kasanicky
*/
public class DelimitedLineAggregatorTests extends TestCase {
private DelimitedLineAggregator aggregator;
public void testAggregate() {
aggregator = new DelimitedLineAggregator();
aggregator.setDelimiter(":");
String[] args = { "a", "bc", "def" };
String expectedResult = "a:bc:def";
String result = aggregator.aggregate(args);
assertEquals(result, expectedResult);
}
}

View File

@@ -0,0 +1,160 @@
/*
* 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.io.file.support.transform;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.support.transform.AbstractLineTokenizer;
import org.springframework.batch.io.file.support.transform.DelimitedLineTokenizer;
public class DelimitedLineTokenizerTests extends TestCase {
private static final String TOKEN_MATCHES = "token equals the expected string";
private DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
public void testTokenizeRegularUse() {
FieldSet tokens = tokenizer.tokenize("sfd,\"Well,I have no idea what to do in the afternoon\",sFj, asdf,,as\n");
assertEquals(6, tokens.getFieldCount());
assertTrue(TOKEN_MATCHES, tokens.readString(0).equals("sfd"));
assertTrue(TOKEN_MATCHES, tokens.readString(1).equals("Well,I have no idea what to do in the afternoon"));
assertTrue(TOKEN_MATCHES, tokens.readString(2).equals("sFj"));
assertTrue(TOKEN_MATCHES, tokens.readString(3).equals("asdf"));
assertTrue(TOKEN_MATCHES, tokens.readString(4).equals(""));
assertTrue(TOKEN_MATCHES, tokens.readString(5).equals("as"));
tokens = tokenizer.tokenize("First string,");
assertEquals(2, tokens.getFieldCount());
assertTrue(TOKEN_MATCHES, tokens.readString(0).equals("First string"));
assertTrue(TOKEN_MATCHES, tokens.readString(1).equals(""));
}
public void testInvalidConstructorArgument() {
try {
new DelimitedLineTokenizer(DelimitedLineTokenizer.DEFAULT_QUOTE_CHARACTER);
fail("Quote character can't be used as delimiter for delimited line tokenizer!");
}
catch (Exception e) {
assertTrue(true);
}
}
public void testDelimitedLineTokenizer() {
FieldSet line = tokenizer.tokenize("a,b,c");
assertEquals(3, line.getFieldCount());
}
public void testNames() {
tokenizer.setNames(new String[] {"A", "B", "C"});
FieldSet line = tokenizer.tokenize("a,b,c");
assertEquals(3, line.getFieldCount());
assertEquals("a", line.readString("A"));
}
public void testTooFewNames() {
tokenizer.setNames(new String[] {"A", "B"});
try {
tokenizer.tokenize("a,b,c");
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
}
}
public void testTooManyNames() {
tokenizer.setNames(new String[] {"A", "B", "C", "D"});
FieldSet line = tokenizer.tokenize("a,b,c");
assertEquals(4, line.getFieldCount());
assertEquals("c", line.readString("C"));
assertEquals(null, line.readString("D"));
}
public void testDelimitedLineTokenizerChar() {
AbstractLineTokenizer tokenizer = new DelimitedLineTokenizer(' ');
FieldSet line = tokenizer.tokenize("a b c");
assertEquals(3, line.getFieldCount());
}
public void testTokenizeWithQuotes() {
FieldSet line = tokenizer.tokenize("a,b,\"c\"");
assertEquals(3, line.getFieldCount());
assertEquals("c", line.readString(2));
}
public void testTokenizeWithNotDefaultQuotes() {
tokenizer.setQuoteCharacter('\'');
FieldSet line = tokenizer.tokenize("a,b,'c'");
assertEquals(3, line.getFieldCount());
assertEquals("c", line.readString(2));
}
public void testTokenizeWithEscapedQuotes() {
FieldSet line = tokenizer.tokenize("a,\"\"b,\"\"\"c\"");
assertEquals(3, line.getFieldCount());
assertEquals("\"\"b", line.readString(1));
assertEquals("\"c", line.readString(2));
}
public void testTokenizeWithUnclosedQuotes() {
tokenizer.setQuoteCharacter('\'');
FieldSet line = tokenizer.tokenize("a,\"b,c");
assertEquals(3, line.getFieldCount());
assertEquals("\"b", line.readString(1));
assertEquals("c", line.readString(2));
}
public void testTokenizeWithDelimiterAtEnd() {
FieldSet line = tokenizer.tokenize("a,b,c,");
assertEquals(4, line.getFieldCount());
assertEquals("c", line.readString(2));
assertEquals("", line.readString(3));
}
public void testEmptyLine() throws Exception {
FieldSet line = tokenizer.tokenize("");
assertEquals(0, line.getFieldCount());
}
public void testWhitespaceLine() throws Exception {
FieldSet line = tokenizer.tokenize(" ");
// whitespace counts as text
assertEquals(1, line.getFieldCount());
}
public void testNullLine() throws Exception {
FieldSet line = tokenizer.tokenize(null);
// null doesn't...
assertEquals(0, line.getFieldCount());
}
public void testMultiLineField() throws Exception {
FieldSet line = tokenizer.tokenize("a,b,c\nrap");
assertEquals(3, line.getFieldCount());
assertEquals("c\nrap", line.readString(2));
}
public void testMultiLineFieldWithQuotes() throws Exception {
FieldSet line = tokenizer.tokenize("a,b,\"c\nrap\"");
assertEquals(3, line.getFieldCount());
assertEquals("c\nrap", line.readString(2));
}
}

View File

@@ -0,0 +1,170 @@
/*
* 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.io.file.support.transform;
import org.springframework.batch.io.file.support.transform.FixedLengthLineAggregator;
import junit.framework.TestCase;
/**
* Unit tests for {@link FixedLengthLineAggregator}
*
* @author robert.kasanicky
* @author peter.zozom
*/
public class FixedLengthLineAggregatorTests extends TestCase {
// object under test
private FixedLengthLineAggregator aggregator = new FixedLengthLineAggregator();
/**
* If no ranges are specified, IllegalArgumentException is thrown
*/
public void testAggregateNullRecordDescriptor() {
String[] args = { "does not matter what is here" };
try {
aggregator.aggregate(args);
fail("should not work with no ranges specified");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Count of aggregated strings does not match the number of columns
*/
public void testAggregateWrongArgumentCount() {
String[] string = { "only one test string" };
aggregator.setColumns(new Range[0]);
try {
aggregator.aggregate(string);
fail("Exception expected: count of aggregated strings"
+ " does not match the number of columns");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Text length exceeds the length of the column.
*/
public void testAggregateInvalidInputLength() {
String[] args = { "Oversize" };
aggregator.setColumns(new Range[] {new Range(1,args[0].length()-1)});
try {
aggregator.aggregate(args);
fail("Invalid text length, exception should have been thrown");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Test aggregation
*/
public void testAggregate() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setColumns(new Range[] {new Range(1,9), new Range(10,18)});
String result = aggregator.aggregate(args);
assertEquals("MatchsizeSmallsize", result);
}
/**
* Test aggregation with last range unbound
*/
public void testAggregateWithLastRangeUnbound() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setColumns(new Range[] {new Range(1,12), new Range(13)});
String result = aggregator.aggregate(args);
assertEquals("Matchsize Smallsize", result);
}
/**
* Test aggregation with right alignment
*/
public void testAggregateFormattedRight() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment("right");
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,23)});
String result = aggregator.aggregate(args);
assertEquals(23,result.length());
assertEquals(result, " Matchsize Smallsize");
}
/**
* Test aggregation with center alignment
*/
public void testAggregateFormattedCenter() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment("center");
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,25)});
String result = aggregator.aggregate(args);
assertEquals(result, " Matchsize Smallsize ");
}
/**
* Test aggregation with left alignment
*/
public void testAggregateWithCustomPadding() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setPadding('.');
aggregator.setAlignment("left");
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,24)});
String result = aggregator.aggregate(args);
assertEquals(result, "Matchsize....Smallsize..");
}
/**
* Test aggregation with left alignment
*/
public void testAggregateFormattedLeft() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment("left");
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,24)});
String result = aggregator.aggregate(args);
assertEquals(result, "Matchsize Smallsize ");
}
/**
* Try set ivalid alignment
*/
public void testInvalidAlignment() {
try {
aggregator.setAlignment("foo");
fail("Exception was expected: invalid alignment value");
} catch (IllegalArgumentException iae) {
// expected
}
}
/**
* If one of the passed arguments is null, string filled with spaces should
* be returned
*/
public void testAggregateNullArgument() {
String[] args = { null };
aggregator.setColumns(new Range[] {new Range(1,3)});
assertEquals(" ", aggregator.aggregate(args));
}
}

View File

@@ -0,0 +1,127 @@
/*
* 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.io.file.support.transform;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.support.transform.FixedLengthTokenizer;
public class FixedLengthTokenizerTests extends TestCase {
private FixedLengthTokenizer tokenizer = new FixedLengthTokenizer();
private String line = null;
/**
* if null or empty string is tokenized, tokenizer returns empty fieldset
* (with no tokens).
*/
public void testTokenizeEmptyString() {
tokenizer.setColumns(new Range[] {new Range(1,5),new Range(6,10),new Range(11,15)});
FieldSet tokens = tokenizer.tokenize("");
assertEquals(0, tokens.getFieldCount());
}
public void testTokenizeNullString() {
tokenizer.setColumns(new Range[] {new Range(1,5),new Range(6,10),new Range(11,15)});
FieldSet tokens = tokenizer.tokenize(null);
assertEquals(0, tokens.getFieldCount());
}
public void testTokenizeRegularUse() {
tokenizer.setColumns(new Range[] {new Range(1,2),new Range(3,7),new Range(8,12)});
// test shorter line as defined by record descriptor
line = "H1";
FieldSet tokens = tokenizer.tokenize(line);
assertEquals(3, tokens.getFieldCount());
assertEquals("H1", tokens.readString(0));
assertEquals("", tokens.readString(1));
assertEquals("", tokens.readString(2));
}
public void testNormalLength() throws Exception {
tokenizer.setColumns(new Range[] {new Range(1,10),new Range(11,25),new Range(26,30)});
// test shorter line as defined by record descriptor
line = "H1";
FieldSet tokens = tokenizer.tokenize(line);
// test normal length
line = "H1 12345678 12345";
tokens = tokenizer.tokenize(line);
assertEquals(3, tokens.getFieldCount());
assertEquals(line.substring(0, 10).trim(), tokens.readString(0));
assertEquals(line.substring(10, 25).trim(), tokens.readString(1));
assertEquals(line.substring(25).trim(), tokens.readString(2));
}
public void testLongerLinesRestIgnored() throws Exception {
tokenizer.setColumns(new Range[] {new Range(1,10),new Range(11,25),new Range(26,30)});
// test shorter line as defined by record descriptor
line = "H1";
FieldSet tokens = tokenizer.tokenize(line);
// test longer lines => rest will be ignored
line = "H1 12345678 1234567890";
tokens = tokenizer.tokenize(line);
assertEquals(3, tokens.getFieldCount());
assertEquals(line.substring(0, 10).trim(), tokens.readString(0));
assertEquals(line.substring(10, 25).trim(), tokens.readString(1));
assertEquals(line.substring(25, 30).trim(), tokens.readString(2));
}
public void testNonAdjacentRangesUnsorted() throws Exception {
tokenizer.setColumns(new Range[] {new Range(14,28), new Range(34,38), new Range(1,10)});
// test shorter line as defined by record descriptor
line = "H1";
FieldSet tokens = tokenizer.tokenize(line);
// test normal length
line = "H1 +++12345678 +++++12345+++";
tokens = tokenizer.tokenize(line);
assertEquals(3, tokens.getFieldCount());
assertEquals(line.substring(0, 10).trim(), tokens.readString(2));
assertEquals(line.substring(13, 28).trim(), tokens.readString(0));
assertEquals(line.substring(33, 38).trim(), tokens.readString(1));
}
public void testAnotherTypeOfRecord() throws Exception {
tokenizer.setColumns(new Range[] {new Range(1,5),new Range(6,15),new Range(16,25),new Range(26,27)});
// test shorter line as defined by record descriptor
line = "H1";
FieldSet tokens = tokenizer.tokenize(line);
// test another type of record
line = "H2 123456 12345 12";
tokens = tokenizer.tokenize(line);
assertEquals(4, tokens.getFieldCount());
assertEquals(line.substring(0, 5).trim(), tokens.readString(0));
assertEquals(line.substring(5, 15).trim(), tokens.readString(1));
assertEquals(line.substring(15, 25).trim(), tokens.readString(2));
assertEquals(line.substring(25).trim(), tokens.readString(3));
}
public void testTokenizerInvalidSetup() {
tokenizer.setNames(new String[] {"a", "b"});
tokenizer.setColumns(new Range[] {new Range(1,5),new Range(6,15),new Range(16,25),new Range(26,27)});
try {
tokenizer.tokenize("Test tokenize");
fail("Exception was expected: too few names provided");
}
catch (Exception e) {
assertTrue(true);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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.io.file.support.transform;
import org.springframework.batch.io.file.support.transform.LineAggregator;
/**
* Stub implementation of {@link LineAggregator} interface for testing purposes.
*
* @author robert.kasanicky
*/
public class LineAggregatorStub implements LineAggregator {
/**
* Concatenates arguments. Ignores the LineDescriptor.
*/
public String aggregate(String[] args) {
String result = "";
for (int i = 1; i < args.length; i++) {
result = result + args[i];
}
return result;
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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.io.file.support.transform;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.support.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
import org.springframework.batch.io.file.support.transform.PrefixMatchingCompositeLineTokenizer;
public class PrefixMatchingCompositeLineTokenizerTests extends TestCase {
PrefixMatchingCompositeLineTokenizer tokenizer = new PrefixMatchingCompositeLineTokenizer();
public void testNoTokenizers() throws Exception {
try {
tokenizer.tokenize("a line");
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
// expected
}
}
public void testNullLine() throws Exception {
tokenizer.setTokenizers(Collections.singletonMap("foo", new DelimitedLineTokenizer()));
FieldSet fields = tokenizer.tokenize(null);
assertEquals(0, fields.getFieldCount());
}
public void testEmptyKeyMatchesAnyLine() throws Exception {
Map map = new HashMap();
map.put("", new DelimitedLineTokenizer());
map.put("foo", new LineTokenizer() {
public FieldSet tokenize(String line) {
return null;
}
});
tokenizer.setTokenizers(map);
FieldSet fields = tokenizer.tokenize("abc");
assertEquals(1, fields.getFieldCount());
}
public void testEmptyKeyDoesNotMatchWhenAlternativeAvailable() throws Exception {
Map map = new LinkedHashMap();
map.put("", new LineTokenizer() {
public FieldSet tokenize(String line) {
return null;
}
});
map.put("foo", new DelimitedLineTokenizer());
tokenizer.setTokenizers(map);
FieldSet fields = tokenizer.tokenize("foo,bar");
assertEquals("bar", fields.readString(1));
}
public void testNoMatch() throws Exception {
tokenizer.setTokenizers(Collections.singletonMap("foo", new DelimitedLineTokenizer()));
try {
tokenizer.tokenize("nomatch");
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
// expected
}
}
public void testMatchWithPrefix() throws Exception {
tokenizer.setTokenizers(Collections.singletonMap("foo", new LineTokenizer() {
public FieldSet tokenize(String line) {
return new FieldSet(new String[] {line});
}
}));
FieldSet fields = tokenizer.tokenize("foo bar");
assertEquals(1, fields.getFieldCount());
assertEquals("foo bar", fields.readString(0));
}
}

View File

@@ -0,0 +1,109 @@
package org.springframework.batch.io.file.support.transform;
import org.springframework.batch.io.file.support.transform.Range;
import org.springframework.batch.io.file.support.transform.RangeArrayPropertyEditor;
import junit.framework.TestCase;
public class RangeArrayPropertyEditorTests extends TestCase {
private Range[] ranges;
private RangeArrayPropertyEditor pe;
public void setUp() {
ranges = null;
pe = new RangeArrayPropertyEditor() {
public void setValue(Object value) {
ranges = (Range[]) value;
}
public Object getValue() {
return ranges;
}
};
}
public void testSetAsText() {
pe.setAsText("15, 32, 1-10, 33");
// result should be 15-31, 32-32, 1-10, 33-unbound
assertEquals(4, ranges.length);
assertEquals(15, ranges[0].getMin());
assertEquals(31, ranges[0].getMax());
assertEquals(32, ranges[1].getMin());
assertEquals(32, ranges[1].getMax());
assertEquals(1, ranges[2].getMin());
assertEquals(10, ranges[2].getMax());
assertEquals(33, ranges[3].getMin());
assertFalse(ranges[3].hasMaxValue());
}
public void testSetAsTextWithNoSpaces() {
pe.setAsText("15,32");
// result should be 15-31, 32-unbound
assertEquals(2, ranges.length);
assertEquals(15, ranges[0].getMin());
assertEquals(31, ranges[0].getMax());
assertEquals(32, ranges[1].getMin());
assertFalse(ranges[1].hasMaxValue());
}
public void testGetAsText() {
ranges = new Range[] { new Range(20), new Range(6, 15), new Range(2),
new Range(26, 95) };
assertEquals("20, 6-15, 2, 26-95", pe.getAsText());
}
public void testValidDisjointRanges() {
pe.setForceDisjointRanges(true);
// test disjoint ranges
pe.setAsText("1-5,11-15");
assertEquals(2, ranges.length);
assertEquals(1, ranges[0].getMin());
assertEquals(5, ranges[0].getMax());
assertEquals(11, ranges[1].getMin());
assertEquals(15, ranges[1].getMax());
}
public void testInvalidOverlappingRanges() {
pe.setForceDisjointRanges(true);
// test joint ranges
try {
pe.setAsText("1-10, 5-15");
fail("Exception expected: ranges are not disjoint");
} catch (IllegalArgumentException iae) {
// expected
}
}
public void testValidOverlappingRanges() {
// test joint ranges
pe.setAsText("1-10, 5-15");
assertEquals(2, ranges.length);
assertEquals(1, ranges[0].getMin());
assertEquals(10, ranges[0].getMax());
assertEquals(5, ranges[1].getMin());
assertEquals(15, ranges[1].getMax());
}
public void testInvalidInput() {
try {
pe.setAsText("1-5, b");
fail("Exception expected: 2nd range is invalid");
} catch (IllegalArgumentException iae) {
// expected
}
}
}

View File

@@ -0,0 +1,90 @@
/*
* 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.io.sample.domain;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* An XML customer.
*
* This is a complex type.
*/
public class Customer {
private String name;
private String address;
private int age;
private int moo;
private int poo;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoo() {
return moo;
}
public void setMoo(int moo) {
this.moo = moo;
}
public int getPoo() {
return poo;
}
public void setPoo(int poo) {
this.poo = poo;
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@@ -0,0 +1,54 @@
package org.springframework.batch.io.sample.domain;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Simple domain object for testing purposes.
*/
public class Foo {
private int id;
private String name;
private int value;
public Foo(){}
public Foo(int id, String name, int value) {
this.id = id;
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String toString() {
return "Foo[id=" +id +",name=" + name + ",value=" + value + "]";
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}

View File

@@ -0,0 +1,53 @@
package org.springframework.batch.io.sample.domain;
import java.util.ArrayList;
import java.util.List;
/**
* Custom class that contains the logic of providing and processing {@link Foo}
* objects. It serves the purpose to show how providing/processing logic contained in a
* custom class can be reused by the framework.
*
* @author Robert Kasanicky
*/
public class FooService {
public static final int GENERATION_LIMIT = 10;
private int counter = 0;
private List generatedFoos = new ArrayList(GENERATION_LIMIT);
private List processedFoos = new ArrayList(GENERATION_LIMIT);
private List processedFooNameValuePairs = new ArrayList(GENERATION_LIMIT);
public Foo generateFoo() {
if (counter++ >= GENERATION_LIMIT) return null;
Foo foo = new Foo(counter, "foo" + counter, counter);
generatedFoos.add(foo);
return foo;
}
public void processFoo(Foo foo) {
processedFoos.add(foo);
}
public void processNameValuePair(String name, int value) {
processedFooNameValuePairs.add(new Foo(0, name, value));
}
public List getGeneratedFoos() {
return generatedFoos;
}
public List getProcessedFoos() {
return processedFoos;
}
public List getProcessedFooNameValuePairs() {
return processedFooNameValuePairs;
}
}

View File

@@ -0,0 +1,80 @@
/*
* 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.io.sample.domain;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* An XML line-item.
*
* This is a complex type.
*/
public class LineItem {
private String description;
private double perUnitOunces;
private double price;
private int quantity;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getPerUnitOunces() {
return perUnitOunces;
}
public void setPerUnitOunces(double perUnitOunces) {
this.perUnitOunces = perUnitOunces;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.io.sample.domain;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* An XML order.
*
* This is a complex type.
*/
public class Order {
private Customer customer;
private Date date;
private List lineItems;
private Shipper shipper;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Date getDate() {
return (Date)date.clone();
}
public void setDate(Date date) {
this.date = date == null ? null : (Date)date.clone();
}
public List getLineItems() {
return lineItems;
}
public void setLineItems(List lineItems) {
this.lineItems = lineItems;
}
public Shipper getShipper() {
return shipper;
}
public void setShipper(Shipper shipper) {
this.shipper = shipper;
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.io.sample.domain;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* An XML shipper.
*
* This is a complex type.
*/
public class Shipper {
private String name;
private double perOunceRate;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPerOunceRate() {
return perOunceRate;
}
public void setPerOunceRate(double perOunceRate) {
this.perOunceRate = perOunceRate;
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(obj, this);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@@ -0,0 +1,183 @@
package org.springframework.batch.io.sql;
import java.util.Properties;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
import org.springframework.util.Assert;
/**
* Common scenarios for testing {@link InputSource} implementations which read data from database.
*
* @author Lucas Ward
* @author Robert Kasanicky
*/
public abstract class AbstractJdbcInputSourceIntegrationTests extends AbstractTransactionalDataSourceSpringContextTests {
protected InputSource source;
/**
* @return input source with all necessary dependencies set
*/
protected abstract InputSource createInputSource() throws Exception;
protected String[] getConfigLocations(){
return new String[] { "org/springframework/batch/io/sql/data-source-context.xml"};
}
protected void onSetUp()throws Exception{
super.onSetUp();
BatchTransactionSynchronizationManager.clearSynchronizations();
source = createInputSource();
getAsInitializingBean(source).afterPropertiesSet();
}
protected void onTearDown()throws Exception {
getAsDisposableBean(source).destroy();
BatchTransactionSynchronizationManager.clearSynchronizations();
super.onTearDown();
}
/**
* Regular scenario - read all rows and eventually return null.
*/
public void testNormalProcessing() throws Exception {
getAsInitializingBean(source).afterPropertiesSet();
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
Foo foo3 = (Foo) source.read();
assertEquals(3, foo3.getValue());
Foo foo4 = (Foo) source.read();
assertEquals(4, foo4.getValue());
Foo foo5 = (Foo) source.read();
assertEquals(5, foo5.getValue());
assertNull(source.read());
}
/**
* Restart scenario.
* @throws Exception
*/
public void testRestart() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
getAsRestartable(source).restoreFrom(restartData);
Foo fooAfterRestart = (Foo) source.read();
assertEquals(3, fooAfterRestart.getValue());
}
/**
* Reading from an input source and then trying to restore causes an error.
*/
public void testInvalidRestore() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
try {
getAsRestartable(source).restoreFrom(restartData);
fail();
}
catch (IllegalStateException ex) {
// expected
}
}
/**
* Empty restart data should be handled gracefully.
*/
public void testRestoreFromEmptyData() {
RestartData restartData = new GenericRestartData(new Properties());
getAsRestartable(source).restoreFrom(restartData);
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
}
/**
* Rollback scenario.
*/
public void testRollback() {
Foo foo1 = (Foo) source.read();
commit();
Foo foo2 = (Foo) source.read();
Assert.state(!foo2.equals(foo1));
Foo foo3 = (Foo) source.read();
Assert.state(!foo2.equals(foo3));
rollback();
assertEquals(foo2, source.read());
}
private void commit() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_COMMITTED);
}
private void rollback() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_ROLLED_BACK);
}
private Restartable getAsRestartable(InputSource source) {
return (Restartable) source;
}
private InitializingBean getAsInitializingBean(InputSource source) {
return (InitializingBean) source;
}
private DisposableBean getAsDisposableBean(InputSource source) {
return (DisposableBean) source;
}
}

View File

@@ -0,0 +1,257 @@
package org.springframework.batch.io.support;
import java.util.Properties;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
import org.springframework.util.Assert;
/**
* Common scenarios for testing {@link InputSource} implementations which read data from database.
*
* @author Lucas Ward
* @author Robert Kasanicky
*/
public abstract class AbstractDataSourceInputSourceIntegrationTests extends AbstractTransactionalDataSourceSpringContextTests {
protected InputSource source;
/**
* @return configured input source ready for use
*/
protected abstract InputSource createInputSource() throws Exception;
protected String[] getConfigLocations(){
return new String[] { "org/springframework/batch/io/sql/data-source-context.xml"};
}
/* (non-Javadoc)
* @see org.springframework.test.AbstractTransactionalSpringContextTests#onSetUpInTransaction()
*/
protected void onSetUpInTransaction() throws Exception {
super.onSetUpInTransaction();
BatchTransactionSynchronizationManager.clearSynchronizations();
source = createInputSource();
}
/* (non-Javadoc)
* @see org.springframework.test.AbstractTransactionalSpringContextTests#onTearDownAfterTransaction()
*/
protected void onTearDownAfterTransaction() throws Exception {
getAsDisposableBean(source).destroy();
BatchTransactionSynchronizationManager.clearSynchronizations();
super.onTearDownAfterTransaction();
}
/**
* Regular scenario - read all rows and eventually return null.
*/
public void testNormalProcessing() throws Exception {
getAsInitializingBean(source).afterPropertiesSet();
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
Foo foo3 = (Foo) source.read();
assertEquals(3, foo3.getValue());
Foo foo4 = (Foo) source.read();
assertEquals(4, foo4.getValue());
Foo foo5 = (Foo) source.read();
assertEquals(5, foo5.getValue());
assertNull(source.read());
}
/**
* Restart scenario - read records, save restart data, create new input source
* and restore from restart data - the new input source should continue where
* the old one finished.
*/
public void testRestart() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
getAsRestartable(source).restoreFrom(restartData);
Foo fooAfterRestart = (Foo) source.read();
assertEquals(3, fooAfterRestart.getValue());
}
/**
* Reading from an input source and then trying to restore causes an error.
*/
public void testInvalidRestore() throws Exception {
Foo foo1 = (Foo) source.read();
assertEquals(1, foo1.getValue());
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
try {
getAsRestartable(source).restoreFrom(restartData);
fail();
}
catch (IllegalStateException ex) {
// expected
}
}
/**
* Empty restart data should be handled gracefully.
*/
public void testRestoreFromEmptyData() {
RestartData restartData = new GenericRestartData(new Properties());
getAsRestartable(source).restoreFrom(restartData);
Foo foo = (Foo) source.read();
assertEquals(1, foo.getValue());
}
/**
* Rollback scenario - input source rollbacks to last commit point.
*/
public void testRollback() {
Foo foo1 = (Foo) source.read();
commit();
Foo foo2 = (Foo) source.read();
Assert.state(!foo2.equals(foo1));
Foo foo3 = (Foo) source.read();
Assert.state(!foo2.equals(foo3));
rollback();
assertEquals(foo2, source.read());
}
/**
* Rollback scenario with skip - input source rollbacks to last commit point.
*/
public void testRollbackAndSkip() {
if (!(source instanceof Skippable)) {
return;
}
Foo foo1 = (Foo) source.read();
commit();
Foo foo2 = (Foo) source.read();
Assert.state(!foo2.equals(foo1));
Foo foo3 = (Foo) source.read();
Assert.state(!foo2.equals(foo3));
getAsSkippable(source).skip();
rollback();
assertEquals(foo2, source.read());
Foo foo4 = (Foo) source.read();
assertEquals(4, foo4.getValue());
}
/**
* Rollback scenario with skip and restart - input source rollbacks to last commit point.
* @throws Exception
*/
public void testRollbackSkipAndRestart() throws Exception {
if (!(source instanceof Skippable)) {
return;
}
Foo foo1 = (Foo) source.read();
commit();
Foo foo2 = (Foo) source.read();
Assert.state(!foo2.equals(foo1));
Foo foo3 = (Foo) source.read();
Assert.state(!foo2.equals(foo3));
getAsSkippable(source).skip();
rollback();
RestartData restartData = getAsRestartable(source).getRestartData();
// create new input source
source = createInputSource();
getAsRestartable(source).restoreFrom(restartData);
assertEquals(foo2, source.read());
Foo foo4 = (Foo) source.read();
assertEquals(4, foo4.getValue());
}
private void commit() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_COMMITTED);
}
private void rollback() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_ROLLED_BACK);
}
private Skippable getAsSkippable(InputSource source) {
return (Skippable) source;
}
private Restartable getAsRestartable(InputSource source) {
return (Restartable) source;
}
private InitializingBean getAsInitializingBean(InputSource source) {
return (InitializingBean) source;
}
private DisposableBean getAsDisposableBean(InputSource source) {
return (DisposableBean) source;
}
}

View File

@@ -0,0 +1,133 @@
/*
* 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.io.support;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
import org.springframework.util.Assert;
/**
* @author Lucas Ward
*
*/
public class AbstractTransactionalIoSourceTests extends TestCase {
private MockIoSource source;
protected void setUp() throws Exception {
super.setUp();
source = new MockIoSource();
if(TransactionSynchronizationManager.isSynchronizationActive()){
TransactionSynchronizationManager.clearSynchronization();
}
TransactionSynchronizationManager.initSynchronization();
}
//AbstractInputSource should synchronize on first call to read.
public void testSynchronizationRegistration(){
source.registerSynchronization();
List synchronizations = (List)TransactionSynchronizationManager.getSynchronizations();
assertEquals(1, synchronizations.size());
}
public void testCommit(){
source.registerSynchronization();
commit();
assertTrue(source.commitCalled);
assertFalse(source.rollbackCalled);
}
public void testRollback(){
source.registerSynchronization();
rollback();
assertFalse(source.commitCalled);
assertTrue(source.rollbackCalled);
}
public void testCommitUnsynchronizedSource(){
commit();
assertFalse(source.commitCalled);
assertFalse(source.rollbackCalled);
}
public void testMultipleSynchronizations(){
source.registerSynchronization();
source.registerSynchronization();
//multiple calls to read should result in only one synchronization
List synchronizations = (List)TransactionSynchronizationManager.getSynchronizations();
assertEquals(1, synchronizations.size());
}
public void testUnknownStatus(){
invokeUnknown();
assertFalse(source.commitCalled);
assertFalse(source.rollbackCalled);
}
private static class MockIoSource extends AbstractTransactionalIoSource{
private boolean commitCalled = false;
private boolean rollbackCalled = false;
protected void transactionCommitted() {
Assert.isTrue(!commitCalled, "Commit aleady called");
commitCalled = true;
}
protected void transactionRolledBack() {
Assert.isTrue(!rollbackCalled, "Rollback aleady called");
rollbackCalled = true;
}
}
private void commit() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_COMMITTED);
}
private void rollback() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_ROLLED_BACK);
}
private void invokeUnknown() {
TransactionSynchronizationUtils.invokeAfterCompletion(
TransactionSynchronizationManager.getSynchronizations(),
TransactionSynchronization.STATUS_UNKNOWN);
}
}

View File

@@ -0,0 +1,132 @@
package org.springframework.batch.io.support;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.util.Assert;
import junit.framework.TestCase;
/**
* Tests for {@link FileUtils}
*
* @author Robert Kasanicky
*/
public class FileUtilsTests extends TestCase {
private File file = new File("FileUtilsTests.tmp");
/**
* No restart + file should not be overwritten => file is created if it does
* not exist, exception is thrown if it already exists
*/
public void testNoRestart() throws Exception {
FileUtils.setUpOutputFile(file, false, false);
assertTrue(file.exists());
try {
FileUtils.setUpOutputFile(file, false, false);
fail();
}
catch (Exception e) {
// expected
}
file.delete();
Assert.state(!file.exists());
FileUtils.setUpOutputFile(file, false, true);
assertTrue(file.exists());
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write("testString");
writer.close();
long size = file.length();
Assert.state(size > 0);
FileUtils.setUpOutputFile(file, false, true);
long newSize = file.length();
assertTrue(size != newSize);
assertEquals(0, newSize);
}
/**
* In case of restart, the file is supposed to exist and exception is thrown
* if it does not.
*/
public void testRestart() throws Exception {
try {
FileUtils.setUpOutputFile(file, true, false);
fail();
}
catch (DataAccessResourceFailureException e) {
// expected
}
try {
FileUtils.setUpOutputFile(file, true, true);
fail();
}
catch (DataAccessResourceFailureException e) {
// expected
}
file.createNewFile();
assertTrue(file.exists());
// with existing file there should be no trouble
FileUtils.setUpOutputFile(file, true, false);
FileUtils.setUpOutputFile(file, true, true);
}
/**
* If the directories on the file path do not exist, they should be created
*/
public void testCreateDirectoryStructure() {
File file = new File("testDirectory/testDirectory2/testFile.tmp");
File dir1 = new File("testDirectory");
File dir2 = new File("testDirectory/testDirectory2");
try {
FileUtils.setUpOutputFile(file, false, false);
assertTrue(file.exists());
assertTrue(dir1.exists());
assertTrue(dir2.exists());
}
finally {
file.delete();
dir2.delete();
dir1.delete();
}
}
public void testBadFile(){
File file = new File("new file"){
public boolean createNewFile() throws IOException {
throw new IOException();
}
};
try{
FileUtils.setUpOutputFile(file, false, false);
fail();
}catch(DataAccessResourceFailureException ex){
assertTrue(ex.getCause() instanceof IOException);
}finally{
file.delete();
}
}
protected void setUp() throws Exception {
Assert.state(!file.exists());
}
protected void tearDown() throws Exception {
file.delete();
}
}

View File

@@ -0,0 +1,257 @@
/*
* 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.io.support;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.io.ItemWriter;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatInterceptor;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author Dave Syer
*
*/
public class HibernateAwareItemWriterTests extends TestCase {
private class HibernateTemplateWrapper extends HibernateTemplate {
public void flush() throws DataAccessException {
list.add("flush");
}
public void clear() {
list.add("clear");
};
}
private class StubItemWriter implements ItemWriter, RepeatInterceptor {
public void write(Object item) {
list.add(item);
}
public void after(RepeatContext context, ExitStatus result) {
list.add(result);
}
public void before(RepeatContext context) {
list.add(context);
}
public void close(RepeatContext context) {
list.add(context);
}
public void onError(RepeatContext context, Throwable e) {
list.add(e);
}
public void open(RepeatContext context) {
list.add(context);
}
}
HibernateAwareItemWriter writer = new HibernateAwareItemWriter();
final List list = new ArrayList();
private RepeatContextSupport context;
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
writer.setDelegate(new StubItemWriter());
context = new RepeatContextSupport(null);
writer.open(context);
writer.setHibernateTemplate(new HibernateTemplateWrapper());
list.clear();
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
Map map = TransactionSynchronizationManager.getResourceMap();
for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
TransactionSynchronizationManager.unbindResource(key);
}
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#initDao()}.
*
* @throws Exception
*/
public void testAfterPropertiesSet() throws Exception {
writer = new HibernateAwareItemWriter();
try {
writer.afterPropertiesSet();
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
assertTrue("Wrong message for exception: " + e.getMessage(), e
.getMessage().indexOf("delegate") >= 0);
}
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#initDao()}.
*
* @throws Exception
*/
public void testAfterPropertiesSetWithDelegate() throws Exception {
writer.afterPropertiesSet();
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#write(java.lang.Object)}.
*/
public void testWrite() {
writer.write("foo");
assertEquals(1, list.size());
assertTrue(list.contains("foo"));
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#write(java.lang.Object)}.
*/
public void testCloseWithFailure() {
final RuntimeException ex = new RuntimeException("bar");
writer.setHibernateTemplate(new HibernateTemplate() {
public void flush() throws DataAccessException {
throw ex;
}
});
try {
writer.close(context);
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("bar", e.getMessage());
}
assertEquals(2, list.size());
assertTrue(list.contains(ex));
assertTrue(list.contains(context));
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#write(java.lang.Object)}.
*/
public void testWriteAndCloseWithFailure() {
final RuntimeException ex = new RuntimeException("bar");
writer.setHibernateTemplate(new HibernateTemplateWrapper() {
public void flush() throws DataAccessException {
throw ex;
}
});
writer.write("foo");
try {
writer.close(context);
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("bar", e.getMessage());
}
assertEquals(3, list.size());
assertTrue(list.contains(ex));
assertTrue(list.contains(context));
writer.setHibernateTemplate(new HibernateTemplateWrapper() {
public void flush() throws DataAccessException {
list.add("flush");
}
});
writer.write("foo");
assertEquals(6, list.size());
assertTrue(list.contains("flush"));
assertTrue(list.contains("clear"));
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#before(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testBefore() {
writer.before(context);
assertEquals(1, list.size());
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#after(org.springframework.batch.repeat.RepeatContext, org.springframework.batch.repeat.ExitStatus)}.
*/
public void testAfter() {
writer.after(context, ExitStatus.FINISHED);
assertEquals(1, list.size());
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#close(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testClose() {
writer.close(context);
assertEquals(3, list.size());
assertTrue(list.contains("flush"));
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#close(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testCloseAfterClear() {
Map map = TransactionSynchronizationManager.getResourceMap();
String key = (String) map.keySet().iterator().next();
TransactionSynchronizationManager.unbindResource(key);
writer.close(context);
assertEquals(3, list.size());
assertTrue(list.contains("flush"));
assertTrue(list.contains("clear"));
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#onError(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)}.
*/
public void testOnError() {
writer.onError(context, new Exception());
assertEquals(1, list.size());
}
/**
* Test method for
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#open(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testOpen() {
writer.open(context);
assertEquals(1, list.size());
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item;
import junit.framework.TestCase;
import org.springframework.batch.item.provider.AbstractItemProvider;
public class ItemProviderTests extends TestCase {
ItemProvider provider = new AbstractItemProvider() {
public Object next() {
return "foo";
}
};
public void testNext() throws Exception {
assertEquals("foo", provider.next());
}
public void testRecover() throws Exception {
try {
provider.recover("foo", null);
}
catch (Exception e) {
fail("Unexpected Exception");
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* 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.item.exception;
import org.springframework.batch.item.exception.UnexpectedInputException;
import org.springframework.batch.repeat.exception.AbstractExceptionTests;
public class UnexpectedInputExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new UnexpectedInputException(msg, null);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new UnexpectedInputException(msg, t);
}
}

View File

@@ -0,0 +1,149 @@
package org.springframework.batch.item.processor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.processor.CompositeItemProcessor;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
/**
* Tests for {@link CompositeItemProcessor}
*
* @author Robert Kasanicky
*/
public class CompositeItemProcessorTests extends TestCase {
// object under test
private CompositeItemProcessor itemProcessor = new CompositeItemProcessor();
/**
* Regular usage scenario.
* All injected processors should be called.
*/
public void testProcess() throws Exception {
final int NUMBER_OF_PROCESSORS = 10;
Object data = new Object();
List controls = new ArrayList(NUMBER_OF_PROCESSORS);
List processors = new ArrayList(NUMBER_OF_PROCESSORS);
for (int i = 0; i < NUMBER_OF_PROCESSORS; i++) {
MockControl control = MockControl.createStrictControl(ItemProcessor.class);
ItemProcessor processor = (ItemProcessor) control.getMock();
processor.process(data);
control.setVoidCallable();
control.replay();
processors.add(processor);
controls.add(control);
}
itemProcessor.setItemProcessors(processors);
itemProcessor.process(data);
for (Iterator iterator = controls.iterator(); iterator.hasNext();) {
MockControl control = (MockControl) iterator.next();
control.verify();
}
}
/**
* Statistics of injected ItemProcessors should be returned under keys prefixed with their list index.
*/
public void testStatistics() {
final ItemProcessor p1 = new ItemProcessorStub();
final ItemProcessor p2 = new ItemProcessorStub();
List itemProcessors = new ArrayList(){{
add(p1);
add(p2);
}};
itemProcessor.setItemProcessors(itemProcessors);
Properties stats = itemProcessor.getStatistics();
assertEquals(String.valueOf(p1.hashCode()), stats.getProperty("0#" + ItemProcessorStub.STATS_KEY));
assertEquals(String.valueOf(p2.hashCode()), stats.getProperty("1#" + ItemProcessorStub.STATS_KEY));
}
/**
* All Restartable processors should be restarted, not-Restartable processors should be ignored.
*/
public void testRestart() {
//this mock with undefined behavior makes sure not-Restartable processor is ignored
MockControl p1c = MockControl.createStrictControl(ItemProcessor.class);
final ItemProcessor p1 = (ItemProcessor) p1c.getMock();
final ItemProcessor p2 = new ItemProcessorStub();
final ItemProcessor p3 = new ItemProcessorStub();
List itemProcessors = new ArrayList(){{
add(p1);
add(p2);
add(p3);
}};
itemProcessor.setItemProcessors(itemProcessors);
RestartData rd = itemProcessor.getRestartData();
itemProcessor.restoreFrom(rd);
for (Iterator iterator = itemProcessors.iterator(); iterator.hasNext();) {
ItemProcessor processor = (ItemProcessor) iterator.next();
if (processor instanceof ItemProcessorStub) {
assertTrue("Injected processors are restarted",
((ItemProcessorStub)processor).restarted);
}
}
}
/**
* Stub for testing restart. Checks the restart data received is the same that was returned by
* <code>getRestartData()</code>
*/
private static class ItemProcessorStub implements ItemProcessor, Restartable, StatisticsProvider {
private static final String RESTART_KEY = "restartData";
private static final String STATS_KEY = "stats";
private boolean restarted = false;
private final int hashCode = this.hashCode();
public RestartData getRestartData() {
Properties props = new Properties(){{
setProperty(RESTART_KEY, String.valueOf(hashCode));
}};
return new GenericRestartData(props);
}
public void restoreFrom(RestartData data) {
if (Integer.valueOf(data.getProperties().getProperty(RESTART_KEY)).intValue() != hashCode()) {
fail("received restart data is not the same which was saved");
}
restarted = true;
}
public void process(Object data) throws Exception {
// do nothing
}
public Properties getStatistics() {
return new Properties() {{
setProperty(STATS_KEY, String.valueOf(hashCode));
}};
}
}
}

View File

@@ -0,0 +1,95 @@
package org.springframework.batch.item.processor;
import java.util.ArrayList;
import junit.framework.TestCase;
import org.easymock.MockControl;
/**
* Tests for {@link CompositeItemTransformer}.
*
* @author Robert Kasanicky
*/
public class CompositeItemTransformerTests extends TestCase {
private CompositeItemTransformer composite = new CompositeItemTransformer();
private ItemTransformer transformer1;
private ItemTransformer transformer2;
private MockControl tControl1 = MockControl.createControl(ItemTransformer.class);
private MockControl tControl2 = MockControl.createControl(ItemTransformer.class);
protected void setUp() throws Exception {
transformer1 = (ItemTransformer) tControl1.getMock();
transformer2 = (ItemTransformer) tControl2 .getMock();
composite.setItemTransformers(new ArrayList() {{
add(transformer1); add(transformer2);
}});
composite.afterPropertiesSet();
}
/**
* Regular usage scenario - item is passed through the processing chain,
* return value of the of the last transformation is returned by the composite.
*/
public void testTransform() throws Exception {
Object item = new Object();
Object itemAfterFirstTransfromation = new Object();
Object itemAfterSecondTransformation = new Object();
transformer1.transform(item);
tControl1.setReturnValue(itemAfterFirstTransfromation);
transformer2.transform(itemAfterFirstTransfromation);
tControl2.setReturnValue(itemAfterSecondTransformation);
tControl1.replay();
tControl2.replay();
assertSame(itemAfterSecondTransformation, composite.transform(item));
tControl1.verify();
tControl2.verify();
}
/**
* The list of transformers must not be null or empty and
* can contain only instances of {@link ItemTransformer}.
*/
public void testAfterPropertiesSet() throws Exception {
// value not set
composite.setItemTransformers(null);
try {
composite.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
// empty list
composite.setItemTransformers(new ArrayList());
try {
composite.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
// invalid list member
composite.setItemTransformers(new ArrayList() {{ add(new Object()); }});
try {
composite.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
}

View File

@@ -0,0 +1,55 @@
package org.springframework.batch.item.processor;
import java.util.List;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.io.sample.domain.FooService;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
/**
* Tests for {@link DelegatingItemProcessor}.
*
* @author Robert Kasanicky
*/
public class DelegatingItemProcessorIntegrationTests extends AbstractDependencyInjectionSpringContextTests {
private DelegatingItemProcessor processor;
private FooService fooService;
protected String getConfigPath() {
return "delegating-item-processor.xml";
}
/**
* Regular usage scenario - input object should be passed to
* the service the injected invoker points to.
*/
public void testProcess() throws Exception {
Foo foo;
while ((foo = fooService.generateFoo()) != null) {
processor.process(foo);
}
List input = fooService.getGeneratedFoos();
List processed = fooService.getProcessedFoos();
assertEquals(input.size(), processed.size());
assertFalse(fooService.getProcessedFoos().isEmpty());
for (int i = 0; i < input.size(); i++) {
assertSame(input.get(i), processed.get(i));
}
}
//setter for auto-injection
public void setProcessor(DelegatingItemProcessor processor) {
this.processor = processor;
}
//setter for auto-injection
public void setFooService(FooService fooService) {
this.fooService = fooService;
}
}

View File

@@ -0,0 +1,186 @@
/*
* 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.item.processor;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
import org.springframework.batch.io.ItemWriter;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.processor.ItemWriterItemProcessor;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.support.PropertiesConverter;
/**
* @author Dave Syer
*
*/
public class ItemWriterItemProcessorTests extends TestCase {
private ItemWriterItemProcessor processor = new ItemWriterItemProcessor();
private ItemWriter writer;
/*
* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
writer = new MockOutputSource("test");
processor.setItemWriter(writer);
processor.afterPropertiesSet();
}
public void testProcess() throws Exception {
processor.process("foo");
assertEquals(1, list.size());
assertEquals("test:foo", list.get(0));
}
/**
* Gets statistics from the input template
*/
public void testGetStatistics() {
Properties props = processor.getStatistics();
assertEquals("b", props.getProperty("a"));
}
/**
* Gets restart data from the input template
*/
public void testGetRestartData() {
Properties props = processor.getRestartData().getProperties();
assertEquals("foo", props.getProperty("value"));
}
/**
* Forward restart data to input template
* @throws Exception
*/
public void testRestoreFrom() throws Exception {
processor.restoreFrom(new GenericRestartData(PropertiesConverter.stringToProperties("value=bar")));
processor.process("foo");
assertEquals("bar:foo", list.get(0));
}
/**
* Forward restart data to input template
* @throws Exception
*/
public void testGetRestartDataWithoutRestartable() throws Exception {
processor.setItemWriter(null);
try {
processor.getRestartData();
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
}
/**
* Forward restart data to input template
* @throws Exception
*/
public void testRestoreFromWithoutRestartable() throws Exception {
processor.setItemWriter(null);
try {
processor.restoreFrom(new GenericRestartData(PropertiesConverter.stringToProperties("value=bar")));
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
}
/**
* Gets statistics from the input template
*/
public void testGetStatisticsWithoutStatisticsProvider() {
processor.setItemWriter(null);
Properties props = processor.getStatistics();
assertEquals(null, props.getProperty("a"));
}
public void testSkip() {
processor.skip();
assertEquals(1, list.size());
assertEquals("after skip", list.get(0));
}
/**
* ItemWriter property must be set.
*/
public void testAfterPropertiesSet() throws Exception {
processor.setItemWriter(null);
try {
processor.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
private List list = new ArrayList();
/**
* @author Dave Syer
*
*/
public class MockOutputSource implements ItemWriter, StatisticsProvider, Restartable, Skippable {
private String value;
public MockOutputSource(String string) {
this.value = string;
}
public void write(Object output) {
list.add(value+":"+output);
}
public void close() {
}
public void open() {
}
public Properties getStatistics() {
return PropertiesConverter.stringToProperties("a=b");
}
public RestartData getRestartData() {
return new GenericRestartData(PropertiesConverter.stringToProperties("value=foo"));
}
public void restoreFrom(RestartData data) {
value = data.getProperties().getProperty("value");
}
public void skip() {
list.add("after skip");
}
}
}

View File

@@ -0,0 +1,58 @@
package org.springframework.batch.item.processor;
import java.util.List;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.io.sample.domain.FooService;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
/**
* Tests for {@link PropertyExtractingDelegatingItemProcessor}
*
* @author Robert Kasanicky
*/
public class PropertyExtractingDelegatingItemProccessorIntegrationTests
extends AbstractDependencyInjectionSpringContextTests {
private PropertyExtractingDelegatingItemProcessor processor;
private FooService fooService;
protected String getConfigPath() {
return "pe-delegating-item-processor.xml";
}
/**
* Regular usage scenario - input object should be passed to
* the service the injected invoker points to.
*/
public void testProcess() throws Exception {
Foo foo;
while ((foo = fooService.generateFoo()) != null) {
processor.process(foo);
}
List input = fooService.getGeneratedFoos();
List processed = fooService.getProcessedFooNameValuePairs();
assertEquals(input.size(), processed.size());
assertFalse(fooService.getProcessedFooNameValuePairs().isEmpty());
for (int i = 0; i < input.size(); i++) {
Foo inputFoo = (Foo) input.get(i);
Foo outputFoo = (Foo) processed.get(i);
assertEquals(inputFoo.getName(), outputFoo.getName());
assertEquals(inputFoo.getValue(), outputFoo.getValue());
assertEquals(0, outputFoo.getId());
}
}
public void setProcessor(PropertyExtractingDelegatingItemProcessor processor) {
this.processor = processor;
}
public void setFooService(FooService fooService) {
this.fooService = fooService;
}
}

View File

@@ -0,0 +1,70 @@
package org.springframework.batch.item.processor;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.ItemWriter;
/**
* Tests for {@link TransformerWriterItemProcessor}.
*
* @author Robert Kasanicky
*/
public class TransformerWriterItemProcessorTests extends TestCase {
private TransformerWriterItemProcessor processor = new TransformerWriterItemProcessor();
private ItemTransformer transformer;
private ItemWriter itemWriter;
private MockControl tControl = MockControl.createControl(ItemTransformer.class);
private MockControl outControl = MockControl.createControl(ItemWriter.class);
protected void setUp() throws Exception {
transformer = (ItemTransformer) tControl.getMock();
itemWriter = (ItemWriter) outControl.getMock();
processor.setItemTransformer(transformer);
processor.setItemWriter(itemWriter);
processor.afterPropertiesSet();
}
/**
* Regular usage scenario - item is passed to transformer
* and the result of transformation is passed to output source.
*/
public void testProcess() throws Exception {
Object item = new Object();
Object itemAfterTransformation = new Object();
transformer.transform(item);
tControl.setReturnValue(itemAfterTransformation);
itemWriter.write(itemAfterTransformation);
outControl.setVoidCallable();
tControl.replay();
outControl.replay();
processor.process(item);
tControl.verify();
outControl.verify();
}
/**
* Item transformer must be set.
*/
public void testAfterPropertiesSet() throws Exception {
// value not set
processor.setItemTransformer(null);
try {
processor.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
}

View File

@@ -0,0 +1,60 @@
package org.springframework.batch.item.provider;
import java.util.Collection;
import java.util.Iterator;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.file.FieldSetMapper;
public class AggregateItemProviderTests extends TestCase {
private MockControl inputControl;
private InputSource input;
private AggregateItemProvider provider;
public void setUp() {
//create mock for input
inputControl = MockControl.createControl(InputSource.class);
input = (InputSource) inputControl.getMock();
//create provider
provider = new AggregateItemProvider();
provider.setInputSource(input);
}
public void testNext() {
//set-up mock input
input.read();
inputControl.setReturnValue(FieldSetMapper.BEGIN_RECORD);
input.read();
inputControl.setReturnValue("line",3);
input.read();
inputControl.setReturnValue(FieldSetMapper.END_RECORD);
input.read();
inputControl.setReturnValue(null);
inputControl.replay();
//read object
Object result = provider.next();
//it should be collection of 3 strings "line"
assertTrue(result instanceof Collection);
Collection lines = (Collection)result;
assertEquals(3, lines.size());
for (Iterator i = lines.iterator(); i.hasNext();) {
assertEquals("line", i.next());
}
//read object again - it should return null
assertNull(provider.next());
//verify method calls
inputControl.verify();
}
}

View File

@@ -0,0 +1,69 @@
package org.springframework.batch.item.provider;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.io.sample.domain.FooService;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
/**
* Tests for {@link DelegatingItemProvider}.
*
* @author Robert Kasanicky
*/
public class DelegatingItemProviderIntegrationTests extends AbstractDependencyInjectionSpringContextTests {
private DelegatingItemProvider provider;
private FooService fooService;
protected String getConfigPath() {
return "delegating-item-provider.xml";
}
/**
* Regular usage scenario - items are retrieved from
* the service injected invoker points to.
*/
public void testNext() throws Exception {
List returnedItems = new ArrayList();
Object item;
while ((item = provider.next()) != null) {
returnedItems.add(item);
}
List input = fooService.getGeneratedFoos();
assertEquals(input.size(), returnedItems.size());
assertFalse(returnedItems.isEmpty());
for (int i = 0; i<input.size(); i++) {
assertSame(input.get(i), returnedItems.get(i));
}
}
/**
* getKey(..) is implemented trivially.
*/
public void testGetKey() {
Object item = new Object();
assertSame(item, provider.getKey(item));
}
/**
* Recover not supported.
*/
public void testRecover() {
assertFalse(provider.recover(null, null));
}
public void setProvider(DelegatingItemProvider provider) {
this.provider = provider;
}
public void setFooService(FooService fooService) {
this.fooService = fooService;
}
}

View File

@@ -0,0 +1,137 @@
/*
* 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.item.provider;
import java.util.Properties;
import junit.framework.TestCase;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.support.PropertiesConverter;
/**
* Unit test for {@link InputSourceItemProvider}
*
* @author Robert Kasanicky
*/
public class InputSourceItemProviderTests extends TestCase {
// object under test
private InputSourceItemProvider itemProvider = new InputSourceItemProvider();
private InputSource source;
// create input template and inject it to data provider
protected void setUp() throws Exception {
source = new MockInputSource(this);
itemProvider.setInputSource(source);
}
public void testAfterPropertiesSet()throws Exception{
//shouldn't throw an exception since the input source is set
itemProvider.afterPropertiesSet();
}
public void testNullInputSource(){
try{
itemProvider.setInputSource(null);
itemProvider.afterPropertiesSet();
fail();
}catch(Exception ex){
assertTrue(ex instanceof IllegalArgumentException);
}
}
/**
* Uses input template to provide the domain object.
*/
public void testNext() {
Object result = itemProvider.next();
assertSame("domain object is provided by the input template", this, result);
}
/**
* Gets statistics from the input template
*/
public void testGetStatistics() {
Properties props = itemProvider.getStatistics();
assertEquals("b", props.getProperty("a"));
}
/**
* Gets restart data from the input template
*/
public void testGetRestartData() {
Properties props = itemProvider.getRestartData().getProperties();
assertEquals("foo", props.getProperty("value"));
}
/**
* Forwared restart data to input template
*/
public void testRestoreFrom() {
itemProvider.restoreFrom(new GenericRestartData(PropertiesConverter.stringToProperties("value=bar")));
assertEquals("bar", itemProvider.next());
}
public void testSkip() {
itemProvider.skip();
assertEquals("after skip", itemProvider.next());
}
private static class MockInputSource implements InputSource, StatisticsProvider, Restartable, Skippable {
private Object value;
public Properties getStatistics() {
return PropertiesConverter.stringToProperties("a=b");
}
public RestartData getRestartData() {
return new GenericRestartData(PropertiesConverter.stringToProperties("value=foo"));
}
public void restoreFrom(RestartData data) {
value = data.getProperties().getProperty("value");
}
public MockInputSource(Object value) {
this.value = value;
}
public Object read() {
return value;
}
public void close() {
}
public void open() {
}
public void skip() {
value = "after skip";
}
}
}

View File

@@ -0,0 +1,181 @@
/*
* 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.item.provider;
import java.util.Date;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.Queue;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.jms.core.JmsOperations;
public class JmsItemProviderTests extends TestCase {
JmsItemProvider itemProvider = new JmsItemProvider();
public void testNoItemTypeSunnyDay() {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
templateControl.expectAndReturn(jmsTemplate.receiveAndConvert(), "foo");
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
assertEquals("foo", itemProvider.next());
templateControl.verify();
}
public void testSetItemTypeSunnyDay() {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
templateControl.expectAndReturn(jmsTemplate.receiveAndConvert(), "foo");
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(String.class);
assertEquals("foo", itemProvider.next());
templateControl.verify();
}
public void testSetItemSubclassTypeSunnyDay() {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
Date date = new java.sql.Date(0L);
templateControl.expectAndReturn(jmsTemplate.receiveAndConvert(), date);
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(Date.class);
assertEquals(date, itemProvider.next());
templateControl.verify();
}
public void testSetItemTypeMismatch() {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
templateControl.expectAndReturn(jmsTemplate.receiveAndConvert(), "foo");
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(Date.class);
try {
itemProvider.next();
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
assertTrue(e.getMessage().indexOf("wrong type") >= 0);
}
templateControl.verify();
}
public void testNextMessageSunnyDay() {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
MockControl messageControl = MockControl.createControl(Message.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
Message message = (Message) messageControl.getMock();
templateControl.expectAndReturn(jmsTemplate.receive(), message);
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(Message.class);
assertEquals(message, itemProvider.next());
templateControl.verify();
}
public void testRecoverWithNoDestination() throws Exception {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(String.class);
itemProvider.recover("foo", null);
templateControl.verify();
}
public void testErrorQueueWithDestinationName() throws Exception {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
jmsTemplate.convertAndSend("queue", "foo");
templateControl.setVoidCallable();
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(String.class);
itemProvider.setErrorDestinationName("queue");
itemProvider.recover("foo", null);
templateControl.verify();
}
public void testErrorQueueWithDestination() throws Exception {
MockControl templateControl = MockControl.createControl(JmsOperations.class);
MockControl queueControl = MockControl.createControl(Queue.class);
Destination queue = (Destination) queueControl.getMock();
queueControl.replay();
JmsOperations jmsTemplate = (JmsOperations) templateControl.getMock();
jmsTemplate.convertAndSend(queue, "foo");
templateControl.setVoidCallable();
templateControl.replay();
itemProvider.setJmsTemplate(jmsTemplate);
itemProvider.setItemType(String.class);
itemProvider.setErrorDestination(queue);
itemProvider.recover("foo", null);
templateControl.verify();
}
public void testGetKeyFromMessage() throws Exception {
MockControl messageControl = MockControl.createControl(Message.class);
Message message = (Message) messageControl.getMock();
messageControl.expectAndReturn(message.getJMSMessageID(), "foo");
messageControl.replay();
itemProvider.setItemType(Message.class);
assertEquals("foo", itemProvider.getKey(message));
messageControl.verify();
}
public void testGetKeyFromNonMessage() throws Exception {
itemProvider.setItemType(String.class);
assertEquals("foo", itemProvider.getKey("foo"));
}
public void testIsNewForMessage() throws Exception {
MockControl messageControl = MockControl.createControl(Message.class);
Message message = (Message) messageControl.getMock();
messageControl.expectAndReturn(message.getJMSRedelivered(), true);
messageControl.replay();
itemProvider.setItemType(Message.class);
assertEquals(true, itemProvider.hasFailed(message));
messageControl.verify();
}
public void testIsNewForNonMessage() throws Exception {
itemProvider.setItemType(String.class);
assertEquals(true, itemProvider.hasFailed("foo"));
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.item.provider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
public class ListItemProviderTests extends TestCase {
ListItemProvider provider = new ListItemProvider(Arrays.asList(new String[] { "a", "b", "c" }));
public void testNext() throws Exception {
assertEquals("a", provider.next());
assertEquals("b", provider.next());
assertEquals("c", provider.next());
assertEquals(null, provider.next());
}
public void testChangeList() throws Exception {
List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c" }));
provider = new ListItemProvider(list);
assertEquals("a", provider.next());
list.clear();
assertEquals(0, list.size());
assertEquals("b", provider.next());
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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.item.provider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
public class TransactionAwareListItemProviderTests extends TestCase {
// TransactionAwareListItemProvider provider = new
// TransactionAwareListItemProvider(Arrays.asList(new String[] { "a",
// "b", "c" }));
ListItemProvider provider;
protected void setUp() throws Exception {
super.setUp();
TransactionAwareProxyFactory factory = new TransactionAwareProxyFactory(Arrays.asList(new String[] { "a", "b",
"c" }));
provider = new ListItemProvider((List) factory.createInstance());
}
public void testNext() throws Exception {
assertEquals("a", provider.next());
assertEquals("b", provider.next());
assertEquals("c", provider.next());
assertEquals(null, provider.next());
}
public void testCommit() throws Exception {
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
final List taken = new ArrayList();
try {
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
taken.add(provider.next());
return null;
}
});
}
catch (RuntimeException e) {
fail("Unexpected RuntimeException");
assertEquals("Rollback!", e.getMessage());
}
assertEquals(1, taken.size());
assertEquals("a", taken.get(0));
taken.clear();
Object next = provider.next();
while (next != null) {
taken.add(next);
next = provider.next();
}
// System.err.println(taken);
assertFalse(taken.contains("a"));
}
public void testTransactionalExhausted() throws Exception {
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
final List taken = new ArrayList();
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Object next = provider.next();
while (next != null) {
taken.add(next);
next = provider.next();
}
return null;
}
});
assertEquals(3, taken.size());
assertEquals("a", taken.get(0));
}
public void testRollback() throws Exception {
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
final List taken = new ArrayList();
try {
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
taken.add(provider.next());
throw new RuntimeException("Rollback!");
}
});
fail("Expected RuntimeException");
}
catch (RuntimeException e) {
assertEquals("Rollback!", e.getMessage());
}
assertEquals(1, taken.size());
assertEquals("a", taken.get(0));
taken.clear();
Object next = provider.next();
while (next != null) {
taken.add(next);
next = provider.next();
}
System.err.println(taken);
assertTrue(taken.contains("a"));
}
}

View File

@@ -0,0 +1,114 @@
/*
* 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.item.provider;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.item.validator.Validator;
/**
* @author Lucas Ward
*
*/
public class ValidatingItemProviderTests extends TestCase {
InputSource inputSource;
ValidatingItemProvider itemProvider;
Validator validator;
MockControl validatorControl = MockControl.createControl(Validator.class);
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
inputSource = new MockInputSource(this);
validator = (Validator)validatorControl.getMock();
itemProvider = new ValidatingItemProvider();
itemProvider.setInputSource(inputSource);
itemProvider.setValidator(validator);
}
/*
* Super class' afterPropertieSet should be called to
* ensure InputSource is set.
*/
public void testInputSourcePropertiesSet(){
try{
itemProvider.setInputSource(null);
itemProvider.afterPropertiesSet();
fail();
}catch(Exception ex){
assertTrue(ex instanceof IllegalArgumentException);
}
}
public void testValidatorPropertesSet(){
try{
itemProvider.setValidator(null);
itemProvider.afterPropertiesSet();
fail();
}catch(Exception ex){
assertTrue(ex instanceof IllegalArgumentException);
}
}
public void testValidation(){
validator.validate(this);
validatorControl.replay();
assertEquals(itemProvider.next(), this);
validatorControl.verify();
}
public void testValidationException(){
validator.validate(this);
validatorControl.setThrowable(new ValidationException(""));
validatorControl.replay();
try{
itemProvider.next();
fail();
}catch(ValidationException ex){
//expected
}
}
public void testNullInput(){
validatorControl.replay();
itemProvider.setInputSource(new MockInputSource(null));
assertNull(itemProvider.next());
//assert validator wasn't called.
validatorControl.verify();
}
private static class MockInputSource implements InputSource{
Object value;
public MockInputSource(Object value){
this.value = value;
}
public Object read() {
return value;
}
}
}

View File

@@ -0,0 +1,150 @@
/*
* 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.item.validator;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.item.validator.SpringValidator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class SpringValidatorTests extends TestCase {
private SpringValidator validator = new SpringValidator();
private Validator mockValidator;
protected void setUp() throws Exception {
mockValidator = new MockSpringValidator();
validator.setValidator(mockValidator);
}
/**
* Validator property is not set
*/
public void testValidateNullValidator() {
validator.setValidator(null);
try {
validator.validate(MockSpringValidator.ACCEPT_VALUE);
fail("must not validate with null validator");
}
catch (ValidationException expected) {
assertTrue(true);
}
}
/**
* Validator does not know how to validate object of the given class
*/
public void testValidateUnsupportedType() {
try {
validator.validate(new Integer(1)); // only strings are supported
fail("must not validate unsupported classes");
}
catch (ValidationException expected) {
assertTrue(true);
}
}
/**
* Typical successful validation
*/
public void testValidateSuccessfully() {
try {
validator.validate(MockSpringValidator.ACCEPT_VALUE);
assertTrue(true);
}
catch (ValidationException unexpected) {
throw unexpected;
}
}
/**
* Typical failed validation
*/
public void testValidateFailure() {
try {
validator.validate(MockSpringValidator.REJECT_VALUE);
fail("exception should have been thrown on invalid value");
}
catch (ValidationException expected) {
assertTrue(true);
}
}
/**
* Typical failed validation
*/
public void testValidateFailureWithFields() {
try {
validator.validate(MockSpringValidator.REJECT_MULTI_VALUE);
fail("exception should have been thrown on invalid value");
}
catch (ValidationException expected) {
assertTrue("Wonrg message: "+expected.getMessage(), expected.getMessage().indexOf("foo, bar")>=0);
}
}
static class MockSpringValidator implements Validator {
public static final TestBean ACCEPT_VALUE = new TestBean();
public static final TestBean REJECT_VALUE = new TestBean();
public static final TestBean REJECT_MULTI_VALUE = new TestBean("foo", "bar");
public boolean supports(Class clazz) {
return clazz.isAssignableFrom(TestBean.class);
}
public void validate(Object value, Errors errors) {
if (value.equals(ACCEPT_VALUE)) {
return; // return without adding errors
}
if (value.equals(REJECT_VALUE)) {
errors.reject("bad.value");
return;
}
if (value.equals(REJECT_MULTI_VALUE)) {
errors.rejectValue("foo", "bad.value");
errors.rejectValue("bar", "bad.value");
return;
}
}
}
static class TestBean {
private String foo;
private String bar;
public String getFoo() {
return foo;
}
public String getBar() {
return bar;
}
public TestBean() {
super();
}
public TestBean(String foo, String bar) {
this();
this.foo = foo;
this.bar = bar;
}
}
}

View File

@@ -0,0 +1,141 @@
/*
* 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.repeat;
import org.apache.commons.lang.SerializationUtils;
import junit.framework.TestCase;
/**
* @author Dave Syer
*
*/
public class ExitStatusTests extends TestCase {
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#ExitStatus(boolean, int)}.
*/
public void testExitStatusBooleanInt() {
ExitStatus status = new ExitStatus(true, "10");
assertTrue(status.isContinuable());
assertEquals("10", status.getExitCode());
}
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#ExitStatus(boolean, int)}.
*/
public void testExitStatusConstantsContinuable() {
ExitStatus status = ExitStatus.CONTINUABLE;
assertTrue(status.isContinuable());
assertEquals("CONTINUABLE", status.getExitCode());
}
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#ExitStatus(boolean, int)}.
*/
public void testExitStatusConstantsFinished() {
ExitStatus status = ExitStatus.FINISHED;
assertFalse(status.isContinuable());
assertEquals("COMPLETED", status.getExitCode());
}
/**
* Test equality of exit statuses.
*
* @throws Exception
*/
public void testEqualsWithSameProperties() throws Exception {
assertEquals(ExitStatus.CONTINUABLE, new ExitStatus(true, "CONTINUABLE"));
}
/**
* Test equality of exit statuses.
*
* @throws Exception
*/
public void testEqualsWithNull() throws Exception {
assertFalse(ExitStatus.CONTINUABLE.equals(null));
}
/**
* Test equality of exit statuses.
*
* @throws Exception
*/
public void testHashcode() throws Exception {
assertEquals(ExitStatus.CONTINUABLE.toString().hashCode(), ExitStatus.CONTINUABLE.hashCode());
}
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#and(boolean)}.
*/
public void testAndBoolean() {
assertTrue(ExitStatus.CONTINUABLE.and(true).isContinuable());
assertFalse(ExitStatus.CONTINUABLE.and(false).isContinuable());
}
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#and(org.springframework.batch.repeat.ExitStatus)}.
*/
public void testAndExitStatus() {
assertTrue(ExitStatus.CONTINUABLE.and(ExitStatus.CONTINUABLE.isContinuable()).isContinuable());
assertFalse(ExitStatus.CONTINUABLE.and(ExitStatus.FINISHED.isContinuable()).isContinuable());
assertTrue(ExitStatus.FINISHED.and(ExitStatus.CONTINUABLE.isContinuable()).getExitCode()
== ExitStatus.FINISHED.getExitCode());
ExitStatus status = new ExitStatus(false, "CUSTOM_CODE", "CUSTOM_DESCRIPTION");
assertTrue(status.and(true).getExitCode() == "CUSTOM_CODE");
assertTrue(status.and(true).getExitDescription() == "CUSTOM_DESCRIPTION");
}
public void testAddExitCode() throws Exception {
ExitStatus status = ExitStatus.CONTINUABLE.addExitCode("FOO");
assertTrue(ExitStatus.CONTINUABLE!=status);
assertTrue(status.isContinuable());
assertEquals("FOO", status.getExitCode());
}
public void testAddExitDescription() throws Exception {
ExitStatus status = ExitStatus.CONTINUABLE.addExitDescription("Foo");
assertTrue(ExitStatus.CONTINUABLE!=status);
assertTrue(status.isContinuable());
assertEquals("Foo", status.getExitDescription());
}
public void testAddExitCodeWithDescription() throws Exception {
ExitStatus status = new ExitStatus(true, "BAR", "Bar").addExitCode("FOO");
assertEquals("FOO", status.getExitCode());
assertEquals("Bar", status.getExitDescription());
}
public void testRunningIsRunning() throws Exception {
assertTrue(ExitStatus.RUNNING.isRunning());
assertTrue(new ExitStatus(true, "RUNNING").isRunning());
}
public void testUnkownIsRunning() throws Exception {
assertTrue(ExitStatus.UNKNOWN.isRunning());
}
public void testSerializable() throws Exception {
ExitStatus status = ExitStatus.CONTINUABLE.addExitCode("FOO");
byte[] bytes = SerializationUtils.serialize(status);
Object object = SerializationUtils.deserialize(bytes);
assertTrue(object instanceof ExitStatus);
ExitStatus restored = (ExitStatus) object;
assertTrue(restored.isContinuable());
assertEquals("FOO", restored.getExitCode());
}
}

View File

@@ -0,0 +1,190 @@
/*
* 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.repeat.aop;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatOperations;
import org.springframework.batch.repeat.exception.RepeatException;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
import org.springframework.batch.repeat.support.RepeatTemplate;
public class RepeatOperationsInterceptorTests extends TestCase {
private RepeatOperationsInterceptor interceptor;
private Service service;
private ServiceImpl target;
protected void setUp() throws Exception {
super.setUp();
interceptor = new RepeatOperationsInterceptor();
target = new ServiceImpl();
ProxyFactory factory = new ProxyFactory(RepeatOperations.class
.getClassLoader());
factory.setInterfaces(new Class[] { Service.class });
factory.setTarget(target);
service = (Service) factory.getProxy();
}
public void testDefaultInterceptorSunnyDay() throws Exception {
((Advised) service).addAdvice(interceptor);
service.service();
assertEquals(3, target.count);
}
public void testSetTemplate() throws Exception {
final List calls = new ArrayList();
interceptor.setRepeatOperations(new RepeatOperations() {
public ExitStatus iterate(RepeatCallback callback) {
Object result = "1";
calls.add(result);
return ExitStatus.CONTINUABLE;
}
});
((Advised) service).addAdvice(interceptor);
service.service();
assertEquals(1, calls.size());
}
public void testVoidServiceSunnyDay() throws Exception {
((Advised) service).addAdvice(interceptor);
RepeatTemplate template = new RepeatTemplate();
// N.B. the default completion policy results in an infinite loop, so we
// need to set the chunk size.
template.setCompletionPolicy(new SimpleCompletionPolicy(2));
interceptor.setRepeatOperations(template);
service.alternate();
assertEquals(2, target.count);
}
public void testCallbackWithException() throws Exception {
((Advised) service).addAdvice(interceptor);
try {
service.exception();
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("Duh", e.getMessage().substring(0, 3));
}
}
public void testCallbackWithThrowable() throws Exception {
((Advised) service).addAdvice(interceptor);
try {
service.error();
fail("Expected BatchException");
} catch (RepeatException e) {
assertEquals("Unexpected", e.getMessage().substring(0, 10));
}
}
public void testInterceptorChainWithRetry() throws Exception {
((Advised) service).addAdvice(interceptor);
final List list = new ArrayList();
((Advised) service).addAdvice(new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
list.add("chain");
return invocation.proceed();
}
});
RepeatTemplate template = new RepeatTemplate();
template.setCompletionPolicy(new SimpleCompletionPolicy(2));
interceptor.setRepeatOperations(template);
service.service();
assertEquals(2, target.count);
assertEquals(2, list.size());
}
public void testIllegalMethodInvocationType() throws Throwable {
try {
interceptor.invoke(new MethodInvocation() {
public Method getMethod() {
return null;
}
public Object[] getArguments() {
return null;
}
public AccessibleObject getStaticPart() {
return null;
}
public Object getThis() {
return null;
}
public Object proceed() throws Throwable {
return null;
}
});
fail("IllegalStateException expected");
} catch (IllegalStateException e) {
assertTrue("Exception message should contain MethodInvocation: "
+ e.getMessage(), e.getMessage()
.indexOf("MethodInvocation") >= 0);
}
}
private interface Service {
Object service() throws Exception;
void alternate() throws Exception;
Object exception() throws Exception;
Object error() throws Exception;
}
private static class ServiceImpl implements Service {
private int count = 0;
public Object service() throws Exception {
count++;
if (count <= 2) {
return new Integer(count);
} else {
return null;
}
}
public void alternate() throws Exception {
count++;
}
public Object exception() throws Exception {
throw new RuntimeException("Duh! Stupid.");
}
public Object error() throws Exception {
throw new Error("Duh! Stupid.");
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* 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.repeat.callback;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.provider.ListItemProvider;
public class ItemProviderRepeatCallbackTests extends TestCase {
ItemProviderRepeatCallback callback;
List list = new ArrayList();
public void testDoWithRepeat() throws Exception {
callback = new ItemProviderRepeatCallback(new ListItemProvider(Arrays.asList(new String[] { "foo", "bar" })),
new ItemProcessor() {
public void process(Object data) {
list.add(data);
}
});
callback.doInIteration(null);
assertEquals(1, list.size());
assertEquals("foo", list.get(0));
}
public void testDoWithRepeatNullProcessor() throws Exception {
ListItemProvider provider = new ListItemProvider(Arrays.asList(new String[] { "foo", "bar" }));
callback = new ItemProviderRepeatCallback(provider);
callback.doInIteration(null);
assertEquals(0, list.size());
assertEquals("bar", provider.next());
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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.repeat.callback;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.support.RepeatTemplate;
public class NestedRepeatCallbackTests extends TestCase {
int count = 0;
public void testExecute() throws Exception {
NestedRepeatCallback callback = new NestedRepeatCallback(new RepeatTemplate(), new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return new ExitStatus(count <= 1);
}
});
ExitStatus result = callback.doInIteration(null);
assertEquals(2, count);
assertFalse(result.isContinuable()); // False because processing has finished
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.repeat.context;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.context.RepeatContextCounter;
import org.springframework.batch.repeat.context.RepeatContextSupport;
public class RepeatContextCounterTests extends TestCase {
RepeatContext parent = new RepeatContextSupport(null);
RepeatContext context = new RepeatContextSupport(parent);
public void testAttributeCreated() {
new RepeatContextCounter(context, "FOO");
assertTrue(context.hasAttribute("FOO"));
}
public void testAttributeCreatedWithNullParent() {
new RepeatContextCounter(parent, "FOO", true);
assertTrue(parent.hasAttribute("FOO"));
}
public void testVanillaIncrement() throws Exception {
RepeatContextCounter counter = new RepeatContextCounter(context, "FOO");
assertEquals(0, counter.getCount());
counter.increment(1);
assertEquals(1, counter.getCount());
counter.increment(2);
assertEquals(3, counter.getCount());
}
public void testAttributeCreatedInParent() throws Exception {
new RepeatContextCounter(context, "FOO", true);
assertFalse(context.hasAttribute("FOO"));
assertTrue(parent.hasAttribute("FOO"));
}
public void testParentIncrement() throws Exception {
RepeatContextCounter counter = new RepeatContextCounter(context, "FOO", true);
assertEquals(0, counter.getCount());
counter.increment(1);
// now get new context with same parent
counter = new RepeatContextCounter(new RepeatContextSupport(parent), "FOO", true);
assertEquals(1, counter.getCount());
counter.increment(2);
assertEquals(3, counter.getCount());
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.repeat.context;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
/**
* @author dsyer
*
*/
public class RepeatContextSupportTests extends TestCase {
private List list = new ArrayList();
/**
* Test method for {@link org.springframework.batch.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
*/
public void testDestructionCallbackSunnyDay() throws Exception {
RepeatContextSupport context = new RepeatContextSupport(null);
context.setAttribute("foo", "FOO");
context.registerDestructionCallback("foo", new Runnable() {
public void run() {
list.add("bar");
}
});
context.close();
assertEquals(1, list.size());
assertEquals("bar", list.get(0));
}
/**
* Test method for {@link org.springframework.batch.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
*/
public void testDestructionCallbackMissingAttribute() throws Exception {
RepeatContextSupport context = new RepeatContextSupport(null);
context.registerDestructionCallback("foo", new Runnable() {
public void run() {
list.add("bar");
}
});
context.close();
// No check for the attribute before executing callback
assertEquals(1, list.size());
}
/**
* Test method for {@link org.springframework.batch.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
*/
public void testDestructionCallbackWithException() throws Exception {
RepeatContextSupport context = new RepeatContextSupport(null);
context.setAttribute("foo", "FOO");
context.setAttribute("bar", "BAR");
context.registerDestructionCallback("bar", new Runnable() {
public void run() {
list.add("spam");
throw new RuntimeException("fail!");
}
});
context.registerDestructionCallback("foo", new Runnable() {
public void run() {
list.add("bar");
throw new RuntimeException("fail!");
}
});
try {
context.close();
fail("Expected RuntimeException");
} catch (RuntimeException e) {
// We don't care which one was thrown...
assertEquals("fail!", e.getMessage());
}
// ...but we do care that both were executed:
assertEquals(2, list.size());
assertTrue(list.contains("bar"));
assertTrue(list.contains("spam"));
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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.repeat.context;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.repeat.context.SynchronizedAttributeAccessor;
import org.springframework.core.AttributeAccessorSupport;
public class SynchronizedAttributeAccessorTests extends TestCase {
SynchronizedAttributeAccessor accessor = new SynchronizedAttributeAccessor();
public void testHashCode() {
SynchronizedAttributeAccessor another = new SynchronizedAttributeAccessor();
accessor.setAttribute("foo", "bar");
another.setAttribute("foo", "bar");
assertEquals(accessor.hashCode(), another.hashCode());
}
public void testToStringWithNoAttributes() throws Exception {
assertNotNull(accessor.toString());
}
public void testToStringWithAttributes() throws Exception {
accessor.setAttribute("foo", "bar");
accessor.setAttribute("spam", "bucket");
assertNotNull(accessor.toString());
}
public void testAttributeNames() {
accessor.setAttribute("foo", "bar");
accessor.setAttribute("spam", "bucket");
List list = Arrays.asList(accessor.attributeNames());
assertEquals(2, list.size());
assertTrue(list.contains("foo"));
}
public void testEqualsSameType() {
SynchronizedAttributeAccessor another = new SynchronizedAttributeAccessor();
accessor.setAttribute("foo", "bar");
another.setAttribute("foo", "bar");
assertEquals(accessor, another);
}
public void testEqualsSelf() {
accessor.setAttribute("foo", "bar");
assertEquals(accessor, accessor);
}
public void testEqualsWrongType() {
accessor.setAttribute("foo", "bar");
Map another = Collections.singletonMap("foo", "bar");
//TODO accessor and another are instances of unrelated classes, they can never be equal
assertFalse(accessor.equals(another));
}
public void testEqualsSupport() {
AttributeAccessorSupport another = new AttributeAccessorSupport() {
};
accessor.setAttribute("foo", "bar");
another.setAttribute("foo", "bar");
assertEquals(accessor, another);
}
public void testGetAttribute() {
accessor.setAttribute("foo", "bar");
assertEquals("bar", accessor.getAttribute("foo"));
}
public void testSetAttributeIfAbsentWhenAlreadyPresent() {
accessor.setAttribute("foo", "bar");
assertEquals("bar", accessor.setAttributeIfAbsent("foo", "spam"));
}
public void testSetAttributeIfAbsentWhenNotAlreadyPresent() {
assertEquals(null, accessor.setAttributeIfAbsent("foo", "bar"));
assertEquals("bar", accessor.getAttribute("foo"));
}
public void testHasAttribute() {
accessor.setAttribute("foo", "bar");
assertEquals(true, accessor.hasAttribute("foo"));
}
public void testRemoveAttribute() {
accessor.setAttribute("foo", "bar");
assertEquals("bar", accessor.getAttribute("foo"));
accessor.removeAttribute("foo");
assertEquals(null, accessor.getAttribute("foo"));
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.repeat.exception;
import junit.framework.TestCase;
public abstract class AbstractExceptionTests extends TestCase {
public void testExceptionString() throws Exception {
Exception exception = getException("foo");
assertEquals("foo", exception.getMessage());
}
public void testExceptionStringThrowable() throws Exception {
Exception exception = getException("foo", new IllegalStateException());
assertEquals("foo", exception.getMessage().substring(0, 3));
}
public abstract Exception getException(String msg) throws Exception;
public abstract Exception getException(String msg, Throwable t) throws Exception;
}

View File

@@ -0,0 +1,32 @@
/*
* 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.repeat.exception;
public class RepeatExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new RepeatException(msg);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new RepeatException(msg, t);
}
public void testNothing() throws Exception {
// fool coverage tools...
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.repeat.exception.handler;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
public class CompositeExceptionHandlerTests extends TestCase {
private CompositeExceptionHandler handler = new CompositeExceptionHandler();
public void testNewHandler() throws Exception {
try {
handler.handleException(null, new RuntimeException());
}
catch (RuntimeException e) {
fail("Unexpected RuntimeException");
}
}
public void testDelegation() throws Exception {
final List list = new ArrayList();
handler.setHandlers(new ExceptionHandler[] {
new ExceptionHandler() {
public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
list.add("1");
}
},
new ExceptionHandler() {
public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
list.add("2");
}
}
});
handler.handleException(null, new RuntimeException());
assertEquals(2, list.size());
assertEquals("1", list.get(0));
assertEquals("2", list.get(1));
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.repeat.exception.handler;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.exception.RepeatException;
public class DefaultExceptionHandlerTests extends TestCase {
private DefaultExceptionHandler handler = new DefaultExceptionHandler();
private RepeatContext context = null;
public void testRuntimeException() throws Exception {
try {
handler.handleException(context, new RuntimeException("Foo"));
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("Foo", e.getMessage());
}
}
public void testError() throws Exception {
try {
handler.handleException(context, new Error("Foo"));
fail("Expected BatchException");
} catch (RepeatException e) {
assertEquals("Foo", e.getCause().getMessage());
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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.repeat.exception.handler;
import java.io.StringWriter;
import junit.framework.TestCase;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.WriterAppender;
import org.springframework.batch.common.ExceptionClassifierSupport;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.exception.RepeatException;
public class LogOrRethrowExceptionHandlerTests extends TestCase {
private LogOrRethrowExceptionHandler handler = new LogOrRethrowExceptionHandler();
private StringWriter writer;
private RepeatContext context = null;
protected void setUp() throws Exception {
super.setUp();
Logger logger = Logger.getLogger(LogOrRethrowExceptionHandler.class);
logger.setLevel(Level.DEBUG);
writer = new StringWriter();
logger.removeAllAppenders();
logger.getParent().removeAllAppenders();
logger.addAppender(new WriterAppender(new SimpleLayout(), writer));
}
public void testRuntimeException() throws Exception {
try {
handler.handleException(context, new RuntimeException("Foo"));
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("Foo", e.getMessage());
}
}
public void testError() throws Exception {
try {
handler.handleException(context, new Error("Foo"));
fail("Expected BatchException");
} catch (RepeatException e) {
assertEquals("Foo", e.getCause().getMessage());
}
}
public void testNotRethrownErrorLevel() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return LogOrRethrowExceptionHandler.ERROR;
}
});
// No exception...
handler.handleException(context, new Error("Foo"));
assertNotNull(writer.toString());
}
public void testNotRethrownWarnLevel() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return LogOrRethrowExceptionHandler.WARN;
}
});
// No exception...
handler.handleException(context, new Error("Foo"));
assertNotNull(writer.toString());
}
public void testNotRethrownDebugLevel() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return LogOrRethrowExceptionHandler.DEBUG;
}
});
// No exception...
handler.handleException(context, new Error("Foo"));
assertNotNull(writer.toString());
}
public void testUnclassifiedException() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return "DEFAULT";
}
});
try {
handler.handleException(context, new Error("Foo"));
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
assertTrue(e.getMessage().toLowerCase().indexOf("unclassified")>=0);
assertEquals("Foo", e.getCause().getMessage());
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* 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.repeat.exception.handler;
import java.util.Collections;
import junit.framework.TestCase;
import org.springframework.batch.common.ExceptionClassifierSupport;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.context.RepeatContextCounter;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.batch.repeat.exception.RepeatException;
public class RethrowOnThresholdExceptionHandlerTests extends TestCase {
private RethrowOnThresholdExceptionHandler handler = new RethrowOnThresholdExceptionHandler();
private RepeatContext parent = new RepeatContextSupport(null);
private RepeatContext context = new RepeatContextSupport(parent);
public void testRuntimeException() throws Exception {
try {
handler.handleException(context, new RuntimeException("Foo"));
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertEquals("Foo", e.getMessage());
}
}
public void testError() throws Exception {
try {
handler.handleException(context, new Error("Foo"));
fail("Expected BatchException");
} catch (RepeatException e) {
assertEquals("Foo", e.getCause().getMessage());
}
}
public void testNotRethrownWithThreshold() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return "RuntimeException";
}
});
handler.setThresholds(Collections.singletonMap("RuntimeException", new Integer(1)));
// No exception...
handler.handleException(context, new RuntimeException("Foo"));
RepeatContextCounter counter = new RepeatContextCounter(context, RethrowOnThresholdExceptionHandler.class.getName() + ".RuntimeException");
assertNotNull(counter);
assertEquals(1, counter.getCount());
}
public void testRethrowOnThreshold() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return "RuntimeException";
}
});
handler.setThresholds(Collections.singletonMap("RuntimeException", new Integer(1)));
// No exception...
handler.handleException(context, new RuntimeException("Foo"));
try {
handler.handleException(context, new RuntimeException("Foo"));
fail("Expected RuntimeException");
}
catch (RuntimeException e) {
assertEquals("Foo", e.getMessage());
}
}
public void testNonIntegerAsThreshold() throws Exception {
try {
handler.setThresholds(Collections.singletonMap("RuntimeException", new Long(1)));
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
}
public void testNotUseParent() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return "RuntimeException";
}
});
handler.setThresholds(Collections.singletonMap("RuntimeException", new Integer(1)));
// No exception...
handler.handleException(context, new RuntimeException("Foo"));
context = new RepeatContextSupport(parent);
try {
// No exception again - context is changed...
handler.handleException(context, new RuntimeException("Foo"));
}
catch (RuntimeException e) {
fail("Unexpected Error");
}
}
public void testUseParent() throws Exception {
handler.setExceptionClassifier(new ExceptionClassifierSupport() {
public Object classify(Throwable throwable) {
return "RuntimeException";
}
});
handler.setThresholds(Collections.singletonMap("RuntimeException", new Integer(1)));
handler.setUseParent(true);
// No exception...
handler.handleException(context, new RuntimeException("Foo"));
context = new RepeatContextSupport(parent);
try {
handler.handleException(context, new RuntimeException("Foo"));
fail("Expected Error");
}
catch (RuntimeException e) {
assertEquals("Foo", e.getMessage());
}
}
public void testNotStringAsKey() throws Exception {
try {
handler.setThresholds(Collections.singletonMap(RuntimeException.class, new Integer(1)));
// It's not an error, but not advised...
}
catch (RuntimeException e) {
throw e;
}
}
}

View File

@@ -0,0 +1,229 @@
/*
* 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.repeat.exception.handler;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.TransactionInvalidException;
import org.springframework.batch.repeat.context.RepeatContextSupport;
/**
* Unit tests for {@link SimpleLimitExceptionHandler}
*
* @author Robert Kasanicky
* @author Dave Syer
*/
public class SimpleLimitExceptionHandlerTests extends TestCase {
// object under test
private SimpleLimitExceptionHandler handler = new SimpleLimitExceptionHandler();
public void testInitializeWithNullContext() throws Exception {
try {
handler.handleException(null, new RuntimeException("foo"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
public void testInitializeWithNullContextAndNullException()
throws Exception {
try {
handler.handleException(null, null);
} catch (NullPointerException e) {
// expected;
}
}
/**
* Other than TransactionInvalidException should be rethrown, ignoring the
* exception limit.
*
* @throws Exception
*/
public void testNormalExceptionThrown() throws Exception {
Throwable throwable = new RuntimeException("foo");
final int MORE_THAN_ZERO = 1;
handler.setLimit(MORE_THAN_ZERO);
try {
handler.handleException(new RepeatContextSupport(null), throwable);
fail("Exception swallowed.");
} catch (RuntimeException expected) {
assertTrue("Exception is rethrown, ignoring the exception limit",
true);
assertSame(expected, throwable);
}
}
/**
* TransactionInvalidException should only be rethrown below the exception
* limit.
*
* @throws Exception
*/
public void testLimitedExceptionTypeNotThrown() throws Exception {
final int MORE_THAN_ZERO = 1;
handler.setLimit(MORE_THAN_ZERO);
handler.setType(RuntimeException.class);
try {
handler.handleException(new RepeatContextSupport(null),
new RuntimeException("foo"));
} catch (RuntimeException expected) {
fail("Unexpected exception.");
}
}
/**
* TransactionInvalidException should only be rethrown below the exception
* limit.
*
* @throws Exception
*/
public void testLimitedExceptionNotThrownFromSiblings() throws Exception {
Throwable throwable = new RuntimeException("foo");
final int MORE_THAN_ZERO = 1;
handler.setLimit(MORE_THAN_ZERO);
handler.setType(RuntimeException.class);
RepeatContextSupport parent = new RepeatContextSupport(null);
try {
RepeatContextSupport context = new RepeatContextSupport(parent);
handler.handleException(context, throwable);
context = new RepeatContextSupport(parent);
handler.handleException(context, throwable);
} catch (RuntimeException expected) {
fail("Unexpected exception.");
}
}
/**
* TransactionInvalidException should only be rethrown below the exception
* limit.
*
* @throws Exception
*/
public void testLimitedExceptionThrownFromSiblingsWhenUsingParent()
throws Exception {
Throwable throwable = new RuntimeException("foo");
final int MORE_THAN_ZERO = 1;
handler.setLimit(MORE_THAN_ZERO);
handler.setType(RuntimeException.class);
handler.setUseParent(true);
RepeatContextSupport parent = new RepeatContextSupport(null);
try {
RepeatContextSupport context = new RepeatContextSupport(parent);
handler.handleException(context, throwable);
context = new RepeatContextSupport(parent);
handler.handleException(context, throwable);
fail("Expected exception.");
} catch (RuntimeException expected) {
assertSame(throwable, expected);
}
}
/**
* TransactionInvalidExceptions are swallowed until the exception limit is
* exceeded. After the limit is exceeded exceptions are rethrown as
* BatchCriticalExceptions
*/
public void testExceptionNotThrownBelowLimit() throws Exception {
final int EXCEPTION_LIMIT = 3;
handler.setLimit(EXCEPTION_LIMIT);
List throwables = new ArrayList() {
{
for (int i = 0; i < (EXCEPTION_LIMIT); i++) {
add(new TransactionInvalidException("below exception limit"));
}
}
};
RepeatContextSupport context = new RepeatContextSupport(null);
try {
for (Iterator iterator = throwables.iterator(); iterator.hasNext();) {
Throwable throwable = (Throwable) iterator.next();
handler.handleException(context, throwable);
assertTrue("exceptions up to limit are swallowed", true);
}
} catch (RuntimeException unexpected) {
fail("exception rethrown although exception limit was not exceeded");
}
}
/**
* TransactionInvalidExceptions are swallowed until the exception limit is
* exceeded. After the limit is exceeded exceptions are rethrown as
* BatchCriticalExceptions
*/
public void testExceptionThrownAboveLimit() throws Exception {
final int EXCEPTION_LIMIT = 3;
handler.setLimit(EXCEPTION_LIMIT);
List throwables = new ArrayList() {
{
for (int i = 0; i < (EXCEPTION_LIMIT); i++) {
add(new TransactionInvalidException("below exception limit"));
}
}
};
throwables
.add(new TransactionInvalidException("above exception limit"));
RepeatContextSupport context = new RepeatContextSupport(null);
try {
for (Iterator iterator = throwables.iterator(); iterator.hasNext();) {
Throwable throwable = (Throwable) iterator.next();
handler.handleException(context, throwable);
assertTrue("exceptions up to limit are swallowed", true);
}
} catch (TransactionInvalidException expected) {
assertEquals("above exception limit", expected.getMessage());
}
// after reaching the limit, behaviour should be idempotent
try {
handler.handleException(context, new RuntimeException("foo"));
assertTrue("exceptions up to limit are swallowed", true);
} catch (RuntimeException expected) {
assertEquals("foo", expected.getMessage());
}
}
}

View File

@@ -0,0 +1,108 @@
/*
* 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.repeat.interceptor;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import junit.framework.TestCase;
/**
* @author Dave Syer
*
*/
public class ApplicationEventPublisherRepeatInterceptorTests extends TestCase {
private ApplicationEventPublisherRepeatInterceptor interceptor = new ApplicationEventPublisherRepeatInterceptor();
private List list = new ArrayList();
private RepeatContext context = new RepeatContextSupport(null);
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
interceptor.setApplicationEventPublisher(new ApplicationEventPublisher() {
public void publishEvent(ApplicationEvent event) {
list.add(event);
}
});
}
/**
* Test method for {@link org.springframework.batch.repeat.interceptor.ApplicationEventPublisherRepeatInterceptor#after(org.springframework.batch.repeat.RepeatContext, ExitStatus)}.
*/
public void testAfter() {
interceptor.after(context, ExitStatus.CONTINUABLE);
assertEquals(1, list.size());
RepeatOperationsApplicationEvent event = (RepeatOperationsApplicationEvent) list.get(0);
assertEquals(RepeatOperationsApplicationEvent.AFTER, event.getType());
assertTrue(event.getMessage().toLowerCase().indexOf("after")>=0);
}
/**
* Test method for {@link org.springframework.batch.repeat.interceptor.ApplicationEventPublisherRepeatInterceptor#before(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testBefore() {
interceptor.before(context);
assertEquals(1, list.size());
RepeatOperationsApplicationEvent event = (RepeatOperationsApplicationEvent) list.get(0);
assertEquals(RepeatOperationsApplicationEvent.BEFORE, event.getType());
assertTrue(event.getMessage().toLowerCase().indexOf("before")>=0);
}
/**
* Test method for {@link org.springframework.batch.repeat.interceptor.ApplicationEventPublisherRepeatInterceptor#close(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testClose() {
interceptor.close(context);
assertEquals(1, list.size());
RepeatOperationsApplicationEvent event = (RepeatOperationsApplicationEvent) list.get(0);
assertEquals(RepeatOperationsApplicationEvent.CLOSE, event.getType());
assertTrue(event.getMessage().toLowerCase().indexOf("close")>=0);
}
/**
* Test method for {@link org.springframework.batch.repeat.interceptor.ApplicationEventPublisherRepeatInterceptor#onError(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)}.
*/
public void testOnError() {
interceptor.onError(context, new RuntimeException("foo"));
assertEquals(1, list.size());
RepeatOperationsApplicationEvent event = (RepeatOperationsApplicationEvent) list.get(0);
assertEquals(RepeatOperationsApplicationEvent.ERROR, event.getType());
assertTrue(event.getMessage().toLowerCase().indexOf("foo")>=0);
}
/**
* Test method for {@link org.springframework.batch.repeat.interceptor.ApplicationEventPublisherRepeatInterceptor#open(org.springframework.batch.repeat.RepeatContext)}.
*/
public void testOpen() {
interceptor.open(context);
assertEquals(1, list.size());
RepeatOperationsApplicationEvent event = (RepeatOperationsApplicationEvent) list.get(0);
assertEquals(RepeatOperationsApplicationEvent.OPEN, event.getType());
assertTrue(event.getMessage().toLowerCase().indexOf("open")>=0);
}
}

View File

@@ -0,0 +1,263 @@
/*
* 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.repeat.interceptor;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatInterceptor;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
public class RepeatInterceptorTests extends TestCase {
int count = 0;
public void testBeforeInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void before(RepeatContext context) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void before(RepeatContext context) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return new ExitStatus(count <= 1);
}
});
// 2 calls: the second time there is no processing
// (despite the fact that the callback returned null and batch was
// complete). Is this OK?
assertEquals(2, count);
// ... but the interceptor before() was called:
assertEquals("[1, 2, 1, 2]", calls.toString());
}
public void testBeforeInterceptorCanVeto() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptor(new RepeatInterceptorAdapter() {
public void before(RepeatContext context) {
calls.add("1");
context.setCompleteOnly();
}
});
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return ExitStatus.FINISHED;
}
});
assertEquals(0, count);
// ... but the interceptor before() was called:
assertEquals("[1]", calls.toString());
}
public void testAfterInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void after(RepeatContext context, ExitStatus result) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void after(RepeatContext context, ExitStatus result) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return new ExitStatus(count <= 1);
}
});
// 2 calls to the callback, and the second one had no processing...
assertEquals(2, count);
// ... so the interceptor after() is not called:
assertEquals("[2, 1]", calls.toString());
}
public void testOpenInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void open(RepeatContext context) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void open(RepeatContext context) {
calls.add("2");
context.setCompleteOnly();
}
} });
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return ExitStatus.CONTINUABLE;
}
});
assertEquals(0, count);
assertEquals("[1, 2]", calls.toString());
}
public void testSingleOpenInterceptor() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptor(new RepeatInterceptorAdapter() {
public void open(RepeatContext context) {
calls.add("1");
}
});
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
context.setCompleteOnly();
return ExitStatus.FINISHED;
}
});
assertEquals(1, count);
assertEquals("[1]", calls.toString());
}
public void testCloseInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void close(RepeatContext context) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void close(RepeatContext context) {
calls.add("2");
}
} });
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
count++;
return new ExitStatus(count < 2);
}
});
// Test that more than one call comes in to the callback...
assertEquals(2, count);
// ... but the interceptor is only called once.
assertEquals("[2, 1]", calls.toString());
}
public void testOnErrorInterceptors() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void onError(RepeatContext context, Throwable t) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
assertEquals(0, count);
assertEquals("[2, 1]", calls.toString());
}
public void testOnErrorInterceptorsPrecedence() throws Exception {
RepeatTemplate template = new RepeatTemplate();
final List calls = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void after(RepeatContext context, ExitStatus result) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
}
assertEquals(0, count);
// The after is not executed, if there is an error...
assertEquals("[2]", calls.toString());
}
public void testAsynchronousOnErrorInterceptorsPrecedence() throws Exception {
TaskExecutorRepeatTemplate template = new TaskExecutorRepeatTemplate();
template.setTaskExecutor(new SimpleAsyncTaskExecutor());
final List calls = new ArrayList();
final List fails = new ArrayList();
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
public void after(RepeatContext context, ExitStatus result) {
calls.add("1");
}
}, new RepeatInterceptorAdapter() {
public void onError(RepeatContext context, Throwable t) {
calls.add("2");
fails.add("2");
}
} });
try {
template.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
throw new IllegalStateException("Bogus");
}
});
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
// expected
assertEquals("Bogus", e.getMessage());
}
assertEquals(0, count);
System.err.println(calls);
// The after is not executed on error...
assertEquals("2", calls.get(0));
assertEquals("2", calls.get(calls.size()-1));
assertFalse(calls.contains("1"));
assertEquals(fails.size(), calls.size());
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.repeat.policy;
import junit.framework.TestCase;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.CompletionPolicy;
public class CompositeCompletionPolicyTests extends TestCase {
public void testEmptyPolicies() throws Exception {
CompositeCompletionPolicy policy = new CompositeCompletionPolicy();
RepeatContext context = policy.start(null);
assertNotNull(context);
assertFalse(policy.isComplete(context));
}
public void testTrivialPolicies() throws Exception {
CompositeCompletionPolicy policy = new CompositeCompletionPolicy();
policy.setPolicies(new CompletionPolicy[] { new MockCompletionPolicySupport(),
new MockCompletionPolicySupport() });
RepeatContext context = policy.start(null);
assertEquals(0, context.getStartedCount());
assertFalse(policy.isComplete(context));
assertFalse(policy.isComplete(context, null));
policy.update(context);
assertEquals(1, context.getStartedCount());
}
public void testNonTrivialPolicies() throws Exception {
CompositeCompletionPolicy policy = new CompositeCompletionPolicy();
policy.setPolicies(new CompletionPolicy[] { new MockCompletionPolicySupport(),
new MockCompletionPolicySupport() {
public boolean isComplete(RepeatContext context) {
return true;
}
} });
RepeatContext context = policy.start(null);
assertTrue(policy.isComplete(context));
}
public void testNonTrivialPoliciesWithResult() throws Exception {
CompositeCompletionPolicy policy = new CompositeCompletionPolicy();
policy.setPolicies(new CompletionPolicy[] { new MockCompletionPolicySupport(),
new MockCompletionPolicySupport() {
public boolean isComplete(RepeatContext context, ExitStatus result) {
return true;
}
} });
RepeatContext context = policy.start(null);
assertTrue(policy.isComplete(context, null));
}
}

Some files were not shown because too many files have changed in this diff Show More