EMMA Coverage Report (generated Fri Jan 30 13:20:29 EST 2009)
[all classes][org.springframework.batch.core.converter]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultJobParametersConverter.java]

nameclass, %method, %block, %line, %
DefaultJobParametersConverter.java100% (1/1)100% (6/6)92%  (287/313)95%  (56.9/60)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultJobParametersConverter100% (1/1)100% (6/6)92%  (287/313)95%  (56.9/60)
getJobParameters (Properties): JobParameters 100% (1/1)86%  (152/177)91%  (31/34)
parseNumber (String): Number 100% (1/1)98%  (39/40)99%  (4/4)
DefaultJobParametersConverter (): void 100% (1/1)100% (15/15)100% (3/3)
getProperties (JobParameters): Properties 100% (1/1)100% (73/73)100% (15/15)
setDateFormat (DateFormat): void 100% (1/1)100% (4/4)100% (2/2)
setNumberFormat (NumberFormat): void 100% (1/1)100% (4/4)100% (2/2)

1/*
2 * Copyright 2006-2008 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 */
16package org.springframework.batch.core.converter;
17 
18import java.text.DateFormat;
19import java.text.DecimalFormat;
20import java.text.NumberFormat;
21import java.text.ParseException;
22import java.text.SimpleDateFormat;
23import java.util.Date;
24import java.util.Iterator;
25import java.util.Map;
26import java.util.Properties;
27import java.util.Map.Entry;
28 
29import org.springframework.batch.core.JobParameters;
30import org.springframework.batch.core.JobParametersBuilder;
31import org.springframework.util.StringUtils;
32 
33/**
34 * Converter for {@link JobParameters} instances using a simple naming
35 * convention for property keys. Key names ending with "(<type>)" where
36 * type is one of string, date, long are converted to the corresponding type.
37 * The default type is string. E.g.
38 * 
39 * <pre>
40 * schedule.date(date)=2007/12/11
41 * department.id(long)=2345
42 * </pre>
43 * 
44 * The literal values are converted to the correct type using the default Spring
45 * strategies, augmented if necessary by the custom editors provided.
46 * 
47 * @author Dave Syer
48 * 
49 */
50public class DefaultJobParametersConverter implements JobParametersConverter {
51 
52        public static final String DATE_TYPE = "(date)";
53 
54        public static final String STRING_TYPE = "(string)";
55 
56        public static final String LONG_TYPE = "(long)";
57 
58        private static final String DOUBLE_TYPE = "(double)";
59 
60        private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
61 
62        private NumberFormat numberFormat = new DecimalFormat("#");
63 
64        /**
65         * Check for suffix on keys and use those to decide how to convert the
66         * value.
67         * 
68         * @throws IllegalArgumentException if a number or date is passed in that
69         * cannot be parsed, or cast to the correct type.
70         * 
71         * @see org.springframework.batch.core.converter.JobParametersConverter#getJobParameters(java.util.Properties)
72         */
73        public JobParameters getJobParameters(Properties props) {
74 
75                if (props == null || props.isEmpty()) {
76                        return new JobParameters();
77                }
78 
79                JobParametersBuilder propertiesBuilder = new JobParametersBuilder();
80 
81                for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
82                        Entry entry = (Entry) it.next();
83                        String key = (String) entry.getKey();
84                        String value = (String) entry.getValue();
85                        if (key.endsWith(DATE_TYPE)) {
86                                Date date;
87                                try {
88                                        date = dateFormat.parse(value);
89                                }
90                                catch (ParseException ex) {
91                                        String suffix = (dateFormat instanceof SimpleDateFormat) ? ", use "
92                                                        + ((SimpleDateFormat) dateFormat).toPattern() : "";
93                                        throw new IllegalArgumentException("Date format is invalid: [" + value + "]" + suffix);
94                                }
95                                propertiesBuilder.addDate(StringUtils.replace(key, DATE_TYPE, ""), date);
96                        }
97                        else if (key.endsWith(LONG_TYPE)) {
98                                Long result;
99                                try {
100                                        result = (Long) parseNumber(value);
101                                }
102                                catch (ClassCastException ex) {
103                                        throw new IllegalArgumentException("Number format is invalid for long value: [" + value
104                                                        + "], use a format with no decimal places");
105                                }
106                                propertiesBuilder.addLong(StringUtils.replace(key, LONG_TYPE, ""), result);
107                        }
108                        else if (key.endsWith(DOUBLE_TYPE)) {
109                                Double result;
110                                try {
111                                        result = (Double) parseNumber(value);
112                                }
113                                catch (ClassCastException ex) {
114                                        throw new IllegalArgumentException("Number format is invalid for double value: [" + value + "]");
115                                }
116                                propertiesBuilder.addDouble(StringUtils.replace(key, DOUBLE_TYPE, ""), result);
117                        }
118                        else if (StringUtils.endsWithIgnoreCase(key, STRING_TYPE)) {
119                                propertiesBuilder.addString(StringUtils.replace(key, STRING_TYPE, ""), value);
120                        }
121                        else {
122                                propertiesBuilder.addString(key, value.toString());
123                        }
124                }
125 
126                return propertiesBuilder.toJobParameters();
127        }
128 
129        /**
130         * Delegate to {@link NumberFormat} to parse the value
131         */
132        private Number parseNumber(String value) {
133                try {
134                        return numberFormat.parse(value);
135                }
136                catch (ParseException ex) {
137                        String suffix = (numberFormat instanceof DecimalFormat) ? ", use "
138                                        + ((DecimalFormat) numberFormat).toPattern() : "";
139                        throw new IllegalArgumentException("Number format is invalid: [" + value + "], use " + suffix);
140                }
141        }
142 
143        /**
144         * Use the same suffixes to create properties (omitting the string suffix
145         * because it is the default).
146         * 
147         * @see org.springframework.batch.core.converter.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters)
148         */
149        public Properties getProperties(JobParameters params) {
150 
151                if (params == null || params.isEmpty()) {
152                        return new Properties();
153                }
154 
155                Map parameters = params.getParameters();
156                Properties result = new Properties();
157                for (Iterator iterator = parameters.entrySet().iterator(); iterator.hasNext();) {
158                        Entry entry = (Entry) iterator.next();
159                        String key = (String) entry.getKey();
160                        Object value = entry.getValue();
161                        if (value instanceof Date) {
162                                result.setProperty(key, dateFormat.format(value));
163                        }
164                        else if (value instanceof Long) {
165                                result.setProperty(key, numberFormat.format(value));
166                        }
167                        else {
168                                result.setProperty(key, "" + value);
169                        }
170                }
171                return result;
172        }
173 
174        /**
175         * Public setter for injecting a date format.
176         * 
177         * @param dateFormat a {@link DateFormat}, defaults to "yyyy/MM/dd"
178         */
179        public void setDateFormat(DateFormat dateFormat) {
180                this.dateFormat = dateFormat;
181        }
182 
183        /**
184         * Public setter for the {@link NumberFormat}. Used to parse longs, so must
185         * not contain decimal place (e.g. use "#" or "#,###").
186         * 
187         * @param numberFormat the {@link NumberFormat} to set
188         */
189        public void setNumberFormat(NumberFormat numberFormat) {
190                this.numberFormat = numberFormat;
191        }
192}

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