use of de.symeda.sormas.api.importexport.ImportErrorException in project SORMAS-Project by hzi-braunschweig.
the class PopulationDataImporter method importDataFromCsvLine.
@Override
protected ImportLineResult importDataFromCsvLine(String[] values, String[] entityClasses, String[] entityProperties, String[][] entityPropertyPaths, boolean firstLine) throws IOException, InvalidColumnException, InterruptedException {
// Check whether the new line has the same length as the header line
if (values.length > entityProperties.length) {
writeImportError(values, I18nProperties.getValidationError(Validations.importLineTooLong));
return ImportLineResult.ERROR;
}
// Reference population data that contains the region, district and community for this line
RegionReferenceDto region = null;
DistrictReferenceDto district = null;
CommunityReferenceDto community = null;
// Retrieve the region and district from the database or throw an error if more or less than one entry have been retrieved
for (int i = 0; i < entityProperties.length; i++) {
if (PopulationDataDto.REGION.equalsIgnoreCase(entityProperties[i])) {
List<RegionReferenceDto> regions = FacadeProvider.getRegionFacade().getReferencesByName(values[i], false);
if (regions.size() != 1) {
writeImportError(values, new ImportErrorException(values[i], entityProperties[i]).getMessage());
return ImportLineResult.ERROR;
}
region = regions.get(0);
}
if (PopulationDataDto.DISTRICT.equalsIgnoreCase(entityProperties[i])) {
if (DataHelper.isNullOrEmpty(values[i])) {
district = null;
} else {
List<DistrictReferenceDto> districts = FacadeProvider.getDistrictFacade().getByName(values[i], region, false);
if (districts.size() != 1) {
writeImportError(values, new ImportErrorException(values[i], entityProperties[i]).getMessage());
return ImportLineResult.ERROR;
}
district = districts.get(0);
}
}
if (PopulationDataDto.COMMUNITY.equalsIgnoreCase(entityProperties[i])) {
if (DataHelper.isNullOrEmpty(values[i])) {
community = null;
} else {
List<CommunityReferenceDto> communities = FacadeProvider.getCommunityFacade().getByName(values[i], district, false);
if (communities.size() != 1) {
writeImportError(values, new ImportErrorException(values[i], entityProperties[i]).getMessage());
return ImportLineResult.ERROR;
}
community = communities.get(0);
}
}
}
// The region and district that will be used to save the population data to the database
final RegionReferenceDto finalRegion = region;
final DistrictReferenceDto finalDistrict = district;
final CommunityReferenceDto finalCommunity = community;
// Retrieve the existing population data for the region and district
PopulationDataCriteria criteria = new PopulationDataCriteria().region(finalRegion);
if (finalCommunity == null) {
criteria.communityIsNull(true);
} else {
criteria.community(finalCommunity);
}
if (district == null) {
criteria.districtIsNull(true);
} else {
criteria.district(finalDistrict);
}
List<PopulationDataDto> existingPopulationDataList = FacadeProvider.getPopulationDataFacade().getPopulationData(criteria);
List<PopulationDataDto> modifiedPopulationDataList = new ArrayList<PopulationDataDto>();
boolean populationDataHasImportError = insertRowIntoData(values, entityClasses, entityPropertyPaths, false, new Function<ImportCellData, Exception>() {
@Override
public Exception apply(ImportCellData cellData) {
try {
if (PopulationDataDto.REGION.equalsIgnoreCase(cellData.getEntityPropertyPath()[0]) || PopulationDataDto.DISTRICT.equalsIgnoreCase(cellData.getEntityPropertyPath()[0]) || PopulationDataDto.COMMUNITY.equalsIgnoreCase(cellData.getEntityPropertyPath()[0])) {
// Ignore the region, district and community columns
} else if (RegionDto.GROWTH_RATE.equalsIgnoreCase(cellData.getEntityPropertyPath()[0])) {
// Update the growth rate of the region or district
if (!DataHelper.isNullOrEmpty(cellData.getValue())) {
Float growthRate = Float.parseFloat(cellData.getValue());
if (finalCommunity != null) {
CommunityDto communityDto = FacadeProvider.getCommunityFacade().getByUuid(finalCommunity.getUuid());
communityDto.setGrowthRate(growthRate);
FacadeProvider.getCommunityFacade().save(communityDto);
} else if (finalDistrict != null) {
DistrictDto districtDto = FacadeProvider.getDistrictFacade().getByUuid(finalDistrict.getUuid());
districtDto.setGrowthRate(growthRate);
FacadeProvider.getDistrictFacade().save(districtDto);
} else {
RegionDto regionDto = FacadeProvider.getRegionFacade().getByUuid(finalRegion.getUuid());
regionDto.setGrowthRate(growthRate);
FacadeProvider.getRegionFacade().save(regionDto);
}
}
} else {
// Add the data from the currently processed cell to a new population data object
PopulationDataDto newPopulationData = PopulationDataDto.build(collectionDate);
insertCellValueIntoData(newPopulationData, cellData.getValue(), cellData.getEntityPropertyPath());
Optional<PopulationDataDto> existingPopulationData = existingPopulationDataList.stream().filter(populationData -> populationData.getAgeGroup() == newPopulationData.getAgeGroup() && populationData.getSex() == newPopulationData.getSex()).findFirst();
// Check whether this population data set already exists in the database; if yes, override it
if (existingPopulationData.isPresent()) {
existingPopulationData.get().setPopulation(newPopulationData.getPopulation());
existingPopulationData.get().setCollectionDate(collectionDate);
modifiedPopulationDataList.add(existingPopulationData.get());
} else {
newPopulationData.setRegion(finalRegion);
newPopulationData.setDistrict(finalDistrict);
newPopulationData.setCommunity(finalCommunity);
modifiedPopulationDataList.add(newPopulationData);
}
}
} catch (ImportErrorException | InvalidColumnException | NumberFormatException e) {
return e;
}
return null;
}
});
// Validate and save the population data object into the database if the import has no errors
if (!populationDataHasImportError) {
try {
FacadeProvider.getPopulationDataFacade().savePopulationData(modifiedPopulationDataList);
return ImportLineResult.SUCCESS;
} catch (ValidationRuntimeException e) {
writeImportError(values, e.getMessage());
return ImportLineResult.ERROR;
}
} else {
return ImportLineResult.ERROR;
}
}
use of de.symeda.sormas.api.importexport.ImportErrorException in project SORMAS-Project by hzi-braunschweig.
the class InfrastructureImporter method insertColumnEntryIntoData.
/**
* Inserts the entry of a single cell into the infrastructure object.
*/
private void insertColumnEntryIntoData(EntityDto newEntityDto, String value, String[] entityPropertyPath) throws InvalidColumnException, ImportErrorException {
Object currentElement = newEntityDto;
for (int i = 0; i < entityPropertyPath.length; i++) {
String headerPathElementName = entityPropertyPath[i];
try {
if (i != entityPropertyPath.length - 1) {
currentElement = new PropertyDescriptor(headerPathElementName, currentElement.getClass()).getReadMethod().invoke(currentElement);
} else {
PropertyDescriptor pd = new PropertyDescriptor(headerPathElementName, currentElement.getClass());
Class<?> propertyType = pd.getPropertyType();
// is referenced in the imported object does not exist in the database
if (!executeDefaultInvoke(pd, currentElement, value, entityPropertyPath)) {
if (propertyType.isAssignableFrom(DistrictReferenceDto.class)) {
List<DistrictReferenceDto> district;
switch(type) {
case COMMUNITY:
district = FacadeProvider.getDistrictFacade().getByName(value, ((CommunityDto) newEntityDto).getRegion(), false);
break;
case FACILITY:
district = FacadeProvider.getDistrictFacade().getByName(value, ((FacilityDto) newEntityDto).getRegion(), false);
break;
case POINT_OF_ENTRY:
district = FacadeProvider.getDistrictFacade().getByName(value, ((PointOfEntryDto) newEntityDto).getRegion(), false);
break;
default:
throw new UnsupportedOperationException(I18nProperties.getValidationError(Validations.importPropertyTypeNotAllowed, propertyType.getName()));
}
if (district.isEmpty()) {
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrRegion, value, buildEntityProperty(entityPropertyPath)));
} else if (district.size() > 1) {
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importDistrictNotUnique, value, buildEntityProperty(entityPropertyPath)));
} else {
pd.getWriteMethod().invoke(currentElement, district.get(0));
}
} else if (propertyType.isAssignableFrom(CommunityReferenceDto.class)) {
List<CommunityReferenceDto> community;
if (type == InfrastructureType.FACILITY) {
community = FacadeProvider.getCommunityFacade().getByName(value, ((FacilityDto) newEntityDto).getDistrict(), false);
} else {
throw new UnsupportedOperationException(I18nProperties.getValidationError(Validations.importPropertyTypeNotAllowed, propertyType.getName()));
}
if (community.isEmpty()) {
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrRegion, value, buildEntityProperty(entityPropertyPath)));
} else if (community.size() > 1) {
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importDistrictNotUnique, value, buildEntityProperty(entityPropertyPath)));
} else {
pd.getWriteMethod().invoke(currentElement, community.get(0));
}
} else {
throw new UnsupportedOperationException(I18nProperties.getValidationError(Validations.importPropertyTypeNotAllowed, propertyType.getName()));
}
}
}
} catch (IntrospectionException e) {
throw new InvalidColumnException(buildEntityProperty(entityPropertyPath));
} catch (InvocationTargetException | IllegalAccessException e) {
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importErrorInColumn, buildEntityProperty(entityPropertyPath)));
} catch (IllegalArgumentException e) {
throw new ImportErrorException(value, buildEntityProperty(entityPropertyPath));
} catch (ImportErrorException e) {
throw e;
} catch (Exception e) {
logger.error("Unexpected error when trying to import infrastructure data: " + e.getMessage());
throw new ImportErrorException(I18nProperties.getValidationError(Validations.importUnexpectedError));
}
}
ImportLineResultDto<EntityDto> constraintErrors = validateConstraints(newEntityDto);
if (constraintErrors.isError()) {
throw new ImportErrorException(constraintErrors.getMessage());
}
}
use of de.symeda.sormas.api.importexport.ImportErrorException in project SORMAS-Project by hzi-braunschweig.
the class InfrastructureImporter method importDataFromCsvLine.
@Override
protected ImportLineResult importDataFromCsvLine(String[] values, String[] entityClasses, String[] entityProperties, String[][] entityPropertyPaths, boolean firstLine) throws IOException, InvalidColumnException {
// Check whether the new line has the same length as the header line
if (values.length > entityProperties.length) {
writeImportError(values, I18nProperties.getValidationError(Validations.importLineTooLong));
return ImportLineResult.ERROR;
}
EntityDto newEntityDto;
switch(type) {
case COMMUNITY:
newEntityDto = CommunityDto.build();
break;
case DISTRICT:
newEntityDto = DistrictDto.build();
break;
case FACILITY:
newEntityDto = FacilityDto.build();
break;
case POINT_OF_ENTRY:
newEntityDto = PointOfEntryDto.build();
break;
case REGION:
newEntityDto = RegionDto.build();
break;
case AREA:
newEntityDto = AreaDto.build();
break;
case SUBCONTINENT:
newEntityDto = SubcontinentDto.build();
break;
case CONTINENT:
newEntityDto = ContinentDto.build();
break;
default:
throw new IllegalArgumentException(type.toString());
}
boolean iHasImportError = insertRowIntoData(values, entityClasses, entityPropertyPaths, false, (cellData) -> {
try {
// If the cell entry is not empty, try to insert it into the current infrastructure object
if (!StringUtils.isEmpty(cellData.getValue())) {
insertColumnEntryIntoData(newEntityDto, cellData.getValue(), cellData.getEntityPropertyPath());
}
} catch (ImportErrorException | InvalidColumnException e) {
return e;
}
return null;
});
// if there is already an infrastructure object with this name in the database
if (!iHasImportError) {
try {
switch(type) {
case COMMUNITY:
FacadeProvider.getCommunityFacade().save((CommunityDto) newEntityDto, allowOverwrite);
break;
case DISTRICT:
FacadeProvider.getDistrictFacade().save((DistrictDto) newEntityDto, allowOverwrite);
break;
case FACILITY:
FacadeProvider.getFacilityFacade().save((FacilityDto) newEntityDto, allowOverwrite);
break;
case POINT_OF_ENTRY:
FacadeProvider.getPointOfEntryFacade().save((PointOfEntryDto) newEntityDto, allowOverwrite);
break;
case REGION:
FacadeProvider.getRegionFacade().save((RegionDto) newEntityDto, allowOverwrite);
break;
case AREA:
FacadeProvider.getAreaFacade().save((AreaDto) newEntityDto, allowOverwrite);
break;
case SUBCONTINENT:
FacadeProvider.getSubcontinentFacade().save((SubcontinentDto) newEntityDto, allowOverwrite);
break;
case CONTINENT:
FacadeProvider.getContinentFacade().save((ContinentDto) newEntityDto, allowOverwrite);
break;
default:
throw new IllegalArgumentException(type.toString());
}
return ImportLineResult.SUCCESS;
} catch (ValidationRuntimeException e) {
writeImportError(values, e.getMessage());
return ImportLineResult.ERROR;
}
} else {
return ImportLineResult.ERROR;
}
}
use of de.symeda.sormas.api.importexport.ImportErrorException in project SORMAS-Project by hzi-braunschweig.
the class EventParticipantImporter method importDataFromCsvLine.
@Override
protected ImportLineResult importDataFromCsvLine(String[] values, String[] entityClasses, String[] entityProperties, String[][] entityPropertyPaths, boolean firstLine) throws IOException, InterruptedException {
// Check whether the new line has the same length as the header line
if (values.length > entityProperties.length) {
writeImportError(values, I18nProperties.getValidationError(Validations.importLineTooLong));
return ImportLineResult.ERROR;
}
// regenerate the UUID to prevent overwrite in case of export and import of the same entities
int uuidIndex = ArrayUtils.indexOf(entityProperties, EventParticipantDto.UUID);
if (uuidIndex >= 0) {
values[uuidIndex] = DataHelper.createUuid();
}
int personUuidIndex = ArrayUtils.indexOf(entityProperties, String.join(".", EventParticipantDto.PERSON, PersonDto.UUID));
if (personUuidIndex >= 0) {
values[personUuidIndex] = DataHelper.createUuid();
}
final PersonDto newPersonTemp = PersonDto.buildImportEntity();
final EventParticipantDto newEventParticipantTemp = EventParticipantDto.build(event.toReference(), currentUser.toReference());
newEventParticipantTemp.setPerson(newPersonTemp);
final List<VaccinationDto> vaccinations = new ArrayList<>();
ImportRelatedObjectsMapper.Builder relatedObjectsMapperBuilder = new ImportRelatedObjectsMapper.Builder();
if (FacadeProvider.getFeatureConfigurationFacade().isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED) && event.getDisease() != null) {
relatedObjectsMapperBuilder.addMapper(VaccinationDto.class, vaccinations, () -> VaccinationDto.build(currentUser.toReference()), this::insertColumnEntryIntoRelatedObject);
}
ImportRelatedObjectsMapper relatedMapper = relatedObjectsMapperBuilder.build();
boolean eventParticipantHasImportError = insertRowIntoData(values, entityClasses, entityPropertyPaths, true, importColumnInformation -> {
try {
if (!relatedMapper.map(importColumnInformation)) {
// If the cell entry is not empty, try to insert it into the current contact or person object
if (!StringUtils.isEmpty(importColumnInformation.getValue())) {
insertColumnEntryIntoData(newEventParticipantTemp, newPersonTemp, importColumnInformation.getValue(), importColumnInformation.getEntityPropertyPath());
}
}
} catch (ImportErrorException | InvalidColumnException e) {
return e;
}
return null;
});
// If the row does not have any import errors, call the backend validation of all associated entities
if (!eventParticipantHasImportError) {
try {
personFacade.validate(newPersonTemp);
eventParticipantFacade.validate(newEventParticipantTemp);
} catch (ValidationRuntimeException e) {
eventParticipantHasImportError = true;
writeImportError(values, e.getMessage());
}
}
PersonDto newPerson = newPersonTemp;
// Sanitize non-HOME address
PersonHelper.sanitizeNonHomeAddress(newPerson);
// if there are any, display a window to resolve the conflict to the user
if (!eventParticipantHasImportError) {
EventParticipantDto newEventParticipant = newEventParticipantTemp;
try {
EventParticipantImportConsumer consumer = new EventParticipantImportConsumer();
ImportSimilarityResultOption resultOption = null;
EventParticipantImportLock personSelectLock = new EventParticipantImportLock();
// We need to pause the current thread to prevent the import from continuing until the user has acted
synchronized (personSelectLock) {
// Call the logic that allows the user to handle the similarity; once this has been done, the LOCK should be notified
// to allow the importer to resume
handlePersonSimilarity(newPerson, result -> consumer.onImportResult(result, personSelectLock), (person, similarityResultOption) -> new PersonImportSimilarityResult(person, similarityResultOption), Strings.infoSelectOrCreatePersonForImport, currentUI);
try {
if (!personSelectLock.wasNotified) {
personSelectLock.wait();
}
} catch (InterruptedException e) {
logger.error("InterruptedException when trying to perform LOCK.wait() in eventparticipant import: " + e.getMessage());
throw e;
}
if (consumer.result != null) {
resultOption = consumer.result.getResultOption();
}
// If the user picked an existing person, override the eventparticipant person with it
if (ImportSimilarityResultOption.PICK.equals(resultOption)) {
newPerson = personFacade.getPersonByUuid(consumer.result.getMatchingPerson().getUuid());
// get first eventparticipant for event and person
EventParticipantCriteria eventParticipantCriteria = new EventParticipantCriteria().withPerson(newPerson.toReference()).withEvent(event.toReference());
EventParticipantDto pickedEventParticipant = eventParticipantFacade.getFirst(eventParticipantCriteria);
if (pickedEventParticipant != null) {
// re-apply import on pickedEventParticipant
insertRowIntoData(values, entityClasses, entityPropertyPaths, true, importColumnInformation -> {
// If the cell entry is not empty, try to insert it into the current contact or person object
if (!StringUtils.isEmpty(importColumnInformation.getValue())) {
try {
insertColumnEntryIntoData(pickedEventParticipant, newPersonTemp, importColumnInformation.getValue(), importColumnInformation.getEntityPropertyPath());
} catch (ImportErrorException | InvalidColumnException e) {
return e;
}
}
return null;
});
newEventParticipant = pickedEventParticipant;
}
}
}
// or an existing person was picked, save the eventparticipant and person to the database
if (ImportSimilarityResultOption.SKIP.equals(resultOption)) {
return ImportLineResult.SKIPPED;
} else {
// Workaround: Reset the change date to avoid OutdatedEntityExceptions
newPerson.setChangeDate(new Date());
boolean skipPersonValidation = ImportSimilarityResultOption.PICK.equals(resultOption);
final PersonDto savedPerson = personFacade.savePerson(newPerson, skipPersonValidation);
newEventParticipant.setPerson(savedPerson);
newEventParticipant.setChangeDate(new Date());
eventParticipantFacade.saveEventParticipant(newEventParticipant);
for (VaccinationDto vaccination : vaccinations) {
FacadeProvider.getVaccinationFacade().createWithImmunization(vaccination, newEventParticipant.getRegion(), newEventParticipant.getDistrict(), newEventParticipant.getPerson().toReference(), event.getDisease());
}
consumer.result = null;
return ImportLineResult.SUCCESS;
}
} catch (ValidationRuntimeException e) {
writeImportError(values, e.getMessage());
return ImportLineResult.ERROR;
}
} else {
return ImportLineResult.ERROR;
}
}
Aggregations