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 の単一継承モデルを考えると、これは、複数の継承階層を補完することを目的としたフレームワーク オブジェクトにはあまりにも制限的です。だからまだ立ち往生。