• Type: Improvement
    • Resolution: Fixed
    • Priority: Major
    • 2.4.24
    • Affects Version/s: 2.4.23
    • Component/s: S2Container
    • None
    • Environment:
      Windows Vista
      JDK1.5.0_14

      提案
      javaではimport句を使えば、いちいち「パッケージ名.クラス名」ではなく、ショット・クラス名のみで引用できます。

      しかしdiconファイルを記述する時、componentのclass属性またはOGNL式の中にjava.langパッケージ以外はすべてフル・クラス名で記入しなければなりません。場合によって開発者に大きな負担になりかねません。javaのimport句のように明示的にパッケージとクラスのインポート機能をS2Containerに追加することを提案いたします。

      実現方法の説明
      S2Containerのソースを分析した結果、インポート機能は実現できて社内プロジェクトに適用されています。S2Containerが提供する公開APIだけではきれいに実装できないところがありますので、できればS2Containerの公式サポートを強く望んでおります。

      宣言及び引用方法
      XMLドキュメントのprocessing instructionを利用します。記述例:

       <?xml version="1.0" encoding="UTF-8" ?>
       <?java-import
                java.util.*;
                com.mydomain.commons.*;
                com.mydomain.util.DebugUtil;
        ?>
       <components>
            <component name="foo" class="DebugUtil">
                 <property name="map">
                       #@TreeMap@{"key1" : "value1", "key2" : "value2"}
                 </property>
            </component>
       </components>
      

      実装クラス

      • EnhancedXmlS2ContainerBuilder extends XmlS2ContainerBuilder
        • <?java-import ?>を認識できる拡張コンテナー・ビルダー
        • 以下EnhancedSaxHandlerParserおよびSmartComponentTagHandlerを引用します
      • EnhancedSaxHandlerParser
        • XMLパーサ、org.seasar.framework.xml.SaxHandlerParserはfinalクラスのため、新規用意
        • 以下EnhancedSaxHandlerを引用います
      • EnhancedSaxHandler extends DefaultHandler
        • <?java-import ?>を解析するハンドラ
        • 解析結果はClassImporterのインスタンスにいれます
      • SmartComponentTagHandler extends ComponentTagHandler
        • componentのclass属性をショット・クラス名を認識できるタグ・ハンドラ
        • ショット・クラス名の解決はClassImporterに委託します
      • ClassImporter
        • インポートしたパッケージ及びクラスのリストを管理します
        • ショット・クラス名をインポート済みリストと突き合わせて、クラス・ローダーにクラスをロードさせます
        • クラスを見つからない場合は、ルート・クラス・インポート(存在すれば)を使ってさらに検索します
      • SmartClassLoader extends ClassLoader
        • 親クラスロードおよびClassImporterオブジェクトを持つクラス・ローダー
        • ショット・クラス名の解決はClassImporterに任せます、クラスは親クラスによってロードされます
        • EnhancedXmlS2ContainerBuilder#parse(parent, path)処理の中で、生成したS2コンテナーにセットされます

      使用方法
      s2container.diconに名前は「dicon」の「EnhancedXmlS2ContainerBuilder」コンポーネントを追加します:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
      	"http://www.seasar.org/dtd/components24.dtd">
      <components>
          <include condition="#ENV == 'ut'" path="warmdeploy.dicon"/>
          <include condition="#ENV == 'ct'" path="hotdeploy.dicon"/>
          <include condition="#ENV != 'ut' and #ENV != 'ct'" path="cooldeploy.dicon"/>
          
           <component name="dicon" class="org.seasar.framework.container.patch.EnhancedXmlS2ContainerBuilder"/>
      
      </components>
      

      以上、ご検討をお願いいたします。

          [CONTAINER-175] SAX サポートクラスの final を外し,OGNL の処理中にクラスを読み込むのを Class#forName() から ClassLoader#loadClass() に変更しました.

          koichik added a comment -

          リリース後に問題が解消していないことが分かっても手遅れなので,対応後の確認および報告はリリースの前にお願いします.
          インポート機能を Seasar2 に取り込む予定はないのでパッチを提供していただく必要はありません.

          koichik added a comment - リリース後に問題が解消していないことが分かっても手遅れなので,対応後の確認および報告はリリースの前にお願いします. インポート機能を Seasar2 に取り込む予定はないのでパッチを提供していただく必要はありません.

          Feng Dihai added a comment -

          2.4.24のリリースを待っているので、返事が遅れて申し訳ございません。

          ご返答の中では、

          また,SmartClassLoader を使うために XmlS2ContainerBuilder を拡張する必要はありません.s2container.dicon に以下のように設定するだけで,そのクラスローダが使われます.

          <component class="org.seasar.framework.container.patch.SmartClassLoader"/>
          

          実際importは個別diconファイルをスコープとし、インクルードより構築されたS2コンテナの階層と関係はありません。よってS2コンテナのインスタンスごとにSmartClassLoaderは必要です。上記のコンポーネント定義に、「 instance="prototype" 」を追加するすてきです:

          <component class="org.seasar.framework.container.patch.SmartClassLoader" instance="prototype" />
          

          PIの使用に関して賛否両論に分かれているみたい(http://www.advogato.org/article/522.html)だけど、<?xml-stylesheet ..?>のような日常的にも使われています。
          <import>要素を定義するのに比べて、PIなら別途DTDを拡張しなくても済むメリットもあります。また、PIはあくまでオプションなので、処理プログラムはただ無視してもいいです。

          私はクラス・インポートの拡張機能を<?java-import ..?>ベースに実装するつもりです。CONTAINER-181対応の様子を見て、後日パッチを用意いたします。

          Feng Dihai added a comment - 2.4.24のリリースを待っているので、返事が遅れて申し訳ございません。 ご返答の中では、 また,SmartClassLoader を使うために XmlS2ContainerBuilder を拡張する必要はありません.s2container.dicon に以下のように設定するだけで,そのクラスローダが使われます. <component class= "org.seasar.framework.container.patch.SmartClassLoader" /> 実際importは個別diconファイルをスコープとし、インクルードより構築されたS2コンテナの階層と関係はありません。よってS2コンテナのインスタンスごとにSmartClassLoaderは必要です。上記のコンポーネント定義に、「 instance="prototype" 」を追加するすてきです: <component class= "org.seasar.framework.container.patch.SmartClassLoader" instance= "prototype" /> PIの使用に関して賛否両論に分かれているみたい( http://www.advogato.org/article/522.html )だけど、<?xml-stylesheet ..?>のような日常的にも使われています。 <import>要素を定義するのに比べて、PIなら別途DTDを拡張しなくても済むメリットもあります。また、PIはあくまでオプションなので、処理プログラムはただ無視してもいいです。 私はクラス・インポートの拡張機能を<?java-import ..?>ベースに実装するつもりです。 CONTAINER-181 対応の様子を見て、後日パッチを用意いたします。

          koichik added a comment -

          この拡張では import の定義に PI が使われていますが,要素を使うことも可能です.

          • <import> 要素を定義した DTD を作成してクラスパス上に配置 (Jar に含めるなど).
          • 追加した要素を扱う AbstractTagHandler のサブクラス (ImportTagHandler) を作成.
          • s2container.dicon に以下のような定義を追加.
            <component name="defaultBuilder" class="org.seasar.framework.container.factory.XmlS2ContainerBuilder">
              <property name="rule">
                <component class="org.seasar.framework.container.factory.S2ContainerTagHandlerRule">
                  <initMethod name="addTagHandler">
                    <arg>"import"</arg>
                    <arg>
                      <component class="org.seasar.framework.container.patch.ImportTagHandler"/>
                    </arg>
                  </initMethod>
                </component>
              </property>
              <initMethod name="addDtd">
                <arg>"-//SEASAR//DTD S2Container 2.4 Import Extension//EN"</arg>
                <arg>"components24ex.dtd"</arg>
              </initMethod>
            </component>
            

          また,SmartClassLoader を使うために XmlS2ContainerBuilder を拡張する必要はありません.s2container.dicon に以下のように設定するだけで,そのクラスローダが使われます.

          <component class="org.seasar.framework.container.patch.SmartClassLoader"/>
          

          koichik added a comment - この拡張では import の定義に PI が使われていますが,要素を使うことも可能です. <import> 要素を定義した DTD を作成してクラスパス上に配置 (Jar に含めるなど). 追加した要素を扱う AbstractTagHandler のサブクラス (ImportTagHandler) を作成. s2container.dicon に以下のような定義を追加. <component name= "defaultBuilder" class= "org.seasar.framework.container.factory.XmlS2ContainerBuilder" > <property name= "rule" > <component class= "org.seasar.framework.container.factory.S2ContainerTagHandlerRule" > <initMethod name= "addTagHandler" > <arg> "import" </arg> <arg> <component class= "org.seasar.framework.container.patch.ImportTagHandler" /> </arg> </initMethod> </component> </property> <initMethod name= "addDtd" > <arg> "-//SEASAR//DTD S2Container 2.4 Import Extension//EN" </arg> <arg> "components24ex.dtd" </arg> </initMethod> </component> また,SmartClassLoader を使うために XmlS2ContainerBuilder を拡張する必要はありません.s2container.dicon に以下のように設定するだけで,そのクラスローダが使われます. <component class= "org.seasar.framework.container.patch.SmartClassLoader" />

          koichik added a comment - SNAPSHOT をデプロイしたのでご確認ください. http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-framework/2.4.24-SNAPSHOT/s2-framework-2.4.24-20080312.085436-3.jar http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-extension/2.4.24-SNAPSHOT/s2-extension-2.4.24-20080312.085436-2.jar http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-tiger/2.4.24-SNAPSHOT/s2-tiger-2.4.24-20080312.090138-3.jar

          koichik added a comment -

          koichik added a comment - 修正しました. http://svn.seasar.org/browse/?view=rev&root=s2container&revision=3530

          Feng Dihai added a comment -

          具体的には,以下の 2 点に対応すれば,「きれいに実装できないところ」がなくなるように思われます.

          • SaxHandlerParser クラスの final を外す.
          • OgnlUtil で Class#forName() を ClassLoader#loadClass() に変更する.

          この2点でも対応していただければ、大変助かります。そうすればおしゃったとおり、Seasar2本体ではなく拡張機能が勝手に作られるようになります。

          よろしいければ、対応の予定を教えていただきませんか?

          Feng Dihai added a comment - 具体的には,以下の 2 点に対応すれば,「きれいに実装できないところ」がなくなるように思われます. SaxHandlerParser クラスの final を外す. OgnlUtil で Class#forName() を ClassLoader#loadClass() に変更する. この2点でも対応していただければ、大変助かります。そうすればおしゃったとおり、Seasar2本体ではなく拡張機能が勝手に作られるようになります。 よろしいければ、対応の予定を教えていただきませんか?

          koichik added a comment -

          Seasar プロジェクトしては dicon ファイルの入力を補完する Eclipse Plugin "Kijimuna" を用意しています.

          このため,本提案を取り込む必要性はあまりありません.
          むしろ Kijimuna との連携がうまくできなくなるというデメリットがあります.

          また,Seasar2 に対する機能追加は基本的に終了しています.

          以上の点から,本提案のパッチを取り込むよりも,このような拡張がしやすいように改善するということでいかがでしょうか?

          具体的には,以下の 2 点に対応すれば,「きれいに実装できないところ」がなくなるように思われます.

          • SaxHandlerParser クラスの final を外す.
          • OgnlUtil で Class#forName() を ClassLoader#loadClass() に変更する.

          koichik added a comment - Seasar プロジェクトしては dicon ファイルの入力を補完する Eclipse Plugin "Kijimuna" を用意しています. http://kijimuna.seasar.org/ このため,本提案を取り込む必要性はあまりありません. むしろ Kijimuna との連携がうまくできなくなるというデメリットがあります. また,Seasar2 に対する機能追加は基本的に終了しています. http://d.hatena.ne.jp/higayasuo/20080129/1201608976 以上の点から,本提案のパッチを取り込むよりも,このような拡張がしやすいように改善するということでいかがでしょうか? 具体的には,以下の 2 点に対応すれば,「きれいに実装できないところ」がなくなるように思われます. SaxHandlerParser クラスの final を外す. OgnlUtil で Class#forName() を ClassLoader#loadClass() に変更する.

          Feng Dihai added a comment -

          実装のソース・ファイルはこちらからダウンロードできます:
          http://fengdh.googlepages.com/s2container_patch_src.jar

          by Feng Dihai

          Feng Dihai added a comment - 実装のソース・ファイルはこちらからダウンロードできます: http://fengdh.googlepages.com/s2container_patch_src.jar by Feng Dihai

            Assignee:
            koichik
            Reporter:
            Feng Dihai
            Votes:
            0 Vote for this issue
            Watchers:
            Start watching this issue

              Created:
              Updated:
              Resolved: