com.sap.cloud.security.token.validation.CombiningValidator Maven / Gradle / Ivy
/**
* SPDX-FileCopyrightText: 2018-2023 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.sap.cloud.security.token.validation;
import com.sap.cloud.security.xsuaa.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* This is a special validator that combines several validators into one. By default the validation stops after one
* invalid result has been found.
*
* @param
* the type to be validated.
*/
public class CombiningValidator implements Validator {
private static final Logger LOGGER = LoggerFactory.getLogger(CombiningValidator.class);
private final List> validators;
private final Set validationListeners = new HashSet<>();
public CombiningValidator(List> validators) {
Assertions.assertNotNull(validators, "validators must not be null.");
this.validators = validators;
}
public CombiningValidator(Validator... validators) {
Assertions.assertNotNull(validators, "validators must not be null.");
this.validators = Arrays.asList(validators);
}
@Override
public ValidationResult validate(T t) {
for (Validator validator : validators) {
ValidationResult result = validator.validate(t);
if (result.isErroneous()) {
debugLog(t, validator);
validationListeners.forEach(listener -> listener.onValidationError(result));
return result;
}
}
return createValidationResult();
}
public List> getValidators() {
return validators;
}
@Override
public String toString() {
StringBuilder validatorNames = new StringBuilder();
for (Validator v : validators) {
validatorNames.append(v.getClass().getName()).append(',');
}
return validatorNames.toString();
}
/**
* Components that are interested in the result of the token validation can register a validation listener which is
* called whenever a token is validated. Listener must implement the {@link ValidationListener} interface.
*
* @param validationListener
* the listener to be added.
*/
public void registerValidationListener(ValidationListener validationListener) {
validationListeners.add(validationListener);
}
/**
* Use this method to remove a registered listener so that it is not called anymore.
*
* @param validationListener
* the listener to be removed.
*/
public void removeValidationListener(ValidationListener validationListener) {
validationListeners.remove(validationListener);
}
private void debugLog(T t, Validator validator) {
if (LOGGER.isDebugEnabled()) {
String objectType = t == null ? "null" : t.getClass().getName();
LOGGER.debug("Validator that caused the failed validation: {}", validator.getClass().getName());
LOGGER.debug("Object of type {} that caused the failed validation: {}{}", objectType,
System.lineSeparator(), t);
}
}
private ValidationResult createValidationResult() {
if (validators.isEmpty()) {
ValidationResult result = ValidationResults
.createInvalid("CombiningValidator must contain at least one validator!");
validationListeners.forEach(listener -> listener.onValidationError(result));
return result;
} else {
validationListeners.forEach(ValidationListener::onValidationSuccess);
return ValidationResults.createValid();
}
}
}