package info.ozkan.vipera.dao.patient; import info.ozkan.vipera.business.patient.PatientManagerResult; import info.ozkan.vipera.business.patient.PatientManagerStatus; import info.ozkan.vipera.business.patient.PatientSearchFilter; import info.ozkan.vipera.entities.Doctor; import info.ozkan.vipera.entities.Patient; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.inject.Named; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; /** * Hastalar üzerinde CRUD işlemi yapan Dao sınıfı * * @author Ömer Özkan * */ @Named("patientDao") public class PatientDaoImpl implements PatientDao { /** * ID ve hekime göre hasta sorgulayan JQL sorgusu */ private static final String JQL_GET_PATIENT_BY_ID_AND_DOCTOR = "from Patient p join fetch p.doctors d WHERE p.id = :id AND d = :doctor"; /** * ID ye göre hasta sorgulayan JQL sorgusu */ private static final String JQL_GET_BY_ID = "from Patient p WHERE p.id = :id"; /** * Persistence context */ private EntityManager em; public PatientManagerResult add(final Patient patient) { em.persist(patient); return createSuccesResult(patient); } /** * Filtreleri CriteriaQuery'ye çevirir * * @param filters * @return */ private CriteriaQuery<Patient> createCriteriaFromFilter( final PatientSearchFilter filter) { final Map<String, Object> filters = filter.getFilters(); final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery<Patient> cq = cb.createQuery(Patient.class); final Root<Patient> root = cq.from(Patient.class); final List<Predicate> predicates = createPredicationsFromFilter(filters, cb, root); cq.select(root).where(predicates.toArray(new Predicate[0])); return cq; } /** * Filtreleri CriteriaQuery nesnesine dönüştürür * * @param filter * @param doctor * @return */ private CriteriaQuery<Patient> createCriteriaFromFilter( final PatientSearchFilter filter, final Doctor doctor) { final Map<String, Object> filters = filter.getFilters(); final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery<Patient> cq = cb.createQuery(Patient.class); final Root<Patient> root = cq.from(Patient.class); final Path<Doctor> path = root.join("doctors"); final List<Predicate> predicates = createPredicationsFromFilter(filters, cb, root); predicates.add(cb.equal(path, doctor)); cq.select(root).where(predicates.toArray(new Predicate[0])); return cq; } /** * arama filtresinden predicate listesi dönderir * * @param filters * @param cb * @param root * @return */ private List<Predicate> createPredicationsFromFilter( final Map<String, Object> filters, final CriteriaBuilder cb, final Root<Patient> root) { final List<Predicate> predicates = new ArrayList<Predicate>(); for (final String attr : filters.keySet()) { final Object obj = filters.get(attr); final String pattern = '%' + obj.toString() + '%'; predicates.add(cb.like(root.<String> get(attr).as(String.class), pattern)); } return predicates; } /** * CriteriaQuery ile veritabanından arama işlemi yaparak alınan sonucu sonuç * nesnesine çevirir * * @param cq * @return */ private PatientManagerResult createManagerResultFromCriteria( final CriteriaQuery<Patient> cq) { final PatientManagerResult result = new PatientManagerResult(); result.setStatus(PatientManagerStatus.SUCCESS); final Query query = em.createQuery(cq); result.setPatientList(query.getResultList()); return result; } /** * Veritabanından dönen listeye göre bir {@link PatientManagerResult} * nesnesi üretir * * @param resultList * @return */ private PatientManagerResult createResult(final List<Patient> resultList) { final PatientManagerResult result = new PatientManagerResult(); if (patientExist(resultList)) { result.setStatus(PatientManagerStatus.NOT_FOUND); } else { final Patient patient = resultList.get(0); result.setPatient(patient); result.setStatus(PatientManagerStatus.SUCCESS); } return result; } /** * Başarılı bir sonuç içeren {@link PatientManagerResult} nesnesi üretir * * @param patient * Hasta * @return */ private PatientManagerResult createSuccesResult(final Patient patient) { final PatientManagerResult result = new PatientManagerResult(); result.setStatus(PatientManagerStatus.SUCCESS); result.setPatient(patient); return result; } public PatientManagerResult delete(final Patient patient) { final PatientManagerResult getResult = getById(patient.getId()); if (userNotFound(getResult)) { return getResult; } final Patient tempPatient = getResult.getPatient(); em.remove(tempPatient); final PatientManagerResult result = new PatientManagerResult(); result.setStatus(PatientManagerStatus.SUCCESS); return result; } /** * Kullanıcı veritabanında kayıtlı değilse true dönderir * * @param getResult * @return */ private boolean userNotFound(final PatientManagerResult getResult) { final PatientManagerStatus status = getResult.getStatus(); return status.equals(PatientManagerStatus.NOT_FOUND); } public PatientManagerResult find(final PatientSearchFilter filter) { final CriteriaQuery<Patient> cq = createCriteriaFromFilter(filter); return createManagerResultFromCriteria(cq); } public PatientManagerResult find(final PatientSearchFilter filter, final Doctor doctor) { final CriteriaQuery<Patient> cq = createCriteriaFromFilter(filter, doctor); return createManagerResultFromCriteria(cq); } public PatientManagerResult getById(final Long id) { final Query query = em.createQuery(JQL_GET_BY_ID); query.setParameter("id", id); final List<Patient> resultList = query.getResultList(); return createResult(resultList); } /** * Kayıtlı herhani bir hasta var olup olmadığını kontrol eder * * @param resultList * @return */ private boolean patientExist(final List<Patient> resultList) { return resultList.size() == 0; } /** * @param entityManager * the entityManager to set */ @PersistenceContext public void setEntityManager(final EntityManager entityManager) { em = entityManager; } public PatientManagerResult update(final Patient patient) { em.merge(patient); return createSuccesResult(patient); } public PatientManagerResult getById(final Long id, final Doctor doctor) { final PatientManagerResult result; final Query query = em.createQuery(JQL_GET_PATIENT_BY_ID_AND_DOCTOR); query.setParameter("id", id); query.setParameter("doctor", doctor); final List<Patient> list = query.getResultList(); if (list.size() != 0) { final Patient patient = list.get(0); result = createSuccesResult(patient); } else { result = new PatientManagerResult(); result.setStatus(PatientManagerStatus.NOT_FOUND); } return result; } }