Newer
Older
CardRegister / src / hayashi / yuu / register / DeviceProcess.java
@yuuhayashi yuuhayashi on 26 Jan 2014 7 KB version 2010-03-19
package hayashi.yuu.register;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;
import java.util.concurrent.FutureTask;

import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import hayashi.yuu.pasori.felica.Felica;
import hayashi.yuu.pasori.felica.FelicaException;
import hayashi.yuu.tools.PlaySound;
import hayashi.yuu.tools.SpeedMail;

public class DeviceProcess extends Thread
{
	public static boolean doing = true;

	public DeviceProcess() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
		super();
		init();
	}

	/**
	 * 参照:
	 *  ArrayList<Byte> SerialPortReader.rcvBuffer
	 */
	public void run() {
		String zenkai = null;
		Felica task = null;
	    try {
	    	task = new Felica();
			while (DeviceProcess.doing) {
    			try {
    				String result = task.getID(Felica.WILDCARD);
    				if ((zenkai == null) || !zenkai.equals(result)) {
    					/*
    					 * 新しい電文を受信できた。
    		        	 */
    					System.out.println(result);

    					command(result);
    					zenkai = new String(result);
    				}
    			}
                catch (FelicaException e) {
                	// 読み取れなかったらそのまま
                	zenkai = null;
                }

				if (!DeviceProcess.doing) {
					break;
				}

	            try {
	                Thread.sleep(500);
	            }
	            catch (InterruptedException e) {}
			}
		}
	    catch (Exception e) {
			e.printStackTrace();
			CardRegister.logger.warning("'FeliCa'デバイスに接続出来ませんでした。");
            JOptionPane.showMessageDialog(CardRegister.mainFrame, "'FeliCa'デバイスに接続出来ませんでした", "エラー", 0);
		}
	    finally {
	    	if (task != null) {
	    		task.close();
	    		task = null;
	    	}
	    }
	}

	public void disable() {
		DeviceProcess.doing = false;
	}

	static final byte CTRL_STX = (byte)0x00fe;
	static final byte CTRL_ETX = (byte)0x0003;
	static final byte CTRL_NAK = (byte)0x0015;
	static final byte CTRL_ACK = (byte)0x0006;

	// 新たな電文を受け取る準備が出来ているかどうか
    boolean telegram = false;

    PlaySound sound = null;

    /**
     * 各種内部フラグをリセットして初期状態に戻す。
     * @throws LineUnavailableException
     * @throws UnsupportedAudioFileException
     * @throws IOException
     */
    public void init() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
        /*
         * デバイス内部状態の初期化
         */
    	DeviceProcess.doing = true;
        CardRegister.device = new DeviceData();
        sound = new PlaySound();
    }

    /**
     * 'EXT'を受信した後の、次のコマンドを送信するシーケンス処理
     * @throws LineUnavailableException
     * @throws UnsupportedAudioFileException
     *
     */
	@SuppressWarnings("unchecked")
	void command(String rcvStr) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
		sound.start();

		/*
		 * 蒐集したデータを表示する
		 */
		CardRegister.textArea.append(rcvStr + "\n");
		CollectData rec = new CollectData(new Date(), rcvStr, null, null);
		CardRegister.dataStore.add(rec);
		CardRegister.tmodel.addRow(rec.getRecordStrs());

		/*
		 * 蒐集したデータをメールで送信する
		 */
		if (CardRegister.isMail()) {
			try {
		    	StringBuffer contentSbuf = new StringBuffer("○○小学校登下校通知システムからのお知らせ。\n");
		    	contentSbuf.append("\n");

		    	String[] recitem = rec.getRecordStrs();
				contentSbuf.append(" 日 時:\t"+ recitem[0] +"\n");
				contentSbuf.append(" カード:\t"+ recitem[1] +"\n");
				contentSbuf.append(" 送信先:\t"+ recitem[2] +"\n");
				contentSbuf.append(" なまえ:\t"+ recitem[3] +"\n");

				FutureTask task;
				SpeedMail mail;
				mail = new SpeedMail(CardRegister.settingDialog.getPropertiesFilename());

	            mail.setSubject(recitem[3] +"ちゃん、登校しました。");
	            mail.setContent(contentSbuf.toString());
	            if (!recitem[2].equals("")) {
	            	mail.setTo(recitem[2]);
	            }

				task = new FutureTask(mail);
				new Thread(task).start();

				//----------------------------------------------------------------------
				// 送信完了を待つと、カードを連続でかざされた時の処理が間に合わなくなる
				//----------------
				/*
				try {
					task.get();
					CardRegister.textArea.append("メールを送信しました。\n");
					CardRegister.logger.info("メールを送信しました。");
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
				catch (ExecutionException e) {
					e.printStackTrace();
				}
				*/
			}
			catch (Exception e) {
				e.printStackTrace();
				CardRegister.logger.warning("メール送信に失敗しました。");
	            JOptionPane.showMessageDialog(CardRegister.mainFrame, "メール送信を送信できませんでした。", "エラー", 0);
			}
		}

		/*
		 * 蒐集したデータをXMLファイルにして保存する
		 */
		if (CardRegister.isXMLout()) {
			try {
		        DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
		        DocumentBuilder docbuilder = dbfactory.newDocumentBuilder();
		        Document document = docbuilder.newDocument();       // Documentの生成

				Element root = document.createElement("collect");   // root(collect)ノード作成
				document.appendChild(root);                			// ノードをDocumentに追加

				Calendar now = Calendar.getInstance();
				root.setAttribute("datetime", (new SimpleDateFormat("yyyy/MM/dd'-'HH:mm:ss")).format(now.getTime()));

				/*
				 * device要素を生成
				 */
				Element device = CardRegister.device.getXmlElement(document);
				root.appendChild(device);

				/*
				 * 読み取ったチェックポイント情報の要素を生成
				 */
				Element point = rec.getXmlElement(document);
				root.appendChild(point);

				/*
				 * DOMオブジェクトを文字列として出力
				 */
				TransformerFactory tfactory = TransformerFactory.newInstance();
				Transformer transformer;
				transformer = tfactory.newTransformer();
				transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

				File outfile = new File("data_"+ (new SimpleDateFormat("yyyyMMddHHmmss")).format(now.getTime()) + ".xml");
				transformer.transform(new DOMSource(document), new StreamResult(outfile));

				CardRegister.logger.info("XMLファイルにして保存しました。");
			}
			catch (ParserConfigurationException e) {
				e.printStackTrace();
				CardRegister.logger.warning("XMLファイルに保存失敗! (ParserConfigurationException)");
			}
			catch (TransformerConfigurationException e) {
				e.printStackTrace();
				CardRegister.logger.warning("XMLファイルに保存失敗! (TransformerConfigurationException)");
			}
			catch (TransformerException e) {
				e.printStackTrace();
				CardRegister.logger.warning("XMLファイルに保存失敗! (TransformerException)");
			}
		}

		/*
		 * 蒐集したデータを削除する。
		 */
		CardRegister.dataStore = new Vector<CollectData>();
		init();
    }
}