DocumentumおよびWebtopでGWTを使用する

はじめに



この記事では、GWTとWebtopの交配に関する小さな研究についてお話したいと思います。

最初に、「なぜこれが必要なのか」という正当な質問に答えます。 私はいくつかの目標を追求しました。

1)GWTを調べます。

2)WDKおよびWebtopの内部の詳細。

3)おそらく、Webtop用のGWTコンポーネントを作成する方法を見つけます。

GWTが選択されたのは、プログラマーがJava用のUIおよびクライアントコードをすばやく作成できるためです。 また、AJAXをそのままサポートしています。

これはWebtopと組み合わせて使用​​され、独自のアプリケーションを最初から作成するのではなく、これには時間がかかり(Documentumセッションのサポート、アクションと前提条件の置き換えの発明)、Webtopで既に記述されたコードの使用が許可されないためです。



境界条件



オブジェクトを操作するロジックにより:

CRUD、オブジェクトのビジネスオペレーション。

アクションで動作し、結果としてWebtopを事前調整する能力。 つまり アクションを呼び出し、クライアント側でアクションの前提条件を確認するためのメソッドを提供する必要があります。



オブジェクトの内容に応じて:

最大100個の属性。 最大100個の繰り返し属性値。



UIにより:

GWTは既存のWebtopソリューションに組み込む必要があります。 少なくとも個々のコンポーネントのレベルで。 つまり 単純なWebtopコンポーネントからGWTコンポーネントを呼び出すことができるはずです。 (「コンポーネント」という語は、標準のWebtopコンポーネントを指します)また、GWTコンポーネントを終了して、呼び出し元のコンポーネントに戻す方法も必要です。



注:

以下は、使用するGWTの主な側面です。 各テクノロジーの動作を詳細に検討しないという事実に注意を喚起したいと思います。記事はそれについてではありません。 何かについてもっと知りたい場合-リンクは記事の最後にあります。



UI



UIを作成するために、最初に単純なGWTメソッドを試してみました-ウィジェットがコード内で直接作成される場合のla Swingです。 それは非常にうまくいきました-すべてのコードは1つのファイルにあり、作成されているものをすぐに見ることができます。 しかし、フォームが非常に大きくなり(少なくとも100行以上)、イベントの多くのリスナーがフォームに表示されると、コードが過負荷になり、読みにくくなります。

コードからウィジェットを作成するのとは対照的に、GWTは別のメカニズム-UIビルダーを提供します。 主な違いは、UIがxmlファイルのロジックとは別に記述されていることです。 UIビルダーの欠点のうち、GWTで使用可能なすべてのウィジェットがUIビルダーコンポーネントパレットで使用できるわけではありません。 Window Builderでのウィジェットのサポートは非​​常に限られているとさえ言えます。 そのため、最終的に、特定の処理(少なくともテーブルに列を追加)を行う必要がある場合は、コードを記述する必要があります。



クライアントによるオブジェクトの受信



Documentumは、サーバーメソッドの呼び出しを介してオブジェクトのすべての作業を行います。 この作業を整理する方法を決定するだけです。 最初の明白な方法は、GWTの標準RPCを使用することです。 データベースオブジェクトの処理を担当する必要なサービスを作成するだけです。たとえば、「従業員」オブジェクトを操作するサービスや「組織」オブジェクトを操作するサービスです。 この場合のオブジェクトは、クライアントとサーバー間で転送されるPOJOです。 GWTの記事には、Hibernate developers.google.com/web-toolkit/articles/using_gwt_with_hibernate?hl=en-USとの作業を整理する方法に関するメモがあります。

同様のコミュニケーション方法を検討します。 DTOの使用における違い(Hibernateが使用されるという事実以外)は、データ転送オブジェクトです。 名前とWikiに続いて、これらはデータベースエンティティをクライアントに転送するための中間オブジェクトです。 クライアントへの不要なデータの送信を最小限に抑えるために必要です。 つまり 100個の属性を含むエンティティがありますが、クライアントは10個のみを使用します。これらの10個のフィールドを使用して、目的のエンティティに対して特別なDTOを作成する方法を次に示します。

この方法の利点は、理解と実装が非常に簡単です。

短所-DTOの使用、またはそうでなければ、オブジェクトの多数の不必要な属性のクライアントへの転送の可能性。

2番目の方法は、Request Factoryです。 これは、オブジェクトに対してCRUD操作を実行するためだけに設計されたRPCの代替です。 単純なRPC呼び出しとの主な違いは、操作が実行されるオブジェクトは、サーバーが操作するオブジェクトとクライアントが操作するプレゼンテーションオブジェクト(EntityProxyの継承)の2つのカテゴリにすぐに分割されることです。 基本的に、プロキシオブジェクトはDTOにすぎません。 この場合、メインオブジェクトからDTOへの変換はGWTによって行われます。

RPCおよびRequestFactoryに関するStackOverflowの議論stackoverflow.com/questions/4119867/when-should-i-use-requestfactory-vs-gwt-rpc

このメソッドは確かに興味深いものですが、追加のコードを書く必要があります。 さらに、RequestContextの子孫のメソッドとこれらのメソッドを実装するオブジェクト、およびProxyオブジェクトのゲッターとセッターとオブジェクト自体の間の明示的ではない関係が好きではありませんでした。 最初のケースでは、GWTはRequestFactoryの検証モジュールを使用して、コンパイル段階で矛盾を見つけます。



WebtopとGWTの間でパラメーターを渡す



検索した後、パラメータをGWTに渡す方法をいくつか見つけました-JSP(値をJSに挿入してから解析)、url(取得リクエストを解析)、およびパラメータを返すサーブレットを使用。

Webtopの場合、JSPオプションは適切なオプションです。コンポーネントは、パラメータを挿入するためのコードのみを含むjspページの存在を前提とし、コンポーネントはこれらのパラメータをJSPに転送できるためです。

これを行うには、次のコードをjspに追加します。

<script type="text/javascript"> var wdk2gwt_param = '${wdk2gwtParam}'; </script>
      
      





ここでは、wsk2gwtParam属性の値が割り当てられるJS変数wdk2gwt_paramについて説明します。



また、パラメーターを記述するためのコンポーネントコードで次のように記述します。

 @Override public void onRender() { getPageContext().setAttribute(“wdk2gwtParam”, “ ”); super.onRender(); }
      
      





ここで、ページを表示するときに、値jdkで前述した値wdk2gwtParamを値に割り当てます。



コンポーネントを終了できるようにするには、イベント処理メソッドを追加する必要があります。

 public void onReturnClick(Control control, ArgumentList list) { setComponentReturn(); }
      
      





これにより、コンポーネントの標準メソッド(setComponentReturn())が呼び出され、呼び出し元のコンポーネントに戻ることができます。



また、GWTでは、次の方法を使用して上記の方法を使用します。

 public native String getParam() /*-{ return $wnd.wdk2gwt_param; }-*/; public native void callPostServerEvent() /*-{ $wnd.postServerEvent(null, null, null, ' onReturnClick ', null, null); }-*/;
      
      







JavaコードからJSコードを呼び出す標準的な方法を次に示します。 getParam()メソッドは、(jspで指定された)wdk2gwt_param変数の値を返すだけです。 callPostServerEvent()メソッドでは、コンポーネントメソッドを呼び出すために標準のJS WDK関数が呼び出されます。 この場合、上記で説明したonReturnClickメソッドが呼び出されます。 JSがpostServerEventを機能させるには、最初に定義する必要があります。 これを行うには、jspで次のタグを指定する必要があります。<dmf:webform />および<dmf:form>

これに関して、完全なjspコードは次のようになります。



 <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib uri="/WEB-INF/tlds/dmform_1_0.tld" prefix="dmf"%> <html> <head> <dmf:webform /> <title></title> </head> <body> <dmf:form> <script type="text/javascript"> var wdk2gwt_param = '${wdk2gwtParam}'; </script> <script language="javascript" src="/Webtop/ru.tim.gwt.correspondent.Correspondent/ru.tim.gwt.correspondent.Correspondent.nocache.js"></script> </dmf:form> </body> </html>
      
      







セッションを操作する



Documentumセッションでの作業として、SessionManagerHttpBindingを使用します。 現在のユーザーのIDfSessionManagerインスタンスを取得できます。 ここからセッション自体を取得できます。

 IDfSessionManager sessionManager = SessionManagerHttpBinding.getSessionManager(); IDfSession session = null; try { session = sessionManager.getSession(SessionManagerHttpBinding.getCurrentDocbase()); } catch (Exception e) { e.printStackTrace(); } finally { sessionManager.release(session); }
      
      





このコードをGWTサーブレットで使用して、セッションを取得して閉じることができます。 もちろん、sessionManagerにアクセスする前に、ログに正しい出力を描画し、nullチェックを追加する必要があります。



アクションWDKの実行



アクションを実行し、前提条件を検証する必要がありました。 ユースケース-リストされたパラメーターで指定されたアクションが実行されることを確認して実行します。

頭に浮かんだ最初のアイデアは、フォームコールをリバースエンジニアリングすることでした。 (ネットワーク上にドックはありません)。 コードをざっと調べて、メソッド呼び出しのチェーンをトレースしました。 その結果、フォームとコンテキストを取得するために多くのことを行う必要があります。

2番目のオプションは、Documentum community.emc.com/docs/DOC-8012を使用するAJAXです。いわゆるインラインコールです。

つまり 本質は、パラメータを使用してクライアントから非同期に呼び出されるコンポーネントのメソッドを作成することです-名前アクションとパラメータアクションのリスト。 そして、実行の結果がクライアントに返されます。 注釈が1つあります-アクションが他のコンポーネントへの切り替えのメソッドを使用する場合:setComponentReturn、setComponentJump、setComponentNested(おそらくその他) ほとんどの場合、これはコンポーネントが現在の状態を終了した(別のコンポーネントに切り替えた)ことによるものですが、サーバーへの要求時に、パラメーターはコンポーネントのすでに古い状態を示しています。 より正確には、パラメーターは、サーバーがコンポーネントの状態を復元する現在のセッション内の一意の行を指定します。 そして、この状態は時代遅れです。

原則として、多かれ少なかれ実用的なソリューションがすでに見つかっています。 しかし、Componentクラスのonactionメソッドもテストすることにしました。 これは、そのフォームのすべてのアクションを実行するメソッドです(ブレークポイントをアクションに入れて呼び出すと、スタックトレースでこれを確認できます)。 正確には、すべての標準アクションコントロールのフォームはこのメソッドを呼び出します。 これは、外部から呼び出すことができる通常のコンポーネントメソッドです。 そして、このメソッドはインライン呼び出しをサポートしています。 したがって、このメソッドを呼び出すには、名前アクションとそのパラメーターを渡す必要があります。 通常のアクションを初めて呼び出すと、エラーが発生します。アクションはIInlineCapableActionインターフェイスを実装する必要があります。 これを修正することにより、アクションを正常に呼び出すことに成功します。 アクションから値を転送するには、Mapを使用して値(IActionExecutionの6番目のパラメーター。実行)を返し、そこにRESPONSE_DATAキーを使用して値を配置する必要があります。

完全なコードは次のようになります。

アクションの説明を含むXMLコンテンツ。

 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <config version="1.0"> <scope> <action id="test_action"> <params> <param name="test_param" required="false"/> </params> <execution class="ru.tim.wdk.test.TestAction"/> </action> </scope> </config>
      
      





注意-アクションはtest_paramパラメーターを取ります。

非同期的に呼び出されるアクションメソッド。

  public boolean execute(String actionName, IConfigElement config, ArgumentList args, Context context, Component component, Map resultMap) { System.out.println("Action param: " + args.get("test_param")); resultMap.put("RESPONSE_DATA", "actionResultValue"); return true; }
      
      





test_paramパラメータがここに表示されます。 上記はxmlで説明されています。 応答を表示するには、RESPONSE_DATAキーを持つ応答actionResultValueが結果マップに配置されます。 RESPONSE_DATA-インラインアクション呼び出しのハードコードされた応答キー。 onactionメソッドのコードを見ているときに見つけました。 ハンドラークラス(CallbackDoneListenerWrapper)からインライン呼び出しアクションを実行すると、RESPONSE_DATAキーを使用してMapの値が取得されます。 クライアントに応答を送信する場合、RESPONSE_DATAキーも使用されます(ComponentクラスのprocessInlineActionResponseDataメソッド)。

アクションの結果を送受信するメソッドを含むjspページの一部:

 <script type="text/javascript"> function executeAction() { var prefs = InlineRequestEngine.getPreferences(InlineRequestType.JSON); prefs.setCallback(callBack); postInlineServerEvent(null, prefs, null, null, "onaction", "action", "test_action", "test_param", "test_param_value"); } function callBack(data) { if (isEventPostingLocked()) { releaseEventPostingLock(); } if (data) { var result = data['RESPONSE_DATA'] window.alert(result); } } </script>
      
      





executeActionメソッドは、サーバーへの非同期リクエストを実行してアクションを実行します。 応答を処理するために、callBack関数が使用されます。

postInlineServerEventメソッドでは、action-onaction実行メソッドが呼び出されます。 パラメーター-アクションでは、パラメーターで、呼び出されたアクションの名前が渡されます。 test_actionは、呼び出されるアクションの名前です。 test_paramは、アクションパラメーターの名前です。 test_param_value-パラメーター値。 さらにパラメーターを追加する必要がある場合は、それらをペアでさらにリストする必要があります-<パラメーター名>、<パラメーター値>。

GWTからアクションを使用するには、GWTメソッドからpostInlineServerEvent関数への呼び出しをラップし、setCallbackでGWT関数をパラメーターとしてスローする必要があります。

これで、指定したアクションの前提条件検証メソッドを実装することができます。

これを行うには、指定されたアクションの前提条件を実行するコンポーネントのメソッドを使用します。 前提条件自体は、ActionService.queryExecute(strAction、args、context、component)関数を使用して実行する必要があります



環境設定



WebtopとEclipseでの便利な作業のために、Gwtプロジェクトを作成します。 プロジェクトのorg.eclipse.wst.common.project.facet.core.xml(プロジェクトフォルダーの.settingsフォルダーにあります)で、次の行を追加します

  <fixed facet="jst.web"/> <fixed facet="java"/> <fixed facet="wst.jsdt.web"/> <installed facet="java" version="1.6"/> <installed facet="jst.web" version="2.5"/> <installed facet="wst.jsdt.web" version="1.0"/>
      
      







結果は次のようになります。

 <?xml version="1.0" encoding="UTF-8"?> <faceted-project> <fixed facet="jst.utility"/> <fixed facet="java"/> <fixed facet="jst.web"/> <fixed facet="wst.jsdt.web"/> <installed facet="java" version="1.6"/> <installed facet="jst.web" version="2.5"/> <installed facet="wst.jsdt.web" version="1.0"/> <installed facet="jst.utility" version="1.0"/> </faceted-project>
      
      







ここでは、プロジェクトがWebプロジェクトになり、Tomcatで起動できることを示しました。 JavaビルドパスウィンドウにクラスのWeptopおよびWeb App Librariesフォルダーを追加します。 Deploymentアセンブリをセットアップして、プロジェクトのgwtおよびwebtopソースフォルダーとgwtおよびweptop Webコンテンツフォルダーをアップロードします。

残っている問題は1つだけです。webtopとは別にgwtを実行できるようにweb.xmlを設定します。 現在、web.xmlには、サーブレットのgwtとサーブレットのWebtopの両方の構成が含まれています。 または、すべての設定を1つのweb.xml Webtopに入れて、それだけをアップロードできます。 gwtについては、設定のみを残します。 アンロードの正しい順序を観察する必要があるのはあなただけです-Webtopが最初にアンロードされ、次にgwtがアンロードされます。 データは上書きされません。



実装



テストのために、特定のタイプのオブジェクトを表示し、複数の単一フィールドを編集できる小さなコンポーネントを作成しました。 ソースはこちらからダウンロードできますdl.dropbox.com/u/7519092/gwt2wdk.rar (動作するにはWebtopが必要です)



おわりに



GWTとWebtopの相互作用の基本は完了しました。 ただし、コンポーネント編集テンプレートカードを完全に実装するには、いくつかのことを行う必要があります。

1)オブジェクト選択のあるフォーム。 Webtopでは、セレクターと呼ばれます。

2)ウィジェットはアクションをサポートしているため、アクションを実行するようにウィジェットを構成でき、このためのコードを記述できません。

3)特定の属性を編集するためのプラグインコンポーネント。 たとえば、Webtopでは、プロパティコンポーネントで使用できます。

さらに、GWTについてさらにいくつかのこと-クライアント側での入力のチェック、UIとイベントの正しい区別。



リンク集



RequestFactoryマニュアルdevelopers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory?hl=en-US#locators

RequestFactoryの例(1) cleancodematters.wordpress.com/2011/06/04/tutorial-gwt-request-factory-part-i

RequestFactoryの例(2) javaasylum.blogspot.com/2010/11/gwt-21-request-factory.html

RequestFactoryの例(3) turbomanage.wordpress.com/2011/03/25/using-gwt-requestfactory-with-objectify



All Articles