2010-06-30

X06HTの保護ケース

X06HTはまだ入手できていないんだが、ストラップホールがないのでケースを探している。
バッファローコクヨサプライから6月下旬にHTC Desire専用レザーケースが発売された。
液晶保護フィルム付きで\2,390、直販サイトでは\1,780だった。(価格.comでは、2010.6.30時点で最安値が\1,300だった)
金額的には、まあ手頃かな。液晶保護フィルムも付いているし。
X06HTを実際に入手するまでには、まだ時間が掛かりそうだから他にも色々探してみるかな。

2010-06-25

X06HT 予約状況

今日、ショップから電話があった。
「ソフトバンクから連絡があり、入荷予定が"6月下旬以降"から"7月下旬以降"に変更になりました」とのこと。
まあ、最初から入手に時間がかかることは承知の上だったので驚かないけどネ。
気長にまつことにしよう。

2010-06-22

X06HT、入手できるのはいつになることやら...(~_~)

今日、Web見てたらこんな記事を見つけた。
ソフトバンク「HTC Desire」が手に入らない!――品薄状態続くDesireの入荷・販売状況
この記事を書いた方は、5月初旬に予約して現時点で7月末あるいはそれ以降に入荷ということらしい。
私は6月中旬に予約したので同じ状況だとすると、9月とかになるっていうこと? 一季節(夏)過ぎてしまうね。
待ちきれない人がiPhone4に流れて、X06HTの品薄状態が解消されたりしないかなぁ...と薄い期待をしている今日この頃でした。

2010-06-19

GAE/J + Slim3 : メール受信アプリを作ってみる(4)

今回はMailServiceを作成する。
前回作成したテスト MailServiceTest#receive_plainText_UTF8()をパスするように MailService#receive()を実装する。
◎まずはコンパイルエラーをなくすように必要最低限のコードを書いてみる。
public MailItem receive(String pAddress, InputStream pInputStream) {
    MailItem mailItem = null;
    return mailItem;
}
これで、コンパイルは通るのでテストを実行してみる。
結果は...NullPointerExceptionでRed、receive()の戻り値がnullなので当たり前だな。
◎次はテストをパスするようにコードを書く。
public MailItem receive(String pAddress, InputStream pInputStream) {
    MailItem mailItem = null;
    Properties prop = new Properties();
    Session session = Session.getDefaultInstance(prop, null);

    try {
        MimeMessage message = new MimeMessage(session, pInputStream);
        mailItem = new MailItem();
        mailItem.setFrom(message.getFrom()[0].toString());
        mailItem.setTo(message.getRecipients(RecipientType.TO)[0].toString());
        mailItem.setSubject(message.getSubject());
        InputStream in = (InputStream)message.getInputStream();
        Reader reader = new InputStreamReader(in);
        BufferedReader bufReader = new BufferedReader(reader);
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = bufReader.readLine()) != null) {
            sb.append(line + "\n");
        }
        mailItem.setBody(sb.toString());
        Datastore.put(mailItem);
    } catch (MessagingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return mailItem;
}
◎コンパイルは通っているので、テストを実行してみる。もちろんGreen、これで基本パターンはOK (^_^)v
次回は通常のメールと同じように文字コードが"ISO-2022-JP"の場合を考えてみる。

2010-06-17

GAE/J + Slim3 : メール受信アプリを作ってみる(3)

今回はMailServiceTestを作成する。
まずは受信メールを表すモデルクラス MailItemを作成しておく。
  • メール受信のサービス: "gen-model"で /src/../model/MailItem.java と /test/../model/MailItem.java を生成する。
  • 属性はfrom, to, subject, bodyを作成する。型は全てStringとする。

では、MailService#receive(String pAddress, InputStream pInputStream)のテストを作成する。
文字コードは、現時点では余計なことは考えたくないので"UTF-8"としておく。またマルチパートも現時点では考慮しない。
最初は、単純で基本的な処理から考えていくのが"吉"です。(^_^)

テストメソッドは以下のようになった。
public class MailServiceTest extends AppEngineTestCase {
    private MailService service = new MailService();

    /**
     * シングルパート(text/plain)を入力し{@link MailItem}オブジェクトが生成されること
     * @throws UnsupportedEncodingException
     */
    @Test
    public void receive_plainText_UTF8() throws UnsupportedEncodingException {
        String mailFormat = "Received: by 10.115.25.19 with SMTP id c19mr2897164waj.34.1275464064977;\n"
            + "Wed, 02 Jun 2010 00:12:34 -0700 (PDT)\n"
            + "Return-Path: <%1$s>\n"
            + "Received: from smtp.hoge.org (ml.hoge.org [128.1.2.3])\n"
            + "by gmr-mx.google.com with ESMTP id u10si11332059wak.6.2010.06.02.00.34.24;\n"
            + "Wed, 02 Jun 2010 00:12:34 -0700 (PDT)\n"
            + "Received-SPF: pass (google.com: best guess record for domain of sender@hoge.org designates 128.1.2.3 as permitted sender) client-ip=128.1.2.3;\n"
            + "Authentication-Results: gmr-mx.google.com; spf=pass (google.com: best guess record for domain of sender@hoge.org designates 128.1.2.3 as permitted sender) smtp.mail=sender@hoge.org\n"
            + "Received: from [128.1.2.3] (unknown [128.1.2.3])\n"
            + "by smtp.hoge.org (Postfix) with ESMTPA id 8F1C716838E\n"
            + "for <%2$s>; Wed,  2 Jun 2010 00:12:34 -0700 (PDT)\n"
            + "Message-ID: <4C060983.1090109@hoge.org>\n"
            + "Date: Wed, 02 Jun 2010 00:12:34 -0700\n"
            + "From: SENDER <%1$s>\n"
            + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4\n"
            + "MIME-Version: 1.0\n"
            + "To: RECEIVER <%2$s>\n"
            + "Subject: %3$s\n"
            + "Content-Type: text/plain; charset=UTF-8\n"
            + "\n"
            + "%4$s\n";
        String encodedSubject = MimeUtility.encodeText("これは件名", "UTF-8", "B");
        String mailStr = String.format(mailFormat, "sender@hoge.org", "reciever@fuga.org", encodedSubject, "本文1行目\n本文2行目");

        byte[] bytes = mailStr.getBytes();
        InputStream in = new ByteArrayInputStream(bytes);
        MailItem mailItem = service.receive("sender@hoge.org", in);
        assertThat(mailItem.getFrom(), is("SENDER <sender@hoge.org>"));
        assertThat(mailItem.getTo(), is("RECEIVER <reciever@fuga.org>"));
        assertThat(mailItem.getBody(), is("本文1行目\n本文2行目\n"));
        assertThat(mailItem.getSubject(), is("これは件名"));
    }
}
内容は、
  • encodedSubjectに、件名を"UTF-8"でエンコードした文字列をセットする(=?UTF-8?B?44GT44KM44Gv5Lu25ZCN?= となる)
  • mailStrにヘッダーを含めた受信メールの文字列を作成する
  • 次の2行でこのmailStrをInputStramに変換する
    byte[] bytes = mailStr.getBytes();
    InputStream in = new ByteArrayInputStream(bytes);
    
  • MailService#receive()メソッドを実行する
  • 生成されたmailItemの内容を検証する
となっている。

この時点ではコンパイルエラー(MailService#receive()が未定義)となっているはず。
次回はこのテストをパスするようにMailService#receive()を実装していく。

2010-06-14

おかえり「はやぶさ」、そしてお疲れ様

はやぶさ君がとうとう帰ってきました。
生中継サイトを見ていたんだが中々繋がらなかったので、管制室の中継サイトをみていた。
20時ころに騒がしくなって、みんなでバンザイをしていたんだが、どうやらカプセル分離に成功した瞬間だったらしい。
結局大気圏突入の生中継は見られなかった。(;_;)

JAXA - ISAS トピックス」によると
  • 2010.6.13 19:51 : カプセルの分離に成功
  • 2010.6.13 22:51 : 大気圏突入
  • 2010.6.13 23:56 : カプセル発見
ということで、無事ミッションを終えました。
カプセルも今日(6.14)回収されたそうです。
上記サイトに大気圏突入直前に「はやぶさ」が撮影した地球の写真が掲載されています。
最後の最後までよく頑張ったネ、はやぶさ君

NASAが観測用航空機から撮影した大気圏突入の映像が公開されています。
バラバラになりながら燃え尽きていく姿を見ると何だか泣けてきますねぇ(T_T)

私がいつもチェックしているITmediaに「お帰りなさい、はやぶさ! 総まとめ」に情報がまとめられています。
あらためて「はやぶさ」の7年の旅を見てみると、すごいことをやってのけたんですね。
はやぶさ君、そして運用関係者の方々、お疲れ様でした。m(_ _)m

2010-06-13

「はやぶさ」が帰ってくる

小惑星イトカワの探査機「はやぶさ」が、7年 50(60?)億kmの旅を終えて今日地球に戻ってきます。(6/13 9:00時点[日本時間]で地球から282,110km)
毎週「今週のはやぶさ君」でチェックしていたが、毎週約300万kmづつ地球に近づいてきていよいよ今日(6/13 22:51[日本時間])地球の大気圏に突入する。
イトカワのサンプルが入っている(と思われる)カプセルは分離されて回収され、「はやぶさ」本体は燃え尽きてしまう。
「はやぶさ」君、もう少しだ頑張れ!!

2010-06-12

X06HT(HTC Desire)予約してきた

今さらだが、今日X06HTを予約してきた。(iPhone4が発表された後なので余計に今更感があるが...)
6月下旬以降ということだったので気長に待つことにしよう。
予約したときに
  • MMSが使えない
  • 電話帳の移行ができない
ことをしつこく確認された。
それを分かった上で予約しに行っているんだけどネ

2010-06-10

GAE/J + Slim3 : メール受信アプリを作ってみる(2)

仕事で他プロジェクトの応援に借り出されて忙しかったので間が空いてしまった。(-_-;

前回、メール受信ができるように設定を行ったので、メール受信するプログラムを作っていく。
まずは必要となるソースを生成しておく。とりあえずコントローラとサービスは必要なので、これらを生成しておく。
  • メール受信のコントローラ: "gen-controller"で /src/../controller/mail/ReceiveController.java と /test/../controller/mail/ReceiveControllerTest.java を生成する。
  • メール受信のサービス: "gen-service"で /src/../service/MailService.java と /test/../service/MailServiceTest.java を生成する。

さて最初はMailServiceのテストだが、仕様を考えなければいけないのでGAE/Jでのメール受信について調べてみる。
メール受信に関しては「Google App Engineドキュメント」の[Java]-[Services]-[Mail]-[Receiving Email]に書かれている。
ここの「Handling Incoming Email」を読むと下記のコードでMimeMessageオブジェクトが取得できる。
import java.util.Properties;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;

Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session, req.getInputStream());

ということで、メール受信のサービス MailServiceの仕様は次のようにする
[receiveメソッド]
  • 引数
    • 受信メールアドレス: コントローラに渡される受信メールアドレス
    • InputStream:メールの内容(上記コード例のreq.getInputStream())
  • 処理内容
    • 引数 InputStreamからMimeMessageを生成する
    • MimeMessageから"From", "To", "件名", "本文"を取り出す
    • 取り出した項目から受信メールを表すモデルクラス(MailItem)を生成する
    • 生成したMailItemを戻り値として返す

風邪気味なので今日はここまで、次回はMailServiceTestを作成する。

2010-06-03

GAE/J + Slim3 : メール受信アプリを作ってみる(1)

会社で開発しているGAE/J + Slim3アプリの開発作業がようやく起動に乗ってきたので、"個人的興味"で"個人的"なアプリを作ってみる。
単なるWebアプリではつまらないので、メールで処理依頼を受け付けられるようにしてみる。
ということで、メールを受信するアプリをGAE/J + Slim3で作ってみる。

まずは設定関係から...
この設定を行えば、アプリ宛のメール"abc@xyz.appspotmail.com"が受けられるようになる。
[war/WEB-INF/appengine-web.xml]
<inbound-services>
    <service>mail</service>
</inbound-services>

[war/WEB-INF/web.xml]
<security-constraint>
    <web-resource-collection>
        <url-pattern>/_ah/mail/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

受信したメールをどのようにアプリで受け取るかというと、URL "/_ah/mail/メールアドレス"にマッピングされるのでサーブレットで処理すればよい。
Slim3の場合、AppRouter.javaでメール受信処理を行うコントローラのURLへのルーティングを定義すればよい。(Slim3 Controller - URL mapping参照)
[controller/AppRouter.java]
public AppRouter() {
  addRouting("/_ah/mail/{address}", "/mail/receive?address={address}");
}
このコードでは、メールを受信すると /mail/receiveにリクエストがくることになる。またメールの宛先(To)アドレスはリクエストパラメータ"address"として渡されてくる。

これでメールを受信する準備が整ったのでメール受信用のコントローラを作ってみる。もちろん、テストもネ!