2008年12月19日金曜日

Surf Dev. Guide [2.10 テンプレートのレンダラ ]

2.9 テンプレートの種類
本文なし

------------------------------------------------------------------------------
2.10 テンプレートのレンダラ
下記の例は「share」の「search.ftl」である。


<#import "import/alfresco-template.ftl" as template />
<@template.header>
<link rel="stylesheet" type="text/css" href="${url.context}/templates/wiki/wiki.css" />
</@>

<@template.body>
<div id="hd">
<@region id="header" scope="global" protected=true />
<@region id="title" scope="template" protected=true />
</div>
<div id="bd">
<div class="yui-t1">
<div id="yui-main">
<@region id="search" scope="template" protected=true />
</div>
</div>
</div>
</@>

<@template.footer>
<div id="ft">
<@region id="footer" scope="global" protected=true />
</div>
</@>




------------------------------------------------------------------------------
2.11 テーマ
本文なし

Surf Dev. Guide [2.8 テンプレートのインスタンス ]

2.8 テンプレートのインスタンス
このサンプルは「share」の「site-data/template-instances/search.xml」である。
指定されているFreeMarkerレンダラは、「classes/alfresco/templates/org/alfresco/search.ftl」である。


<?xml version='1.0' encoding='UTF-8'?>
<template-instance>
<template-type>org/alfresco/search</template-type>
<properties>
</properties>
</template-instance>



上記のサンプルがうまくいく理由は、「テンプレート型」がSurfにとって未知である
(すなわち、webscript,fremarker,などでない)場合には、それをfreemarkerと仮定して
指定のURLから見つけてくるからである。

この他、より明示的に指定する方法としては:



<template-instance>
<template-type>freemarker</template-type>
<url>org/alfresco/search</url>
<properties>
</properties>
<template-instance>

2008年12月18日木曜日

Surf Dev. Guide [2.7 ページ関連]

2.7 ページ関連
ページ関連オブジェクトによって、2つのページを一緒にリンクすることができます。
最も一般的なのな、このリンクは型において子であり、意味するのは
ナビゲーションツリーのような確定した構造を表現することです。
しかし、別の型も可能であり、「ページ関連」が単一の確定木構造だけを
サポートする手段として使用すべきという要件はありません。

関連を使用しての、複数の木構造も可能です。この関連の性質は、
子を超えて拡張した場合、分類子、カテゴリ、タグに非常に類似しています。
言い換えれば、ページが他のページに関連付けられているとしても、
同時に他の要素にも側面からの関連付けを持たせてもよいのです。
これは、ファセットナビゲーションやタグクラウドの実装を考慮しています。

保管場所

/WEB-INF/classes/alfresco/site-data/page-associations


プロパティ

  • id => オブジェクトのid (オプション)

  • title => ページ関連のタイトル (オプション)

  • description => ページ関連の説明 (オプション)

  • source-id => 親要素のid、たいていはページid

  • dest-id => リンクした要素のid、たいていはページid

  • assoc-type => 関連の型



2.7.1 サンプルのページ関連

<page-association>
<title>Products</title>
<source-id>page.home</source-id>
<dest-id>page.products</dest-id>
<assoc-type>child</assoc-type>
</page-association>



注:ホームページと製品ページのリンクは、子の関係を使用している
現在のところ、子の関係のみがSurfプラットホームで認識されます。

Surf Dev. Guide [2.6 ページ]

2.6 ページ
「ページ(page)」とはWebアプリケーションで到達できるページです。
複数の他ページやそのページをキーとしてテンプレートと繋がる複数のフォーマット
と関連することもあります。ページは、トップレベルのオブジェクトであり、
そこを元にして追加的なナビゲーションやレンダリングのパスをたどることができます。

保管場所

/WEB-INF/classes/alfresco/site-data/pages


プロパティ

  • id => オブジェクトのid (オプション)

  • title => コンポーネントのタイトル(オプション)

  • description => コンポーネントの説明(オプション)

  • template-instance => このページを表示するためのテンプレートインスタンスのid

  • authentication => このページを見るために要求される認証(none,user,adminなど)



2.6.1 サンプルのホームページ

<page>
<title>My Home Page</title>
<template-instance>home-main</template-instance>
<authentication>none</authentication>
</page>



注記:シンプルな認証されていないのホームページ
レンダリング時に、ページのマークアップ表示は、ページから
「home-main」テンプレートへ移譲される。

2.6.2 サンプルのホームページ( 2つのフォーマット、ユーザー認証が必要)

<page>
<title>My Home Page</title>
<template-instance>home-main</template-instance>
<template-instance format="print">home-print</template-instance>
<authentication>user</authentication>
</page>



注:アクセスするにはユーザー認証が必要です。
印刷フォーマットが要求された場合、結果表示のために別テンプレート
(home-print)が活躍する。

1つのJVMで異なるライブラリを使用する環境を使う

JBOSSのアプリケーション内から、GlassFishのクライアントコンテナを使用するようなこと。
J2EE関連のライブラリ(JAR)などが競合しそうで、そのままでは使用できそうもない。

アイデア1) GlassFish環境でRMIサーバを立ち上げてRMIベースで連携
そもそも、GlassFishを使用するのはEJBを使うためなので、
RMI->EJB では、ごてごてしすぎだしパフォーマンスも悪くなる
EJB(RMI/IIOP)は単なる接続だけなら製品間のInteroperabilityがあるようだが、
  LoadBalanceやFailOverがからむと、専用のクライアントコンテナが必要になったりする

アイデア2) JavaModeleSystemを使用する:まだドラフト状態

アイデア3)OSGi を利用する:バンドル毎に異なるライブラリを定義できる
 JBOssなどのAppContainerから使用できるかが問題(要調査)

用語:
・Java Module System : 使用するライブラリの集合をモジュールとして定義できる
JSR 277  JAM形式のファイルにパッケージしてモジュールを分離
       リポジトリを持ち、動作時に使用するものを判断してロード
 RubyGemやPerlCPAMに似たしくみ

・OSGi Open Services Gateway initiative
JSR 291: Dynamic Component Support for Java SE
  バンドル毎に異なるライブラリを指定してインストールを動的に行える
  現状ではMinifestベース
 使用している製品 Apache Felix、Knopflerfish、Eclipse Equinox

2008年12月15日月曜日

Surf Dev. Guide [2.5 コンテンツ関連]

2.5 コンテンツ関連

「コンテンツ関連」オブジェクトが意図しているのは、Surfプラットホームが
入力されたコンテンツ部品に対するビュー表示をいかにして処理すべきかという
ことである。

別の言い方をするなら、エンドユーザが指定されたドキュメントに対する
詳細情報を表示するためにリンクをクリックしたとする。目的とするのは
そのドキュメントを開くことではなく、メタデータやプロパティを表示することである。

Surfプラットフォームを使用すると、「document-details-viewer」と呼ぶ
汎用ページを定義することができます。エンドユーザーがシステム内の任意の
文書についての詳細を表示したい時には、このページを使用してもらいたいでしょう。

「コンテンツ関連」を作成し、そのドキュメントとそのページを関連づける
ことでそれが可能になります。特定の文書(オブジェクトidによる)だけでなく、
特定のタイプのドキュメント(オブジェクト型idによる)を関連付けることができます。
ページインスタンスだけでなく、ページ型に対しても関連させられるんのです。

Surfプラットホームで実現していることは、エンドユーザーがドキュメントを
クリックして、「コンテンツ関連」のインスタンスに目を向けられるように、
このコンテンツを表示するためにどこに行くべきかを識別することである。
表示されるページとドキュメントコンポーネントは、利用可能なすべての
コンテンツを有しており、再読み込みが不要である。

保管場所

/WEB-INF/classes/alfresco/site-data/content-associations


プロパティ

  • id => オブジェクトのid (オプション)

  • title => コンテンツ関連のタイトル

  • description => コンテンツ関連の説明

  • source-id => 関連させるコンテンツ型

  • dest-id => コンテンツ型を表示するページまたはコンポーネント

  • assoc-type => 関連の型, 例) page, etc.



2.5.1 サンプルの構成

<content-association>
<title>details: cm_content</title>
<source-id>{http://www.alfresco.org/model/content/1.0}content</source-id>
<dest-id>page.content.details</dest-id>
<assoc-type>page</assoc-type>
</content-association>



注:「http://www.alfresco.org/model/content/1.0 コンテンツ」という型のコンテンツと
表示の時に使用される「page.content.details」というidを持つページとの関連:
This is an example of how you might use the Surf platform to render Alfresco content into a page.
これが例示するのは、Alfrescoコンテンツをページとして表示させるには、
Surfプラットフォームをどう使用すればいいかということ。

Surf Dev. Guide [2.4 構成]

2.4 構成
構成オブジェクトはXMLの集合体であり、その目的は、自然であり妥当なものです。
構造化され永続化されたXML(プロパティとメンバーが分かっている)を持つモデルオブジェクトとは裏腹に、
1つの「構成」が要件としてもつのは、たった1つのこと --- 1つの「id」 --- である。
このidは、XMLから特定されるかファイル名から決定されます。

一般的に、高度なカスタマイズを要する以外は、「構成」オブジェクトを
扱う要はありません。 それらは、主にシステムによって内部的に使用されています。

保管場所

/WEB-INF/classes/alfresco/site-data/configurations


プロパティ

  • id => オブジェクトのid (オプション)

  • title => コンポーネントのタイトル

  • description => コンポーネントの説明



2.4.1 サンプルの構成
「構成」オブジェクトが使用されている場所の1つは、
「global site」に関連する情報を格納するためのです。
現在、 「web site」オブジェクトという概念は、存在しません。
代わりに、「web site」の構成は「構成XMLファイル」として格納されます。
一例はこちら(注意 「root-page」要素は最初に呼び出されるもの):


<configuration>
<title>Surf Platform 3.0 Sample Site</title>
<description>Surf Platform 3.0 Sample Site</description>
<source-id>site</source-id>
<properties>
<root-page>welcome</root-page>
</properties>
</configuration>



注:このXMLは、任意にどんな構造でも持たせることが可能です。
この意味では、構成オブジェクトのことを汎用モデルオブジェクトとして考えることができます。

Surf Dev. Guide [2.3 コンポーネント]

2.3 コンポーネント

コンポーネントは、 コンポーネント型のインスタンスであり、領域またはスロットに属します。
コンポーネントと結合することで、インスタンスはその固有状態を表明することになります。
保管場所

/WEB-INF/classes/alfresco/site-data/components


プロパティ

  • id => オブジェクトのid (オプション)

  • title => コンポーネントのタイトル

  • description => コンポーネントの説明

  • component-type => コンポーネント型id (optional)

  • scope => 結合のスコープ (「global」, 「template」または「page」のどれか).

  • region-id => コンポーネントを領有する領域(またはスロット)のid

  • source-id => コンポーネントが結合する「global」か「page」id か「template」

  • url => レンダラによって実行されるファイルへのパス



2.3.1 サンプルWebScriptコンポーネント

<component>
<scope>page</scope>
<region-id>content</region-id>
<source-id>welcome</source-id>
<url>/test/configtest</url>
</component>


注記: 「pageスコープ」のコンポーネントが、「welcome page」の「content領域」に入ります。
コンポーネント型が指定されていないため、URLプロパティが検査され、WebScriptであると判断されます。
したがって、このコンポーネントでは、 urlが「/test/configtest」であるWebScriptが実行されます 。

2.3.2 サンプルのJSPコンポーネント

<component>
<component-type>jsp-sample-component-type</component-type>
<scope>template</scope>
<region-id>news</region-id>
<source-id>product</source-id>
</component>


注:「templateスコープ」のコンポーネントが、「productテンプレート」の「new領域」に所属します。
コンポーネント型は「jsp-sample-component-type」であり、これは前にサンプルとしてあげています。
これは、JSPレンダラであり、すべてのレンダリング情報はコンポーネント型の上に含まれています。

2008年12月10日水曜日

Surf Dev. Guide [2.2 コンポーネント型]

2.2 コンポーネント型

コンポーネント型とは、Webサイトビルダーが把握し生成する物であり、
Webアプリケーションの多くの箇所で使用されます。新規インスタンスは領域
(またはスロット)にはめ込むことでページと結合します。他のフレームワーク
では、時として「ウィジェット」、「ガジェット」、「ポートレット」、または
「dashlet」と呼ばれています。

保管場所

/WEB-INF/classes/alfresco/site-data/component-types


プロパティ

  • id => オブジェクトのid (オプション)

  • title => コンポーネント型のタイトル

  • description => コンポーネント型の説明

  • renderer-type => レンダラのid (設定で定義、典型例:webscript, jsp, java)

  • renderer => レンダラによって実行されるファイルへのパス




2.2.1 サンプルのWebScriptコンポーネント型

<component-type>
<title>Alfresco RSS Newsfeed Component</title>
<description>Displays a configurable number of Alfresco news items</description>
<renderer-type>webscript</renderer-type>
<renderer>/sample/alfresco-newsfeed</renderer>
</component-type>


注記: レンダラは、WebScriptのXML説明文書内で定義されているWebScriptへのURL

2.2.2 サンプルのJSPコンポーネント型

<component-type>
<id>jsp-sample-component-type</id>
<title>Alfresco RSS Newsfeed Component</title>
<description>Displays a configurable number of Alfresco news items</description>
<renderer-type>jsp</renderer-type>
<renderer>/app/components/alfresco-newsfeed</renderer>
</component-type>


注記: レンダラは、 JSPファイルへのパス(web-application相対的)

2.2.3 サンプルのJava Beanコンポーネント型

<component-type>
<title>Alfresco RSS Newsfeed Component</title>
<description>Displays a configurable number of Alfresco news items</description>
<renderer-type>java</renderer-type>
<renderer>org.alfresco.web.site.ui.AlfrescoRSSNewsFeed</renderer>
</component-type>


注記: レンダラは、インスタンス化される Java Beanのクラス名。
このJavaクラスは、「Renderable」インターフェイスを実装する必要があります。
これに関しては別のセクションでより詳細に扱います。

Surf Dev. Guide [2 オブジェクトモデル]

2 オブジェクトモデル

Webアプリケーションの基本セクションでは、Surfプラットホームのデータモデル
に関して高次の概要を説明していた。本セクションで、各オブジェクトタイプの詳細に入る。

------------------------------------------------------------------------------
2.1 クロム

クロムは、コンポーネントの周辺を取囲む境界要素を意味するものである。
これら境界要素とは、「影付け」のようなスタイル要素を含んだり、
ページにドラッグアンドドロップ機能を付加するものだったりする。
また、ポップアップコンポーネントを設定するボタンのような
「ユーザ機能」を付加させることもある。(しばしばポータルで見かけるもの)

デフォルトでは、クロムはSurfプラットホーム内では最小限に留められています。
新しいコンポーネントが、ページに追加されると、Webアプリケーションのための
デフォルトchromeを受け取ることになります。(当初は空の既製品)

保管場所

/WEB-INF/classes/alfresco/site-data/chrome


プロパティ

  • id => オブジェクトのid (オプション)

  • title => クロムのタイトル

  • description => クロムの説明

  • renderer-type => レンダラのid (設定で定義)

  • renderer => レンダラによって実行されるファイルへのパス



2.1.1 サンプルのJSPクロム

<chrome>
<title>Sample Chrome 1</title>
<renderer>/app/sample-chrome-1.jsp</renderer>
<renderer-type>jsp</renderer-type>
</chrome>


注記: レンダラは、 JSPファイルへのパス(web-application相対的)

2.1.2 サンプルWebScriptクロム

<chrome>
<title>Sample Chrome 2</title>
<renderer>/sample/chrome-2</renderer>
<renderer-type>webscript</renderer-type>
</chrome>


注記: レンダラは、WebScriptのXML説明文書内で定義されているWebScriptへのURL

2.1.3 領域用サンプルクロムテンプレート
@コンポーネントを使用して、領域内のコンポーネントを含めることができます。


<div id="${htmlid}">
<@component/>
</div>



2.1.4 コンポーネント用サンプルクロムテンプレート
@componentIncludeを使用して、コンポーネントが表示される場所を指定できます。


<!-- Start Debug Component Chrome -->
<div style="border: 2px black solid">
<div style="background-color: #aaaaaa; border-bottom: 1px black solid; color: white; padding: 2px"><B>${htmlid}</B></div>
<div style="background-color: #dddddd; padding: 2px">
<@componentInclude/>
</div>
</div>
<!-- End Debug Component Chrome -->

2008年12月9日火曜日

Surf Dev. Guide [1.4 レンダラ]

1.4 レンダラ

新規テンプレートや新規コンポーネントとして定義するために行うのは、
Surfプラットホーム用のモデルオブジェクトを記述するXMLを書くことである。
モデルオブジェクトの役割は、Surfプラットホームに、コンポーネントの存在と
コンポーネントを処理する方法についての情報を与えることである。
とはいっても、後からテンプレートやコンポーネントがどう表示されるかの
情報は開発者が与える必要があります。そのために、「renderer」が必要になります。

少数の「renderer」が既製品として提供されていますが、自分用に追加してもかまいません。
サポートされる既製品の「renderer」は、以下のものである。

  • WebScript

  • Freemarker

  • JSP

  • HTML


1.4.1 WebScriptレンダラ

WebScriptレンダラは、最先端のレンダラであり、これを利用することで
(pre-render処理で)JavaScriptの、(presentation処理で)Freemarkerの、
という2つの利点を活用できることである。

もし以前に、Alfrescoの「web script engine」を利用してWebScriptを構築
したことがある方々は、既に知っていることと思います。
それ以外の場合は、 WebScriptガイドを見てください 。

Surfプラットホーム内では、WebScriptがコンポーネントを表示するためには
最も一般的に使用されます。自分のWebScriptを構築したならば、
/ WEB-INF/classes/alfresco/site-webscriptsのディレクトリに配置します。
少し経つと、コンテナがそれを拾い上げ、自分のモデルオブジェクトから
使用できるようになります。

WebScriptを使用することをコンポーネント側に指示するには、
WebScriptのURLプロパティに適切なurlを設定すること。

1.4.2 FreeMarkerレンダラー

Freemarkerレンダラは、テンプレートを表示する場合に最もよく使用されます。
また、WebScriptレンダラとの組み合わとして自動的に使用されますが、
それはコンポーネントに適用される場合だけです。テンプレートを作成すると、
Freemarkerを直接使用することができます。

Freemarkerテンプレートを作成していて、Alfrescoで使用している方々は
何ができるかについてはすでに熟知していることでしょう。そうでない場合は、
「Alfresco Freemarkerテンプレートガイド」を参照してください。

Surfプラットホーム内では、Freemarkerの「.ftl」テンプレートファイルは、
/ WEB-INF/classes/alfresco/templates ディレクトリに配置することができます 。
少し経つと、テンプレートプレセサがそれを拾い上げ、自分のモデルオブジェクトから
アクセスできるようになります。

テンプレート側にFreemarkerの「.ftl」ファイルを使用することを指示するために
「template-type」パラメータにファイルパス(/templatesからの相対)を
設定すること。

1.4.3 JSPレンダラー

JSPレンダラは、 コンポーネントまたはテンプレートのどちらかを表示するために
使用されており、Java言語の全てとSurfプラットホームのJavaAPIへのアクセスを提供
しています。使用するには、Javaプログラミングの知識が必要です。

JSPレンダラを使用するには、「.jsp」ファイルを作成して、web-applicationの
任意の場所に配置する必要があります。ただし、慣例として /app/components
ディレクトリの下に配置することをお勧めします。

一旦配置した後で、JSPのパス(web-application相対)に対してのレンダラプロパティ
を設定します。後の方で詳しく説明します。

Surf Dev. Guide [1.3 モデルオブジェクト]

1.3 モデルオブジェクト

Surfプラットホームには、それが管理し参照する必要があるオブジェクトのデータモデルが含まれ、
それによって、Webアプリケーションを正しく表示できます。
これらのモデルオブジェクトはメモリに標準的POJO(Plain Old Java Object)として管理されています。
ディスクに書き込むときには、 XMLとしてシリアル化されます。

XMLが格納されるのは、次の場所にあるサブディレクトリです:

/WEB-INF/classes/alfresco/site-data


このディレクトリ内には、次のようなサブディレクトリがモデルオブジェクトの
タイプ毎に1つ存在し、Surfプラットホームによって管理されています:

/site-data/chrome
/site-data/component-types
/site-data/components
/site-data/configurations
/site-data/content-associations
/site-data/page-associations
/site-data/page-types
/site-data/pages
/site-data/template-instances
/site-data/template-types
/site-data/themes


各サブディレクトリ内には、シリアル化されたモデルオブジェクトを表すXMLがあるはずです。
たとえば、デフォルトのalfwf.warファイル内では、welcome.xml というファイルがあります 。
これは、「welcome」というidを持つページであり、内容は次のXMLとなっています:

<?xml version='1.0' encoding='UTF-8'?>
<page>
<title>The test welcome page</title>
<template-instance>welcome-main</template-instance>
<authentication>none</authentication>
</page>


各オブジェクトタイプの正確な意味は、オブジェクトモデルのセクションで
扱われるので、ここでは一般的な感じを示すにとどめます。
XMLを調べて分かることは、これがページであり、
そのタイトルは「The test welcome page」。
テンプレートは「welcome-main」というidで示されること。
アクセスには 認証を必要としないこと。

新規ページまたは新規コンポーネントまたは何らかのモデルオブジェクトを作成するには、
これらのディレクトリに新しいXMLを配置すればよい。
すなわち、データベースにアクセスする必要も、Webクライアントをカスタマイズする必要もないのです。

2008年12月8日月曜日

Surf Dev. Guide [1.2 振分サーブレット]

1.2 振分サーブレット

振分サーブレットの責務は、ユーザーにページを表示することです。
着信要求コンテキストを考慮して、何をどのように表示するかを明確化する
必要があります。
振分が受信可能な要求は、以下のものです:

特定のページ
ページIDが、振分に対して直に送付されることがあります。
ページタイプ
例として、ユーザーがログインページを要求するとします。
アプリケーションが実際には複数のログインページを持っており、
(顧客向けに1つ、 パートナー向けに1つ、従業員向けに、、、など)
そこから1つ選択し、表示して返す必要があります。
オブジェクト
An object id may be given to the dispatcher.
オブジェクトIDが、振分に送付されることがあります。
The dispatcher must then figure out which page to use to render this object.
その場合、振分はこのオブジェクトを表示するためにどのページを使用すべきかを
明確化する必要があります。
他にも組み合わせや、順序の違いが数多くあり得ます。
よって、振分サーブレットは、最小限の工数で動作をカスタマイズできるように
実装されています。
これら拡張機能の正確な性質は、上級編で扱います。

2008年12月5日金曜日

Surf Dev. Guide [1.ウェブアプリの基本]

1 ウェブアプリケーション基礎
このセクションはSurfプラットホームウェブアプリケーションについて説明します。
一般に、SurfプラットホームウェブアプリケーションはWARとしてパッケージされます。
デフォルトで作成されるalfwf.warファイルは、そのようなWARファイルの一例です。

1.1 構成
 WARファイルを展開すると、ここで示すような構成になっています:
 

/core
/css
/images
/WEB-INF
/WEB-INF/classes/alfresco
index.jsp



いくつかのディレクトリが追加されることもありますが、これらが基本構成です。
それはまさに純然たるウェブアプリケーションです。

初めに注目するファイルは「web.xml」であり、WEB-INFの下に位置します。
サーブレットコンテナは、始動時にこのファイルを読み込みます。
「web.xml」の中に、サーブレットとSpringオブジェクトのための設定があります。
それは軽量に保たれますが、いくつかのセクションに注意するべきです。

以下のセクションは「Spring Framework コンテキスト」にロード方法を示します。
Springは、Surfプラットホームに含まれていて、その責務はBeanの管理と生成になります。
このセクションで「webscript-framework-application-context.xml 」が導入されます。
(WebScript Engine構成をロードする)
それから、「web-framework-application-context.xml」を導入します。
(Surfプラット設定をロードする)

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:alfresco/webscript-framework-application-context.xml
classpath:alfresco/web-framework-application-context.xml
</param-value>
<description>Spring config file locations</description>
</context-param>



一度 Webアプリケーションを起動すると、いくつかのサーブレットが利用可能になる。
DispatcherServletもその一つであり、要求をSurfプラットフォームへと導く
主要なハンドラとなっている:

<servlet>
<servlet-name>pageRendererServlet</servlet-name>
<servlet-class>org.alfresco.web.site.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>pageRendererServlet</servlet-name>
<url-pattern>/page/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>pageRendererServlet</servlet-name>
<url-pattern>/p/*</url-pattern>
</servlet-mapping>



リクエストがWebアプリケーションに到着してindex.jspをたたくと、
ディスパッチャサーブレットに転送されます。(/pageへのフォワード)

Alfresco3.0/Suf

SurfPlatformはAlfrescoが持っている、WebApplicationFrameWorkであり、
AlfrescoECMへのAPIを有するCMSといった感じ。基本的にはDashletという
構成部品をならべることでページを作成する。

Surf Platform - Developers Guide

概要を調査

Contents 内容

1 Web Application Basics ウェブアプリの基本
1.1 Structure 構成
1.2 Dispatcher Servlet 振り分けサーブレット
1.3 Model Objects モデル
1.4 Renderers レンダラー
1.4.1 Web Script Renderers WebScriptレンダラー
1.4.2 Freemarker Renderers FreeMarkerレンダラー
1.4.3 JSP Renderers JSPレンダラー

2 The Object Model オブジェクトモデル
2.1 Chrome クロム
2.1.1 Sample JSP Chrome 例:JSPクロム
2.1.2 Sample Web Script Chrome 例:WebScriptクロム
2.1.3 Sample Chrome Template for Region 例:領域に対するクロムテンプレート
2.1.4 Sample Chrome Template for Component 例:コンポーネントに対するクロムテンプレート
2.2 Component Type コンポーネント種別
2.2.1 Sample Web Script Component Type 例:WebScriptコンポーネント
2.2.2 Sample JSP Component Type 例:JSPコンポーネント
2.2.3 Sample Java Bean Component Type 例:JavaBeansコンポーネント
2.3 Component コンポーネント
2.3.1 Sample Web Script Component 例:WebScriptコンポーネント
2.3.2 Sample JSP Component 例:JSPコンポーネント
2.4 Configuration 設定
2.4.1 Sample Configuration 例:設定
2.5 Content Association コンテンツ関連
2.5.1 Sample Configuration 例:設定
2.6 Page ページ
2.6.1 Sample Home Page 例:ホームページ
2.6.2 Sample Home Page (two formats, user authentication required) 例:ホームページ(2形式、認証が必要)
2.7 Page Association ページ関連
2.7.1 Sample Page Association 例:ページ関連
2.8 Template Instance テンプレート
2.9 Template Type テンプレート種別
2.10 Template Renderer テンプレートレンダラー
2.11 Theme テーマ

3 Creating a New Template 新規テンプレートの作成
3.1 Freemarker Example FreeMarkerの例
3.2 JSP Example JSPの例
4 Creating a New Component 新規コンポーネントの作成
4.1 Web Script Example WebScriptの実例
4.2 JSP Example JSPの実例
4.3 Java Bean Example JavaBeansの実例
5 Advanced Surf Platform Configuration SurfPlatformの応用設定
5.1 Request Context 要求コンテクスト
5.2 Page Mapper ページマッパー
5.3 Users ユーザ
5.4 Link Builder リンクビルダ
5.5 File Systems ファイルシステム
5.6 Formats フォーマット
5.7 Model Types モデル種別
5.8 Tag Libraries タグライブラリ
5.9 Renderers レンダラー
5.10 Content Loaders コンテンツローダ
5.11 Error Handlers エラーハンドラ
5.12 System Pages システムページ
5.13 Dispatcher Defaults 振り分けの省略時設定
5.14 Application Defaults アプリケーションの省略時設定
5.15 Debug Settings デバッグ設定
5.16 Advanced Remote Configuration リモートの応用設定

GetProcess.cmd

状況によっては、内部で作成している WShell.exec("xx") の部分が非同期にならず、
PIDを取得しようとした時に当該プロセスが存在しないというエラーになる場合があった。
んで、改良版がこれ。呼び出すプロセスとしてcscript.exeの代わりにcmd.exeを
使用し、pauseにて入力を待つようにした。これだと非同期に実行でき、不要に
なったらさっと片づけられる。


@if(0)==(0) ECHO OFF
:: GetProcessId.cmd ver 1.2
:: PolymorphicScript(CMD/JSCRIPT)
:: http://scripting.cocolog-nifty.com/blog/2007/01/index.html
:: V1.1 20081127 ST(KRB)
:: V1.2 20081202 ST(KRB) replace vbs with self script cause file permission
:: V1.3 20081205 ST(KRB) use cmd.exe for inspect pid instead of cscript.exe
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end
//
var error_level = 0;
try
{
var pGene = 0;
if(WScript.Arguments.Named.Exists("P")) {
pGene = WScript.Arguments.Named.Item("P");
}
if(WScript.Arguments.UnNamed.Length==0) {
PrintPPid(GetPID(), pGene);
//WScript.Echo(GetPPID(GetPID()));
error_level = 0;
} else if(WScript.Arguments.UnNamed.Length==1) {
PrintPPid(WScript.Arguments.Item(0), pGene);
// WScript.Echo(GetPPID(WScript.Arguments.UnNamed.Item(0)));
error_level = 0;
} else {
WScript.StdErr.WriteLine("Usage: GetProcessID.CMD [/P:n | PID]");
error_level = 2;
}
}
catch(e)
{
WScript.StdErr.WriteLine("error:" + e.message);
error_level = 1;
}
finally
{
WScript.Quit(error_level);
}

function PrintPPid(ipid, igen){
var result = ipid;
for (var i=0;i <= igen;i++){
result = GetPPID(result);
}
WScript.Echo(result);
}

function GetPID(){
var Path=WScript.ScriptFullName;
var wShell=new ActiveXObject("WScript.Shell");
// if use cscript.exe ,cannot run as async mode
var oExec=wShell.Exec('cmd.exe /C pause');
var PID=GetPPID(oExec.ProcessID);
try{
// Terminate() may needs waite time for several seconds
// so input as enter to 'pause' cmd
oExec.StdIn.WriteLine("");
oExec.Terminate();
}
catch(e)
{
// none
}
return PID;
}

function GetPPID(PID){
var SWbemObjectSet=GetObject("winmgmts:root/CIMV2").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" + PID);
if(SWbemObjectSet.Count!=1){
WScript.StdErr.WriteLine("ID " + PID + " Not Found.");
WScript.Quit(1);
}
var Processes=new Enumerator(SWbemObjectSet);
for(;!Processes.atEnd();Processes.moveNext()){
var Process=Processes.item();
return Process.ParentProcessID;
}
}

2008年12月4日木曜日

Alfresco

プロジェクトでワークフローを伴ったWebAppの開発をしそうなので、JavaベースのOSSを調査中。
他の候補としては、magnolia, openCms などがある。

1)Aflresco: ECM 中程度の重さ、ドキュメント管理から出発:
政府機関などで使用実績あり、単純な機能はScriptとFreeMarker
2)Magnolia: ECM 軽くてきびきび、ドキュメント管理、Webページも作成しやすい
ワークフローのカスタマイズに難あり
3)OpenCMS: CMS とにかく重い、Memoryが2G以上必要

----------------------------------------------------
1)概要
ドキュメントの生成、更新、削除などの履歴と権限管理
指定の権限者の承認でフォルダーを移動するなどのワークフロー
CMSやWebAppの機能は、比較的最近「Surf Platform」を使用
2)SurfPlatformでのDashletの作成手順
参考:Writing a Hello World Dashlet for Alfresco Share

xxxxId に対する GET で使用するページなら、以下のようなものを作成する
xxxxId.get.xml WebScript 概要など
xxxxId.get.ftl FreeMarker のテンプレート、UI(HTML系)定義
xxxxId.get.js サーバサイド機能
xxxxId.get.config.xml
xxxxId.get.desc.xml
xxxxId.get.properties ラベルの文字などのプロパティ

ftl で使用できるスクリプトの一例
${msg("hello.world")} プロパティファイルから指定エントリを読み込んで出力

3)ボタンなどを追加
参考:Learning Surf 4 - Modifying Share documentLibrary with Create content button

2008年12月2日火曜日

Win32でのPID取得スクリプト改良版

参考にしたものは、VBSのファイルを作成する部分があり、権限によって動作しない
場合があったので、改良してみた。オプションによりN世代親のPIDを取得できる。


@if(0)==(0) ECHO OFF
:: GetProcessId.cmd ver 1.2
:: PolymorphicScript(CMD/JSCRIPT)
:: http://scripting.cocolog-nifty.com/blog/2007/01/index.html
:: V1.1 20081127 ST(KRB)
:: V1.2 20081202 ST(KRB) replace vbs with self script cause file permission
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end
// check if sleep
if(WScript.Arguments.Named.Exists("S")) {
var wait_period;
wait_period = WScript.Arguments.Named.Item("S");
// dummy mode for make process
try{
WScript.sleep(wait_period * 1000 + 10);
}
catch(e)
{
// none
}
finally
{
WScript.Quit(0);
}
}
//
var error_level = 0;
try
{
var pGene = 0;
if(WScript.Arguments.Named.Exists("P")) {
pGene = WScript.Arguments.Named.Item("P");
}
if(WScript.Arguments.UnNamed.Length==0) {
PrintPPid(GetPID(), pGene);
//WScript.Echo(GetPPID(GetPID()));
error_level = 0;
} else if(WScript.Arguments.UnNamed.Length==1) {
PrintPPid(WScript.Arguments.Item(0), pGene);
// WScript.Echo(GetPPID(WScript.Arguments.UnNamed.Item(0)));
error_level = 0;
} else {
WScript.StdErr.WriteLine("Usage: GetProcessID.CMD [/P:n | PID]");
error_level = 2;
}
}
catch(e)
{
WScript.StdErr.WriteLine("error:" + e.message);
error_level = 1;
}
finally
{
WScript.Quit(error_level);
}

function PrintPPid(ipid, igen){
var result = ipid;
for (var i=0;i <= igen;i++){
result = GetPPID(result);
}
WScript.Echo(result);
}

function GetPID(){
var Path=WScript.ScriptFullName;
var wShell=new ActiveXObject("WScript.Shell");
var oExec=wShell.Exec('CScript.exe //B //E:Jscript "' + Path + '" /S:0');
var PID=GetPPID(oExec.ProcessID);
try{
oExec.Terminate();
}
catch(e)
{
// none
}
return PID;
}

function GetPPID(PID){
var SWbemObjectSet=GetObject("winmgmts:root/CIMV2").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" + PID);
if(SWbemObjectSet.Count!=1){
WScript.StdErr.WriteLine("ID " + PID + " Not Found.");
WScript.Quit(1);
}
var Processes=new Enumerator(SWbemObjectSet);
for(;!Processes.atEnd();Processes.moveNext()){
var Process=Processes.item();
return Process.ParentProcessID;
}
}

Win32でのRuntime.getRuntime().exec() のexitCode

Cscript.exe などを実行すると、エラーがでてもexitCodeは「0」のまま?
どうも、明示的に指定しておかないといけないらしい。つまり、WScript.Quit(n)
を入れておかないと、CScript.exe は正常終了と考えてしまうようだ。

■例

var error_level = 0;
try
{
// varius processes
if (ok){
error_level = 0;
}else{
error_level = 2;
}
}
catch(e)
{
WScript.StdErr.WriteLine("error:" + e.message);
error_level = 1;
}
finally
{
WScript.Quit(error_level);
}