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

COVERAGE SUMMARY FOR SOURCE FILE [JdbcExecutionContextDao.java]

nameclass, %method, %block, %line, %
JdbcExecutionContextDao.java100% (4/4)96%  (25/26)86%  (472/549)91%  (108.8/120)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JdbcExecutionContextDao$2100% (1/1)100% (3/3)66%  (55/83)80%  (12/15)
setValues (PreparedStatement, int): void 100% (1/1)58%  (39/67)77%  (10/13)
JdbcExecutionContextDao$2 (JdbcExecutionContextDao, Iterator, Map): void 100% (1/1)100% (12/12)100% (1/1)
getBatchSize (): int 100% (1/1)100% (4/4)100% (1/1)
     
class JdbcExecutionContextDao$1100% (1/1)100% (2/2)78%  (36/46)86%  (6/7)
setValues (PreparedStatement): void 100% (1/1)68%  (21/31)83%  (5/6)
JdbcExecutionContextDao$1 (JdbcExecutionContextDao, String, String, Long): void 100% (1/1)100% (15/15)100% (1/1)
     
class JdbcExecutionContextDao$ExecutionContextRowMapper100% (1/1)100% (3/3)90%  (60/67)86%  (12/14)
mapRow (ResultSet, int): ExecutionContext 100% (1/1)88%  (50/57)85%  (11/13)
JdbcExecutionContextDao$ExecutionContextRowMapper (JdbcExecutionContextDao): ... 100% (1/1)100% (6/6)100% (1/1)
JdbcExecutionContextDao$ExecutionContextRowMapper (JdbcExecutionContextDao, J... 100% (1/1)100% (4/4)100% (1/1)
     
class JdbcExecutionContextDao100% (1/1)94%  (17/18)91%  (321/353)94%  (80.8/86)
access$100 (JdbcExecutionContextDao): LobHandler 0%   (0/1)0%   (0/3)0%   (0/1)
persistSerializedContext (Long, String, String): void 100% (1/1)57%  (24/42)71%  (5/7)
serializeContext (ExecutionContext): String 100% (1/1)86%  (44/51)83%  (10/12)
getExecutionContext (StepExecution): ExecutionContext 100% (1/1)89%  (32/36)83%  (5/6)
JdbcExecutionContextDao (): void 100% (1/1)100% (11/11)100% (4/4)
access$200 (JdbcExecutionContextDao): int 100% (1/1)100% (3/3)100% (1/1)
access$300 (JdbcExecutionContextDao): ExecutionContextSerializer 100% (1/1)100% (3/3)100% (1/1)
afterPropertiesSet (): void 100% (1/1)100% (3/3)100% (2/2)
getExecutionContext (JobExecution): ExecutionContext 100% (1/1)100% (36/36)100% (6/6)
persistSerializedContexts (Map, String): void 100% (1/1)100% (21/21)100% (4/4)
saveExecutionContext (JobExecution): void 100% (1/1)100% (22/22)100% (7/7)
saveExecutionContext (StepExecution): void 100% (1/1)100% (22/22)100% (7/7)
saveExecutionContexts (Collection): void 100% (1/1)100% (44/44)100% (11/11)
setLobHandler (LobHandler): void 100% (1/1)100% (4/4)100% (2/2)
setSerializer (ExecutionContextSerializer): void 100% (1/1)100% (4/4)100% (2/2)
setShortContextLength (int): void 100% (1/1)100% (4/4)100% (2/2)
updateExecutionContext (JobExecution): void 100% (1/1)100% (22/22)100% (7/7)
updateExecutionContext (StepExecution): void 100% (1/1)100% (22/22)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.core.repository.dao;
18 
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.IOException;
22import java.sql.PreparedStatement;
23import java.sql.ResultSet;
24import java.sql.SQLException;
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.Iterator;
28import java.util.List;
29import java.util.Map;
30import java.util.Map.Entry;
31 
32import org.springframework.batch.core.JobExecution;
33import org.springframework.batch.core.StepExecution;
34import org.springframework.batch.core.repository.ExecutionContextSerializer;
35import org.springframework.batch.item.ExecutionContext;
36import org.springframework.core.serializer.Serializer;
37import org.springframework.jdbc.core.BatchPreparedStatementSetter;
38import org.springframework.jdbc.core.PreparedStatementSetter;
39import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
40import org.springframework.jdbc.support.lob.DefaultLobHandler;
41import org.springframework.jdbc.support.lob.LobHandler;
42import org.springframework.util.Assert;
43 
44/**
45 * JDBC DAO for {@link ExecutionContext}.
46 *
47 * Stores execution context data related to both Step and Job using
48 * a different table for each.
49 *
50 * @author Lucas Ward
51 * @author Robert Kasanicky
52 * @author Thomas Risberg
53 * @author Michael Minella
54 * @author David Turanski
55 */
56public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implements ExecutionContextDao {
57 
58        private static final String FIND_JOB_EXECUTION_CONTEXT = "SELECT SHORT_CONTEXT, SERIALIZED_CONTEXT "
59                        + "FROM %PREFIX%JOB_EXECUTION_CONTEXT WHERE JOB_EXECUTION_ID = ?";
60 
61        private static final String INSERT_JOB_EXECUTION_CONTEXT = "INSERT INTO %PREFIX%JOB_EXECUTION_CONTEXT "
62                        + "(SHORT_CONTEXT, SERIALIZED_CONTEXT, JOB_EXECUTION_ID) " + "VALUES(?, ?, ?)";
63 
64        private static final String UPDATE_JOB_EXECUTION_CONTEXT = "UPDATE %PREFIX%JOB_EXECUTION_CONTEXT "
65                        + "SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? " + "WHERE JOB_EXECUTION_ID = ?";
66 
67        private static final String FIND_STEP_EXECUTION_CONTEXT = "SELECT SHORT_CONTEXT, SERIALIZED_CONTEXT "
68                        + "FROM %PREFIX%STEP_EXECUTION_CONTEXT WHERE STEP_EXECUTION_ID = ?";
69 
70        private static final String INSERT_STEP_EXECUTION_CONTEXT = "INSERT INTO %PREFIX%STEP_EXECUTION_CONTEXT "
71                        + "(SHORT_CONTEXT, SERIALIZED_CONTEXT, STEP_EXECUTION_ID) " + "VALUES(?, ?, ?)";
72 
73        private static final String UPDATE_STEP_EXECUTION_CONTEXT = "UPDATE %PREFIX%STEP_EXECUTION_CONTEXT "
74                        + "SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? " + "WHERE STEP_EXECUTION_ID = ?";
75 
76        private static final int DEFAULT_MAX_VARCHAR_LENGTH = 2500;
77 
78        private int shortContextLength = DEFAULT_MAX_VARCHAR_LENGTH;
79 
80        private LobHandler lobHandler = new DefaultLobHandler();
81 
82        private ExecutionContextSerializer serializer;
83 
84        /**
85         * Setter for {@link Serializer} implementation
86         *
87         * @param serializer
88         */
89        public void setSerializer(ExecutionContextSerializer serializer) {
90                this.serializer = serializer;
91        }
92 
93        /**
94         * The maximum size that an execution context can have and still be stored
95         * completely in short form in the column <code>SHORT_CONTEXT</code>.
96         * Anything longer than this will overflow into large-object storage, and
97         * the first part only will be retained in the short form for readability.
98         * Default value is 2500. Clients using multi-bytes charsets on the database
99         * server may need to reduce this value to as little as half the value of
100         * the column size.
101         * @param shortContextLength
102         */
103        public void setShortContextLength(int shortContextLength) {
104                this.shortContextLength = shortContextLength;
105        }
106 
107        @Override
108        public ExecutionContext getExecutionContext(JobExecution jobExecution) {
109                Long executionId = jobExecution.getId();
110                Assert.notNull(executionId, "ExecutionId must not be null.");
111 
112                List<ExecutionContext> results = getJdbcTemplate().query(getQuery(FIND_JOB_EXECUTION_CONTEXT),
113                                new ExecutionContextRowMapper(), executionId);
114                if (results.size() > 0) {
115                        return results.get(0);
116                }
117                else {
118                        return new ExecutionContext();
119                }
120        }
121 
122        @Override
123        public ExecutionContext getExecutionContext(StepExecution stepExecution) {
124                Long executionId = stepExecution.getId();
125                Assert.notNull(executionId, "ExecutionId must not be null.");
126 
127                List<ExecutionContext> results = getJdbcTemplate().query(getQuery(FIND_STEP_EXECUTION_CONTEXT),
128                                new ExecutionContextRowMapper(), executionId);
129                if (results.size() > 0) {
130                        return results.get(0);
131                }
132                else {
133                        return new ExecutionContext();
134                }
135        }
136 
137        @Override
138        public void updateExecutionContext(final JobExecution jobExecution) {
139                Long executionId = jobExecution.getId();
140                ExecutionContext executionContext = jobExecution.getExecutionContext();
141                Assert.notNull(executionId, "ExecutionId must not be null.");
142                Assert.notNull(executionContext, "The ExecutionContext must not be null.");
143 
144                String serializedContext = serializeContext(executionContext);
145 
146                persistSerializedContext(executionId, serializedContext, UPDATE_JOB_EXECUTION_CONTEXT);
147        }
148 
149        @Override
150        public void updateExecutionContext(final StepExecution stepExecution) {
151 
152                Long executionId = stepExecution.getId();
153                ExecutionContext executionContext = stepExecution.getExecutionContext();
154                Assert.notNull(executionId, "ExecutionId must not be null.");
155                Assert.notNull(executionContext, "The ExecutionContext must not be null.");
156 
157                String serializedContext = serializeContext(executionContext);
158 
159                persistSerializedContext(executionId, serializedContext, UPDATE_STEP_EXECUTION_CONTEXT);
160        }
161 
162        @Override
163        public void saveExecutionContext(JobExecution jobExecution) {
164 
165                Long executionId = jobExecution.getId();
166                ExecutionContext executionContext = jobExecution.getExecutionContext();
167                Assert.notNull(executionId, "ExecutionId must not be null.");
168                Assert.notNull(executionContext, "The ExecutionContext must not be null.");
169 
170                String serializedContext = serializeContext(executionContext);
171 
172                persistSerializedContext(executionId, serializedContext, INSERT_JOB_EXECUTION_CONTEXT);
173        }
174 
175        @Override
176        public void saveExecutionContext(StepExecution stepExecution) {
177                Long executionId = stepExecution.getId();
178                ExecutionContext executionContext = stepExecution.getExecutionContext();
179                Assert.notNull(executionId, "ExecutionId must not be null.");
180                Assert.notNull(executionContext, "The ExecutionContext must not be null.");
181 
182                String serializedContext = serializeContext(executionContext);
183 
184                persistSerializedContext(executionId, serializedContext, INSERT_STEP_EXECUTION_CONTEXT);
185        }
186 
187        @Override
188        public void saveExecutionContexts(Collection<StepExecution> stepExecutions) {
189                Assert.notNull(stepExecutions, "Attempt to save an null collection of step executions");
190                Map<Long, String> serializedContexts = new HashMap<Long, String>(stepExecutions.size());
191                for (StepExecution stepExecution : stepExecutions) {
192                        Long executionId = stepExecution.getId();
193                        ExecutionContext executionContext = stepExecution.getExecutionContext();
194                        Assert.notNull(executionId, "ExecutionId must not be null.");
195                        Assert.notNull(executionContext, "The ExecutionContext must not be null.");
196                        serializedContexts.put(executionId, serializeContext(executionContext));
197                }
198                persistSerializedContexts(serializedContexts, INSERT_STEP_EXECUTION_CONTEXT);
199        }
200 
201        public void setLobHandler(LobHandler lobHandler) {
202                this.lobHandler = lobHandler;
203        }
204 
205        @Override
206        public void afterPropertiesSet() throws Exception {
207                super.afterPropertiesSet();
208        }
209 
210        /**
211         * @param executionId
212         * @param serializedContext
213         * @param sql with parameters (shortContext, longContext, executionId)
214         */
215        private void persistSerializedContext(final Long executionId, String serializedContext, String sql) {
216 
217                final String shortContext;
218                final String longContext;
219                if (serializedContext.length() > shortContextLength) {
220                        // Overestimate length of ellipsis to be on the safe side with
221                        // 2-byte chars
222                        shortContext = serializedContext.substring(0, shortContextLength - 8) + " ...";
223                        longContext = serializedContext;
224                }
225                else {
226                        shortContext = serializedContext;
227                        longContext = null;
228                }
229 
230                getJdbcTemplate().update(getQuery(sql), new PreparedStatementSetter() {
231                        @Override
232                        public void setValues(PreparedStatement ps) throws SQLException {
233                                ps.setString(1, shortContext);
234                                if (longContext != null) {
235                                        lobHandler.getLobCreator().setClobAsString(ps, 2, longContext);
236                                }
237                                else {
238                                        ps.setNull(2, getClobTypeToUse());
239                                }
240                                ps.setLong(3, executionId);
241                        }
242                });
243        }
244 
245        /**
246         * @param executionId
247         * @param serializedContext
248         * @param sql with parameters (shortContext, longContext, executionId)
249         */
250        private void persistSerializedContexts(final Map<Long, String> serializedContexts, String sql) {
251        if (!serializedContexts.isEmpty()) {
252            final Iterator<Long> executionIdIterator = serializedContexts.keySet().iterator();
253 
254            getJdbcTemplate().batchUpdate(getQuery(sql), new BatchPreparedStatementSetter() {
255                @Override
256                public void setValues(PreparedStatement ps, int i) throws SQLException {
257                    Long executionId = executionIdIterator.next();
258                    String serializedContext = serializedContexts.get(executionId);
259                    String shortContext;
260                    String longContext;
261                    if (serializedContext.length() > shortContextLength) {
262                        // Overestimate length of ellipsis to be on the safe side with
263                        // 2-byte chars
264                        shortContext = serializedContext.substring(0, shortContextLength - 8) + " ...";
265                        longContext = serializedContext;
266                    } else {
267                        shortContext = serializedContext;
268                        longContext = null;
269                    }
270                    ps.setString(1, shortContext);
271                    if (longContext != null) {
272                        lobHandler.getLobCreator().setClobAsString(ps, 2, longContext);
273                    } else {
274                        ps.setNull(2, getClobTypeToUse());
275                    }
276                    ps.setLong(3, executionId);
277                }
278 
279                @Override
280                public int getBatchSize() {
281                    return serializedContexts.size();
282                }
283            });
284        }
285    }
286 
287        @SuppressWarnings("unchecked")
288        private String serializeContext(ExecutionContext ctx) {
289                Map<String, Object> m = new HashMap<String, Object>();
290                for (Entry<String, Object> me : ctx.entrySet()) {
291                        m.put(me.getKey(), me.getValue());
292                }
293 
294                ByteArrayOutputStream out = new ByteArrayOutputStream();
295                String results = "";
296 
297                try {
298                        serializer.serialize(m, out);
299                        results = new String(out.toByteArray(), "ISO-8859-1");
300                }
301                catch (IOException ioe) {
302                        throw new IllegalArgumentException("Could not serialize the execution context", ioe);
303                }
304 
305                return results;
306        }
307 
308        @SuppressWarnings("unchecked")
309        private class ExecutionContextRowMapper implements ParameterizedRowMapper<ExecutionContext> {
310 
311                @Override
312                public ExecutionContext mapRow(ResultSet rs, int i) throws SQLException {
313                        ExecutionContext executionContext = new ExecutionContext();
314                        String serializedContext = rs.getString("SERIALIZED_CONTEXT");
315                        if (serializedContext == null) {
316                                serializedContext = rs.getString("SHORT_CONTEXT");
317                        }
318 
319                        Map<String, Object> map;
320                        try {
321                                ByteArrayInputStream in = new ByteArrayInputStream(serializedContext.getBytes("ISO-8859-1"));
322                                map = (Map<String, Object>) serializer.deserialize(in);
323                        }
324                        catch (IOException ioe) {
325                                throw new IllegalArgumentException("Unable to deserialize the execution context", ioe);
326                        }
327                        for (Map.Entry<String, Object> entry : map.entrySet()) {
328                                executionContext.put(entry.getKey(), entry.getValue());
329                        }
330                        return executionContext;
331                }
332        }
333 
334}

[all classes][org.springframework.batch.core.repository.dao]
EMMA 2.0.5312 (C) Vladimir Roubtsov