/*******************************************************************************
* Open Behavioral Health Information Technology Architecture (OBHITA.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
package gov.samhsa.consent2share.service.clinicaldata;
import gov.samhsa.consent2share.common.AuthenticatedUser;
import gov.samhsa.consent2share.common.UserContext;
import gov.samhsa.consent2share.domain.clinicaldata.ClinicalDocument;
import gov.samhsa.consent2share.domain.clinicaldata.ClinicalDocumentRepository;
import gov.samhsa.consent2share.domain.patient.Patient;
import gov.samhsa.consent2share.domain.patient.PatientRepository;
import gov.samhsa.consent2share.domain.reference.ClinicalDocumentTypeCodeRepository;
import gov.samhsa.consent2share.service.dto.ClinicalDocumentDto;
import gov.samhsa.consent2share.service.dto.LookupDto;
import gov.samhsa.consent2share.service.dto.PatientProfileDto;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* The Class ClinicalDocumentServiceImpl.
*/
@Transactional
public class ClinicalDocumentServiceImpl implements ClinicalDocumentService,
InitializingBean {
/** The logger. */
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/** The max file size. */
private Long maxFileSize;
/** The permitted extensions. */
private String permittedExtensions;
/** The permitted extensions array. */
private String[] permittedExtensionsArray;
/** The clinical document repository. */
ClinicalDocumentRepository clinicalDocumentRepository;
/** The clinical document type code repository. */
ClinicalDocumentTypeCodeRepository clinicalDocumentTypeCodeRepository;
/** The model mapper. */
ModelMapper modelMapper;
/** The patient repository. */
PatientRepository patientRepository;
/** The user context. */
UserContext userContext;
/** The validator. */
Validator validator;
/**
* Instantiates a new clinical document service impl.
*
* @param maxFileSize
* the max file size
* @param permittedExtensions
* the permitted extensions
* @param clinicalDocumentRepository
* the clinical document repository
* @param clinicalDocumentTypeCodeRepository
* the clinical document type code repository
* @param modelMapper
* the model mapper
* @param patientRepository
* the patient repository
* @param userContext
* the user context
* @param validator
* the validator
*/
public ClinicalDocumentServiceImpl(
String maxFileSize,
String permittedExtensions,
ClinicalDocumentRepository clinicalDocumentRepository,
ClinicalDocumentTypeCodeRepository clinicalDocumentTypeCodeRepository,
ModelMapper modelMapper, PatientRepository patientRepository,
UserContext userContext, Validator validator) {
super();
this.maxFileSize = Long.parseLong(maxFileSize);
this.permittedExtensions = permittedExtensions;
this.clinicalDocumentRepository = clinicalDocumentRepository;
this.clinicalDocumentTypeCodeRepository = clinicalDocumentTypeCodeRepository;
this.modelMapper = modelMapper;
this.patientRepository = patientRepository;
this.userContext = userContext;
this.validator = validator;
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
permittedExtensionsArray = permittedExtensions.split(",");
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #countAllClinicalDocuments()
*/
@Override
public long countAllClinicalDocuments() {
return clinicalDocumentRepository.count();
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #deleteClinicalDocument
* (gov.samhsa.consent2share.service.dto.ClinicalDocumentDto)
*/
@Override
public void deleteClinicalDocument(ClinicalDocumentDto clinicalDocumentDto) {
ClinicalDocument clinicalDocument = getClinicalDocumenFromDto(clinicalDocumentDto);
clinicalDocumentRepository.delete(clinicalDocument);
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findClinicalDocument(java.lang.Long)
*/
@Override
public ClinicalDocument findClinicalDocument(Long id) {
return clinicalDocumentRepository.findOne(id);
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findAllClinicalDocuments()
*/
@Override
public List<ClinicalDocument> findAllClinicalDocuments() {
return clinicalDocumentRepository.findAll();
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findClinicalDocumentEntries(int, int)
*/
@Override
public List<ClinicalDocument> findClinicalDocumentEntries(int firstResult,
int maxResults) {
return clinicalDocumentRepository.findAll(
new org.springframework.data.domain.PageRequest(firstResult
/ maxResults, maxResults)).getContent();
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #saveClinicalDocument
* (gov.samhsa.consent2share.service.dto.ClinicalDocumentDto)
*/
@Override
public void saveClinicalDocument(ClinicalDocumentDto clinicalDocumentDto) {
if (validateClinicalDocumentDtoFields(clinicalDocumentDto) == true) {
ClinicalDocument clinicalDocument = getClinicalDocumenFromDto(clinicalDocumentDto);
clinicalDocumentRepository.save(clinicalDocument);
}
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #updateClinicalDocument
* (gov.samhsa.consent2share.domain.clinicaldata.ClinicalDocument)
*/
@Override
public ClinicalDocument updateClinicalDocument(
ClinicalDocument clinicalDocument) {
return clinicalDocumentRepository.save(clinicalDocument);
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findClinicalDocumentDto(long)
*/
@Override
public ClinicalDocumentDto findClinicalDocumentDto(long documentId) {
ClinicalDocument clinicalDocument = findClinicalDocument(documentId);
ClinicalDocumentDto clinicalDocumentDto = modelMapper.map(
clinicalDocument, ClinicalDocumentDto.class);
// manual mapping without using model mapper
AuthenticatedUser currentUser = userContext.getCurrentUser();
String username = currentUser.getUsername();
clinicalDocumentDto.setPatientId(patientRepository.findByUsername(
username).getId());
return clinicalDocumentDto;
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findByPatient(gov.samhsa.consent2share.domain.patient.Patient)
*/
@Override
public List<ClinicalDocument> findByPatient(Patient patient) {
return clinicalDocumentRepository.findByPatientId(patient.getId());
}
/**
* Find clinical documents by patient Id.
*
* @param patientId
* the patient id
* @return the list
*/
@Override
public List<ClinicalDocument> findByPatientId(long patientId) {
return clinicalDocumentRepository.findByPatientId(patientId);
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #findDtoByPatientDto
* (gov.samhsa.consent2share.service.dto.PatientProfileDto)
*/
@Override
public List<ClinicalDocumentDto> findDtoByPatientDto(
PatientProfileDto patientDto) {
Patient patient = patientRepository.findByUsername(patientDto
.getUsername());
List<ClinicalDocumentDto> dtos = findDtoByPatient(patient);
for (ClinicalDocumentDto dto : dtos) {
if (dto.getClinicalDocumentTypeCode() == null) {
LookupDto typeCode = new LookupDto();
typeCode.setDisplayName("Not Specified");
dto.setClinicalDocumentTypeCode(typeCode);
}
}
return dtos;
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #isDocumentBelongsToThisUser
* (gov.samhsa.consent2share.service.dto.ClinicalDocumentDto)
*/
@Override
public boolean isDocumentBelongsToThisUser(
ClinicalDocumentDto clinicalDocumentDto) {
AuthenticatedUser currentUser = userContext.getCurrentUser();
String username = currentUser.getUsername();
Patient patient = patientRepository.findByUsername(username);
List<ClinicalDocumentDto> clinicaldocumentDtos = findDtoByPatient(patient);
for (ClinicalDocumentDto documentDto : clinicaldocumentDtos) {
if (documentDto.getId().equals(clinicalDocumentDto.getId())) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #isDocumentOversized(org.springframework.web.multipart.MultipartFile)
*/
@Override
public boolean isDocumentOversized(MultipartFile file) {
if (file.getSize() > maxFileSize)
return true;
return false;
}
/*
* (non-Javadoc)
*
* @see
* gov.samhsa.consent2share.service.clinicaldata.ClinicalDocumentService
* #isDocumentExtensionPermitted
* (org.springframework.web.multipart.MultipartFile)
*/
@Override
public boolean isDocumentExtensionPermitted(MultipartFile file) {
boolean result = false;
int indexOfDot = file.getOriginalFilename().indexOf(".");
if (indexOfDot >= 0) {
String extension = file.getOriginalFilename().substring(
indexOfDot + 1);
for (String permittedExtension : permittedExtensionsArray) {
if (extension.equals(permittedExtension)) {
result = true;
break;
}
}
}
return result;
}
/**
* Validate clinical document dto fields.
*
* @param clinicalDocumentDto
* the clinical document dto
* @return true, if successful
*/
boolean validateClinicalDocumentDtoFields(
ClinicalDocumentDto clinicalDocumentDto) {
Set<ConstraintViolation<ClinicalDocumentDto>> violations = validator
.validate(clinicalDocumentDto);
if (violations.isEmpty() == true)
return true;
throw new ConstraintViolationException("Field validation error.",
new HashSet<ConstraintViolation<?>>(violations));
}
/**
* Find dto by patient.
*
* @param patient
* the patient
* @return the list
*/
List<ClinicalDocumentDto> findDtoByPatient(Patient patient) {
List<ClinicalDocument> documents = clinicalDocumentRepository
.findByPatientId(patient.getId());
List<ClinicalDocumentDto> dtos = new ArrayList<ClinicalDocumentDto>();
for (ClinicalDocument doc : documents) {
ClinicalDocumentDto clinicalDocumentDto = modelMapper.map(doc,
ClinicalDocumentDto.class);
// manual mapping without using model mapper
clinicalDocumentDto.setPatientId(patient.getId());
dtos.add(clinicalDocumentDto);
}
return dtos;
}
/**
* Gets the clinical document from dto.
*
* @param clinicalDocumentDto
* the clinical document dto
* @return the clinical document from dto
*/
private ClinicalDocument getClinicalDocumenFromDto(
ClinicalDocumentDto clinicalDocumentDto) {
// required fields
ClinicalDocument clinicalDocument = new ClinicalDocument();
if (clinicalDocumentDto.getId() != null)
clinicalDocument.setId(Long.parseLong(clinicalDocumentDto.getId()));
clinicalDocument.setName(clinicalDocumentDto.getName());
clinicalDocument.setFilename(clinicalDocumentDto.getFilename());
clinicalDocument.setContent(clinicalDocumentDto.getContent());
clinicalDocument.setContentType(clinicalDocumentDto.getContentType());
clinicalDocument.setDocumentSize(clinicalDocumentDto.getDocumentSize());
// optional fields
if (clinicalDocumentDto.getClinicalDocumentTypeCode() != null) {
clinicalDocument
.setClinicalDocumentTypeCode(clinicalDocumentTypeCodeRepository
.findByCode(clinicalDocumentDto
.getClinicalDocumentTypeCode().getCode()));
} else {
clinicalDocument.setClinicalDocumentTypeCode(null);
}
if (StringUtils.hasText(clinicalDocumentDto.getDescription())) {
clinicalDocument.setDescription(clinicalDocumentDto
.getDescription());
} else {
clinicalDocument.setDescription(null);
}
if (StringUtils.hasText(clinicalDocumentDto.getDocumentUrl())) {
clinicalDocument.setDocumentUrl(clinicalDocumentDto
.getDocumentUrl());
} else {
clinicalDocument.setDocumentUrl(null);
}
if (patientRepository.findOne(clinicalDocumentDto.getPatientId()) != null) {
clinicalDocument.setPatient(patientRepository
.findOne(clinicalDocumentDto.getPatientId()));
} else {
clinicalDocument.setPatient(null);
}
if (clinicalDocumentDto.getVersion() != null) {
clinicalDocument.setVersion(clinicalDocumentDto.getVersion());
} else {
clinicalDocument.setVersion(null);
}
return clinicalDocument;
}
}