« 2008年04月 | メイン | 2008年06月 »

2008年05月 アーカイブ

2008年05月01日

AOPの実装

では、どのようにAOPを実装するのかを見ていく。

前回のログを書き出すコードとして拝借したファイルは、LogginAroundAdvice.cfc と LoggingService.cfc の2つ。
LoggingService.cfc は、ログを書き出すだけのコンポーネント。
LogginAroundAdvice.cfc は、ログの機能を追加しようとしている関数に対して、どういうタイミングでログを書き出すかを
指定(Advice)するためのコンポーネント。

Advice という用語が出てきた。これが実にわかりにくい。
今でも、はっきりわかっていない。おぼろげな認識では、
“どういう機能(ログ書き出し)をどのタイミング(前、後、前後、エラー時)で提供”するかということだろうか。
そして、Advisor というものもある。その Advice を“どういうものに付け加えるかを指定”するとでも言うのだろうか。
ドキュメントの英文を読んでも、ピンと来ないし、困ったものだ。


 <bean id="loggingService" class="shopping.model.aop.component.LoggingService" />
 
 <bean id="loggingAdvice" class="shopping.model.aop.aspects.LoggingAroundAdvice">
  <property name="loggingService">
   <ref bean="loggingService">
  </property>
 </bean>
 
 <bean id="loggingAdvisor" class="coldspring.aop.support.NamedMethodPointcutAdvisor">
  <property name="advice">
   <ref bean="loggingAdvice" />
  </property>
  <property name="mappedNames">
   <value>*</value>
  </property>
 </bean>

ColdSpring.xml で、このように設定する。
loggingService という Bean を設定し、その機能を AroundAdvice する loggingAdvice を設定。
任意の関数名で処理を織り込む(Weave)loggingAdvisor を設定。

これにより、ログ機能(shopping.model.aop.component.LoggingService)をAOPで利用するための準備が整う。

前回の

 <bean id="shopping" class="coldspring.aop.framework.ProxyFactoryBean">
  <property name="target">
   <ref bean="cartProcessTarget" />
  </property>
  <property name="interceptorNames">
   <list>
    <value>loggingAdvisor</value>
   </list>
  </property>
 </bean>

で、bean id="shopping" に引数 interceptorNames で渡している loggingAdvisor が上記の設定でできるのである。

サンプルアプリケーション

2008年05月02日

Transfer

いよいよ、Transfer だ。
ちょうど、Transfer 1.0 RC がリリースされたようだ。
気になったのは、この2点。

 ・Composite Key Support
 ・Transaction Support

Composite Key ってなんぞや?
今まで、データベースの主キーとして、カラム一つしか指定できなかったっぽいのが、複数のカラムが指定できるようになったということなのだろうか?
どうやら、複数のカラムが指定できるようになったらしい。が、項目として指定できるのは、1つのみで、あとは、外部参照の項目を指定することのようだ。
基本的に正規化してテーブル設計すれば、問題はなさそうだけど、大丈夫なんだろうか。
古いシステムのテーブル設計によく見られる、4つとか、5つとかの項目からなる主キー設定で、なおかつ、
正規化してある訳じゃないテーブルには、使えないということか。

いよいよ、Transfer を読み解いていくことになるわけだが、まずは、データベースを作らなければいけない。
データベースは、環境に非常に影響を受けるので、著しく汎用性が落ちてしまうのが困りものだけど、仕方ない。

とりあえず、慣れている PostgreSQL で作成する。
バージョンは、8.1 だ。

table_01.gif

各テーブルの意味は、そのまんまだから、わかるだろう。
ちなみに、SERIAL 型というのは、データ挿入でオートインクリメントしてくれる INT 型。

データベース作成

createdb -E UNICODE SHOPPING

テーブル作成

CREATE TABLE public.CATEGORYMST (
categoryid INT NOT NULL
, categoryname TEXT NOT NULL
, PRIMARY KEY (categoryid)
);

CREATE TABLE public.ITEMMST (
itemid SERIAL NOT NULL
, lnkcategoryid INT NOT NULL
, itemname TEXT NOT NULL
, price INT NOT NULL
, PRIMARY KEY (itemid)
);

CREATE TABLE public.CARTDATA (
sessionid CHAR(32) NOT NULL
, lnkitemid INT NOT NULL
, categoryname TEXT NOT NULL
, itemname TEXT NOT NULL
, price INT NOT NULL
, PRIMARY KEY (sessionid, itemid)
);

データ登録

INSERT INTO CATEGORYMST (categoryid, categoryname) VALUES (1, 'マウス');
INSERT INTO CATEGORYMST (categoryid, categoryname) VALUES (2, 'キーボード');

INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (1, 1, '光学式マウス', 2600);
INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (2, 1, 'ボールマウス', 1100);
INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (3, 1, 'レーザー式マウス', 4800);
INSERT INTO ITEMMST (itemid, categoryid, itemname, price) VALUES (4, 2, 'テンキー付きUSBキーボード', 1800);
INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (5, 2, 'テンキーなしUSBキーボード', 1200);
INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (6, 2, 'テンキー付きPS/2キーボード', 1100);
INSERT INTO ITEMMST (itemid, lnkcategoryid, itemname, price) VALUES (7, 2, 'テンキーなしPS/2キーボード', 900);
SELECT SETVAL('ITEMMST_itemid_seq', MAX(itemid)) FROM ITEMMST;

これで、データベースの準備はできた。次は、Transfer の設定だ。

2008年05月07日

Transfer の設定

例のごとく、今までのサンプルアプリケーションを変更していく。

まずは、config/transfer/Datasource.xml から。

<datasource>
 <name>shopping</name>
 <username></username>
 <password></password>
</datasource>

ColdFusion の管理画面で、データソースを設定して、その名前を入れるだけ。

次に、config/ColdSpring.xml 。今までコメントアウトしてきたところだ。

<alias alias="ormAdapter" name="ormAdapter.Transfer" />
<alias alias="ormService" name="ormService.Transfer" />
<bean id="transferConfiguration" class="transfer.com.config.Configuration">
 <constructor-arg name="datasourcePath"><value>/shopping/config/transfer/Datasource.xml</value></constructor-arg>
 <constructor-arg name="configPath"><value>/shopping/config/transfer/Transfer.xml</value></constructor-arg>
 <constructor-arg name="definitionPath"><value>/shopping/model/data/transfer</value></constructor-arg>
</bean>

この状態でアプリケーションが動くかどうか確認してみよう。
Model-Glue デバッグの2行目に、Using ORM Adapter: com.adobe.hs.common.orm.TransferAdapter とか表示されるだろうか。
なにかエラーのようなものがなければ、OKだ。

いよいよ、Transfer の肝、config/transfer/Transfer.xml 。

<objectDefinitions>
 <package name="master">
  <!-- Category -->
  <object name="Category" table="CATEGORYMST">
   <id name="PKeyCategoryId" type="numeric" column="categoryid" />
   <property name="CategoryName" type="string" column="categoryname" />
   <onetomany name="CategoryItemLink" lazy="true">
    <link to="master.Item" column="lnkcategoryid" />
    <collection type="struct">
     <key property="ItemId" />
    </collection>
   </onetomany>
  </object>
  <!-- Item -->
  <object name="Item" table="ITEMMST" sequence="ITEMMST_itemid_seq">
   <id name="PKeyItemId" type="numeric" column="itemid" generate="false" />
   <property name="ItemName" type="string" column="itemname" />
   <property name="Price" type="numeric" column="price" />
   <manytoone name="ItemCategoryLink" lazy="true">
    <link to="master.Category" column="lnkcategoryid" />
   </manytoone>
  </object>
 </package>
</objectDefinitions>

たぶん、いきなり見ても、わからないだろう。
package は、Transfer 上での意味しかなく、テーブルをグループ化するためのもの。
object は、テーブル。id は、主キーカラム。property は、カラム。
onetomany 、manytoone 、は、他のテーブルとのリレーション設定。
これだけ把握した上で、ざっと眺めれば、なんとかわかってくるだろうか。

Model-Glue3 Gesture

ちょくちょく参考にさせてもらってるなんちゃってCF-OOP!で、Model-Glue の次期バージョンの話が出てた。Model-Glue3(Gesture)αリリース!
なにやら、いろいろと機能が追加されるようだけど、個人的には、Model-Glue3.0の新機能1:イベント自動生成が気になる。
Model-Glue などのフレームワークで一番の(個人的な)不都合は、設定ファイルをXMLで書かなきゃいけないことだと思っている。
そんな不満をある程度解消してくれそうな機能なのではないのだろうか。

例えば、だいぶ前に WebSphere で IBM謹製 Studio を使ったときに、設定ファイルは、入力ボックスに各種設定の文字を入れていくようなウィンドウが表示されて、XMLタグを見ることなく設定できた。
XMLファイルというのは、慣れていればいいのかもしれないが、経験の少ない開発者にとって敷居が高いものだと勝手に断定している。

一番いいのは、部品をドラッグアンドドロップとかで配置して、グラフィカルにMVCの流れが見えることだと思うけど、そんなのはかなり厳しい話で、WebSphere のようなものが妥当な線なんだと思う。

Model-Glue のイベント自動生成機能は、イベント名を起こすだけで、ある程度の設定をしてくれるということだから、ゼロから設定ファイルを書くのではなく、都度変更すればよいわけだ。
ゼロからと、変更するだけでは、大きな違いがあると思うし、かなり敷居が低くなるんじゃないかと思う。

今までのようにXMLを直接編集するしかないとか、(あくまで個人的に)作業効率が悪いままでは、結局フレームワークというものが、万人向けではなく、特定層向けツールで終わってしまっているというのが現状ではないだろうか。
なにしろ、ColdFusion の最大の特徴である、「未経験開発者の一定レベル到達時間が短い」を打ち消しかねない。
ちょっと言い過ぎた気もするけど、一向に ColdFusion のフレームワークの情報が世の中に増えてこないのは、その辺にあるのじゃないだろうか。
Model-Glue の新機能に期待である。

2008年05月08日

Transfer の利用

では、Transfer を利用するように書き換えてみる。

ColdSpring.xml で設定していた、販売商品のマスタデータをデータベースから取得するようにするため、下記のように書き換え。

<bean id="itemArrayBean" class="shopping.model.ItemArrayBean">
 <property name="itemArray">
  <list>
   <map>
    <entry key="name"><value>光学式マウス</value></entry>
    <entry key="price"><value>2600</value></entry>
   </map>
   <map>
    <entry key="name"><value>ボール式マウス</value></entry>
    <entry key="price"><value>1100</value></entry>
   </map>
   <map>
    <entry key="name"><value>レーザー式マウス</value></entry>
    <entry key="price"><value>4800</value></entry>
   </map>
  </list>
 </property>
</bean>

 ↓

<bean id="itemArrayBean" class="shopping.model.ItemArrayBean" autowire="byType" />

マスタデータを設定する必要が無くなるため、ばっさり、削除。
その代わり、AutoWire で Bean を注入。

何を注入するのか。shopping.model.CartProcess に以下のコードを追加する。

<cffunction name="setOrmService" access="public" returntype="void" output="false">
 <cfargument name="ormService" type="transfer.TransferFactory" required="true">
 <cfset variables.transfer = arguments.ormService.getTransfer() />
</cffunction>

前回設定した ormService を渡して取得する Transfer オブジェクトを利用してデータベースからデータを取得するようにするのである。
この ormService は、type を見ればわかるように、transfer.TransferFactory である。

一方、ormAdapter の正体は、ModelGlue.unity.orm.transfer.TransferAdapter で、どうやら、Model-Glue が用意してくれたもののようだ。
いっそのこと、抽象クラスかインターフェースかなんかにキャストして、O-R マッピングで汎用的に使えるようになっていれば、おもしろそうだけど、俺が何か間違っているのだろうか。

shopping.model.ItemArrayBean で Transfer オブジェクトを受け取り、データを取得して、既存の戻り値と同じものを返せば、商品一覧をデータベースから取得して表示するだけなら、書き換えるプログラムは、この ItemArrayBean だけとなる。

2008年05月09日

Transfer がうまく動かない

Transfer の迷宮をさまよい中。
とりあえず、以前書いた

<objectDefinitions>
 <package name="master">
  <!-- Category -->
  <object name="Category" table="CATEGORYMST">
   <id name="CategoryId" type="numeric" column="categoryid" />
   <property name="CategoryName" type="string" column="categoryname" />
   <onetomany name="CategoryItemLink" lazy="true">
    <link to="master.Item" column="CategoryId" />
    <collection type="struct">
      <key property="ItemId" />
    </collection>
   </onetomany>
  </object>
  <!-- Item -->
  <object name="Item" table="ITEMMST" sequence="ITEMMST_itemid_seq">
   <id name="ItemId" type="numeric" column="itemid" generate="false" />
   <property name="ItemName" type="string" column="itemname" />
   <property name="Price" type="numeric" column="price" />
   <manytoone name="ItemCategoryLink" lazy="true">
    <link to="master.Category" column="categoryid" />
   </manytoone>
  </object>
 </package>
</objectDefinitions>

は、だめのようだ。

<objectDefinitions>
 <package name="master">
  <!-- Category -->
  <object name="Category" table="CATEGORYMST">
   <id name="CategoryId" type="numeric" column="categoryid" />
   <property name="CategoryName" type="string" column="categoryname" />
   <onetomany name="CategoryItemLink" lazy="true">
    <link to="master.Item" column="CategoryId" />
    <collection type="struct">
      <key property="ItemId" />
    </collection>
   </onetomany>
  </object>
  <!-- Item -->
  <object name="Item" table="ITEMMST" sequence="ITEMMST_itemid_seq">
   <id name="ItemId" type="numeric" column="itemid" generate="false" />
   <property name="ItemName" type="string" column="itemname" />
   <property name="Price" type="numeric" column="price" />
  </object>
 </package>
</objectDefinitions>

外部参照なわけで、相互に参照するような設定にしてはいけない。
相互に参照しないと、双方から参照できないと思っていたら、そんなことはないようだ。

カートのデータをデータベースに登録するプログラムに変更しようとして、面倒な問題に直面。
カートのデータを全消去というコードがなんとも、面倒だ。

もちろん、従来のO-R マッピングを利用しない書き方に比べて面倒ということではなく、折角の Transfer が意味のないコードになってしまうということだ。
やっぱり、Transfer を意識したテーブル設計をしなければならない。

テーブル CARTDATA をヘッダと明細に分けよう。
さて、引き続き、さまようか。

2008年05月12日

なんとか

なんとか、Transfer の迷宮を抜け出せつつある。もちろん、Transfer のほとんどの機能を把握したという意味ではない。

テーブルを下図のように変更。
table_02.gif

CREATE TABLE public.CARTHEADER (
sessionid VARCHAR(32) NOT NULL
, createdate TIMESTAMP NOT NULL
, updatedate TIMESTAMP NOT NULL
, PRIMARY KEY (sessionid)
);

CREATE TABLE public.CARTDATA (
lnksessionid VARCHAR(32) NOT NULL
, lnkitemid INT NOT NULL
, categoryname TEXT NOT NULL
, itemname TEXT NOT NULL
, price INT NOT NULL
, quantity INT NOT NULL
, PRIMARY KEY (lnksessionid, lnkitemid)
);

ついでに、カートデータとして、各商品の個数を登録できるようにした。

主キーに、固定長の文字列を設定して、バイト長が足りない文字列を入れることは、御法度らしい。
他にも、実際にやってみるとわかる Transfer のクセというか作法もちょこっとずつわかってきた。

サンプルアプリケーション

ColdFusion-Style フォーラムで話題があがっていたけど、アプリケーションフレームワークは色々あるが、DIコンポーネントは ColdSpring 、O-Rマッパーは、Transfer を選択する人が多いのだろうか。
アプリケーションフレームワークは ColdBox が流行なのかな。なにやら、Eclipse のプラグインがあるみたいだし、ちょっと読んでみる必要があるのかな。

目下の悩み事は、CFタグのコードと、cfscriptのコードが入り交じっていることだ。
全部CFタグにしたほうが、統一感があっていいのだけど、各種ドキュメントのサンプルコードが cfscript で書いてあったり、ちょっとだけコーディング量が少なかったりと、cfscript で書いちゃう場所もある。
どちらかに全て統一となると、cfscript に統一ということはできないようだから、やっぱり、CFタグの方がいいのかなぁ。

2008年05月13日

Transfer のトランザクション処理

サンプルアプリケーションは、データベースのトランザクション処理ができていない。
こんなアプリケーションが許されるわけはないので、トランザクションを実装しなければならない。
トランザクションはどのように実装するのか。

やり方としては、コンポーネント内の指定した関数を丸ごとトランザクション処理するというイメージになる。
shopping.model.CartProcess の transfer.TransferFactory を AutoWire したタイミングで、transfer.TransferFactory から transfer.com.sql.transaction.Transaction を取得する。

<cffunction name="setOrmService" access="public" returntype="void" output="false">
 <cfargument name="ormService" type="transfer.TransferFactory" required="true">
 <cfset variables.transfer = arguments.ormService.getTransfer() />
 <cfset variables.transaction = arguments.ormService.getTransaction() />
</cffunction>

その Transaction を利用して、

 <cfset transaction.execute(component, methodName, [arguments]) />

と、直接的に関数をトランザクション指定で起動することもできる。
直接指定の場合は、その関数を利用するときに、上記の記述で利用することになる。

また、AOPのように記述して、関数を指定することで、指定した関数が丸ごとトランザクション処理されるようだ。
この記述の場合は、事前に行っておくことで、その関数を通常のように利用した場合でも、トランザクション処理されることになる。

<cffunction name="setOrmService" access="public" returntype="void" output="false">
 <cfargument name="ormService" type="transfer.TransferFactory" required="true">
 <cfset variables.transfer = arguments.ormService.getTransfer() />
 <cfset variables.transaction = arguments.ormService.getTransaction() />
 <cfset variables.transaction.advise(this, insertItem) />
</cffunction>

さらに、

 <cfset arguments.transaction.advise(this, "^save") />

と、正規表現で一括してトランザクション処理指定もできる。
トランザクションで処理したい関数を save で始まる関数名にしておけば、簡単に一括指定できる。

2008年05月14日

ColdBox やってみた

ColdBox を動かしてみよう。

もう、こんなの

や、こんなの

が表示されるだけで、「おぉ」と思ってしまうのは、よくない傾向だ。
我ながら、つくづく、見た目に騙されやすい。と思う。実際に役に立つ情報が表示されているのかどうかは、謎。

ColdBox 公式から、ダウンロードしてきて、解凍したファイルを WEBROOT に配置。
その中の ApplicationTemplate をコピーして、このディレクトリの名前を適当に変える。

とりあえず、これだけで、先ほどのような画面が表示されるようになる。

ここにあった Eclipse のプラグインのインストールができなかった。
バージョンが europa ではだめなのか、はたまた、Eclipse に色々つっこみすぎているのがいけないのか。

なんだか、ドキュメントの項目だけを見ても、機能がいっぱいあるように見える。
個人的には、Model-Glue のようにシンプル設計がいいと思うのだけど、実際のところは、どうなのか。

Model-Glue で作っていたサンプルアプリケーションを移植してみようとしたら、文字化けした・・・。
character_error.gif

2008年05月15日

Ant に注意

前回の文字化けは、ColdBox 上の問題ではなく、Ant 上の問題だった。
やはり、慣れないものを使うときは、慎重にしないといけないということか。

ColdBox のパッケージに含まれる ApplicationTemplate に入っている build.xml を使うときは、

<filterchain>
 <concatfilter prepend="header.txt"/>
</filterchain>

を削除するなり、コメントアウトするなりしよう。

Ant のコピーコマンドは、通常そのままファイルをコピーするのだけど、filter 設定があると、ファイルを開くわけで、その際に、デフォルトではOSデフォルトエンコーディングでファイルを開く。
ファイルが異なるエンコーディングで保存してある場合、問題があるわけで、その結果、ファイルを保存することになると、文字化けする。copy コマンドに encoding 属性を付けるという手もある。

また、上記の Ant 設定は、全てのファイルの先頭に、header.txt の内容を挿入するという内容らしい。
その header.txt も、Ant が都度書き出していて、内容は、CFML のコメントになっている。
CFML のファイルだけなら、いいのだが、外部スタイルシートファイルや、JavaScript ファイルにも入れてしまって、結果、エラーが発生する。

こんなことで、半日以上費やしてしまった・・・。

2008年05月16日

Model-Glue から ColdBox への移植

なんとか、Model-Glue 版ショッピングカートを ColdBox 版ショッピングカートに移植完了。
でも、View 周りがなんとなく、汚い気がする。

基本的には、両者とも、MVCフレームワークなわけで、「とりあえず作ってみました」的なレベルでは、大して差はなかった。

Controller に当たる handler で、設定することなく(Model-Glue は、設定することなく、setter 関数を入れるだけ) AutoWire はしてくれなかったので、handler 上の init 関数などで以下のように、取得する必要がある。

<cffunction name="init" access="public" returntype="any" output="false">
 <cfargument name="controller" type="any">
 <cfset super.init(arguments.controller)>
 <cfset variables.shopping = getPlugin("ioc").getIoCFactory().getBean("shopping") />
 <cfset variables.itemArrayBean = getPlugin("ioc").getIoCFactory().getBean("itemArrayBean") />
 <cfreturn this>
</cffunction>

こうしておけば、handler が初めてよびだされるときに、ColdSpring で設定された Bean を呼び出してくれるのであろう。

また、Model-Glue では、XMLファイルで処理のフローを設定していたものが、ColdBox では、上記の handler 内でほとんど行うようだ。
ApplicationRoot
 ┗handlers
  ┗gengeral.cfc
gengeral.cfc という handler があって、その中に書かれている関数がイベント名になる。
例えば、gengeral.cfc に、CartView という関数があるとすると、gengeral.CartView というイベントを駆動させると、その CartVew 関数が処理される。

あとは、TransferFactory など、AutoWire 関連の記述を書き換えるぐらいでモデルなどのコードは、ほとんど変更しなかった。この辺りは、さすがである。
当然、画面表示周りの部分は、それなりに書き換える必要がある。イベント名の作法が変わるわけだし、画面表示自体の作法が変わる。

個人的な問題として気になることがあった。
開発する際、WEBサーバー(Windows マシンで、IIS)のドキュメントルートにプログラムを置くのではなく、リポジトリとして決めてある場所にプログラムを保存して、実行は、IIS 上で仮想ディレクトリを設定してある。
プログラムを変更した場合、保存後、すぐに、ブラウザのF5リフレッシュで変更結果を確認している。

ColdBox でそのように作成しようとしたら、なぜか、エラーが発生してしまった。設定があるのかもしれないが、わからなかったので、結局、Ant を使って、WEBサーバーのドキュメントルートに配置していたわけで、結果、前回のようなエラーにも遭遇した。
ColdBox のイメージがちょっぴり悪くなってしまった。もちろん、ColdBox は悪くないのだろう。あくまで、個人的な問題だ。

2008年05月17日

EMONSTER

とうとう買ってしまった。
イー・モバイル EMONSTER S11HT
F1000001.JPG
携帯で撮ると、画質悪いんだなぁ。
これまでは、DELL Axim X3i という4年ぐらい前に出たPDAを使っていた。
PDAと言っても、スケジュール管理とかじゃなく、もっぱら、テレビを録画したものを電車で見たり、音楽、ラジオ講座を録音したものを聞いていた。
Axim から EMONSTER になって、「何か違うのか?」と聞かれれば、「何も変わらない」というのが正直な答えだけど、そんなことは、関係ない。
もちろん、機能としては、QWERTYキーボードや、GPSなど、新しいなりに変わっているけど、やることは、結局変わらない。
でもいいのだ。楽しめれば。この辺りは、こういうガジェットが好きな人にしかわかってもらえないだろう。
PocketPC 2003 から Windows Mobile 6 ということで、いろいろと変わってるようだし、とりあえず、環境作るところからはじめなければ。

2008年05月19日

ColdBox の CFEclipse 用便利小物

折角なので、もうちょっと ColdBox をやってみる。

ColdBox は、Eclipse(CFEclipse)で開発することを意識しているようで、いろいろと便利小物を用意してくれている。

以前、インストールに失敗したプラグインが、改めてインストールしたら、あっさり完了した。
これは、ヘルプファイルのようで、
help.gif
Eclipse 上でヘルプを参照できる。

また、WEBのルートにインストールした coldbox ディレクトリにある install ディレクトリ内に cfeclipse_dictionary と cfeclipse_snippets がある。
dictionary の方が、コード補完用のファイルで、snippets の用が、スニペット用のファイルとなっている。
コード補完は、あるのとないのでは、全然違ってくるので、ありがたい。
Eclipse のインストールディレクトリにある Plugins / org.cfeclipse.cfml_1.3.1.6 / dictionary に
dictionaryinstall.gif
とコピーして、その場所にある dictionaryconfig.xml を
dictionaryssetting.gif
と変更する。そうすれば、
autosuggest.gif
のようにコード補完してくれる。しかし、cfscript 内の場合は、してくれなかった。
autosuggest2.gif
なにか、間違っているか、設定があるのか、「そんなのは、自分で加工しろよ!」なのか。
snippets については、ちょっとした発見(自分が知らなかっただけだけど)があって長くなりそうなので、また、後日。

CorePlayer ベンチ

所有しているガジェットで CorePlayer のベンチマークをやってみた。
それぞれ、一番結果のいい設定と思われる状態で計測。
テストデータは、PC-MV9H/U2 で録画した、QVGA H.264 Baseline Level 1.3 可変ビットレート 758Kbps の映画。
普段、この状態のテレビ録画データを Axim X3i を用いて通勤時の電車の中で見ている。
画質とかにはこだわりがない方だと思うが、この状態の動画は、「きれいだよなぁ」と思いながら見ている。

Sigmarion3
詳細設定 / ビデオ / ビデオ出力 ATI IMAGEON
平均速度 136.90%

Axim X3i
詳細設定 / ビデオ / ビデオ出力 Intel XScale
平均速度 100.45%

S11HT
詳細設定 / ビデオ / ビデオ出力 QTv Display
詳細設定 / QTv Display / "TyTNII" driver mode ON
平均速度 100.46%

Sigmarion3 ってすごいな。
S11HTは、動画がしょぼいと言われているみたいだけど、現状の Axim と互角だったので、運用上は問題はない。
平均で 100% というのは、いっぱいいっぱいのフル回転ということか。
しかし、Sigmarion3 は、別としても4年前の Axim と互角というのは、やっぱりしょぼいんだな。

2008年05月20日

ColdBox の CFEclipse 用便利小物2

CFEclipse にある、snippets という機能。
昔々の ColdFusion Studio という開発環境からあった機能だ。Dreamweaver にもあったかなぁ。

さて、ColdBox 用 snippets のインストール。
Eclipse のワークスペースにある .metadata / .plugins / org.cfeclipse.cfml / snippets に cfeclipse_snippets の coldbox ディレクトリを入れる。
snippetsinstall.gif
いままで入れたことがなければ、keyCombos.properties というファイルがあるだけだろうか。
ちょっと自前 snippets を入れてあるので、いろいろ入っているけど、こんな感じ。
再起動して、ちゃんと Eclipse が認識すれば、こうなる。
snippets.gif

次に、cfeclipse_snippets にある、keyCombos.properties で、既存の keyCombos.properties を上書きするのではなく、内容をコピーする。
このファイルの存在というか機能を、今回初めて知ったぐらいなので、空だったから、上書きしても問題なさそうだった。
さて、この keyCombos.properties とは、なんだろうか。
実は、なかなかの優れものだった。今回初めて知ってかなり驚いた。
keycombos1.gif
例えば、switch と入力した状態で、Ctrl + J とキーをたたくと、
このようなダイアログが表示される。
keycombos2.gif
ここで入力して OK ボタンを押すと、
keycombos3.gif
こんな風になるのだ。思わず「おぉ」と声が出てしまった。
snippets とは、本来こういうものだったことを知らなかった。
しかし、この機能が使えない単語で Ctrl + J を押すと、
keycombos_error.gif
こういうダイアログが出てしまうのは、どうしたものか。

で、Snippets で ColdBox に関するコードが出てくるというわけで、なかなか便利そうである。
ほしいものがなければ、自分で作れということでもある。
これは、ColdBox ネタというより、CFEclipse ネタか。

2008年05月21日

Model-Glue のコード補完

Model-Glue の Eclipse 用のコード補完設定ファイルを作ってみた。
modelglue.xml
インストールの仕方は、以前のエントリを参照。

また、関数へのマウスオーバーでポップアップするヘルプを公式ドキュメントから抜き出して日本語訳してみたが、間違いもあるだろう。
仕様として、同じ関数名があると後に定義されたヘルプが出てしまうようなので、同じ関数名は、属するオブジェクトを連ねて表示し、両対応の当たり障りのない(中途半端な)ヘルプ文章にした。

以下、ちょっと用語解説。

続きを読む "Model-Glue のコード補完" »

2008年05月22日

Scaffold

まず、前回の modelglue.xml をちょっと更新した。
ファイル modelglue-02.xml 。念のためファイル名は変えておいた。コード補完部分は変わっていない。

では、今回の本題。Scaffold という機能もなかなか便利。
サンプルアプリケーションでいうと、Transfer.xml に記述してあるオブジェクトを指定して Scaffold を設定すると、そのオブジェクトのデータ管理ができる機能が自動で生成される。
以下のように ModelGlue.xml に一行付け加えるだけで、その機能ができてしまうのである。

<event-handlers>
 ……
 <scaffold object="master.Item" />
</event-handlers>

で、http://localhost/shopping/index.cfm?event=master.Item.list にアクセスすると、そのテーブル内のデータが表示できる。

続きを読む "Scaffold" »

S11HT の液晶保護シート

こともあろうに、買ったときにおまけで付いてきた液晶保護シートが、S11HT 用と書いてありながら、サイズが違って、横が足りない、縦が余るという有様で、さっそくアマゾンで注文。

基本的に、つるつるてかてかの液晶がきらいだから、この brilliant より、この plus の方が好きだ。
巷では、brilliant の方が人気らしいが、どうにも、写り込みが気になるのだ。

続きを読む "S11HT の液晶保護シート" »

2008年05月23日

Scaffold のカスタマイズ

Scaffold には、用意されたデザインではなく、自由にデザインを変更できる機能がある。
これを使えば、もしかすると、本番システムにおいても利用できる機能なのかもしれない。

続きを読む "Scaffold のカスタマイズ" »

2008年05月26日

Model-Glue の初期設定

ここらで、基本的なところに戻って、ColdSpring.xml の先頭にある、
<bean id="modelGlueConfiguration" class="ModelGlue.unity.framework.ModelGlueConfiguration">
を見ていこう。

ここでは、Model-Glue の各種設定項目を、DIコンテナである ColdSprng で設定しているということになる。
設定できる項目は、以下の通り。

続きを読む "Model-Glue の初期設定" »

S11HT の本格稼働

いままで AximX3i でやっていたことを S11HT でやってみた。
変わったことは、この Bluetooth レシーバーを使い始めたこと。
で、本格稼働してみて感じたこと。

続きを読む "S11HT の本格稼働" »

2008年05月27日

XMLの設定ファイルの豆知識

ところでいくつかあるXMLの設定ファイルで、どうするのかなぁと感じていたことがある。
特定のディレクトリを絶対パスで指定したい場合に、配置するサーバーの状態によっては、ディレクトリ名を変えないといけないこともあるだろう。そうしたときに、XML内の該当箇所を全て置き換えていかないといけないのかなぁ。とちょっと不便に思っていた。

ところが、ここのソースを見て解決した。
要は、ColdFusion レベルの手法ではなく、XMLレベルの手法で解決すればいいのだ。

続きを読む "XMLの設定ファイルの豆知識" »

2008年05月28日

TransferDecorator

Transfer の機能にある、decorator とはなんだろうか。
どこかで聞いたような気がしたんだけど、オブジェクト指向に出てくるデコレータパターンかな。
オブジェクトの振る舞いを自由に変更できるということか。

例のごとく、ドキュメントを読んでも、さっぱりわからない。
悪戦苦闘の結果に導き出した答えが、「Transfer のオブジェクトの振る舞いを変更するための仕組み」。
Transfer のオブジェクトは、Transfer.xml の object タグの情報を元に、自動で生成される。Transfer.xml で設定できること以外は、そのオブジェクトに対しては、ブラックボックス状態だ。
そこで、この transfer.com.TransferDecorator の出番となる。

続きを読む "TransferDecorator" »

S11HT 動画を快適に見たい!

どうにも、カクカクなので、ちょっとビットレートを下げてみた。
結局のところ、CorePlayer のベンチマークは、どれぐらいになれば快適なのかわからないので、実際に見て判断しよう。
可変ビットレートなので、はっきりとはわからないけど、平均 500kbps では、画質がわずかに落ちる程度で、だいぶ滑らかになった。でもまだ若干カクカク。
こうなれば、えいっ!と、平均 384kbps にしてみた。
ちなみに、エンコーダーの設定で下限側を 300kbps より下げられなかった。
これぐらいだと、ほどほどの画質になるけど、ほとんど、カクカクしなかった。
やっぱり、こんなもんなのか。まだまだ、いろんな動画で確かめなきゃ。
そういえば、今日は、CorePlayer でCMのときに前送りしてたら、暴走した・・・。

2008年05月29日

Transfer の clone 機能

Transfer は、clone 関数が用意されている。文字通り、オブジェクトの複製ができる。
get で取得した Transfer のオブジェクトを clone するだけだ。

 user = getTransfer().get("user.User", 1);
 cloneUser = user.clone();

どんなときに使うのだろうか。

続きを読む "Transfer の clone 機能" »

About 2008年05月

2008年05月にブログ「気楽に行こう」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2008年04月です。

次のアーカイブは2008年06月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。