2011年11月5日土曜日

RAPを使って連絡先管理アプリをWEBアプリに変換 (1)

RAP と RCP の開発では、シングルソーシングと呼ばれる手法(同一のアプリケーションコードをRCP/RAPそれぞれのターゲットプラットフォームで再利用する手法)があります。本格的に製品の開発とメンテナンスを行う段階では、プラットフォームを意識しないで開発/保守に専念できるように、こういった手法が重要になると思います。しかし、RAPで使用できない API や、WEBアプリケーション特有の問題などを理解するために、まずはRCPとRAPでソースを分けて作成してみたいと思います。以前のポストeclipselink を使う(1)-(8) で作成したRCP版の連絡先管理アプリのプラグインを別のフォルダ(例えば rapcontact)にコピーして、Eclipse IDE でインポートすることにします。(シングルソーシング手法に関しては次のドキュメントを参考にしてください: http://www.ibm.com/developerworks/jp/web/library/wa-rcprap/


RAPアプリケーションを作成するためには、その環境が必要です。RAP開発環境のインストールと初期設定については、RAPチュートリアルを参考にしてください。

ターゲット定義の作成
まず、RAPアプリケーションのためのターゲットプラットフォームの定義を作成しておきます。

既存プラグインのインポート
RAP開発環境を設定したら、rapcontact フォルダにコピーした、com.itrane.mycontact、com.itrane.mycontact.db、com.itrane.mycontact.pdf をインポートします。com.itrane.mycontact.db と pdf の場合、コンパイルエラーは全くありません。 com.itrane.mycontactでは、RAPのターゲットプラットフォームでは使用できない依存プラグイン org.eclipse.ui.* がエラーになります。このプラグインを除去してもいいのですが、シングルソーシングに向けて、プロパティで optional をチェックして、実行時に適切なライブラリが選択されるようにします。


RAP で必要な org.eclipse.rap.ui.* を追加して同じにように optional を有効にします。これでplugin.xml の依存関係ページの必須プラグインは以下のようになります:


依存プラグインが解決してもRAP の UIライブラリではサポートされない API のコンパイルエラーが残っています。連絡先管理アプリケーションの場合、機能別のエラー箇所は次のとおりです。
  • 宛名印刷で、用紙定義ファイルを選択する(FileDialog)
  • 宛名印刷で、作成されたPDFを表示する
  • 写真登録で、イメージファイルを選択する(FileDialog)
  • 連絡先編集で項目別の IMEの制御
  • 乗換え案内の表示(内部ブラウザの使用)
  • WEB検索結果の表示(内部ブラウザの使用)
  • VCard からのインポート、VCardへのエクスポート 
上記のエラー箇所を API 別に分類すると以下のようになります。
  • ファイル選択の FileDialog#open API
  • PDF出力の Httpサーブレットレスポンス
  • IME制御の SWT.Native 定数と Shell#setImeInputMode メソッド
  • SWTブラウザの Browser.forward, Browser.back, Browser.addOpenWindowListener, ... などのメソッド
これらの機能を呼び出すインターフェースを1つのクラス (例えば SingleSourceUtil) にまとめて、別のプラグイン (com.itrane.mycontact.ui.rap) に移します。 com.itrane.mycontact.ui の plugin.xml で、このプラグインを依存プラグインとして追加します。

RAP非サポートAPIを1つにまとめたクラス(赤字部分がエラー箇所):
public class SingleSourceUtil {

    //$$$ FORMS $$$$$
    private static final int PAGE_H_SCROLL_INCREMENT = 64;
    public static void initializeScrollbars(ScrolledForm form) {
        ScrollBar hbar = form.getHorizontalBar();
        if (hbar != null) {
            hbar.setIncrement(PAGE_H_SCROLL_INCREMENT);
        }
    }

    //$$$ IME $$$$$
    public static int imeNative() {
        return SWT.NATIVE;
    }

    public static void setImeInputMode(int fImeMode) {
        PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                .getShell().setImeInputMode(fImeMode);
    }
    
    //$$$ ファイルダイアログ $$$$$
    public static String openFileDialog(Shell shell, String text, 
                             IFileUploadCallback callback) {
        String path = null;
        FileDialog dialog = new FileDialog(shell, SWT.OPEN);
        dialog.setText(text);
        dialog.setFilterExtensions(new String[] { "*.txt" });
        path = dialog.open();
        return path;
    }
    
    //$$$ PDF 出力 $$$$$
    public static String getPdfUrl(String filePath) {
        return "file://" + filePath;
    }
}

サンプルの連絡先管理アプリケーションの場合、非共通部分はこれだけです。とりあえずエラー箇所をコメントアウトしておきます。ブラウザは、別のクラスとして作成してあるのでRAP版では非サポート部分を使用しないように修正するだけです。

最後に com.itrane.mycontact.Application クラスを IEntryPoint を実装するように変更します。
public class Application implements IEntryPoint {

      public int createUI() {
        Display display = PlatformUI.createDisplay();
        WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();
        return PlatformUI.createAndRunWorkbench( display, advisor );
      }
}

それにあわせて plugin.xml で
   <extension
         id="application"
         point="org.eclipse.core.runtime.applications">
      <application>
         <run
               class="com.itrane.mycontact.Application">
         </run>
      </application>
   </extension>

上記の部分を次のように変更します。
   <extension
         point="org.eclipse.rap.ui.entrypoint">
      <entrypoint
            class="com.itrane.mycontact.Application"
            id="com.itrane.mycontact.entrypoint"
            parameter="mycontact">
      </entrypoint>
   </extension>

インポートして、コンパイルエラーを取り除くまで30分も掛かかりませんでした。


ApplicationWorkbenchWindowAdvisor クラスのコードを以下のように修正して、アプリケーションタイトルの変更、クールバーの有効化、アプリケーションウインドウの最大化を設定します:
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    ...
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        configurer.setInitialSize(new Point(1260, 800));
        configurer.setShowCoolBar(true);
        configurer.setShowStatusLine(false);
        configurer.setTitle("マイコンタクト");
        configurer.setShellStyle(SWT.NO_TRIM);
    }

    @Override
    public void postWindowCreate() {
           Shell shell = getWindowConfigurer().getWindow().getShell();
           shell.setMaximized( true );
    }
}

実行構成の Bundles タブで、必要なバンドル追加して実行します:


実行結果は次のようになります:



RCPアプリをコピーして、エラーを取り除いただけで8、9割の機能はそのまま動きます。次回は RAPでサポートされない機能、WEBアプリを考慮した機能について対応していきます。

0 件のコメント: