package gov.samhsa.consent2share.service.valueset; import gov.samhsa.consent2share.domain.valueset.ConceptCodeValueSet; import gov.samhsa.consent2share.domain.valueset.ConceptCodeValueSetRepository; import gov.samhsa.consent2share.domain.valueset.ValueSet; import gov.samhsa.consent2share.domain.valueset.ValueSetCategory; import gov.samhsa.consent2share.domain.valueset.ValueSetCategoryRepository; import gov.samhsa.consent2share.domain.valueset.ValueSetRepository; import gov.samhsa.consent2share.service.dto.ValueSetDto; import gov.samhsa.consent2share.service.dto.ValueSetVSCDto; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.POIXMLException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; /** * The Class ValueSetServiceImpl. */ public class ValueSetServiceImpl implements ValueSetService { /** The logger. */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** The value set page size. */ private final int VALUE_SET_PAGE_SIZE;; /** The value set repository. */ private ValueSetRepository valueSetRepository; /** The value set category repository. */ private ValueSetCategoryRepository valueSetCategoryRepository; /** The concept code value set repository. */ ConceptCodeValueSetRepository conceptCodeValueSetRepository; /** The value set mgmt helper. */ ValueSetMgmtHelper valueSetMgmtHelper; /** * Instantiates a new value set service impl. * * @param valueSetPageSize * the value set page size * @param valueSetRepository * the value set repository * @param valueSetCategoryRepository * the value set category repository * @param conceptCodeValueSetRepository * the concept code value set repository * @param valueSetMgmtHelper * the value set mgmt helper */ public ValueSetServiceImpl(int valueSetPageSize, ValueSetRepository valueSetRepository, ValueSetCategoryRepository valueSetCategoryRepository, ConceptCodeValueSetRepository conceptCodeValueSetRepository, ValueSetMgmtHelper valueSetMgmtHelper) { super(); VALUE_SET_PAGE_SIZE = valueSetPageSize; this.valueSetRepository = valueSetRepository; this.valueSetCategoryRepository = valueSetCategoryRepository; this.conceptCodeValueSetRepository = conceptCodeValueSetRepository; this.valueSetMgmtHelper = valueSetMgmtHelper; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#create(gov. * samhsa.consent2share.service.dto.ValueSetDto) */ @Override @Transactional public ValueSetDto create(ValueSetDto created) throws ValueSetCategoryNotFoundException { logger.debug("Creating a new ValueSet with information: " + created); String description = (created.getDescription() != null) ? created .getDescription() : ""; ValueSet valueSet = ValueSet .getBuilder(created.getCode(), created.getName(), created.getUserName()).description(description).build(); // Step:1 Save the value set in the value_set table. valueSet = valueSetRepository.save(valueSet); // get the value set category entity from chosen value set cat id Long valueSetCategoryId = created.getValueSetCategoryId(); ValueSetCategory selected = valueSetCategoryRepository .findOne(valueSetCategoryId); if (selected == null) { logger.debug("No ValueSet category found with an id: " + valueSetCategoryId); throw new ValueSetCategoryNotFoundException(); } // refere value set category id to the value set entity object valueSet.setValueSetCategory(selected); ValueSetDto valueSetDto = valueSetMgmtHelper .createValuesetDtoFromEntity(valueSet); valueSetDto.setValueSetCatName(selected.getName()); return valueSetDto; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#delete(java * .lang.Long) */ @Override @Transactional(rollbackFor = ValueSetNotFoundException.class) public ValueSetDto delete(Long valueSetId) throws ValueSetNotFoundException { logger.debug("Deleting ValueSet with id: " + valueSetId); ValueSet deleted = valueSetRepository.findOne(valueSetId); if (deleted == null) { logger.debug("No ValueSet found with an id: " + valueSetId); throw new ValueSetNotFoundException( "No ValueSet found with an id: " + valueSetId); } // is it eligible to delete // check if any concept codes associated to this version List<ConceptCodeValueSet> conceptCodeValueSets = deleted .getConceptCodes(); if (null != conceptCodeValueSets && conceptCodeValueSets.size() > 0) { logger.debug("You can not delete a Value Set attached to an active Concept Code. " + valueSetId); throw new ValueSetNotFoundException( "You can not delete a Value Set attached to an active Concept Code. " + valueSetId); } valueSetRepository.delete(deleted); return valueSetMgmtHelper.createValuesetDtoFromEntity(deleted); } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#findById(java * .lang.Long) */ @Override public ValueSetDto findById(Long id) throws ValueSetCategoryNotFoundException { logger.debug("Finding a ValueSet with id: " + id); ValueSet valueSet = valueSetRepository.findOne(id); ValueSetDto valueSetDto = valueSetMgmtHelper .createValuesetDtoFromEntity(valueSet); // Get all valuesets List<ValueSetCategory> valueSetCategories = valueSetCategoryRepository .findAll(); if (valueSetCategories == null || valueSetCategories.size() == 0) { logger.debug("No Valueset Categories found in the system"); throw new ValueSetCategoryNotFoundException(); } valueSetDto.setValueSetCategoryMap(valueSetMgmtHelper .convertValueSetCategoryEntitiesToMap(valueSetCategories)); return valueSetDto; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#update(gov. * samhsa.consent2share.service.dto.ValueSetDto) */ @Override @Transactional(rollbackFor = ValueSetNotFoundException.class) public ValueSetDto update(ValueSetDto updated) throws ValueSetNotFoundException, ValueSetCategoryNotFoundException { logger.debug("Updating ValueSet with information" + updated); ValueSet valueSet = valueSetRepository.findOne(updated.getId()); if (valueSet == null) { logger.debug("No ValueSet found with an id: " + updated.getId()); throw new ValueSetNotFoundException(); } valueSet.update(updated.getCode(), updated.getName(), updated.getDescription(), updated.getUserName()); // category association change Long selValSetId = updated.getValueSetCategoryId(); Long origValSetId = valueSet.getValueSetCategory().getId(); if ((null != selValSetId && null != origValSetId) && selValSetId.equals(origValSetId)) { logger.debug("category association already exists"); } else { ValueSetCategory valueSetCategory = valueSetCategoryRepository .findOne(selValSetId); if (valueSetCategory == null) { logger.debug("No Valueset Category found for the selected id" + selValSetId); throw new ValueSetCategoryNotFoundException( "No Valueset Category found for the selected id" + selValSetId); } // save the association valueSet.setValueSetCategory(valueSetCategory); } return valueSetMgmtHelper.createValuesetDtoFromEntity(valueSet); } /* * (non-Javadoc) * * @see gov.samhsa.consent2share.service.valueset.ValueSetService#create() */ @Override public ValueSetVSCDto create() throws ValueSetCategoryNotFoundException { ValueSetVSCDto valueSetVSCDto = new ValueSetVSCDto(); // Get all valueset categories List<ValueSetCategory> valueSetCategories = valueSetCategoryRepository .findAll(); if (valueSetCategories == null || valueSetCategories.size() == 0) { logger.debug("No Valueset Categories found in the system"); throw new ValueSetCategoryNotFoundException(); } valueSetVSCDto.setValueSetCategoryMap(valueSetMgmtHelper .convertValueSetCategoryEntitiesToMap(valueSetCategories)); return valueSetVSCDto; } /* * (non-Javadoc) * * @see gov.samhsa.consent2share.service.valueset.ValueSetService#findAll() */ @Override public List<ValueSetDto> findAll() { logger.debug("Finding all valueSets"); List<ValueSet> valueSets = valueSetRepository.findAll(); return setDeletableToValueSetDto(valueSets); } /* * (non-Javadoc) * * @see gov.samhsa.consent2share.service.valueset.ValueSetService# * findAllWithoutDeletable() */ @Override public List<ValueSetDto> findAllWithoutDeletable() { logger.debug("Finding all valueSets"); List<ValueSet> valueSets = valueSetRepository.findAll(); return valueSetMgmtHelper .convertValueSetEntitiesToDtosWithoutDeletable(valueSets); } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#findAll(int) */ @Override public Map<String, Object> findAll(int pageNumber) { logger.debug("Finding all valueSets with paging"); Sort sort = new Sort(new Order(Direction.ASC, "code")); PageRequest pageRequest = new PageRequest(pageNumber, VALUE_SET_PAGE_SIZE, sort); Page<ValueSet> valueSets = valueSetRepository.findAll(pageRequest); Map<String, Object> pageResultsMap = new HashMap<String, Object>(); pageResultsMap.put("valueSets", setDeletableToValueSetDto((valueSets.getContent()))); pageResultsMap.put("totalNumberOfValueSets", valueSets.getTotalElements()); pageResultsMap.put("totalPages", valueSets.getTotalPages()); pageResultsMap.put("itemsPerPage", valueSets.getSize()); pageResultsMap.put("currentPage", valueSets.getNumber()); pageResultsMap.put("numberOfElements", valueSets.getNumberOfElements()); return pageResultsMap; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#findAllByName * (java.lang.String) */ @Override public Map<String, Object> findAllByName(String searchTerm, String valueSetCategory, int pageNumber) { Sort sort = new Sort(new Order(Direction.ASC, "code")); PageRequest pageRequest = new PageRequest(pageNumber, VALUE_SET_PAGE_SIZE, sort); Page<ValueSet> pagedValueSets = valueSetRepository.findAllByNameLike( "%" + searchTerm + "%", "%" + valueSetCategory + "%", pageRequest); Map<String, Object> pageResultsMap = new HashMap<String, Object>(); pageResultsMap.put("valueSets", setDeletableToValueSetDto(pagedValueSets.getContent())); pageResultsMap.put("totalNumberOfValueSets", pagedValueSets.getTotalElements()); pageResultsMap.put("totalPages", pagedValueSets.getTotalPages()); pageResultsMap.put("itemsPerPage", pagedValueSets.getSize()); pageResultsMap.put("currentPage", pagedValueSets.getNumber()); pageResultsMap.put("numberOfElements", pagedValueSets.getNumberOfElements()); return pageResultsMap; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#findAllByCode * (java.lang.String) */ @Override public Map<String, Object> findAllByCode(String searchTerm, String valueSetCategory, int pageNumber) { Sort sort = new Sort(new Order(Direction.ASC, "code")); PageRequest pageRequest = new PageRequest(pageNumber, VALUE_SET_PAGE_SIZE, sort); Page<ValueSet> pagedValueSets = valueSetRepository.findAllByCodeLike( "%" + searchTerm + "%", "%" + valueSetCategory + "%", pageRequest); Map<String, Object> pageResultsMap = new HashMap<String, Object>(); pageResultsMap.put("valueSets", setDeletableToValueSetDto(pagedValueSets.getContent())); pageResultsMap.put("totalNumberOfValueSets", pagedValueSets.getTotalElements()); pageResultsMap.put("totalPages", pagedValueSets.getTotalPages()); pageResultsMap.put("itemsPerPage", pagedValueSets.getSize()); pageResultsMap.put("currentPage", pagedValueSets.getNumber()); pageResultsMap.put("numberOfElements", pagedValueSets.getNumberOfElements()); return pageResultsMap; } /* * (non-Javadoc) * * @see * gov.samhsa.consent2share.service.valueset.ValueSetService#valueSetBatchUpload * (gov.samhsa.consent2share.service.dto.ValueSetDto, * org.springframework.web.multipart.MultipartFile) */ @Override @Transactional(rollbackFor = DataIntegrityViolationException.class) public ValueSetDto valueSetBatchUpload(ValueSetDto valueSetDto, MultipartFile file) throws IOException, ValueSetNotFoundException { String userName = valueSetDto.getUserName(); int rowsUpdated = 0; int rowNum = 1; validateCSV(file); try { List<ValueSetDto> listOfValueSetsDtos = valueSetMgmtHelper .readValueSetsFromFile(file, userName); for (int i = 0; i < listOfValueSetsDtos.size(); i++) { ValueSetDto batchValueSetDto = listOfValueSetsDtos.get(i); ValueSet valueSet = new ValueSet(); ValueSetCategory valueSetCategory = valueSetCategoryRepository .findByName(batchValueSetDto.getValueSetCatName()); if (valueSetCategory == null) { throw new ValueSetNotFoundException( "Invalid Value Set Category for row: " + (i + 1)); } valueSet.setUserName(userName); valueSet.setCode(batchValueSetDto.getCode()); valueSet.setName(batchValueSetDto.getName()); valueSet.setDescription(batchValueSetDto.getDescription()); valueSet.setValueSetCategory(valueSetCategory); valueSetRepository.save(valueSet); rowsUpdated++; rowNum++; } valueSetDto.setRowsUpdated(rowsUpdated); } catch (DataIntegrityViolationException ex) { logger.debug("Cannot add value set. There is an error with file at row: " + ex.getMessage()); valueSetDto.setError(true); valueSetDto .setErrorMessage("Cannot add value set. There is an error with file at row: " + (rowNum + 1)); throw ex; } catch (ValueSetNotFoundException ex) { logger.debug("Missing required field while doing batch upload: " + ex.getMessage()); valueSetDto.setError(true); valueSetDto.setErrorMessage(ex.getMessage()); throw ex; } catch (InvalidCSVException ex) { valueSetDto.setError(true); valueSetDto.setErrorMessage(ex.getMessage()); throw ex; } catch (POIXMLException ex) { logger.debug("Incorrect file format: " + ex.getMessage()); valueSetDto.setError(true); valueSetDto .setErrorMessage("Incorrect file format. File should be a correct .xslx file"); } catch (IOException ex) { logger.debug("Unable to open file: " + ex.getMessage()); valueSetDto.setError(true); valueSetDto.setErrorMessage("Unable to open file"); } catch (Exception ex) { logger.debug("Exception thrown: " + ex.getMessage()); valueSetDto.setError(true); valueSetDto .setErrorMessage("An error occurred. Please check with administrator: " + ex.getMessage()); } return valueSetDto; } /** * This setter method should be used only by unit tests. * * @param valueSetRepository * the new value set repository */ protected void setValueSetRepository(ValueSetRepository valueSetRepository) { this.valueSetRepository = valueSetRepository; } /** * Sets the deletable to value set dto. * * @param valueSets * the value sets * @return the list */ protected List<ValueSetDto> setDeletableToValueSetDto( List<ValueSet> valueSets) { List<ValueSetDto> valueSetDtos = valueSetMgmtHelper .convertValueSetEntitiesToDtos(valueSets); // setting deletable flag to each dto for (ValueSetDto valueSetDto : valueSetDtos) { List<ConceptCodeValueSet> cValueSets = conceptCodeValueSetRepository .findAllByPkValueSetId(valueSetDto.getId()); if (null != cValueSets && cValueSets.size() > 0) { valueSetDto.setDeletable(false); } } return valueSetDtos; } /** * Validate csv. * * @param file * the file */ private void validateCSV(MultipartFile file) { if (file.isEmpty()) { throw new InvalidCSVException("File cannot be empty"); } } }