Move docs over from i21 repo

This commit is contained in:
dsyer
2008-02-12 18:34:31 +00:00
parent 8cecd74e3a
commit 17a8b6d734
51 changed files with 6128 additions and 0 deletions

Binary file not shown.

Binary file not shown.

BIN
docs/models/Figures.ppt Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
docs/ppt/Figures.ppt Normal file

Binary file not shown.

View File

@@ -0,0 +1,421 @@
body {
text-align: justify;
margin-right: 2em;
margin-left: 2em;
}
a,
a[accesskey^
=
"h"
]
,
a[accesskey^
=
"n"
]
,
a[accesskey^
=
"u"
]
,
a[accesskey^
=
"p"
]
{
font-family: Verdana, Arial, helvetica, sans-serif
;
font-size:
12
px
;
color: #003399
;
}
a:active {
color: #003399;
}
a:visited {
color: #888888;
}
p {
font-family: Verdana, Arial, sans-serif;
}
dt {
font-family: Verdana, Arial, sans-serif;
font-size: 12px;
}
p, dl, dt, dd, blockquote {
color: #000000;
margin-bottom: 3px;
margin-top: 3px;
padding-top: 0px;
}
ol, ul, p {
margin-top: 6px;
margin-bottom: 6px;
}
p, blockquote {
font-size: 90%;
}
p.releaseinfo {
font-size: 100%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
padding-top: 10px;
}
p.pubdate {
font-size: 120%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
}
td {
font-size: 80%;
}
td, th, span {
color: #000000;
}
td[width^
=
"40%"
]
{
font-family: Verdana, Arial, helvetica, sans-serif
;
font-size:
12
px
;
color: #003399
;
}
table[summary^
=
"Navigation header"
]
tbody tr th[colspan^
=
"3"
]
{
font-family: Verdana, Arial, helvetica, sans-serif
;
}
blockquote {
margin-right: 0px;
}
h1, h2, h3, h4, h6, H6 {
color: #000000;
font-weight: 500;
margin-top: 0px;
padding-top: 14px;
font-family: Verdana, Arial, helvetica, sans-serif;
margin-bottom: 0px;
}
h2.title {
font-weight: 800;
margin-bottom: 8px;
}
h2.subtitle {
font-weight: 800;
margin-bottom: 20px;
}
.firstname, .surname {
font-size: 12px;
font-family: Verdana, Arial, helvetica, sans-serif;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px black;
empty-cells: hide;
margin: 10px 0px 30px 50px;
width: 90%;
}
div.table {
margin: 30px 0px 30px 0px;
border: 1px dashed gray;
padding: 10px;
}
div .table-contents table {
border: 1px solid black;
}
div.table > p.title {
padding-left: 10px;
}
table[summary^
=
"Navigation footer"
]
{
border-collapse: collapse
;
border-spacing:
0
;
border:
1
px black
;
empty-cells: hide
;
margin:
0
px
;
width:
100
%
;
}
table[summary^
=
"Note"
]
,
table[summary^
=
"Warning"
]
,
table[summary^
=
"Tip"
]
{
border-collapse: collapse
;
border-spacing:
0
;
border:
1
px black
;
empty-cells: hide
;
margin:
10
px
0
px
10
px
-
20
px
;
width:
100
%
;
}
td {
padding: 4pt;
font-family: Verdana, Arial, helvetica, sans-serif;
}
div.warning TD {
text-align: justify;
}
h1 {
font-size: 150%;
}
h2 {
font-size: 110%;
}
h3 {
font-size: 100%;
font-weight: bold;
}
h4 {
font-size: 90%;
font-weight: bold;
}
h5 {
font-size: 90%;
font-style: italic;
}
h6 {
font-size: 100%;
font-style: italic;
}
tt {
font-size: 110%;
font-family: "Courier New", Courier, monospace;
color: #000000;
}
.navheader, .navfooter {
border: none;
}
div.navfooter table {
border: dashed gray;
border-width: 1px 1px 1px 1px;
background-color: #cde48d;
}
pre {
font-size: 110%;
padding: 5px;
border-style: solid;
border-width: 1px;
border-color: #CCCCCC;
background-color: #f3f5e9;
}
ul, ol, li {
list-style: disc;
}
hr {
width: 100%;
height: 1px;
background-color: #CCCCCC;
border-width: 0px;
padding: 0px;
}
.variablelist {
padding-top: 10px;
padding-bottom: 10px;
margin: 0;
}
.term {
font-weight: bold;
}
.mediaobject {
padding-top: 30px;
padding-bottom: 30px;
}
.legalnotice {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
font-style: italic;
}
.sidebar {
float: right;
margin: 10px 0px 10px 30px;
padding: 10px 20px 20px 20px;
width: 33%;
border: 1px solid black;
background-color: #F4F4F4;
font-size: 14px;
}
.property {
font-family: "Courier New", Courier, monospace;
}
a code {
font-family: Verdana, Arial, monospace;
font-size: 12px;
}
td code {
font-size: 110%;
}
div.note * td,
div.tip * td,
div.warning * td,
div.calloutlist * td {
text-align: justify;
font-size: 100%;
}
.programlisting .interfacename,
.programlisting .literal,
.programlisting .classname {
font-size: 95%;
}
.title .interfacename,
.title .literal,
.title .classname {
font-size: 130%;
}
/* everything in a <lineannotation/> is displayed in a coloured, comment-like font */
.programlisting * .lineannotation,
.programlisting * .lineannotation * {
color: green;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,468 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This is the XSL FO (PDF) stylesheet for the Spring reference
documentation.
Thanks are due to Christian Bauer of the Hibernate project
team for writing the original stylesheet upon which this one
is based.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:import href="urn:docbkx:stylesheet"/>
<!--###################################################
Custom Title Page
################################################### -->
<xsl:template name="book.titlepage.recto">
<fo:block>
<fo:table table-layout="fixed" width="175mm">
<fo:table-column column-width="175mm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block>
<fo:block font-family="Helvetica" font-size="24pt" padding-before="10mm">
<xsl:value-of select="bookinfo/title"/>
</fo:block>
</fo:block>
<fo:block font-family="Helvetica" font-size="22pt" padding-before="10mm">
<xsl:value-of select="bookinfo/subtitle"/>
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
<xsl:value-of select="bookinfo/releaseinfo"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block font-family="Helvetica" font-size="14pt" padding="10mm">
<xsl:value-of select="bookinfo/pubdate"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
<xsl:text>Copyright &#xA9; 2005-2007 </xsl:text>
<xsl:for-each select="bookinfo/authorgroup/author">
<xsl:if test="position() > 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="surname"/>
</xsl:for-each>
</fo:block>
<fo:block font-family="Helvetica" font-size="10pt" padding="1mm">
<xsl:value-of select="bookinfo/legalnotice"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
<!-- Prevent blank pages in output -->
<xsl:template name="book.titlepage.before.verso">
</xsl:template>
<xsl:template name="book.titlepage.verso">
</xsl:template>
<xsl:template name="book.titlepage.separator">
</xsl:template>
<!--###################################################
Header
################################################### -->
<!-- More space in the center header for long text -->
<xsl:attribute-set name="header.content.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$body.font.family"/>
</xsl:attribute>
<xsl:attribute name="margin-left">-5em</xsl:attribute>
<xsl:attribute name="margin-right">-5em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Custom Footer
################################################### -->
<xsl:template name="footer.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
<xsl:variable name="Version">
<xsl:if test="//releaseinfo">
<xsl:value-of select="//releaseinfo"/>
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="$sequence='blank'">
<xsl:if test="$position = 'center'">
<xsl:value-of select="$Version"/>
</xsl:if>
</xsl:when>
<!-- for double sided printing, print page numbers on alternating sides (of the page) -->
<xsl:when test="$double.sided != 0">
<xsl:choose>
<xsl:when test="$sequence = 'even' and $position='left'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$sequence = 'odd' and $position='right'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version"/>
</xsl:when>
</xsl:choose>
</xsl:when>
<!-- for single sided printing, print all page numbers on the right (of the page) -->
<xsl:when test="$double.sided = 0">
<xsl:choose>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:when test="$position='right'">
<fo:page-number/>
</xsl:when>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--###################################################
Custom Toc Line
################################################### -->
<!-- The default DocBook XSL TOC printing is seriously broken... -->
<xsl:template name="toc.line">
<xsl:variable name="id">
<xsl:call-template name="object.id"/>
</xsl:variable>
<xsl:variable name="label">
<xsl:apply-templates select="." mode="label.markup"/>
</xsl:variable>
<!-- justify-end removed from block attributes (space problem in title.markup) -->
<fo:block end-indent="{$toc.indent.width}pt"
last-line-end-indent="-{$toc.indent.width}pt"
white-space-treatment="preserve"
text-align="left"
white-space-collapse="false">
<fo:inline keep-with-next.within-line="always">
<!-- print Chapters in bold style -->
<xsl:choose>
<xsl:when test="local-name(.) = 'chapter'">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:when>
</xsl:choose>
<fo:basic-link internal-destination="{$id}">
<xsl:if test="$label != ''">
<xsl:copy-of select="$label"/>
<fo:inline white-space-treatment="preserve"
white-space-collapse="false">
<xsl:value-of select="$autotoc.label.separator"/>
</fo:inline>
</xsl:if>
<xsl:apply-templates select="." mode="title.markup"/>
</fo:basic-link>
</fo:inline>
<fo:inline keep-together.within-line="always">
<xsl:text> </xsl:text>
<fo:leader leader-pattern="dots"
leader-pattern-width="3pt"
leader-alignment="reference-area"
keep-with-next.within-line="always"/>
<xsl:text> </xsl:text>
<fo:basic-link internal-destination="{$id}">
<fo:page-number-citation ref-id="{$id}"/>
</fo:basic-link>
</fo:inline>
</fo:block>
</xsl:template>
<!--###################################################
Extensions
################################################### -->
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<!-- FOP provide only PDF Bookmarks at the moment -->
<xsl:param name="fop.extensions">1</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">2</xsl:param>
<!-- Dot and Whitespace as separator in TOC between Label and Title-->
<xsl:param name="autotoc.label.separator" select="'. '"/>
<!--###################################################
Paper & Page Size
################################################### -->
<!-- Paper type, no headers on blank pages, no double sided printing -->
<xsl:param name="paper.type" select="'A4'"/>
<xsl:param name="double.sided">0</xsl:param>
<xsl:param name="headers.on.blank.pages">0</xsl:param>
<xsl:param name="footers.on.blank.pages">0</xsl:param>
<!-- Space between paper border and content (chaotic stuff, don't touch) -->
<xsl:param name="page.margin.top">5mm</xsl:param>
<xsl:param name="region.before.extent">10mm</xsl:param>
<xsl:param name="body.margin.top">10mm</xsl:param>
<xsl:param name="body.margin.bottom">15mm</xsl:param>
<xsl:param name="region.after.extent">10mm</xsl:param>
<xsl:param name="page.margin.bottom">0mm</xsl:param>
<xsl:param name="page.margin.outer">18mm</xsl:param>
<xsl:param name="page.margin.inner">18mm</xsl:param>
<!-- No intendation of Titles -->
<xsl:param name="title.margin.left">0pc</xsl:param>
<!--###################################################
Fonts & Styles
################################################### -->
<!-- Left aligned text and no hyphenation -->
<xsl:param name="alignment">justify</xsl:param>
<xsl:param name="hyphenate">false</xsl:param>
<!-- Default Font size -->
<xsl:param name="body.font.master">11</xsl:param>
<xsl:param name="body.font.small">8</xsl:param>
<!-- Line height in body text -->
<xsl:param name="line-height">1.4</xsl:param>
<!-- Monospaced fonts are smaller than regular text -->
<xsl:attribute-set name="monospace.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$monospace.font.family"/>
</xsl:attribute>
<xsl:attribute name="font-size">0.8em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Tables
################################################### -->
<!-- The table width should be adapted to the paper size -->
<xsl:param name="default.table.width">17.4cm</xsl:param>
<!-- Some padding inside tables -->
<xsl:attribute-set name="table.cell.padding">
<xsl:attribute name="padding-left">4pt</xsl:attribute>
<xsl:attribute name="padding-right">4pt</xsl:attribute>
<xsl:attribute name="padding-top">4pt</xsl:attribute>
<xsl:attribute name="padding-bottom">4pt</xsl:attribute>
</xsl:attribute-set>
<!-- Only hairlines as frame and cell borders in tables -->
<xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
<xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<!--###################################################
Titles
################################################### -->
<!-- Chapter title size -->
<xsl:attribute-set name="chapter.titlepage.recto.style">
<xsl:attribute name="text-align">left</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.8"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
Let's remove it, so this sucker can use our attribute-set only... -->
<xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
xsl:use-attribute-sets="chapter.titlepage.recto.style">
<xsl:call-template name="component.title">
<xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
</xsl:call-template>
</fo:block>
</xsl:template>
<!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
<xsl:attribute-set name="section.title.level1.properties">
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.5"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level2.properties">
<xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.25"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level3.properties">
<xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!-- Titles of formal objects (tables, examples, ...) -->
<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="hyphenate">false</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Programlistings
################################################### -->
<!-- Verbatim text formatting (programlistings) -->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.small * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="verbatim.properties">
<xsl:attribute name="space-before.minimum">1em</xsl:attribute>
<xsl:attribute name="space-before.optimum">1em</xsl:attribute>
<xsl:attribute name="space-before.maximum">1em</xsl:attribute>
<xsl:attribute name="border-color">#444444</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">0.1pt</xsl:attribute>
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
<xsl:attribute name="padding-left">0.5em</xsl:attribute>
<xsl:attribute name="padding-right">0.5em</xsl:attribute>
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="margin-left">0.5em</xsl:attribute>
<xsl:attribute name="margin-right">0.5em</xsl:attribute>
</xsl:attribute-set>
<!-- Shade (background) programlistings -->
<xsl:param name="shade.verbatim">1</xsl:param>
<xsl:attribute-set name="shade.verbatim.style">
<xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Callouts
################################################### -->
<!-- Use images for callouts instead of (1) (2) (3) -->
<xsl:param name="callout.graphics">0</xsl:param>
<xsl:param name="callout.unicode">1</xsl:param>
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">'1'</xsl:param>
<!-- <xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param> -->
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
<xsl:param name="variablelist.as.blocks">1</xsl:param>
<!-- The horrible list spacing problems -->
<xsl:attribute-set name="list.block.spacing">
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
colored and hyphenated links
################################################### -->
<xsl:template match="ulink">
<fo:basic-link external-destination="{@url}"
xsl:use-attribute-sets="xref.properties"
text-decoration="underline"
color="blue">
<xsl:choose>
<xsl:when test="count(child::node())=0">
<xsl:value-of select="@url"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</fo:basic-link>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This is the XSL HTML configuration file for the Spring
Reference Documentation.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:import href="urn:docbkx:stylesheet"/>
<!--###################################################
HTML Settings
################################################### -->
<xsl:param name="html.stylesheet">html.css</xsl:param>
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">3</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<!--###################################################
Callouts
################################################### -->
<!-- Use images for callouts instead of (1) (2) (3) -->
<xsl:param name="callout.graphics">0</xsl:param>
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">0</xsl:param>
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<xsl:template match="author" mode="titlepage.mode">
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:call-template name="person.name"/>
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
</span>
</xsl:template>
<xsl:template match="authorgroup" mode="titlepage.mode">
<div class="{name(.)}">
<h2>Authors</h2>
<p/>
<xsl:apply-templates mode="titlepage.mode"/>
</div>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This is the XSL HTML configuration file for the Spring Reference Documentation.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:import href="urn:docbkx:stylesheet"/>
<!--###################################################
HTML Settings
################################################### -->
<xsl:param name="chunk.section.depth">'5'</xsl:param>
<xsl:param name="use.id.as.filename">'1'</xsl:param>
<xsl:param name="html.stylesheet">html.css</xsl:param>
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">3</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<!--###################################################
Callouts
################################################### -->
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<xsl:template match="author" mode="titlepage.mode">
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:call-template name="person.name"/>
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
</span>
</xsl:template>
<xsl:template match="authorgroup" mode="titlepage.mode">
<div class="{name(.)}">
<h2>Authors</h2>
<p/>
<xsl:apply-templates mode="titlepage.mode"/>
</div>
</xsl:template>
<!--###################################################
Headers and Footers
################################################### -->
<!-- let's have a Spring and I21 banner across the top of each page -->
<xsl:template name="user.header.navigation">
<div style="background-color:white;border:none;height:73px;border:1px solid black;">
<a style="border:none;" href="http://static.springframework.org/spring-batch/"
title="The Spring Framework - Spring Batch">
<img style="border:none;" src="images/xdev-spring_logo.jpg"/>
</a>
<a style="border:none;" href="http://www.interface21.com/" title="Interface21 - Spring from the Source">
<img style="border:none;position:absolute;padding-top:5px;right:42px;" src="images/i21-banner-rhs.jpg"/>
</a>
</div>
</xsl:template>
<!-- no other header navigation (prev, next, etc.) -->
<xsl:template name="header.navigation"/>
<xsl:param name="navig.showtitles">1</xsl:param>
<!-- let's have a 'Sponsored by Interface21' strapline (or somesuch) across the bottom of each page -->
<xsl:template name="footer.navigation">
<xsl:param name="prev" select="/foo"/>
<xsl:param name="next" select="/foo"/>
<xsl:param name="nav.context"/>
<xsl:variable name="home" select="/*[1]"/>
<xsl:variable name="up" select="parent::*"/>
<xsl:variable name="row1" select="count($prev) &gt; 0
or count($up) &gt; 0
or count($next) &gt; 0"/>
<xsl:variable name="row2" select="($prev and $navig.showtitles != 0)
or (generate-id($home) != generate-id(.)
or $nav.context = 'toc')
or ($chunk.tocs.and.lots != 0
and $nav.context != 'toc')
or ($next and $navig.showtitles != 0)"/>
<xsl:if test="$suppress.navigation = '0' and $suppress.footer.navigation = '0'">
<div class="navfooter">
<xsl:if test="$footer.rule != 0">
<hr/>
</xsl:if>
<xsl:if test="$row1 or $row2">
<table width="100%" summary="Navigation footer">
<xsl:if test="$row1">
<tr>
<td width="40%" align="left">
<xsl:if test="count($prev)>0">
<a accesskey="p">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$prev"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'prev'"/>
</xsl:call-template>
</a>
</xsl:if>
<xsl:text>&#160;</xsl:text>
</td>
<td width="20%" align="center">
<xsl:choose>
<xsl:when test="$home != . or $nav.context = 'toc'">
<a accesskey="h">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$home"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'home'"/>
</xsl:call-template>
</a>
<xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
<xsl:text>&#160;|&#160;</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>&#160;</xsl:otherwise>
</xsl:choose>
<xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
<a accesskey="t">
<xsl:attribute name="href">
<xsl:apply-templates select="/*[1]" mode="recursive-chunk-filename">
<xsl:with-param name="recursive" select="true()"/>
</xsl:apply-templates>
<xsl:text>-toc</xsl:text>
<xsl:value-of select="$html.ext"/>
</xsl:attribute>
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'nav-toc'"/>
</xsl:call-template>
</a>
</xsl:if>
</td>
<td width="40%" align="right">
<xsl:text>&#160;</xsl:text>
<xsl:if test="count($next)>0">
<a accesskey="n">
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$next"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="navig.content">
<xsl:with-param name="direction" select="'next'"/>
</xsl:call-template>
</a>
</xsl:if>
</td>
</tr>
</xsl:if>
<xsl:if test="$row2">
<tr>
<td width="40%" align="left" valign="top">
<xsl:if test="$navig.showtitles != 0">
<xsl:apply-templates select="$prev" mode="object.title.markup"/>
</xsl:if>
<xsl:text>&#160;</xsl:text>
</td>
<td width="20%" align="center">
<span style="color:white;font-size:90%;">
<a href="http://www.interface21.com/"
title="Interface21 - Spring from the Source">Sponsored by Interface21
</a>
</span>
</td>
<td width="40%" align="right" valign="top">
<xsl:text>&#160;</xsl:text>
<xsl:if test="$navig.showtitles != 0">
<xsl:apply-templates select="$next" mode="object.title.markup"/>
</xsl:if>
</td>
</tr>
</xsl:if>
</table>
</xsl:if>
</div>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,283 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--xtools2_universal_type_manager-->
<?com.ibm.xtools.emf.core.signature <signature id="com.ibm.xtools.mmi.ui.signatures.diagram" version="7.0.0"><feature description="" name="Rational Modeling Platform (com.ibm.xtools.rmp)" url="" version="7.0.0"/></signature>?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.0/notation" xmlns:uml="http://www.eclipse.org/uml2/2.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.2/Umlnotation" xmi:id="_qxLO8GcLEdySpMFhuX87fw" type="Class" name="flat-file-input-source-design.dnx">
<children xmi:id="_q_L1wGcLEdySpMFhuX87fw">
<children xmi:id="_q_L1w2cLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_q_L1xGcLEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_q_L1xWcLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_q_L1xmcLEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_q_L1x2cLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_q_L1yGcLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_q_L1yWcLEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_q_L1ymcLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_q_L1y2cLEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_q_L1zGcLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_q_L1wWcLEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_q_L1wmcLEdySpMFhuX87fw" x="17118" y="317"/>
</children>
<children xmi:id="_8ceMAGcLEdySpMFhuX87fw">
<children xmi:id="_8ceMA2cLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_8ceMBGcLEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_8ceMBWcLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_8ceMBmcLEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_8ceMB2cLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_8ceMCGcLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_8ceMCWcLEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_8ceMCmcLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_8ceMC2cLEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_8ceMDGcLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_8ceMAWcLEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_8ceMAmcLEdySpMFhuX87fw" x="16801" y="2536"/>
</children>
<children xmi:id="_9kcgsGcLEdySpMFhuX87fw">
<children xmi:id="_9kcgs2cLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_9kcgtGcLEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_9kcgtWcLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_9kcgtmcLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_9kcgt2cLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_9kcguGcLEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9kcguWcLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_9kcgumcLEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9kcgu2cLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_9kcgsWcLEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9kcgsmcLEdySpMFhuX87fw" x="16538" y="4783"/>
</children>
<children xmi:id="_PDX1vGcMEdySpMFhuX87fw">
<children xmi:id="_PDX1v2cMEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_PDX1wGcMEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_PDX1wWcMEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_PDX1wmcMEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_PDX1w2cMEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_PDhmsGcMEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_PDhmsWcMEdySpMFhuX87fw"/>
</children>
<children xmi:id="_PDhmsmcMEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_PDhms2cMEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_PDX1vWcMEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PDX1vmcMEdySpMFhuX87fw" x="16484" y="12997"/>
</children>
<children xmi:id="_7moB2GcOEdySpMFhuX87fw">
<children xmi:id="_7moB22cOEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_7moB3GcOEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_7moB3WcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7moB3mcOEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_7moB32cOEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_7moB4GcOEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7moB4WcOEdySpMFhuX87fw"/>
</children>
<children xmi:id="_7moB4mcOEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7moB42cOEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_7moB2WcOEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=ResourceLineReader%5Bjcu%5Ename=ResourceLineReader.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7moB2mcOEdySpMFhuX87fw" x="8242" y="4755"/>
</children>
<children xmi:id="_7moB7mcOEdySpMFhuX87fw">
<children xmi:id="_7moB8WcOEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_7moB8mcOEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_7moB82cOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7moB9GcOEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_7mxywGcOEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_7mxywWcOEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxywmcOEdySpMFhuX87fw"/>
</children>
<children xmi:id="_7mxyw2cOEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxyxGcOEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_7moB72cOEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=FieldSet%5Bjcu%5Ename=FieldSet.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7moB8GcOEdySpMFhuX87fw" x="25360" y="7925"/>
</children>
<children xmi:id="_7mxyxWcOEdySpMFhuX87fw">
<children xmi:id="_7mxyyGcOEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_7mxyyWcOEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_7mxyymcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7mxyy2cOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7mxyzGcOEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_7mxyzWcOEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_7mxyzmcOEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxyz2cOEdySpMFhuX87fw"/>
</children>
<children xmi:id="_7mxy0GcOEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxy0WcOEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_7mxyxmcOEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=LineTokenizer%5Bjcu%5Ename=LineTokenizer.java%5Bjpack%5Ename=org.springframework.batch.io.file.support.transform%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7mxyx2cOEdySpMFhuX87fw" x="25360" y="5072"/>
</children>
<children xmi:id="_7mxy0mcOEdySpMFhuX87fw">
<children xmi:id="_7mxy1WcOEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_7mxy1mcOEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_7mxy12cOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7mxy2GcOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7mxy2WcOEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_7mxy2mcOEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_7mxy22cOEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxy3GcOEdySpMFhuX87fw"/>
</children>
<children xmi:id="_7mxy3WcOEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7mxy3mcOEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_7mxy02cOEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=RecordSeparatorPolicy%5Bjcu%5Ename=RecordSeparatorPolicy.java%5Bjpack%5Ename=org.springframework.batch.io.file.support.separator%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7mxy1GcOEdySpMFhuX87fw" x="7925" y="7608"/>
</children>
<styles xmi:type="umlnotation:UMLDiagramStyle" xmi:id="_qxLO8WcLEdySpMFhuX87fw"/>
<element xsi:nil="true"/>
<edges xmi:id="_8cn9AGcLEdySpMFhuX87fw" source="_8ceMAGcLEdySpMFhuX87fw" target="_q_L1wGcLEdySpMFhuX87fw">
<children xmi:id="_8cn9A2cLEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_8cn9BWcLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_8cn9BmcLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_8cn9BGcLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_8cn9AWcLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_8cn9AmcLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_9kmRsGcLEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_8ceMAGcLEdySpMFhuX87fw">
<children xmi:id="_9kmRs2cLEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_9kmRtWcLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_9kmRtmcLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9kmRtGcLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9kmRsWcLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9kmRsmcLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_PD0hpWcMEdySpMFhuX87fw" source="_PDX1vGcMEdySpMFhuX87fw" target="_9kcgsGcLEdySpMFhuX87fw">
<children xmi:id="_PD0hqGcMEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_PD0hqmcMEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_PD0hq2cMEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PD0hqWcMEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_PD0hpmcMEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_PD0hp2cMEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_PD0hrGcMEdySpMFhuX87fw" source="_PDX1vGcMEdySpMFhuX87fw" target="_9kcgsGcLEdySpMFhuX87fw">
<children xmi:id="_PD0hr2cMEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_PD0hsWcMEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_PD0hs2cMEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_PD0hsmcMEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PD0hsGcMEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_PD0hrWcMEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_PD0hrmcMEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_7nEtsGcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7moB2GcOEdySpMFhuX87fw">
<children xmi:id="_7nEts2cOEdySpMFhuX87fw" type="FromMultiplicityLabel">
<children xmi:id="_7nEttWcOEdySpMFhuX87fw" type="FromMultiplicity"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nEttGcOEdySpMFhuX87fw" y="396"/>
</children>
<children xmi:id="_7nEttmcOEdySpMFhuX87fw" type="FromRoleLabel">
<children xmi:id="_7nEtuGcOEdySpMFhuX87fw" type="FromRole"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nEtt2cOEdySpMFhuX87fw" y="-397"/>
</children>
<children xmi:id="_7nEtuWcOEdySpMFhuX87fw" type="associationTypeLabel">
<children xmi:id="_7nEtu2cOEdySpMFhuX87fw" type="associationTypeCompartment"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nEtumcOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nEtsWcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Property" href="mmi:///#jfield%5Ename=reader%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Property"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nEtsmcOEdySpMFhuX87fw" points="[-14, 3095, 14723, -11456]$[-14751, 4682, -14, -9869]"/>
</edges>
<edges xmi:id="_7nEtvGcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7moB2GcOEdySpMFhuX87fw">
<children xmi:id="_7nEtv2cOEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_7nEtwWcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7nEtw2cOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7nEtwmcOEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7nEtwGcOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nEtvWcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ResourceLineReader%5Bjcu%5Ename=ResourceLineReader.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nEtvmcOEdySpMFhuX87fw" points="[-14, 3095, 14723, -11456]$[-14751, 4682, -14, -9869]"/>
</edges>
<edges xmi:id="_7nOexWcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7mxy0mcOEdySpMFhuX87fw">
<children xmi:id="_7nOeyGcOEdySpMFhuX87fw" type="FromMultiplicityLabel">
<children xmi:id="_7nOeymcOEdySpMFhuX87fw" type="FromMultiplicity"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOeyWcOEdySpMFhuX87fw" y="396"/>
</children>
<children xmi:id="_7nOey2cOEdySpMFhuX87fw" type="FromRoleLabel">
<children xmi:id="_7nOezWcOEdySpMFhuX87fw" type="FromRole"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOezGcOEdySpMFhuX87fw" y="-397"/>
</children>
<children xmi:id="_7nOezmcOEdySpMFhuX87fw" type="associationTypeLabel">
<children xmi:id="_7nOe0GcOEdySpMFhuX87fw" type="associationTypeCompartment"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOez2cOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nOexmcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Property" href="mmi:///#jfield%5Ename=recordSeparatorPolicy%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Property"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nOex2cOEdySpMFhuX87fw" points="[-14, 3095, -5769, -11456]$[5754, 4682, -1, -9869]"/>
</edges>
<edges xmi:id="_7nOe3WcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7mxyxWcOEdySpMFhuX87fw">
<children xmi:id="_7nOe4GcOEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_7nOe4mcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7nOe5GcOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7nOe42cOEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7nOe4WcOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nOe3mcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=LineTokenizer%5Bjcu%5Ename=LineTokenizer.java%5Bjpack%5Ename=org.springframework.batch.io.file.support.transform%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nOe32cOEdySpMFhuX87fw" points="[-14, 3095, -1, -11456]$[-14, 4682, -1, -9869]"/>
</edges>
<edges xmi:id="_7nOe7WcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7mxy0mcOEdySpMFhuX87fw">
<children xmi:id="_7nOe8GcOEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_7nOe8mcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7nOe9GcOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7nOe82cOEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7nOe8WcOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nOe7mcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=RecordSeparatorPolicy%5Bjcu%5Ename=RecordSeparatorPolicy.java%5Bjpack%5Ename=org.springframework.batch.io.file.support.separator%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nOe72cOEdySpMFhuX87fw" points="[-14, 3095, -5769, -11456]$[5754, 4682, -1, -9869]"/>
</edges>
<edges xmi:id="_7nOe9WcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7mxyxWcOEdySpMFhuX87fw">
<children xmi:id="_7nOe-GcOEdySpMFhuX87fw" type="FromMultiplicityLabel">
<children xmi:id="_7nOe-mcOEdySpMFhuX87fw" type="FromMultiplicity"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOe-WcOEdySpMFhuX87fw" y="396"/>
</children>
<children xmi:id="_7nOe-2cOEdySpMFhuX87fw" type="FromRoleLabel">
<children xmi:id="_7nOe_WcOEdySpMFhuX87fw" type="FromRole"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOe_GcOEdySpMFhuX87fw" y="-397"/>
</children>
<children xmi:id="_7nOe_mcOEdySpMFhuX87fw" type="associationTypeLabel">
<children xmi:id="_7nOfAGcOEdySpMFhuX87fw" type="associationTypeCompartment"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_7nOe_2cOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nOe9mcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Property" href="mmi:///#jfield%5Ename=tokenizer%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Property"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nOe92cOEdySpMFhuX87fw" points="[-14, 3095, -1, -11456]$[-14, 4682, -1, -9869]"/>
</edges>
<edges xmi:id="_7nOfAWcOEdySpMFhuX87fw" source="_9kcgsGcLEdySpMFhuX87fw" target="_7moB7mcOEdySpMFhuX87fw">
<children xmi:id="_7nOfBGcOEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_7nOfBmcOEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7nOfCGcOEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7nOfB2cOEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7nOfBWcOEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7nOfAmcOEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=FieldSet%5Bjcu%5Ename=FieldSet.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7nOfA2cOEdySpMFhuX87fw" points="[-14, 3095, 6323, -11456]$[-6337, 4682, 0, -9869]"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,282 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--xtools2_universal_type_manager-->
<?com.ibm.xtools.emf.core.signature <signature id="com.ibm.xtools.mmi.ui.signatures.diagram" version="7.0.0"><feature description="" name="Rational Modeling Platform (com.ibm.xtools.rmp)" url="" version="7.0.0"/></signature>?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.0/notation" xmlns:uml="http://www.eclipse.org/uml2/2.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.2/Umlnotation" xmi:id="_nppmkGYJEdySpMFhuX87fw" type="Class" name="io-design.dnx">
<children xmi:id="_nvd6sGYJEdySpMFhuX87fw">
<children xmi:id="_nvd6s2YJEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_nvd6tGYJEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_nvd6tWYJEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_nvd6tmYJEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_nvd6t2YJEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_nvd6uGYJEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_nvd6uWYJEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_nvd6umYJEdySpMFhuX87fw"/>
</children>
<children xmi:id="_nvd6u2YJEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_nvd6vGYJEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_nvd6sWYJEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_nvd6smYJEdySpMFhuX87fw" x="317" y="1902"/>
</children>
<children xmi:id="_nvd6vWYJEdySpMFhuX87fw">
<children xmi:id="_nvd6wGYJEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_nvd6wWYJEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_nvd6wmYJEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_nvd6w2YJEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_nvd6xGYJEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_nvd6xWYJEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_nvd6xmYJEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_nvd6x2YJEdySpMFhuX87fw"/>
</children>
<children xmi:id="_nvd6yGYJEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_nvd6yWYJEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_nvd6vmYJEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=OutputSource%5Bjcu%5Ename=OutputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_nvd6v2YJEdySpMFhuX87fw" x="19020" y="1902"/>
</children>
<children xmi:id="_7eV5EGYJEdySpMFhuX87fw">
<children xmi:id="_7eV5E2YJEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_7eV5FGYJEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_7eV5FWYJEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7eV5FmYJEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_7eV5F2YJEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_7eV5GGYJEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_7eV5GWYJEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7eV5GmYJEdySpMFhuX87fw"/>
</children>
<children xmi:id="_7eV5G2YJEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_7eV5HGYJEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_7eV5EWYJEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=ResourceLifecycle%5Bjcu%5Ename=ResourceLifecycle.java%5Bjpack%5Ename=org.springframework.batch.item%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7eV5EmYJEdySpMFhuX87fw" x="9827" y="1268"/>
</children>
<children xmi:id="_DlV1aWYKEdySpMFhuX87fw">
<children xmi:id="_DlV1bGYKEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_DlV1bWYKEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_DlV1bmYKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_DlV1b2YKEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_DlV1cGYKEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_DlV1cWYKEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_DlV1cmYKEdySpMFhuX87fw"/>
</children>
<children xmi:id="_DlV1c2YKEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_DlV1dGYKEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_DlV1amYKEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XmlInputSource%5Bjcu%5Ename=XmlInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.xml%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_DlV1a2YKEdySpMFhuX87fw" x="8876" y="5706"/>
</children>
<children xmi:id="_G5-18WYKEdySpMFhuX87fw">
<children xmi:id="_G5-19GYKEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_G5-19WYKEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_G5-19mYKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_G5-192YKEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_G5-1-GYKEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_G5-1-WYKEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_G5-1-mYKEdySpMFhuX87fw"/>
</children>
<children xmi:id="_G5-1-2YKEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_G6Im8GYKEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_G5-18mYKEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XmlOutputSource%5Bjcu%5Ename=XmlOutputSource.java%5Bjpack%5Ename=org.springframework.batch.io.xml%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G5-182YKEdySpMFhuX87fw" x="19971" y="6657"/>
</children>
<children xmi:id="_bgvekGYKEdySpMFhuX87fw">
<children xmi:id="_bgvek2YKEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_bgvelGYKEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_bgvelWYKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_bgvelmYKEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_bgvel2YKEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_bgvemGYKEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_bgvemWYKEdySpMFhuX87fw"/>
</children>
<children xmi:id="_bgvemmYKEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_bgvem2YKEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_bgvekWYKEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=SqlCursorInputSource%5Bjcu%5Ename=SqlCursorInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.sql%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_bgvekmYKEdySpMFhuX87fw" x="-3170" y="5389"/>
</children>
<children xmi:id="_UeKXNmYLEdySpMFhuX87fw">
<children xmi:id="_UeKXOWYLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_UeKXOmYLEdySpMFhuX87fw" width="530" height="530"/>
</children>
<children xmi:id="_UeKXO2YLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_UeKXPGYLEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_UeKXPWYLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_UeKXPmYLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_UeKXP2YLEdySpMFhuX87fw" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_UeKXQGYLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_UeKXQWYLEdySpMFhuX87fw" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_UeKXQmYLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_UeKXN2YLEdySpMFhuX87fw" showStereotype="Label" useClassifierShape="true"/>
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Interface"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_UeKXOGYLEdySpMFhuX87fw" x="2853" y="5389"/>
</children>
<children xmi:id="_fpausGYLEdySpMFhuX87fw">
<children xmi:id="_fpaus2YLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_fpautGYLEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_fpautWYLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_fpautmYLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_fpaut2YLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_fpauuGYLEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_fpauuWYLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_fpauumYLEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_fpauu2YLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_fpausWYLEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_fpausmYLEdySpMFhuX87fw" x="2536" y="8084"/>
</children>
<children xmi:id="_gPQmsmYLEdySpMFhuX87fw">
<children xmi:id="_gPQmtWYLEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_gPQmtmYLEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_gPQmt2YLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_gPQmuGYLEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_gPQmuWYLEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_gPQmumYLEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_gPQmu2YLEdySpMFhuX87fw"/>
</children>
<children xmi:id="_gPQmvGYLEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_gPQmvWYLEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_gPQms2YLEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_gPQmtGYLEdySpMFhuX87fw" x="2536" y="10461"/>
</children>
<children xmi:id="_BFEmRWYMEdySpMFhuX87fw">
<children xmi:id="_BFOXIGYMEdySpMFhuX87fw" type="ImageCompartment">
<layoutConstraint xmi:type="notation:Size" xmi:id="_BFOXIWYMEdySpMFhuX87fw" width="1320" height="1320"/>
</children>
<children xmi:id="_BFOXImYMEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_BFOXI2YMEdySpMFhuX87fw" type="Name"/>
<children xmi:id="_BFOXJGYMEdySpMFhuX87fw" type="Parent"/>
<children xmi:id="_BFOXJWYMEdySpMFhuX87fw" visible="false" type="AttributeCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_BFOXJmYMEdySpMFhuX87fw"/>
</children>
<children xmi:id="_BFOXJ2YMEdySpMFhuX87fw" visible="false" type="OperationCompartment">
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_BFOXKGYMEdySpMFhuX87fw"/>
</children>
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_BFEmRmYMEdySpMFhuX87fw" showStereotype="Label"/>
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=FlatFileOutputSource%5Bjcu%5Ename=FlatFileOutputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D$uml.Class"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_BFEmR2YMEdySpMFhuX87fw" x="14582" y="6657"/>
</children>
<styles xmi:type="umlnotation:UMLDiagramStyle" xmi:id="_nppmkWYJEdySpMFhuX87fw"/>
<element xsi:nil="true"/>
<edges xmi:id="_7fFf8GYJEdySpMFhuX87fw" source="_nvd6sGYJEdySpMFhuX87fw" target="_7eV5EGYJEdySpMFhuX87fw">
<children xmi:id="_7fFf82YJEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_7fOp4GYJEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7fOp4WYJEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7fFf9GYJEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7fFf8WYJEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ResourceLifecycle%5Bjcu%5Ename=ResourceLifecycle.java%5Bjpack%5Ename=org.springframework.batch.item%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7fFf8mYJEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_7fOp4mYJEdySpMFhuX87fw" source="_nvd6vWYJEdySpMFhuX87fw" target="_7eV5EGYJEdySpMFhuX87fw">
<children xmi:id="_7fOp5WYJEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_7fOp52YJEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_7fOp6GYJEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_7fOp5mYJEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_7fOp42YJEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=OutputSource%5Bjcu%5Ename=OutputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ResourceLifecycle%5Bjcu%5Ename=ResourceLifecycle.java%5Bjpack%5Ename=org.springframework.batch.item%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7fOp5GYJEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_DoU3-mYKEdySpMFhuX87fw" source="_DlV1aWYKEdySpMFhuX87fw" target="_nvd6sGYJEdySpMFhuX87fw">
<children xmi:id="_Doeo8GYKEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_Doeo8mYKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_Doeo82YKEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Doeo8WYKEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_DoU3-2YKEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=XmlInputSource%5Bjcu%5Ename=XmlInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.xml%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_DoU3_GYKEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_G894jGYKEdySpMFhuX87fw" source="_G5-18WYKEdySpMFhuX87fw" target="_nvd6vWYJEdySpMFhuX87fw">
<children xmi:id="_G894j2YKEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_G894kWYKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_G894kmYKEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G894kGYKEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_G894jWYKEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=XmlOutputSource%5Bjcu%5Ename=XmlOutputSource.java%5Bjpack%5Ename=org.springframework.batch.io.xml%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=OutputSource%5Bjcu%5Ename=OutputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_G894jmYKEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_bihnRmYKEdySpMFhuX87fw" source="_bgvekGYKEdySpMFhuX87fw" target="_nvd6sGYJEdySpMFhuX87fw">
<children xmi:id="_bihnSWYKEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_bihnS2YKEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_bihnTGYKEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_bihnSmYKEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_bihnR2YKEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=SqlCursorInputSource%5Bjcu%5Ename=SqlCursorInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.sql%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_bihnSGYKEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_UeThImYLEdySpMFhuX87fw" source="_UeKXNmYLEdySpMFhuX87fw" target="_nvd6sGYJEdySpMFhuX87fw">
<children xmi:id="_UeThJWYLEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_UeThJ2YLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_UeThKGYLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_UeThJmYLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_UeThI2YLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=InputSource%5Bjcu%5Ename=InputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_UeThJGYLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_fqAkkGYLEdySpMFhuX87fw" source="_fpausGYLEdySpMFhuX87fw" target="_UeKXNmYLEdySpMFhuX87fw">
<children xmi:id="_fqAkk2YLEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_fqAklWYLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_fqAklmYLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_fqAklGYLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_fqAkkWYLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=FieldSetInputSource%5Bjcu%5Ename=FieldSetInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_fqAkkmYLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_gQ5ld2YLEdySpMFhuX87fw" source="_gPQmsmYLEdySpMFhuX87fw" target="_fpausGYLEdySpMFhuX87fw">
<children xmi:id="_gQ5lemYLEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_gQ5lfGYLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_gQ5lfWYLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_gQ5le2YLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_gQ5leGYLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Generalization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_gQ5leWYLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_gQ5lfmYLEdySpMFhuX87fw" source="_gPQmsmYLEdySpMFhuX87fw" target="_fpausGYLEdySpMFhuX87fw">
<children xmi:id="_gQ5lgWYLEdySpMFhuX87fw" type="KindLabel">
<children xmi:id="_gQ5lg2YLEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_gQ5lhWYLEdySpMFhuX87fw" type="Kind"/>
<children xmi:id="_gQ5lhGYLEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_gQ5lgmYLEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_gQ5lf2YLEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=DefaultFlatFileInputSource%5Bjcu%5Ename=DefaultFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=SimpleFlatFileInputSource%5Bjcu%5Ename=SimpleFlatFileInputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.Usage"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_gQ5lgGYLEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
<edges xmi:id="_BIWjtmYMEdySpMFhuX87fw" source="_BFEmRWYMEdySpMFhuX87fw" target="_nvd6vWYJEdySpMFhuX87fw">
<children xmi:id="_BIWjuWYMEdySpMFhuX87fw" type="NameLabel">
<children xmi:id="_BIWju2YMEdySpMFhuX87fw" type="Stereotype"/>
<children xmi:id="_BIWjvGYMEdySpMFhuX87fw" type="Name"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_BIWjumYMEdySpMFhuX87fw" y="-186"/>
</children>
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_BIWjt2YMEdySpMFhuX87fw" showStereotype="Text"/>
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=FlatFileOutputSource%5Bjcu%5Ename=FlatFileOutputSource.java%5Bjpack%5Ename=org.springframework.batch.io.file.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=OutputSource%5Bjcu%5Ename=OutputSource.java%5Bjpack%5Ename=org.springframework.batch.io%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=spring-batch-infrastructure%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_BIWjuGYMEdySpMFhuX87fw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,656 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="The Nature of Batch Applications">
<title>The Nature of Batch Applications</title>
<section>
<title id="s.0">Batch Application Overview</title>
<para>The Application layer is anything built on top of the spring batch framework.
Many enterprises solutions are composed of composite applications, meaning online web
applications, SOA Enabled Services, Enterprise Application Integration, and Batch. Despite
the ideal of zero latency applications and the interconnected enterprise many interfaces
still define the exchange of information through flat files. Increasingly these files
are provided in an XML format. The chapter will provide a more in depth coverage of
batch solution space and the kinds of problems that spring batch may provide solutions
for high volume processing.</para>
</section>
<section>
<title id="s.1">Batch Processing Strategies</title>
<para>To help design and implement batch systems, basic batch
application building blocks and patterns should be provided to the
designers and programmers in form of sample structure charts and
code shells. When starting to design a batch job, the business
logic should be decomposed into a series of steps which can be
implemented using the following standard building blocks:</para>
<itemizedlist>
<listitem>
<para>Conversion Applications: For each type of file supplied
by or generated to an external system, a conversion application
will need to be created to convert the transaction records
supplied into a standard format required for processing. This
type of batch application can partly or entirely consist of
translation utility modules (see Basic Batch Services).</para>
</listitem>
<listitem>
<para>Validation Applications: Validation applications ensure
that all input/output records are correct and consistent.
Validation is typically based on file headers and trailers,
checksums and validation algorithms as well as record level
cross-checks.</para>
</listitem>
<listitem>
<para>Extract Applications: An application that reads a set of
records from a database or input file, selects records based on
predefined rules, and writes the records to an output
file.</para>
</listitem>
<listitem>
<para>Extract/Update Applications: An application that reads
records from a database or an input file, and makes changes to
a database or an output file driven by the data found in each
input record.</para>
</listitem>
<listitem>
<para>Processing and Updating Applications: An application that
performs processing on input transactions from an extract or a
validation application. The processing will usually involve
reading a database to obtain data required for processing,
potentially updating the database and creating records for
output processing.</para>
</listitem>
<listitem>
<para>Output/Format Applications: Applications reading an input
file, restructures data from this record according to a
standard format, and produces an output file for printing or
transmission to another program or system.</para>
</listitem>
</itemizedlist>
<para><emphasis role="bold">Pre-processing
Capabilities</emphasis></para>
<para>Additionally a basic application shell should be provided for
business logic that cannot be built using the previously mentioned
building blocks.</para>
<para>In addition to the main building blocks, each application may
use one or more of standard utility steps, such as:</para>
<itemizedlist>
<listitem>
<para>Sort - A Program that reads an input file and produces an
output file where records have been re-sequenced according to a
sort key field in the records. Sorts are usually performed by
standard system utilities.</para>
</listitem>
<listitem>
<para>Split - A program that reads a single input file, and
writes each record to one of several output files based on a
field value. Splits can be tailored or performed by
parameter-driven standard system utilities.</para>
</listitem>
<listitem>
<para>Merge - A program that reads records from multiple input
files and produces one output file with combined data from the
input files. Merges can be tailored or performed by
parameter-driven standard system utilities.</para>
</listitem>
</itemizedlist>
<para>Batch applications can additionally be categorized by their
input source:</para>
<itemizedlist>
<listitem>
<para>Database-driven applications are driven by rows or values
retrieved from the database.</para>
</listitem>
<listitem>
<para>File-driven applications are driven by records or values
retrieved from a file</para>
</listitem>
</itemizedlist>
<para>The foundation of any batch system is the processing
strategy. Factors affecting the selection of the strategy include
estimated batch system volume, concurrency with on-line or with
another batch systems, available batch windows etc. Also with more
enterprises wanting to be up and running 24x7, it is more challenging to
establish batch windows.</para>
<para>Typical processing options for batch are:</para>
<itemizedlist>
<listitem>
<para>Normal processing in a batch window during off-line</para>
</listitem>
<listitem>
<para>Concurrent batch / on-line processing</para>
</listitem>
<listitem>
<para>Parallel processing of many different batch runs or jobs
at the same time</para>
</listitem>
<listitem>
<para>Streaming i.e. processing of many instances of the same
job at the same time</para>
</listitem>
<listitem>
<para>A combination of these</para>
</listitem>
</itemizedlist>
<para>The order in the list above reflects the implementation
complexity, processing in a batch window being the easiest and
streaming the most complex to implement.</para>
<para>Some or all of these options may be supported by a commercial
scheduler.</para>
<para>In the following section these processing options will be
discussed in more detail. It is important to notice that the commit
and locking strategy adopted by batch processes will be dependent
on the type of processing performed and as a rule of thumb, the
on-line locking should use the same principles. Therefore a batch
architecture cannot be simply an afterthought when designing an
overall architecture.</para>
<para>The locking strategy can use only normal database locks, or
an additional custom locking service can be implemented in the
architecture. The locking service would track database locking (for
example by storing the necessary information in a dedicated
db-table) and give or deny permissions to the application programs
requesting a db operation. Retry logic could also be implemented by
this architecture to avoid aborting a batch job in case of a lock
situation.</para>
<para><emphasis role="bold">1. Normal processing in a batch
window</emphasis> For simple batch processes running in a separate
batch window, where the data being updated is not required by
on-line users or other batch processes, concurrency is not an issue
and a single commit can be done at the end of the batch run.</para>
<para>In most cases a more robust approach is more appropriate. A
thing to keep in mind is that batch systems have a tendency to grow
as time goes by, both in terms of complexity and the data volumes
they will handle. If no locking strategy is in place and the system
still relies on a single commit point, modifying the batch programs
can be painful. Therefore, even with the simplest batch systems,
consider the need for commit logic depicted in the
[Restart/Recovery section|Restart &amp; Recovery] as well as the
information concerning the more complex cases below.</para>
<para><emphasis role="bold">2. Concurrent batch / on-line
processing</emphasis> Batch applications processing data that can
simultaneously be updated by on-line users, should not lock any
data (either in the database or in files) which could be required
by on-line users for more than a few seconds. Also updates should
be committed to the database at the end of every transaction or what's
referred to as a commit interval of size=1. This minimizes the portion
of data that is unavailable to other processes and the elapsed time the
data is unavailable.</para>
<para><emphasis role="bold">2. Concurrent batch / on-line
processing</emphasis> Batch applications processing data that can
simultaneously be updated by on-line users, should not lock any
data (either in the database or in files) which could be required
by on-line users for more than a few seconds. Also updates should
be committed to the database at the end of every transaction or what's
referred to as a commit interval of size=1. This minimizes the portion
of data that is unavailable to other processes and the elapsed time the
data is unavailable.</para>
<para>Another option to minimize physical locking is to have a
logical row-level locking implemented using either an Optimistic
Locking Pattern or a Pessimistic Locking Pattern.</para>
<itemizedlist>
<listitem>
<para>Optimistic locking assumes a low likelihood of record
contention. It typically means inserting a timestamp column in
each database table used concurrently by both batch and on-line
processing. When an application fetches a row for processing,
it also fetches the timestamp. As the application then tries to
update the processed row, the update uses the original
timestamp in the WHERE clause. If the timestamp matches, the
data and the timestamp will be updated successfully. If the
timestamp does not match, this indicates that another
application has updated the same row between the fetch and the
update attempt and therefore the update cannot be
performed.</para>
</listitem>
<listitem>
<para>Pessimistic locking is any locking strategy that assumes
there is a high likelihood of record contention and therefore
either a physical or logical lock needs to be obtained at
retrieval time. One type of pessimistic logical locking uses a
dedicated lock-column in the database table. When an
application retrieves the row for update, it sets a flag in the
lock column. With the flag in place, other applications
attempting to retrieve the same row will logically fail. When
the application that set the flag updates the row, it also
clears the flag, enabling the row to be retrieved by other
applications. Please note, that the integrity of data must be
maintained also between the initial fetch and the setting of
the flag, for example by using db locks (e.g.,SELECT FOR
UPDATE). Note also that this method suffers from the same
downside as physical locking except that it is somewhat easier
to manage building a time-out mechanism that will get the lock
released if the user goes to lunch while the record is
locked.</para>
</listitem>
</itemizedlist>
<para>These patterns are not necessarily suitable for batch
processing, but they might be used for concurrent batch and on-line
processing for example in cases where the database doesn&apos;t
support row-level locking. As a general rule, optimistic locking is
more suitable for on-line applications, while pessimistic locking
is more suitable for batch applications. Whenever logical locking
is used, the same scheme must be used for all applications
accessing data entities protected by logical locks.</para>
<para>Note that both of these solutions only address locking a
single record. Often we may need to lock a logically related group
of records. With physical locks, you have to manage these very
carefully in order to avoid potential deadlocks. With logical
locks, it is usually best to build a logical lock manager that
understands the logical record groups you want to protect and can
ensure that locks are coherent and non-deadlocking. This logical
lock manager usually uses its own tables for lock management,
contention reporting, time-out mechanism, etc.</para>
<para><emphasis role="bold">3. Parallel Processing</emphasis>
Parallel processing allows multiple batch runs / jobs to run in
parallel to minimize the total elapsed batch processing time. This
is not a problem as long as the jobs are not sharing the same
files, db-tables or index spaces. If they do, this service should
be implemented using partitioned data. Another option is to build
an architecture module for maintaining interdependencies using a
control table. A control table should contain a row for each shared
resource and whether it is in use by an application or not. The
batch architecture (Control Program Tasklet) or the application in a
parallel job would then retrieve information from that table to
determine if it can get access to the resource it needs or
not.</para>
<para>If the data access is not a problem, parallel processing can
be implemented in a mainframe environment using parallel job
classes, in order to ensure adequate CPU time for all the
processes. In an environment other than the mainframe, a similar
solution can be put in place with for example threads. The solution
has to be robust enough to ensure time slices for all the running
processes.</para>
<para>Other key issues in parallel processing include load
balancing and the availability of general system resources such as
files, database buffer pools etc. Also note that the control table
itself can easily become a critical resource.</para>
<para><emphasis role="bold">4. Partitioning</emphasis> Using
partitioning allows multiple versions of large batch applications
to run concurrently. The purpose of this is to reduce the elapsed
time required to process long batch jobs. Processes which can be
successfully partitioned are those where the input file can be
split and/or the main database tables partitioned to allow the
application to run against different sets of data.</para>
<para>In addition, processes which are partitioned must be designed
to only process their assigned data set. A partitioning
architecture has to be closely tied to the database design and the
database partitioning strategy. Please note, that the database
partitioning doesn&apos;t necessarily mean physical partitioning of
the database, although in most cases this is advisable. The
following picture illustrates the partitioning
approach:!app_style_batch_processing.png|align=center!</para>
<para>The architecture should be flexible enough to allow dynamic
configuration of the number of partitions. Both automatic and user
controlled configuration should be considered. Automatic
configuration may be based on parameters such as the input file
size and/or the number of input records.</para>
<para><emphasis role="bold">4.1 Streaming Approaches</emphasis> The
following lists some of the possible streaming approaches.
Selecting a streaming approach has to be done on a case-by-case
basis.</para>
<para><emphasis>1. Fixed and Even Break-Up of Record
Set</emphasis></para>
<para>This involves breaking the input record set into an even
number of portions (e.g. 10, where each portion will have exactly
1/10th of the entire record set). Each portion is then processed by
one instance of the batch/extract application.</para>
<para>In order to use this approach, preprocessing will be required
to split the recordset up. The result of this split will be a lower
and upper bound placement number which can be used as input to the
batch/extract application in order to restrict its processing to
its portion alone.</para>
<para>Preprocessing could be a large overhead as it has to
calculate and determine the bounds of each portion of the record
set.</para>
<para><emphasis>2. Breakup by a Key Column</emphasis></para>
<para>This involves breaking up the input record set by a key
column such as a location code, and assigning data from each key to
a batch instance. In order to achieve this, column values can
either be</para>
<para><emphasis>3. Assigned to a batch instance via a streaming
table (see below for details).</emphasis></para>
<para><emphasis>4. Assigned to a batch instance by a portion of the
value (e.g. values 0000-0999, 1000 - 1999, etc.)</emphasis></para>
<para>Under option 1, addition of new values will mean a manual
reconfiguration of the batch/extract to ensure that the new value
is added to a particular instance.</para>
<para>Under option 2, this will ensure that all values are covered
via an instance of the batch job. However, the number of values
processed by one instance is dependent on the distribution of
column values (i.e. there may be a large number of locations in the
0000-0999 range, and few in the 1000-1999 range). Under this
option, the data range should be designed with streaming in
mind.</para>
<para>Under both options, the optimal even distribution of records
to batch instances cannot be realized. There is no dynamic
configuration of the number of batch instances used.</para>
<para><emphasis>5. Breakup by Views</emphasis></para>
<para>This approach is basically breakup by a key column, but on
the database level. It involves breaking up the recordset into
views. These views will be used by each instance of the batch
application during its processing. The breakup will be done by
grouping the data.</para>
<para>With this option, each instance of a batch application will
have to be configured to hit a particular view (instead of the
master table). Also, with the addition of new data values, this new
group of data will have to be included into a view. There is no
dynamic configuration capability, as a change in the number of
instances will result in a change to the views.</para>
<para><emphasis>6. Addition of a Processing
Indicator</emphasis></para>
<para>This involves the addition of a new column to the input
table, which acts as an indicator. As a preprocessing step, all
indicators would be marked to non-processed. During the record
fetch stage of the batch application, records are read on the
condition that that record is marked non-processed, and once they
are read (with lock), they are marked processing. When that record
is completed, the indicator is updated to either complete or error.
Many instances of a batch application can be started without any
changes, as the additional column ensures that a record is only
processed once.</para>
<para>With this option, I/O on the table increased dynamically. In
the case of a updating batch application, this impact is reduced,
as a write will have to occur anyway.</para>
<para><emphasis>7. Extract Table to a Flat File</emphasis></para>
<para>This involves the extraction of the table into a file. This
file can then be split into multiple segments and used as input to
the batch instances.</para>
<para>With this option, the additional overhead of extracting the
table into a file, and splitting it, may cancel out the effect of
multi-streaming. Dynamic configuration can be achieved via changing
the file splitting script.</para>
<para><emphasis>8. Use of a Hashing Column</emphasis></para>
<para>This scheme involves the addition of a hash column
(key/index) to the database tables used to retrieve the driver
record. This hash column will have an indicator to determine which
instance of the batch application will process this particular row.
For example, if there are three batch instances to be started, then
an indicator of &apos;A&apos; will mark that row for processing by
instance 1, an indicator of &apos;B&apos; will mark that row for
processing by instance 2, etc.</para>
<para>The procedure used to retrieve the records would then have an
additional WHERE clause to select all rows marked by a particular
indicator. The inserts in this table would involve the addition of
the marker field, which would be defaulted to one of the instances
(e.g. &apos;A&apos;).</para>
<para>A simple batch application would be used to update the
indicators such as to redistribute the load between the different
instances. When a sufficiently large number of new rows have been
added, this batch can be run (anytime, except in the batch window)
to redistribute the new rows to other instances.</para>
<para>Additional instances of the batch application only require
the running of the batch application as above to redistribute the
indicators to cater for a new number of instances.</para>
<para>4.2 Database and Application design Principles</para>
<para>An architecture that supports multi-streamed applications
which run against partitioned database tables using the key column
approach, should include a central streaming repository for storing
streaming parameters. This provides flexibility and ensures
maintainability. The repository will generally consist of a single
table known as the streaming table.</para>
<para>Information stored in the streaming table will be static and
in general should be maintained by the DBA. The table should
consist of one row of information for each stream of a
multi-streamed application. The table should have a similar layout
to the following table:</para>
<para><anchor id="a.center"/>center || Streaming Table || | Program
ID Code Stream Number (Logical ID of the stream) Low Value of the
db key column for this stream High Value of the db key column for
this stream | center</para>
<para>On program start-up the program id and stream number should
be passed to the application from the architecture (Control
Processing Tasklet). These variables are used to read the streaming
table, to determine what range of data the application is to
process (if a key column approach is used). In addition the stream
number must be used throughout the processing to:</para>
<itemizedlist>
<listitem>
<para>Add to the output files/database updates in order for the
merge process to work properly</para>
</listitem>
<listitem>
<para>Report normal processing to the batch log and any errors
that occur during execution to the architecture error
handler</para>
</listitem>
</itemizedlist>
<para>4.3 Minimizing Deadlocks When applications run in parallel or
streamed, contention in database resources and deadlocks may occur.
It is critical that the database design team eliminates potential
contention situations as far as possible as part of the database
design.</para>
<para>Also ensure that the database index tables are designed with
deadlock prevention and performance in mind.</para>
<para>Deadlocks or hot spots often occur in administration or
architecture tables such as log tables, control tables, lock tables
etc.. The implications of these should be taken into account as
well. A realistic stress test is crucial for identifying the
possible bottlenecks in the architecture.</para>
<para>To minimize the impact of conflicts on data, the architecture
should provide services such as wait-and-retry intervals when
attaching to a database or when encountering a deadlock. This means
a built-in mechanism to react to certain database return codes and
instead of issuing an immediate error handling, waiting a
predetermined amount of time and retrying the database
operation.</para>
<para>4.4 Parameter Passing and Validation</para>
<para>The streaming architecture should be relatively transparent
to application developers. The architecture should perform all
tasks associated with running the application in a streamed mode
i.e.</para>
<itemizedlist>
<listitem>
<para>Retrieve streaming parameters before application
start-up</para>
</listitem>
<listitem>
<para>Validate streaming parameters before application
start-up</para>
</listitem>
<listitem>
<para>Pass parameters to application at start-up</para>
</listitem>
</itemizedlist>
<para>The validation should include checks to ensure that:</para>
<itemizedlist>
<listitem>
<para>the application has sufficient streams to cover the whole
data range</para>
</listitem>
<listitem>
<para>there are no gaps between streams</para>
</listitem>
</itemizedlist>
<para>If the database is partitioned, some additional validation
may be necessary to ensure that a single stream does not span
database partitions.</para>
<para>Also the architecture should take into consideration the
consolidation of streams. Key questions include:</para>
<itemizedlist>
<listitem>
<para>Must all the streams be finished before going into the
next job step?</para>
</listitem>
<listitem>
<para>What happens if one of the streams aborts?</para>
</listitem>
</itemizedlist>
</section>
<section>
<title id="bps.2">Batch Job Type Specific Concerns</title>
<para>Batch Jobs Types (e.g. conversion, pdf generation, report generation, high volume print, etc.) require different
technologies in the solution space. For example, conversion may require additional XML technologies, Adobe or iText for
PDF generation, different reporting options for report generation, etc. It is often helpful to isolate batch jobs at a
minimum by job type so that required dependencies for batch job types don't pollute other application styles. It is also
key to leaving the application decoupled by style and by execution environment allowing maximum flexibility at deployment
time.
</para>
</section>
</chapter>

View File

@@ -0,0 +1,546 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="Container Architecture Overview" lang="en">
<title>Container Architecture Overview</title>
<section>
<title>Introduction</title>
<para></para>
</section>
<section>
<title id="s.1">Simple Container Architecture Overview</title>
<para></para>
<section>
<title id="s.1.1">Introduction</title>
<para>This chapter covers the overall spring batch architecture.
The Spring Container Archtiecture is made up of five logical
layers; 1) the Batch Application, 2) the Batch Application Layer,
3) the batch core layer, and 4) the batch infrastucture
layer.</para>
<informaltable colsep="1" frame="all" rowsep="1">
<tgroup cols="3">
<colspec align="center"/>
<colspec align="center"/>
<colspec align="left"/>
<tbody>
<row><entry><para>Provided
By</para></entry><entry><para>Layer</para></entry><entry><para>Description</para></entry></row>
<row><entry><para>Application
Developer</para></entry><entry><para>Batch
Application</para></entry><entry><para>This is where the
application developer writes their batch jobs and
tasklets.</para></entry></row>
<row><entry><para>Spring Batch Execution
Container</para></entry><entry><para>Container Application
Layer</para></entry><entry><para>Allows for extending and
overwriting of the batch support layer for custom
requirements. Facilities implemented in this layer could
migrate down to Batch Support Layer. This is also the layer
to add the project specific jars required by job types
(e.g. reporting jars like Crystal, Brio, etc, form
generation jars like Central Pro or Adobe,
etc).</para></entry></row>
<row><entry><para>Spring Batch Execution
Container</para></entry><entry><para>Container Support
Layer</para></entry><entry><para>Provides default
implementations of batch core services including I/O,
Restart, Partitioning, Statistics, and
configurations</para></entry></row>
<row><entry><para>Spring Batch Execution
Container</para></entry><entry><para>Container Core
Layer</para></entry><entry><para>Enables configuration,
Common Services &amp; Interfaces,
management</para></entry></row>
<row><entry><para>Spring Batch
Infrastructure</para></entry><entry><para>Batch-Infrastructure</para></entry><entry><para>Provides
IO support, Batch style transactions, advanced exception
handling, batch-template, batch-retry</para></entry></row>
</tbody>
</tgroup>
</informaltable>
<variablelist>
<varlistentry>
<term>Figure 2.0</term>
<listitem>
<para>- Batch Architecture Layers</para>
<para>The batch architecture is modeled after a container
architecture, meaning that there are managed resources
essential to high performance batch architectures that are
configured through a spring context. The following sect1s
will provide a quick review of each layer and their role in
the batch architecture.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section>
<title id="s.1.2">Batch Applications</title>
<para></para>
</section>
<section>
<title id="s.1.3">Container Application Layer</title>
<para></para>
</section>
<section>
<title id="s.1.4">Container Support Layer</title>
<para>The batch support layer provides default implementations
for all interfaces, interceptors, advice and other core batch
services. Figure 2.3.1 illustrates the following logical
packages. !Batch Support.png! Although physically they break out
into many more than depicted, logically you can think of the
groupings in the following manner: * I/O Support packages *
Restart Support * Lifecycle Support packages * DAO support
layer</para>
<itemizedlist>
<listitem>
<para>I/O Support Packages</para>
<para>The I/O related packages are currently the richest
packages in the batch architecture. They are modeled after
Spring Patterns of Operations and Templates. For example,
you&apos;ll see FlatFileInputOperations accompanied with a
FlatFileInputTemplate. The FlatFileInputTemplate is wired up
with a File Descriptor, which contains a Record Descriptor
along with various other properties. With the File and Record
Descriptors the InputTemplate supports a callback method that
allows for the mapping of a record into an object. This
support applies to fixed length records, delimited records
and XML records. To further simplify this a
DefaultFlatFileDataProvider is supplied an input template,
which contains the field and record descriptions, along with
a line mapper that knows how to map the line to an object.
The next() operation on a record simply needs to
readAndMap(lineMapper) a record. This pattern is used over
again for XML and SQL input for simple mapping of input
records to objects.</para>
<para>In addition to declarative descriptions of the records
that can be re-used by multiple batch jobs, the I/O
facilities also support configurable validation strategies.
The two currently supported are Apache Commons Validator and
Spring&apos;s VALang.</para>
</listitem>
<listitem>
<para>Restart Support</para>
<para>The Restart Support provides implementations for a few
common restart strategies that will be discussed further in
the respective sect1. The following are provided
out-of-the-box: * IDList Restart Strategy - a strategy that
supports a batch application where the application does not
have a &quot;process&quot; flag and needs the batch
architecture to track which records have been processed. This
is not the ideal scenario. * Last Processed Restart Strategy
- when the record can be identified through a where and order
by only the last record(s) processed needs to be saved for
restart. * No Restart Strategy - some batch jobs simply
can&apos;t support restart. When they are re-run they are
considered to be a new instance of a batch job. * Sql Restart
Strategy - [need some additional javadoc for this
strategy].</para>
</listitem>
<listitem>
<para>Lifecycle Support</para>
</listitem>
</itemizedlist>
</section>
</section>
<section>
<title id="s.1.5">The Core Layer</title>
<para>The Batch Core interfaces and services are illustrated in
a simplified view of a package diagram. There are roughly seven
logical packages: * Core Spring Extensions * Core Batch Advice *
Core Batch Configuration * Core Batch Repository * Core Batch
Tasklet \ !Batch Core.png! [Figure 2.5] Batch Core Layer</para>
<para>In the actual physical packaging there are a few more
logical services that the batch execution environment provides. The following
sections will provide an introduction into each set of core batch
facilities.</para>
<itemizedlist>
<listitem>
<para>Core Spring Extensions</para>
<para>The Core Spring extensions provide the scaffolding for
a batch execution environment. This includes facilities for managing the
batch architecture in terms of launching, suspending and
stopping batch jobs. There is house keeping that goes on,
especially in concurrent batch jobs, related to ensuring that
batch jobs quiese properly. The lifecycle management provides
services for the proper initialization and subsequent
shutdown of batch resources and services. The batch
architecture is flexible in terms of how batch jobs may be
launched. For example, batch jobs can be started via JMX
facilities, scripts from the command line that launch a Java
VM. It can also support launching batch jobs through web
services or http. There are no restrictions. Finally, there
are standard batch error codes. These error codes can be
exposed to external utilities, like Schedulers, to ensure
that batch jobs expose the status of jobs to an operational
environment. This is especially important in the batch
context where the modus operandi is headless, meaning
unattended operation.</para>
</listitem>
<listitem>
<para>Core Batch Advice</para>
<para>Core Batch Advice is an inventory of the type of advice
that batch architectures will inject during the runtime of a
batch application. These are defined as a set of extensible
interfaces, with a number of default implementations in the
support layer that provide some of the most common types of
advice. Partition Advice is helpful with large datasets that
need to be &quot;chunked&quot; up and run concurrently for
better through put. Resource Advice is helpful for
registering interest in transactional information so that
file locations can be kept in sync with information processed
within a transaction. In addition, the resource is associated
with the correct step context and its associated
configuration properties. Skip advice is applied for records
that the tasklet is unable to process. Restart Advice is
helpful for Restartable jobs where for advising the job on
how to restart. There is considerable variability on how
restart can occur. For example, a job may be marking records
as &quot;processed&quot; and the restart advice will advise
the process with query that restarts the job at the last
successfully processed record. Finally, Statistics are vital
in operational environments to report on records processed,
records skipped and total number of records read. In
addition, certain batch jobs lend themselves to custom
reporting to expose additional business level information
like the number of trades processed or cases opened,
etc.</para>
</listitem>
<listitem>
<para>Core Batch Configuration</para>
<para>Batch configuration is considerably different from
online web applications or SOA based applications. The Core
Batch Configuration provides a place for configuring runtime
properties related to the batch application style. This
includes the ability to add Commit Policy. In a batch style
application it is often advantageous to keep the commit
interval as high as possible when processing Logical Units of
Work. Whereas in an online web application with declarative
transaction the transaction scope would be at the entrance to
a business service, a batch transaction scope may include
many logical units of work before a transaction commit is
executed. A Start Policy allows a configuration to tell the
batch job whether it is Restartable, and if so, what type of
restart to initiate. Some jobs are not restartable and care
should be taken to ensure that information is not applied
multiple times when the business rules do not allow for it.
Exception policies deal with what to do when exceptions
occur. This impacts logging policies and exception handling.
The architecture defines a common set of exceptions that
projects can apply handlers to like processing errors,
validation errors, parsing errors, missing configuration
parameters, etc.</para>
</listitem>
<listitem>
<para>2.5.4 Container Repository</para>
<para>This is an internal package for storing the state of a
batch job and any associated partition and step status.</para>
</listitem>
<listitem>
<para>Core Batch Tasklet</para>
<para>The core batch tasklet is where control is handed off to
the application. There are a number of patterns that have
been observed in processing batch data. Spring Core Batch
Tasklet implements the most common patterns and provides and
extension point for additional Tasklet processing
implementations. The basic idea of tasklet provides the
facilities for reading and processing data. The simplest
implementation of Tasklet, the ReadProcessTasklet, handles both
the input and output of data within one class. An alternative
implementation, the DataProviderProcessTasklet, provides
functionality for &apos;split processing&apos;. This type of
processing is characterized by separating the reading and
processing of batch data into two seperate classes:
DataProvider and TaskletProcessor. The DataProvider class
provides a solid means for reusablility and enforces good
architecture practices. Because an object *must* be returned
by the DataProider to continue processing, (Returning null
indicates processing should end) a developer is forced to
read in all relevant data, place it into domain or value
objects, and return the object. The TaskletProcessor will then
use this object within the business logic and final
output.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title id="s.2">Container&apos;s Use of batch
infrastructure</title>
<itemizedlist>
<listitem>
<para>Infrastructure Provided I/O</para>
<para>The I/O core interfaces and implementations provide
facilities for simplifying the extraction of data from I/O
sources like files and database tables. The key concepts are
FieldDescriptors and FieldSets along with appropriate CallBack
Handlers. These are modeled after common spring operations and
templates like JdbcTemplate. Through the use of LineMappers a
developer needs only to describe a record format and write the
appropriate callback method that maps the parsed record into an
object of their choice. These can either be true POJO objects
or Value Objects (structures) that are subsequently available
for the tasklet to processs. The interface for Field Descriptors
also allows for a level of validation through the use of
Spring&apos;s VALang or Apache&apos;s Common Validator.</para>
</listitem>
<listitem>
<para>Core Batch Interceptors &amp; Interceptor
Services</para>
<itemizedlist>
<listitem>
<para>Batch Operations &amp; Batch Template</para>
<para>Interceptors and the associated services are the key
to how advise is applied in the batch architecture. The
interceptors are Point Cuts in the batch lifecycle that
allow the injection of advise. The shared lifecycle
behavior abstracted through the BatchLifeCycleInterceptor
defineds three methods; init, onError and finalize. All
subclasses of LifeCycleInterceptor define default behavior
for these three methods. The JobLifecycleInterceptor
further exposes the methods beforeJob(), beforeStep(),
afterJob(), and afterStep() allowing hooks into the
lifecycle for specific advise. The Batch Architecture
provides default implementations for all lifecycle point
cuts, or interception points. The Tasklet Interceptor, in
addition to the standard lifecycle methods, implements
logic around beforeLuw(), afterLuw(),
commitIntervalStarted() and commitIntervalCompleted().
Having well defined lifecycle interception points allows
for the easy insertion of custom advice into the batch
runtime environment.</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
<section>
<title id="s.3">Batch Execution Container Configurations</title>
<para>In addition to core facilities for configuring or wiring
together jobs and steps with required resources, policies, and
interceptors, spring batch allows considerable flexibility in how
scalability is achieved. More options for scalability will be
available in the future. The important key for scalability in Java
is the recognition that there is a limit to what one JVM may scale
up to in terms of number of threads, managed resources, memory
configuration, etc. The spring batch architecture allows for the
configuration of simple batch jobs where one VM and one process is
sufficient to do perform the work within a batch window all the way
through many threads distributed within a cluster of JEE servers.
The figure below illistrates the scalability spectrum.</para>
<para>This is not to be understood as the only way to scale batch
jobs as there are many factors. For example, other federated java
architectures hold potential like Teracotta or Gigaspaces although
there is no current implementation for these distributed models in
the current batch architecture. !scalability-model.png! [Figure
2.3.1] - Scalability Model</para>
<section>
<title id="s.3.1">Single VM Simple Batch Execution
Container - One Job, One Step, One Partition</title>
<para>The simplest configuration is one job with with step and
hence, one implied partition. Implied means that there is nothing
for the developer to consider because the default number of
partitions is one. There is typically one input source and one
output source in this simple configuration. See the Simple Tasklet
Job for an example of what this configuration looks like. A
simple configuration still typically configures a datasource
context, the batch configuration for describing the Job, Step,
along with the associated configured policies, field descriptors,
and line mappers. !SimpleTradeConfiguration.jpg! [Figure 2.3.1]
Simple Container Configuration</para>
<para>The details of this configuration will be covered
thoroughly in subsequent sect1s of the document but for now it
should be understood that Job, the Step, the input template, the
file descriptor with its associated line mapper, and the output
(e.g. the TradeWriter).</para>
</section>
<section>
<title id="s.3.2">Single VM Multi-threaded Batch Execution
Container Configuration - One Job, One Step, Multiple
Partitions</title>
<para>In a Single JVM using partitioning a multi-threaded
execution is supported. [This is still work in progress]</para>
</section>
<section>
<title id="s.3.3">Batch Execution Container Hosted in J2EE
Container - managed environment</title>
<para>The J2EE container model has fallen under fire over the
past few years for many valid reasons. There are some things that
the J2EE container do very well though that projects should
consider when planning for scalability with batch architectures.
Commercial and open source containers like WebSphere, BEA and
JBOSS typically:</para>
<itemizedlist>
<listitem>
<para>manage datasources effectively along with attendent
services like prepared statement caching.</para>
</listitem>
<listitem>
<para>manage transactions effectively including many
configurable properties for long lived transactions.</para>
</listitem>
<listitem>
<para>manage thread pools more effectively.</para>
</listitem>
<listitem>
<para>supply robust implementations of JTA, a requirement
when batch jobs output to multiple XA resources like JMS and
JDBC.</para>
</listitem>
<listitem>
<para>manage distribution effectively including domains,
clusters and cells</para>
</listitem>
<listitem>
<para>provide robust JMX management for configuring, managing
and administering distributed applications.</para>
</listitem>
<listitem>
<para>workload management facilities (clusters) provided by
J2EE vendors</para>
</listitem>
</itemizedlist>
<para>Projects are encouraged to deploy batch applications with

View File

@@ -0,0 +1,17 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="batch-job-testing">
<title>Batch Unit and Integration Tests</title>
<section>
<title id="bjt.1">Unit Testing</title>
<para>Document Batch Job Unit Testing features. This includes the use of Mock Objects,
embedded database (HSQLDB), etc. </para>
</section>
<section>
<title id="bjt.2">Integration Testing</title>
<para>Document how to test against the targeted database, applications, etc.</para>
</section>
</chapter>

View File

@@ -0,0 +1,17 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="batch-launch">
<title>Run Tier - Launching Batch Jobs</title>
<section>
<title id="bl.1">Mapping Batch Error Codes to Launch Client Error Codes</title>
<para>Mapping Batch Error Codes to Launch Client Error Codes</para>
</section>
<section>
<title id="bl.2">Launch Batch from Command Line</title>
<para>Document Command Line Launching</para>
</section>
<section>
<title id="bl.3">Launch Batch On Demand</title>
<para>Document Launching Batch Jobs on Demand</para>
</section>
</chapter>

View File

@@ -0,0 +1,52 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="batch-performance-testing">
<title>Batch Performance Testing</title>
<section>
<title id="bpt.1">Performance Testing Overview</title>
<para>A batch performance test team needs to have the following at their disposal:
</para>
<para>
<itemizedlist>
<listitem><para>
Define performance Targets -
</para></listitem>
<listitem><para>
Establishing the requirements for a performance testing environment -
</para></listitem>
<listitem><para>
Performance Data - generating adequate volumes of realistic data for performance testing
</para></listitem>
<listitem><para>
Performance Tools -
</para></listitem>
<listitem><para>
Performance Team Roles - Tool SME's, performance DBA.
</para></listitem>
</itemizedlist>
</para>
</section>
<section>
<title id="bpt.2">Defining Performance Targets</title>
<para></para>
</section>
<section>
<title id="bpt.3">Establishing Performance requirements and installing the environment.</title>
<para>Establishing the requirements for the performance environment. </para>
</section>
<section>
<title id="bpt.4">Performance Data</title>
<para>Generating adequate volumes of realistic data for performance testing.</para>
</section>
<section>
<title id="bpt.5">Performance Tools</title>
<para></para>
</section>
<section>
<title id="bpt.6">Performance Team Roles</title>
<para>Tool SME's, performance dba's, environment experts (OS, JVM, etc.)</para>
</section>
</chapter>

View File

@@ -0,0 +1,272 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="container-overview">
<title>Overview of the Spring Batch Environment</title>
<section>
<title id="s.1">
Overview of the Spring Batch Simple Batch Execution
Environment
</title>
<para>
The diagram below provides an overview of the high level
components, technical services, and basic operations
required by a batch architecture. This architecture
framework is a blueprint that has been proven through
decades of implementations on the last several generations
of platforms (COBOL/Mainframe, C++/Unix, and now
Java/anywhere). The Simple Batch Execution Environment
provides a physical implementation of the layers, components
and technical services commonly found in robust,
maintainable systems used to address the creation of simple
to complex batch applications, with the infrastructure and
extensions to address very complex processing needs. The
materials below will walk through the details of the
diagram.
</para>
</section>
<section>
<title id="s.2">
Simple Batch Execution Environment high level flow and
interaction of the architecture.
</title>
<mediaobject>
<imageobject role="fo">
<imagedata
fileref="src/site/resources/reference/images/simple-batch-execution-env.jpg"
format="JPG" align="center" />
</imageobject>
<imageobject role="html">
<imagedata
fileref="images/simple-batch-execution-env.jpg" format="JPG"
align="center" />
</imageobject>
<caption>
<para>Figure 1: Batch Execution Environment</para>
</caption>
</mediaobject>
<para>
Tiers The application style is organized into four logical
tiers, which include Run, Job, Application, and Data tiers.
The primary goal for organizing an application according to
the tiers is to embed what is known as &quot;separation of
concerns&quot; within the system. Effective separation of
concerns results in reducing the impact of change to the
system.
</para>
<itemizedlist>
<listitem>
<para>
<emphasis role="bold">Run Tier:</emphasis>
The Run Tier is concerned with the scheduling and
launching of the application. A vendor product is
typically used in this tier to allow time-based and
interdependent scheduling of batch jobs as well as
providing parallel processing capabilities.
</para>
</listitem>
<listitem>
<para>
<emphasis role="bold">Job Tier:</emphasis>
The Job Tier is responsible for the overall
execution of a batch job. It sequentially executes
batch steps, ensuring that all steps are in the
correct state and all appropriate policies are
enforced.
</para>
</listitem>
<listitem>
<para>
<emphasis role="bold">Application Tier:</emphasis>
The Application Tier contains components required to
execute the program. It contains specific tasklets
that address the required batch functionality and
enforces policies around a tasklet execution (e.g.,
commit intervals, capture of statistics, etc.)
</para>
</listitem>
<listitem>
<para>
<emphasis role="bold">Data Tier:</emphasis>
The Data Tier provides the integration with the
physical data sources that might include databases,
files, or queues.
<emphasis role="bold">Note</emphasis>
: In some cases the Job tier can be completely
missing and in other cases one Job Script can start
several Batch Job instances.
</para>
</listitem>
</itemizedlist>
</section>
<section>
<title id="s.3">High Level Processing Flow</title>
<para>
The diagram above illustrates the flow and architecture
components in a typical batch run execution.
</para>
<para>Standard interaction is described as follows:</para>
<para>
<emphasis role="bold">1.</emphasis>
In the Run tier, a Scheduler starts a batch application by
invoking a Job Script. The Scheduler identifies what batch
process it wants to run by passing the name of the batch
process and any required additional parameters to the Job
Script.
</para>
<para>
<emphasis role="bold">2.</emphasis>
The Job Script initializes the program and executes any job
specific scripts prior to calling the Batch Launcher.
</para>
<para>
<emphasis role="bold">3.</emphasis>
The Batch Launcher starts the Batch Execution Environment
based upon any environment settings established in the
script.
</para>
<para>
<emphasis role="bold">3.1</emphasis>
The Batch Environment starts and controls the batch execution.
It initializes the Job execution environment with static
configuration items such as database settings, logging
levels and creates a Job based on the Job Configuration
created by a Batch Developer.
</para>
<para>
<emphasis role="bold">4</emphasis>
Based on configuration provided by a Batch Developer, the
Job sequentially executes steps after checking policies to
ensure that each step should be started. The status of the
job and step (start time, end time, status such as
&quot;started&quot; or &quot;completed&quot;) is stored at
various points during the process.
</para>
<para>
<emphasis role="bold">5.1</emphasis>
In order to maintain data integrity, at the application
tier, the Step acts as a controller to ensure that either an
entire group of actions completes successfully or that none
of the actions completes. This group of actions is referred
to as a logical unit of work (LUW). The Step controls the
overall execution of the Tasklet, ensuring that transaction
are committed at the appropriate time, and restart and
statistics information is stored appropriately. The first
thing the Step is responsible for is the initialization of
the data required to begin processing. The Step will
interact with other architecture components, such as the
Input Source, to setup the data required to be processed.
</para>
<para>
<emphasis role="bold">5.1.1</emphasis>
The Input Source provides services to access various data
sources. It provides location transparency to the Batch
Tasklet and hides the physical location details of the data.
</para>
<para>
<emphasis role="bold">5.2</emphasis>
Once the data is initialized by the Input Source, the Step
will call into the Tasklet to begin processing. The Tasklet
contains the business logic to define the LUW and the Step
repeatedly calls the Tasklets LUW to finish the business
function. The Step does this by first invoking the execute
method on the Tasklet in order to acquire a single
record/set of data for processing.
</para>
<para>
<emphasis role="bold">5.2.1</emphasis>
Before a record is returned to the Tasklet, it may be
validated by any number of validation Frameworks that can be
provided to an input source. A single record/set of data is
gathered by interacting with the Input Source.
</para>
<para>
<emphasis role="bold">5.3</emphasis>
Once a record/set has been obtained, the step calls the
tasklet to begin processing.
</para>
<para>
<emphasis role="bold">5.3.1</emphasis>
The Tasklet executes its internal business logic by calling
other Business Logic components as necessary. Based on the
business service, it requests or persists objects from the
data access components.
</para>
<para>
<emphasis role="bold">5.3.3</emphasis>
Data Access components can be leveraged retrieve or persist
domain objects.
</para>
<para>
<emphasis role="bold">5.3.4</emphasis>
Once the business logic has been executed, the resulting
output record is written out by utilizing the Output Source
interface. The Step will repeatedly call steps 5.2 -&gt; 5.3
for every record provided by the Input Source.
</para>
<para>
<emphasis role="bold">5.4</emphasis>
Once all of the records are processed, the Step calls the
Tasklet to perform any clean up activities such as closing
connections, exporting files, etc.
</para>
<para>
<emphasis role="bold">5.4.1</emphasis>
The Step is responsible for committing data associated with
the remaining logical units of work as well as performing
any finalization and administrative functions (e.g. closing
database connections).
</para>
<para>
Once the Step has completed finalization the control is
passed back to the Job, where any necessary logging or clean
up is executed for application termination and wrap-up --
provided there are no additional Steps to execute.
</para>
</section>
</chapter>

View File

@@ -0,0 +1,448 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="core">
<title>Spring Batch Core - the Domain language of Batch</title>
<section>
<title>Introduction</title>
<para>To any experienced batch architect, the overall concepts of batch
processing described above should be familiar and comfortable. There are
“Jobs” and “Steps” and a developer supplied processing unit that Spring
Batch refers to as the “Tasklet.” The following diagram is only a slight
variation of the batch reference architecture that has been used for
decades. JCL and COBOL developers are likely to be as comfortable with the
concepts as C++, C# and Java developers. However, because of the Spring
patterns, operations, templates, callbacks, and idioms, there are
opportunities for <itemizedlist>
<listitem>
<para>significant improvement in adherence to a clear separation of
concerns,</para>
</listitem>
<listitem>
<para>clearly delineated architectural layers and services provided
as interfaces,</para>
</listitem>
<listitem>
<para>simple and default implementations that allowed for quick
adoption and ease of use out-of-the-box, and</para>
</listitem>
<listitem>
<para>significantly enhanced extensibility.</para>
</listitem>
</itemizedlist></para>
<para>The diagram below provides an overview of the high level components,
technical services, and basic operations required by a batch architecture.
This architecture framework is a blueprint that has been proven through
decades of implementations on the last several generations of platforms
(COBOL/Mainframe, C++/Unix, and now Java/anywhere). The Simple Batch
Execution Environment provides a physical implementation of the layers,
components and technical services commonly found in robust, maintainable
systems used to address the creation of simple to complex batch
applications, with the infrastructure and extensions to address very
complex processing needs. The materials below will walk through the
details of the diagram.</para>
</section>
<section>
<title id="s.2">Simple Batch Execution Environment high level flow and
interaction of the architecture.</title>
<mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../resources/reference/images/simple-batch-execution-env.jpg"
format="JPG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/simple-batch-execution-env.jpg"
format="JPG" />
</imageobject>
<caption><para>Figure 1: Batch Stereotypes</para></caption>
</mediaobject>
<para>The application style is organized into four logical tiers, which
include Run, Job, Application, and Data tiers. The primary goal for
organizing an application according to the tiers is to embed what is known
as "separation of concerns" within the system. These tiers can be
conceptual but may they prove effective in mapping the deployment of the
artifacts onto physical components like Java runtimes and integration with
data sources and targets. Effective separation of concerns results in
reducing the impact of change to the system. The four conceptual tiers
containing batch artifacts are:</para>
<para><itemizedlist>
<listitem>
<para><emphasis role="bold">Run Tier:</emphasis> The Run Tier is
concerned with the scheduling and launching of the application. A
vendor product is typically used in this tier to allow time-based
and interdependent scheduling of batch jobs as well as providing
parallel processing capabilities.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Job Tier:</emphasis> The Job Tier is
responsible for the overall execution of a batch job. It
sequentially executes batch steps, ensuring that all steps are in
the correct state and all appropriate policies are enforced.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Application Tier:</emphasis> The
Application Tier contains components required to execute the
program. It contains specific tasklets that address the required
batch functionality and enforces policies around a tasklet execution
(e.g., commit intervals, capture of statistics, etc.)</para>
</listitem>
<listitem>
<para><emphasis role="bold">Data Tier:</emphasis> The Data Tier
provides the integration with the physical data sources that might
include databases, files, or queues. <emphasis
role="bold">Note</emphasis> : In some cases the Job tier can be
completely missing and in other cases one Job Script can start
several Batch Job instances.</para>
</listitem>
</itemizedlist>In addition the components describe the batch interaction
and services stereotypes that are the domain language and interfaces
implemented by developers in constructing a batch solution. As he diagram
illustrates, custom applicaton archifacts, generally created by the
developer, are the following:</para>
<itemizedlist>
<listitem>
<para>Job Scripts</para>
</listitem>
<listitem>
<para>JobConfigurations</para>
</listitem>
<listitem>
<para>Tasklet</para>
</listitem>
<listitem>
<para>Business Logic</para>
</listitem>
</itemizedlist>
<para>The application architect needs to consider the batch execution
environment with the following issues:</para>
<itemizedlist>
<listitem>
<para>Define how the batch jobs will be launched</para>
</listitem>
<listitem>
<para>Define the Job Execution Environment</para>
</listitem>
<listitem>
<para>Step construction and Configuration</para>
</listitem>
<listitem>
<para>ItemReaders</para>
</listitem>
<listitem>
<para>ItemWriters</para>
</listitem>
<listitem>
<para>Data Access Strategies</para>
</listitem>
</itemizedlist>
<para>The grey icons indicate the technologies selected as part of the
batch solution that are not part of the final solution and entail items
like:</para>
<itemizedlist>
<listitem>
<para>Schedulers (e.g. Quartz, Tivoli, etc.)</para>
</listitem>
<listitem>
<para>Physical Resources in the Data Tier that are the source and
target of ItemReaders and Writers like Message Queues, Databases,
Files and Print Queues.</para>
</listitem>
</itemizedlist>
<section>
<title id="s.2.1">Batch Domain Stereotypes</title>
<para>We will discuss each of these Batch domain Stereotypes
individually. This section describes stereotypes relating to the concept of a batch job.
A job is an entity that encapsulates an entire batch process.</para>
<section>
<title id="s.2.1.1">Job Configuration</title>
<para>
The job configuration could be described as the heart of the Spring Batch framework.
It is represented by a Spring bean of class _JobConfiguration_ and contains all of
the information necessary to define the operations performed by a job. A job configuration
is typically contained within a Spring XML configuration file and the job's name is
determined by the "id" attribute associated with the job configuration bean. The job configuration contains:
</para>
<itemizedlist>
<listitem>
<para> The simple name of the job</para>
</listitem>
<listitem>
<para>Definition and ordering of [Step Configurations|#Step Configuration]</para>
</listitem>
<listitem>
<para>The limit of how many times this job may be started</para>
</listitem>
<listitem>
<para>Whether or not the job is restartable</para>
</listitem>
</itemizedlist>
The mechanics of defining a job configuration will be discussed in the next chapter. [Provide a link]
</section>
<section>
<title id="s.2.1.2">Job Instance</title>
<para>A job instance refers to the business concept of a single job invocation. In other words, suppose
you have a job called "foo" that is run three times a day. There will be one "foo" configuration,
and each time "foo" is supposed to run would be an instance of the "foo" job. Each instance would be
uniquely identified as each one represents a distinct batch need. Further, each instance might
have attempted several times to complete its work. Each attempt is represented by a [#Job Execution],
described below. A job instance is not considered to be complete until an associated job execution
completes successfully. As such, a single job instance may have many executions.
</para>
<para>For example, a unique instance might be identified by just a job name, or by the combination of a
job name and a scheduled date. Using this second type of identification, we might have two distinct
instances, "foo-01-01-2008" and "foo-01-02-2008." Although these two instances would share the same
configuration, they would each have their own set of executions and the successful completion of one
instance would not affect the status of the other.
</para>
<para>Job instances are represented by objects of the _JobInstance_ class, which are created when the
job is executed. Each job instance contains references to related [Step Instances|#Step Instance]
and a _JobIdentifier_ that uniquely identifies this job instance.
</para>
</section>
<section>
<title id="s.2.1.3">Job Execution</title>
<para>
A job execution refers to the technical concept of a single attempt to run a job. It is a single attempt to execute the logic represented by a job instance. A job execution may end in failure or success, but the job instance corresponding to a given execution will not be marked as complete unless the execution completes successfully.
</para>
<para>
For instance, if we have a job instance "foo-01-01-2008" that fails to successfully complete its work the first time it is run, when we attempt to run it again, a new job execution will be created. If our "foo" configuration is restartable, we may begin our second job execution from a restart point. Otherwise, our job execution will start from the beginning. In either case, we will see that our single job instance has had two job executions.
</para>
<para>
Job executions are represented by objects of the _JobExecution_ class. These job executions are created by an implementation of the _JobExecutorFacade_ interface from a given _JobInstance_ corresponding to a unique _JobIdentifier_. Each job execution contains a reference to its corresponding job instance, related Step Executions and step/chunk context data.
</para>
</section>
<section>
<title id="s.2.1.4">Step Stereotypes</title>
<para>
This section describes stereotypes relating to the concept of a batch step. A step is an entity that encapsulates a single, independent phase of a batch job. Therefore, every batch job is composed entirely of one or more batch steps.
</para>
</section>
<section>
<title id="s.2.1.5">Step Configuration</title>
<para>
The step configuration contains all of the information necessary to define a discrete set of business logic within a job configuration. This is a necessarily vague description because the contents of any given step configuration are at the discretion of the developer writing your jobs. A step can be as narrowly defined as a single line of code or as broadly defined as necessary to complete the entire work of your job. There are several factors that will affect the breadth of your step configurations.
</para>
<itemizedlist>
<listitem>
<para>Re-usability - step definitions can be shared between jobs</para>
</listitem>
<listitem>
<para>Transaction Management - depending on your desired transaction strategy, you may divide the work of your job differently between steps</para>
</listitem>
<listitem>
<para>Extensibility - adequately granular definition of steps allows the addition or subtraction of steps at a later time in the appropriate position within your job configuration</para>
</listitem>
</itemizedlist>
<para>
Step configurations are defined by instantiating implementations of the _StepConfiguration_ interface. Additionally, the utility class _StepConfigurationSupport_ provides a basic implementation of _StepConfiguration_ with default functionality that should be common to any concrete _StepConfiguration_ implementation. Generally, all step configuration implementations should extend from this class.
</para>
<para>
Two step configuration classes are available in the Spring Batch framework, and they are each discussed in detail in other sections of this guide. For most situations, the _SimpleStepConfiguration_ implementation is sufficient, but custom transaction management behavior can also be configured by using a _RepeatOperationsStepConfiguration_.
</para>
</section>
<section>
<title id="s.2.1.6">Step Instance</title>
<para>
A step instance, represented by the _StepInstance_ class, represents the business concept of a single step within a job invocation. That is to say, every job instance contains one or more step instances.
</para>
<para>
For example, suppose we have a job instance called "foo-01-01-2008" that is an instance of a job configuration containing three steps. Suppose these steps are named "step1", "step2" and "step3." There will be corresponding "foo-01-01-2008#step1", "foo-01-01-2008#step2" and "foo-01-01-2008#step3" step instances, which will be distinct from the step instances of any other job instance (e.g. those of "foo-01-02-2008").
{note}The step instance naming here is for clarity, this is not necessarily how the instance will be named internally within the framework.{note}
</para>
<para>
Each step instance will contain the current status of the batch execution, restart data, and a reference to its corresponding [Job Instance]. Additionally, a step instance keeps track of how many attempts are made to run the corresponding step. Each attempt to run a step will create a [Step Execution], so a single job instance might have several corresponding step executions.
</para>
</section>
<section>
<title id="s.2.1.7">Step Execution</title>
<para>
A step execution represents the technical concept of a single attempt to execute a step. It is a single attempt to execute the logic represented by a step instance.
</para>
<para>
For instance, if we have a step instance "foo-01-01-2008#step1" that fails to successfully complete its work the first time it is run, when we attempt to run it again, a new step execution will be created. Each of these step executions may represent a different invocation of the batch framework, but they will all correspond to the same step instance.
</para>
<para>
Step executions are represented by objects of the _StepExecution_ class. These step executions are created by an implementation of the _JobExecutor_ interface from a given _StepInstance_ and _JobExecution_. Each step execution contains a reference to its corresponding step instance and job execution, and transaction related data such as commit and rollback counts, start and end times and a _Properties_ instance containing statistics.
</para>
</section>
<section>
<title id="s.2.1.8">Tasklets</title>
<para>
A tasklet represents the execution of a logical unit of work, as defined by its implementation of the Spring Batch provided _Tasklet_ interface. Tasklets are used when defining step configurations to specify the work done by the step. Subsequently, the logic in a tasklet is atomic in terms of transactions. A transaction will never commit until an entire tasklet execution is complete (unless an exception occurs - a transaction might either commit or rollback if that behavior is specified in the step's exception management strategy).
</para>
</section>
</section>
<title id="s.2.3">Item-Oriented Processing Stereotypes</title>
<para>
A powerful batch processing paradigm implemented by the Spring Batch framework is the concept of item-oriented processing. That is, doing work by defining each unit of work as the operation of retrieving an item from input and then processing that item, including any side effects that processing might entail, such as file or database operations.
</para>
<para>
There are two basic stereotypes that represent the first-class participants in item-oriented processing, item providers and item processors. They are each represented by a simple interface provided by the Spring Batch framework, which allows free reign over their implementations and improves our ability to leverage the Spring framework's dependency injection capabilities.
</para>
<section>
<title id="s.2.3.1">Item Readers</title>
<para>
An item reader is an object that is used to retrieve the inputs for a step, one at a time. When the item reader has exhausted the items it can provide, it will indicate this in a meaningful way (generally by returning _null_). When coupled with an item processor, this forms a complete item-oriented process, as each item taken from the provider is then processed by the processor.
</para>
</section>
<section>
<title id="s.2.3.2">Item Writers/Processors</title>
<para>
An item processor is an object that is used to perform processing for a step, one item at a time. Generally, an item processor has no knowledge of the input it will receive next, only the item that that was passed in its current invocation. As a result, item processors will generally make no assumptions about the input they receive an treat every item the same way and keep track of its own state between invocations. When coupled with an item provider, this forms a complete item-oriented process, as each item taken from the provider is then processed by the processor.
</para>
</section>
</section>
<section>
<title id="s.2.4">Support Stereotypes</title>
<para>While item providers and processors serve as the main entry points for item-oriented processing, they are supplemented by a number of support classes that perform specific tasks within the provider / processor lifecycle. These support stereotypes are useful for dividing the work of item providers and processors into reusable pieces, as well as abstracting away the details of processing, such as interaction with external systems. Additionally, they give us another opportunity to leverage the powerful configuration features of the Spring framework, as we can switch between several beans implementing these support interfaces without changing the driving item provider or processor.
</para>
<section>
<title id="s.2.4.1">Input Sources</title>
<para> An input source is a class that mediates interactions with an external source of input data, such as a file or a database. An input source often serves as a support for an item provider, typically abstracting away the details of interaction, such as the creation and maintenance of file handles, sockets or database connections.
</para>
</section>
<section>
<title id="s.2.4.2">Item Transformers</title>
<para>An item transformer is a class that is capable of taking an object and changing it somehow before processing occurs. For instance, an item transformer my alter an object by changing its properties or by replacing it with another object entirely, such as a wrapper or derivative object. It can also be defined as an adaptor, allowing an object of one type to be converted for use as an object of a second type.
</para>
</section>
<section>
<title id="s.2.4.3">Item Writers</title>
<para>An item writer is a class that mediates interactions with an external target of output data, such as a file or database. An item writer often serves as a support for an item processor, typically abstracting away the details of interaction, such as the creation and maintenance of file handles, sockets, database connections and other output-related tasks such as buffering and stream flushing.
</para>
</section>
</section>
<section>
<title id="s.3">High Level Processing Flow</title>
<para>The diagram above illustrates the flow and architecture components
in a typical batch run execution.</para>
<para>Standard interaction is described as follows:</para>
<para><emphasis role="bold">1.</emphasis> In the Run tier, a Scheduler
starts a batch application by invoking a Job Script. The Scheduler
identifies what batch process it wants to run by passing the name of the
batch process and any required additional parameters to the Job
Script.</para>
<para><emphasis role="bold">2.</emphasis> The Job Script initializes the
program and executes any job specific scripts prior to calling the Batch
Launcher.</para>
<para><emphasis role="bold">3.</emphasis> The Batch Launcher starts the
Batch Execution Environment based upon any environment settings
established in the script.</para>
<para><emphasis role="bold">3.1</emphasis> The Batch Environment starts
and controls the batch execution. It initializes the Job execution
environment with static configuration items such as database settings,
logging levels and creates a Job based on the Job Configuration created by
a Batch Developer.</para>
<para><emphasis role="bold">4</emphasis> Based on configuration provided
by a Batch Developer, the Job sequentially executes steps after checking
policies to ensure that each step should be started. The status of the Job
and Step (start time, end time, status such as "started" or "completed" is
stored at various points during the process. In order to maintain data
integrity at the application tier, the Step acts as a controller to ensure
that either an entire group of actions completes successfully or that none
of the actions completes. In online applications the Unit Of Work and the
scope of a transaction tend to be the same thing (e.g. update customer).
This group of actions controlled by a user interaction is referred to as a
logical unit of work (LUW). However, in batch processing the Step
frequently separates the transactional scope from the LUW so that many
LUWs complete within one commit. This greatly improves batch throughput
(see pseudo code above where REPEAT(size=500). The Step controls the
overall execution of the Tasklet, ensuring that transactions are committed
at the appropriate time and that restart and statistics information is
stored appropriately.</para>
<para><emphasis role="bold">4.1</emphasis> The first thing the Step is
responsible for is the initialization of the data required to begin
processing. The Step will interact with other architecture components,
such as the Input Source, to setup the data required to be
processed.</para>
<para><emphasis role="bold">4.1.1</emphasis> The Input Source provides
services to access various data sources. It provides location transparency
to the Batch Tasklet and hides the physical location details of the
data.</para>
<para><emphasis role="bold">4.2</emphasis> Once the data is initialized by
the Input Source, the Step will call into the Tasklet to begin processing.
The Tasklet contains the business logic to define the LUW and the Step
repeatedly calls the Tasklets LUW to finish the business function. The
Step does this by first invoking the execute method on the Tasklet in
order to acquire a single record/set of data for processing.</para>
<para><emphasis role="bold">4.2.1</emphasis> Before a record is returned
to the Tasklet, it may be validated by any number of validation Frameworks
that can be provided to an input source. A single record/set of data is
gathered by interacting with the Input Source.</para>
<para><emphasis role="bold">4.3</emphasis> Once a record/set has been
obtained, the step calls the tasklet to begin processing.</para>
<para><emphasis role="bold">4.3.1</emphasis> The Tasklet executes its
internal business logic by calling other Business Logic components as
necessary. Based on the business service, it requests or persists objects
from the data access components.</para>
<para><emphasis role="bold">4.3.3</emphasis> Data Access components can be
leveraged retrieve or persist domain objects.</para>
<para><emphasis role="bold">4.3.4</emphasis> Once the business logic has
been executed, the resulting output record is written out by utilizing the
Output Source interface. The Step will repeatedly call steps 4.2 -&gt; 4.3
for every record provided by the Input Source.</para>
<para><emphasis role="bold">4.4</emphasis> Once all of the records are
processed, the Step calls the Tasklet to perform any clean up activities
such as closing connections, exporting files, etc.</para>
<para><emphasis role="bold">4.4.1</emphasis> The Step is responsible for
committing data associated with the remaining logical units of work as
well as performing any finalization and administrative functions (e.g.
closing database connections).</para>
<para>Once the Step has completed finalization the control is passed back
to the Job, where any necessary logging or clean up is executed for
application termination and wrap-up -- provided there are no additional
Steps to execute.</para>
</section>
</chapter>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="execution">
<title>The Batch Execution Environment</title>
<section>
<title>Introduction</title>
<para>The "execution" layer is fertile ground for collaboration and
contributions from the community and from projects in the field. There is
lifecycle support for starting and stopping jobs. The vision for this is
that there can be multiple implementations of this interface providing
different architectural patterns, and delivering different levels of
scalability and robustness, without changing either the business logic or
the job configuration. The initial 1.0 release of Spring Batch will have a
single implementation for the Simple Batch Execution Service.</para>
<para>The Execution Environment is responsible for providing
implementations of the core domain concepts. This includes: <itemizedlist>
<listitem>
<para>Run Tier - Implement the bootstraping and launching of the
Execution Environment.</para>
</listitem>
<listitem>
<para>Job Tier - Implement the Job Configuration and Job Execution
strategies.</para>
</listitem>
<listitem>
<para>Application Tier - Impleement the Step Configuration and Step
Executor strategies.</para>
</listitem>
<listitem>
<para>Data Tier - Implement a Repository solution for storing the
persistence state of the batch domain.</para>
</listitem>
</itemizedlist> <para>We will describe the flow of the simple batch
execution envrionment that is provided with spring-batch to clarify the
sequence of processing in the batch environment. The simple batch
execution environment is a concrete implementation of the core interfaces.
The Simple Batch Execution Environment can be described in the following
way.</para> <orderedlist>
<listitem>
<para>In the Run Tier, asingle Java Project may have one or more
Jobs. Jobs are configured with the JobConfiguration bean.</para>
</listitem>
<listitem>
<para>A single Job must contain at least one Step.Steps are
configured with the StepConfiguration bean. If more than one step is
configured for a Job, then they are executed serially and after the
previous step (all of its items / records) is complete.</para>
</listitem>
<listitem>
<para>Steps are executed by StepExecutor classes, being the
DefaultStepExecutor the most simple for it.</para>
</listitem>
<listitem>
<para>Steps in turn are divided into two “cycles” or “iterators”;
the “stepOperations” iterator and the “chunkOperations” iterator.
The StepOperations of the Step cycles while there is data to be
processed (i.e. a CompletionPolicy returns true) whereas the
chunkOperations executes for every cycle of the stepOperations and
it is used as Transaction controlling mechanism. The idea is that
the chunkOperations iterator executes the number of “commit size”
defined in the configuration unless another CompletionPolicy is
defined. After “# of records per Commit” cycles, it returns control
to the StepOperations which in turn calls again the ChunkOperations
if there are more records to be processed. Programmers should only
define chunkOperations and not stepOperations, unless a parallel
execution strategy is chosen.</para>
</listitem>
<listitem>
<para>The RepeatTemplate class (implementator of the chunk and step
Operations) requires a Tasklet. A Tasklet is responsible for doing
something in each cycle of the "stepOperations". Simple tasklets may
fetch and process data in the same class but typicallyIdevelopers
will use the ItemProviderProcessTasklet that separates fetching data
from processing it in the ItemProvider and ItemProcessor interfaces.
If using DB access it's also common to use an
InputSourceItemProvider as ItemProvider and an
OutputSourceItemProcessor as ItemProcessor. There are even more
specialized classes for working the Jdbc (databases).</para>
</listitem>
</orderedlist></para>
</section>
<section>
<title>Simple Batch Execution Environment</title>
<para></para>
</section>
</chapter>

View File

@@ -0,0 +1,184 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
<chapter id="glossary">
<title>Glossary</title>
<section>
<title>Glossary Items</title>
<para></para>
<orderedlist numeration="arabic">
<listitem>
<para><emphasis role="bold">Batch</emphasis>: An accumulation of
business transactions over time.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Batch Application Style</emphasis>:
Term used to designate batch as an application style in its own
right similar to online, Web or SOA. It has standard elements of
input, validation, transformation of information to business
model, business processing and output. In addition, it requires
monitoring at a macro level.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Batch Processing</emphasis>: The
handling of a batch of many business transactions that have
accumulated over a period of time (e.g. an hour, day, week,
month, or year). It is the application of a process, or set of
processes, to many data entities or objects in a repetitive and
predictable fashion with either no manual element, or a separate
manual element for error processing.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Batch Window</emphasis>: The time
frame within which a batch job must complete. This can be
constrained by other systems coming online, other dependent jobs
needing to execute or other factors specific to the batch
environment.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Step Controller</emphasis>: It is the
main batch task or Unit of Work controller. It initializes the
tasklet, and controls the transaction environment based on commit
interval setting, etc.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Tasklet</emphasis>: The main
application program created by application developer to process
the business logic for each LUW.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Batch Job Type</emphasis>: Job Types
describe application of jobs for particular type of processing.
Common areas are interface processing (typically flat files),
forms processing (either for online pdf generation or print
formats), report processing. s</para>
</listitem>
<listitem>
<para><emphasis role="bold">Driving Query</emphasis>: A driving
query identifies the set of work for a job to do; the job then
breaks that work into individual units of work. For instance,
identify all financial transactions that have a status of
&quot;pending transmission&quot; and send them to our partner
system. The driving query returns a set of record IDs to process;
each record ID then becomes a unit of work. A driving query may
involve a join (if the criteria for selection falls across two or
more tables) or it may work with a single table.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Logicial Unit of Work
(LUW)</emphasis>: A batch job iterates through a driving query
(or another input source such as a file) to perform the set of
work that the job must accomplish. Each iteration of work
performed is a unit of work.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Commit Interval</emphasis>: A set of
LUWs constitute a commit interval.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Partitioning</emphasis>: Splitting a
job into multiple threads where each thread is responsible for a
subset of the overall data to be processed. The threads of
execution may be within the same JVM or they may span JVMs in a
clustered environment that supports workload balancing.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Staging Table</emphasis>: A table
that holds temporary data while it is being processed.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Restartable</emphasis>: - a job that
can be executed again and will assume the same identity as when
run initially. In othewords, it is has the same job instance
id.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Rerunnable</emphasis> - a job that is restartable and manages it&apos;s own state in terms of previous run&apos;s record
processing. Note&gt;&gt;: Rerunnable is tied to the driving query. If the driving query can be formed so that it will limit the
processed rows when the job is restarted than re-runnable = true. This is managed by the application architecture. Often times a
condition is added to the where statement to limit the rows returned by the driving query with something like &quot;and
processedFlag != true&quot;.</para>
<programlisting><![CDATA[
Note: If re-runnable = false the architecture assumes responsibility for tracking which rows have been processed. There is a default strategy
for tracking the last record processed by partition. Most batch jobs only have one partition. The option is only valid for a restartable job.
The reason being is that the architecture will have to persist the restart data, which is only available on a restartable job as the restart data is
saved and made available from the execution of the last run if restartable = true.
In pseudo code it is the following:
StartOver ::= restartable = false. Restartable ::= true | false
If (Restartable)
re-runnable ::= true | false
We don't persist restart information for a non-restartable job. As you can see, it doesn't make sense. Rerunnable has always confused the best
of us and we're open to suggestions on how to better explain it.
]]></programlisting>
</listitem>
<listitem>
<para><emphasis role="bold">Repeat</emphasis>: One of the most basic units of batch processing, that defines repeatability calling a
portion of code until it is finished, and while there is no error. Typically a batch process would be repeatable as long as there is input.
</para>
</listitem>
<listitem>
<para><emphasis role="bold">Retry</emphasis>: Simplifies the execution of operations with retry semantics most frequently associated
with handling transactional output exceptions. Retry is slightly different from repeat, rather than continually calling a block of code,
retry is stateful, and continually calls the same block of code with the same input, until it either succeeds, or some type of retry limit
has been exceeded. It is only generally useful if the operation is non-deterministic meaning that a retry on a subsequent invocation might
succeed because something in the environment has improved.
</para>
</listitem>
<listitem>
<para><emphasis role="bold">Recover</emphasis>: Recover operations handle an exception in such a way that a repeat process is able to
continue.
</para>
</listitem>
<listitem>
<para><emphasis role="bold">Skip</emphasis>: Skip is a recovery strategy often used on file input sources as the strategy for ignoring
bad input records that failed validation.
</para>
</listitem>
</orderedlist>
</section>
</chapter>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<bookinfo>
<title>Spring Batch - Reference Documentation</title>
<releaseinfo>Spring Batch 1.0</releaseinfo>
<authorgroup>
<author>
<firstname>Dave</firstname>
<surname>Syer</surname>
</author>
<author>
<firstname>Wayne</firstname>
<surname>Lund</surname>
</author>
<author>
<firstname>Scott</firstname>
<surname>Wintermute</surname>
</author>
</authorgroup>
<legalnotice>
<para>
Copies of this document may be made for your own use and
for distribution to others, provided that you do not
charge any fee for such copies and further provided that
each copy contains this Copyright Notice, whether
distributed in print or electronically.
</para>
</legalnotice>
</bookinfo>
<xi:include href="spring-batch-intro.xml"/>
<xi:include href="infrastructure.xml"/>
<xi:include href="core.xml"/>
<xi:include href="execution.xml"/>
<xi:include href="application.xml"/>
<xi:include href="samples.xml"/>
<xi:include href="batch-job-testing.xml"/>
<xi:include href="batch-performance-testing.xml"/>
<xi:include href="glossary.xml"/>
</book>

View File

@@ -0,0 +1,529 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="spring-batch-infrastructure">
<title>The Spring Batch Infrastructure</title>
<section>
<title id="i-0.spring-batch-infrastructure-overview">Introduction to the
Spring Batch Infrastructure</title>
<para>Spring Batch is a Pipe and Filters architecture. The Spring Batch
Infrastructure implements key services that enable a high volume of
throughput. These include: <itemizedlist>
<listitem>
<para>Input and Output Resource Faciltities - the management of
input items including reading, validating and mapping raw input to
objects.</para>
</listitem>
<listitem>
<para>Item Providers and Processors - strategy interfaces for
providing and processing the data for a given batch stage
execution.</para>
</listitem>
<listitem>
<para>Validation- interface to support pluggable validation
strategies to ensure the integrity of the input source items or, in
other words, object level validation.</para>
</listitem>
<listitem>
<para>RepeatTemplates- the Repeat Template is responsible for
repeatedly invoking an operation on the Input Provider pulling input
items from an input source until there are no more items to be
processed.</para>
</listitem>
<listitem>
<para>RetryTemplates - a mechanism for attempting to reprocess an
input item that has thrown an exception.</para>
</listitem>
<listitem>
<para>Support for Statistics - an interface that dependent projects
can use to implement application specific statistics.</para>
</listitem>
<listitem>
<para>Transaction semantics for batch - support facilities for
giving transaction extensions used by the batch architecture.</para>
</listitem>
</itemizedlist></para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../resources/reference/images/PipeAndFilter.jpg"
format="JPG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/PipeAndFilter.jpg"
format="JPG" />
</imageobject>
<caption><para>Figure 1: Spring Batch Pipe and Filter
Design</para></caption>
</mediaobject></para>
<para>The Batch Lifecycle is simple. Data comes in one side of the pipe.
It is then parsed, validated and transformed and handed off for business
logic processing. That processing can be as simple as loading records into
a database or as complicated as supporting batch job styles of generating
reports, conversion, pdf generation, generation of high volume print
formats, etc. Spring Batch provides a framework for simplifying the
handling of input and output resources so that developers can concentrate
on what needs to happen during the processing steps.</para>
</section>
<section>
<title id="infrastructure.1">Input and Output Sources</title>
<para><itemizedlist>
<listitem>
<para>Input Source - This is an interface responsible for reading
records from an input stream and also possibly for mapping these
records to objects. It is the responsibility of the implementing
class to decide which technology to use for mapping and configuring
an input source.</para>
</listitem>
<listitem>
<para>Ouput Source - this is the interface for the generation output
operations and works conversely from the input source for
serializing processed data to the appropriate targeted output
source, which includes files, databases or queues.</para>
</listitem>
</itemizedlist></para>
<para>The Input Source is a basic interface for generic input operations.
Subclasses implementing this interface will be responsible for reading
records from input stream and also possibly for mapping these records to
objects. Generally it is the responsibility of implementing class to
decide which technology to use for mapping and how it should be
configured. A picture of the I/O hierarhcy is helpful in understanding
their place within the spring batch infrastructure.</para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../../../target/site/reference/images/io-design.jpg"
format="JPG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../../../target/site/reference/images/io-design.jpg"
format="JPG" />
</imageobject>
<caption><para>Figure 2: Input/Output Sources</para></caption>
</mediaobject></para>
<para>A description of input and output resources that spring batch
supports are the following:</para>
<para><itemizedlist>
<listitem>
<para>File - File Sources read and write lines of data from a flat
file that typically describe records with fields of data defined by
fixed positions in the file or delimited by some special character
(e.g. a comma). There is a line tokenizer associated with input
sources and a line aggregator associated with the output
source.</para>
</listitem>
<listitem>
<para>SQL - a database resource accessed that returns resultsets
that can be mapped to objects for processing. The default SQL Input
Sources invoke a RowMapper to return objects, keep track of the
current row if restart is required, basic statistics, and some
transaction enhancements that will be explained later.</para>
<para>Note: There is no SQL Output Source because there is no state
to manage whereas the SQL Input Source requires state to monitor
skips, the current position in the input source, restart data,
etc.</para>
</listitem>
<listitem>
<para>XML - an XML input and output sources process XML
independently of technologies used for parsing, mapping and
validating objects. Input data allows for the validation of and XML
file against and XSD schema. The input template provides for
restart, skip, statistics and transaction features by implementing
the corresponding interfaces.</para>
</listitem>
</itemizedlist></para>
<section>
<title id="infrastructure.1.1">Flat File Sources</title>
<para>Flat File Input Sources - Flat File Input Sources are basic input
sources that read data from a file and return it as structured tuples in
the form of FieldSet instances. Flat File Input Sources are further
refined as both fixed length and delimited formats.</para>
<para />
<para>
<mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../../../target/site/reference/images/flatfile-input-source-diagram.jpg"
format="JPG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../../../target/site/reference/images/flatfile-input-source-diagram.jpg"
format="JPG" />
</imageobject>
<caption>
<para>Figure 1: Flat File Input Source Collaborations</para>
</caption>
</mediaobject>
</para>
<para>The location of the file is defined by the resource property.
There are only a few methods exposed through a resource service. A
resource is used to help locate, open, and close resources. It can be as
simple as: <programlisting>
Resource resource = new FileSystemResource("resources/trades.csv");
</programlisting></para>
<para>In complex batch environments the directory structures are often
managed by the EAI infrastructure where drop zones for external
interfaces are established for moving files from ftp locations to batch
processing locations and vice versa. File moving utilities are beyond
the scope of the batch architecture but its not unusual for batch job
streams to include file moving utilities as steps in the job stream.
It's sufficient to know that the batch architecture only needs to know
how to find the files to be processed and it begins the process of
feeding the data into the pipe from this starting point.</para>
<para>To separate the structure of the file, LineTokenizer, or one of it
subclasses, is used to parse data obtained from the file. Flat File
Input Sources, as mentioned above, typically come in two forms, fixed
and delimited. A fixed length input record is where the fields are
assigned fixed locations within a line of a file. An example would be:
<programlisting>
12345678901234567890123456789012345678901234567890
AbduKa00Abdul-Jabbar Karim rb19741996
AbduRa00Abdullah Rabih rb19751999
AberWa00Abercrombie Walter rb19591982
AbraDa00Abramowicz Danny wr19451967
AdamBo00Adams Bob te19461969
AdamCh00Adams Charlie wr19792003
</programlisting></para>
On the other hand a delimited record format might look like the following:
<para>
<programlisting>
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
AbduRa00,Abdullah,Rabih,rb,1975,1999
AberWa00,Abercrombie,Walter,rb,1959,1982
AbraDa00,Abramowicz,Danny,wr,1945,1967
AdamBo00,Adams,Bob,te,1946,1969
AdamCh00,Adams,Charlie,wr,1979,2003
</programlisting>
</para>
<para>Neither of these formats are particularly self describing but are
still very much in use in flat file exchanges between system interfaces.
Both formats share in common the requirement to read in a line of data
(a String) and parse it into tokens that can be mapped to an object (or
objects) to be passed to the ItemProcessor. As you can see, there are
two required dependencies of the input source; the first is a resource
to read in, which is the file to process. The second dependency is a
LineTokenizer, which will be discused below.</para>
</section>
<section>
<title id="infrastructure.1.2">Configuring and using FieldSets</title>
<para>A FieldSet is Spring Batchs abstraction for typing fields from a
flat file data source. It allows developers to work with file input in
much the same way as they would work with database input. A FieldSet is
conceptually very similar to a Jdbc Result Set. FieldSets only require
one argument, a list of tokens. Optionally you can also configure in the
names of the fields so that the fields may be accessed either by index
or name as patterned after the JdbcResultSet. In code it means it's as
simple as:</para>
<para><programlisting>
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);
assertTrue(fieldSet.getFieldCount() == 14);
</programlisting></para>
</section>
<section>
<title id="infrastructure.1.3">Configuring and Using
LineTokenizers</title>
<para>The interface for a LineTokenizer is very simple, given a string;
it will return a FieldSet that wraps the results from tokenizing the
provided string. The tokens are created through a
<emphasis>LineTokenizer</emphasis> and a
<emphasis>FieldSetMapper</emphasis> is used to map a the
<emphasis>FieldSet</emphasis> to an object. The framework provides a few
convenience classes, the <emphasis>FieldSetInputSource</emphasis> and
the <emphasis>SimpleFlatFileInputSource</emphasis>. They provide a
convenient way to read the FieldSet. The <emphasis>FieldSet</emphasis>
is configured as a property for an Item Provider, which wraps an Input
Source. You can see this in the following example:</para>
<para><programlisting>
&lt;property name="itemProvider"&gt;
&lt;bean class="org.springframework.batch.sample.item.provider.PlayerItemProvider"&gt;
&lt;property name="inputSource" ref="playerFileInputSource" /&gt;
&lt;property name="fieldSetMapper"&gt;
&lt;bean class="org.springframework.batch.sample.mapping.PlayerMapper" /&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/property&gt;
</programlisting></para>
<para>The LineTokenizer is just one additional property to the
InputSource as seen here:</para>
<para><programlisting>
&lt;property name="tokenizer"&gt;
&lt;bean
class="org.springframework.batch.io.file.support.transform.DelimitedLineTokenizer"&gt;
&lt;property name="names"
value="ID,lastName,firstName,position,birthYear,debutYear" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
</programlisting></para>
<para>And, as you can see, the field names will get passed in the the
mapper. The actual mapping provided by the developer would then look as
simple as:</para>
<para><programlisting>
public class PlayerMapper implements FieldSetMapper {
public Object mapLine(FieldSet fs) {
if(fs == null){
return null;
}
Player player = new player();
player.setID(fs.readString("ID"));
player.setLastName(fs.readString("lastName"));
player.setFirstName(fs.readString("firstName"));
player.setPosition(fs.readString("position"));
player.setDebutYear(fs.readInt("debutYear"));
player.setBirthYear(fs.readInt("birthYear"));
return player;
}
}
</programlisting></para>
</section>
<section>
<title id="infrastructure.1.4">Output Sources</title>
<para>The output source is similar in functionality to the input source
with the exception that the operations are reversed. They still need to
be located, opened and closed but they differ in the case that we write
to output sources. In the case of databases or queues these may be
inserts, updates or sends. The format of the serialization of the output
source is specific for every batch job.</para>
</section>
</section>
<section>
<title id="infrastructure.2.2">SQL Sources</title>
<para>SQL input sources can be configured for various reasons, for
example:</para>
<itemizedlist>
<listitem>
<para>a staging table for large volumes of sorted data that was loaded
from flat files</para>
</listitem>
<listitem>
<para>the beginning of an outbound collection of data targeted for an
external flat file interface</para>
</listitem>
<listitem>
<para>the target of a triggered event like "collect all cases that can
be automatically closed"</para>
<para>Spring Batch supports two approaches for accessing a SQL Input
Source; 1) a cursor driven input source and 2) an indexed based Input
Query. The cursor driven input source is named because it utilizes a
jdbc cursor to stream over the SQL input source whereas an indexed
based input query is designed for easy division of the input into
ranges.</para>
<para></para>
</listitem>
</itemizedlist>
</section>
<section>
<title id="infrastructure.2.3">XML Input and Output</title>
<para>Spring Batch provides transactional infrastructure for both reading
XML records and mapping them to Java objects as well as writing Java
objects as XML records.</para>
<para>StAX API is used for I/O as other standard XML APIs do not fit batch
processing requirements (DOM loads the whole input into memory at once and
SAX controls the parsing process allowing the user only to provide
callbacks).</para>
<para>Spring Batch is not tied to any particular OXM technology. Typical
use is to delegate OXM to Spring WS which provides uniform abstraction for
the most popular OXM technologies. However dependency on Spring WS is
optional and you can choose to implement Spring Batch specific interfaces
if desired.</para>
<para>Lets take a closer look how XML input and output work in batch. It
is assumed the XML resource is a collection of 'fragments' corresponding
to individual records. Note that OXM tools are designed to work with
standalone XML documents rather than XML fragments cut out of an XML
document, therefore the Spring Batch infrastructure needs to work around
this fact (as described below).</para>
<para>On input the reader reads the XML resource until it recognizes a new
fragment is about to start (by matching the tag name by default). The
reader creates a standalone XML document from the fragment (or at least
makes it appear so) and passes the document to a deserializer (typically a
wrapper around Spring WS Unmarshaller) to map the XML to a Java
object.</para>
<para>Output works symetrically to input. Java object is passed to a
serializer (typically a wrapper around Spring WS Marshaller) which writes
to output using a custom event writer that filters the StartDocument and
EndDocument events produced for each fragment by the OXM tools.</para>
<para>For example configuration of XML input and output see the sample
xmlStaxJob. //TODO inline the example once it is not subject to change +
show sample input file</para>
<para></para>
</section>
<section>
<title id="infrastructure.3">Item Providers and Processors</title>
<para>We finally arrive at the Item Provider, We've already alluded to
Item Providers in some of the code samples above.</para>
</section>
<section>
<title id="infrastructure.5">Validating Input</title>
<para></para>
</section>
<section>
<title id="infrastructure.6">Repeat Templates</title>
<para>One of the most fundamental concepts in the batch architecture is
the Repeat Template. The Repeat Template is responsible for repeatedly
invoking an operation on the Input Provider pulling input items from an
input source until there are no more items to be processed. One
interesting analogy used by Dierk Koenig in the book "Groovy in Action" is
a boiler vs. a continuous-flow heater. In this analogy he illustrates how
XML parsers can typically be divided into those that read the entire input
before process begins like DOM Parsers vs. those that stream over the
input like SAX parsers. Spring Batch is a continuous-flow heater and uses
the RepeatTemplate as the mechanism to keep the hot water or input stream
in constant flow.</para>
<para>Many times batch processes are not only working on non-transaction
input sources like files but the output is a transactional resource such
as a queue or database. A common scenario when a batch job is a datastream
coming from a flat file interface is to have a file or files as input
sources and a database resource as the output source. In this case the
repeat templates can be used like the following: <mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../../../target/site/reference/images/RepeatTemplate.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../../../target/site/reference/images/RepeatTemplate.png"
format="PNG" />
</imageobject>
<caption><para>Figure 2: Simple Batch Pseduo code for Repeat
Templates</para></caption>
</mediaobject></para>
<para>In this batch scenario an outer RepeatTemplate initialies the
continuous flow, a TransactionTemplate wraps the input and output
resources and an inner RepeatTemplate manages the commit interval or
chunks of data to be processed. The Business Logic occurs in the input and
output of single items. Of course this is a simplistic view of how batch
really works. Input can be quite complex with multiple files and
complicated validation scenarios. Conversely, the output source can also
be quite complex in determining how the records will be stored in the
database. Spring Batch makes no assumptions about how simple or complex
the business processing is within the RepeatTemplates. It's only job is to
keep the flow moving from the Item Provider to the Item Processor as
quickly as possible. The repeat template can process records irrespective
of the batch architecture. A simple example would be: <programlisting>
RepeatTemplate template = new RepeatTemplate();
Resource resource = new FileSystemResource("resources/trades.csv");
TradeProcessor executor = new TradeProcessor();
TradeItemProvider provider = null;
try {
provider = new TradeItemProvider(resource);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
template.iterate(new ItemProviderRepeatCallback(provider, executor));
</programlisting></para>
<para>A RepeatTemplate has an exception policy that can be
leveraged</para>
</section>
<section>
<title id="infrastructure.7">Retry Template</title>
<para>The retry template is used as a way to overcome failures in the
stream</para>
</section>
</chapter>

View File

@@ -0,0 +1,11 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="namespace">
<title>Namespace Support</title>
<section>
<title id="ns.1">Namespace Support</title>
<para>Document Namespace support here. </para>
</section>
</chapter>

View File

@@ -0,0 +1,62 @@
<?xml version='1.0'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
<book lang="en">
<bookinfo>
<title>The Spring Batch - Reference Documentation</title>
<corpauthor>Wayne Lund, Waseem Malik, Lucas Ward, Scott Wintermute,
Kerry O&apos;Brien, Tomi Vanek</corpauthor>
<date>May 2007</date>
</bookinfo>
<section>
<title id="c.1">Chapter 1: Spring Batch Introduction</title>
<para><ulink url="spring-batch-intro.html">Overview of the Spring Batch Architecture</ulink> - the Spring Batch Reference Model</para>
</section>
<section>
<title id="c.2"><ulink url="infrastructure.html">Chapter 2: The Spring Batch Infrastructure</ulink></title>
<para>Infrastructure covers Repeat Template, I/O facilities and the RetryTemplate</para>
</section>
<section>
<title id="c.3"><ulink url="core.html">Chapter 3: Spring Batch Core</ulink></title>
<para>Describe the domain language of batch and how the pieces fit together.</para>
</section>
<section>
<title id="c.4"><ulink url="execution.html">Chapter 4: Spring Batch Execution</ulink></title>
<para>Describe the simple batch execution environment.</para>
</section>
<section>
<title id="c.5"><ulink url="application.html">Chapter 5: Spring Batch Applications</ulink></title>
<para>Describe the solution space for spring batch.</para>
</section>
<section>
<title id="c.6"><ulink url="samples.html">Chapter 6: Spring Batch Samples</ulink></title>
<para>The documentation for samples goes here</para>
</section>
<section>
<title id="c.7"><ulink url="batch-job-testing.html">Chapter 7: Unit and Integration Testing Batch Jobs</ulink></title>
<para>The documentation for unit and integration testing of batch jobs goes here.</para>
</section>
<section>
<title id="c.8"><ulink url="batch-performance-testing.html">Chapter 8: Performance Testing Batch Jobs</ulink></title>
<para>How to performance test batch jobs.</para>
</section>
<section>
<title id="9"><ulink url="glossary.html">Chapter 9: Glossary</ulink></title>
<para>(Should this be Appendix A?) The Batch Glossary documents common terms used in the batch processing domain.</para>
</section>
<section>
<title>More sections that may come later?</title>
<para>More advanced info about building Spring Batch, how to contribute, JMS integration, management with JMX, the Spring Batch data model, integration with schedulers (eg quartz)</para>
</section>
</book>

View File

@@ -0,0 +1,10 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="Partitioned Containers">
<title>Batch IO Support</title>
<section>
<title id="s.1">Partitioned Containers</title>
<para>Much stuff goes here.</para>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,301 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="spring-batch-intro">
<title>Spring Batch Introduction</title>
<section>
<title id="s.1">Introduction</title>
<para>Many applications within the enterprise domain require bulk
processing to perform business operations in mission critical
environments. These business operations include automated, complex
processing of large volumes of information that is most efficiently
processed without user interaction. These operations typically include
time based events (e.g. month-end calculations, notices or
correspondence), periodic application of complex business rules processed
repetitively across very large data sets (e.g. insurance benefit
determination or rate adjustments), or the integration of information that
is received from internal and external systems that typically requires
formatting, validation and processing in a transactional manner into the
system of record. Batch processing is used to process billions of
transactions every day for enterprises.</para>
<para>Spring Batch is a lightweight, comprehensive batch framework
designed to enable the development of robust batch applications vital for
the daily operations of enterprise systems. Spring Batch builds upon the
productivity, POJO-based development approach, and general ease of use
capabilities people have come to know from the Spring Framework, while
making it easy for developers to access and leverage more advance
enterprise services when necessary.</para>
<para>Spring Batch provides reusable functions that are essential in
processing large volumes of records, including logging/tracing,
transaction management, job processing statistics, job restart, skip, and
resource management. It also provides more advance technical services and
features that will enable extremely high-volume and high performance batch
jobs though optimization and partitioning techniques. Simple as well as
complex, high-volume batch jobs can leverage the framework in a highly
scalable manner to process significant volumes of information.</para>
<para>Spring Batch is part of the <ulink
url="http://www.springframework.org/sub-projects">Spring
Portfolio</ulink>.</para>
<section>
<title id="s.1.1">Spring Batch Architecture</title>
<para>Spring Batch is designed with extensibility and a diverse group of
end users in mind. The figure below shows a sketch of the layered
architecture that supports the extensibility and ease of use for
end-user developers. <mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../resources/reference/images/ExecutionEnvironment.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/ExecutionEnvironment.png"
format="PNG" />
</imageobject>
<caption><para>Figure 1.1: Batch Execution
Environments</para></caption>
</mediaobject></para>
</section>
<section>
<title id="s.1.2">Supporting Batch Execution Environments</title>
<para>Spring Batch Architecture showing potential execution environment
implementations support different platforms and end-user goals from the
same blocks of business logic in the Application Layer. The initial
release provides an Infrastructure layer in the form of low level tools.
There is also a simple batch execution environment with sample jobs,
using the infrastructure in its implementation. The batch execution
environment provides robust features for traceability and management of
the batch lifecycle. A key goal is that the management of the batch
process (locating a job and its input, starting, scheduling, restarting,
and finally processing to created results) should be as easy as possible
for developers.</para>
<para>The Infrastructure provides the ability to batch operations
together, and to retry an piece of work if there is an exception. Both
requirements have a transactional flavour, and similar concepts are
relevant (propagation, synchronisation). They also both lend themselves
to the template programming model common in Spring, c.f.
<literal>TransactionTemplate</literal>, <literal>JdbcTemplate</literal>,
<literal>JmsTemplate</literal>.</para>
<para>The Simple Batch Execution environment is the first execution
environment available. It provides a robust set of integrated features
including logging/tracing, transaction management, job processing
statistics, job restart, skip, and resource management to enable the
management of the full lifecycle of traditional batch processing. A
number of sample jobs are packaged with this execution environment and
are described in detail to more clearly articulate usage and
capabilities of the execution environment.</para>
<para>The runtime dependencies of infrastructure, core and execution are
shown in the figure below. <mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../resources/reference/images/RuntimeDependencies.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/RuntimeDependencies.png"
format="PNG" />
</imageobject>
<caption><para>Figure 1.2: Runtime Dependencies</para></caption>
</mediaobject></para>
</section>
<section>
<title id="s.1.3">Roadmap</title>
<para>Once the framework is released it can be used immediately to
simplify batch optimisations and automatic retries. The framework is
oriented around application developers not needing to know any details
of the framework - there are a few application developer interfaces that
can be used for convenient construction of data processing pipelines,
but apart from that we support as close to a POJO programming model as
is practical. This is similar to the approach taken in Spring Core in
the area of DAO implementation.</para>
<para>A Partitioned Batch Execution Environment is also being developed
that will provide an alternate scaling solution. This execution
environment will provide more advance technical services and features to
enable extremely high-volume and high performance batch jobs though
proven optimization and partitioning techniques. Proven scaling
techniques will be provided as partitioned strategies allowing users to
spread the load across a pool of clustered J2EE application servers.
There are also discussions to leverage grid technologies as an alternate
scaling solution.</para>
<para>Matt Welsh's work shows that <ulink
url="http://www.eecs.harvard.edu/~mdw/proj/seda/">SEDA</ulink> has
enormous benefits over more rigid processing architectures, and
messaging environments provde a lot of resilience out of the box. So we
also want to provide a more SEDA flavoured execution environment, as
well as supporting the more traditional ETL style approach. There might
be a tie in with Mule and/or other ESB tools here, giving the benefit of
a very scalable architecture, where the choice of transport and
distribution strategy can be made as late as possible. The same
application code could be used in principle for a standalone tool
processing a small amount of data, and a massive enterprise-scale
bulk-processing engine.</para>
</section>
<section>
<title id="s.1.4">Background</title>
<para>While open source software projects and associated communities
have focused greater attention on web-based and SOA messaging-based
architecture frameworks, there has been a notable lack of focus on
reusable architecture frameworks to accommodate Java-based batch
processing needs, despite continued needs to handle such processing
within enterprise IT environments. The lack of a standard, reusable
batch architecture has resulted in the proliferation of many one-off,
in-house solutions developed within client enterprise IT
functions.</para>
<para>Interface21 and Accenture are collaborating to change this.
Accenture's hands-on industry and technical experience in implementing
batch architectures, Interface21's depth of technical experience, and
Spring's proven programming model together mark a natural and powerful
partnership to create high-quality, market relevant software aimed at
filling an important gap in enterprise Java. Both companies are also
currently working with a number of clients solving similar problems
developing Spring-based batch architecture solutions. This has provided
some useful additional detail and real-life constraints helping to
ensure the solution can be applied to the real-world problems posed by
clients. For these reasons and many more, Interface21 and Accenture have
teamed to collaborate on the development of Spring Batch.</para>
<para>Accenture is contributing previously proprietary batch processing
architecture frameworks -- based upon decades worth of experience in
building batch architectures with the last several generations of
platforms (i.e., COBOL/Mainframe, C++/Unix, and now Java/anywhere) -- to
the Spring Batch project along with committer resources to drive
support, enhancements, and the future roadmap.</para>
<para>The collaborative effort between Accenture and Interface21 aims to
promote the standardization of software processing approaches,
frameworks, and tools that can be consistently leveraged by enterprise
users when creating batch applications. Companies and government
agencies desiring to deliver standard, proven solutions to their
enterprise IT environments will benefit from Spring Batch.</para>
</section>
</section>
<section>
<title id="s-b-i.1.2">Usage Scenarios</title>
<para>Spring Batch provides a technical framework and programming model to
support long-running processes that perform a given set of tasks
repetitively. A typical batch program generally reads a large number of
records from a database, file, or queue, processes the data in some
fashion, and then writes back data in a modified form. Spring Batch
automates this basic batch iteration, providing the capability to process
similar transactions as a set, typically in an offline environment without
any user interaction. Batch jobs are part of most IT projects and Spring
Batch is the only open source framework that provides a robust,
enterprise-scale solution. Batch processing is an application style for
many enterprise data processing pipelines (e.g. payment and settlement
systems), and the lack of a standard architecture has led many projects to
create their own custom architecture at significant development and
maintenance costs.</para>
<para>Business Scenarios <itemizedlist>
<listitem>
<para>Commit batch process periodically</para>
</listitem>
<listitem>
<para>Concurrent batch processing: parallel processing of a
job</para>
</listitem>
<listitem>
<para>Staged, enterprise message-driven processing</para>
</listitem>
<listitem>
<para>Massively parallel batch processing</para>
</listitem>
<listitem>
<para>Manual or scheduled restart after failure</para>
</listitem>
<listitem>
<para>Sequential processing of dependent steps (with extensions to
workflow-driven batches)</para>
</listitem>
<listitem>
<para>Partial processing: skip records (e.g. on rollback)</para>
</listitem>
<listitem>
<para>Whole-batch transaction: for cases with a simple enough data
model or a small batch size</para>
</listitem>
</itemizedlist></para>
<para>Technical Objectives <itemizedlist>
<listitem>
<para>Batch developers use the Spring programming model: concentrate
on business logic; let the framework take care of
infrastructure.</para>
</listitem>
<listitem>
<para>Clear separation of concerns between the infrastructure, the
batch execution environment, and the batch application.</para>
</listitem>
<listitem>
<para>Provide common, core execution services as interfaces that all
projects can implement.</para>
</listitem>
<listitem>
<para>Provide simple and default implementations of the core
execution interfaces that can be used out of the box.</para>
</listitem>
<listitem>
<para>Easy to configure, customize, and extend services, by
leveraging the spring framework in all layers.</para>
</listitem>
<listitem>
<para>All existing execution environment services should be easy to
replace or extend, without any impact to the infrastructure
layer.</para>
</listitem>
<listitem>
<para>Provide a simple deployment model, with the architecture JARs
completely separate from the application, built using Maven.</para>
</listitem>
</itemizedlist></para>
</section>
<section>
<title id="s-b-i.1.3">How To Get Started</title>
<para>There are a number of sample applications that can be used to get
started with Spring Batch. They can be found in the samples project. They
are executed either from the command line or as unit tests. See <ulink
url="samples.html">Chapter 6: Practical Examples for Spring Batch</ulink>
as a starting point.</para>
</section>
</chapter>

View File

@@ -0,0 +1,30 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="spring-tasklet">
<title>Tasklet and the Repeat Template</title>
<section>
<title id="sp.1">What is a Tasklet?</title>
<para>Document what a Tasklet is. Include the diagram of showing its place in the batch domain world.</para>
</section>
<section>
<title id="sp.2">Item Providers</title>
<para>Document Item Providers. Discuss some default item providers</para>
</section>
<section>
<title id="sp.3">Item Processor</title>
<para>Talk about default Item Processor</para>
</section>
<section>
<title id="sp.4">Item Provider Process Tasklet</title>
<para>Don't worry about how all the pieces work but focus on Talk about default Item Processor</para>
</section>
<section>
<title id="sp.5">The role of the Repeat Template</title>
<para>The two repeat templates used by ItemProcessor.</para>
</section>
</chapter>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -22,6 +22,11 @@
<menu name="Project Documentation">
<item name="${project.name}" href="index.html"/>
<!-- Useful for debugging with "mvn site:run" -->
<!-- item name="Doxia" href="reference/toc.html"/-->
<item name="Html" href="reference/html/index.html"/>
<item name="Html-Single" href="reference/html-single/index.html"/>
<item name="Pdf" href="reference/pdf/spring-batch-docs.pdf"/>
</menu>
${reports}
</body>