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();
}
}