フォトアルバム

2011年10月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

なかのひと

373news.com

google Search

  • Google
    blog.ganymean.org
    WWW

Google Analytics

CFMX開発

ColdfusionでPHP/Ruby!

Coldfusionがスタンドアロンモードで動作するようになったので、Sean corfieldが昨年6月に公開したブログ記事「ColdFusion 8 running PHP and Ruby!」を試してみることにした。

どうしてColdfusion8でPHPやRubyが利用できるようになったかというと、①Java6でマルチスクリプトがサポートされた(JSR-223)、②Caucho社がJava6対応オープンソースPHPスクリプトエンジンQuercusをリリースしたことによるようです。

ダウンロード先は、Scripting for ColdFusion 8 になります。詳細は、RIAForgeも参照してください。

なお、Coldfusion用PHPエンジンのインストール方法は以下のとおりです。

  1. ダウンロードファイルを解凍する。
  2. cfphpディレクトリ内のlib/quercus.jar と lib/resin-util.jar を coldfusion8/lib (スタンドアローン版) もしくは WEB-INF/cfusion/lib/ (マルチサーバ版) にコピーする。
  3. php.cfmをカスタムタグに登録する。
  4. Coldfusionを再起動する。

また、Resin版Railo用PHPエンジンのインストール方法は、以下のとおりです。

  1. ダウンロードファイルを解凍する。
     
  2. resin-util.jarとquercus.jarは、Resinにインストール済のためコピー不要。
  3. php.cfmをカスタムタグに登録する。
  4. Railoを再起動する。

Seanのブログでの使用例は、以下のとおりです。

<cfset who = "Sean" />
  <cf_php>
     <?php
        echo "Hello ".$_COLDFUSION["who"]."<br />";
        $_COLDFUSION["greeting"] = "wibble";
     ?>
  </cf_php>
  <cfoutput>greeting = #greeting#</cfoutput>

ポイントは、.$_COLDFUSION[]。
これを使って、Coldfusion -> PHP、PHP -> Coldfusion 間でデータをやりとりするようです。

続きを読む "ColdfusionでPHP/Ruby!" »

Apache2+RailoにColdfusion8.01をスタンドアロンモードで同居させる

先週、xampp環境でRailoとapacheを連携させる ためのセットアップを行った。
これで、Coldfusionデベロッパー版は不要になるかな?と考えていたのだが、cfcgeneratorが使えなくなることにふと気づいた。
cfcgeneratorは、Coldfusion8が動作するAdminapiコンポーネント(wwwroot/CFCIDE/adminapi配下)にアクセスするため次の2つのCF開発環境を準備した。

  1. Apache2.2+Railo3.0(Railoスタンドアロンモード:8600番ポート)
  2. CF8スタンドアロンモード

通常の動作テストは Apache2.2+Railo3.080番ポート 、
cfcgeneratorを使用する場合のみ CF8スタンドアロンモード:8500番ポート 、
にすることとしよう。

さて、CF8をスタンドアロンモードでインストールすると、そのウェブルートは、

C:/Coldfusion8/wwwroot/

となります。
また、そのウェブサーバ(8500番ポート)は、Jrun上に構成され、そのコンフィグ情報は、

C:/Coldfusion8/wwwroot/WEB-INF/jrun-web.xml

にあります。
CF8ドキュメント『ColdFusion の設定と管理』の「第 5 章 : Web サーバーの管理」を参照すると、

ビルトイン Web サーバーに別の Web ルートディレクトリのページを提供させる場合は、次の例に示すように、"<ColdFusion のルートディレクトリ>/wwwroot/WEB-INF/jrun-web.xml" ファイル (マルチサーバー設定の場合は "<JRun のルートディレクトリ>/servers/cfusion/cfusion-ear/cfusion-war/WEB-INF/jrun-web.xml" ファイル) に仮想マッピングを定義します。

つまり、"<ColdFusion のルートディレクトリ>/wwwroot/WEB-INF/jrun-web.xml" ファイル に仮想マッピングを定義すれば良いようです。私が追加した仮想マッピング定義は、以下の3ブロックです。

<virtual-mapping>
    <resource-path>/CFIDE</resource-path>
    <system-path>C:/Coldfusion8/wwwroot/CFIDE</system-path>
</virtual-mapping>

<virtual-mapping>
    <resource-path>/cfdocs</resource-path>
    <system-path>C:/Coldfusion8/wwwroot/cfdocs</system-path>
</virtual-mapping>

<virtual-mapping>
    <resource-path>/*</resource-path>
    <system-path>C:/xampp/htdocs</system-path>
</virtual-mapping>

<virtual-mapping>
  <resource-path>/WEB-INF</resource-path>
  <system-path>C:/ColdFusion8/wwwroot/WEB-INF</system-path>
</virtual-mapping>

Answer from Railo developper!

ModelGlue3(Gesture)がRailoでエラーメッセージを吐く事象について、ModelGlue-MLとRailo-MLに各々投げました。結果、以下のようになりましたー。

1 Create Java Object エラー
  Railoのバグ:ネクストリリースでバグフィックス予定。

2 include .cfm インクルードエラー
  Railoの仕様(ポリシー)
  以下のステートメントは、認めない。

<cfset this = variablues />

   以下のステートメントで代用。

<cfloop collection="#variables#" item="key">
    <cfset this[key]=variables[key] />
</cfloop>

  パッチファイルをModelGlue-MLに投げました・・・


Do not work the gesture helpers on Railo!

Railo3.0(Ver3.0.0.005 for Windows)で、Model-Glue 3.0(Gesture)のサンプルアプリケーションを動かしてみた。
helpers機能を利用するサンプリアプリケーションが動作しない。
問題は2つあるようだ。

1.MathLib.cfm
 インクルードエラー(Include error)

 MathLib.cfmを直接コールしてみると、次のようなエラーが返される。RailoのMLに問い掛け中・・・

Railo 3.0.0.005 Error (Java.lang.verifyerror)
Message (class: modelglue/helpers/cflib/mathlib$cfm, method: udfCall8 signature: (Lrailo/runtime/PageContext;Lrailo/runtime/type/UDF;I)Ljava/lang/Object;) Illegal target of jump or branch
Java Stacktrace
(class: modelglue/helpers/cflib/mathlib$cfm, method: udfCall8 signature: (Lrailo/runtime/PageContext;Lrailo/runtime/type/UDF;I)Ljava/lang/Object;) Illegal target of jump or branch
at java.lang.Class.getDeclaredConstructors0(Native Method):-2
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source):-1
at java.lang.Class.getConstructor0(Unknown Source):-1
at java.lang.Class.newInstance0(Unknown Source):-1
at java.lang.Class.newInstance(Unknown Source):-1
at railo.runtime.PageSourceImpl.a(Unknown Source):-1
at railo.runtime.PageSourceImpl.a(Unknown Source):-1
at railo.runtime.PageSourceImpl.loadPage(Unknown Source):-1
at railo.runtime.PageContextImpl.include(Unknown Source):-1
at railo.runtime.listener.ClassicAppListener._onRequest(Unknown Source):-1
at railo.runtime.listener.MixedAppListener.onRequest(Unknown Source):-1
at railo.runtime.PageContextImpl.execute(Unknown Source):-1
at railo.runtime.engine.CFMLEngineImpl.serviceCFML(Unknown Source):-1
at railo.loader.servlet.CFMLServlet.service(CFMLServlet.java:32):32
at javax.servlet.http.HttpServlet.service(HttpServlet.java:91):91
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103):103
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:175):175
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:240):240
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:263):263
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:481):481
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:685):685
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:607):607
at java.lang.Thread.run(Unknown Source):-1

2.IncludeHelperShell.cfc
  インクルードCFMのCFC関数化ができていない。
 Coldfusionでは動作する以下のステートメントがRailo3.0では無視される・・・
 <cfset this = variables />

 結果として、該当ファンクション無しエラーが発生。
 RailoでのDUMP結果は以下のとおり。Railo固有のバグか・・・

Component (ModelGlue.gesture.helper.Helpers)
Only the function and data member that are accesible from your location are displayed
Hint I act as a target for the helpers loaded into a Model-Glue application.
public
DateLib
Component (ModelGlue.gesture.helper.IncludeHelperShell)
Only the function and data member that are accesible from your location are displayed
Hint I am a shell CFC into which an include-based helper file is loaded.
public
INIT
init
Includes a .cfm's functions into this CFC.
Public Function init
arguments
label name required type default hint
TEMPLATE false string null
return type any

   

Railo3.0リリース!

「気楽に行こう」のブログで、Model-GlueがRailoで見事撃沈されたと紹介されていたのだが、RaymondがRailo3.0のリリースを紹介していたので、初めて試してみた・・・

  • CF8サポート
  • 非サポートは、一般Webアプリでは気にならない・・・
  • マルチメディア強化(CFVIDEO)

Model-Glue(Gesture)のサンプルアプリケーションを流してみたが、すべては通らないないようだ。
helper機能はNG。その他バグもあるみたい・・・
でも、Coldfusionと比較して軽いような印象をうける。今後、VPSサイトで運用できそうかかんじ・・・

Railoは、非日本語サポートなので、翻訳作業ボランティアに手をあげるかなあー。

Model-Glue3.0の新機能9:Model-Glueリモーティング

Model-Glue3.0の新機能9は、Model-Glueリモーティングです。

Joe曰く、「HTMLだけのWebアプリは終わりました。典型的なColdFusionアプリケーションは、HTMLおよびFlex(Flexベースのウィジェット)の両方を包含することになるでしょう。」とのことです。確かにそうですね。

★Flex / Flashのサポート
Gestureでは、HTMLのエントリーポイントとしてのindex.cfmはもちろん、FlexまたはFlashウィジェットのためのエントリポイントとしてのModelGlueGateway CFCも含みます。

★Flexアプリでのユーザリスト取得例
JSON(.XMLデータも同様):

<event-handler name=”user.list.page”
        <broadcasts>
        <message name=”needUserList” />
        </broadcasts>
        <views format=”HTML,HTMLPartial”>
        <include template=”dspUserList.cfm” name=”body” />
        </views>
        <views format=”JSON”>
        <include template=”dspDataAsJson.cfm” name=”body”>
                <value name=”data” name=”userQuery” />
        </include>
        </views>
        <results format=”HTML”>
        <result do=”view.template” />
        </results>
</event-handler>

. MXML:

<mx:RemoteObject id=”modelGlueGateway”destination=”ColdFusion”source=”ModelGlueGateway” />

. AS3:

var event:ModelGlueEvent =new ModelGlueEvent(“user.list”, [“userQuery”]);
modelGlueGateway.runEvent(event);

現時点では未実装ですが、HTML、Flex、Flashのエンドポイントに対応できることは大変楽しみです。
Model-Glue:Gestureは、Model-Glue:Flexを統合することになるのでしょうか?

Model-Glue3.0の新機能8:マルチ出力フォーマット対応

Model-Glue3.0の8番目の新機能は、マルチ出力フォーマット対応機能です。
なお、この機能は現時点で未実装ですので、注意してください。

Webアプリケーション用MVCフレームワークは、もはやWebページだけでなく、さまざまな出力フォーマットに対応できる必要があります:

  • HTML形式
  • 部分HTML形式
  • XML形式
  • JSON形式

今までのModel-Glue開発では、悪評の高い重複作業が発生していました。
つまり、N個のフォーマット形式に対応するため、N個のイベントハンドラーを必要とします。

HTMLフォーマット:

<event-handler name=”user.list.page”>
        <broadcasts>
        <message name=”needUserList” />
         </broadcasts>
        <views>
        <include template=”dspUserList.cfm” name=”body” />
        </views>
        <results>
        <result do=”view.template” />
        </results>
</event-handler>

断片HTMLフォーマット(<div>置換):

<event-handler name=”user.list.pagepartial”>
        <broadcasts>
        <message name=”needUserList” />
        </broadcasts>
        <views>
        <include template=”dspUserList.cfm” name=”body” />
        </views>
</event-handler>

XMLフォーマット:

<event-handler name=”user.list.xml”>
        <broadcasts>
        <message name=”needUserList” />
        </broadcasts>
        <views>
        <include template=”dspDataAsXML.cfm” name=”body”>
                    <value name=”data” name=”userQuery” />
        </include>
        </views>
</event-handler>

JSONフォーマット:

<event-handler name=”user.list.json”>
        <broadcasts>
        <message name=”needUserList” />
        </broadcasts>
        <views>
        <include template=”dspDataAsJson.cfm” name=”body”>
                <value name=”data” name=”userQuery” />
            </include>
        </views>
</event-handler>

Gestureでは、<broadcasts>、<views>、<results>ブロックは、特定のフォーマットだけに作用するように設定できます。
フォーマット名は、URLまたはFormのHTTP要求で指定される要求メッセージの書式設定方法(デフォルト:"requestFormat")です。
これにより、Gestureでは4つのフォーマットを1つのイベントハンドラーで定義可能となります:

<event-handler name=”user.list.page”>
    <broadcasts>
        <message name=”needUserList” />
        </broadcasts>
        <views format=”HTML,HTMLPartial”>
            <include template=”dspUserList.cfm” name=”body” />
        </views>
        <views format=”JSON”>
        <include template=”dspDataAsJson.cfm” name=”body”>
                <value name=”data” name=”userQuery” />
        </include>
        </views>
        <results format=”HTML”>
        <result do=”view.template” />
        </results>
</event-handler>

Model-Glue3.0の新機能7:コンテンツキャッシュ

Model-Glue3.0の7番目の新機能は、コンテンツキャッシュ機能です。

ポイントは、以下の3点のようです。

  1. 大部分のMVCフレームワークは、何らかのキャッシングメカニズムを提供しています。
  2. Model-Glue3.0は、オブジェクトキャッシュを提供しません。サービス層の仕事だと思うからです
  3. Model-Glue3.0は、コンテンツキャッシュを"dead-simple"に提供します。

★キャッシュキーとタイムアウト
以下のコードは、アプリケーションスコープにおいて、コンテンツ内にhomepageというキーがあるものをキャッシュします。タイムアウト時間は、300秒です。

<event-handler name=”page.home” cache=”application” cacheKey=”homepage” timeout=”300”/>

★キャッシュキー・バリュー(Cachekeyvalues)
.イベントキーからダイナミックにキャッシュを生成するには、CacheKeyValues を使用します。

<event-handler name=”user.profile” cacheKeyValues=”sessionId”/>

<event-handler name=”product.details” cacheKeyValues=”productId”/>

★キャッシュの解除方法は?
.コントローラー内のリスナー関数で、指定イベントのキャッシュキーを無効にできます:

<cfset beans.cacheAdapter.purge(“page.home”) />

続きを読む "Model-Glue3.0の新機能7:コンテンツキャッシュ" »

Model-Glueの新機能6:Beanインジェクション

Model-Glue3.0の6番目の新機能は、Beanインジェクション機能です。

一言でいうと、Autowiringがより便利になったよ!ってことです。

Model-Glue2.0では、コントローラ内に"ビーンA"のsetter関数を定義することによって、コントローラーが"ビーンB"をビーンAに自動的にAutowiringします。

Model-Glue3.0では、Beanインジェクション機能という名称に進化し、コントローラ内のsetter関数定義が一切不要になりました。

どういうことかと言うと、"Beans"スコープをビーンCFCに定義するだけで、コントローラーが直接Autowiringしてくれるというものです。便利!

<cfcomponent beans=”someDAO” />

また、 コントローラー内では、以下のように使い方もできます。

  <cfset beans.SomeDAO.save(SomeThing) />


Model-Glue3.0の新機能5:ヘルパー

Model-Glue3.0の5番目の新機能は、ヘルパー機能です。

以前のModel-Glueで使用してきたUDFはどうなるのでしょうか?
. 以前のModel-Glueでは、UDFの使用は、ちょっと不便でした・・・
. view内でUDFライブラリーをインクルード可能であったが、そのための厄介な設定が必要でした。
. またコントローラー層で利用できませんでした。

★簡単なヘルパー:Include-Style
. CFLib.orgのdateLib.cfmを"/helpers"フォルダに配置すると、そのすべての関数がコントローラーと
  ビューの内部で"helpers"スコープ関数として利用できます。

<cfoutput>#helpers.dateLib.daysTilXmas()#</cfoutput>

★簡単なヘルパー: CFC-Style
. ヘルパー関数として動作するCFCを"/helpers"フォルダに配置すると、
  includeのようにそのすべての関数が"helpers"スコープにコピーされます。

Model-Glue3.0の新機能4:SES URLとURLマネージャー

Model-Glue3.0の4番目の新機能は、SES URLとURLマネージャーです。

. SES URLをサポートしました。
  index.cfm/eventname/key1/value1/key2/value2 形式でのSES URLでアクセス可能です。

. オーバーホールされたEventContext常駐アーキテクチャーのおかげで、URLManagerを通してSES URLをプラグイン的に実装することができました。

. SES URLセーフであるViewをビルドするために、イベントコンテキスト機能を使用します:

  <a href=”#event.linkTo(“user.profile”, “userId,profileId”) />

このように、Viewファイルに記述すると、リンクURLは、次のようにSES形式/非SES形式の両方でアクセス可能となります。

  • 非SES URL形式:index.cfm?userId=2&profileId=42
  • SES URL形式 :index.cfm/userId/2/profileId/42

Model-Glue3.0の新機能3:Application.cfcとの統合

Model-Glue3.0の3番目の新機能は、Application.cfcとの統合です。

. アプリケーション開始、セッション開始もしくはセッション終了を知りたい場合、
. Model-Glue3では、メッセージリスナーに次のように定義するだけです:

<message-listener message=”onApplicationStart” .../>
<message-listener message=”onSessionStart” .../>
<message-listener message=”onSessionEnd” .../>

Model-Glue3.0の新機能2:イベントタイプ

Model-Glue3.0の2番目の新機能は、イベントタイプ(Event Type)です。

この機能は、ModelGlue.xmlファイルの<Event-handler>タグ内でサイト横断的なビューテンプレートを使用すると、<results>タグを反復して記述する必要があります。

<event-handler name="do.this">
    <results>
        <result do="view.template" />
    </results>
</event-handler>

Model-Glue3.0では、イベントハンドラーのサブクラスを定義することによって、イベント完了後に継続して実施するイベントをイベントタイプの引数として与えられるようになっています。つまり、

<Event-handler name="do.this" type="events.templatedEvent" />

"view.template"を実行する<results>タグだけを定義したイベント"events.templatedEvent"をtype属性で与えると、"do.this"の実行後に、"events.templatedEvent"が実行されるという仕掛けです。

定義するイベントのサブクラスは、<results>タグの他に、<broardcasts>タグや<views>タグを含めることができます。

Model-Glue3.0の新機能1:イベント自動生成

Model-Glue3.0の新機能1は、Event eneration(イベントの自動生成)です。

一言でいうと、Model-Glue.xmlのイベントハンドラーを逐一定義せずに、URLにイベントを定義していくと、自動的にイベントが作成され、対応するコントローラー(CFC)、ビューファイル(CFM)、イベント定義&リスナー定義ファイル(ModelGlue.xml)を作成してくれるという優れものです。
この機能は、開発モード(deveropment=true)のみで提供されます。
ColdBoxで先行提供された機能ですが、私もまだ試していないので、あとから実施に試してみます(笑。

以下のYouTubeは、Joe RinehartによるEvent Genarationのデモビデオです。
雰囲気をつかむのには、いいかもしれません。

YouTube: Model-Glue 3 (

続きを読む "Model-Glue3.0の新機能1:イベント自動生成" »

Model-Glue3(Gesture)αリリース!

先週末は、久しぶりにCF-OOP関連のサイトを渡り歩いた。
理由は、Flex3やAIR(APPLO)がリリースされて以降、ColdFusionの開発環境に大きな刺激が加わり、Model-Glue:Unityでは限界かなあと思い始めていたからであった。

そういう意味では、ColdBox が一番開発ニーズを先取りしているような気がしたのだが、Model-Glueが先月3.0(コードネーム:Gesture)をαリリースしていたので、こちらを先にチェックしてみることにした。

Model-Glue3(Gesture)の新機能は、SVN内の開発ロードショウ.PDFを抜粋すると、以下のとおりです。
      ■Model-Glue3.0の新機能
・新機能1:イベント自動生成(開発モード)
・新機能2:イベントタイプ
・新機能3:Application.cfcとの統合
・新機能4:SES URLとURLマネージャー
・新機能5:ヘルパー
・新機能6:Beanインジェクション(Autowiring)
・新機能7:コンテンツキャッシュ
・新機能8:マルチ出力対応 ※未実装
・新機能9:Model-Glueリモーティング ※未実装

ColdBoxに先を越された分、しっかりと原点に返っているような気がします。
次回以降、意訳したものを紹介していこうと思います。



Model-Glue:UnityにおけるAutowiringのミステリー

久しぶりにブログを書く気になりました。
サボッていた自分にムチ打って、継続は力なりを実践しようと思います。

今日は、Model-Glue:UnityにおけるAutowiringについて、プレゼンテーション資料を作成したので、Googleドキュメントを使って公開してみようと思います。

続きを読む "Model-Glue:UnityにおけるAutowiringのミステリー" »

Ajax Scaffolds in ModelGlue

Ajax・・・世の中全盛ですね。
Joe Rinehartが、ModelGlue:UnityでAjaxベースのScaffoldsを行う方法を彼のブログで紹介しています。

Video: Ajax Scaffolds in Model-Glue

彼のビデオをadamが彼のブログで要約しています。
ご参考まで!

CFOpenID

OpenIDって、Coldfusionの自分サイトで使ってます?
日本における代表的OpenID認証サイトであるopenid.ne.jpでは以下のようにOpenIDが紹介されています。

  • OpenIDとは、webサイトのURL 形式で構成されたユーザーの身元確認をするためのIDです。
  • 誰でもインターネット上で自分の情報を作成・管理することができます。
  • 発行されるOpenIDはウェブ構築のまさに核心部分と呼べるURL形式で構成されているため、スパムメールや不正アクセス等の心配がなく、安全にログインすることができます。
  • OpenIDとは、webサイトのURL 形式で構成されたユーザーの身元確認をするためのIDです。

OpenID認証サーバ用のプロジェクトとして、RIAForgeでOpenID認証フレームワークが立ち上がっています。このフレームワークを使って、OpenID認証サーバも立ち上げてみようと思います。

また、OpenIDに関して、Brian RinaldiのColdfusion  Open  Source  Update で2つの記事が紹介されていたので、ご参考に!

続きを読む "CFOpenID" »

cf.objective 2007 サマリ

Coldfusionファンには、生唾ものの情報です。

CF-OOPのまとめをしなきゃと思って、本家メンバーのRSSフィードをチェックしていたら、cf.objectiveのプレゼン概要を、Matt Woodwardが日々google Docs形式でアップしています。ご覧あれ!

 cf.objective 2007 - Jason Delmore KeynoteColdFusion Weekly Flickr Photos
 Mark Mandel - Intro to Transfer ORM
 Hal Helms - Object Modeling
Sean Corfield - AJAX in Scorpio
Adam Lehman - .NET and Exchange Integration with Scorpio 
 CFEclipse Project - Mark Drew
Adam Lehman - Scorpio Server Monitoring and Alerts
 Peter Farrell - Head First Mach-II
 Peter Farrell - What's New in Mach-II 1.5
Jason Delmore - 1337 Scorpio
Sean Corfield - Real World SOA With ColdSpring and Transfer
Ben Forta - Top Secret Scorpio
 Dave Ross - ColdSpring 101
 Maxim Porges - Maximizing Your CF/Flex Applications With Java

 


Mach-IIとColdspringの統合

ModelGlue:UnityとColldspringの統合アプリケーションは希少なので、Mach-IIとColdspringの統合例を探してみました。テンプレート的なものから本格的なものまで以下の3つが大変参考になります。

  1. appbooster(Kurt Wiersma、テンプレート的アプリ)
  2. M2bookstorereactor(Matt Williams、ORM:Reactor使用)
  3. Machblog(Matt Woodward / Peter J. Farrell、本格ブログ)

また、Kurt Wiersmaのプレゼンは、大変わかりやすです。ご参考までにどうぞ!

Coldfusion最新アーキテクチャ

Brian KotekのmgbookstorereactorのUnity版を作成してから、Coldfusionによるアプリケーション設計の最新アーキテクチャを再検証してみました。
FrameworkConference2007におけるプレゼンターからColdspring関連のものを拾い出してみると、以下の記事が目に付きます。

  1. Leveraging ColdSpring To Make Better Applications(Kurt Wiersma)
  2. Designing Framework-Agnostic Models with CFCs(Brian Kotek)
  3. ColdSpring Powered Fusebox Applications(Adam Wayne Lehman)

Kurtのプレゼンは、ModelGlue、Mach-II、Fusebox5などのWebアプリケーション用Framework間でCFCsを共用するためためのサービスアーキテクチャについて言及されています。

 Brianのプレゼンは、ModelGlueとFlexでCFCsを共用するためのアーキテクチャについて、言及されています。

Virtualreprentationofservicelayer_3 Apparchtecture

 

 

 

 

 


 


 



 


これをふまえると、ModelGlue:UnityのCFC設計では、

 

  1. Contoller.cfcでserviceのsetter/getterとビジネスロジックを定義
  2. service.cfcでエンティティ(VO)やDAO、Gatewayへのsetter/getterを定義

     

し、あとはColdspringを使って、各オブジェクトをAutowireしたり、AOPを展開すればよいようです。AOPのサンプルパターンを絵にすると、以下の絵になると思います。

Coldspringaopsample

 

 

MG1.1からMG:Unityへのアップグレード(その1)

ModelGlue:UnityによるCFアプリケーション開発の慣らし運転として、ModelGlue1.1ベースで作成されたサンプルアプリケーションをModelGlue:Unityにアップグレードしてみます。

選定するサンプルアプリケーションは、以前の記事で紹介したBrian Kotekのmgbookstorereactor。DIにColdspringを、ORMにReactorを使用しているので、ModelGlue:Unityへの移行ポイントがつかみやすいと思います。

移行ポイントは、以下の3点になります。

  1. Coldspring.xmlによる依存性注入パラメータの集中管理
  2. ormAdaptorとormServiceによるORM選択(Reactor/Transfer)
  3. 各種コントローラからinit()メソッドの削除

続きを読む "MG1.1からMG:Unityへのアップグレード(その1)" »

CF-OOPのリソースリスト

昨日に続いて、CF-OOPに関する頭の体操をしています。
やはり、参考になるのは、Brian Rinaldi のディレクトリかなあーと思って、ググッてみると、
Objects and Frameworks - the Big Resource List
というタイトルで、CF-OOPマニアにはヨダレが垂れるような記事をわかりやすく整理してくれています。

これを読んで頭慣らしかなあー。

なんでもRSSのHack-2

なんでもRSSのHackで鹿児島県内の公的団体(自治体、マスコミ、観光協会など)のホームーページからRSSを自動抽出するために、nandemoRSS.cfcなるものを作成してみた。

ポイントは以下のとおり。

  1. ターゲットURLとレスポンスモード(RSS)を指定して、なんでもRSSをgetする。
  2. rdf:liでRSSのリストを返すので、各RSSの解析キー:keyを取得する。
  3. 全ての解析キー:keyを指定して、なんでもRSSを再度getする。
  4. get結果をXMLドキュメントにして、配列に放り込む。

鹿児島県のトップページ例は、こちら からどうぞ。
また、ソースを見たい方は、コメント か右下のフォームからメールください。

cf_googlemap

Brian RinaldiのThe ColdFusion Open-Source Project Listを久しぶりに眺めていたら、CF_GoogleMapというGoogle Maps用カスタムタグを見つけました。
以前紹介したCFGoogleMapsというCFCと異なるアプローチですが、こちらのほうが結構使いやすいかもしれません。
ただし、日本国内のGeocodingはサポートされていないので、住所に対する位置情報は別途与える必要があります。

使用可能なタグは、以下の5つです。

  • CF_GoogleMap
    • マップ表示領域とデフォルトビューを定義する親タグです。
    • このタグ内部に残りの3つのタグを配置します。
  • CF_GoogleMapIcon
    • 位置情報表示用のカスタムアイコンを定義します。
  • CF_GoogleMapLine
    • 複数のCF_GoogleMapPointを直線で結びます。
  • CF_GoogleMapPoint
    • マップ上に位置情報を定義します。
    • 位置情報をインフォメーションウィンドウで表示したり、CF_GoogleMapLineタグ内部に複数配置すると、直線を引けます。
  • CF_GoogleMapShow
    • 地図を表示するために、CF_GoogleMapタグの直後に配置します。

サンプルスクリプトは、以下のとおりです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
</head>
<body>
<cf_googlemap width="500" height="300" key="#Application.GoogleMapKey#" maptype="map">
<cf_googlemappoint title="Bashas" address="4321 E. Baseline Rd gilbert az 85234" lon="-111.74097" lat="33.379044">
</cf_googlemap>
<cf_googlemapshow>
</body>
</html>



			

CFCベスト・プラクティス

ColdFusionオブジェクト指向プログラミング・ユーザーのための
「CFCベスト・プラクティス」がPeter Bellのブログで紹介されています。
さくっと意訳してみました。

詳しくは、CF-OOP Wikiを確認してください。

  1. メソッド内のローカル変数には、常に"var"を使え!
    • ループカウンタ
    • テンポラリ変数
  2. パブリックデータへのダイレクトアクセスは厳禁!
    • コンポーネント名.メソッド()でアクセスしろ!
    • パブリックデータへのダイレクトアクセスは、インタフェースの設計に反します。
    • 良い例
      foo = myCFCInstance.getInterestingStuff()
      myCFCInstance.setInterestingStuff(foo)
    • 悪い例
      foo = myCFCInstance.interestingStuff
      myCFCInstance.interestingStuff = foo.
  3. プライベート・データとして、"this"スコープを使用するな!
    • "this"は、"variables"スコープのことです。
  4. "arguments"は、常に明示するか、一切明示しないかのどちらかにしろ!
    • 常時、明示するのがお勧めです。
  5. CFCOMPONENTとCFFUNCTIONタグでは、「OUTPUT="false"」にすること!
    • ファンクションの実行結果をページに書き出したいのであれば、cfmファイルに以下のように記述すること。
      "#myCFC.someHTMLGeneratingMethod()#"
  6. ドキュメントの可読性向上のため、CFCOMPONENT/CFFUNCTION/CFARGUMENTの"hint"属性を必ず使用すること!
  7. CFFUNCTIONのRETURNTYPE属性 と CFARGUMENTSのTYPE属性 は必ず指定しろ。
    • ドキュメントの可読性向上とランタイムによる型式チェック速度向上のためです。
    • ファンクションが何も返さないのであれば、RETURNTYPE="void"を忘れずに!
    • カスタムオブジェクト型を使用する場合、TYPE="any"とすることで、速度パフォーマンスが向上する。
  8. CFC内で外部変数を直接参照しないこと!
    • session変数やapplication変数など
    • 例外は、ウェブサービスやFlashリモーティング用にファザード(facade)を構築するときだけです。
  9. メソッド引数のうち、必須でないものには"DEFAULT"値を指定すること!
  10. CFCタグの"EXTENDS"は、"is-a"として使用しろ!"has-a"やコード再利用目的で使用するな! 

RIAForge

Adobe製品によるRIA(Rich Internet Application)支援サイトが
立ち上がっています。 その名も、 RIAForge

Coldfusion, Flex, Flash, DreamWeaver, Livesycle, PhotoShop

Coldfusionだけではなく、その他Adobeプロダクト用の
オープンソースが入手できるのは大変ありがたい。

Model-Glue:Unityドキュメント意訳

Model-Glue:Unity公式ドキュメントの意訳をmediawikiで立ち上げました。

具体的なプログラミング方法やサンプルプログラムも随時アップしていく予定です。
ご質問や間違いなどがあれば、このブログの左サイドバーのメールフォームからご連絡ください。

どうぞよろしくお願いします。

ColdSpring in MG:Unity No.3

ColdSpringの公式ドキュメントのAutoWiringを意訳してみました。
前回紹介したpropertyチャイルドタグ/constructor-argチャイルドタグは、依存性の注入方法を規定していましたが、beanタグのautowire属性はColdSpringが注入先のCFCをどのようにして発見するかを規定していて、autowire属性が指定されていれば、セッターメソッドは不要であることが記述されています。
また、autowiringの設定には、"byName"および"byType"の2つがあるようです。

"autowire"とは、Bean定義用xmlファイルでお互いの依存性を定義せずに、ColdSpringのbeanFactoryが依存する相互のオブジェクトを自動的に結合する能力のことを指します。

ColdSpring beanFactoryの中でCFCsを定義すると、ColdSpringは各CFCのメタデータを点検して、他のCFCにpropertyかconstructor-argで指定するものがあるかどうかを探します。

autowiringはBeanFactory内で、デフォルトで'オフ'にされていますが、'オン'にセットすると(bean全体かbeanの要素毎にセットできます)、ColdSpringは自動的に、依存性の注入(と自動的にオブジェクト結合)を行います。

autowiringの設定には、"byName"および"byType"の2つがあります。

推測できると思いますが、"byName"は、beanのname属性つまりCFC内にsetSomeService(...)メソッドか"SomeService"をコンストラクタ引数に持つCFCとColdSpring.xmlでid="SomeService"がある<bean/>内のCFCを結合し、"SomeService"を該当するCFCにいつでも注入します。

"byType"は、ColdFusionコード内に"type"属性、つまり、セッターメソッドの引数(または、コンストラクタ引数に) type="type.of.SomeService"を使用することによって、ColdSpring.xmlにclass="type.ofSomeService"があるbeanがあれば、そのbeanを該当するCFCにいつでも注入します。

benaタグのエンティティ全体にautowiringをセットするには、default-autowire属性を使用してください:

<beans default-autowire="byName">
    <bean id="cfc1" class="..."/>
    <bean id="cfc2" class="..."/>
...
</beans>

各々のbean(default-autowire設定をオーバライドすることになります)にautowiringをセットするには、autowire属性を使用してください:

<beans>
    <bean id="cfc1" class="..." autowire="byType"/>
    <bean id="cfc2" class="..."/>
    <bean id="cfc3" class="..." autowire="byName"/>
...
</beans>

ColdSpring in MG:Unity No.2

前回に引き続き、Nandoのブログを紹介してみます。
Nando曰く、ModelGlue:UnityでColdSpringについて学ぶべきことは、最低3つとのことです。

最初に専念したほうがよいことは、Bean FactoryリファレンスのうちのBeanタグ属性Beanチャイルドタグチャイルドタグのconstructor-argとpropertyの3セクションです。

これらを理解すると、ModelGlueでColdSpingを使いこなすことができると思います。

なお、個人的には、Bean FactoryリファレンスAutoWiringDeveloping w/ColdSpringService Layers and ColdSpringも一読したほうがよいと思います。

beanのチャイルドタグであるpropertyタグとconstructor-argタグについて、Nandoは次のように解説しています。

1.propertyタグ

constructor-argと全く同様です。しかしながら、この場合、ColdSpringはname属性で特定されるセッターメソッドへの引数として何らかの単純変数かオブジェクトをBeanに渡します。

したがって、CFCには、propertyタグのname属性に合致するセッターメソッド名がなければなりません(例えば、propertyが"foo"なら、CFCはsetFoo()メソッドを必要とします)。

2.constructor-argタグ

constructor-argタグは、(CFCがinit()メソッドを通して)CFCが初期化されるときに、name属性で指定された引数を渡すことによって単純変数かオブジェクトへの参照をbeanに対して提供することを、Coldspringにもたらします。

以上の2つのチャイルドタグを使って、あるファクトリクラスの初期化の際にパラメータを注入する方法が、次のように紹介されています。

◆bean.xml
<!-- "samasati.model.appFactory"クラスを"appFactory"として定義 -->
<bean id="appFactory" class="samasati.model.AppFactory">
   <!-- appFactory.init()に対して、appConfigを引数として渡す -->
   <constructor-arg name="appConfig">
      <!-- AppConfigビーンを参照 -->
      <ref bean="AppConfig" />
   </constructor-arg>
</bean>

<!-- "ModelGlue.Bean.CommonBeans.SimpleConfig"クラスの"AppConfig"として定義 -->
<bean id="AppConfig" class="ModelGlue.Bean.CommonBeans.SimpleConfig">
   <!-- Bean"AppConfig"の引数の実体は、property"config" -->
   <property name="config">
      <map>
         <entry key="dsn"><value>samasati</value></entry>
         <entry key="imagePath"><value>images/</value></entry>
      </map>
   </property>
</bean>


◆someContoroller.cfc
<cffunction name="init" access="public" output="false">
   <cfargument name="appConfig" required="true">
   <!--- Instansiated by setAppConfig Method passed through arguments.appConfig --->
   <cfset setAppConfig(arguments.appConfig) />
</cffunction>

<!--- autowire setters and getters for bean id:AppConfig --->
<cffunction name="setAppConfig" access="public" returntype="void" output="false">
   <cfargument name="appConfig" required="true">
   <cfset variables.appConfig = arguments.appConfig />
</cffunction>
   
<cffunction name="getAppConfig" access="private" output="false">
   <cfreturn variables.appConfig />
</cffunction>
   
<!--- autowire setters and getters for bean id:AppFactory --->
<cffunction name="setAppFactory" access="public" returntype="void" output="false">
   <cfargument name="appFactory" required="true">
   <cfset variables.appFactory = arguments.appFactory />
</cffunction>

<cffunction name="getAppFactory" access="private" output="false">
   <cfreturn variables.appFactory />
</cffunction>

ColdSpring in MG:Unity

ModelGlue:Unityを使って本格的なアプリケーションを考えようと、過去の記事やModelGlue、ColdSpring、Reactorの公式サイトのドキュメントを眺めていました。

そんなところに、Sean CorfieldがNandoのブログを紹介しているのが目に留まりました。
彼は、ModelGlueやColdSpringのメーリングリストにおいて、NewBie的なアプローチから大きな貢献をしているので、彼の書く記事は私と同じ目線、つまり独学でColdFusionやオブジェクト指向(OO)を学んでいるため、非常に共感できるものがあります。

彼の記念すべき第一回目の記事は、The Mystery of AutoWiring in Model-Glue Unity
つまり、ModelGlue:UnityにおけるAutoWiringに関するものです。

AutoWiringは、ColdSpringの公式ドキュメントにおいて、以下のように定義されています。

"autowire"は、Bean定義用xmlファイルでお互いの依存性を定義せずに、ColdSpringのbeanFactoryが依存する相互のオブジェクトを自動的に結合する能力のことを指します。

このことをNandoも、最初のころはなんのこっちゃ全然わからんかったと言っています。

MGを学ぼうとする人々を困らせるように思えるものの1つは、autowiring機能です。

多くの人々が、ドキュメンテーションでまだそれほど明確に説明していないので、それが存在するのを知ってさえいないかもしれません。

autowiringを使いこなすには、ColdSpringを少しいじくる必要があります。

ColdSpringがColdFusionと異なった名称を使うので、最初は外国に行ったみたいな感覚になります。

ColdSpringでは、CFCをBean、structをmap、arrayをlist などと呼びます。

しかし、あなたがいったん使用される用語を翻訳して、少しそのやり方に慣れると、突然として、とても簡単に使用することができるようになります。

そして、Nando曰く、ModelGlue:UnityにおけるAutoWiringとは、次のようなことであると・・・

簡単に言うと、AutoWiringは、ColdSpringを使用してModelGlueのコントローラに記述されたCFCに初期化パラメータを注入する非常に便利な方法です。

そのことを、EmailServiceを例にとって、以下のように説明しています。

アプリケーション規模が大きくなると、おそらくModelGlueコントローラ内でサービスレイヤのCFCを初期化する必要が生じるでしょう。

そして、おそらくアプリケーションを論理的な単位に分割するため、複数のコントローラを使用し始めるでしょう。

そうなると、例えば、EmailService自身を初期化する代わりに、EmailServiceを必要とする各々のコントローラのinit()メソッドで、ColdSpringが作成するEmailServiceのインスタンスに初期化パラメータを注入する際に、AutoWiringを使えばいいのです。

うーん、こういう風に説明されると、とてもしっくりと頭に入ります。

以前の記事で紹介したように、第三世代のMVCフレームワーク、即ちModel層における単調なコードの繰り返し記述を回避するため、Modelをビジネスロジック、サービス、パーシスタントという複数レイヤに分割することを支援してくれるんだなーという実感です。

はてなキーワードAPI

Technoratiブログ検索で、鹿児島県内の地名や特産物に関するキーワードのクエリーを発行すると、該当するキーワードが記事エントリーに出現するブログのPermalinkを返してくれのだけど、いかんせん精度が悪い・・・
鹿児島に関する辞書やコーパスを持っていればいいのだが、メンテナンスするのも面倒くさい。ということで、一番安易な方法に頼ってみました。はてなキーワードAPIです。

naoyaさんのブログで、はてなキーワードAPIには、隠しモードで'lite'というのがあって、所与のテキストからキーワードを抽出してくれるようです。スコア(score)というパラメータで返すキーワードのしきい値を調整(重要語ほど値が大きい:0~100、20以上が目安)し、カテゴリ(cname)というパラメータリストで、地名(geometory)や食物(food)を絞り込むこともできます。

TechnoraiとはてなキーワードAPIをハックしたら、こんな感じになりました。左端に’鹿児島関連’がないブログは、はてなキーワードAPIからのキーワード抽出結果に検索ワードが返ってこなかったエントリーです。
ヒット精度は、90%くらいかな?
(米国の共用ホスティング環境で動かしているのでレスポンスが悪いのはご容赦を!)

ColdFusion用REST-API/XMLRPC-API

最近、TechnoratiウェブサービスやはてなWebサービスを使うことが多くなってきた。
スクラッチでRESTやXML-RPCのAPIを書こうかどうしようか迷ってぐぐってみたら、
RESTがSean Corfieldのブログで、XML-RPCがRoger Benningfieldのブログで
提供されていた。サンキュー、Sean and Roger!

続きを読む "ColdFusion用REST-API/XMLRPC-API" »

Technorati用API

Tekunoratiのブログ検索サービスは結構使えます。

日本国中から'鹿児島'というキーワードで最新ブログを検索してみると、
およそ1時間で20件程度のブログがヒットします。
これを、ColdFusion経由で呼び出すためのスクリプトをスクラッチで
書いていたら、さすがU.S.、Coldfusionデベロッパーはいるものです。

続きを読む "Technorati用API" »

Model-Glue:Unityサンプルアプリ

早速、Sean Corfieldが彼のブログでModel-Glue:Unity対応のサンプルアプリケーションggcc11をアップした。
このサンプルアプリケーションは、彼がFuseBox、Mach-II、Model-Glue、ColdSpring、TartanなどColdfusion向けFramework Sample Code、ggccシリーズの最新版です。
Model-Glue:Unityによって、

プレゼンテーション層:ModelGlue:Unity
コントローラー:ModelGlue:Unity(ビジネスロジック)
サービス層:ColdSpring
ORM層:Reactor

と各々のフレームワークが相当の機能を分担したため、今回Sean自身が書いたものは、プレゼンテーション層であるviewと、ビジネスロジック層のcontroller.cfcだけになっています。
私のホスティング環境では、エラーが発生しています。Reactor関連のパーミッションかもしれません。



Model-Glue:Unityの新機能

Joe RinehartがAdobe's Developers Weekで実施したModel-Glue:Unityのプレゼン内容を、Brian Rinaldiが彼のブログで紹介しています。

彼のプレゼンは、まだAdobeサイトにアップされていないので、Brian RinaldのブログからModel-Glue:Unityの新機能を読み取ってみます。

1.Model-Glue1.1との完全下位互換

  • Model-Glue1.1は、第二世代のフレームワークである。

即ち、MVCアーキテクチャを使って、プレゼンテーションからモデル層を分離することがその目的であった。
しかしながら、beans/Records、DAOs、Gatewaysなどの共通タスクを取り扱う繰り返しのコードを生むことになった。

  • Model-Glue:Unityは、第三世代のフレームワークである。

モデル層における単調な繰り返しコード生成作業を自動化する。

2.他のフレームワークとの統合

  • 第三世代フレームワーク化推進のため、他のフレームワークとの統合を図った。

ColdSpring
サードバーティサービスの統合と依存性の注入(DI/IoC)をの実現。
依存性の注入は、Model-GlueとReactorのコンフィグ情報をColdSpring.xmlに記述することで実現。
Reactor
ORMの自動化に、Reactorを採用。
ModelGlue自身が実装したData Controllerを使って、イベントハンドラー内の<message>タグでGDMと呼ぶメッセージを記述して、DAOやGatewayを呼び出す。

  • ModelGLue.GenericList(Gateway)
  • ModelGLue.GenericRead(Read)
  • ModelGLue.GenericCommit(Create&Update)
  • ModelGLue.GenericDelete(Delete)

ORM用フレームワークには、Reactor以外も利用可能であるが、自分自身でcustom adapter, DataController, 及びscaffold .XSL を作成する必要がある。

     

3.Scaffolding

  • XSLによるカスタマイズ可能なHTMLの "scaffolds(足場)"を実現。
  • ModelGlue.xml内の<event-handlers>タグ内に<scaffold>タグを定義すれば良い。
  • <Scaffold>タグにより、5つのイベントを作成可能。
    • マスターリストの表示(table.list)
    • レコードデータとリレーションデータの修正フォームの表示(table.edit)
    • レコードデータの読み出し専用ビューの表示(table.view)
    • レコードデータの更新(table.commit)
    • レコードデータの削除(table.delete)
  • <Scaffold>タグ内には、<Broadcasts>、<Results>、<Views>タグを記述可能。
  • <Scaffold>タグの属性に、typeを指定することで、作成するイベントハンドラータイプを指定可能。

4.レコードデータのAutoValidation

  • GDMのGeneric.Commitで、<arguments>タグにname="validationName"を指定することにより、自動的にValidateを実行できます。(より複雑なValidateのカスタマイズは、Reactorが自動生成するDAOオブジェクトを拡張する必要がありますが・・・)

最後に、Joe Rinehartのビデオデモも参考になるので、一読をお勧めします。

ModelGlue:Unity Public Beta1リリース!

Joe Rinehartのブログで、ModelGlue:Unity Public Beta1のリリースがアナウンスされています。
ダウンロードサイトは、こちらです。また、ドキュメントは、こちらです。

私のCF-OOPサイトで、ドキュメントの意訳を行っていきますので、今しばらくお待ちを・・・

ModelGlu2.0:Unityを使う10の理由

Joe Rinehartが彼のブログで、ModelGlu2.0:Unityを使う10の理由を書いている。

  1. Expression over depression. UI関連作業を大幅に削減できること
  2. Near-instant applications. かんたんにアプリケーションが構築できること
  3. MVC without the guesswork. 明快なMVCであること
  4. It does CRUD for you. CRUD機能を提供すること
  5. It makes OOP easier to learn. OOPを簡単に学べること
  6. Already got CFC code? Reuse it effortlessly. CFCの再利用を高められること
  7. Don't like something? You can change it. フレームワークの機能拡張性が高いこと
  8. It's fast. 高速であること(旧版と比較して)
  9. It's free. 無料であること
  10. It's open source. オープンソースであること

しばらく、ModelGlueやColdspringから遠ざかっているので、再度ModelGlue:Unity+Coldspring1.0RCを楽しんでみよう・・・(Reactor1.0RCも含めて)

ColdfusionCookbook

Raymond Camdenのブログで、Coldfusion Cookbookの記事が100件を突破したことのアナウンスがありました。
Coldfusionに関する総合ポータルとして継続的にウォッチしていこうと思います。
RSS2.0のURLは、こちら。興味を引いたエントリーは、以下のとおりです。

How do I perform an XSLT transform?

MachBlog

Matt WoodwardとPeter J.Farrellが、Mach-IIとColdSpringを使ったMachBlogを立ち上げているようです。
URLは、その名のとおり、

http://www.machblog.org/

です。興味ある方は、コンタクトしてみてください。

なんでもRSSのHack

今日、何気なくBlogWatcher( 東京工業大学 精密工学研究所 奥村研究室)を見に行ったら、BlogWatcherが3.0b公開に備えて、サービス中断がされていた。
しかたなく、BlogWatcherの一機能である「なんでもRSS!」は動いていたので、その機能をHackしてみた。

CGI-URL

http://blogwatcher.pi.titech.ac.jp/nandemorss/index.cgi

取得方法

getのみ?(postは試していない)   

パラメータ

url=http://www.synapse.jp/(ターゲットURLをutf-8エンコーディングして渡す。)
mode=rss

このレスポンス結果は、こちら
取得されるRSSフィードのURLを返してくれる。
よく見ると、CGIパラメータに'type='が追加されているので、構文パターンに応じたRSSフィードをtype指定で返すようである。
シナプストップページ(www.synapse.jp)の場合、3つのRSSフィードURL一覧が返されたので、type指定をつけて再度呼び出してみたときのレスポンス結果は、こちら
やったー、ものの見事にRSSフィードが返される。

HTMLそのものを解析するMyRSS.jpと比較して、日付を含む表現とHTML構文パターンからRSSフィードに適するものを抽出するため、Hackする際に、抽出パターンの指定が必要らしい。ターゲットサイトごとに、mode=rssを指定して、RSSフィードURL一覧を入手し、再度RSSフィード単位に再呼び出しをかければ、すべてのRSSフィードを入手できる。

明日、東京出張なので、ビジネスショウと同時開催のIPAのブースに出展している奥村先生か南野さんに、商用利用していいか訊ねてみよう。

CF-Unitedでの発表

[ColdSpring-Dev]のメーリングリストで、Sean A Corfieldが予告した。
6月下旬のCF-Unitedで、ModelGlue、ColdSpring、Reactor、そしてFuseBoxが商用利用可能なオープンソースとして公開されるらしい。
非常に楽しみだ。自社の開発に持ち込むか、このまま趣味の世界で続けるか悩むなあ・・・

CFGoogleMapsサンプル

CFGoogleMapsとGeocode.JPを使って、GoogleMapsのサンプル表示を行なってみました。
私の住む鹿児島市(たぶん、鹿児島市役所)と自宅(鹿児島市上福元町・・・)の住所をGeocode.JPに投げると緯度経度が帰ってくるので、これをCFGoogleMapsに食わせると、

こんな

感じになります。

PHPベースのGoogleMapAPIもインストールしてみました。

こちら

このPHPサンプルソースは、MVCスタイルになっていないので、PEAR(オープンソースコード構造化ライブラリ)やSmarty(テンプレートエンジン)に対応させようと思っているんだけど、うまくいかない・・・やはり、PHPは苦手だ・・・。
苦手なことには、あえてチャレンジしなきゃね!!

ColdFusionMapにJoin!

Joe Rinehartのブログに、ColdfusionDeveloper's Mapへの参加を呼びかける記事があったので、参加してみました。日本一番乗りみたいだ。ちょっぴり、うれしい。

Frappr map for CF:  http://www.frappr.com/cfdevelopers.

CFGoogleMaps

GoogleMapsAPIのPHP用クラスライブラリに続いて、Coldfusion用クラスライブラリが引っかかりました。

作者:Bryan Kaiser
CFCクラス名:CFGoogleMaps
対応バージョン:GoogleMapsAPI V1
リリース日:2005/10/27

サンプルスクリプト例は、以下のとおりです。
  1. CFCコンポーネント名を与えて、オブジェクト化
  2. GoogleMapsAPI KEYとマップセンターの緯度と経度を与えて初期化
  3. あとは、CFOUTPUTで呼び出すだけ
<html>
<body>
<cfscript>
    //Create the object
    cfgm = CreateObject('component','cfgooglemaps');
    //Pass the init function your google key and the
    //lat and lon on which the map should be centered
    cfgm.init('INSERT GOOGLE MAP KEY',38.898748,-77.037684);
</cfscript>

<cfoutput>
    <!--- Now just output the map --->
    #cfgm.getMap()#
</cfoutput>
</body>
</html>

ModelGlue+GoogleMaps+AjaxCFC+αで面白いことができそう・・・
Rob Gondaのサンプルを例に、あれこれ模索してみます。

MG/CS/Reactor連携アプリケーション例

Brian Kotekが、ModelGlue-ColdSpring-Reactor連携のブックストアアプリケーションを
彼のブログにアップしています。
早速、私のサイトにインストールしてみました。
(彼は、Windowsマシンで開発しているらしく、View関連のフォルダ名とファイル名は一部変更が必要です)

1.ColdSpringによるModelGlue用BeanFactoryLoaderとAutowiring用コントローラー
2.ColdSpringによるReactorオブジェクトのファクトリー機能
を活用して、Model内がビジネスロジック層、サービス層、パーシスタント層にきれいに構造化されています。

次回は、その概要を紹介してみます。

また、Mach-II-ColdSpring-Reactor連携モデルも彼のブログにアップされています。

Reactorをはじめる-18

さて、前回の記事 で、リソース情報を表示するのに、あるテクニックが使われていました。
即ち、GatewayオブジェクトでCreateQuery()メソッドを実行し、テーブル間のリレーションシップ(join)やソート条件(getOrder)およびフィルタ条件(GetWhere)と、2つのテーブルの全フィールドを対象フィールドに指定(returnObjectFields)していました。

Recordオブジェクトと組み合わせて使用するgetXyzIterator()との相違点を明確にしていくために、以前作成したuserGatewayオブジェクトにQueryオブジェクトを作成してダンプしてみます。
以下のCFMLスクリプトを実行してみましょう。

続きを読む "Reactorをはじめる-18" »

Reactorをはじめる-17

さて、次はcfOpenSourceListの表示部分です。

1.最初に、オープンソースリストを表示するので、リソースはGatewayオブジェクトとして定義します。

<cfset resourceGateway = application.reactor.createGateway("OpenSourceResource") />


2.次に、リソースとカテゴリーの結合クエリーをリソースGatewayに定義していきます。

<!--- build a joined query of resources and resource categories --->
<cfset objQry = resourceGateway.createQuery() />
<cfset objQry.join('OpenSourceResource','OpenSourceResourceCategories') />
<cfset objQry.join('OpenSourceResourceCategories','OpenSourceCategory') />
<cfset objQry.returnObjectFields("OpenSourceResource") />
<cfset objQry.returnObjectFields("OpenSourceCategory") />
<cfset objQry.getOrder().setAsc('OpenSourceResource','title')>
<cfset objQry.getOrder().setAsc('OpenSourceResource','resourceID')>
<cfif structKeyExists(url,"categoryID")>
   <cfset objQry.getWhere().isEqual('OpenSourceCategory','categoryID',url.categoryID) />
</cfif>
<cfset qryResources = resourceGateway.getByQuery(objQry) />


あらかじめ、カテゴリが指定されていれば、それをgetWhere()で指定しています。

3.あとは、qryResourcesを出力するだけです。

<cfoutput query="qryResources" group="resourceID">
<div id="resource">
   <p><span class="title"><a href="#qryResources.href#">#qryResources.title#</a></span> | <span class="edit"><a href="edit.cfm?resourceID=#qryResources.resourceID#">edit</a></span><br />
   <span class="description">#qryResources.description#</span><br />
   <cfif len(qryResources.license)>
      <span class="license">License: #qryResources.license#</span><br />
   </cfif>
   <span class="categories">Categories:
   <cfoutput group="categoryID">
      <a href="#CGI.SCRIPT_NAME#?categoryID=#qryResources.categoryID#">#qryResources.category#</a>
   </cfoutput>
   </span>
   <p>
</div>
</cfoutput>

Reactorをはじめる-16

さて、Reactorと他のCF-MVCフレームワークの連携に入る前に、もう少しスクラッチベースでreactorの利用方法を復習してみます。Reactorをはじめる-3で取り上げたBrian RinaldiによるReactorアプリケーション紹介記事を見てみましょう。

テーブルは、以下の3つのとおりです。

・OpenSourceResource
 オープンソースソフトウェアのリソース情報
・OpenSourceCategory
 オープンソースソフトウェアのカテゴリ情報
・OpenSourceResourceCategories
 OpenSourceResourceとOpenSourceCategoryをつなぐリンクテーブル

紹介記事の流れは以下のとおりです。

続きを読む "Reactorをはじめる-16" »

Reactorをはじめる-15

■Iterator

Iteratorは、hasManyリレーションを作成すると、自動的に作成されるということなので、Reactorドキュメントの例にあるCustomer、Address、Invoice、productオブジェクト間のリレーションを以下のように定義して、AddressRecordをダンプしてみます。

続きを読む "Reactorをはじめる-15" »

Reactorをはじめる-14

■RecordオブジェクトとDAOオブジェクト&TOオブジェクトの関係について

本日、Reactorのソースコードを見ていたら、abstractRecord.cfcのconfigure()メソッドに、以下のような記述がありました。
RecordオブジェクトをCreateすると、DAOとTOも自動的に生成するようです。

<cfset _setTo(_getReactorFactory().createTo(arguments.alias)) />
<cfset _setDao(_getReactorFactory().createDao(arguments.alias)) />

■Iteratorについて
 
Doug Houghesの2/28付の記事に、Reactorの最新リリースがアナウンスされていたのを見つけました。それによると、Iteratorは、

hasManyリレーションシップを作成すると、Recordオブジェクト:XyzRecordに2つのメソッド、getXyzQuery()とgetXyzArray()を作成していました。

It used to be that when you created a hasMany relationship that reactor would create two methods on your Record objects, getXyzQuery() and getXyzArray() where Xyz is the name of the related objects.

今回、これらをIteratorオブジェクトで置き換えました。hasManyリレーションを作成すると、getXyzIterator()メソッドが作成されます。これによって、XyzオブジェクトのIteratorを返します。
このIteratorはパワフルで、データのフィルタやソートを行いつつ、クエリー結果を得たり、ページ数を付けたり、配列結果を得たりできます。

This was replaced with an Iterator object.  Now, when you use hasMany one method named getXyzIterator() is created.  This returns an Iterator for your Xyz object.  The Iterator is more powerful because it allows for filtering and sorting data, getting a query of the results, paginating the data and getting arrays of results.

ということになるのだそうです。

Iteratorオブジェクトをどこで生成しているのか、よくわかりません。もう少し、追っかけてみます。

Reactorをはじめる-13

Reactorの基本オブジェクト

  • Gateway
  • DAO
  • Record
  • To
  • Iterator

について、そのダンプ内容を紹介してきましたが、おわかりいただけましたか?うん?なんだかしっくり来ない?そのとおりです!DougがReactorドキュメントで言及しているように、ORMの世界も経験するしかないんです・・・
DougのReactorSamples/Blogが最も参考になるアプリケーションですので、これを随時紹介していくことにしましょう・・・

また、次回まで。

Reactorをはじめる-12

Reactorの基本オブジェクトの各種メソッドをダンプ結果から確認しています。今回は、Iteratorオブジェクトに着目します。

Iteratorは、要素の集まりを保有するオブジェクトの各要素に順番にアクセスする方法を提供するオブジェクトでIteratorデザインパターンとしてよく知られています。

■userIterator

init ------------------ Objectを初期化し、Iteratorオブジェクトを返します。
getQuery ------------- 指定するレコードから指定カウント分のクエリーセットを返します。
getArray ------------- 指定するレコードから指定カウント分のアレイセットを返します。
setDistinct ----------- 単一レコードモードにします。
setJoinList ----------- JOINリストを指定します。
getJoinList ----------- JOINリストを返します。
getDictionary --------- Dictionaryオブジェクトを返します。
setGateway ----------- gatewayオブジェクトをセットします。
getGateway ----------- gatewayオブジェクトを返します。
getRecordCount ------- レコード総数を返します。
getName ------------- Iterator名を返します。
getWhere ------------- whereストリングを返します。
hasMore -------------- 次のレコードがあるかどうか返します。
getNext -------------- ネクストレコードを返します。
getValueList ---------- カレントレコードの指定フィールドリストの値を返します。
reset ---------------- Iteratorをリセットします。
getOrder ------------- orderストリングを返します。
resetOrder ----------- orderストリングをリセットします。

続きを読む "Reactorをはじめる-12" »

Reactorをはじめる-11

Reactorの基本オブジェクトの各種メソッドをダンプ結果から確認しています。今回は、Toオブジェクトに着目します。

ToはTrasfer Objectのことで、variablesスコープの代わりに、thisスコープでインスタンスデータを保持するオブジェクトです。

■userTo

configure ------------ Objectを初期化し、オブジェクトを返します。
userID --------------- userID
userName ------------ userName
passWord ------------- passWord
firstName ------------- firstName
lastName ------------- lastName
dateCreated ----------  dateCreated
merge ---------------  他のTo値を注入します。
_getSignature -------- 依存するDBの署名を返します。.
_getInstanceID ------- ObjectのインスタンスをUUID形式で返します。

続きを読む "Reactorをはじめる-11" »

Reactorをはじめる-10

Reactorの基本オブジェクトの各種メソッドをダンプ結果から確認しています。今回は、Recordオブジェクトに着目します。

■userRecord

configure ------------ Objectを初期化し、abstractRecordオブジェクトを返します。
init ----------------- userRecordオブジェクトを返します。
getUserID ------------ userIDをゲットします。(string)
setUserID ------------ userIDをセットします。(void)
getUserName --------- userNameをゲットします。(string)
setUserName --------- userNameをセットします。(void)
getPassWord --------- PassWordをゲットします。(string)
setPassWord --------- PassWordをセットします。(void)
getFirstName --------- firstNameをゲットします。(string)
setFirstName --------- firstNameをセットします。(void)
getLastName --------- lastNameをゲットします。(string)
setLastName --------- lastNameをセットします。(void)
getDateCreated ------- dateCreatedをゲットします。(string)
setDateCreated ------- dateCreatedをセットします。(void)
load ---------------- Recordオブジェクトをロードします。
save ---------------- Recordオブジェクトを保存します。
delete -------------- Recordオブジェクトを削除します。
createErrorCollection --- 検証用エラーコレクションオブジェクトを作成します。
validate ------------ Recordオブジェクトを検証します。
validated ------------ Recordオブジェクトが検証済かどうか返します。
hasError ------------ Recordオブジェクトに検証エラーがあるかどうか返します。
_getValidateErrorCollection --- Recordオブジェクトの検証エラー内容を返します。
newEvent ------------ 新規イベントをセットします。
announceEvent ------- イベントをアナウンスします。
attachDelegate ------- リスンするイベントと対応するオブジェクトとそのメソッドを追加します。

リスンイベント:beforeValidate, afterValidate, beforeSave, afterSave, beforeLoad, afterLoad, beforeDelete, afterDelete

detachDelegate ------- 特定のリスンイベントを解除します。
detatchAllDelegate ---- リスンするイベントをすべて解除します。
_getTO -------------- userToオブジェクトをゲットします。
_setTO -------------- userToオブジェクトをセットします。
_getDICTIONARY ------ userDICTIONARYオブジェクトをゲットします。
_setDICTIONARY ------ userDICTIONARYオブジェクトをセットします。
_getSignature -------- 依存するDBの署名を返します。
_getInstanceID ------- ObjectのインスタンスをUUID形式で返します。

続きを読む "Reactorをはじめる-10" »

Reactorをはじめる-9

Reactorの基本オブジェクトの各種メソッドをダンプ結果から確認しています。今回は、Daoオブジェクトに着目します。

■userDAO

configure ------------ Objectを初期化し、オブジェクトを返します。
create -------------- 指定するToオブジェクトを新規生成します。(void)
save ---------------- 指定するToオブジェクトに指定するレコードを読み込みます。(void)
update -------------- 指定するToオブジェクトの指定するレコードを更新します。(void)
delete -------------- 指定するToオブジェクトに指定するレコードを削除します。(void)
_getSignature -------- 依存するDBの署名を返します。
_getInstanceID ------- ObjectのインスタンスをUUID形式で返します。

続きを読む "Reactorをはじめる-9" »

Reactorをはじめる-8

Reactorの基本オブジェクトの各種メソッドをダンプ結果から確認しています。最初に、Gatewayオブジェクトに着目します。

■userGateway

configure ----------- Objectを初期化し、オブジェクトを返します。
getAll -------------- 全てのレコードセットを返します。
createQuery -------- クエリーオブジェクトを作成します。
getByFields --------- 指定されたフィールドの全てのレコードセットを返します。
getByQuery --------- クエリーオブジェクトの条件に合致するレコードセットを返します。
_getSignature -------- 依存するDBの署名を返します。
_getInstanceID ------- ObjectのインスタンスをUUID形式で返します。

続きを読む "Reactorをはじめる-8" »

Reactorをはじめる-7

今回は、Reactorオブジェクトの詳細を確認してみます。
Reactorオブジェクトには、initを含めて全部で13のメソッドがあります。
以下に示す7つの基本オブジェクトに対するCreateメソッドと、

  1. CreateRecordメソッド
  2. CreateGatewayメソッド
  3. CreateDAOメソッド
  4. CreateTOメソッド
  5. CreateMetadataメソッド
  6. CreateIteratorメソッド
  7. CreateDictionaryメソッド

そして、残り5つのメソッドは、次のとおりです。

  1. CreatePluginメソッド
  2. SetBeanFactoryメソッド
  3. CreateValidator
  4. Compileメソッド
  5. GetXMLメソッド

続きを読む "Reactorをはじめる-7" »

Reactorをはじめる-6

今日は、cfOpenSourceListアプリケーションのReactorのオブジェクト定義を確認します。
Reactorをはじめる-3で紹介したように、このアプリケーションは3つのテーブルをもっています。

一つ目は、オープンソースソフトウェアのリソース情報を格納するOpenSourceResourceテーブル。
二つ目は、オープンソースソフトウェアのカテゴリ情報を格納するOpenSourceCategoryテーブル。
三つ目は、OpenSourceResourceとOpenSourceCategoryをつなぐリンクテーブルであるOpenSourceResourceCategoriesテーブル。

このように、Reactorではデータベース内のテーブルオブジェクト間のリレーションシップも定義できます。

続きを読む "Reactorをはじめる-6" »

Reactorをはじめる-5

さて、Brian RinaldiのReactorアプリケーション紹介記事で、cfOpenSourceListアプリケーションのreactor.xmlにおけるconfigセクションを確認してみます。

<config>
    <dsn value="remotesynthesis" />
   <type value="mysql" />
    <mapping value="/CFOSListData" />
    <mode value="development" />
</config>

■dsn
dsnは、"remotesynthesis"に設定されています。
ColdFusionに登録したdsnそのものです。

■type
typeは、"mysql"に設定されています。
MySQL5を使用しているということです。

■mapping
mappingは、"/CFOSListData"に設定されています。
ColdFusionのwwwroot直下にある/CFOSListData"か、ColdFusionで設定したwwwroot以外のディレクトリへのマッピング名を指定しています。
個人的には、アプリケーションのルートディレクトリ内にdataディレクトリを作成し、"/app/data"と指定するのが、一番シンプルなように思えます。

■mode
modeは、"development"に設定されています。
開発モードであることを示しています。
Reactorがdsnとtypeによって指定されたDBMSを常時チェックすることを意味しますので、開発モードの場合レスポンスが悪くなります。
開発が終了したら、"production"に設定してください。

■project
このタグは指定されていませんが、最新バージョンでは必須になっています。

projectは、dsnと同じ値にセットするのが一般的なようです。
<project name="remotesynthesis" />
dsnと同じセッティングで良いのではないかと思います。

Reactorをはじめる-4

今回は、Reactor.xmlのconfigセクションの各要素を、Reactorユーザズガイドから抜粋してみます。

■Project

プロジェクトタグは、プロジェクトのために変化しない安全な名前を定義するのに使用されます。プロジェクト名はReactorが揮発性のプロジェクトファイルを格納する位置を定義します。 データベース非依存のファイルはプロジェクトディレクトリ配下でファイルを展開しています。

いったん設定して、再び働かせるために手であなたのカスタムファイルを編集するのに時間を費やしたくないなら、この値を変えないでください。

シンタックス:

<project value="cfOpenSourceList" />

 

 

 

 

 

 

 

 

Argument

Required

Type

Description

Value

Yes

String

プロジェクト名を指定します。

dsn

dsnタグは、クエリーを実行する際、Reactorが使用するColdFusionデータソース名を定義するのに使用されます。ColdFusionで設定済のデータソース名を指定する必要があります。

シンタックス: 

<dsn value="ReactorBlog" />
 

 

 

 

 

 

 

 

 

Argument

Required

Type

Description

Value

Yes

String

Reactorが使用するColdFusionデータソースを指定します。

type

タイプタグは、Reactorがクエリー実行可能なデータベースタイプを定義するのに使用されます。 現在サポートしているサーバは以下の通りです:

  • Microsoft SQL Server 2000 and 2005
  • MySQL 4
  • MySQL 5 and later. 

MySQL45は、各々が動作するために、異なった構成値(以下を参照)を必要とするので、別々に記載されています。

Type設定は、そのコードがどのように、そしてどこで実行されるかを制御します。 例えば、Microsoft SQLを使用している旨を示すと、Reactorは構成されたマッピング配下の"mssql"というフォルダーにカスタマイズ可能なコードを生成します。

加えて、データベースサーバーは、コードを実行する際、異なったセマンティックを必要とします。Reactorは、ある意味でコードがデータベースによってサポートされるようにDBタイプセッティングを使用します。

シンタックス: 

<type value="mssql" />
 

 

 

 

 

 

 

 

 

Argument

Required

Type

Description

Value

Yes

String

使用するデータベースタイプを指定します。オプション文字列は以下のとおりです。

  • mssql        – Micrsoft SQL Server 2000 and 2005.
  • mysql4      – MySQL 4.
  • mysql        – MySQL 5 and later.
  • db2           – IBM DB2.
  • postgresql – PostgreSQL.
  • oracle      – Oracle.
  • oraclerdb  – Oracle RDB.
  • access     – MS-Access.

■mapping

 Reactorがファイルを生成するディレクトリへのマッピングです。CFマッピングで与えられるか、webルート直下にある必要があります。 

■mode

詳細には触れませんが、アプリケーション開発中は、モードを”development”に設定しておきたいものです。データベース構造が変化したときやリレーションを変更したときに、Reactorにオブジェクトを再作成させます。

 

 

 

 

 

 

 

 

Argument

Required

Type

Description

Value

Yes

String

Reactorシステムが動作するモードを指定します。指定可能なモードは以下のとおりです。

development - 開発モード

production - 製品モード

always - 常時モード(=開発モード)

 

Reactorをはじめる-3

さっそく、Brian Rinaldiのブログで、cf open-source listのReactorアプリケーション紹介記事を見てみます。
ColdFusion用オープンソースを管理するために、データベースに3つのテーブルを作成しています。
一つ目は、オープンソースソフトウェアのリソース情報を格納するOpenSourceResourceテーブル。
二つ目は、オープンソースソフトウェアのカテゴリ情報を格納するOpenSourceCategoryテーブル。
三つ目は、OpenSourceResourceとOpenSourceCategoryをつなぐリンクテーブルであるOpenSourceResourceCategoriesテーブルです。

各オープンソースソフトウェア毎に複数のカテゴリを登録可能なように、リンクテーブルを介してリソーステーブルとカテゴリテーブルのリレーションを定義しています。

それを含めて、Reactor.xmlというコンフィグレーションファイルに以下のセクションを定義します。

<reactor>

<config>

<dsn></dsn>
<project></project>
<type></type>
<mapping></mapping>
<mode></mode>

</config>
<objects>

<object name="OpenSourceResource"></obeject>
<object name="OpenSourceCategory"></obeject>
<object name="OpenSourceResourceCategories"></obeject>

</objects>

</reactor>

各々のセクションについては、次回説明します。

Reactorをはじめる-2

さて、Reactorについては、以前のブログで紹介しました。
Reactorは、ColdFusion上でパーシスタントレイヤをハンドリングするサブフレームワークです。
Reactorの主要機能は以下のとおりです。

  • Reactorは、以下のORMオブジェクトを自動生成する。
  1. Recordオブジェクト
  2. Gatewayオブジェクト
  3. DAOオブジェクト
  4. TOオブジェクト
  5. Metadataオブジェクト
  • Reactor.xmlファイルで、テーブル間のリレーションシップを定義できる。
  1. HasOne
  2. HasMany(Direct)
  3. HasMany(Link)
  4. Super
  • サポートするDBMSは以下のとおり。
  1. MSSQL
  2. MySQL4
  3. MySQL5
  4. PostgreSQL
  5. MS-ACCESS
  6. DB2
  7. Oracle
  • Iteratorやイベントモデルも可能
  • RecordオブジェクトやDAOオブジェクト内でValidate用のファンクションをユーザ定義することが可能

Brian Rinaldi が彼のブログで Getting Started with Reactorを書いてあるので、サンプルとして次回から紹介してみることにします。
ちなみに、彼のcf open-source Listは、Reactorを使って作成されています。

Reactorをはじめる-1

ここしばらく、CF-OOP関連記事の投稿をさぼっていました。

実は理由があって、
hostnexus.comでのCFホスティングを利用しはじめたんですけど、
CFホスティングとMySQL間のエンコーディング問題が発生して、サジを投げていたところなんです。
でも、サジを投げてばかりもいられないので、以下のことを、シコシコがんばっていました。
本格的にこのサイトと連動しながら、独り言風にブログで活動状況をお知らせしていこうと思います。

  • CF-OOPサイトの立上げ(MediaWikiベース) 

http://ganymean.org/mediawiki/

  • Reactor関連ドキュメントの翻訳作業

近々、アップする予定です。
また、ModelGlue+ColdSpring+Reactorのアプリケーション開発について、このブログを通じて、皆さんにサンプルアプリケーション例を紹介していく予定です。

  • ポータルサイトの立上げ

http://ganymean.org/ をManboを使って、ポータル化
CF-Nuke等に近々変更予定。Geeklogに変更済みです。

  • このブログをドメインマッピング化

http://blog.ganymean.org/
でアクセス可能にしてあります。

フレームワーク連携

以前、ModelGlue+ColdSpring+reactorによるフレームワークの連携が
今後の主流になるかもしれないと予想しましたが、その後、
1.reactorの機能強化
2.ColdSpringによる外部Factory呼び出しの実装
3.ModelGlueにおけるAutowiringControllerの実装
を経て、それが現実的になろうとしています。

Seanの最近の記事には、彼のフレームワークサンプルggccのバリアント、
ModelGlue+ColdSpring+reactorに対応させるためのColdSpringとreactorの
連携が紹介されています。以下は、その関連記事です。

Model-Glue, ColdSpring and Reactor
Model-Glue, ColdSpring and Reactor - follow-up
Model-Glue, ColdSpring and Reactor - another follow-up

Sean曰く、bean.cfc、DAO.cfc、Gateway.cfcなど12のCFCsが不要に
なったとのことです。Seanのggcc10アプリケーションアップをアップを
楽しみにして待っていよう。

cfObjectiveサマリー

SeanがcfObjectiveのサマリーリポートを彼のブログで紹介しています。
興味あるセッションタイトルは以下のとおり。

  • Managing ColdFusion Components with Factories - Sean Corfield
  • AOP with ColdSpring - Chris Scott
  • Mach II and ColdSpring - Kurt Wiersma
  • Objects & Persistence  - Sean Corfield
  • Frameworks Roundtable - Panel Discussion
  • Model Management with ColdSpring - Chris Scott

Seanは、セッションのプレゼン資料を彼のブログで紹介しています。
ご参考までに

CFMXでRuby on Rails風に・・・(その2)

前回のポストで宿題にしておいた

について、CDCDEVのメーリングリストをトレースしてみた。
やはり、Sean CorfieldがML上で多くコメントしている。
彼曰く、

Reactor caches database object instances (metadata, essentially, not actual application data).
Arf! and objectBreeze do not provide caching.

Arf! and objectBreeze introspect the database without needing an XML file.
Transfer and Reactor use an XML file to describe the database.

Model-Glue + ColdSpring + Arf! / Reactor
(Arf! for simple stuff, Reactor for more complex stuff)

obJectBreezeという新しいORMサブフレームワークもあるようだが、
一言でいうと、

Reactor:大規模向き、パーシスタント機能あり、DB定義にXML使用。
Arf!:小規模向き、パーシスタント機能なし、DB定義にXML不使用。

Brian Rinaldiのブログの記事:Arf, ObjectBreeze, Reactor and More!
参考になると思います。

個人的には、
- Model-Glue - for presentation / event wiring
- ColdSpring - for model management
- Reactor - for persistence
を試してみようと思う。
早速、Doug HughesのサンプルコードにあるBLOGを試してみよう。
(ModelGlue+Reactor)

CFMXでRuby on Rails風に・・・

10月下旬から11月上旬にかけて、Seanが彼のブログで'Ruby on Rails’を
何度か取り上げていたのを、ふと思い出した。

さっそく、日本Rubyの会のRuby on Railsに飛んでみる。
おお、CFと同じくMVCフレームワークではないか!!

  • モデル:ActiveRecord(専用O/Rマッパーライブラリ)
  • コントローラ:ActiveController(アクション管理単位は、クラス単位でなくメソッド単位)
  • ビュー:ActionView+Erb(ヘルパーライブラリーをつけた埋め込みRuby)

満足せる豚。眠たげなポチ。さんのRuby on Rails日本語訳記事を除いてみると、
な、なんと、O/Rマッパーのおかげで、モデルを定義するだけで、
何もSQLを書く必要がない!!GWやDAOの機能が最初から実装されている。
便利だ!

そんなこんなで、CFでRuby on Rails風なサブフレームを探してみたら、
やはりありました。

パッと見たところでは、両方ともMVCフレームワークではなく、
他のCFフレームワークと連携するサブフレームワークのようだ。
ドキュメントを読んで、もう少し違いをまとめてみよう。

海外のColdfusionHosting

mixiのColdfusionコミュニティで、「ヘテムル」という
Coldfusionの共有ホスティングサービスが紹介されていたので、
早速サービス紹介やサポートをチェックしたのだけど・・・
イマイチ、ピンとこない。

というわけで、海外のColdfusionHosting関連の情報をネットで
あさっていたら、最初に見つけたのがこの比較サイト。

ColdFusion Hosting and CFMX Hosting Plans Comparison Table

一番上に載っている xtreme Host 。確かに安い!
このプランで、6.99USD/Month。

Disk Space: 200MB      
Transfers: 8GB
Unlimited Email Accounts
Control Panel: PLESK 7.5 RELOADED

Pleskも使える。Mysql/Postgresql/MSSQLも使える。
しかもDB数は無制限。
ColdfusionからMysqlへはDSNが無制限に設定可能。
でも、Coldfusion用PleskControlPanelは使えないみたい。
メールでのやりとりなんだろうなー。

どこにデータセンタがあるのかと思って、PINGとTRACERTを打ってみると、
PING        207msec TTL=41
TRACERT KDDI経由で海外にわたってから先の経路が見えない。
ということで、日本からのネットワークが不安なので、今回はパス。
将来的には使ってもいいかなー。

次に見つけたのは、Xtreme Hostより若干仕様が劣るけど、
日本からのネットワークがしっかりしてそうな Host Nexus

PING        193msec TTL=44
TRACERT Verio、Abovenet経由でUSのニュージャージーにあるみたい。
経路もしっかりと見えているので、ここを使うことにした。
このプランで、9.5USD/Month。

300MB Disk Space
10GB Data Transfer
Linux: 10 MySQL Databases
Host 3 Domains
Plesk Control Panel

使用レポートは、またの機会に。

AjaxCFC

昨年、CFAjaxを見て、フレームワークとの整合性が悪いなあーと思っていたら、
CFCベースのAjaxフレームワークが出てきました。
Rob Gondaのブログに行くと、ModelGlueとの連携も紹介してくれています。
Robさん、サンキュ!
これで、GoogleMapsとのマッシュアップが簡単に出来そう!

ajaxCFC for Model-Glue Explained

Ajax.cfcは、ModelGlueで利用可能な汎用modelです。したがって、コントローラで利用可能です。コントローラ内のinitファンクションで初期化し、コントローラ内のvariablesスコープに常駐させます。

<cffunction name="Init" access="Public" returnType="controller" output="false" hint="I build a new SampleController">
  <cfargument name="ModelGlue">
 
  <cfscript>
      super.Init(arguments.ModelGlue);
    variables.echo = createObject("component", "blog.projects.ajaxcfc.examples.modelgluesamples.echo.model.echo");
    variables.ajax = createObject("component", "blog.projects.ajaxcfc.examples.modelgluesamples.echo.model.ajax");
  </cfscript>
  <cfreturn this />
</cffunction>

Ajaxのリモートリクエストは、標準的なWebリクエストと同じく、以下のようにフローします。 

  1. ページがAJAXリクエストを発生させる。
  2. ModelGlueフレームワークによって、イベントが捕捉される。
  3. ModelGlueのイベントハンドラーがメッセージをブロードキャストする。
  4. コントローラでメッセージをピックアップする。
  5. AjaxCFCを使い、onRequestStart内で、メッセージをパースする。
  6. イベントに応じて他のmodelを利用し、レスポンスデータを作成する。
  7. 再度AjaxCFCを使い、レスポンスに備える。
  8. 'ajaxResponse'にレスポンス値をセットし、viewに渡す。
  9. modelGlue.xmlで、レスポンスを運びJavaScriptのコールバックファンクションに返すviewとしてのajaxResponse.cfmを含める。

ModelGlue+AjaxCFC+ColdspringでGoogleMapsとの連携版を作ってみよう!

ModelGlueV1.1近し!

Joe Rinehartのブログに、ModelGlue V1.1のリリースが近いことが
1月になって発表されていたようです。

彼の記事を2件引用すると・・・・こんな感じになるようです。
Model-Glue 1.1 Preview

  • ColdSpringとの統合
    1. ChiliBeansとColdspringの簡易切替(modelglue.xml内の<setting>タグ)
    2. Controllerとservice/conponent間の自動ワイヤリング(自動Bean化、beanFactoryLoader使用)
  • スタータキット(テンプレート)のリニューアル
    1. MySQL/MSSQLサポート(ColdSpringのDAO/Gateway経由?)
    2. 基本Webアプリ用テンプレート(ログイン/ログアウト、プロフィール管理、ユーザ管理)
  • redirectタグのバグフィックス
    1. リダイレクト先未指定の場合に、リダイレクトを実施しないようにした
  • 静的ブロードキャスト機能の追加
    1. controller内のOnRequestStartファンクション内でスタティックなリダイレクトが可能になった。

Model-Glue "Headstart" Preview (screenshots!)

  • MySQL and MS SQL Server Support

  • ロールベース/キーベースセキュリティ(グループレベル/レコードレベルセキュリティ)

  • ユーザ管理ツール

  • ユーザサインアップの設定(on/off)

  • ログインアクセスの設定(on/off)

  • 手のかかる例外処理のハンドリング

    • エラー情報、スコープ情報、デバッギングスタック情報付メールの自動通知

  • メールサービス用CFCのビルトイン

上記管理ツールのスクリーンショットはこちら

Fusebox5

Sean Corfieldのブログに、Fusebox5開発スタートの記事があったので紹介しておきます。

  • Fusebox4.1と後方コンパチ
  • コアファイルをリビルド(メンテナンス性の追求)
  • 文法の構造化

メーリングリストも作成されたようななので、興味のある方はどうぞ参加してください。
http://groups.yahoo.com/group/fusebox5/

mach-ii.jp

会社の同僚からmixiへの招待をもらった。
Coldfusion関連で2つのコミュニティがあった。
ひとつは、ColdFusion。もうひとつは、Mach-II for ColdFusion。
Mach-II for ColdFusionの中を覗くと、管理人の侍さんが
Mach-IIの日本語ウェブサイト http://www.mach-ii.jp/ を
立ち上げていたので、Mach-IIの日本語化に人肌脱いでみようと
思い、協力を申し出たところ管理人からOKをいただいた。
Mach-II.comのドキュメントの更新チェックと過去に翻訳した
ドキュメントのチェックを今月は集中的にやろうと思う。

Tartan Ver1.05仕様

Paul KennyからTartan1.05のプレビューがリリースされた。
どうやら、TartanからColdSpringが使えるように、User-defined Factoriesを実装したようだ。
サンプルプログラムもMach-IIの一部が移植されているようなので、じっくりながめてみてから報告します。

Property Manager - tartan.core.PropertyManager

ServiceContext - tartan.context.ServiceContext

User-defined Factories - tartan.core.Factory (abstract base class)

configure() method
Flash Remoting

XmlReaders/Builders

Sample Applications

 

MachII1.1.0リリース!

Mach-II Ver1.1.0がリリースされました。
今回のリリースから、Peter J Farrellがコアメンバーになっています。
彼のブログの記事からVer1.1.0のリリースノートを抜粋・翻訳しておきます。
一つづつ読みこなしながら詳細をリポートしようと思います。

  • Full backwards compatibility – fully tested under CFMX 6.1 and 7
    • 完全後方互換(CFMX6.1とCFMX7で検証済)
  • Developed under a new community oriented development process
    • コミュニティ志向開発プロセスの採用
  • Updated sample applications
    • サンプルアプリケーションの更新
  • 14 page Mach-II Frequently Asked Questions PDF
  • New QuickStart by Matt Woodward
    • 新クイックスタートのリリース(By Matt Woodward)
  • Bug fixes!
    • バグフィックス
  • New Redirect command
    • 新リダイレクトコマンド
  • ResultArg and ContentArg attributes (no more having to use the request scope as a data bus)
    • ResultArg/ContentArg属性(リクエストスコープのデータバス使用は不要となる)
  • Better exception handling
    • 改良された例外処理
  • XML config file validation (CFMX7 only)
    • XML Configファイルの検証(CFMX7のみ)
  • The ability to get the original cfcatch object when an exception occurs
    • 例外発生時のオリジナルcfcatchオブジェクトのハンドリング
  • New invokers for listeners
    • リスナーの新しい呼出方法
  • Updated and completely NEW documentation
    • 更新され、完全にリニューアルされたドキュメント
  • Better hints in the framework - fire up your CFCExplorer when you need help
    • CFCExplorerで利用可能なフレームワーク用ヒントファイルの提供

CFMX用フレームワーク比較

Sean CorfieldがColdfusion用フレームワークの比較プレゼンを彼のブログにアップした。
Fusebox4、Mach-II、Model-Glueの3つについて、特徴と概観図をシンプルに比較しており、大変わかりやすい。
早速、Model-Glue+ColdSpringとTartanの比較資料における概観図に引用させてもらった。

ModelGlue+TarTan or ColdSpring(その2)

前回、紹介した資料の最終ページにあるとおり、
Sean CorfieldのColdfusionフレームワーク用サンプルアプリケーションGGCCでファイル数を比較してみると、ModelGlue+ColdSpringのModelGlue+Tartanに対する優位性がはっきりわかります。

  1. ggcc7 : ModelGlue                       17Files (Corrected at Nov 17, 2005 By suggest Sean Corfield)
  2. ggcc8 : ModelGlue+Tartan            27Files
  3. ggcc9 : ModelGlue+ColdSpring      21Files

Tartanは、サービスコントローラがあり、コマンドcfcを介して、VO/DAO/Gateway/Exceptionなどのモデルcfcにアクセスするため、サービスコントローラやCommandファイルの分だけファイル構成が複雑になります。
したがって、ModelGlueのフットワークの軽さにフィットするのは、ColdSpringになるのかもしれません。

ModelGlue+TarTan or ColdSpring

ColdSpringに触れてから、ModelGlue+ColdSpringの組合せを研究してきたけど、
ここらで一旦

  1. ModelGlue+Tartan
  2. ModelGlue+ColdSpring

の違いについて整理してみる。

  • Tartan
    • サービスフレームワーク
    • コマンドドリブンベース
    • IoC機能(DI機能)
    • サービスレイヤ機能
      • Service, VO, DAO, Gateway, Utility, Exception
  • ColdSpring
    • MVCフレームワークのサポート
    • AOP機能
    • IoC機能(DI機能)
    • サービスレイヤ支援機能(Bean化)
      • Service, VO, DAO, Gateway, Utility, Exception

各々の特徴と概観を資料 にまとめてみました。ご参考までに 。

LoggingAOP with ColdSpring

今日は、ColdSpringAOPとLog4jを使ったロギングサービスについて、解説します。
Chris ScottのColdSpringAOPのチュートリアルから引用してみます。

1.最初に、LoggingServiceを定義します。javaのlog4jからloggerクラスを生成しています。

<cfcomponent name="LoggingService" output="false">

  <cffunction name="init" returntype="net.klondike.service.LoggingService" access="public" output="false">
    <cfset var category = CreateObject("java", "org.apache.log4j.Category") />
    <cfset variables.logger = category.getInstance('net.klondike') />

    <cfreturn this />
  </cffunction>
 
  <cffunction name="info" access="public" returntype="void" output="false">
    <cfargument name=message" type="string" required="true" />
    <cfif variables.logger.isInfoEnabled()>
    <cfset variables.logger.info(arguments.message) />
    </cfif>

  </cffunction>
 
</cfcomponent>

2.次に、AOPパートです。loggingBeforeAdviceを定義します。

<cfcomponent name="loggingBeforeAdvice" extends="coldspring.aop.BeforeAdvice">

  <!--- setters for dependencies --->
  <cffunction name="setLoggingService" returntype="void" access="public""false" hint="Dependency: security service"> output=
    <cfargument name="loggingService" type="net.klondike.service.LoggingService" required="true"/>
    <cfset variables.m_loggingService = arguments.loggingService />
  </cffunction>
<cffunction name="getLoggingService" returntype="net.klondike.service.LoggingService""public" output="false" hint="Dependency: security service"> access=
    <cfreturn variables.m_loggingService />
  </cffunction>
 
  <!--- before() is called by the aop framework before method invocation --->
  <cffunction name="before" access="public" returntype="any">
    <cfargument name="method" type="coldspring.aop.Method" required="true" />
    <cfargument name="args" type="struct" required="true" />
    <cfargument name="target" type="any" required="true" />
   
    <cfset var arg = '' />
    <cfset var argString = '' />
    <cfset var objName = getMetadata(arguments.target).name />
    <cfloop collection="#args#" item="arg">
      <cfif isSimpleValue(args[arg])>
        <cfif len(argString)>
          <cfset argString = argString & ', ' />
        </cfif>
        <cfset argString = argString & arg & '=' & args[arg] >
      </cfif>
    </cfloop>
        <cfset variables.m_loggingService.info("[" & objName & "] " & method.getMethodName() & "(" & argString & ") called!") />
      </cffunction>
  </cfcomponent>

3.最後に、ColdSpringのbean定義を行います。

<beans>
 
  <!—define the logging service -->
  <bean id="loggingService"
        class="net.klondike.component.LoggingService" />

 
  <!--define the loggingBeforeAdvice and set its logging service property to reference the bean above -->
  <bean id="loggingBeforeAdvice"
        class="net.klondike.aspects.loggingBeforeAdvice">

    <property name="loggingService">
      <ref bean="loggingService" />
    </property>
  </bean>
 
  <!—now define a NamedMethodPointcutAdvisor, set the advice property to the bean above, and set its mappedNames property to ‘*’ which will create a pointcut to match all methods excluding any init method -->
  <bean id="loggingAdvisor"
        class="coldspring.aop.support.NamedMethodPointcutAdvisor">

    <property name="advice">
      <ref bean="loggingBeforeAdvice" />
    </property>
    <property name="mappedNames">
      <value>*</value>
    </property>
  </bean>
 
  <!-- to create the proxy object, first create our dao as the target object -->
  <bean id="catalogDaoTarget"
        class="net.klondike.component.catalogDAO">
    <property name="dsn">
      <value>klondike</value>
    </property>
  </bean>
 
  <!-- now create a ProxyFactoryBean with the id catalogDAO, set the target to the catalogDaoTarget bean above, and give it ,the id of the NamedMethodPointcutAdvisor above in the list of interceptorNames -->
  <bean id="catalogDAO"
        class="coldspring.aop.framework.ProxyFactoryBean">
    <property name="target">
      <ref bean="catalogDaoTarget" />
    </property>
    <property name="interceptorNames">
      <list>
        <value>loggingAdvisor</value>
      </list>
    </property>
  </bean>

 
  <!--now to use the proxy DAO, we give the id of the ProxyFactoryBean to the catalog service as the reference for the property catalogDAO -->
  <bean id="catalogService"
        class="net.klondike.component.CatalogService">
    <property name="catalogDAO">
      <ref bean="catalogDAO" />
    </property>
  </bean>

</beans>

オープンソースCFプロジェクト

Seanが Brian RinaldiがまとめたColdFusionのオープンソースプロジェクトを紹介している。

ColdFusionでも、フレームワーク以外にポータル、ブログ、アルバム、Ajax、JUnit・・・
結構使えるオープンソースがあるもんだ・・・

ColdSpring Ver0.5

ColdSpringのMLで次期バージョンの内容がDave Rossからアナウンスされた。

次期バーションは0.5、12/15リリース予定

1.Hierarchical BeanFactory(階層化BeanFactory)
 親bean
  子bean(オーバライド可能)
 Mach-IIは、plugin動作の検証済み
 ModelGlueは、開発中(見送りもあり?)
2.Remoting helper classes
 Flash Remoting対応(to do mapping of CFC types to AS types)
3.ModelGlue controller autowiring by Sean
4.Mach-II controller (listener/filter/plugin) autowiring
5.コアBeanFactory機能のバグフィックス&アップグレード
6.AOP機能ののバグフィックス&アップグレード
7.factory-bean/factory-methodの属性サポート
8.AfterThrowing advice(例外処理後のAdvice)
9.bean生成における例外処理の強化

			

ModelGlue1.0.01の新機能

ModelGlue1.0.01の新機能について、ドキュメントの該当部分を和訳したので紹介しておきます。

1.ステートフルResultリダイレクト    <result name="xxx" do="yyy" redirect="ture" append="zzz" />
2.ステートフルフォワーディング      arguments.event.forward( )

■クイックスタート: ステートフルResultリダイレクト

しばしば、あるフォームがポストされたときに、"Reload"によってユーザがフォームをリポストすることを防ぐために、新しいページへのCFLocation を行うことが定例化しています。Model-Glue1.0 では、ModelGlue.xml ファイルを通じてこの動作を模倣することが可能になりました。

どのような<result>タグにも、REDIRECT属性を追加することができるようになりました。REDIRECT="true"にセットされている場合、フレームワークはすぐ現在の要求を停止し、すべての変数値を維持しながら、あらかじめ設計された<event-handler>へのサーバーサイドリダイレクトを実行します。

URL のparamaters を含んでいるページにリダイレクトしたいと思うことはかなりありうることです。例えば、誰かがコンテンツ管理システムのあるセクションに新しい記事をポストしたら、"index.cfm?event=showSection&sectionId=12345" のようなURL に遷移することを望むはずです。しかしながら、resultタグ上のREDIRECT属性は、url に追加すべきの"sectionId" 変数の値を知る方法がありません。この理由のために、オプションとしてAPEND属性が今回サポートされました。それは、変数コレクションをURLに追加するために、コンマ区切りの変数リストを含まなければなりません。フレームワークはURL に自動的にこのリストの単純変数すべてを追加します。

オーケー、それでは簡単なサンプルを見てみましょう:

<result name="articleAdded" do="showSection" redirect="true" append="sectionId">

全然OKでしょう?

■クイックスタート: ステートフルフォワーディング

行くためにどうしてもどこに知らない時があります。例えば、"ポッド" の中にあるフォームは、何かを行い、そしてどんなイベントから来たかユーザに示すことが必要になるでしょう。<result>タグを書くとき、"do"属性を動的にセットする方法はありません。

このような特別な事例のために、(arguments.event として知られている) EVENTオブジェクトは、Forward()メソッドを実装しました。このメソッドの使用方法は、次のようになります:

arguments.event.forward(<event-handler>名) - 直ちに指定された<event-handler>へのステートフルリダイレクトを実行する。arguments.event.forward("showSection ") は、index.cfm?event=showSection と同等です。

arguments.event.forward(<event-handler>名, append) - 直ちに、appendで与えられる変数コレクションをURLに追加しながら、指定された<event-handler>へのステートフルリダイレクトを実行します。arguments.event.forward("showSection" , sectionId )は、"12345" という値を有するsectionIdという変数コレクションを与えられた、index.cfm?event=showSection&sectionId=12345と同等です。

ColdSpringAOP Sample

SeanのModelGlue+ColdSpringサンプルアプリケーションGGCC9における
ColdSpringのAOP機能をチェックしてみます。

ggcc.xmlを眺めてみると・・・task関連処理におけるセキュリティチェックに
AOP機能を適用しているようです。

Target:
 taskDAOTarget(class->ggcc9.model.taskDAO)
 taskGatewayTarget(class->ggcc9.model.taskGateway)
Advice:
 checkIdentity(class->ggcc9.aspects.checkIdentity)
Advisor:
 securityAdvisor(Advice->checkIdentity MappedNames->*)
Service:
 taskDAO:Target->taskDAOTarget  InterCepternames->securityAdvisor
 taskGateway:Target->taskGatewayTarget  InterCepternames->securityAdvisor

このことによって、event-handlerの定義からセキュリティチェックの前処理がなくなって
います。
ggcc9->ModelGlue.xml->event-handler:showManager

        <event-handler name="ggcc.showmanager">
            <broadcasts>
                    <--
                    <message name="checkIdentity"/>        <--- AOP化したことにより、コメント化
                    -->
                <message name="needMembers"/>
                <message name="needMembersByID"/>
                <message name="needTasks"/>
                <message name="needStatii"/>
                <message name="needStatiiByID"/>
            </broadcasts>
            <views>
                <include template="dspShowTaskList.cfm" name="content">
                    <value name="XFA.AddTask" value="ggcc.newtask"/>
                    <value name="XFA.ChangeIdentity" value="ggcc.identify"/>
                    <value name="XFA.TaskDetail" value="ggcc.showtask"/>
                </include>
                <include template="layGGCC.cfm" name="final"/>
            </views>
        </event-handler>

また、DAOとGatewayをビーン化したことにより、コントローラーtaskManager.cfcの
内部が非常にシンプルになっています。

■GGCC7->taskManager.cfc->saveTask

    <cffunction name="saveTask" returntype="ModelGlue.Core.Event" access="public" output="false">
        <cfargument name="event" type="ModelGlue.Core.Event" required="true"/>
        <cfset var taskID = arguments.event.getValue("taskID") />
        <cfset var ownerID = arguments.event.getValue("ownerID") />
        <cfset var statusID = arguments.event.getValue("statusID") />
        <cfquery datasource="#variables.dsn#" username="#variables.dbUser#" password="#variables.dbPass#">
            UPDATE ggcctask
            SET ownerID = <cfqueryparam value="#ownerID#" cfsqltype="cf_sql_varchar"/>,
                statusID = <cfqueryparam value="#statusID#" cfsqltype="cf_sql_varchar"/>,
                lastUpdated = <cfqueryparam value="#now()#" cfsqltype="cf_sql_date"/>
            WHERE taskID = <cfqueryparam value="#taskID#" cfsqltype="cf_sql_varchar"/>
        </cfquery>
        <cfreturn arguments.event />
    </cffunction>

■GGCC9->taskManager.cfc->saveTask

    <cffunction name="saveTask" returntype="ModelGlue.Core.Event" access="public" output="false">
        <cfargument name="event" type="ModelGlue.Core.Event" required="true"/>

        <cfset var task = createObject("component","ggcc9.beans.taskBean").init(argumentCollection=arguments.event.getAllValues()) />
        <cfset variables.taskDAO.update(task) />

        <cfreturn arguments.event />

    </cffunction>

次回は、Javaのlog4Jをロギングに使う場合のサンプルについて解説します。


ColdSpringAOP

ColdSpringsの 正式サイトがオープンしました。

SpikeのCFCDOCによるColdSpringのコード参照機能、
Raymond CamdenのGalleonによるフォーラム機能、
Daemonの FarcryによるCMS機能を使っているようです。
ColdfusionMX用フリーソフトを使ってここまでできるんですねえー。

  • The code (that helps)
  • Docs (those help too)
  • Forums powered by Ray's Galleon
  • API Docs powered by Spikes CFCDoc
  • And of course the whole site is powered by Daemon's Farcry.

ModelGlue+ColdSpringAOP

Model-Glue + ColdSpringAOP連携アプリケーション ggcc9
じっくりながめてみた。
Model-Glue + tartan連携アプリケーション ggcc8 と比べてみると
ColdSpringAOPのAOP機能ではなく、bean(VO)機能によって
ずいぶんシンプルコードがシンプルになったなーという印象。
 


続きを読む "ModelGlue+ColdSpringAOP" »

Spring

Springの概要を以下のサイトを参照しながら、まとめてみた。
もともとはJava/J2EEアプリケーション用に開発されたフレームフレームなので、
非常にシンプルな考えに基づいている。

概要とキーワードは以下のとおりだろうか・・・

Java / J2EE アプリケーション用フレームワーク(オープンソース)

MVC フレームワーク
JDBC抽象化フレームワーク
既存フレームワークの利活用
トランザクション管理
AOP (アスペクト指向プログラミング)

すべての層をカバー

プレゼンテーション層、ビジネス層、パーシスタント層

IoC ( Inversion of Control )コンテナ

コンテナ上でコンポーネントを管理するための技術
XML で記述された Bean 定義ファイルを使用
オブジェクトの生成、オブジェクト同士の関連を生成
既存フレームワークへの統合アクセスを実現

Struts
Hibernate
WebWork
JDO

以下のサイトが参考になります。
Spring-Java/J2EEアプリケーションフレームワークリファレンスドキュメント

徹底解剖! Spring Framework の実力を探る

 

o

ColdSpringAOP & ModelGlue

ModelGlue+Tartanで当面はアプリケーションを作っていこうと思っていたら、
今月、Dave Ross & Chirs ScottによるColdSpringAOP0.2.1がリリースされ、ModelGlueとの連携も
あっという間に、Seanが作り上げてしまった。

しばらく、ColdSpringAOP関連を追っかけて、
Model-Glueとの連携についても整理したので、まとめておきます。

ColdSpringAOPのまとめ ColdSpringAOP.txtをダウンロード
Model-Glue + ColdSpringAOP連携アプリケーション ggcc9

次回から数回にわたって、ColdSpringAOPの解説してみます。

modelglue+tartanのサンプル紹介-5

今日は、getMembersについて・・・
init()メソッドで定義したLoacalServiceへのproxyとサービス定義を使って、これに
コマンド名
引数パラメータ(struct)
戻り値(struct)
を定義して、あとはほいっと

  <cfset result = proxy.invokeCommand(service, command, args) />

でコールするだけです。

<cffunction name="getMembers" returntype="ModelGlue.Core.Event" access="public" output="false"  hint="I return a query object containing all of the members' information">
    <cfargument name="event" type="ModelGlue.Core.Event" required="yes" />

    <!--- appended for Tartan handling 2005/06/28 By Tomoaki Tanaka --->
    <cfset var proxy = GetTartan() />
    <cfset var service = getHelloService() />
    <cfset var command = "getMembers" />
    <cfset var args = structNew() />
    <cfset var result = structNew() />

    <cfset result = proxy.invokeCommand(service, command, args) />
    <cfif structKeyExists(result,"users") >
         <cfset arguments.event.setValue("users",result.users) />
         <cfset arguments.event.setValue("userByCookie",result.userByCookie) />
         <cfset arguments.event.setValue("userByID",result.userByID) />
   </cfif>
   <!---
        <cfif structKeyExists(result,"result") >
                <cfset arguments.event.addResult("setIdentitySuccess") />
        <cfelse>
                <cfset arguments.event.addResult("setIdentityFailure") />
        </cfif>
   --->
   <cfreturn arguments.event />
 
<!--- Original setting & scripts ggcc7
    <cfset var users = 0 />
    <cfquery name="users" datasource="#variables.dsn#" username="#variables.dbUser#" password="#variables.dbPass#">
    SELECT * FROM ggccuser
    ORDER BY firstName
    </cfquery>
    <cfset arguments.event.setValue("users",users) />
    <cfreturn arguments.event />
--->
</cffunction>

modelGlue+tartanは、modelGlueのControllerをシンプルにすることが、重要かなあー。
なぜなら、modelGlueのControllerを複雑にしても、Tartan側のサービスは一つだけだから・・・
それに、ModelGlueからTartanをコールする際にメモリを節約したいよねえ・・・

modelglue+tartanのサンプル紹介-4

さて、modelglue.xmlの一例を紹介したところで、controller<userManager>を見てみます。
 controller<userManager>は、ModelGlue.Core.Controllerを拡張したものです。
冒頭に、お決まりのinit( )メソッドがありますが、一般的なmodelglueアプリケーションの場合と比較して、tartan連携モデルでは、tartanサービスの呼出し手続きをinit( )で行います。

1.一般的modelGlueアプリケーション

    <cffunction name="init" returntype="usermanager" access="public" output="false">
        <cfargument name="core" type="ModelGlue.ModelGlue" required="true"/>
        <cfset super.init(arguments.core) />
        <cfset variables.dsn = arguments.core.getConfigSetting("dsn") />
        <cfset variables.dbUser = arguments.core.getConfigSetting("dbUser") />
        <cfset variables.dbPass = arguments.core.getConfigSetting("dbPass") />
        <cfreturn this />
    </cffunction>

2.tartan連携modelGlueアプリケーション

<cffunction name="Init" access="Public" returnType="userManager" output="false" hint="I build a new SampleController">
  <cfargument name="ModelGlue" type="ModelGlue.ModelGlue" required="true" />
  <cfset var result = "" />

  <cfset super.Init(arguments.ModelGlue) />
 
  <!--- Load the config params for the Tartan app we're talking to --->
  <cfset result = getModelGlue().getConfigBean("Tartan.xml") />
 
  <!--- Load the Tartan proxy --->
  <cfset variables.tartanProxy = createObject("component", "ModelGlue.Util.TartanProxy").init(result) />
 
  <!--- We're going to need the catClub service universally --->
  <cfset variables.clubService = getTartan().CreateService("catClub") /> 

<!--- append from original "init" function ---> 
  <cfset variables.dsn = arguments.ModelGlue.getConfigSetting("dsn") />
  <cfset variables.dbUser = arguments.ModelGlue.getConfigSetting("dbUser") />
  <cfset variables.dbPass = arguments.ModelGlue.getConfigSetting("dbPass") />


  <cfreturn this />
</cffunction>

tartan連携アプリケーションでは、以下の部分をおまじないとして追加すればいいようです。
(ただし、CreateService( ) 内のサービス名をターゲットに応じて変更してください。)

  <!--- Load the config params for the Tartan app we're talking to --->
  <cfset result = getModelGlue().getConfigBean("Tartan.xml") />
 
  <!--- Load the Tartan proxy --->
  <cfset variables.tartanProxy = createObject("component", "ModelGlue.Util.TartanProxy").init(result) />
 
  <!--- We're going to need the catClub service universally --->
  <cfset variables.clubService = getTartan().CreateService("catClub") /> 


次回は、メソッド<getMembers>について、紹介します。

modelglue+tartanのサンプル紹介-3

ggcc8におけるevent-handlerとcontrollerの関係を、ggcc.homeイベントを例にじっくり見てみる。
ggcc.homeイベントは、以下のように定義さrている。

<event-handler name="ggcc.home">
    <broadcasts>
        <message name="needMembers"/>
    </broadcasts>
    <views>
        <include template="dspShowHome.cfm" name="content">
            <value name="XFA.ShowTasks" value="ggcc.showmanager"/>
            <value name="XFA.Constitution" value="ggcc.showpage"/>
            <value name="XFA.Bylaws" value="ggcc.showpage"/>
            <value name="XFA.Minutes" value="ggcc.showpage"/>
        </include>
        <include template="layGGCC.cfm" name="final"/>
    </views>
</event-handler>

ggcc.homeイベントの挙動は次のようになる。
1.<needMembers>リスナーを呼び出し、
2.<dspShowHome.cfm>にいくつかのパラメータを渡しながら、その表示結果を<content>に保存し、
3.最後に<layGGCC.cfm>で端末に表示している。

<needMembers>リスナーはどこで定義されているかと、controllersセクションを見渡すと、
controller<userManager>に"needMembers"がある。

<controller name="usermanager" type="ggcc8.controller.usermanager">
<message-listener message="needMembers" function="getMembers"/>
 <message-listener message="choseIdentity" function="setIdentity"/>
<message-listener message="checkIdentity" function="checkIdentity"/>
</controller>

したがって、message<userManager>がブロードキャストされると、userManager.cfc内のファンクション<getMembers>をコールしています。つまり、フレームワーク名:ModelGlueの指し示すとおり、イベントとモデル(ビジネスロジック)を接着することがこのフレームワークの特徴と言えます。

modelglue+tartanのサンプル紹介-2

さて、前回のディレクトリ構成とコンフィグ構成に続いて、今日はコンフィグ構造に着目します。まずは、modelglue.xmlから。

1.<controllers>セクション
  5つのcontrollerが定義されている。
    mailer                        メール送信マネージャ
     taskmanager               タスクマネージャ
     usermanager              ユーザマネージャ
     relocator                  リロケータ
     viewConstants           キュー完了フォロワー
2.<event-handlers>セクション
   13のevent-handlerが定義されている。
    ggcc.home                 デフォルトイベント
    ggcc.showpage           スタティックページ表示用イベント
    ggcc.contact              コンタクト問い合わせイベント
    ggcc.sendmail             メール送信イベント
    ggcc.identify              ユーザ認証イベント
    ggcc.setidentity         ユーザ完了イベント
    ggcc.showmanager    最新情報表示イベント
    ggcc.showtask           最新タスク表示イベント
    ggcc.newtask             新規タスク生成イベント
    ggcc.savetask            タスク保存イベント
    ggcc.addtask              タスク追加イベント
    addnoteandnotify       記事追加&通知イベント
    failure                      例外発生イベント

modelglue+tartanのサンプル紹介-1

前回、再度紹介したmodelglue+tartanアプリケーション例”ggcc8”について、しばらく解説していきたいと思います。初回は、ディレクトリ構成とコンフィグ構成について紹介します。なお、アプリケーション名とアプリケーションフォルダはともに、ggcc8とします。

1.ディレクトリ構成
  ColdFusionのWWWルートフォルダの配下に、modelglue、tartan及びggcc8フォルダを配置します。

    cfmx_wwwroot--+---modelglue/
                           +---tartan/
                           +---ggcc8/--+--application.cfm
                                               +--index.cfm
                                               +--config/--+--ModelGlue.xml
                                               |                  +--service.xml
                                               |                  +--beans/tartan.xml
                                               +--controller/--+--mailer.cfc
                                               |                        +--relocate.cfc
                                               |                        +--taskmanager.cfc
                                               |                        +--usermanager.cfc
                                               |                        +--viewconstants.cfc
                                               +--view/--+--layGGCC.cfm
                                               |                +--dspShowHome.cfm
                                               |                +--dspxxxxxxxxx.cfm
                                               |                +--exception.cfm
                                               |                +--etc.cfm
                                               +--tartan/--+--services/localservice.cfc
                                                                  +--commands/someCommand.cfc
                                                                  +--vo/someBean.cfc
                                                                  +--data/--+--someDAO.cfc
                                                                  |                 +--someGateway.cfc
                                                                  +--exceptions/xxxxxx.cfc
2.コンフィグ構成
  ggcc8の配下にあるconfigフォルダに、
  1)modelglue用コンフィグファイル:ModelGlue.xml
  2)tartan用コンフィグファイル   :service.xml
  config/beansフォルダに、
  3)tartanマッピング用コンフィグビーン:tartan.xml
  を配置します。

次回は、各々のコンフィグファイルについて解説します。

Model-Glue+Tartan その2

ModelGlueとTartanの連携について、資料 をまとめてみた。

しばらく、このパターンでアプリケーション開発にいそしんでみようと思う。
また、ModelGlueのサンプルアプリケーションの中から、tartan連携アプリケーション:helloWorldをまとめてみた。modelgluetartan_example.txtをダウンロード

SeanCorfieldに紹介された応用アプリケーションggcc8のダウンロードはこちらから、どうぞ!

Tartan 1.04 リリース!

Tartan1.04がリリースされました。詳細はこちら

1.unit testsの追加
2.tartan.service.LocalServiceProxy classの追加
    RemoteFlashService と RemoveSoapServiceのベースクラスに!
    tartan.service.RemoteService classは廃止
3.tartan.service.RemoteService classの追加
    MachIIListener classの別機能として追加
4.その他・・・

Model-Glue DTD#2

Model-Glue DTDで紹介したとおり、Model-Glue.xmlもXML DTDに対応する動きとなったことを紹介しましたが、Wayne GrahamがXML SchemaやRelaxNGに対応させる記事をポストしています。
対応するModel-Glueのバーションは0.9となっています。

XML Schema         :こちら
RelaxNG(Full)         :こちら
RelaxNG(Compact) :こちら


 




Model-Glue Viewデータのキャッシング

topica.comのModel-GlueのMLで、'Caching Content in MG'というタイトルでコンテンツのキャッシングに関するスレッドが立った。

解決方法は、ズバリ・・・
ModelGlue.Core.controller.cfc内のGetFromCache

ModelGlue.Util.TimedCache.cfc内のItemNotFound

ModelGlue.Core.controller.cfc内のAddToCache
を使う。つまり、
1.キャッシュしたいコンテンツ<"news">を定義し、
 <cftry>

   <cfset news =GetFromCache("news") />
2.次に、キャッシュの有無をチェックし、
   <cfcatch type="ModelGlue.Util.TimedCache.ItemNotFound">
3.例外が生じた場合、特定の処理を実施し、キャッシュに追加

     something query
     <cfset addToCache("news", news) />

       <cfcache />

  </cftry>

するようだ。

<cffunction name="GetNews" access="Public" returnType="void"
output="false" hint="I am an event handler.">
  <cfargument name="event" type="ModelGlue.Core.Event" required="true">

  <cfset var news = "" />

  <cftry>
    <!--- Try to get it from the cache --->
    <cfset news = getFromCache("news") />
    <!--- If it's not in the cache --->
    <cfcatch type="ModelGlue.Util.TimedCache.ItemNotFound">
      <cfquery datasource="foo" name="news">
        SELECT newsId, title FROM news
      </cfquery>
      <cfset addToCache("news", news) />
    </cfcatch>
  </cftry>

  <cfset arguments.event.setValue("news", news) />
</cffunction>

うーん、やはりModelGlueの内部をもう少し学ぶ必要がありそうだなあー。



 

Model-Glue DTD

Model-Glueの公式サイトに、Model-GlueのDTDに関するエントリーがVer1.0のリリースにあわせてポストされた。
Wayne Graham's blogのエントリーと併用するとModel-Glueのxml定義が楽になりそう。

<!ELEMENT modelglue (config,controllers,event-handlers)>
<!ELEMENT config (setting+)>
<!ELEMENT setting (#PCDATA)>
<!ATTLIST setting name CDATA #REQUIRED value CDATA #REQUIRED>
<!ELEMENT controllers (controller+)>
<!ELEMENT controller (message-listener+)>
<!ATTLIST controller name CDATA #REQUIRED type CDATA #REQUIRED>
<!ELEMENT message-listener (#PCDATA)>
<!ATTLIST message-listener message CDATA #REQUIRED function CDATA #REQUIRED>
<!ELEMENT event-handlers (event-handler+)>
<!ELEMENT event-handler (broadcasts*,views*,results*)>
<!ATTLIST event-handler name CDATA #REQUIRED access CDATA #IMPLIED>
<!ELEMENT broadcasts (message*)>
<!ELEMENT message (argument*)>
<!ATTLIST message name CDATA #REQUIRED>
<!ELEMENT argument (#PCDATA)>
<!ATTLIST argument name CDATA #REQUIRED value CDATA #REQUIRED>
<!ELEMENT results (result*)>
<!ELEMENT result (#PCDATA)>
<!ATTLIST result name CDATA #IMPLIED do CDATA #REQUIRED relocate CDATA #IMPLIED>
<!ELEMENT views (include*,value*)>
<!ELEMENT include (value*)>
<!ATTLIST include name CDATA #REQUIRED template CDATA #REQUIRED append CDATA #IMPLIED>
<!ELEMENT value (#PCDATA)>
<!ATTLIST value name CDATA #REQUIRED value CDATA #REQUIRED overwrite CDATA #IMPLIED>

 

Model-Glue.xmlの拡張

Sean Corfieldのブログで、Model-Glue DTD がVer1.0のリリースにあわせて検討されているらしい旨を書かれていたが、Ver1.0RC1では今だリリースされていない。
そんなところに、Wayne Grahamのブログで、modelglue.xmlに、DOCTYPEを定義して拡張する方法が記述されていた。

ポイントは以下のとおり。
1.modelglue.xml内に、DOCTYPEを定義する。
2.外部拡張用フォルダとして、wwwroot内(もしくは、マッピングフォルダ内)にtempletesフォルダを作成する。
3.templetes配下にmodelGlueアプリケーションフォルダ:stockQuateを作成し、三つの拡張xmlファイルを作成する。
 1)config.xml
  2)controllers.xml
  3)event-handlers.xml
4.model.glue.xmlの定義イメージは以下のとおり。

<!DOCTYPE  [
     <!ENTITY mapping
"/modelgluesamples">
     <!ENTITY appName "StockQuote">
     <!ENTITY folder "stockquate">
     <!ENTITY hello "HelloWorld">
     <!ENTITY config SYSTEM "http://localhost/modelgluesamples/templates/stockquate/config.xml">
     <!ENTITY controllers SYSTEM "http://localhost/modelgluesamples/templates/stockquate/controllers.xml">
     <!ENTITY events SYSTEM "http://localhost/modelgluesamples/templates/stockquate/event-handlers.xml">
  ]>
    <modelglue>
     &config;
     &controllers;
         &events;
  </modelglue>

5.config.xmlの定義イメージは以下のとおり。

<?xml version="1.0" encoding="UTF-8"?>
  <config>
              <setting name="defaultEvent" value="&appName;" />
              <setting name="applicationMapping" value="&mapping;/&folder;" />
              <setting name="beanMappings" value="&mapping;/&folder;/config/beans/" />
              <setting name="viewMappings" value="&mapping;/&folder;/views" />
              <setting name="reload" value="false" />
              <setting name="reloadKey" value="init" />
              <setting name="reloadPassword" value="true" />
              <setting name="statePrecedence" value="Form" />
              <setting name="eventValue" value="event" />
              <setting name="modelGlueMapping" value="/ModelGlue" />
              <setting name="defaultExceptionHandler" value="Exception" />
              <setting name="debug" value="true" />
              <setting name="defaultCacheTimeout" value="5" />
       </config>

6.controller.xmlの定義イメージは以下のとおり。

<?xml version="1.0" encoding="UTF-8"?>
  <controllers>
      <controller name="myController" type="&mapping;.&folder;.controller.Controller">
          <message-listener message="OnRequestStart" function="OnRequestStart" />
          <message-listener message="OnRequestEnd" function="OnRequestEnd" />
          <message-listener message="DoHelloWorld" function="GetGreeting" />
          <message-listener message="DoStockQuote" function="GetStockQuote" />
      </controller>
  </controllers>

7.event-handler.xmlの定義イメージは以下のとおり。

<?xml version="1.0" encoding="UTF-8"?>
  <event-handlers>
      <event-handler name="Home">
          <results>
              <result do="Layout" />
          </results>
      </event-handler>
            <event-handler name="&hello;">
          <broadcasts>
              <message name="DoHelloWorld" />
          </broadcasts>
          <views>
              <include name="content" template="dsp.helloworld.cfm">
                  <value name="greeting" value="I am the default greeting." />
              </include>
          </views>
          <results>
              <result do="Layout" />
          </results>
      </event-handler>
            <event-handler name="&appName;">
          <broadcasts>
              <message name="DoStockQuote">
                  <argument name="DefaultSymbol" value="MACR" />
              </message>
          </broadcasts>
          <views>
              <include name="content" template="form.&folder;.cfm" />
          </views>
          <results>
              <result name="BadSymbol" do="BadStockSymbol" />
              <result do="Layout" />
          </results>
      </event-handler>
            <event-handler name="BadStockSymbol" access="private">
          <views>
              <include name="content" template="dsp.badStocksymbol.cfm" />
          </views>
      </event-handler>
            <event-handler name="Layout" access="private">
          <views>
              <include name="main" template="layout.main.cfm" />
          </views>
      </event-handler>
            <event-handler name="Exception">
          <views>
              <include name="body" template="exception.cfm" />
          </views>
      </event-handler>
  </event-handlers>

ModelGlue Ver1.0RC1

Model-GlueのVer1.0のRC1がここから入手できます。
ダウンロードするには、SVNクライアントが必要なようです。


Model-Glue+Tartan

Sean Corfieldの記事にあったサンプルアプリケーションGGCCをModelGlue+Tartanに移植してみた。
移植に際してのベースアプリケーションは、GGCC7(ModelGlue)+GGCC6(FuseBox4.1+Tartan)。
動作確認済コードは、GGCC8です。興味のある方はこちら から、どうぞ!

FuseBox4.1+Tartanの動作環境から大きく変更したポイントは以下のとおりです。

  1. LocalService.cfc内FunctionのReturnTypeを"void"から"struct"に変更
  2. ModelGlue用Controllerのinit( )FunctionにtartanProxyの初期化ブロックを追加。
  3. ModelGlue.xml内<broadcasts>セクションから、needMemberByIDとneedStatiiByIDをコメント化。

詳細は、ぼちぼちご案内します。

 

Model-Glue FAQ

SeanのブログにModel-GlueのFAQ例が紹介されていた。
もう少しブレークダウンしたFAQが必要だとは思いますが、日本語訳したものを取り急ぎご紹介しておきます。

Eddie Awad’s Blog

全般

ビュースタックのうちどれがユーザに表示されますか?
レンダリングされた最後のViewだけがユーザに表示されます。


HTML FormとURL変数はどこに保存されますか?

全てのHTML formとURL変数は、ModelGlue.Core.Eventオブジェクトに保存されます。

Event起動の優先順位は?(resultタグ)
明示的なresult(名前属性を有する)を暗黙的なresult(名前属性を有しない)の前に起動します。

コントローラー:

データをViewに渡すには?
データをViewに渡す (コンプレックスデータタイプを含む)にはarguments.event.setValue(”name”, value)を使います。


ModelGlue.xmlのConfigデータセクションにアクセスするには?
<config>と</config>で与えられるModelGlue.xmlのConfigデータセッティングにアクセスするには、GetModelGlue().getConfigSetting(”settingName”)を使います。


マップドイベントを呼び出すには?

resultをeventにマッピングし、イベントを呼び出すにはarguments.event.addResult(”eventName”)を使います。


ConfigBeanへの参照を得るには?

まず、 <cfset appConfig = GetModelGlue().GetConfigBean("yourBeanFile.xml")> を使い、 セットしたデータをフェッチするには、appConfig.getSettingName() を使います。


Messageの引数にアクセスするには?

arguments.event.getArgument(”name”)を使います。

ModelGlue.xml:

Viewにデータを送るには?
Viewにデータを送るには、
<include>タグの中で<value>タグをこのように使います。 
<event-handler name="dosomething">
            <views>
                <include template=”view.cfm” name=”body”>
                    <value name=”name” value=”value” />
                </include>
            </views>
        </event-handler>

overwrite=”true” か overwrite=”false” を <value>タグに追加することによって、オーバライドするかしないかを指定することができます。


既存Viewに追加するには?

ユニークでないView名をincludeタグに与えるには、'append=”true”‘ を属性に追加しますI。そうすることで、既存Viewのコンテンツに追加書き出しできます。
    <event-handler name="dosomething">
        <views>
            <include template=”view1.cfm” name=”body” />
            <include template=”view2.cfm” name=”body” append=”true” />
        </views>
    </event-handler>

‘append=”true”‘ がない場合、既存Viewをオーバライドします。


M
odelGlue.xmlに一つまたはそれ以上のControllerを定義できますか?
はい、複数のControllerを定義できますが、Controller間でユニークなmessage名である必要があります。


Model-Glueには特別なmessageが準備されていますか?

ModelGlue.xmlでは, Controller内に次のような特別なMessageをマッピングできます:

onRequestStart: リクエスト開始時に必要となる処理をここに記述します。
onRequestEnd:
リクエスト終了時に必要となる処理をここに記述します。
onQueueComplete: すべてのViewが追加され、レンダリングされる前に必要となる処理をここに記述します。


messageに引数を追加できますか?
はい、次のようにしてMessageに引数を追加できます。
<message name="dosomething">
        <argument name=”name” value=”value” />
    </message>

Controller内の対応するファンクション内で次のようにして引数を読み出せます。
arguments.event.getArgument(”name”)

Views:

レンダリングされたViewスタック内のViewにデータをセットするには?
Use viewState.setValue(”name”,”value”)


Controller、ModelGlue.xml及びViewスタックからデータを読み出すには?
Use viewState.getValue(”name”, “default value”)


V
iewスタック内におけるViewの存在をチェックするには?
Use viewCollection.Exists(”viewName”)


過去に定義されたViewコンテンツを表示するには?
Use viewCollection.getView(”viewName”)

リソース:

 

Mach-IIは死んだ?

Sean Corfieldのブログでは、最近"Mach-IIが死んだ""Mach-II退場、ModelGlue入場"を意味するような記事やタイトルが飛び交っている。私も昨年からMach-IIのドキュメントを読みあさったりしていたのだけど、なかなかサンデープログラマーには敷居が高くて、なかなかサンプルアプリケーションを作り出せずにいた。
でも、Model-Glueに接していらい、Mach-IIから乗り換えることに決めた。

先日、SeanがFuseBoxベースのCatClubというプログラムを、Mach-II、Model-Glueに移植した例を彼のブログに掲載した。確かにModel-Glueが一番エレガントだ。今後は、Model-Glue+TarTanが主流になると思う。

Model-Glue Ver0.9リリース

Sean CorfieldのAn Archtecture's ViewModel-GlueのVer0.9がリリースされた旨のアナウンスがありました。
今回のリリース内容は以下のとおりのようです。

  1. Controllerがタイムキャッシュももてるようになった。
  2. サブアプリケーションのサポート(ModelGlue_APP_KEY)
  3. eventオブジェクトにデバックトレースが追加された。
    • arguments.event.trace(label, value)
    • 任意形式の値
    • CFDump結果同様に扱えるようになった。
  4. デバッグトレースは、例外が発生したときのみ表示するようになった。

Mach-IIとModel-Glue(続き)

Sean Corfieldが、Mach-IIとModel-Glueに関する記事の続きを書いた。

More thoughts on Mach II and Model-Glue
Mach-II アプリケーションのModel-Glueへの移管でわかったこと。

総じてModel-Glueの長所を言及している。

1.event-handlerの定義がMach-IIとModel-Glueで異なる。ちょっと混乱?
    Mach-II          <event-handler event= ... >
    Model-Glue    <event-handler name=... >
2.シンタックスの構造化とシンプルなタグ
    Mach-II           フラットシンタックス
         event-handlersセクション:連続した1行単位のXMLタグ

              event-handlerセクション

                   event-mappingセクション
                   event-argsセクション
                   notifyセクション
                   annouceセクション
                   filterセクション

    Model-Glue    ネステッドシンタックス

         event-handlersセクション:ネストされ、インデントされ構造化されたXMLタグ
              broadcastsセクション
                   messageセクション   
              viewsセクション
                   includeセクション
              resultsセクション
                   resultセクション

結果として、Mach-IIと比較して、Model-Glueのほうが、コントロールロジックとプレゼンテーションロジックを明確に分離でき、eventオブジェクトをデータバスとして一貫して使用できる・・・

3.リスナー定義数の削減
    Mach-II            25個のListnerCFCs
    Model-Glue        6個のControllerCFCs
4.ちょっと困ったこと
    notifyセクションとview-pageセクションの組合せで実現できていたビューの結果をMach-IIではビジネスロジック中で使用できていたが、Model-Glueでは代替手段(Cfsavecontent)を使うことでしかできない。

5.総括:Model-Glueがいい!
    There's no doubt that Model-Glue has benefitted from the experiences of both Mach II and Fusebox but it has also added its own unique elements. Consistency and simplicity are key drivers for Model-Glue which means you sacrifice some power and expressiveness. As always, it's all about tradeoffs and you need to make the choice based on the needs of your project (and, to some extent, your own personal preferences).

Mach-IIとModel-Glue

最近は、Model-Glueのマニュアルの日本語化を通じてModel-Glueの概要を作成していた。
Model-GlueってMach-IIより敷居が低くて結構使えるなーって思いつつ会社の新しい業務プロセスに応用してみようと思っていたところ、Sean Corfieldがブログでそのことを言及していました。

MachII OUT, Model-Glue In!
MacromediaのWebチームのスタンダードになっているMach-IIは、アプリケーション構造、コントロールフローがmacii.xmlファイルに書かれているので、メンテナンス性が悪い。いわば、コンテナのマネージメント:"Inversion of Control"(制御の逆転)を行うため、Model-Glueへの移行を検討した。

Mach-ii.xml file:
    522行, 23Kバイト(XML圧縮後), 25個のListner定義
ModelGlue.xml file:
    427行, 11Kバイト(XML圧縮前), 6個のController定義、5個のConfigBeanCFCs、
    22個のBean定義ファイル(710行, 16Kバイト).

早速、Mach-IIとModel-Glueの比較をビジュアル化してみようと思う。

CFMX開発 Mach-II vs FuseBox

Mach-IIとFuseBoxの領域モデルについて、Hal Helms とJeff Petersが熱く語っているサイトの内容をゆっくり熟読してみた。
広くCFMX開発者で認識されている

Mach-I I ⇒ OO(Object Oriented)
FuseBox ⇒ Procedual

ではなく、

Mach-I I ⇒ 厳密なOO    
       ⇒ OOを熟知したOOPが必須
                  ⇒ 敷居が高い
FuseBox ⇒ ゆるやかなOO
                ⇒ OOを熟知していなくても、OOPもどきができる
                  ⇒ 敷居が低い

ということのようだ。
ブログの記事をハックして表示するためのサンプルプログラムを作りながら、比較してみよう。

CFMX開発 Tartanとは?

Tartanの公式サイトを訪問してみた。

Tartan
とは?を読むと・・・こんな感じかなー。

リリースノートを見ると、Mach-IIのリスナーとして使えるようだ。
また、ロードマップを見ると、FuseBox4.1やFlashRemotingにも対応予定みたい。
ColdFusionMX 7のAsynchronous CFML Eventsもサポート予定。

  1. Tartanは、ColdFusion MX 用のコマンドドリブンのサービスフレームワーク
  2. 機能性の完全分離かレイヤリングを指向する大規模なアプリケーションアーキテクチャのサービスレイヤを開発を手助けするもの
  3. ビジネスロジック配下に対する全てのアクセスは、ローカルアクセスのCFCsとリモートアクセスとしてのFlash RomortingおよびSOAPウェブサービスにアクセス可能なパブリックサービス(public service)に制御される。
  4. ひとつのサービスは、いくつかのコマンドで構成され、各コマンドはアプリケーションにおいて、ある分離された機能を実装している。
  5. 各コマンドは、アプリケーションのコアロジックを包含している。
  6. 各コマンドは、DAOsを介してデータベースと通信し、クライアントから受信したデータを取り扱い、他のコマンドを実行し、他のリモートサーバ上で利用可能なサービスと通信することができる。
  7. Tartanには、6つのコアクラスがある。
    • Core Clases
    • RemoteService
    • LocalService
    • Command
    • DAO
    • VO(Value Object)
    • ExceptionHandler
  8. 6つのコアクラスは、フレームワークの主要機能を提供し、アプリケーション開発者によって継承可能。


 

CFMX開発 Fusebox4.1 with Lexicon

Fuseboxのサブフレームワークとして、'Lexicon'がリリースされていた。
Fuseaction毎のView表示に異なるスタイルシートを適用するためのようだ。

CFMX開発 フレームワーク比較表2

CFMX用フレームワーク比較表で、Fusebox、Mach-II、Model-Glueの比較をしていたことを思い出して、もう比較表を見直してみました。
やっぱり、Fuseboxは敷居の低さ、Mach-IIはプロフェッショナル用、Model-Glueは両方のいいとこ取りって感じです。

各比較項目のうち、1行目は共通点、2行目以降は差異点です。
(以下、各フレームワークの略称 FB:Fusebox/M2:Mach-II/MG:Model-Glue)

・XML
All use XML config files
FB has multiple XML,  M2/MG has one XML
・MVC
Can use MVC
FB allows but does not enforce, M2/MG pretty much forces it
・MVC Structure
Model/View directories
FB typically has controller circuit directory, M2/MG has implicit controller in framework
・CFCs
Can use CFCs
FB allows but does not enforce, M2/MG pretty much forces it
・Plugins
All have plugin points
FB has more plugin points, M2 distinguishes events and views, MG has simple request/queue model
・Access control
All have private / public concepts
FB has per circuit and per fuseaction as well as roles-based model, M2/MG has per event access only
・Auth / Security
None
FB has roles support builtin, M2 provides a sample filter, MG is free form
・Install / Config
One-stop core files, basic properties in XML file
One-stop core files is brand new in FB41, FB provides finer control over framework behavior, MG has a simple framework control model
・Modularity of Application
None
FB has circuits to partition large applications
・Modularity of Site
None
M2 allows multiple sub-applications to share application scope
・Commonality
Can explicitly invoke fuseactions / announce events / add results to handle common functionality  FB has per-circuit pre-/post-fuseaction hooks, providing framework level support for commonality
・Views
All encourage views to contain “only HTML” (no logic)
FB/MG lets you include a view directly, M2 requires that you declare all views in XML
・Handler Model
All declare 'handlers' for 'events' in XML
FB is a static, explicit invocation model, M2 is a dynamic, implicit invocation model, MG is somewhere in between
・Data bus
Can use request scope as data bus (but it's not always best practice) – MG uses event object   FB allows variables scope as data bus, M2 allows event object as data bus, MG enforces event object as data bus
・Global data
None
FB has fusebox.init.cfm, M2 uses either 《property》 tags or plugin (or both), MG has settings
・Model CFC Structure
Most CFC methods could be the same
FB uses standard init() construction controlled by explicit code in fusebox.init.cfm or circuit, M2 reserves init() and uses a managed configure() method to initialize CFCs – with no arguments – and CFCs must extend the framework, MG has base controller init() method
・Conditional logic
None
FB has some conditional logic in the XML grammar, M2 requires conditional logic placed in CFCs, MG requires controller CFCs
・Model Actions
All have the concept of separating business model logic from presentation logic
FB allows a model action to set multiple outputs, M2 uses strict call/return semantics so each action can have only one result, MG allows a model to set multiple outputs via event object
・Model Queries
None
FB specifically separates out persistence operations (by a naming convention on files), M2/MG draws no distinction between actions and queries

ちょっと長かったかな?

CFMX開発 Model-Glue

Tartanのことを調べていたら、Model-Glueにたどり着いた。
確かに、一回目の記事で、Coldfusion用フレームワークのひとつとしてSeanの記事を引用していたのだけど、Model-GlueがTartanの機能を包含しているようだ。

There's been a lot of talk about using ColdFusion Components (CFCs) to seperate presentation layer from business logic. Model-Glue facilitates this by giving you an easier, more powerful way to connect your presentation layer (View) from your business logic (Model). It does this by letting you create what are called "Controllers", and then letting you define how they interact with the presentation layer (We're calling it View from now on!) through a simple XML schema.

Model-Glue also provides a configuration utility for your applications called ChiliBeans. It makes it easy to offload configuration information (like development datasource vs. production datasource) into XML files. More on that in another Quickstart.

Mach-IIの思想を取り入れつつ、Fuseboxの敷居の低さを追求しているのだろうか?もう少し調べてみよう。

CFMX開発 フレームワーク論

CFMX開発とフレームワークをGoogleで検索したら、ここに参考資料がありました。
フレームワークとは?を以下のように述べている。ふむふむ・・・

1.パターン
家づくりを考えろ!
建築様式と建造方法にはどんなパターンがありますか?
2.ルール
やっていいこと、やってはいけないこと、そして最適解。
屋根を地面にある家はないだろう?
3.構造
壁、ドア、窓、屋根の型式を定義しなさい。
産業的に統一されたパターンとルールが、標準ドア(カスタムフィットオプションが可能な)を供給する。

さらに、Coldfusionの3つのフレームワークを以下のように比較している。

1.Mach-II
MVCイベントドリブンベースのcfcフレームワーク
2.Fusebox4.1
簡単、標準、柔軟、自然なcfmフレームワーク
3.Tartan
オブジェクト指向のコマンドドリブンベースのサービス層フレームワーク

なんとなく、個人的な好みとしては、Mach-II+Tartanかなー。

CFMX開発 Fuseboxドキュメント

Fuseboxの日本語ドキュメントを探したら、ここにありました。

Fusebox メソドロジー

FuseboxとMach-IIを比較すると、こんな感じかなー。

Fusebox cfmベースのフレームワーク(シロウトさんもOK!)

Mach-II  cfcベースのフレームワーク(プロ向け!)

CFMX開発 Fuseboxって?

Fuseboxの本家は、ここなんだけど、googleで国内サイトを検索したら、リンコムのテクノロジー紹介に、Fuseboxの記事が載っていた。
>岩上さん、わかりやすい紹介ありがとうございます。

それによると、

【Fuseboxの設計手法上の特徴】
Fuseboxが提供しているものは単にプログラム設計手法だけでなく、ドキュメンテーションなど多岐に渡っています。ここではそのうち、「リンコム ネクスト 2」が採用しているプログラム設計手法に的を絞って説明していきます。

Fuseboxの設計手法上の特徴は大きく分けて以下の2つがあります。
    (1)プログラムのモジュール化/コンポーネント化
    (2)役割に応じたプログラムファイルの分割

とFuseboxの特徴が紹介されていて、
1)プログラムののモジュール/コンポーネント
では、cfmプログラムをヒューズボックスのように、多段構成的にディスパッチすることから、Fuseboxというフレームワーク名となったことが書かれてあった。ふむふむ・・・・
2)役割に応じたプログラムファイルの分割
では、cfmファイルを役割に応じて使い分ける手法がとられているとのこと。

ファイルの役割分担

・Displayファイル
    主に画面に表示するHTMLを記述したcfmファイルです。このファイルの中には極力ロジックの記述は避け、CFOUTPUTのような変数内容を表示するタグのみを記述するようにします。
    ファイル名は「dsp_***.cfm」というフォーマットになります。

・Actionファイル
    画面に表示する内容は含まず、プログラムロジックを記述したcfmファイルです。
    CFMLの表示をつかさどる機能を持ったタグ以外のほとんどのタグは、このファイル内に記述します。ただし以下に示すように、CFQUERYやCFLOCATIONは特別なファイルに分けて記述する場合があります。
    ファイル名は「act_***.cfm」というフォーマットになります。

・Queryファイル
    CFQUERYタグを使ってデータベースへアクセスする部分を切り出したファイルです。こうすることによって、同じクエリー文があったときにはQueryファイルをインクルードするようにすれば、クエリー文の再利用性が高まります。
    ファイル名は「qry_***.cfm」というフォーマットになります。

・Redirectionファイル
    CFLOCATIONタグを使って画面を遷移させる部分を切り出したファイルです。こうすることによって、モジュールを再利用した際に利用者が意図しない画面遷移が起きてしまうのを防ぎやすくなります。
    ファイル名は「url_***.cfm」というフォーマットになります。

4つのファイルは、各々DIsplay(View)、Action(Controller)、Query(Model)、Redirection(View)というように、MVCライクに使われるようです。ふむふむ・・・・

ちなみに、リンコムネクスト2は、Fuseboxの開発手法を取り入れているそうです。

CFMX用フレームワークの比較表

昨日の続き・・・
CF用フレームワークの比較表をSeanが作成していました。

CFMX開発者から、熱いコメントが寄せられているが、SeanはFuseBoxをもっとも支持しているようだ。

Roger Lancefield がそれにフォローする形で、以下のコメント。

Something else that I think would be very interesting for Fuseboxers (in particular), both more and less experienced, would be an analysis of the degree to which Fusebox applications can approximate the structural features of Mach-II applications, and in which areas it makes any sense to do so.

Roger Lancefieldは、CFMX開発には3つのスタイルがあると言っている。
 Fusebox
 Fusebox+Tartan
 Mach-II('fat'Listnersスタイルと'thin'Listnersスタイル)

I'd say there are far more than two approaches to developing Fusebox applications. In my frameworks talk, I cover specifically three different styles of Fusebox application and then show a variant of one of those (using Fusebox with Tartan). I also show two Mach II styles (one with 'fat' listeners, one with 'thin' listeners and a separate business model).

もう少し、様子を見てみよう。

CFMX開発日記はじめよう!

会社の業務支援ツールを作るのに、何気に手にしたColdFusion(CF)のテキスト本・・・

『ColdFusionMXプロフェッショナルガイド』(奥川博司・須賀正明共著)

社内の業務ツールとかコソコソ<コツコツではない(爆)>作りながら、
日本のJCFMLで語られないCFのオブジェクト指向開発やフレームワークについて、
備忘録的に書き綴ってみたいと思う。

ということで、本日の話題は、CF用フレームワークについて・・・・

Sean Corfieldのブログサイトを除いてみると・・・・

    *  Traditional Fusebox
    * MVC Fusebox
    * OO Fusebox
    * Simple Mach II
    * Refactored Mach II using design patterns
    * Fusebox + Tartan
    * Model-Glue

なるフレームワークがCFにはあるそうな・・・・
個人的には、Mach-IIに興味を持ってきたが、こんなにあると何が最適解かわからなくなる・・・・

まあ、ぼちぼち考えていきます。

ログイン

  • コントロールパネルへのログイン
    アカウント:

    パスワード:

更新ブログ

最近のトラックバック

Google

ブログ powered by TypePad
Member since 04/2005