3

現在、XML スキーマでSpring LDAP フィルターをモデル化しようとしています。これには、任意にネストできるポリモーフィック型が含まれます。

<andFilter>
  <notFilter>
     <equalsFilter name="mail" value="asfd@example.com" />
  </notFilter>
  <likeFilter name="mail" value="asdf*" />
</andFilter>

これは、xsd で上記のフィルターを定義する方法です (実際にはいくつかの中間抽象型が定義されていますが、簡単にするためにそれらを省略しています)。

<xsd:complexType name="baseFilterType" abstract="true" />
<xsd:element name="filter" type="tns:baseFilterType" />

<xsd:complexType name="andFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:filter" minOccurs="1" maxOccurs="unbounded" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="andFilter" type="tns:andFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="notFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:filter" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="notFilter" type="tns:notFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="likeFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:attributeName" />
    <xsd:element ref="tns:value" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="likeFilter" type="tns:likeFilterType" substitutionGroup="tns:filter" />

<xsd:complexType name="equalsFilterType">
  <xsd:sequence>
    <xsd:element ref="tns:attributeName" />
    <xsd:element ref="tns:value" />
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="equalsFilter" type="tns:equalsFilterType" substitutionGroup="tns:filter" />

JAXBElement<? extends BaseFilterType>(ビジター パターンを実装するために) いくつかのカスタム動作を使用して各フィルター クラスを拡張しましたが、生成されたクラス全体で使用される代わりに、JAXB をそれらにバインドする方法がわかりません。

JAXB モデル クラスはビルド時に生成されるため、それらを直接変更することはできません。カスタマイズには外部カスタム バインディングを使用する必要がありますimplClassとカスタマイズを試みましたが、そのbaseClass方法を理解できませんでした。

誰でも助けることができますか?

編集:マーシャリングとアンマーシャリングにSpringのセットを使用してJaxb2Marshallerいます。contextPathsこれがオブジェクトのインスタンス化に利用されることを期待してObjectFactoryいましたが、そうではないようです。

編集 2:フィルター要素は、次のように、最上位の要素と相互に参照されます。

<xsd:element name="GetAttributesRequest">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element ref="filter:filter" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

そのため、GetAttributesRequestオブジェクトは でマークされますが@XmlRootElement、フィルター クラス自体はマークされません。ただし、トップレベルのGetAttributesRequestオブジェクトでさえインスタンス化されていませんObjectFactory...

4

1 に答える 1

0

編集 :

質問の作成者が使用したソリューション:

JAXBバインディングのカスタマイズを使用して、ObjectFactoryにクラスのインスタンスを生成させてから、SpringのJaxb2Marshallerにcom.sun.xml.internal.bind.ObjectFactory(内部に注意)unmarshallerプロパティを設定して、ファクトリを使用するように強制しました。


元の答え:

はい、生成されたクラスに動作を追加することは可能です。関連ドキュメントをご覧ください

ドキュメントからの簡単な例を次に示します。

JAXBで生成されたコード

package org.acme.foo;

@XmlRootElement
class Person {
  private String name;

  public String getName() { return name; }
  public void setName(String) { this.name=name; }
}

@XmlRegistry
class ObjectFactory {
  Person createPerson() { ... }
}

拡張クラス

パッケージorg.acme.foo.impl;

class PersonEx extends Person {
  @Override
  public void setName(String name) {
    if(name.length()<3) throw new IllegalArgumentException();
    super.setName(name);
  }
}

@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
  @Override
  Person createPerson() {
    return new PersonEx();
  }
}

アンマーシャリングの例

Unmarshaller u = context.createUnmarshaller();
u.setProperty("com.sun.xml.bind.ObjectFactory",new ObjectFactoryEx());
PersonEx p = (PersonEx)u.unmarshal(new StringReader("<person />"));

詳細はこちら

于 2013-01-15T15:54:09.243 に答える