001/*
002 * Copyright 2006-2013 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.springframework.batch.core.step.job;
017
018import java.util.Arrays;
019import java.util.Date;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
023
024import org.springframework.batch.core.Job;
025import org.springframework.batch.core.JobParameter;
026import org.springframework.batch.core.JobParameters;
027import org.springframework.batch.core.JobParametersBuilder;
028import org.springframework.batch.core.StepExecution;
029import org.springframework.batch.item.ExecutionContext;
030
031/**
032 * Simple implementation of {@link JobParametersExtractor} which pulls
033 * parameters with named keys out of the step execution context and the job
034 * parameters of the surrounding job.
035 *
036 * @author Dave Syer
037 * @author Will Schipp
038 *
039 */
040public class DefaultJobParametersExtractor implements JobParametersExtractor {
041
042        private Set<String> keys = new HashSet<String>();
043
044        private boolean useAllParentParameters = true;
045
046        /**
047         * The key names to pull out of the execution context or job parameters, if
048         * they exist. If a key doesn't exist in the execution context then the job
049         * parameters from the enclosing job execution are tried, and if there is
050         * nothing there either then no parameter is extracted. Key names ending
051         * with <code>(long)</code>, <code>(int)</code>, <code>(double)</code>,
052         * <code>(date)</code> or <code>(string)</code> will be assumed to refer to
053         * values of the respective type and assigned to job parameters accordingly
054         * (there will be an error if they are not of the right type). Without a
055         * special suffix in that form a parameter is assumed to be of type String.
056         *
057         * @param keys the keys to set
058         */
059        public void setKeys(String[] keys) {
060                this.keys = new HashSet<String>(Arrays.asList(keys));
061        }
062
063        /**
064         * @see JobParametersExtractor#getJobParameters(Job, StepExecution)
065         */
066        @Override
067        public JobParameters getJobParameters(Job job, StepExecution stepExecution) {
068                JobParametersBuilder builder = new JobParametersBuilder();
069                Map<String, JobParameter> jobParameters = stepExecution.getJobParameters().getParameters();
070                ExecutionContext executionContext = stepExecution.getExecutionContext();
071                if (useAllParentParameters) {
072                        for (String key : jobParameters.keySet()) {
073                                builder.addParameter(key, jobParameters.get(key));
074                        }
075                }
076                for (String key : keys) {
077                        if (key.endsWith("(long)")) {
078                                key = key.replace("(long)", "");
079                                if (executionContext.containsKey(key)) {
080                                        builder.addLong(key, executionContext.getLong(key));
081                                }
082                                else if (jobParameters.containsKey(key)) {
083                                        builder.addLong(key, (Long) jobParameters.get(key).getValue());
084                                }
085                        }
086                        else if (key.endsWith("(int)")) {
087                                key = key.replace("(int)", "");
088                                if (executionContext.containsKey(key)) {
089                                        builder.addLong(key, (long) executionContext.getInt(key));
090                                }
091                                else if (jobParameters.containsKey(key)) {
092                                        builder.addLong(key, (Long) jobParameters.get(key).getValue());
093                                }
094                        }
095                        else if (key.endsWith("(double)")) {
096                                key = key.replace("(double)", "");
097                                if (executionContext.containsKey(key)) {
098                                        builder.addDouble(key, executionContext.getDouble(key));
099                                }
100                                else if (jobParameters.containsKey(key)) {
101                                        builder.addDouble(key, (Double) jobParameters.get(key).getValue());
102                                }
103                        }
104                        else if (key.endsWith("(string)")) {
105                                key = key.replace("(string)", "");
106                                if (executionContext.containsKey(key)) {
107                                        builder.addString(key, executionContext.getString(key));
108                                }
109                                else if (jobParameters.containsKey(key)) {
110                                        builder.addString(key, (String) jobParameters.get(key).getValue());
111                                }
112                        }
113                        else if (key.endsWith("(date)")) {
114                                key = key.replace("(date)", "");
115                                if (executionContext.containsKey(key)) {
116                                        builder.addDate(key, (Date) executionContext.get(key));
117                                }
118                                else if (jobParameters.containsKey(key)) {
119                                        builder.addDate(key, (Date) jobParameters.get(key).getValue());
120                                }
121                        }
122                        else {
123                                if (executionContext.containsKey(key)) {
124                                        builder.addString(key, executionContext.get(key).toString());
125                                }
126                                else if (jobParameters.containsKey(key)) {
127                                        builder.addString(key, jobParameters.get(key).getValue().toString());
128                                }
129                        }
130                }
131                return builder.toJobParameters();
132        }
133
134        /**
135         * setter to support switching off all parent parameters
136         *
137         * @param useAllParentParameters if false do not include parent parameters.
138         * True if all parent parameters need to be included.
139         */
140        public void setUseAllParentParameters(boolean useAllParentParameters) {
141                this.useAllParentParameters = useAllParentParameters;
142        }
143
144        
145}