115 lines
4.7 KiB
Java
115 lines
4.7 KiB
Java
package ru.ulstu.odin.service;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.stereotype.Service;
|
|
import ru.ulstu.core.error.OdinException;
|
|
import ru.ulstu.odin.model.OdinBooleanField;
|
|
import ru.ulstu.odin.model.OdinCollectionField;
|
|
import ru.ulstu.odin.model.OdinDateField;
|
|
import ru.ulstu.odin.model.OdinDto;
|
|
import ru.ulstu.odin.model.OdinField;
|
|
import ru.ulstu.odin.model.OdinMetadata;
|
|
import ru.ulstu.odin.model.OdinNumericField;
|
|
import ru.ulstu.odin.model.OdinObjectField;
|
|
import ru.ulstu.odin.model.OdinStringField;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Modifier;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.Optional;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service
|
|
public class OdinService<L, E extends OdinDto> {
|
|
private final Logger log = LoggerFactory.getLogger(OdinService.class);
|
|
|
|
private final Map<String, OdinField.OdinFieldType> aliases;
|
|
|
|
public OdinService() {
|
|
aliases = new HashMap<>();
|
|
aliases.put("boolean", OdinField.OdinFieldType.BOOLEAN);
|
|
aliases.put("date", OdinField.OdinFieldType.DATE);
|
|
aliases.put("instant", OdinField.OdinFieldType.DATE);
|
|
aliases.put("localdate", OdinField.OdinFieldType.DATE);
|
|
aliases.put("localtime", OdinField.OdinFieldType.DATE);
|
|
aliases.put("localdatetime", OdinField.OdinFieldType.DATE);
|
|
aliases.put("int", OdinField.OdinFieldType.NUMERIC);
|
|
aliases.put("integer", OdinField.OdinFieldType.NUMERIC);
|
|
aliases.put("double", OdinField.OdinFieldType.NUMERIC);
|
|
aliases.put("float", OdinField.OdinFieldType.NUMERIC);
|
|
aliases.put("long", OdinField.OdinFieldType.NUMERIC);
|
|
aliases.put("string", OdinField.OdinFieldType.STRING);
|
|
aliases.put("collection", OdinField.OdinFieldType.COLLECTION);
|
|
aliases.put("object", OdinField.OdinFieldType.OBJECT);
|
|
}
|
|
|
|
private OdinField.OdinFieldType getFieldTypeByTypeAlias(String fieldType) {
|
|
return Optional.ofNullable(aliases.get(fieldType)).orElse(OdinField.OdinFieldType.UNKNOWN);
|
|
}
|
|
|
|
private String getTypeAlias(String fieldType) {
|
|
return fieldType.replaceAll(".*\\.", "").toLowerCase().trim();
|
|
}
|
|
|
|
private OdinField.OdinFieldType getFieldType(Field field) {
|
|
final String typeAlias;
|
|
if (Collection.class.isAssignableFrom(field.getType())) {
|
|
typeAlias = "collection";
|
|
} else if (OdinDto.class.isAssignableFrom(field.getType())) {
|
|
typeAlias = "object";
|
|
} else {
|
|
typeAlias = getTypeAlias(field.getGenericType().getTypeName());
|
|
}
|
|
return getFieldTypeByTypeAlias(typeAlias);
|
|
}
|
|
|
|
private <T> List<OdinField> getDtoMetaModel(Class<T> dtoClass) {
|
|
return Arrays.stream(dtoClass.getDeclaredFields())
|
|
.filter(field -> !field.isAnnotationPresent(JsonIgnore.class)
|
|
&& !Modifier.isStatic(field.getModifiers()))
|
|
.map(field -> {
|
|
OdinField.OdinFieldType fieldType = getFieldType(field);
|
|
switch (fieldType) {
|
|
case BOOLEAN:
|
|
return new OdinBooleanField(field);
|
|
case DATE:
|
|
return new OdinDateField(field);
|
|
case NUMERIC:
|
|
return new OdinNumericField(field);
|
|
case STRING:
|
|
return new OdinStringField(field);
|
|
case COLLECTION:
|
|
return new OdinCollectionField(field);
|
|
case OBJECT:
|
|
return new OdinObjectField(field);
|
|
default:
|
|
log.debug("Unknown type {}. Skip field {} of DTO {}.",
|
|
field.getGenericType().getTypeName(), field.getName(), dtoClass.getSimpleName());
|
|
}
|
|
return null;
|
|
})
|
|
.filter(Objects::nonNull)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
public OdinMetadata getListModel(Class<L> listDtoClass) {
|
|
if (listDtoClass == null) {
|
|
throw new OdinException("List DTO class is null");
|
|
}
|
|
return new OdinMetadata(OdinDto.class.isAssignableFrom(listDtoClass), getDtoMetaModel(listDtoClass));
|
|
}
|
|
|
|
public OdinMetadata getElementModel(Class<E> elementDtoClass) {
|
|
return elementDtoClass == null
|
|
? null :
|
|
new OdinMetadata(true, getDtoMetaModel(elementDtoClass));
|
|
}
|
|
}
|