2010-12-20

[GWT]Amazon API のXMLを解析する (クライアントサイド)

Amazon Product Advertising APIを利用して商品データを解析するGWTのサンプルです。クライアント側の処理なので、XMLパーザーは、com.google.gwt.xml.client.*のパッケージのクラスを利用します。まあ、ふつうのXMLの処理ですので特筆するべきところはありませんが、商品によって要素が抜ける場合がありますので注意が必要です。例えば下記では、AuthorとCreatorの扱い方など。


2010-12-17

[Java]ファイルアップロードサーブレットプログラム

純粋なサーブレットでのファイルアップロードプログラムの例です。下記のプログラムの動作には、
のライブラリが必要です。
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Logger log = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
        try {

            //URLより保存場所の絶対パスを入手
            ServletContext sc = getServletContext();
            String path = sc.getRealPath("/WEB-INF");
            log.info("filepath:" + path);
            File fileDir = new File(path);

            if (!ServletFileUpload.isMultipartContent(new ServletRequestContext(request))) {
                throw (new Exception("Not FileUpload Request"));
            }
            ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
            List<fileitem> list = upload.parseRequest(request);
            for (Iterator<fileitem> iter = list.iterator(); iter.hasNext();) {
                FileItem fItem = (FileItem) iter.next();
                if (fItem.isFormField()) {
                    continue;
                }
                String fileName = (new File(fItem.getName())).getName();
                File newFile = new File(fileDir, fileName);
                fItem.write(newFile);

            }
            log.info("アップロード終了");
        } catch (Exception ex) {
            log.warning("アップロード処理異常終了");
        }

    }


2010-12-16

[C++] Visual C++でerror C2143: 構文エラー がでた場合の原因と対処

卒研のプログラムで、
  • error C2143: 構文エラー : ';' が '◯◯' の前に必要です。
というエラーが発生。ちょっとハマったのでそのメモ書きです。まず、その原因は次の2つのいずれかです。
  1. ケアレスミス。括弧やセミコロンが抜けているなど
  2. 利用しているクラスが未定義

今回の原因は後者でした。具体的に言いますと以下のような記述のところでエラーがでました。
CString str;
CTest* test; // ←ここでerror C2143

なにがまずいかというと、この状況でのエラーは、「CTestがクラスとして認識されていない」のが原因だったようです。

【解決策】
  • CTestを定義しているヘッダをincludeする
  • プロジェクトのプロパティ→構成プロパティ→C/C++→全般→追加のインクルードディレクトリ にCTest.hが入っているディレクトリを指定する
インクルードディレクトリの設定もうっかり忘れることがありますので、気をつけたいものです。


2010-12-14

[C#] WebRequestクラスの利用時のプロトコル違反への対応策

WebRequestクラスを利用してウェブサーバにアクセスした場合、
  • サーバーによってプロトコル違反が発生しました. Section=ResponseHeader Detail=CR の後には LF を指定しなければなりません。
という意味不明なエラーが発生します。このようなときは、アクセスする前に以下のような記述をしてください。
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
SettingsSection section = (SettingsSection)config.GetSection("system.net/settings");
section.HttpWebRequest.UseUnsafeHeaderParsing = true;
config.Save();
なお、ここで記述しているクラスは、
  • System.Configuration
  • System.Net.Configuration
のライブラリを利用します。参照設定で追加しておきましょう。


2010-12-13

Netbeansのインストールでトラブった場合の対処法

Netbeansのバージョンアップを繰り返すと、最新版にした場合にインストール後の動作がおかしくなる場合があります。例えば

  • インストールしたはずのサーバがない、登録できない
  • プラグインが見つからない
  • 動作がやけに遅くなる
などなど、、、これらは、前バージョンの設定ファイルを継承し続けたことによる弊害が原因の場合があります。
思い切ってフレッシュな気分で新しいバージョンのNetbeansを使いたいときは、
  • ホームディレクトリ下の隠しファイルになっている「.netbeans*」関係のファイルをごっそり消す
という荒業をすることで、正常に動作するかもしれません。うちの研究室では、きままにバージョンアップをしているので、バージョンが変わったときに前の設定の継承を何回か行う傾向があります。その際に、何らかのデータの齟齬が発生して、まともに動かなくなることがあります。今日もそういったトラブルがあり、再インストールなどを行って3時間ぐらい時間を潰しましたが、結局設定ファイルを削除してOKという感じでした。




2010-12-10

ET研究会に参加してきました

「Web検索APIを利用した英語表現評価支援システム」という題目で、信学会教育工学研究会にて発表をしてきました。発表したのは院生でしたが、無事終了です。質疑応答もちょっと難しかったですが自分なりに答えてたと思います。で、反省と感想です。

質疑応答から感じたこと
「ターゲットとするユーザ」については、もう少し考えたほうがいいかもしれません。ただし、目的として支援したいユーザと、現状のシステムの実装機能で支援できる内容に齟齬が起きないように気をつけなければなりません。あるいは、現状のシステムが本来の目標に対してどのような立ち位置にあるのか?を説明できないといけないでしょう。
「先行研究」については、ちょっと調べ直しですね。元々のこの研究を始めた発端が、個人的なモチベーションからはじまったものなので、調査不足の点は否定できないですね。まあ、先行研究と類似していたとしても、前々から研究室でやりたかった「英語学習支援」がテーマなので、今回のシステムをベースに、いろいろ発展させていきたいなと思う今日この頃です。

その他の発表について
特に気になった発表を2点ほど。
「e-Leariningにおける受講者の動作の分析」については、うちの研究室でも動作分析の研究をやっていたので、興味深いものでした。特徴量の取り方とか、評価の仕方など参考になりそうです。
「学習・教育支援環境支援フレームワークMeshの構成」については、「汎用的なフレームワークを作る」という研究の視点はマネしたいなと。。。ただ、なかなか難しい感じがしているので、まずはWeb APIレベルかなぁというのが思っているんですが、、、
その他、今回の研究会のテーマにインタフェースというのがあったせいか、PCのマウス・キーボード以外のデバイスを利用する研究の多さが目立ちました。

[GWT] Cometでプッシュプログラミング ~クライアントプログラミング編~

GWTでCometサーバーにアクセスするクライアントプログラムの実装方法についてです。

基本的には、通常のサーバアクセスと同様にRequestBuilderを利用してCometサーバに非同期にアクセスします。Cometからデータが送られてくると、onResponseReceivedメソッドが呼ばれるのでそこで内容を抽出し処理を行います。処理が終わったら、再帰的に接続処理を呼び出すことで、Cometサーバとの通信を継続して処理することができます。

private void connectComet() {
        try {
            Window.alert("CometConnect()");
            RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, cometURL);
            
            requestBuilder.sendRequest(null, new RequestCallback() {
                @Override
                public void onResponseReceived(Request request, Response response) {
                  String tmp= response.getText();
                  connectComet();
                }
                @Override
                public void onError(Request request, Throwable exception) {
                                  }
            });
        } catch (RequestException ex) {
            //エラー処理をここで書く
        }
    }


2010-12-08

Amazon Product Advertising API 利用時の日本語処理

Amazon Product Advertising API を利用したプログラムをGAE上で動かしているのだけれど、日本語の処理で手間取ったので、覚書き。いちおう話の前提としては、GWTとGWT-RPCを利用してサーバ側でAmazonに接続しています。アクセス方法は、HttpURLConnectionクラスを用いました。

【検索キーに日本語を含める場合】
検索クエリーを生成する際に、

  • URLEncoder.encode(keyword,"utf-8")

というように、UTF-8に変換しておきます。こうしておかないと、正しい検索がされません。

【検索結果に日本語が含まれる場合】
検索するプログラムについては、サンプルプログラムにある SignedRequestHelprクラスを利用してます。日本語が含まれていると文字化けとなって、ただしく受け取ることができません。そこで、BufferReaderに受け渡すときには、以下のように記述します。


  • BufferedReader reader = new BufferedReader(new InputStreamReader(urlconn.getInputStream(),"UTF-8"));


2010-12-06

プログラミングリソースをWebサービスで残す

うちの研究室にはいろいろプログラミングのリソースが溜まっているのだけれど、なかなか後年への技術継承が上手くいかない、、、その理由は、やはりソースコードレベルの継承だと、そもそもそのソースコードが汎用的に作られているかが怪しいし、継承する学生もその理解に追いつかないという問題。。。そう考えるともっと使いやすい形に落としこむ必要があるわけで、その策としてWebサービス化という結論に。。。このことは昔から思っていたんだけど、実際問題として実装時にWebサービス化する利点がなかなかなかったというのもある。最近は、研究室でも各種外部ウェブサービスをマッシュアップするようになったので、それだったら研究室のリソースもウェブサービス化したらいいじゃんということで、今回ウェブサービス化に踏み切ることに。。。

とりあえずは研究室での運用だけど、今後は学外への公開も視野に入れる予定。

[Java]Cometプログラミング ~Glassfishの設定~

ここでは、Glassfishをサーバにした際の設定について取り上げます。また、開発環境としてNetbeansを利用する場合についても取り上げます。

[Glassfishでの設定]
Cometを利用する際、古い記事を見るといろいろ設定が必要なような記述がみられますが、Glassfish v3では標準で Cometをサポートしていますので設定は簡単です。手順としては

  1. 管理コンソールを立ち上げる(4848が標準ポートです)
  2. ネットワーク設定→プロトコル→http-listerner-1を開く
  3. Cometサポートを有効にする

これだけでOKです。

[Netbeansで利用する場合]
Netbeansには、標準でGlassfishがついてきます(これがNetbeansをオススメする理由の一つでもあるんですが)。同様にすればいい、、、と思ってるとドツボにハマります。
実は、NetbeansでGlassfishの管理コンソールで設定した内容は一時的なもので、サーバを再起動すると設定が標準に戻ってしまいます。どうすればいいのかというと、

  1. Netbeansでサービスペインをクリック
  2. サーバ→Glassfishを右クリックし、プロパティを選択
  3. Cometサポートを有効にする

という手順をふみます。これがわからず、設定ファイルをいじったりして悩んでました。(^^ゞ

2010-12-03

徳島大への遠隔講義配信を行いました

昨年度もおこなった、徳島大への遠隔講義配信を行いました。1年前にやっていたので気を抜いてたのですが、前日にちょっと慌てました。。。。というのも、Polycomにネットワークカメラを接続するということを行っているのですが、それをどう接続すればよいのかというのをすっかり忘れてまして、、、(^^ゞやはりこういうちょっとしたノウハウも残しておくべきですね。昨日は、システムの配置位置とかを根本から考え直し、できるだけ柔軟にカメラを配置できるように、ラックに機器を収納するなど配置変更を行いました。おかげで、今日はすんなり行きましたが、、、、

さて、本日の講義の内容は昨年度と同様に
  • 画像映像処理技術を利用した教育システム
についてお話をさせてもらいました。前半は世間話でしたが、、、質問がなかったのが残念だなぁ。

なお、来年はハイビジョンカメラとハイビジョン対応Polycomを利用した配信を検討中です。


[Java] Cometでプッシュプログラミング ~サーバプログラミング編~

サーバーサイドからのプッシュ配信を実現するフレームワークとしてCometというのがあります。これは昔からありまして、うちの研究室でも数年前の卒論で利用してました。で、今年も利用することになったんですが、ノウハウを整理しきれてなくて卒論だけ見てもわかりにくい状況になってましたので、ここであらためて整理しておきます。

12/6 プログラムに一部追記しました。

Cometの原理
httpで接続したコネクションを接続しっぱなしにして、レスポンスのストリームにデータを流し込むことでプッシュを実現します。

クラス構成
サーバー側では少なくとも3つのクラスが必要です
  • Cometサーバ実装クラス ・・・ プッシュするためのコネクションを確保するクラス。サーブレットです
  • Cometハンドルクラス ・・・ CometHandlerを実装したクラス。ここにプッシュで送信する処理を記述します。
  • ユーザプログラム ・・・ Cometを利用するプログラムです。

関連ライブラリ
Glassfishには
  • grizzly-comet.jar
というライブラリが同梱されています。このファイル名で探せば出てくるはずですから、見つけたらクラスパスに設定しましょう。

 Cometサーバプログラム
 クライアントとの接続を確保します。まず、init内では
  • Cometエンジンの登録
  • Cometエンジンの設定
を行います。そして、ユーザからコネクション要求があれば、processRequest(サーブレットのdoGet、doPost相当)内で、以下のように書かれている処理を行います。
  • Cometエンジンの呼び出し
  • Cometハンドラーへのコネクションストリームの受け渡し
  • Cometハンドラーの登録
//初期設定
    @Override
    public void init(ServletConfig config) throws ServletException {
        cometContextPath = config.getServletContext().getContextPath() + "/comet";
        System.out.println("cometContextPath:"+cometContextPath);
        CometContext context = CometEngine.getEngine().register(cometContextPath);
        context.setExpirationDelay(10 * 60 * 60 * 1000);
    }
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //CometHandlerクラスの登録
        CometHandler handler = new MyHandler();
        handler.attach(out);
        CometContext context = CometEngine.getEngine().getCometContext(cometContextPath);
        context.addCometHandler(handler);
    }
Cometハンドラー Cometハンドラーとは何か?それは、Cometでの配信時の処理を記述するクラスです。ここで大切なのは、onEventメソッドです。これは、Pushする際に呼ばれるメソッドです。ここでwriterに対して書き込みを送ることで、クライアントにその内容が配信されます。なぜでしょう?それは、ここのwriterというのは、上記のサーバプログラムでハンドラーを登録する際にattachメソッドにて受渡したHttpServletResponseのWriterの事なのです。
public class MyHandler implements CometHandler<PrintWriter> {

    private PrintWriter writer = null;

    public void onEvent(CometEvent event) throws IOException {
        if (CometEvent.NOTIFY == event.getType()) {

           String id = (String) event.attachment();
            writer = response.getWriter();
            writer.write(id);
            writer.flush();
            event.getCometContext().resumeCometHandler(this);
        }
    public void onInitialize(CometEvent event) throws IOException {
        System.out.println("Init");
    }

    public void onTerminate(CometEvent event) throws IOException {
        onInterrupt(event);
    }

    public void onInterrupt(CometEvent event) throws IOException {
        writer.close();
        event.getCometContext().removeCometHandler(this);
    }
 //クライアントとのストリームを受け取る
    public void attach(PrintWriter writer) {
        this.writer = writer;
    }
   private void removeThisFromContext() throws IOException {
        response.getWriter().close();
        CometContext context =
                CometEngine.getEngine().getCometContext(cometContextPath);
        context.removeCometHandler(this);
    }



ユーザプログラム ユーザプログラムでの記述は下記の通りです。以下はサーブレットの例ですが、ポイントは最後の行です。notifyメソッドを呼ぶことで、CometハンドラークラスのonEventが呼ばれることになります。つまり、プッシュしたい時にnotifyを呼び出せば良いわけです。引数は、ハンドラーのonEventメソッドでeventのアタッチメントとして取り出すことができます。
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        ServletConfig config=this.getServletConfig();
        String id = request.getParameter("id");
        CometContext context = CometEngine.getEngine().getCometContext(cometContextPath);
        context.notify(id);
 }
以上の3つを見比べることで、Cometが何をやっているのかわかるでしょう。コメットのサーバの設定や、クライアントプログラムの記述については、後日書こうかと思ってます。

2010-12-01

GWTでXMLを扱う ~クライアントサイド編~

GWTでのXMLプログラミングについて基本のところを書いてなかったので、、、今回は、クライアントサイド編です。クライアントサイドでの操作は、JavaScriptでの操作とほぼ同じになるのでそんなに難しく考える必要はないでしょう。利用するクラスは、 com.google.gwt.xml.clientパッケージを利用します。importする際には間違えないようにしましょう。

gwt.xmlファイルに以下の記述を追加してください。
操作するXMLファイル
Javaのコードは以下のようになります。基本的な使い方のパターンを挙げています。前提として、stringXML変数に上述のXMLデータが入っているものとします。
注意点ですが、他のXMLパーザーと同様に子ノードを取ってくる際には、改行が入ってくると子ノードの個数が変わってきます。具体的に言うと、上記のXMLではsbosyタグの子ノードは2つとなりますが、これらに改行が入ってくると、改行がテキストノードとしてカウントされます。たいていのXMLドキュメントには改行は入ってないと思いますが、気をつけてください

2010-11-30

GWTでサーバーに直接アクセスする ~Requestbuilderを利用する~

GWTでサーバと通信する場合はGWT-RPCを利用するのがスタイリッシュですが、サーバ内にあるコンテンツやサーブレットにアクセスしたいというときがあります。その際は、Requestbuilderを利用します。使い方は以下のとおり。
@UiHandler("btnSubmit")
    void onClick(ClickEvent e) {
        try {
            final String url = "/test.txt";
            final RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url);
            requestBuilder.sendRequest("GET", new RequestCallback() {

                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert("ファイルの読み込みに失敗しました");
                }

                @Override
                public void onResponseReceived(Request request, Response response) {
                    Window.alert("読み込みました" + response.getText());
                }
            });
        } catch (RequestException ex) {
            //エラー処理をここで書く
        }
    }
このサンプルは、ボタンを押したときにサーバ内にあるファイルtest.txtにアクセスしています。アクセスに成功すると、onResponseReceivedメソッドが起きますのでそこで、処理をします。受け取ったデータは引数のResponseクラスに入ってます。なお、GWTはJavaScriptと同じ制約を受けますので、外部のサーバに対してこのようなアクセスをすることは無理です。

2010-11-27

TemplateエンジンVelocityを使ってみよう

今さら感がありますが、TemplateエンジンVelocityについてです。ずいぶん昔からあったフレームワークですが、私自身、以前はJSFベースで作っていたので全く眼中になかったというのが正直なところ。ただ今はGWTに移行したこともあり、Servlet回帰も含めて再評価しているところです。

ライブラリのダウンロードと設定

以下のサイトからダウンロードして下さい。


クラスパスには、"velocity-1.6.4.jar"を追加しておくとよいでしょう。

Velocityの仕組み
利用方法はとてもシンプルです。まず、Templeteとなるファイル(拡張子はvm)を用意し、そこにVelocityの命令文法に従ってテンプレートを記述していきます。Velocityの文法と言っても身構えることはなく、通常のテキスト文の中に命令文法を記述するだけです。その特徴は以下のとおりです。

  • 変数は頭に$を付ける。任意の位置に記述することが可能。
  • foreach, if 文等の繰り返しや条件分岐の処理ができる。
  • Velocityの命令文法を記述した行は先頭に#を付ける

テンプレートファイルの書き方

ここではJSON形式のファイル作成を対象としてみます。

{"name": "$user.name", "age": "$user.age"}


Javaの記述の仕方は以下のようになります。

StringWriter w = new StringWriter();
 //マッピングするデータをクラスに格納
 testUser u = new testUser();
 u.setName("おち");
 u.setAge(20);
 Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, new JdkLogChute());
 Velocity.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
 Velocity.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
 Velocity.init(); // 初期化
 VelocityContext context = new VelocityContext();
 //テンプレートとのマッピング
 context.put("user", u);
 //テンプレートファイルの指定
 Template template = Velocity.getTemplate("/WEB-INF/test.vm", "UTF-8");
 //実行。結果はwに出力
 template.merge(context, w);

補足しますと、上記のプログラムはテンプレート内の変数とJava内でのデータ変数をクラスの受け渡しによりマッピングさせていることがわかります。

今回はシンプルなJSONを例にしましたが、複雑な形式のファイルをテンプレートを利用して動的に生成することができます。XMLは当然のこと、HTMLの記述もできます。また、Texような文書ファイルにも適用できるでしょう。

これをみて思うのはJSPと何が違うのかということですが、まあVelocityのほうはあくまでもTemplateエンジンとしてシンプルな枠組みになっているような気がします。JSPはあれもこれもいろいろできてしまうわけで、、、
個人的には、XMLとかJSONとかのフォーマットをServlet等で出力する際に、print文とか使ってコード内にガガガッと書かれるのは勘弁してほしいなと思っていたので、VelocityみたいなTemplateエンジンは魅力的なだなぁといまさらながら感じた次第です。

追記:注意事項
上記のサンプルで、testUserというデータクラスを用意していますが、このデータクラスは必ずpublicなものにして下さい。ここをうっかり忘れてて、テンプレートに反映されないという自体に何回か繰り返したので、自分用のメモ追記です。

2010-11-26

GAE/JでAmazon Product Advertising APIを使い始める際の注意事項

Amazon Product Advertising APIで遊んでいるわけですが、ちょっと注意することがあったのでメモ。このAPIについては、認証シグネチャーを要求するようになって、プログラム的にめんどくさそうな感じはしてるが、実際はサンプルプログラムに同梱されているSignedRequestHelperクラスを利用すれば問題ない。。。。はずなんですが、それでも認証のエラーが出ることがあります。これはBASE64エンコードの処理でトラブルらしいのですが、いろいろ情報が錯綜しているようなので,整理してみます。

【GAE/J上で動作させる場合】

  • commons-codec-1.3を利用するとOK
  • 最新版であるcommons-codec-1.4を利用するとエラーになります。

参考までに、

【GAE/J以外で動作させる場合(例えばGlassfishの場合)】

  • commons-codec-1.4での動作OK

ということらしいです。

また、いろいろ検索して出てくる

Base64 encoder = new Base64(); を Base64 encoder = new Base64(0); に修正する

というのもやらなくても動きました。(逆に0を追記するとエラーになりました。1.4では)これは古い情報なのでしょうか?

2010-11-20

[C++/CLI] UDPプログラミング ~非同期通信編~

クライアント側で受信する際に、非同期で処理をしたほうがスムーズに動作する場合があります。以下は、クライアント側のソースです。
BeginReceiveが実行されると、非同期で受信を行いコールバック関数が呼び出されます。この方法を利用することで、受信を行うまでに次の処理にすすめることができます。

2010-11-13

Twitterアプリを開発でOAuthを利用する際のはじめのはじめの一歩

卒研で、OAuth認証を利用したTwitterアプリを作らせているのですが、ちょっとつまづいたのでそのメモ書き。

まず、TwitterAPIを利用するには、IDとパスワードが必要なわけで、2010年8月まではBASIC認証ができましたが、それ以降はできなくなりました。その代替としてOAuth/xAuthを利用する事になります。この手順としては基本は以下のとおりです。

事前準備
  1. OAuthを使うアプリケーションをTwitterサイトで事前登録する 
  2. 設定画面よりConsumer keyとConsumer secret(アプリのIDとパスワードみたいなもの)を入手
(開発する)アプリでの手順
  1. ユーザにアプリが自身のIDを利用してTwitterにアクセスできるように許可をさせる。具体的にはConsumer keyとConsumer secretを利用して、アプリで認証のためのURLを入手し、そのサイトへユーザをアクセスさせる。
  2. サイト上でユーザが許可するとPINCODE(暗証番号)が表示される
  3. Consumer key、Consumer secret、PINCODEを利用して、AccessTokenとAccessTokenSecretを入手する(これが、ユーザのID、パスワード替りになります)。
  4. 以後、 Consumer key、Consumer secret、AccessToken、AccessTokenSecretを利用してAPIにアクセスする
基本的に、PINCODEの入手は一度だけでいいです。(これを短期間で何回もやってると 401エラーがでるような気がします。真偽は未確認ですが、、、)

アプリを開発する際には、
  • アプリ認証のためにブラウザを起動し認証用URLへ行かせる記述が必要。ウェブアプリの際には、自分のサイトへ戻ってこさせる記述も必要。
  • PINCODEをユーザに入力させる画面とそれを保存する記述が必要。
  • AccessToken、AccessTokenSecretを保存する記述が必要
ということになります。

以上が基本的な考え方ですが、アプリの形態によりちょっとした補足をしておきます。


【マルチユーザでないアプリの場合】
自分しか使わない、あるいはbotのようなアプリの際に、わざわざPINCODEを入手してAccessToken、AccessTokenSecretを入手するプログラムの記述と操作をするのははばからしいです。Twitter上のアプリのサイトには、自分用のAccessToken、AccessTokenSecretを入手するボタンがあります。これをコードに埋め込んでおけば、手軽に利用できます。

【PINCODE入手させることが困難な場合】
アプリによっては、PINCODE入手のためにウェブサイトにアクセスさせることが困難なケースが考えられます。あるいは、いったんウェブブラウザでサイトに行かせるというのは、ユーザビリティの観点からもいまいちです。その際には、xAuth認証(AccessToken、AccessTokenSecretを入手する最初の時だけ、ID、パスワードを入力させる)という枠組みもあります。これを利用する際には、Twitterへメール申請が別途必要です。

2010-10-19

GWTでJSONを扱う ~JsonpRequestBuilderを利用する~

GWTでJSONPを扱う方法です。JsonpRequestBuilderを使うことで、JSONデータを自動的にクラスにマッピングしてくれます。以下のサンプルは次のJSONのデータを扱うことを前提としています。JSONPですから、外部サイトも参照可能です。
{
"name":"ochi",
"age":10,
"adress":
{"name":"Osaka"}
}
以下のプログラムは、クライアント側のプログラムです。Userクラスに自動的にマッピングしてくれます。
JsonpRequestBuilder jb = new JsonpRequestBuilder();
   jb.requestObject(
      "http://XXXXX.XXX.XXXX.json",
        new AsyncCallback<JsArray>() {
        public void onFailure(Throwable caught) {
           GWT.log("failure", caught);
        }
        public void onSuccess(JsArray<User> result) {
            StringBuilder sb = new StringBuilder();
            Window.alert("Success");
            for (int i = 0; i < result.length(); i++) {
               sb.append(result.get(i).getName());
            }
            resultArea.setValue(sb.toString());
        }
   });
ここで、注意しなければならないのは、クラスの宣言方法です。下記のように、JSNI形式でなければなりません。
import com.google.gwt.core.client.* ;
import java.util.* ;

final public class User extends JavaScriptObject {

  protected User(){
  }

  public native java.lang.Long getId()/*-{
     return this['id'];
  }-*/;

  public native Address getAddress()/*-{
     return this['address'];
  }-*/;

  public native java.lang.String getName()/*-{
     return this['name'];
  }-*/;

  final static public class Address extends JavaScriptObject {

    protected Address(){
    }

    public native java.lang.String getName()/*-{
       return this['name'];
    }-*/;

  }
}
このようなクラスを記述するのが手間ですが、実は作成を支援してくれるサイトがあります。
 JSONの雛形データをいれるとこのフォーマットに変換してくれるとても素敵なサイトです。(こういう世のためになるサイトを作りたいですね)

(追記:2010/10/22)
***.gwt.xml ファイルには
<inherits name='com.google.gwt.jsonp.Jsonp' /> 
の記述が必要です。

GWTでJSONを扱う ~JSONParserを利用する~

GWTのクライアント側で、JSONのパースを行う方法です(この方法はあまり使われないかもしれません)。
下記は、testjsonという文字列にJSON形式のデータが入っているという前提です。
最終的にJSONStringに変換してその値を取り出しています。なんかまどろっこしいですよね。

なお***.gwt.xml ファイルには
< inherits name='com.google.gwt.json.JSON' />
の記述が必要です。

2010-10-07

[C++/CLI] UDPプログラミング

UDP送信プログラムのメモ書きです。下記のサンプルは、サーバー側でテキストボックスの内容を送信しています。

送信側(サーバ)
int groupPort = 11000;
IPEndPoint ^groupEP = gcnew IPEndPoint(IPAddress::Parse("255.255.255.255"), groupPort);
//ブロードキャストの場合
//groupEP = gcnew IPEndPoint(IPAddress::Broadcast, groupPort);
groupEP = gcnew IPEndPoint(IPAddress::Parse("192.168.1.28"), groupPort);

Socket ^socket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);
socket->SetSocketOption(SocketOptionLevel::Socket, SocketOptionName::Broadcast, 1);
socket->SendTo(System::Text::ASCIIEncoding::ASCII->GetBytes(textBox1->Text), groupEP);
受信側(クライアント)
Socket ^listener = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram,ProtocolType::Udp);
IPEndPoint ^localEndPoint = gcnew IPEndPoint(IPAddress::Any, 11000);
listener->Bind(localEndPoint);

EndPoint ^ep = gcnew IPEndPoint(0,0);
System::Diagnostics::Debug::WriteLine("Ready to receive…");


array<Byte> ^data = gcnew array<Byte>(1024);
int recv = listener->ReceiveFrom(data, ep);
String ^stringData = Encoding::ASCII->GetString(data, 0, recv);
System::Diagnostics::Debug::WriteLine(stringData);
listener->Close();


2010-10-06

2010年 第21回教育システム若手の会(misokatsu2010)開催概要

テーマ:教育システム研究のこれから

内容:今回で21回目を迎える教育システム若手の会では,「教育システム研究マップ」を作り,自分たちの研究を位置づけていくことを通して,教育 システム研究のこれからを考えるディスカッションを企画しました.それに加えて,1日目の午後には,若手の研究発表(リサーチセッション)を設け ることで,若手自身の研究について学生や若手研究者同士で議論する機会を新たに企画しました.

研究についての発表やディスカッションを通して,自分の研究と他の人の研究を相対比しながら,今後の教育システム研究について考えていきます.
また,若手の会に参加する年齢層が広くなってきたこともあり,20代の院生を中心とした若手と,30代の教員を中心とした中堅とに分けてディス カッションすることで,視点の違いなども感じられるように考えています.


日時: 11月5日(金)~7日(日)

場所: 観光旅館 柏屋
〒470-3235 愛知県知多郡 美浜町野間字畑中45番地
http://www.mihama-s.or.jp/kashiwaya/

対象者: 教育システム関連の若手研究者(自称も含む)及び学生

スケジュール概要:

5日(金)
15:00-18:00 リサーチセッション(研究発表&議論)
夕食
20:00-22:00 開会のあいさつ,自己&研究紹介

6日(土)
9:00-9:15 議論のテーマについて説明
9:15-10:20 セッション1:『自分たちの研究について整理・分類』
10:30-12:00 セッション2:『教育システム研究マップの作成』
昼食
13:00-14:30 セッション3:『教育システム研究マップの融合・マッピング』
休憩
14:45-16:45 セッション4:『次なる研究の位置づけ』
17:00-18:00 全体セッション『成果発表&議論』
夕食
21:00-    ナイトセッション・エンドレスセッション

7日(日)
朝食・部屋の片づけ
9:30-10:00 クロージングセッション
移動
12:00-    味噌カツパーティー
解散

補足:セッション1,2では,若手グループと中堅グループに分けてセッション.


後援: 人工知能学会 先進的学習科学と工学研究会(予定)
電子情報通信学会 教育工学研究会(予定)
日本教育工学会
教育システム情報学会


参加申込はWebからできます。
http://www.watanabe.ss.is.nagoya-u.ac.jp/wakate2010/index.html


幹事:広島大学    倉山 めぐみ
関西大学    遠海 友紀
京都外国語大学 村上 正行
名古屋大学   林 佑樹
名古屋工業大学 立岩 佑一郎

問い合わせ先:
プログラム幹事:京都外国語大学 村上 正行
会場幹事:名古屋工業大学 立岩 佑一郎
問い合わせ用メールアドレス:
misokatsu@watanabe.ss.is.nagoya-u.ac.jp

========================================

2010-10-02

Java Logging API ~まずはSystem.out.printlnから脱却しよう~

ここでいうログとはシステムが出力するログのことで、
  • 利用状況のログ
  • 動作確認のログ
  • エラーログ
などがあります。プログラミングの際には標準出力(System.out.println等)やファイル出力などで行うことがあると思いますが、上述のようなログの目的であればロギングツールの利用を勧めます。代表的なロギングツールには
  • Log4J
  • Java Logging API(Java標準)
があります。後者はJava標準ですので、ここではJava Logging APIを扱います。
 
このようなLoggingツールを利用する理由ですが、
  1. ログ情報であるということが明示的になる
  2. ログの目的に応じたレベル設定ができる
  3. 各種ログ生成のためのツールが揃っている
などが挙げられます。もちろん自前で用意してもいいのですが、このようなライブラリには「ロギング」についてしっかりと考えられて作られてますから、中途半端に自作するよりはましであることがわかると思います。また、この種のライブラリやフレームワークを利用する方が第3者が可読しやすいコードが書けるというのもあります。

ログのレベル
以下の7種類が用意されています。
  1. FINEST
  2. FINER
  3. FINE
  4. CONFIG
  5. INFO ・・・ 情報
  6. WARNING ・・・ 警告
  7. SEVERE ・・・ 致命的
通常はINFO以下の3つの段階を利用します。

Java Loggin APIの使い方

以下のような記述をします。
Logger log =Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
log.info("プログラムを実行します");
log.warning("警告メッセージです");
log.severe("致命的なエラーが発生しました");

ログのレベルに対応した出力メソッドがありますので、使い分けることになります。これだけでは便利さが分かりにくいかもしれませんが、実行時にログの出力レベルを設定することで、重要なメッセージだけを出力できるようになります。例えば、動作確認はINFOレベルでありデバッグ時に確認するさいに使われるものです。稼動時には、WARNIGやSEVEREのみを出力するといったことが可能です。また、System.out.printlnよりはどういう意味であるのかが明示的になり、コードが読みやすくなります。

2010-10-01

無名クラス、匿名クラスを理解する

GWTのRPCを利用するときに、無名クラスの記述がでてきます。Javaに慣れていない人にはわかりにくいところですので、無名クラスについて取り上げます。
例えば、以下のようなインタフェースが定義されていたとします。このインタフェースには2つの抽象メソッドが定義されています。抽象メソッドですので、定義されているのは名前だけで、実際の内容は実装するクラスで書く必要があります。
interface Callback {
  void onSuccess();
  void onFailure()
}
つづいて、このインタフェースを実装するクラスを作成します。必ずCallbackインタフェースで定義されているメソッドを定義しなければなりません。
class TestImpl implements Callback{
  void onSuccess(){
   //ここに何かかく
  }
 void onFailure(){
   //ここに何かかく
  }
}
そして、実際に利用するときには、下記のように書くことになります。
このようにクラスのインスタンスを生成することで、onSuccess等のメソッドを呼び出すことができます。
Callback test = new TestImpl();//あるいは右のような書き方でもよい TestImpl test = new TestImpl();
test.onSuccess();
上記のクラスを宣言する手間を省けるのが無名クラスです。以下のように省略することができます。
Callback test = new Callback{
  void onSuccess(){
   //ここに何かかく
  }
 void onFailure(){
   //ここに何かかく
  }
}
何が省略されているかわかりますか?インタフェースクラスは、直接newすることはできませんが、このようにnewしながら中身を定義することで、newされるものは Callbackインタフェースを実装した何か?(つまり無名のクラス)になります。だから、インタフェースで受け取ることができます。

UIBinderにて画像を表示する ~Imageタグ~

UiBinderを利用して、画像を配置するには、Imageタグを使います。



あるいは、Java側で処理することも可能です。
userIcon.setUrl("ochi.png");
画像ファイルは、webのディレクトリに配置してください。


なお、ImageResourceクラスを利用する方法があるらしいのですが、まだ未確認なのでこの方法で。確認次第、アップします。

2010-09-30

UiBinderにてCSSの設定をする

ウェブアプリケーションでは、ページのデザインにCSSを利用するのは常識なわけで、UiBinderでも当然利用することができます。

        .important {
            font-weight: bold;
        }

  
基本的な記述方法は上記のようになります。呼び出し方に注意してください。また、設定するCSSはfield属性を設定することで、呼び出しのクラス名を変更することができます。以下は、MyStyleという名前を独自に付けています。

        .important {
            font-weight: bold;
        }

  

CSSの思想はデザインと画面設計を分離させることですから、UIBinderでも従来同様、CSSのスタイル情報を独立させて外部ファイルとして呼び出すことも可能です。src属性を利用します。もちろん、fieldの指定も可能です。



  


2010-09-28

GAEのお勉強に良いサイト~App Engline Code Lab~

GAEについては、本研究室でもジワジワと使っていこうと思っていますが、良いサイトがありますので、、、
このサイトでは、BLOGシステムを作成するという目標のもと、GAE周りの周辺技術の使い方をマスターすることができます。ただし、漠然とコピペして作るだけではまずいです。いろいろ疑問点が出てくると思いますが、これを起点に理解すればいいかなと。うちの研究室でもこれをちょっとやってみようかなと思ったり、、、、個人的には、この教材をGWT化したいなとか、、

2010-09-27

EclipseでSubversionを利用する

Netbeansだけでなく、Eclipseも併用することが増えてきそうなので、とりあえずメモ。なお、この記事を書いているのは、3.6(Heliosを想定)です。

ポイントとして、Subversionを使うには2つのプラグインをインストールする必要があります。
  • SubversiveというSVNクライアント
  • SVNコネクター
Subversiveのインストール
プラグインのインストール方法と同様に、Help -> Install new softwareからインストールします。 URLはEclipseのプラグインサイトです(バージョンに注意)。
http://download.eclipse.org/releases/helios 
です。


  • Subversive SVN Team Provider (Incubation)
  • Subversive SVN JDT Ignore Extensions (Optional)
をインストールします。後者のほうはいらないかもしれません。

SVNコネクターのインストール
SVNコネクターは同様の方法でプラグインを探し出してもいいのですが、上記URLにはありません。一番手っ取り早い方法は、SVNコネクターがない状態からSVNを起動してみます。例えば、SVNレポジトリからImportするというのも手でしょう。



そうすると、SVNコネクターを入れろという画面がでてきます。最新版を選択。



すると、プラグインのインストール画面がでてきますので、いつものようにプラグインをインストールします。JavaHLはインストールしなくてよいようです。




なお、本記事は、下記のサイトを参考にさせていただきました。



2010-09-14

Netbeansでsubversionを利用する

Netbeansは、Subversionに対応しているのだが、クライアントソフトが入っていない。32bit版だと自動的にプラグインをとってきてくれるらしいが(未確認)、64bit版では自分でインストールする必要がある。条件としてコマンドラインで動作するSubversionでなければならず、いちおう、Netbeansが推奨するクライアントソフトがあるが、そこはユーザ登録する必要があるため、なんか面倒。。。

というわけで、ユーザ登録の必要のないSubversionクライアントを探して発見。Slik Subversionというやつだ。64bit版も用意されている。64bitのNetbeansを使ってる人はお試しあれ。

2010-09-10

C++/CLIを辞めるべきか、、、

表題の通り、C++/CLIを辞めるべきか、、、悩んでます。もともとうちの研究室は、MFCで書いていたのですが、昨今、MSが.NETフレームワークに重点を置いている点と、開発効率のしやすさを考え、.NETベースの言語に切り替えようと昨年からジワジワとC++/CLIに移行してきました(お勉強としてはもっと前からやってましたが)。このBLOGでもC++/CLIの記事がいくつかあると思います。そもそもC#ではなくC++/CLIを選んだのは学科の特徴から、C++系のほうがいいかなーという感じだったんですが、先日、VisualStudio2010をインストールして愕然としました。「Intellisenceが働かない」。まさかと思い、ネットをググッてみますと、対応していないという話が続々と出てきました。

Intellisense、、、いわゆるコード補完が働かないというのは、死に近いんじゃないでしょうか? SP1で対応するんじゃないか、、、という話も出てますが、そういうのは待ってられません。2008までは対応しているので、しばらくはそれでごまかしても良いですが、雰囲気的に、「C++/CLIは主流じゃないのでは?」という気がしてきました。また、C++/CLIについてのよくある誤解 というBLOG記事に書いてあるように、C++/CLIはネイティブCとのラッパー的な役割に徹したほうがいいのかなという気がしてきました。

まあきっと、時間が経てば対応するとは思います。ただ、主流ではないのは間違いなく、また言語としてのわかりにくさもあることから、研究室での導入は限定的にするべきかなと思ったりしてます。ただ、研究室での開発言語はなるべく増やしたくないんですよね。学生が対応しきれませんから。。。。難しいところです。

そんなわけで、このBLOGでもC++/CLIは緩やかにフェードアウトしそうな雰囲気です。

GWT:RichTextAreaを利用する

GWTにはリッチテキストエディターが存在するが、実際にこれを使おうとしたらフォントの設定などの処理をおこなういわゆるツールバーの記述をすべて自前で書く必要がある。これは面倒なわけだが、リッチテキスト用のツールバーのライブラリが存在するのでその利用を含めて使い方を紹介する。

RichTextToolBarクラス(GWT ShowCase版)
GWTのShowCaseで動いているリッチテキストエディターがある。これはApache2.0ライセンスで公開されているので、基本的にこれを使えばよい。ただ、各種操作ボタンの画像などもあわせて取ってくる必要がある。

RichTextToolBarクラス(Erik Scholtz版)
Erik Scholtz  氏が公開しているRichTextToolBarクラス。彼のBLOGにて公開している。また同じものが、GoogleCodeにも公開されている。

どちらも使い方は同じで、制御したいRichTextAreaのインスタンスを宣言時にコンストラクタの引数として渡せばオッケイ。
なお両者の違いだが、後者のErikのクラスはアイコン画像ファイルをErikのサイトからダウンロードする形になっています。ソースを見てもらえばわかりますが、アイコンをまとめたファイルを一気にとってきてそれを分割して各ボタンに割り当てています。こっちのほうがダウンロードして即使えるという利点がありますね。

参考までに、UIBinderでの記述例を以下に載せます。

(~.ui.xmlファイル)







サブジェクト
OKCancel

(~.javaファイル)
@UiField
RichTextArea rtext;
@UiField
SimplePanel  tbar;

RichTextToolbar toolBar = new RichTextToolbar(rtext);
tbar.add(toolBar);


このように記述するだけで、ちょっとしたリッチテキストエディターの完成です。


なお、本サイトの掲載内容は、www.keicode.comさんの「書式付入力ボックス ~ RichTextArea の利用」を参考にさせていただきました。

2010-09-07

.NETフレームワークにおける言語間の連携について

マイクロソフトは、.NETフレームワークを採用して以来、提供していた各開発言語を全て.NETフレームワークに対応させている。C++、C#、VBの各言語はネイティブコードではなく、共通した中間コードを出力することになったわけだ。これにより、各言語でライブラリの共通化がはかられ、どの言語においてもほぼ同じ名前のパッケージやクラス、メソッドを呼び出すことになる。

これは自作ライブラリについても同様のことが言えて、他言語で自作したライブラリを容易に呼び出すことができる。従来の.NET以前の言語でも、C++のライブラリをVBで呼び出すことは可能であったが、それとは全く次元の違う手軽さで、連携させることができる。具体的にいえば、一つのソリューションの中に、異なる言語のプロジェクトを混在させ、特別なインタフェースを記述することなく、他言語で呼び出すことができる。
以下、例として、C++のプロジェクトからC#のクラスライブラリを呼び出す方法を紹介する。

C#側
呼び出されるクラスライブラリを作成しておく。特別なことは必要なく、.NETのコンポーネントクラスとして作成しておけばよい。

C++側
.NETのC++、つまりC++/CLIのプロジェクトを作成する。MFCのプロジェクトからは呼び出すことはできないので注意。

以上、2つのプロジェクトを同一のソリューション内で開いておいてください(ソリューションを右クリックして既存のプロジェクトを追加しておく)。

呼び出すC#のプロジェクトを参照に追加する
ここが一番のポイント。C++のプロジェクトを右クリックし、参照を選択する。


 「新しい参照の追加」ボタンをクリック。
 プロジェクトのタブを選択し、呼び出したいC#のプロジェクトを選択し追加。 
以上の設定により、C#で作成したライブラリをC++で呼び出すことができる。

今回、ツイッタークライアントのプログラムをC++/CLIで作成しようとしてサンプルがなく、C#で書かれているサンプルを元に書き直すしかないのか、、、と思っていて結論としてこの方法を採用することにしました。C++/CLI側から全く違和感なく利用できるというのは大変魅力です。本研究室では、MFCとの親和性からC++/CLIを中心言語としていますが、C#をもっとうまく取り入れれば開発効率が上がるかも、、、と感じました。
注意事項
原則として、どのようなクラス(型)でも気にすることなく、C++側で呼び出し可能です。ただし、C#側でrefとかoutといった参照渡しをするようなメソッドがあれば、その呼び出し方は注意が必要です。ここでは書きませんが、C++側での記述にちょっと細工が必要なようです。


2010-08-23

GWTで時間表示

Javaにおいて、時間表示をする際には、
  1. Dateクラスで現在時間を入手
  2. SimpleDateFormatクラスで、表示フォーマットを決定

といった手順をとるのが手っ取り早いが、GWTではSimpleDateFormatが使えない。そこで、com.google.gwt.i18n.client.DateTimeFormatクラスを利用しよう。
詳細は、JavaDocを参照のこと


GWT:UIBinderにてDiv,Spanタグを使う

GWT:UiBinderでは、com.google.gwt.user.client.uiで定義されたタグを配置することができますが、純粋なHTMLのタグを埋め込むことも当然可能です。そして、それに対してもUIBinderに対応づけることができます。具体的には以下のような記述になります。

ui.XMLファイルの記述
Java側での記述
@UiField
DivElement div1;
@UiField
SpanElement span1;
このようにui:fieldで名前を定義することで、Java側でも呼び出すことができます。

2010-07-25

オープンキャンパスで研究室紹介

オープンキャンパスにて研究室紹介の担当になったので、1日デモをやってました。とりあえず一番わかりやすいネタがいいだろうということで、いろいろやっているプロジェクトのひとつでありる、「映像・画像処理技術を利用した教育情報システムの研究開発」をテーマとしました。こういうのをやるのははじめてで、正直、ちゃんとできるのか心配だったのですが、無事終えることができました。

下の写真は、リラックマ人形を認識させる簡単なデモで、これを教育にどう応用するかを話しました。



下の写真は、「指示棒を利用したカメラ制御」の図です。きちんと動作し、ウケもよかったですね。
あと、音声認識でカメラ制御をするデモもやり、これもうまくいきました。



今回は、 開放している5時間の間に90名超の来訪がありましたが、問題なくシステムが動作したのはよかったです。

やっぱり、こういう特別なイベントだけでなく、いつでもデモができる環境を用意しておくべきだなと感じました。そうすることで、卒研やっている学生にも、自分の開発しているシステムが、どう反映していくのかがみえてきますしね。
それと、こういうデモをきっかけにシステム開発に鞭を打つというのもいいアイデアではないかと。以前の職場でそれをやってましたが、今は鞭を打たれるのは学生ではなく僕自身なわけですが、、、、
まあとにかく、この手のイベントのタスクは前向きに活用していきたいなと。

来訪者の皆様、関係者の皆様、補助してくれた陰性のU君、ありがとうございました。

Netbeans6.9でGAEのプラグインを使う

NetbeansでGAEを使うためには、nbappengineというプラグインを使えば良いわけだが、これはデフォルトのライブラリサーバーには存在しないので、Kenaiにあるプロジェクトサーバーを登録する必要がある。で、ここのライブラリURLが、6.8と6.9で異なっているようで、でそのURLは
  • http://kenai.com/downloads/nbappengine/NetBeans69/updates.xml
と6.8の場合と微妙に表記パターンが異なっているようだ。

今日、こういう初歩的なことをBLOGに書いたのは、研究室のマシンでNetbeans6.9にしたらGAEが動かなくなったというのがある。6.9に6.8のライブラリを入れると、プロジェクト作成時にエラーがでるようなので(実際ほんとうにそうなのかは確証できませんが)、気をつけてほしい。

2010-07-21

教育改善のためのティーティングポートフォリオ

今日は、学内のFD研究会で加藤由香里先生@農工大をお招きし、表題の件についてご講演いただいたので、その件についてメモ書き。

ティーティングポートフォリオとは
今までティーティングポートフォリオ(TP)というのが今までピンと来なかったのだが、今回の話を聞いて分かってきたというのが第一の印象。TPの目的というのは、
  • 授業改善のための振り返りの資料
  • 教員(教育)実績評価のためのエビデンスとしての資料
の2つの面がある。後者はけっこう生々しい話になるが、TPの海外でのきっかけはこの後者の話のようだ。前者については、自分のためというだけに考えると費用対効果に疑問がでてくるが、それを共有し組織だてて改善していくという視点で考えると面白い話になってくる。

FDとしてのポートフィリオ作成
ミニワークを通して、ポートフォリオの作成を行なわれました。具体的には以下の項目について。
  1. ふりかえり(どのように)
  2. 方法から理念を確認(どうして)
  3. 改善(どうかわったか?)
特に若手の場合は、がむしゃらに試行錯誤で講義をしているケースがおおいので理念というのが後回しになりがち。そういう点でこの手順は面白かった.

ちなみに 本学の先生には、2の部分が納得いかなかった方がいたようだ。「教育理念なんか持ってて当たり前だろう」と、、、「方法から理念を考えるなんておかしいのではないか」と、、、まあそれは正論なわけで、若手はそこを認識する余裕がないケースが多いんですよ、、、とあとで説明はしておいたのだが、、、、

TPをつくってみようかな
個人的に、TPを作ってみようかなと思ったり。もともとポートフォリオには興味があったのだけど、どちらかというと学習者側の視点に意識が向いていたので、、、あと、本学はJABEE等でそれなりの資料を残しているわけだから、これをTPとしてとらえて、管理するシステムなどがあると面白いかも。

2010-07-08

OpenCV2.1をWindowsで利用する

以前の記事、OpenCV2.0をWindowsで利用するの続編です。

前回の時は、Cmakeを利用して各種ファイルをコンパイルする必要がありましたが、 今はそんなことをしなくてもいいよいです。公式サイトの中に
  •  OpenCV-2.1.0-win32-vs2008.exe
 というファイルがあります。これを使えば、CMakeでコンパイルする必要はないようです。

なお、
  • ヘッダ:c:\OpenCV2.1\include\opencv
  • ライブラリ: c:\OpenCV2.1\lib
  • DLL: c:\OpenCV2.1\bin
に存在します。また、Debug用ファイルにはdという接尾語がついてます。(例:cv201d.lib) DebugとReleaseにあわせて適切に設定したほうがよいでしょう。

このインストールファイルは、vs2008用のような名前ですが、VS2010でも使えます。ネットでは、2005でも動くと書かれています。

まだ本研究室では2.0系はまともに動かしてないのですが、いつまでたっても1.0系というのはどうかと思うのでー。今年から徐々に2.0系に乗り換えようかと思います。

[C++/CLI] Visual Stdio 2010でのライブラリ設定について ~OpenCV設定を題材に~

Visual Stdio 2010になって、各種ライブラリやインクルードのディレクトリ設定の方法が変わっているようなので、メモ書きです。なお、今回はOpenCV1.0を題材にしてます。

変更点
【ツール】の【オプション】でのVC++ディレクトリの編集は奨励されなくなりました。プロパティシートを使えと言われます。

プロパティシートとは
各種設定情報を、プロパティシートというファイルに保存する形式を採用したようです。このことにより、
  • ライブラリ設定情報を各プロジェクトで共有できたり切り替えが容易になる
という利点があります。

設定手順

1.プロパティマネージャーを表示



2.プロパティシートを作成します



3.好きなファイル名を入れてください。



4.プロパティマネージャーにあるプロジェクトをひらくと、さきほど作成したプロパティシートが追加されています。(下記の例では、opencv)





5.opencvをダブルクリックすると、プロパティの編集ができますので、各項目を適切に設定しましょう。



なお、今回はプロパティを追加しましたが、既存のプロパティシートの設定を再利用する時は、2のところで、【既存のプロパティシートの追加】を選んでください。






2010-07-05

【C++/CLI】OpenCVでのBitmapとIplImageへの相互変換

OpenCVを利用する際には、画像を扱う構造体がIplImageなわけだが、C++/CLIで利用する際の扱い方のメモ。基本的に、C++/CLIでは Bitmapクラスなわけなので、両者の変換をどうするか?ということになるが、
  •  IplImageへの変換は、IplImageのimageDataのメンバ変数に画像のアドレスを渡す
  • Bitmapへの変換は、 、IplImageのimageDataが指しているアドレスを渡す

というのが基本になります。下記は例ですが、通常のC++/MFC or Win32でのやり方とそんなに違いはないということがわかります。
Bitmap -> IplImageへの変換
private: IplImage* GetIplImage(Bitmap^ bitmap)
    {
     //IplImage *img = 0;
     Drawing::Imaging::BitmapData^ bd;

     IplImage *img = cvCreateImage(cvSize(bitmap->Width, bitmap->Height), IPL_DEPTH_8U, 3);

     bd = bitmap->LockBits(
      Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height),
      Drawing::Imaging::ImageLockMode::ReadOnly,
      Drawing::Imaging::PixelFormat::Format24bppRgb
      );

     memcpy(img->imageData, bd->Scan0.ToPointer(), img->imageSize);

     bitmap->UnlockBits(bd);
     return img;
    }


IplImage -> Bitmapへの変換
private: Bitmap^ GetBitmap(IplImage* src_img){
    
     Bitmap^ bmp = gcnew Bitmap(src_img->width, src_img->height, src_img->widthStep,
      System::Drawing::Imaging::PixelFormat::Format24bppRgb, IntPtr(src_img->imageData));
     return bmp;     
    }



2010-06-21

GWTでのXML処理 ~Namespaceありのノードを読み込む問題~

現在調査中なのだが、GWTのクライアント側で、com.google.gwt.xml.clientパッケージ下のXMLライブラリを使う場合、Namespaceの処理ができない?という結論に至っている。厄介なのは、
  • getElementsByTagName()メソッドで、NamespaceのPrefixを付け足しすとそのノードを導けない
  • getNamespaceURI ()メソッドは有効になっている
つまり、ノードとしてはNamespaceを区別しているんだけど、呼び出し等のメソッドが対応していないと。 。。

では、どうすればいいのかというと、
  • getElementsByTagName()の引数は、Namespaceは無視してタグ名だけを記述する
 ということ。

もし、同一名称のタグが存在するのであれば、その区別をする必要があるので、その場合は、
  • getPrefix()でNamespaceのPrefixがとってこれるのでそれを比較する
というなんか情けないことをするしかないようで、、、、、これは、JavaScriptのXMLパーザーの仕様が関係しているのでしょうか?ちょっと個人的には信じられない仕様なので、今後も調査を継続したいところです。


個人的なつぶやき

  • getNamespaceURI ()があるのに、なんでsetNamespaceURI ()がないのか、、、
  • GWTの開発陣営はこの点をどう考えているのかな


2010-06-15

UIBinderで各種Widgetを使ってみる~ラジオボタン、チェックボックス、リストボックス~

各種標準WidgetのUiBinderのXMLの記述方法について、現状把握していることを書いてみます。情報が少ないので、ちょっと間違っているかもしれません。とりあえずの参考にしてください。

リストボックス
項目をxmlで定義する方法はわかりませんでしたが、下記の記述でリストボックスの配置はできますので、あとはJava側で書けばよいかと、、、


ラジオボタン
  • FormPanelの子要素として存在しないといけないようです。
  • ラジオボタンのグループはnameで指定します。
  • Javaからアクセスするためには、ui:fieldを指定します。
  • Java側からは、ラジオボタンの選択部分はgetValue()で入手することになります。

 
 りんご
 オレンジ
 
 
チェックボックス
ラジオボタンのようにformPanelの子要素にしなくてもできました。下記のような項目を複数並べてgetValue()で選択されているかどうか取り出すことができます。
Labo
正しい使い方がわかり次第、随時、修正していきます。また、別のWidgetについても取り上げていきます。

2010-06-10

C++/CLIでHTTPアクセス

以前、ツイッタークライアントの記事で書いた内容と同じですが、C++/CLIでHTTPアクセスする方法として2つ書いておきます。

HttpWebRequestを使うならこちら
    String^ result;
    String^ url = "ここにURLを書く";

   //IDとパスワードを設定するならここで
    NetworkCredential^ nc = gcnew NetworkCredential(id,password);  
    try{
      HttpWebRequest^ request = (HttpWebRequest^)HttpWebRequest::Create(url);
      request->Credentials=nc;
      WebResponse^ response = request->GetResponse();
      StreamReader^ reader =     gcnew StreamReader(response->GetResponseStream());
      result = reader->ReadToEnd();
      reader->Close();
      response->Close();
  }catch(System::Net::WebException^ e){
        //ここでなんらかのエラー処理をする
        System::Diagnostics::Debug::WriteLine("エラー:"+ e->Response->ToString());
        return "";
    }


WebClientを使うなら、こんな感じです。
    String^ result;
    String^ url = "ここにURLを書く";
      try{
        WebClient^ client = gcnew WebClient();
        client->Credentials = nc;

        client->Encoding = Encoding::UTF8;

        array^ data =client->DownloadData(url);
        String^ result =Encoding::UTF8->GetString(data);
        return result;

    }catch(System::Net::WebException^ e){
        //ここでなんらかのエラー処理をする
        System::Diagnostics::Debug::WriteLine("エラー:"+ e->Response->ToString());
        return "";
    }


GWTのUIBinderでコンポーネント化を試みる

GWTのUIBinderは、ただ単にUIの記述が楽になると言うだけでなく、UIの部品化(コンポーネント化)を容易に実現することができます。 具体的に言えば、UIBinderにて設計したインタフェース部分は、また別のUIBinderのところで呼び出すことができます。
例えば、あるページの本体構造を定義するMainFormのUI定義ファイルを以下のように定義されていたとします。

MainForm.ui.xml
    
        header
        
            left
            center
            right
        
    
こ の例では、「heder」の領域とその下に、「left」「center」「right」にエリアが並ぶことになります(便宜上、ラベルを配置しています が、、、)。

このヘッダ領域に表示する内容を別のUIBinderで下記のように設計したとします。
HeaderArea.ui.xml

    
    
    
        

試作システムのヘッダ


このようにUIBinderで定 義したUIを一部は、下記のようにすることでMainFormに記述することができます。

MainForm.ui.xml(変更後)

    
    
    
        
        
            left
            center
            right
        
    


こ のように、定義したUIBinderのクラスのパッケージをimportによりXMLのNamespaceに関連付け、利用するクラス名をタグ名として記 述することで、呼び出すことができます。こ れは、インタフェース部分の分業をはかる際に非常に強力になりますので、そういった意味でもUIBinderはおすすめだと思います。

2010-05-17

GWTでSVGを利用する

HTML5の流れで、SVGが再び陽の目を見るようになってきました雰囲気になってます。で、HTML5へのGWTの対応が気になるところですが、今日は、GWTでSVGを扱うライブラリについて紹介します。

Vectormaticさんのところにあるlib-gwt-svg というライブラリーです。
http://www.vectomatic.org/lib-gwt-svg

ライブラリの使い方ですが、設定として
  • lib-gwt-svg-0.4.jar をダウンロードしてクラスパスへ
  • gwt設定ファイル(~.gwt.xml)に以下の記述を追加
以上の作業をおこなう必要があります。あとの使い方については、APIのJavaDocに書いてあるわけですが、サンプルデモが参考になります。ソースコードとあわせてみることができるので、使い方がだいたいつかめます。

このライブラリがいいのは、UIバインダーに対応しているところです。これはなかなか頑張っていると思います。興味がある人はぜひお試しください。

2010-04-22

GWT2.0 のUIBinderを試してみた(その2)

前回の記事以降いろいろ試行錯誤してわかってきたことがあるので、訂正も含めて改めて書きます(あの記事はなかった事にしてもらっても結構ですw)。Netbeansでは、最新のプラグインを入れていればUIBinderに対応しているので簡単に作成することができます(Eclipseでも同様です)。

UIBinder関連ファイルの作成
【新規ファイル】→【GWT UIBinder】を選択することで、xmlファイルとJavaファイルが作成されます。
XMLファイル
ここでは、ボタンを配置してみます。htmlPanelがベースになっていますので、そこに下記のようにボタンを追加します。

 

 
 
            ボタンー
 


Javaファイル
ここでは、ボタンにイベントを記述しています。

public class NewUiBinder extends Composite {
    private static NewUiBinderUiBinder uiBinder = GWT.create(NewUiBinderUiBinder.class);

    interface NewUiBinderUiBinder extends UiBinder<widget, newuibinder=""> {
    }
    @UiField
    Button btn1;
    
    @UiHandler("btn1")
    void onClick(ClickEvent e) {
        Window.alert("ボタンが押されましたー");

    }


    public NewUiBinder() {
        initWidget(uiBinder.createAndBindUi(this));
    }
}
上記のJavaファイルのポイントは2点。
  • @UiFieldアノテーションで、xmlで定義したwidget要素と関連付ける。
    注意1:同じ名前である必要があります
    注意2:各変数のそれぞれこのアノテーションを書かないといけません
  • @UiHandlerアノテーションで、イベント貼付け
@UiFieldアノテーションによる記述については、特にプログラム中で呼び出しをしないのであれば、記述する必要がありません。つまり、わざわざ newでインスタンスを生成する必要がないということです。@UiHandlerアノテーションを利用したでのイベントの割り当てですが、 イベントの関数名はなんでもいいです。上記の場合は別にクリックイベントを拾いたいからといってメソッド名をonClickにしているのではありません。キャッチするイベントの種類を決定するのはメソッドの引数の型です。上記の場合は、ClickEventを引数の型にしているので、btn1に対するClickEventを拾っているのです。

最後、上記の方法で定義したWidgetの呼出し方法ですが、
final NewUiBinder uib = new NewUiBinder();
 RootPanel.get().add(uib);
というように、普通にWidgetを張り付ける方法でオッケイです。

以上のように、プラグインが自動生成するファイルを利用することで、効率良く開発することができます。UIBinderは必須の機能ですね。

2010-04-10

第1回 Google Web Toolkit 勉強会 in 京都 (#gwt_kyoto) を開催します

GWT使ってますか?このブログでも何度かGWTのことを取り上げていますが(メモ的な内容ですが)、GWTはJavaを利用して簡単にAJaxアプリケーションを作成することができる強力なフレームワークです。

以下の日時にて、京都GTUG主催の「第1回 Google Web Toolkit 勉強会 in 京都」が開催されます。

日程
日時: 2010/04/16(金) 19:00~21:00
会場: 京都リサーチパーク
定員: 40名
参加費: 無料
懇 親会: 希望があれば勉強会後に懇親会を開く予定です(参加任意)

セッション
  • GWT2.0 入門 (19:00 ~ 19:55)
発表者: 越智洋司
テーマ: GWT2.0入門
内容: GWT概要、GWT2.0の特徴、他
  • GWT2.0 応用 (20:05 ~ 21:00)

    発表者: 白山 文彦 (twitter:@fshiroyama)
    テーマ: GWTで実際にウェブアプリケーションを作成してみよう
    内容: 入門の内容を踏まえて実際にウェブアプリを作成してみます。こんなに簡単に非同期通信を使ったアプリが作れるんだということを実感していただけると思いま す。

後援:京都リサーチパーク株式会社



今回は、私も京都GTUGスタッフとして、初の発表をさせていただくことになりました。私自身、大学の研究室において、今まで、ウェブアプリケーションのフレームワークはいろいろ試行してきましたが、半年ほど前に導入して以来、GWTの開発のしやすさにすっかり陶酔している今日この頃です。

今回の勉強会では、GWTの入門的から2.0の新機能の話題までを取り上げ、また実際の開発を通してそのメリットを体験していただければと思います。

申し込みはこちらです。皆様の参加をお待ちしております~。

2010-03-24

研究推進と人材育成のポジティブな関係を考えるフォーラム に参加して

先日のBLOGネタにタイムリーなフォーラム「研究推進と人材育成のポジティブな関係を考えるフォー ラム」に参加してきました。つまり、研究室の運営をどうするかというお題な、国内初のイベントらしいです。ニーズ的にはかなり高いと思いますけど ね。とりあえず、参加した印象・感想とか書いてみます。

まず全体的な感想
正直、拍子抜けした面がありました。取 り上げられている研究室のレベルが高い。つまり悩みのレベルが高いということ。話に上がった研究室は「研究室」の体をなしている。一方、僕が期待したの は、もっと低レベルな話。低レベルってのは言い方が悪いかもしれないけど、いわゆる「講座制」の研究室ではない、教員単独の研究室体制であるとか、院生の 存在が保証されない研究室であるとか、いわゆる「研究室」という形を維持することが非常に難しい状況とか、、、話の中で「中には目的を持っていない学生が いる」、、、という話題があって笑いが出ていましたが、目的を持っていない学生ばかりだったらどうするのか?など、、、、 ちょっと否定的なこと先に書い てしまいましたが、本プロジェクトの取組や本フォーラムを否定するわけではないので>関係者の方。研究室運用の問題っていろいろあると思いますんでね。以降に期待します。

さて、本フォーラムを通 して、いろいろ考えさせられたことを以下に書いていきます。

科学と日常と教育
最初の開会挨拶で、佐倉先生(東大)の 「科学と日常はどう違うか?」という話が非常に興味深かったですね。我々のいるアカデミック(研究)な世界というのは、一般とは違った評価軸を持ち、論文 を中心にした閉鎖的な世界(自己完結した自然科学の評価システム)であるということ。ただ、アカデミックな世界は日常の部分集合であるし、日常との接点の 機会が増えてきているので、日常を無視することはできない、、、という話をされてました。僕は、そこに「教育」の位置づけを重ねて考えてみました。下の図 は佐倉先生が書かれた図(簡略表記)に、教育という面を追記した図です(黄色の部分が僕の考え)。つまり、日常と研究をつなげる役割として教育が存在する のかなぁと、、、もう少しいうと、「学生」というのは日常の世界からやってきているわけですが、大学教員というのはこの図の真中に君臨しているわけで、当 然考え方が違う。教員は、学生を真ん中の世界に引き込もうとし、その手段として教育が存在すると、、、一方、’学生は日常的な感覚で物事を捉えようとする ので、教育に対しても日常の感覚で評価しようとする。このギャップが学生の授業に対する不満を生んでいるのかなぁという気がしました。教育というものを潤 滑油にして、学生をアカデミックな世界に引き込みつつ、研究過程においてうまく日常へと戻していくことが大切なのでしょう。今は、学生をいったん引き込ん だら、卒論・修論書くまで抜け出せないようなシステムになっている気がします。



図1 日常と科学と教育の関係

チー ムワークと個人能力

鈴木先生(東大)の話で「チームワークと個人能力」というのが取り上げられましたが、うちでは研究テーマを学生個別 に与えているので、チームワーク力については正直養われてないかなぁという気がしています。チームでやると必ずやらない学生が出てきますからね。という か、できる学生とできない学生とかで進度が変わってきて、結果的にできる人がどんどんやっていくということになりがちですから。まあ、できる人がどんどん やってくれるならいいのですが、「なんで自分だけ、いっぱいやらなければならないのか?」とか言われてしまったらお手上げです。まあ、チームワークは研究 テーマではなく、非研究活動を通して学ぶような場を提供していけばよいでしょうかね。

研究室の分類
岡本さん(東 大)の話で、アンケートを通して研究室のパターンを3つに分類をしたという話があり、これは興味深かった。その3つとは、
  1. 研究業 績追求型
  2. 個人成長志向型
  3. 不活発型
なわけで、まあ名前から内容は想定できると思います。うちはど ちらかというと2かなぁ。宮野先生(京大)が、「学生のモチベーションを重視して、研究が学生のモチベーションを上げていくというスタイル」、、、の話を されていましたが、うちはまさにソレですね。うちは基本的に卒研テーマは、学生のやりたいことを尊重して決定してます。ただ、学生の考えるネタと言うのは 当然「浅い」わけで、結果的にこちらのやりたい方向にもっていきますけどね。結果として、研究業績にはなりにくいですが。。。

学生 をうまく参加させる
今回のフォーラムでは、グループワークを通して、研究室での教員、学生の役割についていろいろ情報交換をしたわけです が、学生を研究室にうまく巻き込むには、研究室内の様々なタスクに学生を参加させることが重要かなという印象でした。ただ、学生を参加させることで効率が 悪くなることもありうるわけで、正直、難しいですね。学生に完全に丸投げするというのは、院生が多く存在することが保証され、研究室の体をなしていればで きることだし。。。。

とりあえず、思うことをざっと書いてみました。本プロジェクトの動向はとても興味が有りますので、関西圏でもぜひイ ベントを、、、、

2010-03-20

2009年度卒業生をおくり出して、、、、

本日、卒業式があったので、今年1年間を振り返って思うことを書いてみます

大就職氷河期時代の研究指導スタイルとは
 4年生というのは、就職活動だけでなく、卒業研究、通常講義とやることがあります。特に就職活動は人生を決める重要なイベントなわけですから、これを最優先するというのはおかしな話ではないでしょう。もちろん大学の本分は「教育」であることは間違いないですが、就職活動というのは精神的に大きなプレッシャーになりますから、配慮は必要だと個人的には思ってます。
そんなわけで例年、前半は就活優先で、内定後、卒業研究に力を入れていく、、、というスタイルをとっていたのですが、今年はこの思惑が外れました。とにかく内定がでない。。。。例年だったら決まっているハズの時期に、まだ就活をしている。別に学生が悪いわけではないですが、これだと、なかなか卒研に取り組めません。結果的に、卒研にとりかかる時期が非常に遅れてしまいました。今までだと、就職先さえ決まってしまえば、はっきりいって卒研なんてどうでもいい通過儀式っていうのが学生の感覚でしょう。が、就職も決まらない場合は、卒研も中途半端で結局この1年間何を学んだのだろうか?、、、といった状況になってしまいます。おそらくこの氷河期は今後も続くでしょう。せめて、「就職は決まらなかったけど、研究室でシステム開発の技術ノウハウを得た」ぐらいのことはやらせておくべきだなと、研究指導スタイルの再検討したいと感じた一年でした。

どこまで教えるべきか?
これは「研究内容」とは直接関係しない、いわゆる組織におけるコミュニケーション能力の話。今年に限らず毎年感じていて、年々強く思い始めていることです。クラブ・サークルなどの活動経験の少なさが関係しているのでしょうか?こちらとしては、「ふつう、~するだろう」と思っていることをしない。「いったい何を考えてるんだろう?」と思ったりもしたこともありましたが、これは「知らない」んです。「知らない」ことを教えるのは教員の役目ですが、これは教員が教えることなのか?ということ。ちょっとオブラートに包んで書いてますのでわかりにくいですが、研究室で学生に教えることはなんなのか?これも再考したいですね。

卒業生へのメッセージ
学生には研究室で口頭で伝えましたが、ポイントを箇条書きで書いておきます。

* 卒業はゴールではない。人生はこれから。
* 淡々と仕事するな。興味を持って仕事に取り組んで楽しめ。
* 視野を世界に広げろ。
* 相談事があればいつでも研究室に来てください。


以上、4年生の皆さん、卒業おめでとうございます。

2010-03-03

GAEデータストアで条件検索(JDO利用)

以下のサンプルは、データストアにあるUserテーブルのunivIDプロパティが"1234567"という文字列であるデータを検索する例です。下記のサンプル内で一部全角の「<>」を用いてますが、半角に直して下さい。


JDOQLのフル記述の場合
//JDOのマネージャーのインスタンス呼び出し
        PersistenceManager pm = PMF.get().getPersistenceManager();
        String query ="select from org.ochilab.server.user.User where univID=='1234567'";
        List<org.ochilab.server.user.user>result=(List<org.ochilab.server.user.user>pm.newQuery(query).execute();

JDOQLのところは以下のように書くことも可能です。
パラメータ変数で記述する場合
Query query = pm.newQuery(User.class,"univID == univIDParam");
        query.declareParameters("String univIDParam");
        List<org.ochilab.server.user.user>result= (List<org.ochilab.server.user.user>query.execute("1234567");

個人的には後者がよいかと思われます。なお、条件の指定には、下記の方法でもOKです。
Query query = pm.newQuery(Users.class);
     query.setFilter("univID == univIDParam");
     query.declareParameters("String univIDParam");

条件を複数にする場合は、上記、setFilter()の条件を&&で結び、declareParameters()ならびに、query.execute()の各引数を複数にすればOKらしいです。

2010-03-01

GWT-RPCでの効率的なファイルの記述の仕方

以下の話はNetbeansの場合です。


ご存知のように、GWT-RPCを利用する場合は、3つのファイルが必要になります。(Netbeansの場合は下記のファイルが自動生成されます)


(1)サーバ用サービスインタフェース
(2)クライアント用サービスインタフェース(Asyncで終わる名前のインタフェース)
(3)メソッド実装クラス(Implで終わる名前のクラス)

この3つは関連していますので、3つともメソッドの定義を共通させておく必要があります。しかし、2については微妙に異なっていたりしますので、どうも面倒。。。。Netbeansの場合には、ある程度アシストしてくれますので、次のようにすればOKです。

  1. 最初に(1)にてメソッドを定義
  2. するとエラーができるので、右クリック操作により(2)に自動的にメソッドが定義
  3. つづいて(3)にエラーがでているので、右クリック操作にてメソッドを記述
まあ、しっかり設計していれば必然的にこの順番になるとは思いますが。あと、メソッド名の変更などは、リファクタリングで対応できます。だったら、メソッドの追加も完全に自動対応してくれてもいいような気がしますが、、、、ボクが知らないだけかな?他にいい方法がアルかもしれません。

2010-02-27

GWT+GAEでのファイルアップロード処理

とりあえず試してみたのでメモ書きです。本番環境で試してないのですが、たぶんおっけい?


クライアント側
下記のサンプルは、GWTのAPI仕様書(JavaDoc)に書かれている内容を参考にしてます。FileUploadウィジェットを用います。Formパネルの子としておかないとダメなのに注意。FileUploadウィジェットを用いれば、ファイルの選択などのGUIが用意されます。
サーバー側

下記の例では、純粋なサーブレットですが、GAEでも動かすことを前提にしてます(本番環境では試してませんが)。ポイントは、FileItemStreamからInputStreamを生成しているところでしょうか。これで、ファイルタイプに応じていろんな対応ができるはずです。
なお、Apache のCommons FileUploadライブラリを仕様してます。

上記のプログラムでは、アップロード処理が終わった後の処理について書いてませんので、そこは各自で対応をお願いします。

2010-02-25

GooglePicasa APIを試してみた

PicasaのAPIを試してみました。基本的には、Developer's Guide: Java を参考にしてます。

SDKインストールについて
Java Google Data APIs Client Libraryをダウンロードしてパスを通せばいいのですが、不足のライブラリを言われます。
  • Google-Collect
  • JavaMail
の2つを追加ライブラリとしました。前者は、DataAPIClientライブラリの中に入ってますが、JavaMailはなかったですね。

とりあえず試したのは、アルバムと写真のリストの入手です。以下のサンプルで出力している内容自体はあまり意味はありません。どんな情報が出てくるのかは、各自で試してみてください。

アルバムリストの入手 

public void getAlbumList() throws MalformedURLException, IOException, ServiceException {
 PicasawebService myService = new PicasawebService("example");         
 myService.setUserCredentials("USERID", "PASSWD");
 URL feedUrl = new URL("http://picasaweb.google.com/data/feed/api/user/USERID?kind=album");
 UserFeed myUserFeed = myService.getFeed(feedUrl, UserFeed.class);
 for (AlbumEntry myAlbum : myUserFeed.getAlbumEntries()) {
    System.out.println(myAlbum.getTitle().getPlainText());
    System.out.println(myAlbum.getId());
 }
}


フォトリストの入手
public void getPhotoList() throws MalformedURLException, IOException, ServiceException {
        PicasawebService myService = new PicasawebService("example");
        URL feedUrl = new URL("http://picasaweb.google.com/data/feed/api/user/USERID/albumid/ALUBUMID");
        myService.setUserCredentials("USERID", "PASSWD");
        AlbumFeed feed = myService.getFeed(feedUrl, AlbumFeed.class);
        for (PhotoEntry photo : feed.getPhotoEntries()) {
            System.out.println(photo.getTitle().getPlainText());
            System.out.println(photo.getHtmlLink().getHref());
            System.out.println(photo.getId());
            }
        }
    }



2010-02-23

GAEのデータストアを試してみた

GAEのデータストアについては、サンプルプログラムでは動かしてみたことはあるのだが、開発中のシステムへの利用を前提にちょっと動かしてみた。今日はそのメモ書き。。。。

ローカルでのGAE管理コンソール

http://localhost:8080/_ah/admin
でアクセスできます。データベースの中身も見れます。

データストアのIDについて
IDについてはなんでもいいのではなく、どうやら型に制約があるらしい。
  • Longクラス ← longではなくLongね
  • Stringクラス
  • Keyクラス


IDの自動生成について
いちいちIDをアプリケーション側で生成するのが面倒な場合は、GAEに任せるという手がある。

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;


参考URL


2010-02-22

GWT2.0のUIBinderを試してみた

2.0からの新機能であるUIBinderについて、試してみました。ネタ元は、本家のサイ トDeclarative Layout with UiBinderです。




ファイル構成
○○○.ui.xml 
ここで ユーザインタフェースの定義をします。Java側で呼び出す際の変数名も指定します。スタイルシートの設定も可能です。








Hello, .

○○○.java
  • UIObject を継承したクラスを宣言します。ui.xmlと同じ名前にしましょう。
  • クラス内でUiBinderを継承したインタフェース (MyUiBinder)を宣言します。
  • MyUiBinderを呼び出し、コンストラクタにてUIBindの初期化をします。
  • @UiField アノテーションにより、上記xmlファイルで定義した要素と変数を関連付けます

public class HelloWorld extends UIObject { // Could extend Widget instead
  interface MyUiBinder extends UiBinder<divelement, helloworld=""> {}
  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

  @UiField SpanElement nameSpan;

  public HelloWorld() {
    // createAndBindUi initializes this.nameSpan
      
    setElement(uiBinder.createAndBindUi(this));
  }
  public void setName(String name) { nameSpan.setInnerText(name); }
}

わかりにくいのは、UIBinderを継承したインタフェース定義のところでしょうか?このインテフェース定義は、最終的にUiBind処理の初期化に利用 されます。ここで重要なのは、 extends UiBinder<U,O>のところの2つのパラメーターです。

  • U はui.xmlファイルで記述しているエレメントのrootのタイプを記述します。
  • O@UiFields を所有するクラスを記述します。
ui.xmlとJavaのファイルの関連付け
次の 2つの方法があります。

  • ファイル名を同じにする
  • @UiTemplate("ファイル名.ui.xml") と 指定する
後者については、interface定義をするところの直前に記述すればOKです。


MainEntryPoint クラスでの記述

普通にクラスのインスタンスを生成し、Elementとしてappendするという方法になります。
public void onModuleLoad() {
        HelloWorld helloWorld = new HelloWorld();
        Document.get().getBody().appendChild(helloWorld.getElement());
        helloWorld.setName("おちくん");
     
    }

ちょっと 触ってみて感想

今のところ、個人的には正直、このUIBinderの利便性についてはいまいち整理できてなく、
  • 全部Javaでゴリゴリ 書きあげることができるGWTが好きだったので、タグを書くことになるのは個人的にはどうも、、、
  • でも、複雑なレイアウトのUIを考え た場合、Javaで書いていくのはちょっと面倒な点はある。その点、UIBinderのやり方は直感的
  • というか雰囲気的に StrutsとかJSFでやってるUIBindの方法と同じ感じか
  • ui.xmlで記述するタグに付いてはちょっと勉強が必要だけど、
  • ス タイルシートの変数も動的に変えられるというのは面白い
  • 使いこなすにはちょっと勉強する必要があるかも。ただ、壁を乗り越えたら開発効 率があがる?
なんて、いろいろ思ったりしてます。まあ、Google様を信用して今後導入していこうかとは思ってます。

2010-02-02

ランダム文字列を生成する

パスワードの初期発行の時に使えるcommonsを利用したランダムな文字列の生成サンプルです。

//commonsを使用
import org.apache.commons.lang.RandomStringUtils; 
String  string = RandomStringUtils.randomAlphabetic(20); //長さ20


2010-01-16

NetbeansでGAEのサンプルを動かしてみた

いまさらですが、Netbeansでプラグインを利用してGAEを動かしてみた。そのメモ書きです。

Java JDKのインストールと設定
Netbeans使ってる人は、必要ないと思ってる人もいるかもしれませんが要注意です。コマンドプロンプトにて
  • javac
  • java
の各コマンドが動くか確認してください。つまり、パスの設定ができているかが重要です。ここをミスるとGAEアプリの実行時にエラーがでます。

Google App Engine SDKのインストール
まずは、SDKをインストールしましょう。ダウンロードサイトはこちら

GAEプラグインの登録
デフォルトではプラグインはないので、kenaiのアップデートサーバーを登録しておく必要があります。
http://kenai.com/projects/nbappengine/downloads/download/Latest_NetBeans68/updates.xml
を追加して、Google AppEngineのプラグインを利用できるようにします。


Google App Engineのサーバー登録
GAEはJettyと呼ばれるコンテナ上で動きます。よって、Netbeansで使うサーバーとして登録します。名前は、Google App Engineとなっていると思います。

サンプルプログラムを動かしてみる
まずは、サンプルプログラムを動かしてみましょう。これが動かないと話になりませんので。で、これが動かないようだと、上述の設定のどこかを見逃していることになります。

GAEにデプロイする
プ ロジェクトの上で右クリックすると[Deploy to Google App Engine]というメニューがあります。これを使えばいいわけですが、さてどこにデプロイされるのか?その設定は、appengine-web.xml に記述します。GAEに登録しているアプリケーション名を書けばOKです。ここを設定しないと、プロジェクト名をアプリケーション名として登録しにいくよ うです(当然その名前のプロジェクトがないとエラーがでるはず)。

で、先述の[Deploy to Google App Engine]を選んで、パスワードなどを入力すればうごくはず、、、ですが、この段階で、
java.lang.IllegalStateException: cannot find javac executable based on java.home,,,,,,
というエラーが出てしまった場合、、、これは、Google App Engine SDKがjavacを認識できていないということなので、Google App Engine SDK for java のインストールディレクトリにある、bin/appcfg.cmdを編集し、

変更前:@java -cp .....
変更後:@"%JAVA_HOME%\bin\java" -cp ...
に書き換えればオッケイです。

とりあえず、上述により無事デプロイすることで動きましたので、これでやっとNetbeansで作成したアプリをGAEに移植できるかなぁ。