diff --git a/docs/src/site/docbook/reference/domain.xml b/docs/src/site/docbook/reference/domain.xml
index d04a1bab8..d0d61bc6e 100644
--- a/docs/src/site/docbook/reference/domain.xml
+++ b/docs/src/site/docbook/reference/domain.xml
@@ -90,7 +90,7 @@
In Spring Batch, a Job is simply a continer for Steps. It combines
multiple steps that belong logically together in a flow and allows for
configuration of properties global to all steps, such as restartability.
- The job configuration contains:
+ The job configuration contains:
@@ -303,7 +303,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
JOB_NAME
@@ -323,7 +323,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
TYPE_CD
@@ -339,7 +339,7 @@
schedule.Date
- 2008-01-01 00:00:00
+ 2008-01-01
@@ -351,9 +351,9 @@
- JOB_EXECUTION_ID
+ JOB_EXEC_ID
- JOB_INSTANCE_ID
+ JOB_INST_ID
START_TIME
@@ -367,9 +367,9 @@
1
- 2008-01-01 21:00:23.571
+ 2008-01-01 21:00
- 2008-01-01 21:30:17.132
+ 2008-01-01 21:30
FAILED
@@ -378,8 +378,8 @@
- extra columns in the tables have been removed for added
- clarity.
+ column names may have been abbreviated or removed for clarity
+ and formatting
Now that the job has failed, let's assume that it took the entire
@@ -409,7 +409,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
JOB_NAME
@@ -435,7 +435,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
TYPE_CD
@@ -473,9 +473,9 @@
- JOB_EXECUTION_ID
+ JOB_EXEC_ID
- JOB_INSTANCE_ID
+ JOB_INST_ID
START_TIME
@@ -522,6 +522,11 @@
+
+
+ column names may have been abbreviated or removed for clarity
+ and formatting
+
@@ -717,7 +722,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
JOB_NAME
@@ -735,7 +740,7 @@
- JOB_INSTANCE_ID
+ JOB_INST_ID
TYPE_CD
@@ -751,7 +756,7 @@
schedule.Date
- 2008-01-01 00:00:00
+ 2008-01-01
@@ -761,9 +766,9 @@
- JOB_EXECUTION_ID
+ JOB_EXEC_ID
- JOB_INSTANCE_ID
+ JOB_INST_ID
START_TIME
@@ -777,9 +782,9 @@
1
- 2008-01-01 21:00:23.571
+ 2008-01-01 21:00
- 2008-01-01 21:30:17.132
+ 2008-01-01 21:30
FAILED
@@ -791,9 +796,9 @@
- STEP_EXECUTION_ID
+ STEP_EXEC_ID
- JOB_EXECUTION_ID
+ JOB_EXEC_ID
STEP_NAME
@@ -811,9 +816,9 @@
loadDate
- 2008-01-01 21:00:23.571
+ 2008-01-01 21:00
- 2008-01-01 21:30:17.132
+ 2008-01-01 21:30
FAILED
@@ -825,7 +830,7 @@
- STEP_EXECUTION_ID
+ STEP_EXEC_ID
SHORT_CONTEXT
@@ -945,8 +950,8 @@
public interface JobLauncher {
- public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException,
- JobRestartException;
+ public JobExecution run(Job job, JobParameters jobParameters)
+ throws JobExecutionAlreadyRunningException, JobRestartException;
}
diff --git a/docs/src/site/docbook/reference/images/meta-data-erd.png b/docs/src/site/docbook/reference/images/meta-data-erd.png
index 2a7179068..31771519e 100755
Binary files a/docs/src/site/docbook/reference/images/meta-data-erd.png and b/docs/src/site/docbook/reference/images/meta-data-erd.png differ
diff --git a/docs/src/site/docbook/reference/job.xml b/docs/src/site/docbook/reference/job.xml
index 92efd3f85..138fa6a91 100644
--- a/docs/src/site/docbook/reference/job.xml
+++ b/docs/src/site/docbook/reference/job.xml
@@ -154,11 +154,12 @@
void afterJob(JobExecution jobExecution){
- if( jobExecution.getStatus = BatchStatus.COMPLETED ){
- //job success
- }
- else if(jobExecution.getStatus = BatchStatus.FAILED){
- //job failure
+ if( jobExecution.getStatus = BatchStatus.COMPLETED ){
+ //job success
+ }
+ else if(jobExecution.getStatus = BatchStatus.FAILED){
+ //job failure
+ }
}
@@ -379,7 +380,8 @@
that you just don't need to persist status for a particular job. Spring
batch provides a solution:
- <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
+ <bean id="jobRepository"
+ class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
diff --git a/docs/src/site/docbook/reference/readersAndWriters.xml b/docs/src/site/docbook/reference/readersAndWriters.xml
index be82d6c85..c9bf6b77e 100644
--- a/docs/src/site/docbook/reference/readersAndWriters.xml
+++ b/docs/src/site/docbook/reference/readersAndWriters.xml
@@ -182,11 +182,14 @@
fields so that the fields may be accessed either by index or name as
patterned after ResultSet:
- String[] tokens = new String[]{"foo", "1", "true"};
+
+ String[] tokens = new String[]{"foo", "1", "true"};
FieldSet fs = new DefaultFieldSet(tokens);
String name = fs.readString(0);
int value = fs.readInt(1);
- boolean booleanValue = fs.readBoolean(2);
+ boolean booleanValue = fs.readBoolean(2);
+
+
There are many more options on the FieldSet
interface, such as Date, long,
@@ -217,7 +220,7 @@
guide will not go into the details of creating
Resource objects. However, a simple example of a
file system resource can be found below:
- Resource resource = new FileSystemResource("resources/trades.csv");
+ Resource resource = new FileSystemResource("resources/trades.csv");
In complex batch environments the directory structures are often
@@ -320,10 +323,13 @@
As with RowMapper, which takes a low
level construct such as ResultSet and returns an Object,
flat file procesing requires the same construct to convert a String
- line into an Object:public interface LineMapper<T> {
+ line into an Object:
+ public interface LineMapper<T> {
- T mapLine(String line, int lineNumber) throws Exception;
-}
+ T mapLine(String line, int lineNumber) throws Exception;
+ }
+
+
The basic constract is that, given the current line, and the
line number its associated with, return a resulting domain object.
@@ -349,11 +355,14 @@
necessary. In Spring Batch, this is called a
LineTokenizer:
- public interface LineTokenizer {
+
+ public interface LineTokenizer {
FieldSet tokenize(String line);
- }
+ }
+
+
The contract of a LineTokenizer is such
that, given a line of input (in theory the
@@ -397,11 +406,14 @@
LineTokenizer to translate a line of data from
a resource into an object of the desired type:
- public interface FieldSetMapper<T> {
+
+ public interface FieldSetMapper<T> {
T mapFieldSet(FieldSet fieldSet);
- }
+ }
+
+
The pattern used is the same as RowMapper
used by JdbcTemplate.
@@ -459,7 +471,9 @@
public void setFieldSetMapper(FieldSetMapper<T> fieldSetMapper) {
this.fieldSetMapper = fieldSetMapper;
}
-}
+ }
+
+
The above functionality is provided in a default implementation,
rather than being built into the reader itself (as was done in
@@ -522,7 +536,8 @@
return player;
}
- }
+ }
+
The file can then be read by correctly constructing a
FlatFileItemReader and calling
@@ -583,7 +598,8 @@
return player;
}
- }
+ }
+
@@ -599,14 +615,17 @@
FieldSetMapper configuration looks like the
following:
- <bean id="fieldSetMapper"
+
+ <bean id="fieldSetMapper"
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="player" />
</bean>
<bean id="player"
class="org.springframework.batch.sample.domain.Player"
- scope="prototype" />
+ scope="prototype" />
+
+
For each entry in the FieldSet, the
mapper will look for a corresponding setter on a new instance of the
@@ -680,7 +699,8 @@
ApplicationContext:
- <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+ <bean id="customEditorConfigurer"
+ class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="org.springframework.batch.item.file.transform.Range[]">
@@ -717,7 +737,8 @@
PrefixMatchingCompositeLineTokenizer makes this easier by matching the
prefix in a line with a particular tokenizer:
- <bean id="orderFileDescriptor"
+
+ <bean id="orderFileDescriptor"
class="org.springframework.batch.io.file.transform.PrefixMatchingCompositeLineTokenizer">
<property name="tokenizers">
<map>
@@ -733,7 +754,9 @@
<entry key="" value-ref="defaultLineDescriptor" />
</map>
</property>
- </bean>
+ </bean>
+
+
This ensures that the line will be parsed correctly, which is
especially important for fixed length input. Any users of the
@@ -863,11 +886,14 @@
writing to a file. In Spring Batch this is the
LineAggregator:
- public interface LineAggregator<T> {
+
+ public interface LineAggregator<T> {
public String aggregate(T item);
- }
+ }
+
+
The LineAggregator is the opposite of a
LineTokenizer.
@@ -927,20 +953,26 @@
FlatFileItemWriter expresses this in
code:
- public void write(T item) throws Exception {
+
+ public void write(T item) throws Exception {
write(lineAggregator.aggregate(item) + LINE_SEPARATOR);
- }
+ }
+
+
A simple configuration would look like the following:
- <bean id="itemWriter"
+
+ <bean id="itemWriter"
class="org.springframework.batch.io.file.FlatFileItemWriter">
<property name="resource"
value="file:target/test-outputs/20070122.testStream.multilineStep.txt" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator"/>
</property>
- </bean>
+ </bean>
+
+
@@ -1201,12 +1233,12 @@
+ format="PNG" width="40%" />
+ width="40%" />
Figure 3.1: XML Input
@@ -1228,12 +1260,12 @@
+ format="PNG" width="40%" />
+ format="PNG" width="40%" />
Figure 3.2: OXM Binding
@@ -2241,7 +2273,8 @@
<job id="ioSampleJob">
<step name="step1">
- <tasklet reader="fooReader" processor="fooProcessor" writer="compositeItemWriter" commit-interval="2"/>
+ <tasklet reader="fooReader" processor="fooProcessor" writer="compositeItemWriter"
+ commit-interval="2"/>
<streams>
<stream ref="barWriter" />
</streams>
@@ -2357,11 +2390,14 @@
rather provides a very simple interface that can be implemented by any
number of frameworks:
- public interface Validator {
+
+ public interface Validator {
void validate(Object value) throws ValidationException;
- }
+ }
+
+
The contract is that the validate method
will throw an exception if the object is invalid, and return normally if
@@ -2381,9 +2417,14 @@
<value>
<![CDATA[
{ orderId : ? > 0 AND ? <= 9999999999 : 'Incorrect order ID' : 'error.order.id' }
- { totalLines : ? = size(lineItems) : 'Bad count of order lines' : 'error.order.lines.badcount'}
- { customer.registered : customer.businessCustomer = FALSE OR ? = TRUE : 'Business customer must be registered' : 'error.customer.registration'}
- { customer.companyName : customer.businessCustomer = FALSE OR ? HAS TEXT : 'Company name for business customer is mandatory' :'error.customer.companyname'}
+ { totalLines : ? = size(lineItems) : 'Bad count of order lines'
+ : 'error.order.lines.badcount'}
+ { customer.registered : customer.businessCustomer = FALSE OR ? = TRUE
+ : 'Business customer must be registered'
+ : 'error.customer.registration'}
+ { customer.companyName : customer.businessCustomer = FALSE OR ? HAS TEXT
+ : 'Company name for business customer is mandatory'
+ :'error.customer.companyname'}
]]>
</value>
</property>
@@ -2468,7 +2509,8 @@
basic contract of ItemReader,
read:
- public class CustomItemReader<T> implements ItemReader<T>{
+
+ public class CustomItemReader<T> implements ItemReader<T>{
List<T> items;
@@ -2484,7 +2526,9 @@
}
return null;
}
- }
+ }
+
+
This very simple class takes a list of items, and returns one at a
time, removing it from the list. When the list empty, it returns null,
diff --git a/docs/src/site/docbook/reference/schema-appendix.xml b/docs/src/site/docbook/reference/schema-appendix.xml
index ace579cfd..c7c1b28da 100644
--- a/docs/src/site/docbook/reference/schema-appendix.xml
+++ b/docs/src/site/docbook/reference/schema-appendix.xml
@@ -27,12 +27,14 @@
-
+
-
+
@@ -518,13 +520,13 @@ INSERT INTO BATCH_JOB_SEQ values(0);
The framework will use the meta-data tables to determine if a
particular JobInstance has been run before. If it has been run, and
- the job is not restartable, then an exception will be thrown.
+ the job is not restartable, then an exception will be thrown.
If an entry for a JobInstance is removed without having
completed successfully, the framework will think that the job is new,
- rather than a restart.
+ rather than a restart.
@@ -536,4 +538,4 @@ INSERT INTO BATCH_JOB_SEQ values(0);
-
+
\ No newline at end of file
diff --git a/docs/src/site/docbook/reference/step.xml b/docs/src/site/docbook/reference/step.xml
index fc0b9df9e..95cd4cca9 100644
--- a/docs/src/site/docbook/reference/step.xml
+++ b/docs/src/site/docbook/reference/step.xml
@@ -204,8 +204,8 @@
<step name="step1">
- <tasklet reader="itemReader" writer="itemWriter" commit-interval="10" allow-start-if-complete="true"/>
+ <tasklet reader="itemReader" writer="itemWriter" commit-interval="10"
+ allow-start-if-complete="true"/>
</step>
@@ -484,7 +484,8 @@
</tasklet>
</step>
- <beans:bean id="compositeWriter" class="org.springframework.batch.item.support.CompositeItemWriter">
+ <beans:bean id="compositeWriter"
+ class="org.springframework.batch.item.support.CompositeItemWriter">
<beans:property name="delegates">
<beans:list>
<beans:ref bean="fileItemWriter1" />
@@ -972,13 +973,13 @@
+ scale="" width="40%" />
+ width="40%" />
@@ -1019,13 +1020,13 @@
rather than causing failure?
+ scale="" width="40%" />
+ width="40%" />
@@ -1237,7 +1238,7 @@
- Creating File Names at Runtime
+ Late binding of Job and Step Attributes
Both the XML and Flat File examples above use the Spring
Resource abstraction to obtain the file to read
@@ -1246,11 +1247,14 @@
java.io.File. Both XML and Flat File resources
can be configured using standard Spring constructs:
- <bean id="flatFileItemReader"
+
+ <bean id="flatFileItemReader"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource"
value="file://outputs/20070122.testStream.CustomerReportStep.TEMP.txt" />
- </bean>
+ </bean>
+
+
The above Resource will load the file from
the file system, at the location specificied. Note that absolute
@@ -1260,10 +1264,13 @@
may need to be determined at runtime as a parameter to the job. This
could be solved using '-D' parameters, i.e. a system property:
- <bean id="flatFileItemReader"
+
+ <bean id="flatFileItemReader"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="${input.file.name}" />
-</bean>
+ </bean>
+
+
All that would be required for this solution to work would be a
system argument (-Dinput.file.name="file://file.txt"). (Note that
@@ -1275,35 +1282,63 @@
Often in a batch setting it is preferable to parameterize the file
name in the JobParameters of the job, instead of
through system properties, and access them that way. To allow for this,
- Spring Batch provides the
- StepExecutionResourceProxy. The proxy can use
- either job name, step name, or any values from the
- JobParameters, by surrounding them with %:
+ Spring Batch allows for the late binding of various Job and Step
+ attributes:
- <bean id="inputFile"
- class="org.springframework.batch.core.resource.StepExecutionResourceProxy" />
- <property name="filePattern" value="//%JOB_NAME%/%STEP_NAME%/%file.name%" />
- </bean>
+
+ <bean id="flatFileItemReader" scope="step"
+ class="org.springframework.batch.item.file.FlatFileItemReader">
+ <property name="resource" value="#{jobParameters[input.file.name]}" />
+ </bean>
- Assuming a job name of 'fooJob', and a step name of 'fooStep', and
- the key-value pair of 'file.name="fileName.txt"' is in the
- JobParameters the job is started with, the
- following filename will be passed as the
- Resource:
- "//fooJob/fooStep/fileName.txt". It should be noted
- that in order for the proxy to have access to the
- StepExecution, it must be registered as a
- StepListener:
+
- <bean id="fooStep" parent="abstractStep"
- p:itemReader-ref="itemReader"
- p:itemWriter-ref="itemWriter">
- <property name="listeners" ref="inputFile" />
- </bean>
+ Both the JobExecution and
+ StepExecution level
+ ExecutionContext can be access in the same
+ way:
- The StepListener interface will be
- discussed in more detail in Chapter 4. For now, it is sufficient to know
- that the proxy must be registered.
+
+ <bean id="flatFileItemReader" scope="step"
+ class="org.springframework.batch.item.file.FlatFileItemReader">
+ <property name="resource" value="#{jobExecutionContext[input.file.name]}" />
+ </bean>
+
+
+
+
+ <bean id="flatFileItemReader" scope="step"
+ class="org.springframework.batch.item.file.FlatFileItemReader">
+ <property name="resource" value="#{stepExecutionContext[input.file.name]}" />
+ </bean>
+
+
+
+
+ Step Scope
+
+ All of the late binding examples from above have a scope of
+ "step" declared on the bean definition:
+
+
+ <bean id="flatFileItemReader" scope="step"
+ class="org.springframework.batch.item.file.FlatFileItemReader">
+ <property name="resource" value="#{jobParameters[input.file.name]}" />
+ </bean>
+
+
+
+ Using a scope of Step is required in
+ order to use late binding, since the bean cannot actually be
+ instantiated until the Step starts, which
+ allows the attributes to be found. Because it is not part of the
+ Spring container by default, it must be added explicitely:
+
+
+ <bean class="org.springframework.batch.core.scope.StepScope" />
+
+
+
\ No newline at end of file