Package open.dolphin.impl.claim

Source Code of open.dolphin.impl.claim.SendClaimImpl$Consumer

package open.dolphin.impl.claim;

import java.io.*;
import java.net.Socket;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.JOptionPane;
import open.dolphin.client.ClaimMessageEvent;
import open.dolphin.client.ClaimMessageListener;
import open.dolphin.client.ClientContext;
import open.dolphin.client.MainWindow;
import open.dolphin.project.Project;
import org.apache.log4j.Logger;


/**
* SendClaimPlugin
*
* @author  Kazushi Minagawa, Digital Globe, Inc.
*/
public class SendClaimImpl implements ClaimMessageListener {
   
    // Socket constants
    private final int EOT                     = 0x04;
    private final int ACK                     = 0x06;
    private final int NAK                     = 0x15;
    private final int DEFAULT_TRY_COUNT       = 3;    // Socket 接続を試みる回数
    private final long DEFAULT_SLEEP_TIME     = 20*1000L;   // Socket 接続が得られなかった場合に次のトライまで待つ時間 msec
    private final int MAX_QUEU_SIZE     = 10;
   
    // Alert constants
    private final int TT_QUEUE_SIZE         = 0;
    private final int TT_NAK_SIGNAL         = 1;
    private final int TT_SENDING_TROUBLE    = 2;
    private final int TT_CONNECTION_REJECT  = 3;
   
    // Strings
    private final String proceedString      = "継続";
    private final String dumpString         = "ログへ記録";
   
    // Properties
    private LinkedBlockingQueue queue;
    private String host;
    private int port;
    private String enc;
    private int tryCount   = DEFAULT_TRY_COUNT;
    private long sleepTime   = DEFAULT_SLEEP_TIME;
    private int alertQueueSize   = MAX_QUEU_SIZE;
   
    private Logger logger;
    private ExecutorService sendService;
   
    private MainWindow context;
    private String name;
   
    /**
     * Creates new ClaimQue
     */
    public SendClaimImpl() {
    }
   
    @Override
    public String getName() {
        return name;
    }
   
    @Override
    public void setName(String name) {
        this.name = name;
    }
   
    @Override
    public MainWindow getContext() {
        return context;
    }
   
    @Override
    public void setContext(MainWindow context) {
        this.context = context;
    }
   
    private void setup() {
        logger = ClientContext.getPart11Logger();
        setHost(Project.getClaimAddress());
        setPort(Project.getClaimPort());
        setEncoding(Project.getClaimEncoding());
       
        if (queue == null) {
            queue = new LinkedBlockingQueue();
        }
    }
   
    /**
     * プログラムを開始する。
     */
    @Override
    public void start() {
       
        setup();
       
        OrcaSocket orcaSocket = new OrcaSocket(getHost(), getPort(), sleepTime, tryCount);
        sendService = Executors.newSingleThreadExecutor();
        sendService.execute(new Consumer(orcaSocket));
        logger.info("SendClaim started with host=" + getHost() + " port=" + getPort());
    }
   
    /**
     * プログラムを終了する。
     */
    @Override
    public void stop() {
       
        try {
            if (sendService != null) {
                sendService.shutdownNow();
            }
           
            logDump();
           
            logger.info("SendClaim stopped");
           
        } catch (Exception e) {
            e.printStackTrace();
            logger.warn("Exception while stopping the SendClaim");
            logger.warn(e.getMessage());
        }
    }
   
    @Override
    public String getHost() {
        return host;
    }
   
    @Override
    public void setHost(String host) {
        this.host = host;
    }
   
    @Override
    public int getPort() {
        return port;
    }
   
    @Override
    public void setPort(int port) {
        this.port = port;
    }
   
    @Override
    public String getEncoding() {
        return enc;
    }
   
    @Override
    public void setEncoding(String enc) {
        this.enc = enc;
    }
   
    public int getTryCount() {
        return tryCount;
    }
   
    public void setTryCount(int val) {
        tryCount = val;
    }
   
    public int getAlertQueueSize() {
        return alertQueueSize;
    }
   
    public void getAlertQueueSize(int val) {
        alertQueueSize = val;
    }
   
    /**
     * カルテで CLAIM データが生成されるとこの通知を受ける。
     */
    @Override
    public void claimMessageEvent(ClaimMessageEvent e) {
        queue.offer(e);    
    }
   
    /**
     * Queue から取り出す。
     */
    public Object getCLAIM() throws InterruptedException {
        return queue.take();
    }
   
    public int getQueueSize() {
        return queue.size();
    }
   
    /**
     * Queue内の CLAIM message をログへ出力する。
     */
    public void logDump() {
       
        Iterator iter = queue.iterator();
       
        while (iter.hasNext()) {
            ClaimMessageEvent evt = (ClaimMessageEvent) iter.next();
            logger.warn(evt.getClaimInsutance());
        }
       
        queue.clear();
    }
   
    private int alertDialog(int code) {
       
        int option = -1;
        String title = "OpenDolphin: CLAIM 送信";
        StringBuffer buf;
       
        switch(code) {
           
            case TT_QUEUE_SIZE:
                buf = new StringBuffer();
                buf.append("未送信のCLAIM(レセプト)データが");
                buf.append(getQueueSize());
                buf.append(" 個あります。CLAIM サーバとの接続を確認してください。\n");
                buf.append("1. このまま処理を継続することもできます。\n");
                buf.append("2. 未送信データをログに記録することができます。\n");
                buf.append("   この場合、データは送信されず、診療報酬は手入力となります。");
               
                option = JOptionPane.showOptionDialog(
                        null,
                        buf.toString(),
                        title,
                        JOptionPane.DEFAULT_OPTION,
                        JOptionPane.WARNING_MESSAGE,null,
                        new String[]{proceedString, dumpString},proceedString);
                break;
               
            case TT_NAK_SIGNAL:
                buf = new StringBuffer();
                buf.append("CLAIM(レセプト)データがサーバにより拒否されました。\n");
                buf.append("送信中のデータはログに記録します。診療報酬の自動入力はできません。");
                JOptionPane.showMessageDialog(
                        null,
                        buf.toString(),
                        title,
                        JOptionPane.ERROR_MESSAGE);
                break;
               
            case TT_SENDING_TROUBLE:
                buf = new StringBuffer();
                buf.append("CLAIM(レセプト)データの送信中にエラーがおきました。\n");
                buf.append("送信中のデータはログに記録します。診療報酬の自動入力はできません。");
                JOptionPane.showMessageDialog(
                        null,
                        buf.toString(),
                        title,
                        JOptionPane.ERROR_MESSAGE);
                break;
               
            case TT_CONNECTION_REJECT:
                buf = new StringBuffer();
                buf.append("CLAIM(レセプト)サーバ ");
                buf.append("Host=");
                buf.append(host);
                buf.append(" Port=");
                buf.append(port);
                buf.append(" が ");
                buf.append(tryCount*sleepTime);
                buf.append(" 秒以上応答しません。サーバの電源及び接続を確認してください。\n");
                buf.append("1. このまま接続を待つこともできます。\n");
                buf.append("2. データをログに記録することもできます。\n");
                buf.append("   この場合、データは送信されず、診療報酬は手入力となります。");
               
                option = JOptionPane.showOptionDialog(
                        null,
                        buf.toString(),
                        title,
                        JOptionPane.DEFAULT_OPTION,
                        JOptionPane.WARNING_MESSAGE,null,
                        new String[]{proceedString, dumpString},proceedString);
                break;
        }
       
        return option;
    }
   
    private void warnLog(String result, ClaimMessageEvent evt) {
        logger.warn(getBasicInfo(result, evt));
        logger.warn(evt.getClaimInsutance());
    }
   
    private void log(String result, ClaimMessageEvent evt) {
        logger.info(getBasicInfo(result, evt));
    }
   
    private String getBasicInfo(String result, ClaimMessageEvent evt) {
       
        String id = evt.getPatientId();
        String nm = evt.getPatientName();
        String sex = evt.getPatientSex();
        String title = evt.getTitle();
        String timeStamp = evt.getConfirmDate();
       
        StringBuilder buf = new StringBuilder();
        buf.append(result);
        buf.append("[");
        buf.append(id);
        buf.append(" ");
        buf.append(nm);
        buf.append(" ");
        buf.append(sex);
        buf.append(" ");
        buf.append(title);
        buf.append(" ");
        buf.append(timeStamp);
        buf.append("]");
       
        return buf.toString();
    }
   
    /**
     * CLAIM 送信スレッド。
     */
    private class Consumer implements Runnable {
       
        private OrcaSocket orcaSocket;
       
        public Consumer(OrcaSocket orcaSocket) {
            this.orcaSocket = orcaSocket;
        }
       
        @Override
        public void run() {
           
            ClaimMessageEvent claimEvent = null;
            Socket socket;
            BufferedOutputStream writer;
            BufferedInputStream reader;

            String instance = null;

            while (true) {

                try {
                    // CLAIM Event を取得
                    claimEvent = (ClaimMessageEvent) getCLAIM();
                    instance = claimEvent.getClaimInsutance();

                    // Gets connection
                    socket = orcaSocket.getSocket();
                    if ( socket == null ) {
                        int option = alertDialog(TT_CONNECTION_REJECT);
                        if (option == 1) {
                            warnLog("CLAIM  Socket Error", claimEvent);
                            continue;
                        } else {
                            // push back to the queue
                            claimMessageEvent(claimEvent);
                            continue;
                        }
                    }

                    // Gets io stream
                    writer = new BufferedOutputStream(new DataOutputStream(socket.getOutputStream()));
                    reader = new BufferedInputStream(new DataInputStream(socket.getInputStream()));

                    // Writes UTF8 data
                    writer.write(instance.getBytes(enc));
                    writer.write(EOT);
                    writer.flush();

                    // Reads result
                    int c = reader.read();
                    if (c == ACK) {
                        log("CLAIM ACK", claimEvent);
                    } else if (c == NAK) {
                        warnLog("CLAIM NAK", claimEvent);
                    }
                    socket.close();
                    writer.close();
                    reader.close();

                } catch (IOException e) {
                    alertDialog(TT_SENDING_TROUBLE);
                    System.out.println(e.getMessage());
                    if (instance != null) {
                        warnLog("CLAIM IO Error", claimEvent);
                    }

                } catch (Exception e) {
                    logger.warn("Exception " + e.getMessage());
                    break;
                }
            }
        }
    }
}
TOP

Related Classes of open.dolphin.impl.claim.SendClaimImpl$Consumer

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.