blob: 5e9fdd373f9adc60c0b677518ffc6f505709d5bb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.accumulo.core.util;
import java.util.function.Predicate;
/**
* A class that validates arguments of a particular type. Implementations must implement
* {@link #test(Object)} and should override {@link #invalidMessage(Object)}.
*/
public abstract class Validator<T> implements Predicate<T> {
/**
* Validates an argument.
*
* @param argument
* argument to validate
* @return the argument, if validation passes
* @throws IllegalArgumentException
* if validation fails
*/
public final T validate(final T argument) {
if (!test(argument))
throw new IllegalArgumentException(invalidMessage(argument));
return argument;
}
/**
* Formulates an exception message for invalid values.
*
* @param argument
* argument that failed validation
* @return exception message
*/
public String invalidMessage(final T argument) {
return String.format("Invalid argument %s", argument);
}
/**
* Creates a new validator that is the conjunction of this one and the given one. An argument
* passed to the returned validator is valid only if it passes both validators.
*
* @param other
* other validator
* @return combined validator
*/
public final Validator<T> and(final Validator<T> other) {
if (other == null)
return this;
final Validator<T> mine = this;
return new Validator<>() {
@Override
public boolean test(T argument) {
return mine.test(argument) && other.test(argument);
}
@Override
public String invalidMessage(T argument) {
return (mine.test(argument) ? other : mine).invalidMessage(argument);
}
};
}
/**
* Creates a new validator that is the disjunction of this one and the given one. An argument
* passed to the returned validator is valid only if it passes at least one of the validators.
*
* @param other
* other validator
* @return combined validator
*/
public final Validator<T> or(final Validator<T> other) {
if (other == null)
return this;
final Validator<T> mine = this;
return new Validator<>() {
@Override
public boolean test(T argument) {
return mine.test(argument) || other.test(argument);
}
@Override
public String invalidMessage(T argument) {
return mine.invalidMessage(argument);
}
};
}
/**
* Creates a new validator that is the negation of this one. An argument passed to the returned
* validator is valid only if it fails this one.
*
* @return negated validator
*/
public final Validator<T> not() {
final Validator<T> mine = this;
return new Validator<>() {
@Override
public boolean test(T argument) {
return !mine.test(argument);
}
@Override
public String invalidMessage(T argument) {
return "Validation should have failed with: " + mine.invalidMessage(argument);
}
};
}
}