Archives

You are currently viewing archive for July 2006

[Java] 26 July 2006

[Groovy]馬鹿丸出しな利用法

昔の連絡先をメモするのが不便なこともあって、携帯から抽出しておいたVCF(VCARD形式)ファイルを見つけた・・・・。
が・・・、はっきり言ってアレは人間の読むものじゃないのでGroovyで名前と電話、メアドだけパース
そのときの馬鹿丸出しのScript。

vcfFile = new File(args[0])
fnPattern = ~"FN\\:(.*)"
telPattern = ~"TEL.*\\:(.*)"
mailPattern = ~"EMAIL.*\\:(.*)"
vcfFile.eachLine
{
printMatcher(fnPattern.matcher(it))
printMatcher(telPattern.matcher(it))
printMatcher(mailPattern.matcher(it))
}

def printMatcher(matcher){
if(matcher.matches()){
println matcher.group(1)
}
}

[@上海] 20 July 2006

つるつる

くるくるが不快なので、つるつるにした。
↑いつもと一緒じゃん・・・w
30元だった。

[@上海] 16 July 2006

くるくる・・・orz

床屋でバックを取られた・・・・。
疲れてたのと面倒なのとで「好的、好的。」言ってました。
したらば、気がつくと髪の毛を「くるくる」してやがります。
あれよあれよという間に頼んでもいないパーマ液がかけられ、パーマ頭にされました。コッチの床屋さんは油断すると色々オプションを勧めてきます。
*注意してください、床屋だからこれですんでます。中国において、デフォルト値は「不要。」が望ましいです。

て、今週半ばですが10ヶ月ぶりに日本へ帰ります。
そんなわけで、会社の上司(っていうか老板w)にお客さんと一緒に連れて行ってもらった茶館(中山路×玉屏南路)に行ってきました。買ったお茶は高山烏龍茶、茉莉花茶(ジャスミン茶)です。
ここはビル一つがまるまるお茶関連の店で成り立っているところで、10平米前後の店がたくさん軒を連ねています。

cha
まずは以前高山烏龍茶を購入した店に行きました。店番のお兄ちゃんと色々話しながら1時間ほど何種類かのお茶を飲んだあと気に入った物を買いました。
前回聞いた話だと、何でもこの店は福建省に自前の茶畑を持っているらしく、売っているのもそこの茶葉だそうで、出してくれた新茶も非常に甘い香りがしとても美味しいです。

価格的には、良い方のお茶が一斤(500g)400元、普通のお茶が一斤200元でした。ひょっとしたら少し高いかもしれませんが、土産物ということで値切らずに買いました。面倒な小分けもしてくれましたし、おまけもつけてくれました。

cha2
2件目では、見て楽しい花が開くジャスミン茶を買いました。これは香りはそんなに良くないですが、ともかく見ていて綺麗なのでお土産として喜ばれます。
ここでも、何種類かお茶(苦丁茶と言う超苦い茶も・・・)を飲みながら、おばちゃんと小一時間ほど話しました。あとバナナもくれましたw


価格的には、20個で60元払いました。だから、1個あたり3元ですね。

久しぶりの日本なので超ドキドキしてます。
日本で会う約束をしている方も何人かいらっしゃるので楽しみです。
では、ごきげんよう

[@上海] 12 July 2006

女性に人気の都市上海

中国の一般消費者の「住みたい家の形」
http://www.nikkeibp.co.jp/style/biz/china/market/060712_sumai/index.html

いや、やはり上海は人気なのですな。
意外なのは北京、上海と競って大連が上位に来ているところ、風光明媚で空気も綺麗と評判なので一度は行ってみたいです。日本人とのゆかりも深く、日本人も非常に多いと聞きますしね。

laofangzi
上海の不動産の高騰具合というのは皆さんも聞いたことはあるかと思いますが、中国人の住居に対するこだわりも半端じゃありません。
なにせ、家を持っていない男は結婚すらできないという有様です。もう家を持っていない男なんか結婚対象としては箸にも棒にもかからないワ!みたいな?w
実際、私の居る会社でも私よりずっと若い子が既に家を持っています!
↑信じられますか?20代前半で家を持っていたりローンを組んだり!
*写真は华上路交差点のアパートメント、超クールです。


かつて日本人も、高度経済成長期において数十年のローンを組み、立派なローンソルジャーとして勤め上げゴールという風潮がありました。←べつに悪い意味ではないですよ。
ところが、こちらではそんな次元を超えているように感じます。いやしくも男なら、家を買い居を構えてようやく一人前である!みたいな感じが・・・・w
信じられますか?ホワイトカラーの平均月収6000元前後の中で100万元を超える物件を買うのですよ?平均年収の10倍を超える家を買うわけです。
*まあ、貧富の差が超激しいので平均月収なる統計にどこまで意味があるのかはさておいて

いやもうホントにびっくりです。

[Java] 10 July 2006

[Groovy&Velocity]最初の成果物0.0.1

とりあえず最初の成果物0.0.1を公開したく思います。
突貫なので簡単な作りでアレなんですが、興味ある人は、是非いじってみてください。
http://www.makino-style.org/ura/index.php?hymall%2F0.0.1

うまくいかない場合、コメントに質問書いてください。可能な限り返答します。
あと、もし面白いと感じてくれる人がいたら手伝ってください。まじめに作りますw

[徒然] 10 July 2006

予期せぬ実行時例外への日本の対応、どうよ?

いま、世間は予期せぬ実行時例外がスローされてきた事で大騒ぎとなっておりますが、ここは一つ感情論に流されず考えてみましょう。

現在アンポリにて日本主導で進められているせーさい決議案だけれど、これは考え得る対応策の中で最も安易で愚かな対応かと思います。

別にアッチ(例外の発生元)とかコッチ(地元)の肩を持つわけではないです。しかし、せーさい決議案を出したところで状況の打開は見込めないと思うのです。たぶん、私も含めて大部分はせーさい決議案が出されれば
「どうだ、それ見たことか!俺をなめんなよ。」
という気持ちは満たされるでしょう。しかしながら、それではその後のゴールが見えないわけです。
誰がどう考えたって、この状況でアッチの人たちが
「ごめんなさい。僕たち反省しました。二度としません。」
と言うはずがないでしょうw

» 続きを読む

[Java] 09 July 2006

GroovyがVelocityを引っ張るのです。その3

S2を取り込んで見ました。
現状でBindingの生成にS2を利用してます。
良くある区分値テーブルとかの情報一覧を表示する場合のコード例
Sample.gdo
  import groovy.sql.Sql
  list = new ArrayList()
  sql = new Sql(dataSource)
  sql.eachRow("select * from sys_param") { row |
    kbnData = new KbnData()
    kbnData.name_j=row.name_j
    kbnData.kbn=row.kbn
    kbnData.kbn_id=row.kbn_id
    list.add(kbnData)
  }
  if(list.size()>0){
    request.setAttribute("list",list)
  }
  class KbnData{
    @Property name_j,kbn_id,kbn
  }
Sample.htm
  <html>
  <body>
  #if($!list)
    <table>
      <tr>
        <td>kbn_id</td>
        <td>kbn</td>
        <td>name_j</td>
      </tr>
  #foreach($data in $list)
      <tr>
        <td>$data.kbn_id</td>
        <td>$data.kbn</td>
        <td>$data.name_j</td>
      </tr>
  #end
    </table>
  #else
    <h1>結果は0件</h1>
  #end
  </body>
  </html>

#S2の手軽さに感動しました。

[Java] 09 July 2006

Dispatchしたときの・・・・(原因解明編)

きっとGroovy本家の人やコアな人は既に把握していて既出かもしれないのだが・・・・

ある程度原因が判明、状況から判断すると、結局スクリプト実行時にダイナミックにCategoryサポートを付加する際に、クラスの型ごとに行なっており、なおかつ実行時MetaClassImplにて関連するMetaMethodをすべて取得しているという動作に由来するようだ。

なぜこのような現象が発生するかというと、結局Servletコンテナの実装のため、もしくはGroovyの実装のためとしか言いようがない。

現象に照らし合わせて、状況を整理してみる。
1,スクリプトAでrequestのsetを実行しスクリプトBへDispatchする。
2,スクリプトBでrequestのsetを実行する。
そうするとGroovyRuntimeExceptionでAmbiguous method overloading for methodと例外が発生。

この時、最初のスクリプトAでバインドされたrequestはorg.apache.catalina.connector.RequestFacadeのインスタンスであり、GroovyCategorySupportのThreadLocalのstackにもRequestFacadeクラスのClassインスタンスをkeyとしてsetのCategoryMethodがキャッシュされる。
(詳しく言えばRequestFacadeがcategorizedClassとされ、さらにCategoryMethodにてHttpServletReqeustを対象としてキャッシュされる。)

ところが、スクリプトBでバインドされたrequestはコンテナによりDispatchされたrequestなのでorg.apache.catalina.core.ApplicationHttpRequest(HttpServletRequestWrapperのサブクラス)となっている。
そのためstackには新たにApplicationHttpRequestをkeyとしてsetのCategoryMethodがキャッシュされる。
(同じくApplicationHttpRequestがcategorizedClassとされ、さらにCategoryMethodにてHttpServletReqeustを対象としてキャッシュされる。)

このためスクリプトBの実行時にはCategoryメソッドの検索で、見事に2つのsetメソッドが存在することになり、結果的にAmbiguous method overloading for methodとなるらしい。

ということで、結局Servlet関連のrequest,session,contextに関連するCategoryサポートは利用できる局面と利用できない局面が混在することになるので、紛らわしいから利用しない方向で実装することに決定。
まあsetAttributeを書くのがそれほど苦痛とも思われないので、問題ないかと・・・

参考:
GroovyCategorySupportのコードを追ってみた。
裏マキノ式:GroovyCategorySupportの分析

[Java] 05 July 2006

DispatchしたときのGroovyCategorySupportの振る舞い

GroovyのスクリプトでServletCategoryを利用して、RequestDispatcherを利用するとrequestとかのsetでこける。

具体的には
1,スクリプトAでrequestのsetを実行しスクリプトBへDispatchする。
2,スクリプトBでrequestのsetを実行する。
そうするとGroovyRuntimeExceptionでAmbiguous method overloading for methodと怒られてしまうのだが、これはおかしいよなー
場所的にはMetaClassImplクラスのchooseMostSpecificParamsにおいてmatchesが1ないしは0以外の時に発生する。つまり簡単に言えば、ServletCategoryで追加しているsetメソッドが重複しているよーって言っているのである。

Groovyのソースコードを追っていると、GroovyCategorySupportにおいてCategoryのキャッシュを保持するためにThreadLocalを利用しているが、ここが超臭う。
private static ThreadLocal local = new ThreadLocal() {
 protected Object initialValue() {
  List stack = new ArrayList();
  stack.add(Collections.EMPTY_MAP);
  return stack;
 }
};
RequestDispatcherを利用しない場合は問題ないのになー。
↑これはTomcatがThreadの使い回しの際にinitialValueで初期化しているからと思われ・・・

オリジナルのGroovletでも同じ現象が発生してる・・・・・orz
そんなに影響はないけどCategory使えないのは利便性の観点から痛いなー

[Java] 03 July 2006

GroovyがVelocityを引っ張るのです。その2

昨日スタバのテラスで汗を流しながら考えたメモ
1.HTMLのモックアップからアプリケーションを作り上げる。
→ これは業務ではなくサイト構築という観点では非常に重要、理想論ではなく現場の現実論としての実装

2.共通のプレロジックの実行をサポート
→ 呼び出されたServletPathから判断して上位ディレクトリから順に規定された名称のGroovyスクリプトをチェーンして実行

3.DIコンテナによるカスタムBindingの生成
→ 既存Java資産の活用やトランザクションの実現が可能

4.Exceptionのハンドリング
→ 細かくは考えていないけど、規定の場所に配置して、ハンドリング後に呼び出し

5.その他
 VelocityのTemplateの実装、VelocityToolsのGroovyによる記述

番外
→ フレームワークの名前はスタバの隣のスーパーの名前(Hymall)にしようかとw

1は非常に重要で、コンシューマ向けのサイトを作り上げるときに見逃してはならない点である。具体的な実装方法としては、GroovyServletの親クラスであるAbstractHttpServletを継承して独自のコントローラを用意している。先頃GroovyのJSR06が出たのでそちらのソースコードを閲覧する必要もあるが、とりあえずJSR05で実装してみた。
大まかな流れとしては下記のようになっている。
①*.htmをハンドリング
②GroovyScriptが存在するなら、ServletPathから対応するGroovyScriptのパスを生成して実行
③Velocity用のHTMが存在するなら、マッピングされていないVelocityViewServletをgetNamedDispatcherにより取得してforward実行
④Groovy、Velocityとも対象ファイルが存在しない場合は404

開発スタイルのイメージとしては、デザイナーなどが作り上げたモックアップを配置して、Groovyのロジックを書き足していくイメージである。
仮にGroovyのロジックが存在しない場合でも、VelocityがHTMを配信するのでモックアップのまま利用すれば画面の流れが寸断されず良い。(*.htmでハンドリングしているため)
例えば下記の場合
/Sample.htm?name=F.Makino&address=Shanghai
既にSample.htmが存在して居るため対応するGroovyScriptであるSample.gdoが存在しなくても表示されるということ

#デプロイなしでシームレスに開発ができるのがこんなに幸せだとは思わなかったヨ...(TーT)

#あと意外にGroovyServletのソースは汚いよw

[Java] 02 July 2006

GroovyがVelocityを引っ張るのです。

ある日、会社の中国人エンジニアがJavaはめんどくさいと言いました。
(結構根に持つタイプ→俺)
悔しいので、高速開発可能な簡易フレームワークというか環境を作ろうと心に決めました。
#目標メモ
http://www.makino-style.org/ura/index.php?AntiPhpProject


やっべー、マジで楽しいよ!グリグリいけるよ。
(今作り中、基本ができたらここでリリース予定w)
GroovyとVelocityServletは相性が良いと思う。サクサク行ける。
デプロイとリロードいらずでラピッドな開発ができるぜ!

Sample.gdo(Groovy側)
name = request.getParameter("name")
address = request.getParameter("address")
if(name!=null&&address!=null){
 info = new PersonalInfo()
 info.name = name
 info.address = address
 request.set("info",info)
}
class PersonalInfo{
 @Property name,address
}

Sample.htm(Velocity側)
<html>
 <body>
  <h1>Sample</h1>
  <h2>
   #if($!info)
    Your name is $info.name!<br>
    Your Address is $info.address
   #end
  </h2>
 </body>
</html>

Groovyへのバインド周りでDIをうまく使えば、面白いかもー
→ URLからkeyを生成して、DIでBindingオブジェクトを生成みたいな?さすれば、通常の方法で作ったDAOとかも容易に利用できるし

------------------
追記:
Spring使おうかS2使おうか迷ってたけど、ThinkITの速度比較見たらS2のほうがかなり速いのと使いやすいことからS2を使うことにする。正直Springの設定はめんどい


[メモ] 01 July 2006

M2でマルチプロジェクトでWARのリソースの指定方法

Maven2でWARを作るときクラスパスではなくWEB-INF以下などにリソースをおくことが良くあるが、そんな際にこんな指定をすることで通常のリソースファイルと同様にリソースのフィルタリングができる。
 <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-war-plugin</artifactId>
   <version>2.0</version>
   <configuration>
  <warSourceDirectory>src/main/webapp</warSourceDirectory>
  <webResources>
   <resource>
    <directory>src/main/webapp</directory>
    <filtering>true</filtering>
     <includes>
      <include>**/velocity.properties</include>
      <include>**/web.xml</include>
     </includes>
    </resource>
   </webResources>
  </configuration>
 </plugin>
ただ、上記の場合一点問題があり、マルチプロジェクトにした際相対パスになってしまい、親プロジェクトのディレクトリをベースにしてしまう。
↑これで1時間はまったorz
なので正しくは、下記のように記述するべき
<warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>
  <webResources>
   <resource>
    <directory>${basedir}/src/main/webapp</directory>
ちなみに、web.xmlとかをUTF-8で記述して日本語混ぜると文字化けしてトラぶる。
↑ひょっとしてリソースフィルタの読み込み書き込みがOSデフォルト?