1

MOXy/JAXB 2.5.0 を使用して、Gang of Four のプロトタイプ パターンのバージョンを実装しようとしています。アイテムのリストを指定できるようにしたいのですが、そのうちのいくつかは他の「に基づいて」います。つまり、他のインスタンスからデータをコピーします。再利用性のために、プロトタイプ可能なオブジェクトが実装するインターフェイスを作成したいと思います。これは、パターンをサポートするために必要なプロパティの注釈を提供します。

@XmlRootElement(name="IPrototype")
public interface IPrototype
{
    /**
     * Acts as a "copy constructor"
     */
    @XmlAttribute(name="prototype")
    @XmlIDREF
    public void setPrototype(IPrototype prototype); 

    @XmlAttribute(name="id")
    @XmlID
    public void setId(String id);

    public String getId();
}

実装オブジェクトは、インターフェースから実装されたメソッドの注釈を気にする必要さえなく、理想的には次のようになります。

@XmlRootElement(name="Item")
public class Item implements IPrototype
{
    private String m_id = null;

    private String m_data = null;

    public Item()
    {

    }

    /**
     * Never called
     */
    @Override
    public void setPrototype(IPrototype prototype)
    {
        m_data = ((Item)prototype).getData();
    }

    @Override
    public void setId(String id)
    {
        m_id = id;
    }

    @Override
    public String getId()
    {
        return m_id;
    }

    @XmlAttribute(name="data")
    public void setData(String data)
    {
        m_data = data;
    }

    public String getData()
    {
        return m_data;
    }
}

XML は次のようになります。

<Wrapper>
    <Item id="Item1" data="stuff and things" />
    <Item id="Item2" prototype="Item1" />
</Wrapper>

ここで、ラッパーは次のように定義されます。

@XmlRootElement(name="Wrapper")
public class Wrapper
{
    @XmlElementRef
    private ArrayList<Item> m_items = null; 
}

希望どおりに機能する場合は、同じデータを含む 2 つの要素 (どちらも Item 型) を持つリストを取得します。ただし、MOXy はインターフェイスの注釈を「認識」していないようで、XmlID が設定されていない 2 つのアイテムのリストを取得し、setPrototype() が呼び出されることはありません。唯一の解決策は、Item クラスの setPrototype() および setId() メソッドに注釈を付けることのようですが、これには setPrototype() の引数の型を IPrototype から Item に変更する必要があるようで、MOXy は適切なクラスで XmlID を探します。残念ながら、これは継承されたインターフェースを壊します。

代わりに、リスト タイプを IPrototype に変更すると、MOXy がその注釈を表示できるようになることを期待して、同じ動作になります。null ID、setPrototype() は呼び出されません。とにかく、これは私が本当に望んでいるものではありません。特定のリストに含まれる可能性のあるサブタイプを制限できるようにしたいと考えています。

インターフェイス注釈がどのように機能するかについて正しい期待を持っているかどうかはわかりません。おそらくそれが私のエラーの原因です。

これを機能させる方法について何か考えはありますか?前もって感謝します、

スティーブ

更新: setPrototype のメソッド シグネチャを変更せずに Item クラスに注釈を付けると (これで問題ないと思います)、XmlID が正しく設定された 2 つの項目を含むリストが取得されますが、setPrototype() はまだ呼び出されません。MOXy は、Item インスタンスではなく、同じ XmlID を持つ IPrototype (不可能) のインスタンスを探しているようです。

更新 2: IPrototype を抽象クラスに変換すると、すべてが完全に機能します。ただし、Java の単一継承モデルを考えると、これは、複数の継承階層を補完することを目的としたフレームワーク オブジェクトにはあまりにも制限的です。だからまだ立ち往生。

4

2 に答える 2

0

MOXy の外部バインディング ドキュメントを使用して、実装クラスのスーパー クラス (つまりItem) をObjectインターフェイスからオーバーライドできますIPrototype。これにより、インターフェイスからマッピングを継承できます。

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum16807019">
    <java-types>
        <java-type name="Item" super-type="forum16807019.IPrototype"/>
    </java-types>
</xml-bindings>

完全な例については、次を参照してください。

于 2013-06-07T15:08:59.783 に答える
0

Item のプロパティに注釈を付け、ジェネリックを使用して setPrototype() を宣言することで、この実行のある程度受け入れられるバージョンを取得しました。IPrototype での宣言は次のようになります。

public <T> void setPrototype(T prototype);

Item での実装は次のとおりです。

@XmlAttribute(name="prototype")
@XmlIDREF
@Override
public <T> void setPrototype(T prototype)
{
    m_data = ((Item)prototype).getData();
}

それは機能しますが、サブクラスに再度注釈を付けなければならないのは特に好きではありません。それについては別の質問を開きました。これは、(私にとって)直感的にはインターフェース注釈が機能する方法ではないように思われるためです。

MOXy/JAXB インターフェースの注釈

于 2013-06-02T04:37:10.650 に答える