Package open.dolphin.ejb

Source Code of open.dolphin.ejb.RemotePatientServiceImpl

package open.dolphin.ejb;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import open.dolphin.dto.PatientSearchSpec;
import open.dolphin.infomodel.DocumentModel;
import open.dolphin.infomodel.HealthInsuranceModel;
import open.dolphin.infomodel.KarteState;
import open.dolphin.infomodel.PatientModel;
import open.dolphin.infomodel.PatientVisitModel;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.jboss.ejb3.annotation.SecurityDomain;

@Stateless
@SecurityDomain("openDolphin")
@RolesAllowed("user")
@Remote({RemotePatientService.class})

public class RemotePatientServiceImpl extends DolphinService implements RemotePatientService {   
    private static final long serialVersionUID = -456476244129106722L;
    private Logger logger = Logger.getLogger("CONSOLE");
   
    @Resource
    private SessionContext ctx;
   
    @PersistenceContext
    private EntityManager em;
   
    /**
     * 患者オブジェクトを取得する。
     * @param spec PatientSearchSpec 検索仕様
     * @return 患者オブジェクトの Collection
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<PatientModel> getPatients(PatientSearchSpec spec) {
       
        String fid = getCallersFacilityId(ctx);
       
        // 戻り値
        List<PatientModel> ret = new ArrayList<PatientModel>();
        // 絞り込み id
        List<Long>ids = spec.getNarrowingList();

        switch (spec.getCode()) {
           
            case PatientSearchSpec.DATE_SEARCH:
                final String dateQuery = "from PatientVisitModel p where p.facilityId = :fid and p.pvtDate like :date";
                final String dateQueryNarrow = dateQuery + " and p.patient.id in (:ids)";
               
                List<PatientVisitModel> pvtList;
               
                if (ids.isEmpty()) {
                    pvtList = em.createQuery(dateQuery).setParameter("fid", fid).setParameter("date", spec.getDate()+ "%")
                            .getResultList();
                } else {
                    pvtList = em.createQuery(dateQueryNarrow).setParameter("fid", fid).setParameter("date", spec.getDate()+ "%")
                            .setParameter("ids", ids).getResultList();                   
                }
                for (PatientVisitModel pvt : pvtList) {
                    ret.add(pvt.getPatient());
                }
                break;
           
            case PatientSearchSpec.ID_SEARCH:
                final String idQuery = "from PatientModel p where p.facilityId = :fid and p.patientId like :pid";
                final String idQueryNarrow = idQuery + " and p.id in (:ids)";
               
                String pid = spec.getPatientId();
                if (!pid.endsWith("%")) pid +="%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(idQuery).setMaxResults(50).setParameter("fid", fid).setParameter("pid", pid)
                            .getResultList();
                } else {
                    ret = em.createQuery(idQueryNarrow).setMaxResults(50).setParameter("fid", fid).setParameter("pid", pid)
                            .setParameter("ids", ids).getResultList();                   
                }
                break;
               
            case PatientSearchSpec.NAME_SEARCH:
            case PatientSearchSpec.KANA_SEARCH:
            case PatientSearchSpec.ROMAN_SEARCH:
                final String nameQuery = "from PatientModel p where p.facilityId = :fid and "
                        + "(p.fullName like :name or p.kanaName like :name or p.romanName like :name)";
                final String nameQueryNarrow = nameQuery + " and p.id in (:ids)";
               
                String name = spec.getName();
                if (!name.endsWith("%")) name +="%";
               
                if (ids.isEmpty()) {
                    ret = em.createQuery(nameQuery).setParameter("fid", fid).setParameter("name", name)
                            .getResultList();
                } else {
                    ret = em.createQuery(nameQueryNarrow).setParameter("fid", fid).setParameter("name", name)
                            .setParameter("ids", ids).getResultList();                   
                }
                break;
               
            case PatientSearchSpec.TELEPHONE_SEARCH:
                final String telQuery = "from PatientModel p where p.facilityId = :fid and (p.telephone like :number or p.mobilePhone like :number)";
                final String telQueryNarrow = telQuery + " and p.id in (:ids)";
               
                String number = spec.getTelephone();
                if (!number.endsWith("%")) number += "%";
               
                if (ids.isEmpty()) {
                    ret = em.createQuery(telQuery).setParameter("fid", fid).setParameter("number", number)
                            .getResultList();
                } else {
                    ret = em.createQuery(telQueryNarrow).setParameter("fid", fid).setParameter("number", number)
                            .setParameter("ids", ids).getResultList();                   
                }
                break;
               
            case PatientSearchSpec.ZIPCODE_SEARCH:
                final String zipQuery = "from PatientModel p where p.facilityId = :fid and p.address.zipCode like :zipCode";
                final String zipQueryNarrow = zipQuery + " and p.id in (:ids)";
               
                String zipCode = spec.getZipCode();
                if (!zipCode.endsWith("%")) zipCode += "%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(zipQuery).setParameter("fid", fid).setParameter("zipCode", zipCode)
                            .getResultList();
                } else {
                    ret = em.createQuery(zipQueryNarrow).setParameter("fid", fid).setParameter("zipCode", zipCode)
                            .setParameter("ids", ids).getResultList();                   
                }
                break;

            case PatientSearchSpec.ADDRESS_SEARCH:
                final String addressQuery = "from PatientModel p where p.facilityId = :fid and p.address.address like :address";
                final String addressQueryNarrow = addressQuery + " and p.id in (:ids)";
               
                String address = spec.getAddress();
                if (!address.endsWith("%")) address += "%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(addressQuery).setParameter("fid", fid).setParameter("address", address)
                            .getResultList();
                } else {
                    ret = em.createQuery(addressQueryNarrow).setParameter("fid", fid).setParameter("address", address)
                            .setParameter("ids", ids).getResultList();                   
                }
                break;
               
            case PatientSearchSpec.EMAIL_SEARCH:
                final String emailQuery = "from PatientModel p where p.facilityId = :fid and p.email like :address";
                final String emailQueryNarrow = emailQuery + " and p.id in (:ids)";
               
                address = spec.getEmail();
                if (!address.endsWith("%")) address += "%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(emailQuery).setParameter("fid", fid).setParameter("email", address)
                            .getResultList();
                } else {
                    ret = em.createQuery(emailQueryNarrow).setParameter("fid", fid).setParameter("email", address)
                            .setParameter("ids", ids).getResultList();
                }
                break;
               
            case PatientSearchSpec.BIRTHDAY_SEARCH:
                final String birthdayQuery = "from PatientModel p where p.facilityId = :fid and p.birthday like :birthday";
                final String birthdayQueryNarrow = birthdayQuery + " and p.id in (:ids)";
               
                String birthday = spec.getBirthday();
                if (!birthday.endsWith("%")) birthday += "%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(birthdayQuery).setMaxResults(50).setParameter("fid", fid).setParameter("birthday", birthday)
                            .getResultList();
                } else {
                    ret = em.createQuery(birthdayQueryNarrow).setMaxResults(50).setParameter("fid", fid).setParameter("birthday", birthday)
                            .setParameter("ids", ids).getResultList();
                }
                break;
               
            case PatientSearchSpec.MEMO_SEARCH:
                final String memoQuery = "select p.karte.patient from PatientMemoModel p where p.karte.patient.facilityId = :fid and p.memo like :memo";
                final String memoQueryNarrow = memoQuery + " and p.karte.patient.id in (:ids)";
               
                String memo = spec.getSearchText();
                if (!memo.endsWith("%")) memo += "%";

                if (ids.isEmpty()) {
                    ret = em.createQuery(memoQuery).setParameter("fid", fid).setParameter("memo", memo)
                            .getResultList();
                } else {
                    ret = em.createQuery(memoQueryNarrow).setParameter("fid", fid).setParameter("memo", memo)
                            .setParameter("ids", ids).getResultList();                  
                }               
                break;
               
            case PatientSearchSpec.FULL_TEXT_SEARCH:
                final FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
                final Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer(DocumentModel.class);
                final org.apache.lucene.util.Version ver = org.apache.lucene.util.Version.LUCENE_35;
                final String pk = "karte.patient.id:";
               
                // preparing seach text with narrowing list
                String searchText = spec.getSearchText();

                if (! ids.isEmpty()) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(pk).append(String.valueOf(ids.get(0)));
                    for (int i=1; i<ids.size(); i++) {
                        sb.append(" OR ").append(pk).append(String.valueOf(ids.get(i)));
                    }               
                    searchText = String.format("(%s) AND (%s)", spec.getSearchText(), sb.toString());
                }
              
                try {
                    // create native Lucene query
                    org.apache.lucene.queryParser.QueryParser parser = new QueryParser(ver, "modules.beanBytes", analyzer);           
                    parser.setAutoGeneratePhraseQueries(true)// http://lucene.jugem.jp/?eid=403
                    org.apache.lucene.search.Query luceneQuery = parser.parse(searchText);
                    // wrap Lucene query in a javax.persistence.Query
                    javax.persistence.Query persistenceQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, DocumentModel.class);
           
                    // Too many results (>32768) cause
                    // java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: xxxxx
                    // 暫定的に 1000 にしておく
                    persistenceQuery.setMaxResults(1000);
                   
                    // execute search
                    List<DocumentModel> result = persistenceQuery.getResultList();

                    for (DocumentModel dm : result) {
                        PatientModel pm = dm.getKarte().getPatient();
                        if (!ret.contains(pm)) {
                            ret.add(pm);
                        }
                    }

                } catch (ParseException e) {
                    logger.info(e.getMessage(), e.getCause());
                }
                break;
        }
       
        if (! ret.isEmpty()) {
            // pvt をまとめて取得する(高速化のため)
            List<PatientVisitModel> pvts = em.createQuery("from PatientVisitModel p "
                            + "where p.facilityId = :fid and p.status != :status and (p.patient in (:pts)) order by p.pvtDate desc")
                    .setParameter("fid", fid)
                    .setParameter("pts", ret)
                    .setParameter("status", KarteState.CANCEL_PVT)
                    .getResultList();

            // まとめて取った pvt から最新の日付を PatientModel にセット
            for (PatientModel pm : ret) {
                for (PatientVisitModel pvt : pvts) {
                    // 最初にマッチした pvt が最新 (last visit)
                    if (pm.getId() == pvt.getPatient().getId()) {
                        pm.setLastVisit(pvt.getPvtDate());
                        break;
                    }
                }
            }
        }
       
        return ret;
    }
   
    /**
     * HealthInsurance を返す
     * @param patientPk
     * @return
     */
    @Override
    public List<HealthInsuranceModel> getHealthInsurance(long patientPk) {
        final String sql = "from HealthInsuranceModel h where h.patient.id = :pk";       
        List<HealthInsuranceModel> insurances = em.createQuery(sql).setParameter("pk", patientPk).getResultList();
       
        return insurances;
    }
   
    /**
     * 患者ID(BUSINESS KEY)を指定して患者オブジェクトを返す。
     *
     * @param patientId 施設内患者ID
     * @return 該当するPatientModel
     */
    @SuppressWarnings({"unchecked","unchecked"})
    @Override
    public PatientModel getPatient(String patientId) {
       
        String facilityId = getCallersFacilityId(ctx);
       
        // 患者レコードは FacilityId と patientId で複合キーになっている
        PatientModel bean
                = (PatientModel)em.createQuery("from PatientModel p where p.facilityId = :fid and p.patientId = :pid")
                .setParameter("fid", facilityId)
                .setParameter("pid", patientId)
                .getSingleResult();
       
        long pk = bean.getId();
       
        // Lazy Fetch の 基本属性を検索する
        // 患者の健康保険を取得する
        Collection insurances
                = em.createQuery("from HealthInsuranceModel h where h.patient.id = :pk")
                .setParameter("pk", pk).getResultList();
        bean.setHealthInsurances(insurances);
       
        return bean;
    }
   
    /**
     * 患者を登録する。
     * @param patient PatientModel
     * @return データベース Primary Key
     */
    @Override
    public long addPatient(PatientModel patient) {
        String facilityId = getCallersFacilityId(ctx);
        patient.setFacilityId(facilityId);
        em.persist(patient);
        long pk = patient.getId();
        return pk;
    }
   
    /**
     * 患者情報を更新する。
     * @param patient 更新する患者
     * @return 更新数
     */
    @Override
    public int update(PatientModel patient) {
        em.merge(patient);
        return 1;
    }
}
TOP

Related Classes of open.dolphin.ejb.RemotePatientServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.