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:
@@ -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")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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...
|
||||
}
|
||||
}
|
||||
@@ -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...
|
||||
}
|
||||
}
|
||||
@@ -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...
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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...
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user