Reputation: 7615
I have been tasked with refactoring some components that used xmlbeans to now make use of jaxb. Everything is going great, until I get to a place where the previous author has called the copy() function of one of the XmlObjects. Since all objects in xmlbeans extend XmlObject, we get the magic deep copy function for free.
Jaxb does not seem to provide this for us. What is the correct and simple way to make a deep copy of a Jaxb object?
Upvotes: 2
Views: 8601
Reputation: 5209
You can refer this
public static <T> T deepCopyJAXB(T object, Class<T> clazz) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
JAXBElement<T> contentObject = new JAXBElement<T>(new QName(clazz.getSimpleName()), clazz, object);
JAXBSource source = new JAXBSource(jaxbContext, contentObject);
return jaxbContext.createUnmarshaller().unmarshal(source, clazz).getValue();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static <T> T deepCopyJAXB(T object) {
if(object==null) throw new RuntimeException("Can't guess at class");
return deepCopyJAXB(object, (Class<T>) object.getClass());
}
It works for me.
All the credit goes to https://gist.github.com/darrend/821410
Upvotes: 7
Reputation: 29240
You can declare a base class for the generated jaxb objects using an annotation in the XSD...
<xsd:annotation>
<xsd:appinfo>
<jaxb:globalBindings>
<xjc:superClass name="com.foo.types.support.JaxbBase" />
</jaxb:globalBindings>
</xsd:appinfo>
</xsd:annotation>
You can add the clonability support there using the xmlbeans base class as a template.
Upvotes: 3
Reputation: 419
You can use JAXBSource
Say you want to deep copy a sourceObject, of type Foo. Create 2 JAXBContexts for the same Type:
JAXBContext sourceJAXBContext = JAXBContext.newInstance("Foo.class");
JAXBContext targetJAXBContext = JAXBContext.newInstance("Foo.class");
and then do:
targetJAXBContext.createUnmarshaller().unmarshal(
new JAXBSource(sourceJAXBContext,sourceObject);
Upvotes: 4
Reputation: 63094
You could make your JAXB classes serializable and then deep copying an object by serializing and deserializing it. The code might look something like:
Object obj = ... // object to copy
ObjectOutputStream out = new ObjectOutputStream(new ByteArrayOutputStream());
out.writeObject(obj);
byte[] bytes = baos.toByteArray();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
Object copy = in.readObject();
Upvotes: 3