001/* 002 * Copyright 2012-2018 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.job; 017 018import java.util.Arrays; 019import java.util.Collection; 020import java.util.HashSet; 021import java.util.Set; 022 023import org.springframework.batch.core.JobParameters; 024import org.springframework.batch.core.JobParametersInvalidException; 025import org.springframework.batch.core.JobParametersValidator; 026import org.springframework.beans.factory.InitializingBean; 027import org.springframework.lang.Nullable; 028import org.springframework.util.Assert; 029 030/** 031 * Default implementation of {@link JobParametersValidator}. 032 * 033 * @author Dave Syer 034 * @author Mahmoud Ben Hassine 035 * 036 */ 037public class DefaultJobParametersValidator implements JobParametersValidator, InitializingBean { 038 039 private Collection<String> requiredKeys; 040 041 private Collection<String> optionalKeys; 042 043 /** 044 * Convenient default constructor for unconstrained validation. 045 */ 046 public DefaultJobParametersValidator() { 047 this(new String[0], new String[0]); 048 } 049 050 /** 051 * Create a new validator with the required and optional job parameter keys 052 * provided. 053 * 054 * @see DefaultJobParametersValidator#setOptionalKeys(String[]) 055 * @see DefaultJobParametersValidator#setRequiredKeys(String[]) 056 * 057 * @param requiredKeys the required keys 058 * @param optionalKeys the optional keys 059 */ 060 public DefaultJobParametersValidator(String[] requiredKeys, String[] optionalKeys) { 061 super(); 062 setRequiredKeys(requiredKeys); 063 setOptionalKeys(optionalKeys); 064 } 065 066 /** 067 * Check that there are no overlaps between required and optional keys. 068 * @throws IllegalStateException if there is an overlap 069 */ 070 @Override 071 public void afterPropertiesSet() throws IllegalStateException { 072 for (String key : requiredKeys) { 073 Assert.state(!optionalKeys.contains(key), "Optional keys cannot be required: " + key); 074 } 075 } 076 077 /** 078 * Check the parameters meet the specification provided. If optional keys 079 * are explicitly specified then all keys must be in that list, or in the 080 * required list. Otherwise all keys that are specified as required must be 081 * present. 082 * 083 * @see JobParametersValidator#validate(JobParameters) 084 * 085 * @throws JobParametersInvalidException if the parameters are not valid 086 */ 087 @Override 088 public void validate(@Nullable JobParameters parameters) throws JobParametersInvalidException { 089 090 if (parameters == null) { 091 throw new JobParametersInvalidException("The JobParameters can not be null"); 092 } 093 094 Set<String> keys = parameters.getParameters().keySet(); 095 096 // If there are explicit optional keys then all keys must be in that 097 // group, or in the required group. 098 if (!optionalKeys.isEmpty()) { 099 100 Collection<String> missingKeys = new HashSet<String>(); 101 for (String key : keys) { 102 if (!optionalKeys.contains(key) && !requiredKeys.contains(key)) { 103 missingKeys.add(key); 104 } 105 } 106 if (!missingKeys.isEmpty()) { 107 throw new JobParametersInvalidException( 108 "The JobParameters contains keys that are not explicitly optional or required: " + missingKeys); 109 } 110 111 } 112 113 Collection<String> missingKeys = new HashSet<String>(); 114 for (String key : requiredKeys) { 115 if (!keys.contains(key)) { 116 missingKeys.add(key); 117 } 118 } 119 if (!missingKeys.isEmpty()) { 120 throw new JobParametersInvalidException("The JobParameters do not contain required keys: " + missingKeys); 121 } 122 123 } 124 125 /** 126 * The keys that are required in the parameters. The default is empty, 127 * meaning that all parameters are optional, unless optional keys are 128 * explicitly specified. 129 * 130 * @param requiredKeys the required key values 131 * 132 * @see #setOptionalKeys(String[]) 133 */ 134 public final void setRequiredKeys(String[] requiredKeys) { 135 this.requiredKeys = new HashSet<String>(Arrays.asList(requiredKeys)); 136 } 137 138 /** 139 * The keys that are optional in the parameters. If any keys are explicitly 140 * optional, then to be valid all other keys must be explicitly required. 141 * The default is empty, meaning that all parameters that are not required 142 * are optional. 143 * 144 * @param optionalKeys the optional key values 145 * 146 * @see #setRequiredKeys(String[]) 147 */ 148 public final void setOptionalKeys(String[] optionalKeys) { 149 this.optionalKeys = new HashSet<String>(Arrays.asList(optionalKeys)); 150 } 151 152}