package open.dolphin.adm10.rest;
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.StreamingOutput;
import open.dolphin.adm10.converter.IBundleModule;
import open.dolphin.adm10.converter.IOSHelper;
import open.dolphin.converter.UserModelConverter;
import open.dolphin.infomodel.ChartEventModel;
import open.dolphin.infomodel.DiagnosisSendWrapper;
import open.dolphin.infomodel.DocInfoModel;
import open.dolphin.infomodel.DocumentModel;
import open.dolphin.infomodel.PVTHealthInsuranceModel;
import open.dolphin.infomodel.PVTPublicInsuranceItemModel;
import open.dolphin.infomodel.PatientList;
import open.dolphin.infomodel.PatientModel;
import open.dolphin.infomodel.UserModel;
import open.dolphin.infomodel.VisitPackage;
import open.dolphin.adm10.converter.IPatientList;
import open.dolphin.adm10.converter.ISendPackage;
import open.dolphin.adm10.converter.IVisitPackage;
import open.dolphin.adm10.session.ADM10_EHTServiceBean;
import open.dolphin.adm10.session.ADM10_IPhoneServiceBean;
import open.dolphin.infomodel.BundleDolphin;
import open.dolphin.infomodel.DrugInteractionModel;
import open.dolphin.infomodel.IInfoModel;
import open.dolphin.infomodel.IStampTreeModel;
import open.dolphin.infomodel.InfoModel;
import open.dolphin.infomodel.InteractionCodeList;
import open.dolphin.infomodel.ModuleModel;
import open.dolphin.infomodel.StampModel;
import open.dolphin.session.ChartEventServiceBean;
import open.dolphin.session.KarteServiceBean;
import open.orca.rest.ORCAConnection;
import org.codehaus.jackson.map.ObjectMapper;
/**
*
* @author Kazushi Minagawa.
*/
@Path("/10/adm/jtouch")
public class JsonTouchResource extends open.dolphin.rest.AbstractResource {
private static final String QUERY_FACILITYID_BY_1001
="select kanritbl from tbl_syskanri where kanricd='1001'";
@Inject
private ADM10_IPhoneServiceBean iPhoneService;
@Inject
private ADM10_EHTServiceBean ehtService;
@Inject
private KarteServiceBean karteService;
@Inject
private ChartEventServiceBean chartService;
//minagawa^ 2013/08/29
//@Resource(mappedName="java:jboss/datasources/OrcaDS")
//private DataSource ds;
//minagawa$
@GET
@Path("/user/{uid}")
@Produces(MediaType.APPLICATION_JSON)
public UserModelConverter getUserById(@PathParam("uid") String uid) {
// 検索
UserModel user = iPhoneService.getUserById(uid);
// Converter
UserModelConverter conv = new UserModelConverter();
conv.setModel(user);
return conv;
}
@GET
@Path("/patients/name/{param}")
@Produces(MediaType.APPLICATION_JSON)
public IPatientList getPatientsByNameOrId(@Context HttpServletRequest servletReq, @PathParam("param") String param) {
//System.err.println("getPatientsByNameOrId");
String [] params = param.split(",");
String fid = getRemoteFacility(servletReq.getRemoteUser());
String name = params[0];
//System.err.println(name);
int firstResult = params.length==3 ? Integer.parseInt(params[1]) : 0;
int maxResult = params.length==3 ? Integer.parseInt(params[2]) :100;
List<PatientModel> list;
// ひらがなで始まっている場合はカナに変換する
if (KanjiHelper.isHiragana(name.charAt(0))) {
name = KanjiHelper.hiraganaToKatakana(name);
}
if (KanjiHelper.isKatakana(name.charAt(0))) {
list = iPhoneService.getPatientsByKana(fid, name, firstResult, maxResult);
} else {
// 漢字で検索
list = iPhoneService.getPatientsByName(fid, name, firstResult, maxResult);
}
//System.err.println(list.size());
PatientList patients = new PatientList();
patients.setList(list);
IPatientList ipatients = new IPatientList();
ipatients.setModel(patients);
return ipatients;
}
@GET
@Path("/visitpackage/{param}")
@Produces(MediaType.APPLICATION_JSON)
public IVisitPackage getVisitPackage(@PathParam("param") String param) {
String[] params = param.split(",");
long pvtPK = Long.parseLong(params[0]);
long patientPK = Long.parseLong(params[1]);
long docPK = Long.parseLong(params[2]);
int mode = Integer.parseInt(params[3]);
// VisitTouchでカルテ作成に必要なwrapperオブジェクト
VisitPackage visit = iPhoneService.getVisitPackage(pvtPK, patientPK, docPK, mode);
if (visit.getDocumenModel()!=null) {
visit.getDocumenModel().toDetuch();
}
// 保健医療機関コードとJMARI番号
String number = getFacilityCodeBy1001();
visit.setNumber(number);
// Converter
IVisitPackage conv = new IVisitPackage();
conv.setModel(visit);
return conv;
}
@POST
@Path("/sendPackage")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String postSendPackage(String json) throws IOException {
//System.err.println(json);
ObjectMapper mapper = new ObjectMapper();
ISendPackage pkg = mapper.readValue(json, ISendPackage.class);
long retPk = 0L;
// カルテ文書
DocumentModel model = pkg.documentModel();
if (model!=null) {
//minagawa^ VisitTouch 公費保険不具合
DocInfoModel docInfo = model.getDocInfoModel();
PVTHealthInsuranceModel pvtIns = docInfo.getPVTHealthInsuranceModel();
if (pvtIns!=null) {
PVTPublicInsuranceItemModel[] arr;
arr = pvtIns.getPVTPublicInsuranceItem();
if (arr!=null && arr.length>0) {
List<PVTPublicInsuranceItemModel> list = new ArrayList(arr.length);
list.addAll(Arrays.asList(arr));
pvtIns.setPublicItems(list);
}
}
//minagawa$
retPk = karteService.addDocument(model);
}
// 病名Wrapper
DiagnosisSendWrapper wrapper = pkg.diagnosisSendWrapperModel();
if (wrapper!=null) {
karteService.postPutSendDiagnosis(wrapper);
}
// 削除病名
List<String> deleted = pkg.deletedDiagnsis();
if (deleted!=null) {
List<Long> list = new ArrayList(deleted.size());
for (String str : deleted) {
list.add(Long.parseLong(str));
}
karteService.removeDiagnosis(list);
}
// Status更新
ChartEventModel cvt = pkg.chartEventModel();
if (cvt!=null) {
chartService.processChartEvent(cvt);
}
return String.valueOf(retPk);
}
/**
* 保健医療機関コードとJMARIコードを取得する。
* @return
*/
private String getFacilityCodeBy1001() {
//s.oh^ 2013/10/17 ローカルORCA対応
try {
// custom.properties から 保健医療機関コードとJMARIコードを読む
Properties config = new Properties();
// コンフィグファイルを読み込む
StringBuilder sb = new StringBuilder();
sb.append(System.getProperty("jboss.home.dir"));
sb.append(File.separator);
sb.append("custom.properties");
File f = new File(sb.toString());
FileInputStream fin = new FileInputStream(f);
try (InputStreamReader r = new InputStreamReader(fin, "JISAutoDetect")) {
config.load(r);
}
// JMARI code
String jmari = config.getProperty("jamri.code");
String hcfacility = config.getProperty("healthcarefacility.code");
if(jmari != null && jmari.length() == 12 && hcfacility != null && hcfacility.length() == 10) {
StringBuilder ret = new StringBuilder();
ret.append(hcfacility);
ret.append("JPN");
ret.append(jmari);
return ret.toString();
}
} catch (FileNotFoundException ex) {
Logger.getLogger(JsonTouchResource.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(JsonTouchResource.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(JsonTouchResource.class.getName()).log(Level.SEVERE, null, ex);
}
//s.oh$
// SQL 文
StringBuilder buf = new StringBuilder();
buf.append(QUERY_FACILITYID_BY_1001);
String sql = buf.toString();
Connection con = null;
PreparedStatement ps;
StringBuilder ret = new StringBuilder();
try {
//minagawa^ 2013/08/29
//con = ds.getConnection();
con = ORCAConnection.getInstance().getConnection();
//minagawa$
ps = con.prepareStatement(sql);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
String line = rs.getString(1);
// 保険医療機関コード 10桁
ret.append(line.substring(0, 10));
// JMARIコード JPN+12桁 (total 15)
int index = line.indexOf("JPN");
if (index>0) {
ret.append(line.substring(index, index+15));
}
}
}
ps.close();
con.close();
con = null;
} catch (Exception e) {
e.printStackTrace(System.err);
} finally {
if (con != null) {
try {
con.close();
} catch (Exception e) {
}
}
}
return ret.toString();
}
////minagawa^
// private void log(String msg) {
// Logger.getLogger("open.dolphin").info(msg);
// }
//
// private void warn(String msg) {
// Logger.getLogger("open.dolphin").info(msg);
// }
////minagawa$
//---------------------------------------------------------------------------
// EHT から引っ越し
//---------------------------------------------------------------------------
@GET
@Path("/order/{param}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public StreamingOutput collectModules(final @PathParam("param") String param) {
return new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException, WebApplicationException {
String [] params = param.split(",");
long pk = Long.parseLong(params[0]); // patientPK
Date fromDate = IOSHelper.toDate(params[1]); // fromDate
Date toDate = IOSHelper.toDate(params[2]); // tOdate
List<String> entities;
if (params.length>3)
{
entities = new ArrayList(2);
for (int i=3; i <params.length; i++) {
entities.add(params[i]); // entity
}
}else{
entities = new ArrayList(2);
entities.add(IInfoModel.ENTITY_MED_ORDER);
}
List<ModuleModel> list = ehtService.collectModules(pk, fromDate, toDate, entities);
List<IBundleModule> result = new ArrayList(list.size());
for (ModuleModel module : list) {
if (module.getModel() instanceof BundleDolphin) {
IBundleModule ib = new IBundleModule();
ib.fromModel(module);
BundleDolphin bd = (BundleDolphin)module.getModel();
ib.getModel().setOrderName(bd.getOrderName());
result.add(ib);
}else{
IBundleModule ib = new IBundleModule();
ib.fromModel(module);
result.add(ib);
}
}
ObjectMapper mapper = getSerializeMapper();
mapper.writeValue(output, result);
}
};
}
@PUT
@Path("/interaction")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public StreamingOutput checkInteraction(final String json) {
return new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException, WebApplicationException {
ObjectMapper mapper = new ObjectMapper();
InteractionCodeList input = mapper.readValue(json, InteractionCodeList.class);
// 相互作用モデルのリスト
List<DrugInteractionModel> ret = new ArrayList<DrugInteractionModel>();
if (input.getCodes1() == null ||
input.getCodes1().isEmpty() ||
input.getCodes2() == null ||
input.getCodes2().isEmpty()) {
mapper = getSerializeMapper();
mapper.writeValue(os, ret);
}
// SQL文を作成
StringBuilder sb = new StringBuilder();
sb.append("select drugcd, drugcd2, TI.syojyoucd, syojyou ");
sb.append("from tbl_interact TI inner join tbl_sskijyo TS on TI.syojyoucd = TS.syojyoucd ");
sb.append("where (drugcd in (");
sb.append(getCodes(input.getCodes1()));
sb.append(") and drugcd2 in (");
sb.append(getCodes(input.getCodes2()));
sb.append("))");
String sql = sb.toString();
Connection con = null;
Statement st = null;
try {
con = getConnection();
st = con.createStatement();
try (ResultSet rs = st.executeQuery(sql)) {
while (rs.next()) {
ret.add(new DrugInteractionModel(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)));
}
}
closeStatement(st);
closeConnection(con);
mapper = getSerializeMapper();
mapper.writeValue(os, ret);
} catch (SQLException | IOException e) {
processError(e);
closeStatement(st);
closeConnection(con);
throw new WebApplicationException(e);
}
}
};
}
//--------------------------------------------------------------------
@GET
@Path("/stampTree/{param}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public StreamingOutput getStampTree(final @PathParam("param") String param) {
return new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException, WebApplicationException {
long pk = Long.parseLong(param);
String json = getTreeJson(pk);
os.write(json.getBytes());
}
};
}
private String getTreeJson(long userPK) {
IStampTreeModel treeModel = ehtService.getTrees(userPK);
try {
String treeXml = new String(treeModel.getTreeBytes(), "UTF-8");
String json;
try (BufferedReader reader = new BufferedReader(new StringReader(treeXml))) {
JSONStampTreeBuilder builder = new JSONStampTreeBuilder();
StampTreeDirector director = new StampTreeDirector(builder);
json = director.build(reader);
}
return json;
} catch (UnsupportedEncodingException ex) {
//System.err.println("getTreeJson:" + ex.getMessage());
} catch (IOException ex) {
//System.err.println("getTreeJson:" + ex.getMessage());
}
return null;
}
@GET
@Path("/stamp/{param}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public StreamingOutput getStamp(final @PathParam("param") String param) {
return new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException, WebApplicationException {
StampModel stampModel = ehtService.getStamp(param);
if (stampModel!=null) {
XMLDecoder d = new XMLDecoder(
new BufferedInputStream(
new ByteArrayInputStream(stampModel.getStampBytes())));
InfoModel model = (InfoModel)d.readObject();
JSONStampBuilder builder = new JSONStampBuilder();
String json = builder.build(model);
os.write(json.getBytes());
} else {
os.write(null);
}
}
};
}
// srycdのListからカンマ区切りの文字列を作る
private String getCodes(Collection<String> srycdList){
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String srycd : srycdList){
if (!first){
sb.append(",");
} else {
first = false;
}
sb.append(addSingleQuote(srycd));
}
return sb.toString();
}
private String addSingleQuote(String str) {
StringBuilder sb = new StringBuilder();
sb.append("'").append(str).append("'");
return sb.toString();
}
private Connection getConnection() {
return ORCAConnection.getInstance().getConnection();
}
private void closeStatement(java.sql.Statement st) {
if (st != null) {
try {
st.close();
}
catch (SQLException e) {
e.printStackTrace(System.err);
}
}
}
private void closeConnection(Connection c) {
try {
c.close();
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private void processError(Throwable e) {
e.printStackTrace(System.err);
}
}