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