技術ネタ‎ > ‎

開発日誌

Wicket DataTableのヘッダーにclassを追加する

2009/09/15 2:38 に ユーザー不明 が投稿   [ 2009/09/15 18:53 に かとうまさき さんが更新しました ]

DataTableクラスはお気楽なんだけど、テンプレートがあまりにそっけなくてカラム毎に細かく制御したい時に途方に暮れるよね(僕だけかな?)

twitterで呟いてみた

DataTableで個別のカラム毎に処理を変えたい場合、Component階層から目的のカラムをさがしだしてごゴニョゴニョする感じでいいのかな。

t_yanoさんからreplyが来た。感激!

DataTable作るときにIColumnオブジェクトをaddしていくのだから、独自のIColumnをaddすればいいのではないか。 *P3

それまで僕はICoumnで変更ができるなんて可能性を考えもしなかった。(@秒速)


みてみると下のようなメソッドがAbstractColumnに。

public Component getHeader(String componentId)
{
return new Label(componentId, getDisplayModel());
}

で早速オーバーライド。

@Override
public Component getHeader(String componentId) {
Component header = super.getHeader(componentId);
header.add(new AttributeAppender("class", Model.of("photo"), " "));
return header;
}

結果は thのクラスにはphotoがつかず、spanについたorz。

<th class="first-child nth-child-odd nth-child-1" wicket:id="header">
<span class="photo first-child nth-child-odd only-child nth-child-1 last-child" wicket:id="label">イメージ</span>
</th>

ソースを見てみるとHeadersToolbarというクラスでthを作っている感じ。

WicketTesterで、pathを表示。

searchResultTable:topToolbars:2:toolbar:headers:1:header org.apache.wicket.markup.html.WebMarkupContainer []
searchResultTable:topToolbars:2:toolbar:headers:1:header:label org.apache.wicket.markup.html.basic.Label [イメージ]

という事で

DataTable.get("topToolbars:2:toolbar:headers:1:header").add(
new AttributeAppender("class", Model.of("photo"), " "));

これでTHにclassが追加されました:)
 
2009-09-16 追記
その後、org.apache.wicket.extensions.markup.html.repeater.data.table.HeadersToolBarのソースを見てみると
 
   if (column instanceof IStyledColumn) {
    header.add(new CssAttributeBehavior() {
     private static final long serialVersionUID = 1L;

     @Override
     protected String getCssClass() {
      return ((IStyledColumn<?>) column).getCssClass();
     }
    });
   }
こんなのを見つけました。
げ。そのCssClassをbehaviorを使って追加しているようです。
 
よって、IColumnに次のようなメソッドをつけるのが一番簡単でした;ぐぬぬ。勉強になったからいいや。
     @Override
     public String getCssClass() {
      return super.getCssClass() + " photo";
     }
 
 

WicketのHTML Validationをちょっとまともにしてみるてすと

2009/08/17 4:53 に ユーザー不明 が投稿   [ 2009/09/15 3:12 に かとうまさき さんが更新しました ]

AE/JのEclipseプラグインがアップデートされてからクラウドにdeployする際にporblemsにerrorがあると警告が出るようになりました。
WicketのHTMLを正しく書いているにもかかわらずValidateでエラーが発生します。

これには理由があって、配布、公開されているDTDが適当だからです^^;
 

http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd

<!ENTITY % coreattrs
 "id             ID             #IMPLIED
  class          CDATA          #IMPLIED
  style          %StyleSheet;   #IMPLIED
  title          %Text;         #IMPLIED
  wicket:id      %Text;         #IMPLIED
  wicket:preview %Text;         #IMPLIED"
  >

 
DTDの中にwicket関係の定義はこれしかありません。
coreattsとして、大抵のエレメントにはwicket:idとwicket:previewを書けるよって定義してあるだけです。
 
 
そこでXHTMLのRNGを拡張してみることにしました。
 
まず、WicketBlockを定義します
 
 
 

WicketBlock

  <define name="wicketBlock">
 <zeroOrMore>
   <choice>
  <!-- 
        <element name="wicket:head">
    <ref name="Flow"/>
  </element>
  -->
        <element name="wicket:panel">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:remove">
    <!--
    <oneOrMore>
     <element>
      <anyName/>
      <oneOrMore>
       <attribute>
        <anyName/>
       </attribute>
      </oneOrMore>
     </element>
    </oneOrMore
       -->
    <ref name="coreattrs"/>
    <ref name="Flow"/>
       <zeroOrMore>
     <ref name="li"/>
    </zeroOrMore>
  </element>
        <element name="wicket:body">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:border">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:child">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:container">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:fragment">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:link">
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
        <element name="wicket:message">
    <attribute name="key">
     <ref name="Text"/>
    </attribute>
    <ref name="coreattrs"/>
    <ref name="Flow"/>
  </element>
   </choice>
 </zeroOrMore>
  </define>
 
このwicketBlockをinlineとblockに追加します。
 

blockとinline

  <define name="block">
    <choice>
      <ref name="p"/>
      <ref name="heading"/>
      <ref name="div"/>
      <ref name="lists"/>
      <ref name="blocktext"/>
      <ref name="fieldset"/>
      <ref name="table"/>
      <ref name="wicketBlock"/>
    </choice>
  </define>
 
  <define name="inline">
    <choice>
      <ref name="a"/>
      <ref name="special"/>
      <ref name="fontstyle"/>
      <ref name="phrase"/>
      <ref name="inline.forms"/>
   <ref name="wicketBlock"/>
    </choice>
  </define>

 
 
このスキーマで少しまともになりました。RNGやXSDに対応したエディターで入力補完やvalidateができるようになります。
 
ただし、根本的にコンテキストを無視したスキーマなのでちゃんとしたものを作るのは難しいです。
 
問題点として、例えば
 
  • <wicket:remove>等はどんなコンテキストにおいても良い
  • tag nameの置き換えを行うのでそれに対応したスキーマを書くのは煩雑
    • <div colspan="2" wicket:id="record"> とか書いて <tr colspan="2">に変換されるが、スキーマ的にはdivにcolspanは無い。
 
validateを通すだけならanyName + excludeを使ったりすれば可能だけど負けた気になります…。
 
自分で使う範囲で適当に拡張するしかないみたいです。
 
 2009/09/15 追記

div/spanの代わりにwicket:containerを使うと少しはスキーマに沿った記述ができそうだ。
 

AppEngineからYahoo!の日本語形態素解析APIを実行する

2009/08/16 20:29 に Shinichi Ogawa が投稿   [ 2009/08/16 21:36 に かとうまさき さんが更新しました ]

ちょっと試すだけなら簡単でした。以前は結構遅くて、AppEngineのURLFetchServiceのレスポンス制限に引っかかるなーとか思ってましたが、さっきなにげに試してみたところ特に問題のない速度でレスポンスされてました。以前試したときのタイミングが悪かったか、Postメソッドを使ってたか、そんなくらいしか差がないんだけどなぁ。
試すには上記URLからYahooアカウントの登録と、アプリケーションIDの登録が必要です。既にどちらもある人は以下のURLでアプリケーションIDを確認できます。
サンプルは単純にGETメソッドでAPIを実行しています。

StringBuilder b = new StringBuilder();

b.append("appid=" + URLEncoder.encode(appId, "utf-8"));

b.append("&sentence=" + URLEncoder.encode(text, "utf-8"));

b.append("&results=ma,uniq");

URLFetchService service = URLFetchServiceFactory.getURLFetchService();

HTTPResponse response = service.fetch(new HTTPRequest(new URL(APIURL + "?" + b.toString())));


これで、後はHTTPResponse#getContent()でbyte配列を取得する事ができます。

Hudsonのプラグインのインストール

2009/08/12 18:36 に Shinichi Ogawa が投稿   [ 2009/08/12 19:06 に かとうまさき さんが更新しました ]

1年ぶりくらいに新しいHudson(1.319だった)を触ってみると、プラグインがWeb経由でインストールできそうな雰囲気。これは便利だなぁ、と思うも、いざ試してみると

プラグインのインストール/アップグレード
インストールが完了したら、Hudsonを再起動して更新を有効にしてください。
準備
  • インターネットとの接続をチェックします。
  • java.netとの接続をチェックします。
  • 成功
Cobertura Plugin 保留

というカンジにプラグインのステータスはいつまで待っても保留のまま。やっぱり昔と同じくインストール自体は手動アップロード、という理解でいいのかなぁ?このまま再起動ボタンで再起動しても「インストール済み」には反映されていないし…。コンテナにTomcatを使用している事が問題なのかな?

キムチーさんの愚痴

2009/08/12 18:14 に ユーザー不明 が投稿   [ 2009/08/12 18:22 に かとうまさき さんが更新しました ]

現在、検索部分の開発をしております。
AppEngine JDOでは、通常のlike検索ができないので、キムチーさんが作っているcompassをいれて全文検索を行っています。

色々なkind(テーブル)から検索用のkindにデータをtriggerのような仕組みを使って投入する部分を作っています。
 
JDO的にはInstanceLifeCycleListenerを使ってインサートやアップデート、デリートをHookできます。
開発時にはインターフェイスの階層をeclipseで見て、すでに実装されている物があればそれを参考にします。
実際にListenerの階層を見てみると、下のようになっています。
 
 
 
 
CompassではJDOのEntityの生成、消滅をHookしてインデックスを作っているのですね。
実際に中を見てみると、CreateLifecycleListenerがコメントアウトされてStoreLifeCycleLinstenerがimplementされてます。
 
実装仕様が変わったのか?
コメントを見るとちょっと愚痴っぽくて面白いです:)
 

JdoGpsInstanceLifecycleListener

    // we don't implement CreateLifecycleListener since no id is set in this case , and store is called anyhow
    private class JdoGpsInstanceLifecycleListener implements DeleteLifecycleListener, StoreLifecycleListener/*, CreateLifecycleListener*/ {

 

1-5 of 5

Comments