package fr.openwide.core.jpa.more.util.init.util; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.MutablePropertyValues; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; import fr.openwide.core.jpa.business.generic.model.GenericEntity; import fr.openwide.core.jpa.more.util.init.dao.IImportDataDao; import fr.openwide.core.spring.util.SpringBeanUtils; import fr.openwide.core.spring.util.StringUtils; public class GenericEntityConverter implements GenericConverter { private ConversionService conversionService; private IImportDataDao importDataDao; private Workbook workbook; private Map<Class<?>, Class<?>> classMapping; private Map<String, Map<String, GenericEntity<Long, ?>>> idsMapping; public GenericEntityConverter(IImportDataDao importDataDao, Workbook workbook, Map<Class<?>, Class<?>> classMapping, Map<String, Map<String, GenericEntity<Long, ?>>> idsMapping) { super(); this.importDataDao = importDataDao; this.workbook = workbook; this.classMapping = classMapping; this.idsMapping = idsMapping; } @Override public Set<ConvertiblePair> getConvertibleTypes() { Set<ConvertiblePair> convertibleTypes = new LinkedHashSet<ConvertiblePair>(); convertibleTypes.add(new ConvertiblePair(String.class, GenericEntity.class)); return Collections.unmodifiableSet(convertibleTypes); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Object item = null; String importId = StringUtils.trimWhitespace((String)source); if (StringUtils.hasText(importId)) { item = convertFromDatabase(importId, targetType); if (item == null) { item = convertFromWorkbook(importId, targetType); } } return item; } public void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } private Object convertFromDatabase(String importId, TypeDescriptor targetType) { Class<GenericEntity<Long, ?>> clazz = getTargetClass(targetType); Long databaseId = getDatabaseId(clazz, importId); if (databaseId != null) { return importDataDao.getById(clazz, databaseId); } return null; } private Object convertFromWorkbook(String importId, TypeDescriptor targetType) { Class<GenericEntity<Long, ?>> clazz = getTargetClass(targetType); Sheet sheet = workbook.getSheet(clazz.getSimpleName()); if (sheet != null) { Map<String, Object> itemData = getItemData(sheet, importId); if (itemData != null) { if (!idsMapping.containsKey(clazz.getName())) { idsMapping.put(clazz.getName(), new HashMap<String, GenericEntity<Long, ?>>()); } GenericEntity<Long, ?> item = BeanUtils.instantiateClass(clazz); BeanWrapper wrapper = SpringBeanUtils.getBeanWrapper(item); wrapper.setConversionService(conversionService); wrapper.setPropertyValues(new MutablePropertyValues(itemData), true); idsMapping.get(clazz.getName()).put(importId, item); return item; } } return null; } @SuppressWarnings("unchecked") private Class<GenericEntity<Long, ?>> getTargetClass(TypeDescriptor targetType) { Class<GenericEntity<Long, ?>> clazz = (Class<GenericEntity<Long, ?>>) targetType.getType(); if (classMapping.containsKey(clazz)) { clazz = (Class<GenericEntity<Long, ?>>) classMapping.get(clazz); } return clazz; } private Long getDatabaseId(Class<GenericEntity<Long, ?>> clazz, String importId) { if (idsMapping.containsKey(clazz.getName()) && idsMapping.get(clazz.getName()).containsKey(importId)) { return idsMapping.get(clazz.getName()).get(importId).getId(); } else { return null; } } private Map<String, Object> getItemData(Sheet sheet, String importId) { for (Map<String, Object> line : WorkbookUtils.getSheetContent(sheet)) { if (line.containsKey("id") && importId.equals(line.get("id"))) { line.remove("id"); return line; } } return null; } }