--- /dev/null
+package de.example.symfony.validator;
+
+
+public interface PostValidatorBase {
+
+ void doPostValidate(String value);
+}
--- /dev/null
+package de.example.symfony.validator;
+
+
+public abstract class ValidatorBase {
+ private final boolean required;
+ private final String requiredRule;
+ private final String invalidRule;
+
+
+ public ValidatorBase(boolean required, String requiredRule, String invalidRule) {
+ this.required = required;
+ this.requiredRule = requiredRule;
+ this.invalidRule = invalidRule;
+ }
+
+ public void doValidate(String value) {
+ if (isBlank(value)) {
+ if (this.isRequired()) {
+ // HTTP 422 unprocessable entity.
+ throw new RuntimeException(this.requiredRule);
+ }
+
+ return;
+ }
+
+ this.validate(value);
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public String getInvalidRule() {
+ return invalidRule;
+ }
+
+ public String getRequiredRule() {
+ return requiredRule;
+ }
+
+ protected abstract void validate(String value);
+
+ /**
+ * <p>Checks if a String is whitespace, empty ("") or null.</p>
+ *
+ * <pre>
+ * StringUtils.isBlank(null) = true
+ * StringUtils.isBlank("") = true
+ * StringUtils.isBlank(" ") = true
+ * StringUtils.isBlank("bob") = false
+ * StringUtils.isBlank(" bob ") = false
+ * </pre>
+ *
+ * @param str the String to check, may be null
+ * @return <code>true</code> if the String is null, empty or whitespace
+ * @since 2.0
+ */
+ public static boolean isBlank(String str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if ((Character.isWhitespace(str.charAt(i)) == false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
--- /dev/null
+package de.example.symfony.validator;
+
+
+
+public class ValidatorNumber extends ValidatorBase {
+ private static final String REQUIRED_DEFAULT_RULE = "validator.number.required";
+ private static final String INVALID_DEFAULT_RULE = "validator.number.invalid";
+ private static final String MAX_DEFAULT_RULE = "validator.number.max";
+ private static final String MIN_DEFAULT_RULE = "validator.number.min";
+
+ private final Integer max;
+ private final String maxRule;
+ private final Integer min;
+ private final String minRule;
+
+
+ public ValidatorNumber(Integer max, String maxRule, Integer min, String minRule,
+ boolean required, String requiredRule, String invalidRule) {
+ super(required, requiredRule, invalidRule);
+ this.max = max;
+ this.maxRule = maxRule;
+ this.min = min;
+ this.minRule = minRule;
+ }
+
+ @Override
+ protected void validate(String value) {
+ if (!isNumeric(value)) {
+ // Wrong syntax: HTTP 400 bad request.
+ throw new RuntimeException(this.getInvalidRule());
+ }
+
+ double clean = Double.valueOf(value);
+
+ if (this.max != null && clean > this.max) {
+ // Wrong semantic: HTTP 422 unprocessable entity.
+ throw new RuntimeException(this.maxRule);
+ }
+
+ if (this.min != null && clean < this.min) {
+ // Wrong semantic: HTTP 422 unprocessable entity.
+ throw new RuntimeException(this.minRule);
+ }
+ }
+
+ public static class Builder {
+ private Integer mMax;
+ private String mMaxRule = MAX_DEFAULT_RULE;
+ private Integer mMin;
+ private String mMinRule = MIN_DEFAULT_RULE;
+ private boolean mRequired = true;
+ private String mRequiredRule = REQUIRED_DEFAULT_RULE;
+ private String mInvalidRule = INVALID_DEFAULT_RULE;
+
+
+ public Builder setMax(int max) {
+ this.mMax = max;
+ return this;
+ }
+
+ public Builder setMaxRule(String maxRule) {
+ this.mMaxRule = maxRule;
+ return this;
+ }
+
+ public Builder setMin(int min) {
+ this.mMin = min;
+ return this;
+ }
+
+ public Builder setMinRule(String minRule) {
+ this.mMinRule = minRule;
+ return this;
+ }
+
+ public Builder setRequired(boolean required) {
+ this.mRequired = required;
+ return this;
+ }
+
+ public Builder setRequiredRule(String requiredRule) {
+ this.mRequiredRule = requiredRule;
+ return this;
+ }
+
+ public Builder setInvalidRule(String invalidRule) {
+ this.mInvalidRule = invalidRule;
+ return this;
+ }
+
+ public ValidatorNumber build() {
+ return new ValidatorNumber(mMax, mMaxRule, mMin, mMinRule,
+ mRequired, mRequiredRule, mInvalidRule);
+ }
+ }
+
+ private boolean isNumeric(String str) {
+ try {
+ Double.parseDouble(str);
+ }
+ catch(NumberFormatException exception) {
+ return false;
+ }
+
+ return true;
+ }
+}
--- /dev/null
+package de.example.symfony.validator;
+
+
+public class ValidatorString extends ValidatorBase {
+ private static final String REQUIRED_DEFAULT_RULE = "validator.string.required";
+ private static final String INVALID_DEFAULT_RULE = "validator.string.invalid";
+ private static final String MAX_LENGTH_DEFAULT_RULE = "validator.string.length.max";
+ private static final String MIN_LENGTH_DEFAULT_RULE = "validator.string.length.min";
+
+ private final Integer maxLength;
+ private final String maxLenghtRule;
+ private final Integer minLength;
+ private final String minLengthRule;
+
+ public ValidatorString(Integer maxLength, String maxLenghtRule, Integer minLength, String minLengthRule,
+ boolean required, String requiredRule, String invalidRule) {
+ super(required, requiredRule, invalidRule);
+ this.maxLength = maxLength;
+ this.maxLenghtRule = maxLenghtRule;
+ this.minLength = minLength;
+ this.minLengthRule = minLengthRule;
+ }
+
+ @Override
+ protected void validate(String value) {
+ int length = value.codePointCount(0, value.length());
+
+ if (this.maxLength != null && length > this.maxLength) {
+ // Wrong semantic: HTTP 422 unprocessable entity.
+ throw new RuntimeException(this.maxLenghtRule);
+ }
+
+ if (this.minLength != null && length < this.minLength) {
+ // Wrong semantic: HTTP 422 unprocessable entity.
+ throw new RuntimeException(this.minLengthRule);
+ }
+ }
+
+ public static class Builder {
+ private Integer mMaxLength;
+ private String mMaxLenghtRule = MAX_LENGTH_DEFAULT_RULE;
+ private Integer mMinLength;
+ private String mMinLengthRule = MIN_LENGTH_DEFAULT_RULE;
+ private boolean mRequired = true;
+ private String mRequiredRule = REQUIRED_DEFAULT_RULE;
+ private String mInvalidRule = INVALID_DEFAULT_RULE;
+
+ public Builder setMaxLength(Integer maxLength) {
+ this.mMaxLength = maxLength;
+ return this;
+ }
+
+ public Builder setMaxLenghtRule(String maxLenghtRule) {
+ this.mMaxLenghtRule = maxLenghtRule;
+ return this;
+ }
+
+ public Builder setMinLength(Integer minLength) {
+ this.mMinLength = minLength;
+ return this;
+ }
+
+ public Builder setMinLengthRule(String minLengthRule) {
+ this.mMinLengthRule = minLengthRule;
+ return this;
+ }
+
+ public Builder setRequired(boolean required) {
+ this.mRequired = required;
+ return this;
+ }
+
+ public Builder setRequiredRule(String requiredRule) {
+ this.mRequiredRule = requiredRule;
+ return this;
+ }
+
+ public Builder setInvalidRule(String invalidRule) {
+ this.mInvalidRule = invalidRule;
+ return this;
+ }
+
+ public ValidatorString build() {
+ return new ValidatorString(mMaxLength, mMaxLenghtRule, mMinLength, mMinLengthRule,
+ mRequired, mRequiredRule, mInvalidRule);
+ }
+ }
+}
--- /dev/null
+package de.example.symfony.validator.main;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import de.example.symfony.validator.service.impl.ValidatorServiceImpl;
+
+
+public class ValidatorMainExample {
+ private static final String FROMID = "fromId";
+ private static final String TOID = "toId";
+ private static final String DESCRIPTION = "description";
+
+ public static void main(String[] args) {
+ Map<String, String> params = new HashMap<>();
+ params.put(FROMID, "50");
+ params.put(TOID, "75");
+ params.put(DESCRIPTION, "Snake Eyes");
+
+ ValidatorServiceImpl validatorService = new ValidatorServiceImpl(params);
+ validatorService.doValidate();
+
+ validatorService.doPostValidate();
+ }
+
+}
--- /dev/null
+package de.example.symfony.validator.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import de.example.symfony.validator.PostValidatorBase;
+import de.example.symfony.validator.ValidatorBase;
+
+
+public abstract class ValidatorService {
+ protected final Map<String, String> params;
+ protected final Map<String, ValidatorBase> validators = new HashMap<>();
+ protected final Map<String, PostValidatorBase> postValidators = new HashMap<>();
+
+
+ public ValidatorService(Map<String, String> params) {
+ this.params = params;
+
+ this.configureValidators();
+ this.configurePostValidators();
+ }
+
+ public void doValidate() {
+
+ for (Map.Entry<String, ValidatorBase> validator : validators.entrySet()) {
+ validator.getValue().doValidate(params.get(validator.getKey()));
+ }
+
+ }
+
+ public void doPostValidate() {
+
+ for (Map.Entry<String, PostValidatorBase> postValidator : postValidators.entrySet()) {
+ postValidator.getValue().doPostValidate(params.get(postValidator.getKey()));
+ }
+
+ }
+
+ protected abstract void configureValidators();
+
+ protected abstract void configurePostValidators();
+}
--- /dev/null
+package de.example.symfony.validator.service.impl;
+
+import java.util.Map;
+
+import de.example.symfony.validator.ValidatorNumber;
+import de.example.symfony.validator.ValidatorString;
+import de.example.symfony.validator.service.ValidatorService;
+
+
+public class ValidatorServiceImpl extends ValidatorService {
+ private static final String FROMID = "fromId";
+ private static final String TOID = "toId";
+ private static final String DESCRIPTION = "description";
+
+ private String fromId;
+ private String toId;
+ private String description;
+
+ public ValidatorServiceImpl(Map<String, String> params) {
+ super(params);
+ }
+
+ @Override
+ protected void configureValidators() {
+ validators.put(FROMID, new ValidatorNumber.Builder().setRequired(true).setMin(5).build());
+ validators.put(TOID, new ValidatorNumber.Builder().setRequired(true).setMax(100).build());
+ validators.put(DESCRIPTION, new ValidatorString.Builder().setRequired(false).setMaxLength(70).setMinLength(5).build());
+ }
+
+ @Override
+ protected void configurePostValidators() {
+
+ postValidators.put(FROMID, value ->
+ {
+ fromId = value;
+ System.out.println("fromId: " + fromId);
+ });
+
+ postValidators.put(TOID, value ->
+ {
+ toId = value;
+ System.out.println("toId: " + toId);
+
+ });
+
+ postValidators.put(DESCRIPTION, value ->
+ {
+ description = value;
+ System.out.println("description: " + description);
+
+ });
+ }
+
+}