2012-02-12 13 views
7

私の質問はJAXBプラグイン、特にJAXBのコードモデルを書くことです。CodeModelでClassOutline/JClass/CClassの役割は何ですか?

ClassOutline(と、それはcompanionsだ)とJClass(およびcompanions)とCClass(およびcompanions)の役割は何ですか?対応するパッケージ内のクラスのリストを見ると、何が鶏で、何が卵であるのかは不明です。

私の解釈は、CClassCPropertyInfoCEnumConstant、...)は、XSDの最初の草稿解析時にXJCによって作成されています。その後、いくつかの魔法が発生し、このモデルはJClassJFieldVarJEnumConstant、...)に変換され、この変換の間にカスタマイズが適用されます。その後、プラグインが呼び出されます。 ClassOutlineは、これらの2つのモデルの間のブリッジとして使用されます。全体が非常に複雑に見えます。

これらの並列モデルでは、同じ情報がいくつかの方法で導出できると私は信じています。たとえば、クラスのフィールドタイプ:

  • JClass#fields()JFieldVar#typeJType
  • CClassInfo#getProperties()CPropertyInfo#baseTypeJType

私は、上記のモデルのライフサイクルの詳細な説明を探しています。ありがとう。

答えて

17

ああ、誰かがXJC内部に興味があります。他の誰よりもJAXBプラグインを開発している可能性があるので、助けてもらえます(JAXB2 Basicsなど)

さて、始めましょう。 XJCスキーマコンパイラは約

  • 次んするスキーマ
  • スキーマ(CClass、CPropertyInfo等)のモデルを作成し解析し
  • 輪郭(ClassOutline、FieldOutline等)を作成
  • レンダリングコードモデル(JCLASS、JDefinedClass、JMethodなど)
  • は、(ディスク上のex.Javaファイル)の物理的なコードを書き込み

最後の2つから始めましょう。

Javaファイルは説明を必要としません。

コードモデルも親しみやすいものです。プログラムでJavaコードを構築するために使用できるAPIです。代わりに文字列連結を使用することもできますが、エラーが発生しやすくなります。 CodeModelでは、少なくとも文法的に正しいJavaコードを取得することがほぼ保証されています。だから私はこの部分も明確であることを願っています。 (ちなみに、私はCodeModelが大好きです。私は最近、CodeModelのアイデアに基づいてJavaScript Code Modelを書いています。) "モデル"と "アウトライン"を見てみましょう。 モデルは、受信したスキーマを解析した結果です。それは、複雑な型に対応する "クラス"と、要素、属性、値に対応する "プロパティ"の観点から、着信スキーマの構造をモデル化します。単純なコンテンツを持つ複雑なタイプの場合)。

モデルは、XMLとスキーマに近い論理モデリング構築物として理解されなければなりません。そのようなものとして、それは彼らが持っているタイプとプロパティを記述するだけです。私がどのように記述しているかははっきりとはっきりと分かりますが、wilcardのタイプ(xsd:any)、置換グループ、列挙型、組込み型など、あらゆる例外と警告があります。

非常に興味深いことに、Modelの兄弟は、実行時にJAXBによって使用されるRuntimeTypeInfoSetImplです。つまり、XMLスキーマから解析されるのではなく、クラスのJAXBアノテーションから解析されるモデルの一種です。概念は同じです。 ModelとRuntimeTypeInfoSetImplの両方は、スーパーコンストラクトであるTypeInfoSetインターフェイスを実装しています。 ClassInfoPropertyInfoなどのインターフェースをチェック - 彼らは、コンパイル時(XJCでCClassInfoCPropertyInfo)のためにと実行時(JAXB RIのためのRuntimeClassInfoImplなど)の両方の実装を持っています。

XJCスキーマを解析され、分析されたときに[OK]を、ので、あなたがModelを持っています。このModelはまだコードを生成できません。実際には、コードを作成するさまざまな戦略があります。アノテートされたクラスだけを生成することもできますし、JAXB 1のようにインターフェイス/インプリメンテーションクラスのペアを生成することもできます。コード生成の全体は実際にはモデルのタスクではありません。さらに、Javaコードの物理的性質に関連する多くの側面がありますが、実際にはモデルには関係ありません。たとえば、クラスをパッケージにグループ化する必要があります。これは、Java自体のプロパティではなく、Javaのパッキングシステムによって駆動されます。

そして、輪郭が遊びに来る場所です。スキーマモデルとコードモデルの間のステップとしてアウトラインを見ることができます。コードの構成を担当するコード・モデル要素のファクトリとしてアウトラインを表示し、の生成をCClassInfoから行うことができます。

だから、あなたは正しい、それは確かに非常に複雑です。私はサン/オラクルの従業員ではなく、私はそれをデザインしませんでした(私はそれをした人を知っていますが、彼を大いに尊敬しています)。 私は、例えば、特定の設計上の決定の理由のカップルを推測することができます。

  • は、コンパイル時に同じインタフェースを使用して実行時のモデルは
  • コード生成の異なる戦略
  • はにプラグインを許可を許可します作成したモデルを操作する

このデザインは非常に複雑ですが、その理由はわかります。そのための1つの証拠は、基本的に同じモデル上で、XMLとJavaScriptのマッピング用のマッピングジェネレータを実際に構築することが実際に可能であったことです。私はちょうどスキーマ分析をそのまま残してコード生成を置き換えなければなりませんでした。 (そのためJsonixを参照してください。)

[OK]を、うまくいけば私はXJCで物事は、彼らがどのようにしている理由についていくつかの光を当てます。これらのAPIで幸いですが、それほど厳しいものではありません。既存のオープンソースコードを自由にチェックしてください。多くの例があります。

ps。本当にいつもこれを書こうと思っていました。 :)

+0

実際、素晴らしい説明です。私が尋ねる理由は、私が['jaxb-xew-plugin']を改良しているからです(https://github.com/dmak/jaxb-xew-plugin/blob/master/src/main/java/com/sun /tools/xjc/addon/xew/XmlElementWrapperPlugin.java)、いくつかの情報がアウトラインモデルにあり、いくつかはコードモデルにあるため、アルゴリズム全体がちょっと台無しです。おそらくあなたは私の小さな質問に答えることができます:与えられたプロパティがカスタマイズされたことを知ることは可能でしょうか( 'fieldOutline.getPropertyInfo()。getCustomizations()'は常に空です)?そして、一般的に、そのようなトリックを議論する最良の場所は何ですか?ありがとう。 –

+0

こんにちは@lexicore、私は質問を追加しました。http://stackoverflow.com/questions/32677605/jaxb-how-to-remove-anything-from-jdefinedclassあなたはそれを見てくださいできますか? – weima

+0

あなたはそれが "コード生成のさまざまな戦略を可能にする"ことができると言いました。続くことができる戦略は何ですか – weima

2

(これは、一層のご質問にお答えすることです。)

はい、カスタマイズを確認することが可能です。 Here is私はカスタマイズにアクセスするために使用しているクラスです。

トリックは、参照プロパティが独自のカスタマイズを持たないということです。カスタマイズは、参照された要素プロパティに配置されます。

public static CCustomizations getCustomizations(
     final CPropertyInfo propertyInfo) { 

    final CCustomizations main = new CCustomizations(
      propertyInfo.getCustomizations()); 

    final Collection<CCustomizations> elementCustomizations = propertyInfo 
      .accept(new CPropertyVisitor<Collection<CCustomizations>>() { 
       public Collection<CCustomizations> onAttribute(
         CAttributePropertyInfo info) { 
        return Collections.emptyList(); 
       } 

       public Collection<CCustomizations> onElement(
         CElementPropertyInfo arg0) { 
        return Collections.emptyList(); 
       } 

       public Collection<CCustomizations> onReference(
         CReferencePropertyInfo info) { 

        final List<CCustomizations> elementCustomizations = new ArrayList<CCustomizations>(
          info.getElements().size()); 

        for (CElement element : info.getElements()) { 
         if (!(element instanceof CElementInfo && ((CElementInfo) element) 
           .hasClass())) { 
          elementCustomizations.add(element 
            .getCustomizations()); 
         } 
        } 

        return elementCustomizations; 
       } 

       public Collection<CCustomizations> onValue(
         CValuePropertyInfo arg0) { 
        return Collections.emptyList(); 
       }; 

      }); 

    CCustomizations customizations = main; 

    for (CCustomizations e : elementCustomizations) { 
     main.addAll(e); 
    } 

    return customizations; 
} 

私は[email protected]がそのような議論のための良い場所だと思います。

+0

実際、 'jaxb-xew-plugin'はJAXB2 Basicsプロジェクトの一部になる可能性があります。なぜそれがずっと前に起こらなかったのか - 私はただ疑問に思うことができます。どういうわけか、モデルAPIの改良を進めることができれば、私が大好きです。たとえば、私が挙げた問題を見てみましょう。[プロジェクトページ](https://github.com/dmak/jaxb-xew-plugin/#algorithm-description )。 –

+0

Hm、strange。あなたが提供したコードスニペットを使用しようとしていますが、 'elementCustomizations'コレクションは常に空です。カスタマイズが適用されると、カスタマイズが削除されるという感覚があります。 'getCustomizations()'関数は 'FieldOutline.getPropertyInfo()'によって返されたオブジェクトに渡されます。 –

+0

@dma_kまあ、あなたは奇妙なコーナーケースに遭遇しているかもしれませんが、XJCはそれらでいっぱいです。これは実際にJAXB2-Basicsのカスタマイズに使用するコードです。https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/tools/src/main/java/org/jvnet/jaxb2_commons/ util/CustomizationUtils.java – lexicore

関連する問題