com.softicar.platform.common.core.constant.container.validator.AbstractConstantContainerValidator Maven / Gradle / Ivy
Show all versions of platform-common Show documentation
package com.softicar.platform.common.core.constant.container.validator;
import com.softicar.platform.common.core.constant.container.field.ConstantContainerFieldExtractor;
import com.softicar.platform.common.core.constant.container.field.IConstantContainerField;
import com.softicar.platform.common.core.constant.container.validator.error.ConstantContainerMustBeInterfaceError;
import com.softicar.platform.common.core.constant.container.validator.error.ConstantContainerMustNotDeclareMethodError;
import com.softicar.platform.common.core.constant.container.validator.error.ConstantContainerMustNotExtendOtherClassError;
import com.softicar.platform.common.core.constant.container.validator.result.ConstantContainerValidatorResult;
import com.softicar.platform.common.core.java.code.validation.output.JavaCodeViolations;
import com.softicar.platform.common.core.java.code.validator.JavaClassValidator;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Validates a given "constant container" class.
*
*
* - The class must be an interface.
* - The class may not have a super class.
* - The class may not declare any methods.
*
*
* - All fields must be public and static and final.
* - All fields must be in alphabetic order.
* - All field names must obey the Java conventions for constants.
*
*
* TODO Improve and use {@link JavaClassValidator} instead of
* {@link ConstantContainerValidatorResult}.
*
* TODO Improve and use {@link JavaCodeViolations} instead of redundant
* implementations of
* {@link #validateClassType(ConstantContainerValidatorResult)} /
* {@link #validateSuperClass(ConstantContainerValidatorResult)} /
* {@link #validateMethods(ConstantContainerValidatorResult)}.
*
* @param
* the expected type of the fields in the constant container class
* @author Alexander Schmidt
* @author Oliver Richers
*/
public abstract class AbstractConstantContainerValidator implements IConstantContainerValidator {
private final List> additionalValidators;
protected final Class containerClass;
protected final Class expectedFieldType;
public AbstractConstantContainerValidator(Class containerClass, Class expectedFieldType) {
this.additionalValidators = new ArrayList<>();
this.containerClass = containerClass;
this.expectedFieldType = expectedFieldType;
}
@Override
public void validate(ConstantContainerValidatorResult result) {
validateClassType(result);
validateSuperClass(result);
validateMethods(result);
validateFields(result);
validateAdditionally(result);
}
public void addAdditionalValidator(IConstantContainerValidator additionalValidator) {
additionalValidators.add(additionalValidator);
}
protected abstract IConstantContainerValidator createFieldValidator(IConstantContainerField currentField, IConstantContainerField previousField);
protected ConstantContainerFieldExtractor createFieldExtractor() {
return new ConstantContainerFieldExtractor<>(containerClass, expectedFieldType);
}
private void validateClassType(ConstantContainerValidatorResult result) {
if (!containerClass.isInterface()) {
result.addError(new ConstantContainerMustBeInterfaceError<>(containerClass));
}
}
private void validateSuperClass(ConstantContainerValidatorResult result) {
if (containerClass.getSuperclass() != null) {
result.addError(new ConstantContainerMustNotExtendOtherClassError<>(containerClass));
}
}
private void validateMethods(ConstantContainerValidatorResult result) {
for (Method method: containerClass.getDeclaredMethods()) {
result.addError(new ConstantContainerMustNotDeclareMethodError<>(containerClass, method));
}
}
private void validateFields(ConstantContainerValidatorResult result) {
var extractor = createFieldExtractor();
IConstantContainerField previousField = null;
for (IConstantContainerField field: extractor.extractFields()) {
createFieldValidator(field, previousField).validate(result);
previousField = field;
}
}
private void validateAdditionally(ConstantContainerValidatorResult result) {
additionalValidators.forEach(validator -> validator.validate(result));
}
}