IN PROGRESS - issue BATCH-412: consistent ItemStream key prefixes

http://jira.springframework.org/browse/BATCH-412

added ExecutionContextUserSupport class as superclass for those who need to save data into ExecutionContext - removes the tons of copy-pastes used to handle naming and unique key generation
This commit is contained in:
robokaso
2008-03-05 10:28:48 +00:00
parent fcb5da0831
commit 2aa867c535
15 changed files with 199 additions and 128 deletions

View File

@@ -24,12 +24,11 @@ import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.reader.AbstractItemStreamItemReader;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -50,13 +49,11 @@ import org.springframework.util.StringUtils;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class HibernateCursorItemReader extends AbstractItemStreamItemReader implements Skippable, InitializingBean {
public class HibernateCursorItemReader extends ExecutionContextUserSupport implements ItemReader, ItemStream, Skippable, InitializingBean {
private static final String RESTART_DATA_ROW_NUMBER_KEY = ClassUtils.getShortName(HibernateCursorItemReader.class)
+ ".rowNumber";
private static final String RESTART_DATA_ROW_NUMBER_KEY = "rowNumber";
private static final String SKIPPED_ROWS = ClassUtils.getShortName(HibernateCursorItemReader.class)
+ ".skippedRows";
private static final String SKIPPED_ROWS = "skippedRows";
private SessionFactory sessionFactory;
@@ -81,9 +78,12 @@ public class HibernateCursorItemReader extends AbstractItemStreamItemReader impl
private boolean initialized = false;
private String name = HibernateCursorItemReader.class.getName();
private boolean saveState = false;
public HibernateCursorItemReader() {
setName(HibernateCursorItemReader.class.getSimpleName());
}
public Object read() {
if (!initialized) {
@@ -235,10 +235,6 @@ public class HibernateCursorItemReader extends AbstractItemStreamItemReader impl
cursor.setRowNumber(lastCommitRowNumber - 1);
}
}
private String getKey(String key){
return name + "." + key;
}
public void setSaveState(boolean saveState) {
this.saveState = saveState;

View File

@@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.ResetFailedException;
@@ -102,17 +103,17 @@ import org.springframework.util.StringUtils;
* @author Lucas Ward
* @author Peter Zozom
*/
public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemStream, Skippable {
public class JdbcCursorItemReader extends ExecutionContextUserSupport implements ItemReader, InitializingBean, ItemStream, Skippable {
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);
public static final int VALUE_NOT_SET = -1;
private static final String CURRENT_PROCESSED_ROW = "sqlCursorInput.lastProcessedRowNum";
private static final String CURRENT_PROCESSED_ROW = "lastProcessedRowNum";
private static final String SKIPPED_ROWS = "sqlCursorInput.skippedRows";
private static final String SKIPPED_ROWS = "skippedRows";
private static final String SKIP_COUNT = "sqlCursorInput.skippedRrecordCount";
private static final String SKIP_COUNT = "skippedRrecordCount";
private Connection con;
@@ -150,8 +151,10 @@ public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemS
private boolean initialized = false;
private boolean saveState = false;
private String name = JdbcCursorItemReader.class.getName();
public JdbcCursorItemReader() {
setName(JdbcCursorItemReader.class.getSimpleName());
}
/**
* Assert that mandatory properties are set.
@@ -381,9 +384,9 @@ public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemS
if (saveState) {
Assert.notNull(executionContext, "ExecutionContext must not be null");
String skipped = skippedRows.toString();
executionContext.putString(addName(SKIPPED_ROWS), skipped.substring(1, skipped.length() - 1));
executionContext.putLong(addName(CURRENT_PROCESSED_ROW), currentProcessedRow);
executionContext.putLong(addName(SKIP_COUNT), skipCount);
executionContext.putString(getKey(SKIPPED_ROWS), skipped.substring(1, skipped.length() - 1));
executionContext.putLong(getKey(CURRENT_PROCESSED_ROW), currentProcessedRow);
executionContext.putLong(getKey(SKIP_COUNT), skipCount);
}
}
@@ -399,23 +402,23 @@ public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemS
initialized = true;
// Properties restartProperties = data.getProperties();
if (!context.containsKey(addName(CURRENT_PROCESSED_ROW))) {
if (!context.containsKey(getKey(CURRENT_PROCESSED_ROW))) {
return;
}
try {
this.currentProcessedRow = context.getLong(addName(CURRENT_PROCESSED_ROW));
this.currentProcessedRow = context.getLong(getKey(CURRENT_PROCESSED_ROW));
rs.absolute((int) currentProcessedRow);
}
catch (SQLException se) {
throw getExceptionTranslator().translate("Attempted to move ResultSet to last committed row", sql, se);
}
if (!context.containsKey(addName(SKIPPED_ROWS))) {
if (!context.containsKey(getKey(SKIPPED_ROWS))) {
return;
}
String[] skipped = StringUtils.commaDelimitedListToStringArray(context.getString(addName(SKIPPED_ROWS)));
String[] skipped = StringUtils.commaDelimitedListToStringArray(context.getString(getKey(SKIPPED_ROWS)));
for (int i = 0; i < skipped.length; i++) {
this.skippedRows.add(new Long(skipped[i]));
}
@@ -510,14 +513,6 @@ public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemS
this.sql = sql;
}
public void setName(String name) {
this.name = name;
}
public String addName(String key) {
return name + "." + key;
}
public void setSaveState(boolean saveState) {
this.saveState = saveState;
}

View File

@@ -5,48 +5,52 @@ import java.util.List;
import org.springframework.batch.io.driving.DrivingQueryItemReader;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.util.Assert;
import com.ibatis.sqlmap.client.SqlMapClient;
/**
* {@link KeyGenerator} based on iBATIS ORM framework. It is functionally similar to
* {@link SingleColumnJdbcKeyGenerator} but does not make assumptions about the primary key
* structure.
*
* {@link KeyGenerator} based on iBATIS ORM framework. It is functionally
* similar to {@link SingleColumnJdbcKeyGenerator} but does not make assumptions
* about the primary key structure.
*
* @author Robert Kasanicky
* @author Lucas Ward
* @see DrivingQueryItemReader
*/
public class IbatisKeyGenerator implements KeyGenerator {
public class IbatisKeyGenerator extends ExecutionContextUserSupport implements KeyGenerator {
public static final String RESTART_KEY = "IbatisDrivingQueryItemReader.keyIndex";
public static final String RESTART_KEY = "keyIndex";
private SqlMapClientTemplate sqlMapClientTemplate;
private String drivingQuery;
private String restartQueryId;
private String name = IbatisKeyGenerator.class.getName();
public IbatisKeyGenerator() {
setName(IbatisKeyGenerator.class.getSimpleName());
}
/*
* Retrieve the keys using the provided driving query id.
*
*
* @see org.springframework.batch.io.support.AbstractDrivingQueryItemReader#retrieveKeys()
*/
public List retrieveKeys(ExecutionContext executionContext) {
if(executionContext.containsKey(getKey(RESTART_KEY))){
if (executionContext.containsKey(getKey(RESTART_KEY))) {
Object key = executionContext.getString(getKey(RESTART_KEY));
return sqlMapClientTemplate.queryForList(restartQueryId, key);
}
else{
else {
return sqlMapClientTemplate.queryForList(drivingQuery);
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.io.driving.KeyGenerator#getKeyAsExecutionContext(java.lang.Object)
*/
public void saveState(Object key, ExecutionContext executionContext) {
@@ -55,7 +59,8 @@ public class IbatisKeyGenerator implements KeyGenerator {
executionContext.putString(getKey(RESTART_KEY), key.toString());
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
@@ -81,7 +86,7 @@ public class IbatisKeyGenerator implements KeyGenerator {
/**
* Set the id of the restart query.
*
*
* @param restartQueryId id of the iBatis select statement that will be used
* to retrieve the list of primary keys after a restart.
*/
@@ -90,14 +95,7 @@ public class IbatisKeyGenerator implements KeyGenerator {
}
public final SqlMapClientTemplate getSqlMapClientTemplate() {
return sqlMapClientTemplate;
}
public void setName(String name) {
this.name = name;
}
private String getKey(String key){
return name + "." + key;
return sqlMapClientTemplate;
}
}

View File

@@ -20,25 +20,26 @@ import java.util.List;
import org.springframework.batch.io.driving.DrivingQueryItemReader;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* <p>Jdbc implementation of the {@link KeyGenerator} interface that works for composite keys.
* (i.e. keys represented by multiple columns) A sql query to be used to return the keys and
* a {@link ExecutionContextRowMapper} to map each row in the resultset to an Object must be set in
* order to work correctly.
* <p>
* Jdbc implementation of the {@link KeyGenerator} interface that works for
* composite keys. (i.e. keys represented by multiple columns) A sql query to be
* used to return the keys and a {@link ExecutionContextRowMapper} to map each
* row in the resultset to an Object must be set in order to work correctly.
* </p>
*
*
* @author Lucas Ward
* @see DrivingQueryItemReader
* @since 1.0
*/
public class MultipleColumnJdbcKeyGenerator implements
KeyGenerator {
public class MultipleColumnJdbcKeyGenerator extends ExecutionContextUserSupport implements KeyGenerator {
public static final String RESTART_KEY = "CompositeKeySqlDrivingQueryItemReader.key";
public static final String RESTART_KEY = "key";
private JdbcTemplate jdbcTemplate;
@@ -47,20 +48,20 @@ public class MultipleColumnJdbcKeyGenerator implements
private String sql;
private String restartSql;
public MultipleColumnJdbcKeyGenerator() {
super();
setName(MultipleColumnJdbcKeyGenerator.class.getSimpleName());
}
/**
* Construct a new ItemReader.
*
*
* @param jdbcTemplate
* @param sql - Sql statement that returns all keys to process.
* @param keyMapper - RowMapper that maps each row of the ResultSet to an object.
* @param keyMapper - RowMapper that maps each row of the ResultSet to an
* object.
*/
public MultipleColumnJdbcKeyGenerator(JdbcTemplate jdbcTemplate,
String sql){
public MultipleColumnJdbcKeyGenerator(JdbcTemplate jdbcTemplate, String sql) {
this();
Assert.notNull(jdbcTemplate, "The JdbcTemplate must not be null.");
Assert.hasText(sql, "The DrivingQuery must not be null or empty.");
@@ -69,24 +70,26 @@ public class MultipleColumnJdbcKeyGenerator implements
this.sql = sql;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.io.sql.scratch.AbstractDrivingQueryItemReader#retrieveKeys()
*/
public List retrieveKeys(ExecutionContext executionContext) {
Assert.state(keyMapper != null, "KeyMapper must not be null.");
Assert.state(StringUtils.hasText(restartSql), "The RestartQuery must not be null or empty" +
" in order to restart.");
Assert.state(StringUtils.hasText(restartSql), "The RestartQuery must not be null or empty"
+ " in order to restart.");
if (executionContext.size() > 0) {
return jdbcTemplate.query(restartSql, keyMapper.createSetter(executionContext), keyMapper);
}
else{
else {
return jdbcTemplate.query(sql, keyMapper);
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.io.driving.KeyGenerator#getKeyAsExecutionContext(java.lang.Object)
*/
public void saveState(Object key, ExecutionContext executionContext) {
@@ -97,14 +100,15 @@ public class MultipleColumnJdbcKeyGenerator implements
/**
* Set the query to use to retrieve keys in order to restore the previous
* state for restart.
*
*
* @param restartQuery
*/
public void setRestartSql(String restartQuery) {
this.restartSql = restartQuery;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
@@ -112,7 +116,7 @@ public class MultipleColumnJdbcKeyGenerator implements
Assert.hasText(sql, "The DrivingQuery must not be null or empty.");
Assert.notNull(keyMapper, "The key RowMapper must not be null.");
}
/**
* Set the {@link ExecutionContextRowMapper} to be used to map a resultset
* to keys.
@@ -122,7 +126,7 @@ public class MultipleColumnJdbcKeyGenerator implements
public void setKeyMapper(ExecutionContextRowMapper keyMapper) {
this.keyMapper = keyMapper;
}
/**
* Set the sql statement used to generate the keys list.
*
@@ -131,7 +135,7 @@ public class MultipleColumnJdbcKeyGenerator implements
public void setSql(String sql) {
this.sql = sql;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

View File

@@ -17,9 +17,9 @@ package org.springframework.batch.io.driving.support;
import java.util.List;
import org.apache.commons.lang.ClassUtils;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;
@@ -50,9 +50,9 @@ import org.springframework.util.StringUtils;
* @author Lucas Ward
* @since 1.0
*/
public class SingleColumnJdbcKeyGenerator implements KeyGenerator {
public class SingleColumnJdbcKeyGenerator extends ExecutionContextUserSupport implements KeyGenerator {
public static final String RESTART_KEY = ClassUtils.getShortClassName(SingleColumnJdbcKeyGenerator.class) + ".key";
public static final String RESTART_KEY = "key";
private JdbcTemplate jdbcTemplate;
@@ -63,7 +63,7 @@ public class SingleColumnJdbcKeyGenerator implements KeyGenerator {
private RowMapper keyMapper = new SingleColumnRowMapper();
public SingleColumnJdbcKeyGenerator() {
super();
setName(SingleColumnJdbcKeyGenerator.class.getSimpleName());
}
/**

View File

@@ -33,6 +33,7 @@ import org.springframework.batch.io.file.transform.AbstractLineTokenizer;
import org.springframework.batch.io.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.transform.LineTokenizer;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
@@ -63,7 +64,7 @@ import org.springframework.util.Assert;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class FlatFileItemReader implements ItemReader, Skippable, ItemStream, InitializingBean {
public class FlatFileItemReader extends ExecutionContextUserSupport implements ItemReader, Skippable, ItemStream, InitializingBean {
private static Log log = LogFactory.getLog(FlatFileItemReader.class);
@@ -93,14 +94,16 @@ public class FlatFileItemReader implements ItemReader, Skippable, ItemStream, In
private LineTokenizer tokenizer = new DelimitedLineTokenizer();
private FieldSetMapper fieldSetMapper;
private String name = FlatFileItemReader.class.getName();
/**
* Encapsulates the state of the input source. If it is null then we are
* uninitialized.
*/
private LineReader reader;
public FlatFileItemReader() {
setName(FlatFileItemReader.class.getSimpleName());
}
/**
* Initialize the reader if necessary.
@@ -366,9 +369,5 @@ public class FlatFileItemReader implements ItemReader, Skippable, ItemStream, In
Assert.notNull(resource, "Input resource must not be null");
Assert.notNull(fieldSetMapper, "FieldSetMapper must not be null.");
}
private String getKey(String key){
return name + "." + key;
}
}

View File

@@ -32,6 +32,7 @@ import org.springframework.batch.io.file.mapping.FieldSetCreator;
import org.springframework.batch.io.file.transform.DelimitedLineAggregator;
import org.springframework.batch.io.file.transform.LineAggregator;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
@@ -65,7 +66,7 @@ import org.springframework.util.Assert;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class FlatFileItemWriter implements ItemWriter, ItemStream,
public class FlatFileItemWriter extends ExecutionContextUserSupport implements ItemWriter, ItemStream,
InitializingBean {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@@ -84,7 +85,9 @@ public class FlatFileItemWriter implements ItemWriter, ItemStream,
private FieldSetCreator fieldSetCreator;
private String name = FlatFileItemWriter.class.getName();
public FlatFileItemWriter() {
setName(FlatFileItemWriter.class.getSimpleName());
}
/**
* Assert that mandatory properties (resource) are set.
@@ -483,11 +486,4 @@ public class FlatFileItemWriter implements ItemWriter, ItemStream,
getOutputState().mark();
}
public void setName(String name) {
this.name = name;
}
private String getKey(String key){
return name + "." + key;
}
}

View File

@@ -17,6 +17,7 @@ import org.springframework.batch.io.xml.stax.DefaultTransactionalEventReader;
import org.springframework.batch.io.xml.stax.FragmentEventReader;
import org.springframework.batch.io.xml.stax.TransactionalEventReader;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
@@ -35,10 +36,10 @@ import org.springframework.util.Assert;
*
* @author Robert Kasanicky
*/
public class StaxEventItemReader implements ItemReader, Skippable, ItemStream,
public class StaxEventItemReader extends ExecutionContextUserSupport implements ItemReader, Skippable, ItemStream,
InitializingBean {
public static final String READ_COUNT_STATISTICS_NAME = "StaxEventReaderItemReader.readCount";
public static final String READ_COUNT_STATISTICS_NAME = "readCount";
private FragmentEventReader fragmentReader;
@@ -62,6 +63,10 @@ public class StaxEventItemReader implements ItemReader, Skippable, ItemStream,
private boolean saveState = false;
public StaxEventItemReader() {
setName(StaxEventItemReader.class.getSimpleName());
}
/**
* Read in the next root element from the file, and return it.
*
@@ -127,8 +132,8 @@ public class StaxEventItemReader implements ItemReader, Skippable, ItemStream,
}
initialized = true;
if (executionContext.containsKey(READ_COUNT_STATISTICS_NAME)) {
long restoredRecordCount = executionContext.getLong(READ_COUNT_STATISTICS_NAME);
if (executionContext.containsKey(getKey(READ_COUNT_STATISTICS_NAME))) {
long restoredRecordCount = executionContext.getLong(getKey(READ_COUNT_STATISTICS_NAME));
int REASONABLE_ADHOC_COMMIT_FREQUENCY = 100;
while (currentRecordCount <= restoredRecordCount) {
currentRecordCount++;
@@ -196,7 +201,7 @@ public class StaxEventItemReader implements ItemReader, Skippable, ItemStream,
public void update(ExecutionContext executionContext) {
if(saveState){
Assert.notNull(executionContext, "ExecutionContext must not be null");
executionContext.putLong(READ_COUNT_STATISTICS_NAME, currentRecordCount);
executionContext.putLong(getKey(READ_COUNT_STATISTICS_NAME), currentRecordCount);
}
}

View File

@@ -16,6 +16,7 @@ import javax.xml.stream.XMLStreamException;
import org.springframework.batch.io.support.FileUtils;
import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
@@ -37,7 +38,7 @@ import org.springframework.util.CollectionUtils;
* @author Peter Zozom
*
*/
public class StaxEventItemWriter implements ItemWriter, ItemStream, InitializingBean {
public class StaxEventItemWriter extends ExecutionContextUserSupport implements ItemWriter, ItemStream, InitializingBean {
// default encoding
private static final String DEFAULT_ENCODING = "UTF-8";
@@ -49,10 +50,10 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
private static final String DEFAULT_ROOT_TAG_NAME = "root";
// restart data property name
public static final String RESTART_DATA_NAME = "staxstreamoutputsource.position";
public static final String RESTART_DATA_NAME = "position";
// restart data property name
public static final String WRITE_STATISTICS_NAME = "staxstreamoutputsource.record.count";
public static final String WRITE_STATISTICS_NAME = "record.count";
// file system resource
private Resource resource;
@@ -101,10 +102,12 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
// current count of processed records
private long currentRecordCount = 0;
private String name = StaxEventItemWriter.class.getName();
private boolean saveState = false;
public StaxEventItemWriter() {
setName(StaxEventItemWriter.class.getSimpleName());
}
/**
* Set output file.
*
@@ -448,13 +451,5 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
public void setSaveState(boolean saveState) {
this.saveState = saveState;
}
public void setName(String name) {
this.name = name;
}
private String getKey(String key){
return name + "." + key;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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 org.springframework.util.Assert;
/**
* Facilitates assigning names to objects persisting data in
* {@link ExecutionContext} and generating keys for {@link ExecutionContext}
* based on the name.
*
* @author Robert Kasanicky
*/
public class ExecutionContextUserSupport {
private String name;
/**
* @param name unique name for the item stream used to create execution
* context keys.
*/
public void setName(String name) {
this.name = name;
}
/**
* Prefix the argument with the name of the item stream to create a unique
* key that can be safely used to identify data stored in
* {@link ExecutionContext}.
*/
protected String getKey(String s) {
Assert.hasLength(name, "ItemStream must have a name assigned.");
return name + "." + s;
}
}