<< 2006/03/02 | Home | 2006/03/04 >>
PR: 転職    転職    合宿免許    漫画    シルバー    ブライダルエステ    墓地・霊園    葬式   

jaxbでちょっと遊び。

servletでprintln(HTML)もイヤだけど、JSPの「"」と「'」のネスト合戦や、EL式やJSTLをこねくりまわすのもイヤ。

んで、ここにxhtml 1.0のdtdが落ちているので、こいつをjaxbに喰わせてやったら全部オブジェクトモデルでxhtmlを表現できるなぁと。

jaxbのxjcに-dtdオプション付けて読ませようとしたら、xhtmlの属性名にclassがあって、これがJavaのclassとぶつかるので、エラー出て変換できない。xsdならbindingルールを指定できるのだけど、dtdではどうもできないっぽい。サクっとあきらめて、trangでdtdからxsdに変換。これに以下のbindingルールを付けてxjcでクラス群に変換。

<jxb:bindings version="1.0"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings schemaLocation="DTD/xhtml1-strict.xsd" node="/xs:schema">
    <jxb:bindings node="//xs:element[@name='block']">
      <jxb:class name="SmallBlock"/>
      <jxb:property name="SmallBlock"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:element[@name='inline']">
      <jxb:class name="SmallInline"/>
      <jxb:property name="SmallInline"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:element[@name='map']//xs:attribute[@name='class']">
      <jxb:property name="class1"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:attributeGroup[@name='coreattrs']//xs:attribute[@name='class']">
      <jxb:property name="class2"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:attributeGroup[@name='i18n']/xs:attribute[@name='lang']">
      <jxb:property name="langCode"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:element[@name='bdo']//xs:attribute[@name='lang']">
      <jxb:property name="langCode"/>
    </jxb:bindings>

    <jxb:bindings node="//xs:group[@name='head.misc']//xs:choice">
      <jxb:class name="HeadMisc"/>
      <jxb:property name="HeadMisc"/>
    </jxb:bindings>
  </jxb:bindings>
</jxb:bindings>

JavaDoc出してみたら、10分もかかったよ。ドキドキしながらオブジェクトモデルでxhtmlを書いてみる。こんな感じになる。

        Html html = objFactory.createHtml();

        Head head = objFactory.createHead();
        html.setHead(head);

        Title title = objFactory.createTitle();
        head.getContent().add(title);

        title.getContent().add("Hello!");

        Body body = objFactory.createBody();
        html.setBody(body);
 
        final Br BR = objFactory.createBr();
        P p = objFactory.createP();
        body.getBlockOrFormOrMisc().add(p);

        p.getContent().add("Hello");
        p.getContent().add(BR);
        p.getContent().add("World");

これをjaxbのマーシャラに喰わせれば、xhtmlが出力される。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes"?>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Hello!</title>
    </head>
    <body>
        <p>Hello
            <br/>World</p>
    </body>
</html>

傍から見たら、やっぱり狂気だろうか。でも個人的には気に入ってしまった。だってコンパイル段階でかなり静的なチェックできるしマーシャラがある程度の構造のバリデーションしてくれるし、不等号とか&とかエスケープしなくていいし、タグの閉じ忘れとか起こり得ないし、ループとか条件分岐は楽勝だし、テストはオブジェクトモデル段階でassertすればokだし。OOがフル活用できるからデザイン統一とかも楽勝な気がするし、自分のページ全部書き直してみようかな。

SLF4JとNLF4J

久しぶりに、Commons-Loggingを見に行ったら、1.1が出たように見えるんだけど、downloadsに行くと1.0.4しかない。1.0.5はcancelされてるし。

と思ったら、log4jの作者はSLF4JNLF4Jに移行しているようだ。そういえば、これってこの辺で見た記憶があるんだけど、この解説記事だと単に新しい選択肢が出来ただけ? としか見えなくて、そのまま通り過ぎていた。

でも、これらは遥かに重要な意味を持っていることが分かった。基本的にはCommons-Loggingとlog4jは近い将来、obsoleteになりそうだ。新しいロギングAPIが必要になった理由は、Ceki自身がここで解説していて、クラスローダまわりのややこしい仕様のために、Commons-Loggingがいろいろといやらしい問題を引き起こす例が、詳細に述べられている。

自分でこれから作るクラスは、SLF4Jを使うとしても、色々なオープンソースを組み合わせて使うケースでは、Commons-Loggingを使っているコンポーネントだって使わなきゃならない。その場合は、jcl104-over-slf4j.jarを使って段階的に乗り換える方法があるようだ。

このサイトの掲載内容は私自身の見解であり、必ずしもIBMの立場、戦略、意見を代表するものではありません。
日本アイ・ビー・エム 花井 志生 Since 1997.6.8