Commit 962c8850 authored by Matthieu Bonnouvrier's avatar Matthieu Bonnouvrier
Browse files

Add first version of DAO and implementation

parent 90b6ed25
Pipeline #262258 failed with stages
in 4 minutes and 36 seconds
......@@ -21,9 +21,9 @@ public class PatientAliases {
/**
* Constructor for the class
*
* @param uuid the identifier of the patient aliases
* @param lastModifier the name of the last modifier
* @param lastModifierDateTime the date time of the last update
* @param uuid the identifier of the patient aliases
* @param lastModifier the name of the last modifier
* @param lastModifierDateTime the date time of the last update
*/
public PatientAliases(String uuid, String lastModifier, Date lastModifierDateTime) {
this.uuid = uuid;
......@@ -43,7 +43,7 @@ public class PatientAliases {
/**
* set patientAliases gazelle identifier
*
* @param uuid the value to set to the uuid property
* @param uuid the value to set to the uuid property
*/
public void setUuid(String uuid) {
this.uuid = uuid;
......@@ -61,7 +61,7 @@ public class PatientAliases {
/**
* set the last modifier of the PatientAliases
*
* @param lastModifier the name of the last modifier
* @param lastModifier the name of the last modifier
*/
public void setLastModifier(String lastModifier) {
this.lastModifier = lastModifier;
......@@ -78,7 +78,6 @@ public class PatientAliases {
/**
* set the Date Time of the last modifier
*
*/
public void setLastModifierDateTime() {
this.lastModifierDateTime = new Timestamp(new Date().getTime());
......@@ -95,23 +94,32 @@ public class PatientAliases {
/**
* Add a list of patient to the current list of patient if it is not already in the list
*
* @param patients
*/
public void addMembers(List<Patient> patients){
if(patients != null) {
public void addMembers(List<Patient> patients) {
if (patients != null) {
for (Patient patient : patients) {
setLastModifierDateTime();
if(!this.members.contains(patient)) {
if (!this.members.contains(patient)) {
this.members.add(patient);
}
}
}
}
public void setMembers(List<Patient> patients) {
if (patients != null) {
setLastModifierDateTime();
this.members = patients;
}
}
/**
* add a patient to a members
*
* @param member the patient to add
* @param member the patient to add
*/
public void addMember(Patient member) {
setLastModifierDateTime();
......@@ -121,8 +129,8 @@ public class PatientAliases {
/**
* add a patient to a members
*
* @param member the patient to add
* @param index the index to insert the patient
* @param member the patient to add
* @param index the index to insert the patient
*/
public void addMember(Patient member, int index) {
setLastModifierDateTime();
......@@ -132,7 +140,7 @@ public class PatientAliases {
/**
* remove a member to a list of members
*
* @param member the patient to remove
* @param member the patient to remove
*/
public void removeMember(Patient member) {
setLastModifierDateTime();
......
package net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.converter;
import net.ihe.gazelle.app.patientregistryapi.business.*;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.GenderCodeDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.PatientDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.references.CrossReferenceDB;
import java.util.ArrayList;
import java.util.List;
/**
* Converter for Names from business model to Database model and back.
*/
public class PatientAliasesConverter {
/**
* Private constructor to hide implicit one.
*/
private PatientAliasesConverter() {
}
/**
* @param patientaliases
* @return
*/
public static CrossReferenceDB toCrossReferenceDB(PatientAliases patientaliases) {
CrossReferenceDB crossReferenceDB = new CrossReferenceDB();
List<PatientDB> patientDB = new ArrayList<>();
for (Patient patient : patientaliases.getMembers()) {
patientDB.add(PatientConverter.toPatientDB(patient));
}
crossReferenceDB.setPatients(patientDB);
crossReferenceDB.setLastModifier(patientaliases.getLastModifier());
crossReferenceDB.setLastChanged(patientaliases.getLastModifierDateTime());
return crossReferenceDB;
}
/**
* @param crossReferenceDB
* @return
*/
public static PatientAliases toPatientAliases(CrossReferenceDB crossReferenceDB) {
PatientAliases patientaliases = new PatientAliases();
List<Patient> patients = new ArrayList<>();
for (PatientDB patientDB : crossReferenceDB.getPatients()) {
patients.add(PatientConverter.toPatient(patientDB));
}
patientaliases.setMembers(patients);
patientaliases.setLastModifier(crossReferenceDB.getLastModifier());
patientaliases.setLastModifierDateTime();
return patientaliases;
}
public static List<PatientAliases> toListOfPatientAliases(List<CrossReferenceDB> crossReferenceDBS){
List<PatientAliases> patientAliases = new ArrayList<>();
crossReferenceDBS.forEach(crossReference -> {
PatientAliases patientAlias = toPatientAliases(crossReference);
patientAliases.add(patientAlias);
});
return patientAliases;
}
}
......@@ -17,6 +17,7 @@ import java.util.List;
@NamedQuery(name = "PatientDB.findByUuid", query = "SELECT p FROM PatientDB p WHERE p.uuid = :uuid")
@NamedQuery(name = "PatientDB.findForSimulatedActor", query = "SELECT p FROM PatientDB p WHERE p.simulatedActor = :actorKeyword")
@NamedQuery(name = "PatientDB.findUUID", query = "SELECT p.uuid FROM PatientDB p WHERE p.uuid = :uuid")
@NamedQuery(name = "PatientDB.findByPatientIdentifier", query = "SELECT p.patientIdentifiers FROM PatientDB p WHERE p.patientIdentifiers = :patientIdentifier")
@Table(name = "pat_patient", schema = "public", uniqueConstraints = @UniqueConstraint(columnNames = "id"))
@SequenceGenerator(name = "pat_patient_sequence", sequenceName = "pat_patient_id_seq", allocationSize = 1)
public class PatientDB extends AbstractPatientDB {
......
......@@ -14,6 +14,7 @@ import java.util.List;
@Table(name = "pam_patient_identifier", schema = "public", uniqueConstraints = @UniqueConstraint(columnNames = {
"full_patient_id", "identifier_type_code" }))
@SequenceGenerator(name = "pam_patient_identifier_sequence", sequenceName = "pam_patient_identifier_id_seq", allocationSize = 1)
@NamedQuery(name = "PatientIdentifierDB.findByHierarchicDomain", query = "SELECT pi FROM PatientIdentifierDB pi WHERE pi.domain = :domain_id")
public class PatientIdentifierDB {
@Id
......
......@@ -8,8 +8,12 @@ import java.util.Date;
import java.util.List;
@Entity
//@NamedQuery(name = "CrossReferenceDB.findUUID", query = "SELECT c.patients FROM CrossReferenceDB c WHERE c.patients = :")
@Table(name = "pix_cross_reference", schema = "public")
@SequenceGenerator(name = "pix_cross_reference_sequence", sequenceName = "pix_cross_reference_id_seq", allocationSize = 1)
@NamedQuery(name = "CrossReferenceDB.findByPatient", query = "SELECT cr FROM CrossReferenceDB cr WHERE :patient in (cr.patients)")
@NamedQuery(name = "CrossReferenceDB.findById", query = "SELECT cr FROM CrossReferenceDB cr WHERE cr.id = :id")
@NamedQuery(name = "CrossReferenceDB.countPatient", query = "SELECT COUNT (cr) FROM CrossReferenceDB cr WHERE :patient in (cr.patients)")
public class CrossReferenceDB {
@Id
......
......@@ -62,6 +62,7 @@ public class DomainDAOImpl implements DomainDAO, DomainService {
* @param domainIdentifier identifier of the Domain to retrieve.
* @return retrieved Domain if exists, or null.
*/
//TODO refactor pour virer le null | a recopier dans PCRDAOImpl ?
public HierarchicDesignatorDB retrieve(String domainIdentifier) {
TypedQuery<HierarchicDesignatorDB> query = entityManager.createNamedQuery("HierarchicDesignatorDB.findByUniversalID",
HierarchicDesignatorDB.class);
......
......@@ -6,6 +6,7 @@ import net.ihe.gazelle.app.patientregistryapi.business.PatientAliases;
import java.util.List;
public interface PatientCrossReferenceDAO {
List<PatientAliases> searchForPatientAliasesInSourceIdentifier(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException;
}
package net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.service;
import net.ihe.gazelle.app.patientregistryapi.application.SearchCrossReferenceException;
import net.ihe.gazelle.app.patientregistryapi.business.EntityIdentifier;
import net.ihe.gazelle.app.patientregistryapi.business.Patient;
import net.ihe.gazelle.app.patientregistryapi.business.PatientAliases;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.EntityManagerProducer;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.converter.IdentifierConverter;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.converter.PatientAliasesConverter;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.DesignatorTypeDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.HierarchicDesignatorDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.PatientDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.PatientIdentifierDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.references.CrossReferenceDB;
import net.ihe.gazelle.app.patientregistryservice.application.PatientReadException;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.*;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;
@Named("PatientCrossReferenceDAO")
public class PatientCrossReferenceDAOImpl implements PatientCrossReferenceDAO {
private EntityManager entityManager;
private PatientCrossReferenceDAOImpl() {
}
/**
* Constructor for the class. Takes an EntityManager as argument. It will be used to perform actions on Database.
*
* @param entityManager {@link EntityManager} to perform actions on Database.
*/
@Inject
public PatientCrossReferenceDAOImpl(@EntityManagerProducer.InjectEntityManager EntityManager entityManager) {
if (entityManager == null) {
throw new IllegalArgumentException("EntityManager cannot be null");
}
this.entityManager = entityManager;
}
//TODO
/*
Ask for :
If the service receives a request with a valid sourceIdentifiter (patient found) but any Patient aliases does not exit
then the service shall return a new patient aliases with the associated patient.
*/
//Si on en trouve aucun, on le crée
/**
* Search for a list of patient alias by a source identifier
*
* @param sourceIdentifier
* @return
* @throws SearchCrossReferenceException
*/
@Override
public List<PatientAliases> searchForPatientAliasesInSourceIdentifier(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException {
String systemIndentifier = sourceIdentifier.getSystemIdentifier();
String value = sourceIdentifier.getValue();
HierarchicDesignatorDB hierarchicDesignatorDB = searchForHierarchicDesignator(systemIndentifier);
PatientIdentifierDB patientIdentifier = searchForPatientIdentifier(hierarchicDesignatorDB, value);
PatientDB patientDB = searchforPatient(patientIdentifier);
if (!isExistingPatientAliases(patientDB)) {
createPatientAliases(patientDB);
}
List<CrossReferenceDB> crossReferences = searchForPatientAliases(patientDB);
crossReferences = deleteKnownPatient(patientDB, crossReferences);
return PatientAliasesConverter.toListOfPatientAliases(crossReferences);
}
public HierarchicDesignatorDB searchForHierarchicDesignator(String systemIndentifier) {
TypedQuery<HierarchicDesignatorDB> queryForAPatient = entityManager.createNamedQuery("HierarchicDesignatorDB.findByUniversalID", HierarchicDesignatorDB.class);
queryForAPatient.setParameter("universalID", systemIndentifier);
return queryForAPatient.getSingleResult();
}
public PatientIdentifierDB searchForPatientIdentifier(HierarchicDesignatorDB hierarchicDesignatorDB, String uuid) {
TypedQuery<PatientIdentifierDB> queryForAPatient = entityManager.createNamedQuery("PatientIdentifierDB.findByHierarchicDomain", PatientIdentifierDB.class);
// A garder pour le moment queryForAPatient.setParameter("id", uuid);
queryForAPatient.setParameter("domain_id", hierarchicDesignatorDB);
return queryForAPatient.getSingleResult();
}
public PatientDB searchforPatient(PatientIdentifierDB patientIdentifier) {
TypedQuery<PatientDB> queryForAPatient = entityManager.createNamedQuery("PatientDB.findByPatientIdentifier", PatientDB.class);
queryForAPatient.setParameter("patientIdentifier", patientIdentifier);
return queryForAPatient.getSingleResult();
}
public boolean isExistingPatientAliases(PatientDB patient) {
TypedQuery<Long> queryForPatientAliases = entityManager.createNamedQuery("CrossReferenceDB.countPatient", Long.class);
queryForPatientAliases.setParameter("patient", patient);
Long count = queryForPatientAliases.getSingleResult();
return count > 0;
}
public List<CrossReferenceDB> searchForPatientAliases(PatientDB patient) {
TypedQuery<CrossReferenceDB> queryForPatientAliases = entityManager.createNamedQuery("CrossReferenceDB.findByPatient", CrossReferenceDB.class);
queryForPatientAliases.setParameter("patient", patient);
return queryForPatientAliases.getResultList();
}
public List<CrossReferenceDB> deleteKnownPatient(PatientDB patientDB, List<CrossReferenceDB> crossReferences) {
List<CrossReferenceDB> crossReferencesCopy = new ArrayList<>(crossReferences);
for (CrossReferenceDB crossReference : crossReferencesCopy) {
if (crossReference.getPatients().size() > 1) {
crossReference.getPatients().remove(patientDB);
}
}
return crossReferencesCopy;
}
public void createPatientAliases(PatientDB patientDB) {
CrossReferenceDB crossReference = new CrossReferenceDB(patientDB.getFirstName());
List<PatientDB> patients = new ArrayList<>();
patients.add(patientDB);
crossReference.setPatients(patients);
entityManager.persist(crossReference);
entityManager.flush();
}
// @Override
// public void createDomain(String domainIdentifier, String domainName) {
// HierarchicDesignatorDB domain = new HierarchicDesignatorDB(domainName, domainIdentifier, "ISO", null);
// domain.setUsage(DesignatorTypeDB.PATIENT_ID);
// entityManager.persist(domain);
// entityManager.flush();
// }
// CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(PatientAliases.class);
// From from = criteriaQuery.from(PatientAliases.class);
//
//
// Path<String> uuidFromPatientAliases = from.get("uuid");
//
// List<Predicate> predicates = new ArrayList<>();
// predicates.add(criteriaBuilder.equal(uuidFromPatientAliases, sourceIdentifier));
//
// Predicate finalPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
//
// TypedQuery<PatientAliases> query = entityManager.createQuery(criteriaQuery.select(from).where(finalPredicate).distinct(true));
// try {
// return query.getResultList();
// } catch (NoResultException e) {
// throw new SearchCrossReferenceException("The source identifier is unknown");
// }
}
......@@ -7,7 +7,6 @@ import net.ihe.gazelle.app.patientregistryapi.business.EntityIdentifier;
import net.ihe.gazelle.app.patientregistryapi.business.Patient;
import net.ihe.gazelle.app.patientregistryapi.business.PatientAliases;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.service.PatientCrossReferenceDAO;
import net.ihe.gazelle.lib.searchmodelapi.business.exception.SearchException;
import javax.inject.Inject;
import javax.inject.Named;
......@@ -17,67 +16,97 @@ import java.util.List;
public class PatientCrossReferenceSearchImpl implements PatientCrossReferenceSearch {
private DomainService domainDao;
private PatientCrossReferenceDAO patientCrossReferenceDAO;
private DomainService domainDao;
private PatientCrossReferenceDAO patientCrossReferenceDAO;
@Inject
public PatientCrossReferenceSearchImpl(@Named("domainDAOService") DomainService domainDao,
@Named("tobedefined") PatientCrossReferenceDAO patientCrossReferenceDAO) {
this.domainDao = domainDao;
this.patientCrossReferenceDAO = patientCrossReferenceDAO;
// TODO define a name for patientCrossReferenceDAO
}
@Inject
public PatientCrossReferenceSearchImpl(@Named("domainDAOService") DomainService domainDao,
@Named("PatientCrossReferenceDAO") PatientCrossReferenceDAO patientCrossReferenceDAO) {
this.domainDao = domainDao;
this.patientCrossReferenceDAO = patientCrossReferenceDAO;
}
@Override
public PatientAliases search(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException {
checkSourceIdentifier(sourceIdentifier);
/**
* Search for a patient alias by a source identifier
* <p>
* Verify that the source identifier is valid
* Call the DAO to get a list of patient alias
* Merge those patient aliases into one
*
* @param sourceIdentifier the search key
* @return
* @throws SearchCrossReferenceException
*/
@Override
public PatientAliases search(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException {
List<PatientAliases> patientAliases = patientCrossReferenceDAO
.searchForPatientAliasesInSourceIdentifier(sourceIdentifier);
PatientAliases patientAlias = mergePatientAliases(patientAliases);
checkSourceIdentifier(sourceIdentifier);
List<PatientAliases> patientAliases = patientCrossReferenceDAO
.searchForPatientAliasesInSourceIdentifier(sourceIdentifier);
PatientAliases patientAlias = mergePatientAliases(patientAliases);
return patientAlias;
}
return patientAlias;
}
private void checkSourceIdentifier(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException {
if (sourceIdentifier == null) {
throw new SearchCrossReferenceException("The source identifier cannot be null");
}
String systemIdentifier = sourceIdentifier.getSystemIdentifier();
String value = sourceIdentifier.getValue();
if (systemIdentifier == null || systemIdentifier.isBlank()) {
throw new SearchCrossReferenceException("The system identifier from sourceIdentifier cannot be null or empty");
}
/**
* Check if the source identifier is valid
* <p>
* Throw an exception if the source identifier :
* - is null
* - has mandatory variables missing
* - is unknown
*
* @param sourceIdentifier
* @throws SearchCrossReferenceException
*/
private void checkSourceIdentifier(EntityIdentifier sourceIdentifier) throws SearchCrossReferenceException {
if (sourceIdentifier == null) {
throw new SearchCrossReferenceException("The source identifier cannot be null");
}
String systemIdentifier = sourceIdentifier.getSystemIdentifier();
String value = sourceIdentifier.getValue();
if (systemIdentifier == null || systemIdentifier.isBlank()) {
throw new SearchCrossReferenceException("The system identifier from sourceIdentifier cannot be null or empty");
}
if (value == null || value.isBlank()) {
throw new SearchCrossReferenceException("The value from sourceIdentifier cannot be null or empty");
}
if (domainDao == null || !domainDao.exist(sourceIdentifier.getSystemIdentifier())) {
if (domainDao == null || !domainDao.exist(systemIdentifier)) {
throw new SearchCrossReferenceException("This source identifier does not exist");
}
}
}
public List<Patient> getUniqueMemberFromPatientAliases(List<PatientAliases> patientAliases) {
List<Patient> members = new ArrayList<>();
for (PatientAliases pa : patientAliases) {
members.addAll(pa.getMembers());
}
List<Patient> uniquePatients = new ArrayList<>(new HashSet<>(members));
/**
* Merge the list of patient for each patient alias into one
*
* @param patientAliases
* @return
*/
private List<Patient> getUniqueMemberFromPatientAliases(List<PatientAliases> patientAliases) {
List<Patient> members = new ArrayList<>();
for (PatientAliases pa : patientAliases) {
members.addAll(pa.getMembers());
}
List<Patient> uniquePatients = new ArrayList<>(new HashSet<>(members));
return uniquePatients;
}
return uniquePatients;
}
public PatientAliases mergePatientAliases(List<PatientAliases> patientAliases) {
/**
* Merge a list of patient alias into one
*
* @param patientAliases
* @return
*/
private PatientAliases mergePatientAliases(List<PatientAliases> patientAliases) {
PatientAliases patientAlias = new PatientAliases();
if (patientAliases.size() >= 1) {
System.out.println("patientAliases.size() >= 1");
patientAlias = patientAliases.get(0);
}
if (patientAliases.size() > 1) {
System.out.println("patientAliases.size() > 1");
patientAlias.addMembers(getUniqueMemberFromPatientAliases(patientAliases));
}
PatientAliases patientAlias = new PatientAliases();
if (patientAliases.size() >= 1) {
patientAlias = patientAliases.get(0);
}
if (patientAliases.size() > 1) {
patientAlias.addMembers(getUniqueMemberFromPatientAliases(patientAliases));
}
return patientAlias;
}
return patientAlias;
}
}
package net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.service.patient;
import net.ihe.gazelle.app.patientregistryapi.business.*;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.converter.PatientConverter;