ng-tracker/src/main/java/ru/ulstu/odin/service/OdinService.java
Anton Romanov f587f80eb6 fix code
2018-11-14 17:03:22 +04:00

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));
}
}