Translate

2013年3月28日木曜日

Dartチュートリアルを探す




Dartが何物なのか
全く知らないので

A Game of Darts—Tutorials
http://www.dartlang.org/docs/tutorials/

の頭の英文だけ翻訳してみた。

どうもここのコンテンツを理解すれば
概要がさわりだけでもわかりそうだ。

以下、翻訳したもの
#AT YOUR OWN RISKで参照してください
-----

A Game of Darts - チュートリアル集


Dartを使った素晴らしいWebアプリケーションを構築するためのガイドへようこそ。

"A Game of Darts"はチュートリアル、ターゲット(Dart言語を使ってどうやってWebアプリを構築するかの学習)、ツール、そしてAPI群をあつめたものです。順番にターゲットをフォローしても、必要なターゲットだけを選択してもどちらでもかまいません。

CやJavaのような構造化言語によるプログラム方法については既に知っている前提とします。

チュートリアル集を使用するにあたって、JavaScriptやDOM(Document Object Model)を知っている必要はありません。DOMはプログラミングの鍵であり、ターゲット2内の基本コンセプトにて学習することになるでしょう。


Dart ターゲット1:はじめに


Dartソフトウェアバンドルをダウンロードします、そしてDartソフトェアでどのツールやライブラリがあるかを発見し、Dart Editorを使って2つのアプリを動かします。


Dart ターゲット2:DartとHTMLをつなげる

Dart Editorを使って余計なものが一切ないブラウザページの上にテキストを置くだけの簡単なDartプログラムを作成します。この簡単なプログラムは、シンプルですが、DartプログラムがWebページ上でどうホストされDOMをどう操るかを確認することができます。


Dart ターゲット3:DOMへエレメントを追加する

このターゲットであつかう小さなプログラムは、DOMへエレメント追加することで発生するユーザ生成イベントに応答します。


Dartターゲット4:DOMエレメントの削除


このターゲットでは、ターゲット3をもとにDOMからエレメントを削除する小さなToDoアプリを作成します。



Dartターゲット5:共有パッケージのインストール

パッケージはプログラマはコードの組織化、共有を助けてくれます。多くのオープンソースDartパッケージは pub.dartlang.org リポジトリにホストされています。このターゲットでは1つのパッケージをインストールする手順の練習をします。





DartのWeb UIパッケージ

Webコンポーネントとテンプレートは、Webアプリ開発における次に素晴らしいアイディアです。あわせて、よりリッチで動的なWebアプリケーションを構築するためのビルディングブロックを提供します。DartチームのWeb UIパッケージで、いますぐいWebコンポーネントやテンプレートの利用を始めることができます。

ターゲット6:はじめてのWeb UI利用


このターゲットでは、Web UIパッケージのインストールからDart Editorの自動ビルドプロセスまでのロジスティックスからはじまります。
次に、Webアプリパッケージ内に変更の多いDartデータを組み込むための片方向/双方向データバインディングの使い方を紹介し、データ同期中のUIを維持するためにウォッチャーの利用を説明します。
最後に、テンプレート表現や宣言的なUIエレメントへのイベントハンドラのアタッチについて学習します。

ターゲット7:<テンプレート>の使用


このターゲットでは条件付きでUIエレメントをアクティベートするWeb UIテンプレートの使い方を紹介します。またDartオブジェクトのCollectionを元にしたUI構築のためのテンプレートループの使い方も紹介します。



ターゲット8:カスタムDOMタグの定義

Web UIパッケージ紹介の続きとして新規DOMタグ定義によるカスタムエレメントの使い方を紹介します。カスタムエレメントは、W3Cコンソーシアム提供のWebコンポーネントモデルの機能の一つです。

----
サンプルコードの一部をみたけど
JavaやCよりもJavaに近い。
型宣言は緩そうな気配..


2013年3月18日月曜日

MGWTにおけるスタイル表示方法

MGWTのProjectページに
スタイルシートの設定方法についての
Wikiページがあったので
翻訳してみました。


先に謝っておきますが、
このパートの翻訳はあまり品質が良くありません。
AT YOUR OWN RISKでの参照願います。

翻訳元:


----
MGWTにおけるスタイル表示方法
提供されているテーマの使い方や独自構築方法などを紹介します。

イントロダクション

表示の際にもっとも効果的にするために、mgwtはGWT ClientBundlesを使用します。
この文書ではGWT ClientBundlesがどうやって動作するのか説明しません、かわりにmgwtがどうやってGWT ClientBundlesを使用しているのかに焦点をあてます。

ClientBundlesについての基本的な情報は完璧なGWTドキュメントを参照して下さい:

ClientBundle


mgwtの見た目をカスタマイズするためにはいくつかの方法があります:

 1. selector obfuscationを分岐し、カスタムCSSファイルを追加
 2. mgwt cssインターフェイスを拡張し、ベースとなるCSSファイルを変更もしくは拡張
 3. デフォルトのカスタムカラーテーマを使用
 4. スタイルに影響する他のGWTメカニズムを使用

このドキュメントはカスタムテーマのローリング同様にmgwtの見た目の小さな変更をどうやって行うかについて明確にすることを意図しています。

デザインをどう見せるかについて決まっているのであれば、それらの最適化のためにClient Bundleを使用すべきです。それゆえgwt css インターフェイスとバンドル、いくつかのCSSを簡単に拡張することができます。


Selector Obfuscationの分岐

もしあなたがselector obfuscationを分岐させるならあなたはプレーンなCSSクラス名を使ってアプリケーションを表現することができます。しかし同時ににコンパイル時チェックとパフォーマンを犠牲にしています。このアプローチは素早くテストしたい場合にはよいアイディアです。

gwt.xmlファイルにこのルールを記述します:

 

設定後、このプロパティクラス名はこれ以上わかりずらい難読化されません、それらは"mgwt-Button"の様な可読なプレーンな名称になります。
CSSが処理すべきことを終了し計算し終えたら、同様にClientBundlesの使用を始めます。

CSSを使ったスタイリング:

selector obfuscationを切った後、DOM内のmgwt クライアントバンドルよりも後にCSSファイルをインクルードする必要があります、このため、スタイルをオーバライドすることができます。

これによりCSSを簡単に拡張可能となります:

//this will create a link element at the end of head 
  MGWTStyle.getTheme().getMGWTClientBundle().getMainCss().ensureInjected();

//append your own css as last thing in the head 
MGWTStyle.injectStyleSheet("yourcssfile.css");


エントリポイントへ記述してください、ただしClientBundleの使用やエンベッデッドバンドルをオーバライド使用がより効果的です。

拡張mgwt css インタフェイス

gitリポジトリに完全なスタイリング例があります。


この方法で、簡単にウィジェットをオーバライドして気の向くままにスタイリングを行うことができます:


1. ClientBundleマッチングの拡張
2. 適当なgetter(例:getButtonCss())をオーバライド
3. 最初にベースCSSをアノテート+カスタムCSS
4. バンドルを返却するMGWTThemeのカスタム実装を記述
5. テーマをデフォルトとしてセット、もしくはカスタムWidgetのコンストラクタを通す

GWTはCSSファイルを記述するためのインタフェイスを使用します。mgwtにおいても怒鳴時アプローチを使用しています。Widgetごとに(重要)1つのCSSインタフェイスと(少なくとも)1つのCSSファイルがあります。CSSインタフェイスやCSSファイルは1つのバンドルと一緒に運ばれます。どのCSSファイルがどのインタフェイスのために使用するかを簡単にアノテートします。MGWTは、異なるプラットフォームのために、異なる(イメージを含む)バンドルを保有しています。これは、iOSアプリ内にはAndroidに特化したCSSが無いことを意味しています。

現在7つの異なるBundleが存在します:

 iPhone (非 Retina ディスプレイ)
 iPhone (Retina ディスプレイ)
 iPad
 Android 携帯
 Android タブレット
 Blackberry
 デスクトップ

MGWTColorBundleNonRetinaの例をちょっと見てください:


 public interface MGWTColorBundleNonRetina
  extends MGWTClientBundleBaseThemeNonRetina {
  
  @Source({ "color.css",
   "com/googlecode/mgwt/ui/client/theme/base/css/progressbar.css",
   "css/progressbar.css" })
  ProgressBarCss getProgressBarCss();
   ...
 }

インタフェイスProgressBarCssはProgressBarに関するすべてのCSSクラスを含んでいます。このインタフェイスにCSSファイルをアノテートします。重要:順序は通常のCSSファイル同様重要です。最初にカラーテーマのためのカラー定義、その後にmgwtテーマのベースとなるCSSフォーム、そして最後にカスタムCSS(クラスをオーバライドする場合)をインクルードします。デフォルトのprogressbar.cssのコピーを必要としないことに注意してください。必要な際、オーバライドすることができます。

つぎにやらなくてはならないことは、MGWTThemeインタフェイスを作成する事です。

 public interface MGWTTheme {
 
  public MGWTClientBundle getMGWTClientBundle();
 
 }

すべてのプラットフォームのための単純な2つのカラーテーマの構築を始めましょう(このテーマは実際にmgwtの一部となり大変簡単に使用されます):

最初にMGWTTheme実装の構築が必要です(参照:MGWTColorTheme):



 public class MGWTColorTheme implements MGWTTheme {
  
  private MGWTClientBundle bundle;
  
  public MGWTColorTheme() {
   if (MGWT.getOsDetection().isIOs()) {
    if (MGWT.getOsDetection().isRetina()) {
     bundle =
      (MGWTColorBundleRetina) GWT.create(
       MGWTColorBundleRetina.class);
    } else {
     bundle =
      (MGWTColorBundleNonRetina)GWT.create(
       MGWTColorBundleNonRetina.class);
    }
   } else {
    bundle =
     (MGWTColorBundleNonRetina) GWT.create(
      MGWTColorBundleNonRetina.class);
   }
  }
  
  @Override
  public MGWTClientBundle getMGWTClientBundle() {
   return bundle;
  }
 }


上記実装ではMGWTClientBundleの2つの異なる実装のインスタンスを返します。一方はRetinaディスプレイ搭載iPhone向け、他方はその他すべてのデバイス向けです。
Retinaディスプレイ上できれいに見せるためアイコンはより大きいレゾリューションが必要なため、別々のMGWTClientBundle実装が必要です。
CSSファイル内で条件付きイメージをインクルードできないので(イメージは通常インライン定義される場合が多いが..)、異なるバンドルを使用します。

最後にやるべきこととしてデフォルトとしてのテーマのセットもしくはテーマをWidgetへパスします:

 MGWTStyle.setTheme(new MGWTColorTheme());

重要:アプリ処理の最初に行う必要があります。実行中テーマ変更はできません。

カスタムテーマをただ一つのWidgetへパスします:

 new Button(theme.getMGWTClientBundle().getButtonCss())


mgwtテーマ

mgwtは以下の各プラットフォームに対応するテーマを提供します:

 iPhone
 iPad
 Android
 Blackberry


そして、OSに依存せず簡単に拡張可能なテーマを1つサポートします:

 mgwt base

Widgetのスタイル定義方法

各Widgetや類似するCSSクラスのDOM構造を参照したい場合はWidgetのjavadocをちょっと見てください。Wikiで個別に更新するよりむしろ、コード内に直接文書化するほうが最新版を維持しやすいためjavadocを選択しました。



 Button
 ButtonBar
 CellList
 HeaderButton
 HeaderPanel
 LayoutPanel
 MCheckBox
 MValueBoxBase(MTextBoxのようなほとんどの入力要素向け)
 MListBox
 MRadioBox
 MSearchBox
 MSlider
 ProgressBar
 ProgressIndicator
 PullToRefresh
 ScrollPanel
 WidgetList
 TabPanel


ブラウザ内部のアニメーションの一般的な考え方

ブラウザ内部でどのようにアニメーションが処理されるかに関するブログ:
http://blog.daniel-kurka.de/2011/12/animating-in-browser.html


RootPanel vs RootLayoutPanel


GWT RootLayoutPanelは異なるブラウザでのスクリーンのリサイズをハンドルするために必要な処理を行います。IEにおけるボックスモデルの遅延のため、RootLayoutPanelはボックスモデルをサポートするブラウザ内で動作する必要がないコードを含んでいます。
RootLayoutPanelが複数のブラウザで動作する関連するレイアウトを提供する仕事をしている間、子供要素をレイアウトするためにJavaScriptが動作しています。

MGWTを使用して、WebKitエンジンにのみWidgetのレイアウトさせて、ほかのJavaScriptはレイアウトのための動作は行いません。
これはすべてのWidget上で早くスムースなレスポンスを保証します。なぜならすべてのコードはネイティブのレイアウトエンジンの範囲内で動作しているからです。

RootLayoutPanelはこのパターンを壊すため、MGWTでは使用しません。RootLayoutPanelを決して使用しないで下さいAnimationDisplayを追加のためにはRootPanelを使用して下さい
-----

ClientBundleをあまり使用してなかったから
もうちょっとそのあたりをしっかり利用したUI設計になれとかないと..

2013年3月15日金曜日

Dart vs GWT

さきほどMLのメールに
今日のABC2012の丸山先生の資料リンクがついていた

「Androidの次の飛躍を考える
   --- Webアプリ / HTML5開発の新しい動向 」
https://skydrive.live.com/#cid=6E2ADAE3A1DC9B62&id=6E2ADAE3A1DC9B62%2118387

というタイトルだったので
GWTを最近いいなあと思い始めた矢先
mgwtとかも乗ってるかもな..

とおもいみてみると..

なに新言語?
ブラウザにVMを搭載??
Dart???


..じゃGWTはどうなるんじゃい..
せっかくわざわざJavaScriptフレームワークいれないで
MVPフレームワークを提供してくれているのに..

でちょっと検索してみたら
DartのFAQにこんな文章がのっていた


Dart: FAQ
Q. What's the future for GWT?
http://www.dartlang.org/support/faq.html#future-for-GWT

該当箇所を翻訳してみた(間違ってたらご容赦!)


ブルースジョンソン氏は、GWTブログに以下のような記事を投稿した(G+コメント付きで):

"DartとGWTはともに構造化Webプログラミングを可能にすることをゴールとしている。事実、GWTを提供してきた同じエンジニアの多くがDartに取り組んでいる。我々は、より良くWebアプリをエンドユーザに提供するというGWTのミッションの野心的な進化としてみており、Dartの可能性を楽観視している。Dartが進化して、プライムタイムへの準備ができるようになり、GWT開発者コミュニティがDart調査を密に取り組むことを楽しみにしている。"


..なんか余裕ですね..
いまのところDartは海山だろうし..
DartにGWT-RPCやGWT-MVP相当があるのかもわからないし..
Chromeがブラウザ界を席巻しきっている前提だろうし..
ChromeがWebkitベースから脱却してかないといけなくなるかもだし..


Javaで書けるというのはビジネスアプリ
ビジネスアプリ開発者にとって
強力なアドバンテージだとおもうんだよなあ..

ビジネスアプリの開発者って
サラリーマンSEが多いから
新しい言語をまたぐパラダイムシフトが超絶遅いわけで..
JavaからDartへは..なかなか...


GWT続けてていいんかな..おれ...




Dartチュートリアルを探す

なぜmgwtなの?

MGWTプロジェクトページに

Why mgwt?
http://code.google.com/p/mgwt/wiki/Why

というページが有った。

いかん、こっちを先に読まないと..
ということで訳してみた。
#参照する場合はat your own riskでお願いします



-------
HTML5対ネイティブモバイルアプリ

モバイル機器のためにネイティブアプリを書く時や(特定の範囲内でデプロイされる)Webアプリを書く時に議論されてつづけています。
もしパッケージ化されモバイルデバイスへデプロイされるWebアプリがphonegapなどを使うのであれば、ネイティブアプリが実現できることができるようになります。

ひとつの基本的な決定

もし少しでもパフォーマンスを上げる必要があったり、デバイスの最新APIが必要な場合は、ネイティブアプリが進むべき道にみえるでしょう。しかし、もし複数のデバイスで多くのユーザへ低コストで届けたいのであれば、HTML5を選択するでしょう。しかしHTML5アプリを構築する場合いくつかの考慮すべき点がいくつかあります:

パフォーマンス

実際、パフォーマンスはモバイル携帯において重要です。もしアプリをJavaScriptで記述したのであれば、より効率的なJavaScritを記述しなくてはなりません。さもなくば動作が遅くなり、デバイスのバッテリを消耗させてしまいます。皆さんご存知のように、GWTコンパイラは非常に効果的なアプリを生産するよい手段です。

理論的にはGWTコンパイラのようなJavaScriptアプリを自分で最適化することは可能です。しかしそれはとても大変でエラーを起こしやすい仕事です。ですから、モバイル開発にGWTを使用して、Googleに書き換えさせてJava環境のすべてのツール導入することで偉大な業績の利益をえるのはいかがでしょうか。

アプリが効果的な実行を実現するために、mgwtはいくつかの大変クールなことを行います:


  • CSSで出来ることはすべてCSSで行います、例えばJavaScriptで記述するよりも、アニメーションをWebKitエンジンへ以上することでより高速に処理します
  • 遅延バインディングの多用により必要なコードのみ含むアプリを実現します。ダウンロード時間が早くして評価速度を向上させるために、最小のコードサイズを保証します。
  • 一般的に、電話は遅くかつ高レイテンシなネットワーク接続です。劇的な速度向上のために多くの小さなファイルを要求する必要はありません。mgwtはCssResourcesを使用し、すべて1つのファイルに詰め込みます(もしJavaScriptファイルが巨大になった場合は、もちろんgwtにより分割ポイントを管理します)。
  • キャッシュを使用します。ローカルコピーが古い場合だけスクリプトをダウンロードすることを実現します。このため既に訪問済みのページだったり、キャッシュ内にカレントアプリを持っているのであれば、再度ダウンロードしようとせず即座にアプリを開始します。

MGWTは既知のGWTベストプラクティスを使用しています

mgwtは全体を最初から構築しません。GoogleはGWTという偉大な仕事を成し遂げました。sそして決してmgwtを使うことで頂点に立つことではありません。このためmgwtは同様のコンセプトを持つGWTプロバイダやアニメーションをハンドルするGWTへの追加機能を使います。アニメーションをハンドルするカスタムActivityManagerを提供することで、mgwtはGWTの提供するMVPフレームワークを拡張します。すべてのmgwtウィジェットは編集フレームワーク同様UiBinderフレームワークを使って動作します。このため、みなさんご存知のとおりテスト可能なGWTアプリケーションはmgwtと一緒に動作します。


mgwtイベントモデル

mgwtは、カスタムDOM実装により、タッチイベントサポートとアニメーションイベントをGWTに追加します。マウス入力は一本指での接触として扱われます、このためマウスとタッチ両方ハンドルするコードを書かないで下さい
------

GWTが必要で、ほかのモバイル系追加機能も積極活用するよ
というアーキテクチャのざくっとしたコンセプト的な文章だった。

ただmgwtウェブサイトトップに張ってあった動画

mgwt & gwt-phonegap talk at dutch GTUG 1st May 2012 
http://www.youtube.com/watch?feature=player_embedded&v=0V0CdhMFiao

よりはぜんぜん総花的。
こっちの動画のほうがもうすこしくわしいアーキテクチャ説明をしている。


ただ油断してたら、
本文さいごにしれっとマウスイベントとタッチイベント共用不可
という重要な情報がしれっと書いてあった...


あぶないあぶない。

MGWT開発用Eclipseプロジェクトを作ってみる

ちょっとおもしろそうなMGWT+GWT+phonegapだけど..

まあ
なんにせよMGWTを使ったGWT開発ができる環境をまずつくらないといけないが、
そのあたりもMGWTのWikiに英語だけどのっていた。

SetupProject(Google Project: MGWT)
http://code.google.com/p/mgwt/wiki/SetupProject


この手順通りに試してみたが
とりあえずすんなりいった。


なので一応翻訳してみたので
下記にはりつけておく。
なお画面ダンプは私が試した時のものである。


プロジェクトの設定

mgwt/phonegapプロジェクトのために、簡単に生成をする既存のmaven archetypeがあります。

前提条件

mavenおよびGoogle Eclipseプラグインが導入されたEclipseがインストールされていることとします。

mavenは<mavenのフォルダパス>\binへパスをとおしとおくこと。
proxy経由の場合はconf\settings.xml上に設定を記述しておく。
3.0.3なら104行目あたりのコメントを外して設定する。

 
   
      optional
      true
      http
      proxy.xxxxx.co.jp
      8080
      localhost
   

 

ステップ1-archetypeからプロジェクト生成

Eclipseのワークスペース内でプロジェクトを生成します。

workspaceフォルダ上に入り、以下のコマンドを実行して下さい:

 mvn archetype:generate -DarchetypeRepository=http://www.m-gwt.com/m2/repo -DarchetypeGroupId=com.googlecode.mgwt.archetypes -DarchetypeArtifactId=mgwt-standard-archetype -DarchetypeVersion=1.0.8





実行中にgroupId、artifactId、version、packeageの入力を求められます。groupIdは、<あなたの組織のドメイン名>.<プロジェクト名>にならった文字列を指定してください。
artifactIdは文字のみで構成(マイナス、空白不可etc)された文字列を指定して下さい。versionはデフォルトのままにすることができます、そしてpackageはgroupIdと同じ値を指定して下さい。



ステップ2-ワークスペースの設定

この設定はワークスペースごとに一度だけ必要となります。
Eclipseが動作中であれば終了して下さい。
ここではローカルで動作中のmavenを指し示すM2_REPOと呼ばれる変数を生成します。
このため、依存性解析がEclipse内で動作します。ワークスペースフォルダへ入り、以下のコマンドを実行して下さい:

 mvn eclipse:configure-workspace -Declipse.workspace="/path/toyourworkspace"





システムに合わせたパラメータに変更して下さい、Windowsの場合"C:\workspace"など、LinuxやMacの場合/somepath/workspace などです。


ステップ3-mavenからEclipseプロジェクト作成

次の手順ではmavenを使ってmaven pom.xmlからEclipse用のプロジェクトやクラスパスファイルを生成します。
依存関係が変更する場合は、この手順を再実行する必要があります。
生成したプロジェクトディレクトリに移って以下のコマンドを実行して下さい:

 mvn eclipse:eclipse





 


ステップ4-Webリソースをtargetへコピー

この手順では、src/main/webappからWebアプリパーツをtargetフォルダへコピーします。src/main/webapp内のいずれかのファイルを変更した場合は、この手順を再実行する必要があります。

 mvn war:exploded





ステップ5-プロジェクトをEclipseへインポート

起動したEclipse上で以下の操作を実行します

プロジェジェクトをEclipseへインポート

ファイル>インポート


一般>既存プロジェクトをワークスペースへ>次へ




作成したプロジェクトフォルダを選択して開くと、Eclipseはプロジェクトを発見しインポート可能になります。

Google Eclipseプラグイン設定

プロジェクトエクスプローラ>trialで右クリック

プロパティ>Google>Webアプリケーション



このプロジェクトはWARディレクトリを持つ:チェック
WARディレクトリ:src/main/webapp
このディレクトリから起動及びデプロイ:チェックしない
OKボタンをクリック

ここでGWT開発モードを開始するとWAR Directory Selectionダイアログ表示されます:



"target/<artifactId>-<version>を選択してください(プロジェクト作成時の値を指定してください)。



実行が成功するとurlが表示されるので、コピーしてブラウザで開いて下さい。



以上までがwikiの文書。

で起動するブラウザがChromeの場合はそのままエラー無く動作するが、
Windows OSのSafariやIE、Firefoxで開くと以下の様なエラーダイアログが出てしまう。






このような場合は~.gwt.xmlを開いて
safariの部分をダイアログ上の文字列に変更すればよい。



だが、中身空っぽの画面なので
正常に動作したかがよくわからない..

中身をもうすこし探検しないと..

2013年3月14日木曜日

mgwtのプロジェクトトップページを翻訳してみる。



GWTを試している時に
検索にちょこちょこひっかかるmgwtの文字..

気になったので調べてみたが、
iOSやAndroidなどの画面部品系をWebアプリで実現するライブラリのようだ。

手っ取り早く知るにはshowcaseというデモを
自分のPCのブラウザ見ればはやい。

http://mobilegwt.appspot.com/showcase/

WindowsPC上のブラウザでも
十分にiOSっぽい画面部品を表現できている。

さらにスマホで味わえる感触ヌルヌル感。
上のサイトのAnimationsを選択したところ
画面遷移間の移動、最初ゆっくりでだんだん加速がついて..とかの
移動の感触をGWTが生成するHTML5+CSS3で表現しようというものだ。

..これだけだと正直ネイティブアプリでいいじゃんとおもってしまうが、
GWT+mgwtにする意義の一つとして通信料の少なさがあるようだ。
同じくらいの小さいライブラリもあるらしいが、
Ajax+DOMのちょこちょこ少量の通信というやつがキャリア通信に合っているんでないの
というのがGoogleの言い分らしい。

携帯アプリをGWTベースで作るにはまだ、携帯デバイス固有の機能、
カメラだとかGPS、傾きなどの各種センサなど
あったりなかったりする部分のライブラリだが、
そこはもうひとつのphonegapというプロジェクトをあわせ技でつかうことで
対処しようとしているらしい。

画面はmgwt、アプリ本体+サーバ側処理はGWT、クライアントの固有デバイスをphonegapで対応することでiOSアプリやAndroidアプリを実現しようとしている。


複数デバイスでの違いをGWT開発環境でひとまとめにして、
iOSでもAndroidでも同じアプリを作ってねという腹だ。

ちょっとおもしろそうだ、もう少し調べてみようかな..

p.s.
以下mgwtのプロジェクトページのトップを翻訳したものを貼り付けておく。
#参照はat your own riskでお願いします。
http://code.google.com/p/mgwt/wiki/GettingStarted

-----
基本

MGWTはGWT MVP、ClientBundles、GWTロギングに深く依存しています。もしあなたがこれらのGWTの基本を知らないのであれば、GWTドキュメントを読んでおいて下さい。mgwtはGWT機能の模倣しようとはしていません、現在GWTコアにないモバイル開発の機能を追加しただけです。mgwtはたいていこの流れにそって試行しています。

mgwtを使用するために最新リリースをダウンロードし、クラスパス上に配置する必要があります。そして、gwt.xmlファイルにそのことを記述しなくてはなりません。またgwtのためにsafariへのuser agentの設定も必要です、なぜならほとんどのモバイルデバイスはwebkitベースで動作しており、mgwtはwebkitに依存しているからです。

<inherits name="com.googlecode.mgwt.MGWT"/>
<set-property name="user.agent" value="safari" />


MGWT MVP

モバイルデバイス上で、UIにおける2つの状態間のほとんどの処理は、いくつかの種類のアニメーション付きで実行されます。それゆえ、mgwt自身はAnimatingActivityManagerと呼ばれるActivityManager実装を提供しています。
AnimatingActivityManagerはアニメーション付きページ処理をハンドルすることができます。画面のいずれのリージョンでも対応するためには、AnimatingActivityManagerが必要となります。(GWTのActivityManagerに似ています)


AnimatingActivityManagerが処理を行うために必要とすること:

  • 1つのAnimatableDisplayインスタンス - DOM処理をハンドル
  • 1つのActivityMapperインスタンス    - placeからactivityへのマッピング
  • 1つのAnimationMapperインスタンス  - マッピング(lastPlace, newPlace)→アニメーション

Animation Mapper

MGWT ActivityManagerは、place変更時必要なアニメーションを提供するAnimationMapperに依存しています。
どんあplaceの組み合わせに対しても、異なったアニメーションを提供することができます。
個々に簡単な例をあげます:

public class PhoneAnimationMapper implements AnimationMapper {
 @Override
 public Animation getAnimation(Place oldPlace, Place newPlace) {
  if (oldPlace instanceof AboutPlace && newPlace instanceof HomePlace) {
   return Animation.SLIDE;
  }
  return Animation.FADE;
 }
}



Animation Display

アニメーションは、mgwtによって異なるプラットフォーム上で別々にハンドルされます。
保証するために、mgwtは遅延バインディングを行うことでオーバヘッドを得ることはありません。AnimatableDisplayインスタンスを取得するために、簡単なGWT.create()を使用します:

 AnimatableDisplay display =
  GWT.create(AnimatableDisplay.class);


基本的な例

 //AnimatableDisplayインスタンス生成
 AnimatableDisplay display =
  GWT.create(AnimatableDisplay.class);

 //ActivityMapperのインスタンス化
 PhoneActivityMapper appActivityMapper =
  new PhoneActivityMapper(clientFactory);

 //AnimationMapperのインスタンス化
 PhoneAnimationMapper appAnimationMapper =
  new PhoneAnimationMapper();

 //ディスプレイのためのActivityManagerをセットアップ
 AnimatingActivityManager activityManager =
  new AnimatingActivityManager(
   appActivityMapper, appAnimationMapper,
   clientFactory.getEventBus());

 //ActivityManagerへディスプレイを渡す
 activityManager.setDisplay(display);

 //DOMへディスプレイを追加
 RootPanel.get().add(display);


MGWT 変数

もし(デバッグ目的のため)mgwtのCSSの曖昧性を消したいのであれば、ファイルgwt.xmlへ以下の記述を追加することができます:

 <set-configuration-property name="mgwt.css" value="pretty" />


もし1つの特定のプラットフォームへのコンピュテーションを制限したい場合(もしくは、開発モードでの特定のプラットフォームのテスト)、変数mgwt.osを設定することができます。

 <set-property name="mgwt.os" value="iphone" />

有効な変数値は以下のとおり:

 iphone
 retina (iPhone 4、4S向け)
 ipad
 ipad_retina
 desktop
 android
 android_tablet
 blackberry

2013年3月11日月曜日

CloudStack APIを呼び出すURLを作成するサイトを作ってみる



Google Web Toolkitを使って
Google App Engine上で動作するツールサイトを
ためしに一つ作ってみました。

https://cloudstacktools.appspot.com/

CloudStack APIを外部から呼び出すURL文字列を作成するサイトで、

BaseURLの左側は、管理サーバのホスト名orIPアドレス、
BaseURLの右側は、管理サーバ側のポート番号、
あとはコマンドとパラメータ群を行追加しながら記述して、
管理サーバから入手したAPIキーと秘密キーをセットします。

"Create URL"ボタンは、サーバでURL文字列生成するので
秘密キーなどを外部に漏らしたくない場合は
(もちろんサーバ側で記録していないが..)
"Create URL(Local)"ボタンを代わりに使用すれば、
URL生成をすべてクライアントで処理してくれます。
#画面がロードされきったら、LANケーブルを外しても実行できます
#サーバ側はもちろんエラーになりますが..


とりあえず自前のしょぼい環境の
管理サーバには使えたのだけど
テストは完璧というわけではありません。

なので、もし活用される場合は
AT YOUR OWN RISK
でお願いします。

もちろんGAEは無課金なので
親の敵のように激しくサーバ処理を呼び出すと
パンクします。
その際は
夕方5時にクリアされるので
それまでお待ちください。
#米国時間?らしいので夏冬で1時間ずれます


p.s.
何か変な所があればコメントに書いて下さい。
時間があれば..ですが修正します。

2013年3月9日土曜日

Google Web Toolkitクライアント側でURLエンコード変換する

GWTクライアント側のみでURLEncode変換する場合
そう難しくはない。

GWTのクライアント側クラス
com.google.gwt.http.client.URL
を使えばよい。

String converted =
 URL.encode(original);

という具合。

通常のURLへのリダイレクト処理などは
これで大丈夫である。


しかし..なぜか

String converted =
 java.net.URLEncoder.encode(original, "UTF-8");


と全く同じ文字列にならない..

今回の実装はCloudStack APIを呼び出すURL生成を
サーバへ秘密キー送信せずに処理することなので
同じ結果にしないといけない。


いろいろ調べてみると
com.google.gwt.http.client.URL#encode()では
RFC3986にて定義されている予約文字を%から始まるUTF-8コードに
変換しないのだ。

しょうがないので
com.google.gwt.http.client.URL#encode()
で変換した文字列を以下の処理をかけ
予約後をすべてUTF-8コードに手動で変換して対応した。

public static final String[][] RF3986_RESERVED =
 {{":",    "%3A"},
 {"/",    "%2F"},
 {"?",    "%3F"},
 {"#",    "%23"},
 {"[",    "%5B"},
 {"]",    "%5D"},
 {"@",    "%40"},
 {"!",    "%21"},
 {"$",    "%24"},
 {"&",    "%26"},
 {"'",    "%27"},
 {"(",    "%28"},
 {")",    "%29"},
 {"*",    "%2A"},
 {"+",    "%2A"},
 {",",    "%2C"},
 {";",    "%3B"},
 {"=",    "%3D"}};

 private String replaceRFC3984ReservedChars(String org){
  StringBuffer ret = new StringBuffer();
  for(int pos=0;pos<org.length();pos++){
   String tgt = String.valueOf(org.charAt(pos));
   for(int index=0;index
    if(tgt.equals(RF3986_RESERVED[index][0])){
     tgt = RF3986_RESERVED[index][1];
     break;
    }
   }
   ret.append(tgt);
  }
  return ret.toString();
 }

これでなんとかURLencodeすることが出来た。

Google Web Toolkitクライアント側でBase64変換する

GWTクライアント側のみでBase64変換する場合も
簡単にはいかない。


Base64変換は
外部jarを投入できるJavaSE環境なら
apache-commonsを使うのが良くやる方法、

import org.apache.commons.codec.binary.Base64
..
// apache-commonsでbyte[]をBase64変換し文字列化
return new String(Base64.encodeBase64(hash));

GWTサーバ側(GAE上)なら
com.google.gwt.user.server.Base64Utilsというクラス
を使うことが出来る。

import com.google.gwt.user.server.Base64Utils;
..
// GWTサーバでbyte[]をBase64変換し文字列化
return Base64Utils.toBase64(hash);

しかしGWTクライアントではそれらが使えない。
なので
これまた以下のオープンソースのJavaソースbase64.javaを
使用した。

http://svn.apache.org/repos/asf/directory/sandbox/erodriguez/preferences/src/main/java/org/apache/preferences/service/Base64.java

ほかにもいろいろ実装はあるが、
このコードを選んだのはGWTクライアント側で使用できる
クラスのみを使っての実装になっていたためだ。

return Base64.byteArrayToBase64(hash);


でとりあえず対応できるようになった。

Google Web Toolkitクライアント側でHmacSHA1変換する

CloudStack APIを呼び出すURLを生成する
Webアプリツールを作っていた。
GWTクライアントから非同期呼び出しして
サーバ上でJavaで処理させれば問題ないなとおもい
さくっとつくったのだけど、
どこの誰とも分からない人間に
自分のAPIキーや秘密キーを送ることはできない
人もいるだろうなあと思い
完全クライアント処理できるように
実装しようと修正しだしたのだけど..

Base64、URLエンコードなどは
クライアントのJava実装→JavaScript変換
で実装できた。
しかし..

HmacSHA1変換がどうしてもGWTのクライアント側で出来ない..

具体的にかくと、
通常のJavaSEが使える環境で
変数messageを秘密キー変数secretPassphraseで
HmacSHA1変換する場合は、

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
...

SecretKeySpec secretKeySpec =
 new SecretKeySpec(secretPassphrase.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes());

といった実装していた部分を
clientパッケージ以下では動作しない。

結局以下のオープンソースJavaScript関数を
HTMLでロードさせてJSNI(JavaScript Native Interface)で
呼び出す方法を使った。

CryptJS
http://code.google.com/p/crypto-js/


通常のJavaScriptでの使い方は

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-md5.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha512.js"></script>
<script>
 var hash = CryptoJS.HmacMD5("Message", "Secret Passphrase");
 var hash = CryptoJS.HmacSHA1("Message", "Secret Passphrase");
 var hash = CryptoJS.HmacSHA256("Message", "Secret Passphrase");
 var hash = CryptoJS.HmacSHA512("Message", "Secret Passphrase");
</script>

である。
なのでGWTを使用するHTMLファイル上に
上記のscriptタグ部分を定義しておく。


変数hashはバイト配列である。

JSNIでは呼び出す側の戻り値が特殊な場合は
JavaScriptObjectに受けないといけない。

なので

GWTクライアント側では

  • private static native JavaScriptObject _hmac_sha1(String org, String secretKey) /*-{
  •  return $wnd.CryptoJS.HmacSHA1(org, secretKey);
  • }-*/;

と受けるしかない。
これをbyte[]に戻すためにイロイロ試したが
一旦Stringで受けて出てきた文字列を
先頭から2文字づつ切り出し
符号つき16進数をそれぞれバイト化して配列にすると
サーバ側で処理した文字列と同じ結果になった。

private static byte[] HmacSHA1(
  String message, String secretPassphrase){
 String org =
  UrlLocalGenerator._hmac_sha1(
   message, secretPassphrase).toString();
 int length = org.length()/2;
 byte[] ret = new byte[length];
 for(int cnt=0;cnt<length;cnt++){
  String tgt = "0x" + org.substring(0, 2);
  org = org.substring(2);
  ret[cnt] = (byte)Integer.decode(tgt).intValue();
 }
 return ret;
}

というなんともかっこわるい実装になってしまった..

2013年3月5日火曜日

Google Web ToolkitはAndroid開発に似ている



※この記事には、特に内容はありません



App Engine環境でDDoS攻撃対策をやっていくうちに
結局GWT+GAE環境に行き着いた。

GWTはAppletの実装、VBでもよいが
イベントハンドラ系の実装を経験したことのある人
なら素直に入って行きやすい。

#実際はクライアント側のJavaSEライブラリが
#どれがつかえてどれが使えないかとかで悩むのだけど
#そこは置いておいて..

GWTはクライアントだけでなく
非同期通信で使用するサービスのサーバ側実装もできる環境を
実装することができる。

なのでGWTを使っていたのだけど..
ふとAndroid開発者に対しての設計構造指針の
勉強になるのではないかと思った。



上図のように起動するところがまず似ている。

アプリが起動するところも本当に似ているし、
画面構成をしてから
イベントハンドラを1つづつ実装していく流れは
Andoridでも似たようなものだ。

しかもできるだけクライアントで処理して、
必要最小限の通信をサーバと非同期通信するところは
GWTとおんなじだ。

だからAndroid経験者はGWTに素直に入りやすいかもなあ..
と思っただけ。

既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ

既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。   1. The Twelve Factors (日本語訳からの転記) コードベース   バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 ...