test code coverage improved and more JSon/field types
This commit is contained in:
@ -28,10 +28,6 @@ abstract class JSonAccessFilter<T> {
|
||||
this.parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class);
|
||||
}
|
||||
|
||||
boolean isParentIdField(final Field field) {
|
||||
return field.equals(parentIdField);
|
||||
}
|
||||
|
||||
Long getId() {
|
||||
if (selfIdField == null) {
|
||||
return null;
|
||||
@ -95,7 +91,7 @@ abstract class JSonAccessFilter<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object loadDto(final Class<? extends IdToDtoResolver> resolverClass, final Long id) {
|
||||
verify(id != null, "id must not be null");
|
||||
verify(id != null, "id must not be null for " + resolverClass.getSimpleName());
|
||||
|
||||
final AutowireCapableBeanFactory beanFactory = ctx.getAutowireCapableBeanFactory();
|
||||
verify(beanFactory != null, "no bean factory found, probably missing mock configuration for ApplicationContext, e.g. given(...)");
|
||||
|
@ -11,6 +11,7 @@ import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@ -40,8 +41,8 @@ public class JSonDeserializerWithAccessFilter<T> extends JSonAccessFilter<T> {
|
||||
treeNode.fieldNames().forEachRemaining(fieldName -> {
|
||||
try {
|
||||
final Field field = dto.getClass().getDeclaredField(fieldName);
|
||||
final Object newValue = readValue(treeNode, field);
|
||||
writeValue(dto, field, newValue);
|
||||
final Object newValue = readValueFromJSon(treeNode, field);
|
||||
writeValueToDto(dto, field, newValue);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException("setting field " + fieldName + " failed", e);
|
||||
}
|
||||
@ -69,12 +70,12 @@ public class JSonDeserializerWithAccessFilter<T> extends JSonAccessFilter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private Object readValue(final TreeNode treeNode, final Field field) {
|
||||
return readValue(treeNode, field.getName(), field.getType());
|
||||
private Object readValueFromJSon(final TreeNode treeNode, final Field field) {
|
||||
return readValueFromJSon(treeNode, field.getName(), field.getType());
|
||||
|
||||
}
|
||||
|
||||
private Object readValue(final TreeNode treeNode, final String fieldName, final Class<?> fieldClass) {
|
||||
private Object readValueFromJSon(final TreeNode treeNode, final String fieldName, final Class<?> fieldClass) {
|
||||
final TreeNode fieldNode = treeNode.get(fieldName);
|
||||
if (fieldNode instanceof NullNode) {
|
||||
return null;
|
||||
@ -88,23 +89,29 @@ public class JSonDeserializerWithAccessFilter<T> extends JSonAccessFilter<T> {
|
||||
if (fieldNode instanceof LongNode) {
|
||||
return ((LongNode) fieldNode).asLong();
|
||||
}
|
||||
if (fieldNode instanceof DoubleNode) {
|
||||
// TODO: we need to figure out, why DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS does not work
|
||||
return ((DoubleNode) fieldNode).asDouble();
|
||||
}
|
||||
if (fieldNode instanceof ArrayNode && LocalDate.class.isAssignableFrom(fieldClass)) {
|
||||
return LocalDate.of(((ArrayNode) fieldNode).get(0).asInt(), ((ArrayNode) fieldNode).get(1).asInt(), ((ArrayNode) fieldNode).get(2).asInt());
|
||||
}
|
||||
{
|
||||
throw new NotImplementedException("property type not yet implemented: " + fieldNode + " -> " + fieldName + ": " + fieldClass);
|
||||
}
|
||||
throw new NotImplementedException("JSon node type not implemented: " + fieldNode.getClass() + " -> " + fieldName + ": " + fieldClass);
|
||||
}
|
||||
|
||||
private void writeValue(final T dto, final Field field, final Object value) {
|
||||
private void writeValueToDto(final T dto, final Field field, final Object value) {
|
||||
if (value == null) {
|
||||
ReflectionUtil.setValue(dto, field, null);
|
||||
} else if (field.getType().isAssignableFrom(value.getClass())) {
|
||||
ReflectionUtil.setValue(dto, field, value);
|
||||
} else if (Integer.class.isAssignableFrom(field.getType()) || int.class.isAssignableFrom(field.getType())) {
|
||||
} else if (int.class.isAssignableFrom(field.getType())) {
|
||||
ReflectionUtil.setValue(dto, field, ((Number) value).intValue());
|
||||
} else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) {
|
||||
ReflectionUtil.setValue(dto, field, ((Number) value).longValue());
|
||||
} else if (BigDecimal.class.isAssignableFrom(field.getType())) {
|
||||
ReflectionUtil.setValue(dto, field, new BigDecimal(value.toString()));
|
||||
} else if (Boolean.class.isAssignableFrom(field.getType()) || boolean.class.isAssignableFrom(field.getType())) {
|
||||
ReflectionUtil.setValue(dto, field, Boolean.valueOf(value.toString()));
|
||||
} else if (field.getType().isEnum()) {
|
||||
ReflectionUtil.setValue(dto, field, Enum.valueOf((Class<Enum>) field.getType(), value.toString()));
|
||||
} else if (LocalDate.class.isAssignableFrom(field.getType())) {
|
||||
|
@ -4,10 +4,12 @@ package org.hostsharing.hsadminng.service.accessfilter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hostsharing.hsadminng.service.util.ReflectionUtil;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class JSonSerializerWithAccessFilter<T> extends JSonAccessFilter<T> {
|
||||
@ -41,32 +43,27 @@ public class JSonSerializerWithAccessFilter<T> extends JSonAccessFilter<T> {
|
||||
// Alternatively extract the supported types to subclasses of some abstract class and
|
||||
// here as well as in the deserializer just access the matching implementation through a map.
|
||||
// Or even completely switch from Jackson to GSON?
|
||||
final Object fieldValue = get(dto, field);
|
||||
final Object fieldValue = ReflectionUtil.getValue(dto, field);
|
||||
if (fieldValue == null) {
|
||||
jsonGenerator.writeNullField(fieldName);
|
||||
} else if (String.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeStringField(fieldName, (String) fieldValue);
|
||||
} else if (Integer.class.isAssignableFrom(field.getType()) || int.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeNumberField(fieldName, (int) fieldValue);
|
||||
} else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeNumberField(fieldName, (long) fieldValue);
|
||||
} else if (LocalDate.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper format
|
||||
jsonGenerator.writeStringField(fieldName, fieldValue.toString());
|
||||
} else if (Enum.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper representation
|
||||
} else if (String.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeStringField(fieldName, (String) fieldValue);
|
||||
jsonGenerator.writeStringField(fieldName, ((Enum) fieldValue).name());
|
||||
} else if (Boolean.class.isAssignableFrom(field.getType()) || boolean.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeBooleanField(fieldName, (Boolean) fieldValue);
|
||||
} else if (BigDecimal.class.isAssignableFrom(field.getType())) {
|
||||
jsonGenerator.writeNumberField(fieldName, (BigDecimal) fieldValue);
|
||||
} else {
|
||||
throw new NotImplementedException("property type not yet implemented: " + field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object get(final Object dto, final Field field) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
return field.get(dto);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("getting field " + field + " failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user