Skip to content

Commit

Permalink
Added new static utility method
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-schnell committed Jan 20, 2024
1 parent 9983066 commit afbc008
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.validation.ConstraintValidatorContext;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
Expand All @@ -20,39 +21,61 @@ public void initialize(HasSerializedDataTypeConstant annotation) {

@Override
public boolean isValid(Object obj, ConstraintValidatorContext context) {
final Result result = analyze(obj.getClass(), name);
if (result.message() == null) {
return true;
}
error(context, result.message());
return false;
}

private void error(ConstraintValidatorContext context, String message) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
}

private static Result analyze(final Class<?> clasz, final String name) {
try {
final Field field = obj.getClass().getField(name);
final Field field = clasz.getField(name);
final int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers)) {
error(context, "Field '" + name + "' is not static (#1)");
return false;
return new Result("Field '" + name + "' is not static (#1)", null);
}
if (field.getType() != SerializedDataType.class) {
error(context, "Expected constant '" + name + "' to be of type '" + SerializedDataType.class.getName() + "', but was: " + field.getType().getName() + " (#3)");
return false;
return new Result("Expected constant '" + name + "' to be of type '" + SerializedDataType.class.getName() + "', but was: " + field.getType().getName() + " (#3)", null);
}
final Object value = field.get(obj);
final Object value = field.get(clasz);
if (value == null) {
error(context, "Constant '" + name + "' is expected to be a non-null value (#4)");
return false;
return new Result("Constant '" + name + "' is expected to be a non-null value (#4)", null);
}
if (!Modifier.isFinal(modifiers)) {
error(context, "Constant '" + name + "' is not not final (#5)");
return false;
return new Result("Constant '" + name + "' is not not final (#5)", null);
}
return true;
return new Result(null, value);
} catch (final NoSuchFieldException ex) {
error(context, "The field '" + name + "' is undefined or it is not public (#2)");
return false;
return new Result("The field '" + name + "' is undefined or it is not public (#2)", null);
} catch (final IllegalAccessException ex) {
throw new IllegalStateException("Failed to execute method", ex);
}
}

private record Result(String message, Object value) {
}

private void error(ConstraintValidatorContext context, String message) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
/**
* Returns a constant of type {@link SerializedDataType} in a class. Throws an {@link IllegalArgumentException}
* in case there is a problem with the field.
*
* @param clasz Class to inspect.
* @param fieldName Name of the public static field of type {@link SerializedDataType}.
* @return Value of the constant.
*/
public static SerializedDataType extractValue(final Class<?> clasz, final String fieldName) {
final Result result = analyze(clasz, fieldName);
if (result.message() == null) {
return (SerializedDataType) result.value();
}
throw new IllegalArgumentException(result.message());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

public final class HasSerializedDataTypeConstantValidatorTest {

public static final String FIELD_NAME = "SER_TYPE";
private static Validator validator;

@BeforeAll
Expand All @@ -42,36 +44,80 @@ static void beforeAll() {
@Test
public final void testValid() {
assertThat(validator.validate(new MyClassValid())).isEmpty();
assertThat(HasSerializedDataTypeConstantValidator
.extractValue(MyClassValid.class, FIELD_NAME)).isEqualTo(new SerializedDataType("XYZ"));
}

@Test
public final void testNotStatic() {

assertThat(first(validator.validate(new MyClassNotStatic()))).contains("#1");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassNotStatic.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#1");

}

@Test
public final void testNotPublic() {

assertThat(first(validator.validate(new MyClassNotPublic()))).contains("#2");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassNotPublic.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#2");

}

@Test
public final void testWrongReturnType() {

assertThat(first(validator.validate(new MyClassWrongType()))).contains("#3");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassWrongType.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#3");

}

@Test
public final void testWrongReturn() {

assertThat(first(validator.validate(new MyClassNullValue()))).contains("#4");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassNullValue.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#4");

}

@Test
public final void testNoMethod() {
public final void testNoField() {

assertThat(first(validator.validate(new MyClassNoField()))).contains("#2");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassNoField.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#2");

}

@Test
public final void testNotFinal() {

assertThat(first(validator.validate(new MyClassNotFinal()))).contains("#5");

assertThatThrownBy(
() -> HasSerializedDataTypeConstantValidator.extractValue(MyClassNotFinal.class, FIELD_NAME))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("#5");

}

private static String first(Set<?> violations) {
Expand Down

0 comments on commit afbc008

Please sign in to comment.