There is next problem, i have similar class structure:
class A {
public String a;
}
class B extends A {
public String b;
}
class C {
public List<A> alist;
public A current;
}
Structure of this classes can not be changed. I.e. i can not add id attribute.
I need to create xsd schema for those classes. current
element is one from alist
element.
So I wa开发者_运维知识库nt some kind of references here. But I don't see how @XmlID
, @XmlIREF
can be used.
Then base on schema xml files will be generated and loaded via JAXB to objects.
Are there any way to do this? May be somehow use xpointer or whatever, that JAXB can understand?
Ok, I end up with such solution:
Using custom impl of RuntimeAnnotationReader, i embed two type of adater to alist and current elements.
public class ABeanAdapterList extends XmlAdapter<ABeanWrapper, Abean> {
public int i = 0;
private Map<Abean, String> unmarshall = new HashMap<Abean, String>();
private Map<String, Abean> marshall = new HashMap<String, Abean>();
@Override
public Abean unmarshal(ABeanWrapper v) throws Exception {
marshall.put(v.id, v.abean);
return v.abean;
}
@Override
public ABeanWrapper marshal(Abean v) throws Exception {
ABeanWrapper beanWrapper = new ABeanWrapper();
beanWrapper.abean = v;
beanWrapper.id = String.valueOf(i++);
unmarshall.put(beanWrapper.abean , beanWrapper.id);
return beanWrapper;
}
public String getId(Abean abean) {
return unmarshall.get(abean);
}
public Abean getAbean(String id) {
return marshall.get(id);
}
}
where ABeanWrapper contains two field: id and ABean for alist, and for current:
public class ABeanAdapterImpl extends XmlAdapter<ABeanRef, Abean> {
private ABeanAdapterList listAdapter;
public ABeanAdapterImpl(ABeanAdapterList list) {
listAdapter = list;
}
@Override
public Abean unmarshal(ABeanRef wrapper) throws Exception {
return listAdapter.getAbean(wrapper.refId);
}
@Override
public ABeanRef marshal(Abean abean) throws Exception {
ABeanRef ref = new ABeanRef();
ref.refId = listAdapter.getId(abean);
return ref;
}
}
And ABeanRef contains only one ref field. Invoke it such way:
Marshaller marshaller = context.createMarshaller();
ABeanAdapterList adapterList = new ABeanAdapterList();
marshaller.setAdapter(adapterList);
ABeanAdapterImpl beanAdapter = new ABeanAdapterImpl(adapterList);
marshaller.setAdapter(beanAdapter);
marshaller.marshal(sBean, new File("testSBean.xml"));
May by there is a better way, but this approach works...
精彩评论