EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[all classes][org.springframework.batch.core.converter]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultJobParametersConverter.java]

nameclass, %method, %block, %line, %
DefaultJobParametersConverter.java100% (1/1)100% (8/8)97%  (348/359)98%  (63.9/65)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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