EMMA Coverage Report (generated Thu May 22 12:08:10 CDT 2014)
[all classes][org.springframework.batch.item.support]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractItemCountingItemStreamItemReader.java]

nameclass, %method, %block, %line, %
AbstractItemCountingItemStreamItemReader.java100% (1/1)100% (11/11)92%  (158/172)93%  (50/54)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractItemCountingItemStreamItemReader100% (1/1)100% (11/11)92%  (158/172)93%  (50/54)
close (): void 100% (1/1)56%  (9/16)71%  (5/7)
open (ExecutionContext): void 100% (1/1)89%  (54/61)89%  (16/18)
AbstractItemCountingItemStreamItemReader (): void 100% (1/1)100% (12/12)100% (4/4)
getCurrentItemCount (): int 100% (1/1)100% (3/3)100% (1/1)
isSaveState (): boolean 100% (1/1)100% (3/3)100% (1/1)
jumpToItem (int): void 100% (1/1)100% (11/11)100% (3/3)
read (): Object 100% (1/1)100% (26/26)100% (7/7)
setCurrentItemCount (int): void 100% (1/1)100% (4/4)100% (2/2)
setMaxItemCount (int): void 100% (1/1)100% (4/4)100% (2/2)
setSaveState (boolean): void 100% (1/1)100% (4/4)100% (2/2)
update (ExecutionContext): void 100% (1/1)100% (28/28)100% (7/7)

1/*
2 * Copyright 2006-2013 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.item.support;
18 
19import org.springframework.batch.item.ExecutionContext;
20import org.springframework.batch.item.ItemCountAware;
21import org.springframework.batch.item.ItemReader;
22import org.springframework.batch.item.ItemStreamException;
23import org.springframework.batch.item.ParseException;
24import org.springframework.batch.item.UnexpectedInputException;
25import org.springframework.util.Assert;
26 
27/**
28 * Abstract superclass for {@link ItemReader}s that supports restart by storing
29 * item count in the {@link ExecutionContext} (therefore requires item ordering
30 * to be preserved between runs).
31 * 
32 * Subclasses are inherently *not* thread-safe.
33 * 
34 * @author Robert Kasanicky
35 */
36public abstract class AbstractItemCountingItemStreamItemReader<T> extends AbstractItemStreamItemReader<T> {
37 
38        private static final String READ_COUNT = "read.count";
39 
40        private static final String READ_COUNT_MAX = "read.count.max";
41 
42        private int currentItemCount = 0;
43 
44        private int maxItemCount = Integer.MAX_VALUE;
45 
46        private boolean saveState = true;
47 
48        /**
49         * Read next item from input.
50         * 
51         * @return item
52         * @throws Exception
53         */
54        protected abstract T doRead() throws Exception;
55 
56        /**
57         * Open resources necessary to start reading input.
58         */
59        protected abstract void doOpen() throws Exception;
60 
61        /**
62         * Close the resources opened in {@link #doOpen()}.
63         */
64        protected abstract void doClose() throws Exception;
65 
66        /**
67         * Move to the given item index. Subclasses should override this method if
68         * there is a more efficient way of moving to given index than re-reading
69         * the input using {@link #doRead()}.
70         */
71        protected void jumpToItem(int itemIndex) throws Exception {
72                for (int i = 0; i < itemIndex; i++) {
73                        read();
74                }
75        }
76 
77        @Override
78        public T read() throws Exception, UnexpectedInputException, ParseException {
79                if (currentItemCount >= maxItemCount) {
80                        return null;
81                }
82                currentItemCount++;
83                T item = doRead();
84                if(item instanceof ItemCountAware) {
85                        ((ItemCountAware) item).setItemCount(currentItemCount);
86                }
87                return item;
88        }
89 
90        protected int getCurrentItemCount() {
91                return currentItemCount;
92        }
93 
94        /**
95         * The index of the item to start reading from. If the
96         * {@link ExecutionContext} contains a key <code>[name].read.count</code>
97         * (where <code>[name]</code> is the name of this component) the value from
98         * the {@link ExecutionContext} will be used in preference.
99         * 
100         * @see #setName(String)
101         * 
102         * @param count the value of the current item count
103         */
104        public void setCurrentItemCount(int count) {
105                this.currentItemCount = count;
106        }
107 
108        /**
109         * The maximum index of the items to be read. If the
110         * {@link ExecutionContext} contains a key
111         * <code>[name].read.count.max</code> (where <code>[name]</code> is the name
112         * of this component) the value from the {@link ExecutionContext} will be
113         * used in preference.
114         * 
115         * @see #setName(String)
116         * 
117         * @param count the value of the maximum item count
118         */
119        public void setMaxItemCount(int count) {
120                this.maxItemCount = count;
121        }
122 
123        @Override
124        public void close() throws ItemStreamException {
125                super.close();
126                currentItemCount = 0;
127                try {
128                        doClose();
129                }
130                catch (Exception e) {
131                        throw new ItemStreamException("Error while closing item reader", e);
132                }
133        }
134 
135        @Override
136        public void open(ExecutionContext executionContext) throws ItemStreamException {
137                super.open(executionContext);
138                try {
139                        doOpen();
140                }
141                catch (Exception e) {
142                        throw new ItemStreamException("Failed to initialize the reader", e);
143                }
144                if (!isSaveState()) {
145                        return;
146                }
147 
148                if (executionContext.containsKey(getExecutionContextKey(READ_COUNT_MAX))) {
149                        maxItemCount = executionContext.getInt(getExecutionContextKey(READ_COUNT_MAX));
150                }
151 
152                if (executionContext.containsKey(getExecutionContextKey(READ_COUNT))) {
153                        int itemCount = executionContext.getInt(getExecutionContextKey(READ_COUNT));
154 
155                        if (itemCount < maxItemCount) {
156                                try {
157                                        jumpToItem(itemCount);
158                                }
159                                catch (Exception e) {
160                                        throw new ItemStreamException("Could not move to stored position on restart", e);
161                                }
162                        }
163                        currentItemCount = itemCount;
164 
165                }
166 
167        }
168 
169        @Override
170        public void update(ExecutionContext executionContext) throws ItemStreamException {
171                super.update(executionContext);
172                if (saveState) {
173                        Assert.notNull(executionContext, "ExecutionContext must not be null");
174                        executionContext.putInt(getExecutionContextKey(READ_COUNT), currentItemCount);
175                        if (maxItemCount < Integer.MAX_VALUE) {
176                                executionContext.putInt(getExecutionContextKey(READ_COUNT_MAX), maxItemCount);
177                        }
178                }
179 
180        }
181 
182 
183        /**
184         * Set the flag that determines whether to save internal data for
185         * {@link ExecutionContext}. Only switch this to false if you don't want to
186         * save any state from this stream, and you don't need it to be restartable.
187         * Always set it to false if the reader is being used in a concurrent
188         * environment.
189         * 
190         * @param saveState flag value (default true).
191         */
192        public void setSaveState(boolean saveState) {
193                this.saveState = saveState;
194        }
195 
196        /**
197         * The flag that determines whether to save internal state for restarts.
198         * @return true if the flag was set
199         */
200        public boolean isSaveState() {
201                return saveState;
202        }
203 
204}

[all classes][org.springframework.batch.item.support]
EMMA 2.0.5312 (C) Vladimir Roubtsov