48 WEMフレームワークでのアプリケーションの開発

Articlesサンプル・アプリケーションを操作して、RESTコールを実行するアプリケーションの基本的なアーキテクチャを理解できます。

WEMフレームワークでのアプリケーションの開発の詳細は、次の項を参照してください。

Articlesサンプル・アプリケーションの構造について

Articlesサンプル・アプリケーションのソース・ディレクトリには、ソース・ファイル、ログ出力ファイル、インストーラ・リソース、ホーム・ページ・ファイルおよび構成ファイルがあります。

次の図は、Articlesサンプル・アプリケーションのソース構造を示しています。デプロイメント時に、次のディレクトリはソースからターゲットにコピーされます。libディレクトリの内容は/WEB-INF/lib/にコピーされます。resourcesディレクトリの内容は、/WEB-INF/classes/にコピーされます。

図48-1 Articlesサンプル・アプリケーションのソース構造

図48-1の説明が続きます
「図48-1 Articlesサンプル・アプリケーションのソース構造」の説明

Articlesは、Spring MVCで開発されたJava Webアプリケーションです。次のページを使用できます。

  • /install.appは、Articlesのインストール・ページで、また、アプリケーションが正常にインストールされた場合に確認メッセージが表示されます。

  • /home.appは、Articlesアプリケーションのホーム・ページです。

Articlesサンプル・アプリケーションの構成ファイルについて

Articlesサンプル・アプリケーションの構成ファイルは、applicationContext.xmlおよびspring-servlet.xmlです。

  • applicationContext.xml(/WEB-INF/)には、SSO構成およびアプリケーション固有の構成(事前定義済ユーザーや、データ・モデルおよびアセットが有効化されるサイトなど)が保持されます。

  • spring-servlet.xml (/WEB-INF/)は、デフォルトのSpring構成ファイルです。このファイルはSpring構成を格納し、次のコントローラを参照します(「ソース・ファイル」を参照)。

    • HomeController

    • InstallController

    • LayoutController

    • ProxyController

    • loggingconfig.xml (/<sitesshared>/config内)は、ロギング構成ファイルです。アプリケーションのデプロイ時に、/<sitesshared>/configからwebcentersites\sites-home\template\configにコピーされます。

ソース・ファイル

/sample app/articles/src/main/java/

/sample/フォルダには、次に示すソース・ファイルが含まれます。

  • Configuration.javaは、(Springフレームワークによって) applicationContext.xmlファイルから移入されます。

  • HomeController.javaは、単一のホーム・ページをレンダリングするホーム・ページ・コントローラです。このコントローラは、REST APIを使用してWebCenter Sitesプラットフォームからサンプル記事のリストを読み込み、それらをホーム・ページに表示します。

    サンプル記事は、/sample app/articles/src/main/resources/installに格納されているイメージとテキストで構成されます。サンプル記事は、InstallController.javaによって、WebCenter Sitesデータベースにインストールされます。

  • InstallController.javaはArticlesアプリケーションを登録し、アプリケーションのアセット・モデルとサンプル・アセットをデータベースに書き込みます。

  • LayoutController.javaは、WEM UIフレームワークで使用されるアプリケーションのレイアウト・ページ(layout.app)を表示します。LayoutController.javaは、アプリケーションの登録時にも使用されます。

  • ProxyController.javaは、AJAXリクエストをWebCenter Sites RESTサーブレットに委任します。

  • TldUtil.javaユーティリティ・クラスにはTLD機能の実装が含まれます。

インストーラのリソース

/sample app/articles/src/main/resources/install

/install/フォルダには次のリソースが含まれます。これらのリソースはホーム・ページを構成する際に、InstallControllerで使用されます(図48-3)。

  • strategies.png

  • strategies.txt

  • tips.png

  • tips.txt

Home Page Files

/sample app/articles/src/main/webapp/images

/images/フォルダには次のファイルが含まれます。

  • articles.pngアイコン(図48-2)。アプリケーション・バーでArticlesアプリケーションを表します

  • 図48-3の詳細:

    • edit.pngは、「編集」機能用のアイコンです。

    • save.pngは、「保存」機能用のアイコンです。

    • cancel.pngは、「取消」機能用のアイコンです。

スクリプト

/sample app/articles/src/main/webapp/scripts

/scripts/フォルダには、文字列とJSONオブジェクトとの変換に使用されるjson2.jsユーティリティ・スクリプトが含まれます。

スタイル

/sample app/articles/src/main/webapp/styles

/styles/フォルダには、このWebアプリケーションで使用されるCSSスタイルを指定するためのmain.cssが含まれます。

ビュー

/sample app/articles/src/main/WEB-INF/jsp

/jsp/フォルダには次のファイルが含まれます。

  • home.jsp。Articlesアプリケーションのホーム・ページ・ビューをレンダリングする際に使用されます(図48-3)。

  • layout.jsp。アプリケーションのレイアウトを定義します。

WEB-INF

/sample app/articles/src/main/WEB-INF

/WEB-INF/フォルダには次のファイルが含まれます。

RESTコールの実行

WebCenter Sites RESTリソースは、XMLおよびJSONという2種類の入出力フォーマットをサポートしています。特定の戻りフォーマットを取得する場合、MIMEタイプapplication/xmlまたはapplication/jsonを指定するHTTPヘッダーを使用します。

たとえば、入力フォーマットをXMLに指定する場合は、Content-Typeapplication/xmlに設定します。出力フォーマットを指定する場合は、Accept (予期されるフォーマット)をapplication/xmlに設定します。その他の出力フォーマットを指定すると、それらは無視されます。Content-TypeまたはAcceptで何も指定されていない場合のデフォルトはXMLです(サンプル・コードについては、「JavaScriptからのRESTコールの実行」を参照)。

トピック:

JavaScriptからのRESTコールの実行

  • 次のコード(home.jsp内)を使用して、アセットのRESTサービスに対してAJAXコールを実行し、アセット・データを保存します。実際には、プロキシ・コントローラに対してリクエストが実行され、プロキシ・コントローラから宛先のRESTサービスにリクエストがリダイレクトされます。

    ノート:

    JSONのstringifyライブラリを使用して、JavaScriptオブジェクトを文字列としてシリアライズします。文字列のかわりにJSONオブジェクトを記述する方が便利です。

    // Form the URL pointing to the asset service 
    // to the proxy controller, which will redirect this request to the CS REST servlet.
    var idarr = assetId.split(":");
    var assetUrl = "${pageContext.request.contextPath}/REST/sites/${config.csSiteName}/types/" + idarr[0] + "/assets/" + idarr[1];
    
    // For the data object to be posted.
    var data = 
    {
     "attribute" : 
    [
    {
       "name" : "source",
      "data" : 
     {
        "stringValue" : document.getElementById("source_e_" + assetId).value
    }
    },
    {
      "name" : "cat",
     "data" : 
     {
    "stringValue" : document.getElementById("cat_e_" + assetId).value
    }
    }
    ],
     "name" : document.getElementById("name_e_" + assetId).value,
     "description" : document.getElementById("desc_e_" + assetId).value,
     // This should be removed.
     "publist" : "${config.csSiteName}"
    };
    // Convert JSON data to string.
    var strdata = JSON.stringify(data);      
      
    // Perform AJAX request.
    var req = getXmlHttpObject();       
    req.onreadystatechange = function ()
    {
    if (req.readyState == 4)
    {
    if (req.status == 200)
     {
     // On successful result
    // update the view controls with new values and switch the mode to 'view'.
      for (c in controls)
    {
    document.getElementById(controls[c] + "_v_" + assetId).innerHTML = 
    document.getElementById(controls[c] + "_e_" + assetId).value;
    }  
    switchMode(assetId, false);
    }
    else
    {
    // Error happened or the session timed out,
    // reload the current page to re-acquire the session. 
    alert("Failed to call " + assetUrl + ", " + req.status + " " + req.statusText);
    window.location.reload( false );
    }
    }
    };
    // We put Content-Type and Accept headers
    // to tell CS REST API which format we are posting
    // and which one we are expecting to get.
    req.open("POST", assetUrl, true);
    req.setRequestHeader("Content-Type", "application/json;charset=utf-8");
    req.setRequestHeader("Content-Length", strdata.length);
    req.setRequestHeader("Accept", "application/json");
    req.send(strdata);
    }
    

JavaからのRESTコールの実行

  • 次のコード(HomeController.java)を使用して、アセット検索サービスをコールし、FW_Articleタイプのすべてのアセットをリストします。このコードでは、Jersey Clientライブラリを使用して、WEMフレームワークが提供するrest-api-<version>.jarライブラリからオブジェクトを渡します。この方法を利用すると、Javaでの入力が強化されます。

    SSOAssertion.get().createToken()メソッドをコールして、トークンをJavaコードから取得する必要がある点に注意してください。JavaScript側ではWEMのSSOに対してすでに認証が行われているため、同様の処理を行う必要はありません。

    // Use Jersey client to query CS assets.
    Client client = Client.create();
    String url = config.getRestUrl() + "/types/FW_Article/search";
    WebResource res = client.resource( url );
                    
    // Construct URL and add token (for authentication purposes)
    // and fields (specify which fields to retrieve back) parameters.        
    res = res.queryParam("fields", URLEncoder.encode("name,description,content,cat,source", "UTF-8"));
    res = res.queryParam("ticket", SSO.getSSOSession().getTicket(res.getURI().toString(), config.getCsUsername(), config.getCsPassword()));
    // Put Pragma: auth-redirect=false to avoid redirects to the CAS login page.
    Builder bld = res.header("Pragma", "auth-redirect=false");
            
    // Make a network call.
    AssetsBean assets = bld.get(AssetsBean.class);

    ノート:

    カスタム・ヘッダーPragma: auth-redirect=falseは、CAS SSOフィルタにCASサインイン・ページにリダイレクトしないように指示しますが、チケットが指定されていない場合または指定されたチケットが無効の場合は403エラーが返されます。

バイナリ・データを処理するURLの作成

Articlesアプリケーションに対して、WebCenter SitesのBlobサーバーを使用してBLOBデータを処理できます。getBlobUrl関数を使用して、特定のアセットの特定の属性のバイナリ・データを指すURLを構成できます。

  • blobUrlは、デフォルトでBlobサーバー(http://localhost:8080/cs/BlobServer)を指します。

    public String getBlobUrl(String assetType, String assetId, String attrName, String contentType)
    throws Exception
    {
    String contentTypeEnc = URLEncoder.encode(contentType, "UTF-8");
            
    return blobUrl + "?" +
    "blobkey=id" + 
    "&blobnocache=true" +
    "&blobcol=thumbnail" +
    "&blobwhere=" + assetId +
    "&blobtable=" + assetType +
    "&blobheader=" + contentTypeEnc +
    "&blobheadername1=content-type" +
    "&blobheadervalue1=" + contentTypeEnc;
        }
    
  • バイナリ・データを取得する別の方法は、リソース/sites/{sitename}/types/{assettype}/assets/{id}を使用してアセットをロードすることです。ロードされたアセットには、BLOBサーバーを指すURLが格納されます。

WEMフレームワークからのパラメータへのアクセス

WemContext JavaScriptコンテキスト・オブジェクトでは、どのユーザーがどのサイトにログインしたかをアプリケーションで検出できるようにすることができます。アプリケーションでデータを共有できるようにすることもできます。

UIコンテナは、コンテナ内のすべてのアプリケーションにJavaScriptコンテキスト・オブジェクト(WemContext)を提供します。コンテキスト・オブジェクトは、ログイン済ユーザーやサイトに関する詳細情報をWEMフレームワークから取得するためにアプリケーションで使用します(通常は、UIコンテナから現在のサイトの名前を取得します)。また、コンテキスト・オブジェクトは、アプリケーションでデータを共有する際に使用する各種ユーティリティ・メソッドも提供します。コンテキスト・オブジェクトは、WebCenter Sitesと同一ドメインまたは異なるドメインで実行されているアプリケーションで使用できます。

ノート:

wemcontext.htmlファイルには公開されるメソッドがリストされています(「コンテキスト・オブジェクトで使用可能なメソッド」でまとめられています)。

トピック:

サンプル・ドメイン内のコンテキスト・オブジェクトの初期化および使用

WebCenter Sitesドメイン内にあるアプリケーションのコンテキスト・オブジェクトを初期化して使用するには:

  1. wemcontext.jsを含みます。
  2. WemContextオブジェクトのインスタンスを取得します。
  3. WemContextのメソッドを使用します。
<script src='http://<csinstalldomain>/<contextpath>/wemresources/js/WemContext.js'></script>
<script type="text/javascript">
var wemContext = WemContext.getInstance(); // Instantiate Context Object
var siteName = wemContext.getSiteName(); // Get Site Name
var userName = wemContext.getUserName(); // Get UserName
</script>

クロスドメイン・アプリケーションのコンテキスト・オブジェクトの初期化および使用

クロスドメイン・アプリケーションのコンテキスト・オブジェクトを初期化して使用するには:

  1. wemxdm.jsjson2.jsおよびhash.htmlを(Misc/Samplesフォルダから)アプリケーションにコピーします。
  2. クロスドメイン・コールを実行するために、sample.html ファイルを開いて、次のように変更します。
    • wemxdm.jsjson.jsおよびhash.htmlのパスを、アプリケーション内でのそれぞれのパスに変更します(ステップdの後の例を参照)。

    • wemcontext.htmlのパスを、WebCenter Sites内でのこのファイルの場所に変更します(wemcontext.html/wemresources/wemcontext.htmlにあります。WebCenter Sitesのホスト名とコンテキスト・パスを使用します。)

    • インタフェース宣言で、フレームワークで使用するメソッドを指定します。

    • これらのメソッドをローカル・スコープに実装し、リモート・メソッドを起動します。

<script type="text/javascript" src="../js/wemxdm.js"></script>
<script type="text/javascript">
//  Request the use of the JSON object
WemXDM.ImportJSON("../js/json2.js");
var remote;
window.onload = function() {
// When the window is finished loading start setting up the interface
remote = WemXDM.Interface(/** The channel configuration */
{
// Register the url to hash.html.
local: "../hash.html",
// Register the url to the remote interface
remote: "http://localhost:8080/cs/wemresources/wemcontext.html"
}, /** The interface configuration */
{
remote: {
getSiteName :{},
...

}
},/**The onReady handler*/ function(){
// This function will be loaded as soon as the page is loaded
populateAttributes();
});
}
</script>

<script type="text/javascript"> 
/** Define local methods for accessing remote methods  */
function getSiteName(){
remote.getSiteName(function(result){
alert("result = " + result);
});
}
 ... 
</script> 

コンテキスト・オブジェクトで使用可能なメソッド

次の表に、コンテキスト・オブジェクトで使用可能なメソッドのリストと説明を示します。

表48-1 コンテキスト・オブジェクトで使用可能なメソッド

戻り型 メソッド名および説明

Object

getAttribute(attributename)

指定された属性名の属性値を返します。

Object

getAttributeNames()

すべての属性名を返します。

Object

getCookie(name)

指定された名前のCookie値を返します。通常のブラウザのCookieの制限がすべて適用されます。

Object

getCookies()

すべてのCookieを返します。

Object

getLocale()

ロケールを返します。

Object

getSiteId()

サイトIDを返します。

Object

getSiteName()

サイト名を返します。

Object

getUser()

ユーザー・オブジェクトを返します。

Object

getUserName()

ユーザー名を返します。

void

removeCookie(name, properties)

Cookieを削除します。

void

setAttribute(attributename, attributevalue)

属性を設定します。これらの属性には、他のアプリケーションからアクセスできます。

void

setCookie(name,value,expiredays,properties)

Cookieを設定します。

様々なビューを使用したアプリケーションの登録

WEMフレームワークで、アプリケーションを公開するために登録すると、FW_ApplicationタイプのアセットおよびFW_Viewタイプのもう1つのアセットが、アプリケーションに関連付けられた各ビューに作成されます。これらのアセット・タイプは、AdminSiteで有効になります。

これらの属性は、Oracle WebCenter Sites Java APIリファレンスに定義されています。プログラムによる登録をお薦めします。手動登録の例は、「WEMフレームワークでのアプリケーションの手動登録」を参照してください。

トピック:

iframeビューを使用したアプリケーションの登録

この項では、Articlesサンプル・アプリケーションのコードを使用して登録プロセスについて説明します。Articlesには、iframeタイプの単一ビューが含まれます。JavaScriptおよびHTMLのビューにも同じステップが適用されます。

アプリケーションを登録するには::

  1. アプリケーションを表すアイコンを作成または取得します。(アイコンは、アプリケーション・バーに表示されます。)

    (Articlesサンプル・アプリケーションは、/sample app/articles/src/main/webapp/images/にあるarticles.pngイメージ・ファイルを使用します。)

  2. アプリケーションのレイアウト(つまり各ビュー)をHTMLで指定するファイルを作成し、ビューでレンダリングされるコンテンツを保持するためのプレースホルダ・エレメントを作成します。次の図に、アプリケーションとビューの関係を示します。

    たとえば、Articlesサンプル・アプリケーションのlayout.jspには次の行が含まれます。

    <div id="articles" style="float:left;height:100%;width:100%" class="wemholder"></div>

    ビューのコンテンツは、アプリケーションが表示される際にプレースホルダ・エレメント内にレンダリングされます(layout.appがアプリケーションのレイアウトをレンダリングし、home.appがビューをレンダリングします)。

    ノート:

    レイアウト・ファイルの作成時に、プレースホルダ・エレメントに一意のidを指定します。viewオブジェクトをコーディングする際には、同じidparentnode属性に指定します。プレースホルダ・エレメントにclass="wemholder"を使用します。

    図48-4 アプリケーションとビュー

    図48-4の説明が続きます
    「図48-4 アプリケーションとビュー」の説明

    アプリケーションとビューは、多対多の関係にあります。1つのアプリケーションで複数のビューを使用でき、各ビューは複数のアプリケーションで使用できます。登録済のビューは(ビューのアセットIDによって)共有可能です。アセットIDが省略されている場合は、そのアプリケーションのコンテキスト内にビューが作成されます。ベーシックの場合、1つのアプリケーションに関連付けられるビューは1つのみです。

  3. PUT wem/applications/{applicationid} RESTサービスを起動して、アプリケーションBeanを指定します。
  4. Beanにビュー・アセットとアプリケーション・アセットに移入します。

    iframeビューの場合、Articlesサンプル・アプリケーションのコード(InstallController.java)を使用します(コメント行// Create a new view objectおよび// Create a new application objectを見つけます)。layouturl属性を設定して、アプリケーションのレイアウト・ページのURLを指定します。

    Articlesアプリケーションで、次のように、layouturl属性をlayout.app (LayoutController.javaで実装)のURLに指定します。

    app.setLayouturl(config.getArticlesUrl() + "/layout.app");
    
  5. 登録プロセスの結果をテストするには、WEM Adminインタフェースに一般管理者としてログインし、メニュー・バーで「アプリケーション」を選択します。このページにアプリケーションが一覧表示されるはずです。

JavaScriptビューおよびHTMLビューを使用したアプリケーションの登録

HTMLビューおよびJavaScriptビューを使用するアプリケーションの場合、「iframeビューを使用したアプリケーションの登録」のステップに従いますが、次の各項に示すサンプル・コードと属性を使用します。

JavaScriptビューのレンダリング

ノート:

ビューで指定したJavaScriptは、アプリケーションがレンダリングされるときにレンダリング(実行)されます。JavaScriptが他のビューと競合しないようにしてください。

サンプル・コード:

   window.onload = function () { 
      if (GBrowserIsCompatible()) { 
        var map = new GMap2(document.getElementById("map_canvas")); 
        map.setCenter(new GLatLng(37.4419, -122.1419), 13); 
        map.setUIToDefault(); 
      } 
   }
  • ソースURLからのJavaScriptビューのレンダリング

    次の属性を設定します。

    • name: ビューの名前

    • parentnode: (「iframeビューを使用したアプリケーションの登録」のステップ2からの)プレースホルダ・エレメントのID

    • viewtype: fw.wem.framework.ScriptRenderer。プレースホルダ・エレメントにJavaScriptをレンダリングします。

    • sourceurl: .jsファイルのパス。ビューのコンテンツを提供します。たとえば: http://example.com:8080/js/drawTree.js

  • ソース・コードからのJavaScriptビューのレンダリング

    次の属性を設定します。

    • name: ビューの名前

    • parentnode: (「iframeビューを使用したアプリケーションの登録」のステップ2からの)プレースホルダ・エレメントのID

    • viewtype: fw.wem.framework.ScriptRenderer。プレースホルダ・エレメントにJavaScriptをレンダリングします。

    • javascriptcontent: JavaScriptコード(前述のサンプル)。<script>タグはコードに含めないでください。

HTMLビューのレンダリング

ノート:

ビューで指定したHTMLは、アプリケーションがレンダリングされるときにレンダリング(実行)されます。

サンプル・コード:

<object width="480" height="385">
 <param name="movie" value="http://www.localhost:8080/jspx/flash_slider_main.swf"></param>
 <param name="allowFullScreen" value="true"></param>
 <embed src=" http://www.localhost:8080/jspx/flash_slider_main.swf"
  type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"
  width="480" height="385">
 </embed>
</object>
  • ソースURLからのHTMLビューのレンダリング

    次の属性を設定します。

    • name: ビューの名前

    • parentnode: (「iframeビューを使用したアプリケーションの登録」のステップ2からの)プレースホルダ・エレメントのID

    • viewtype: fw.wem.framework.IncludeRenderer。プレースホルダ・エレメントにJavaScriptをレンダリングします。

    • sourceurl: ビューのコンテンツを提供するHTMLファイルのパスです。たとえば: http://example.com:8080/js/drawTree.jsp

  • ソース・コードからのHTMLビューのレンダリング

    次の属性を設定します。

    • view: ビューの名前

    • parentnode: (「iframeビューを使用したアプリケーションの登録」のステップ2からの)プレースホルダ・エレメントのID

    • viewtype: fw.wem.framework.IncludeRenderer。プレースホルダ・エレメントにJavaScriptをレンダリングします。

    • includecontent: HTMLコンテンツ(前述のサンプル。<html>または<body>タグはコードに含めないでください。)