MOXy:JAXBElement的高效深度拷贝
docx4j v3.3.0使用以下代码克隆JAXB对象:MOXy:JAXBElement的高效深度拷贝,jaxb,eclipselink,moxy,docx4j,Jaxb,Eclipselink,Moxy,Docx4j,docx4j v3.3.0使用以下代码克隆JAXB对象: public static <T> T deepCopy(T value, JAXBContext jc) { if (value==null) { throw new IllegalArgumentException("Can't clone a null argument"); } try { @SuppressWarnings("unchecked")
public static <T> T deepCopy(T value, JAXBContext jc) {
if (value==null) {
throw new IllegalArgumentException("Can't clone a null argument");
}
try {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) value.getClass();
JAXBElement<T> contentObject = new JAXBElement<T>(new QName(clazz.getSimpleName()), clazz, value);
JAXBSource source = new JAXBSource(jc, contentObject);
JAXBElement<T> elem = jc.createUnmarshaller().unmarshal(source, clazz);
T res;
if (value instanceof JAXBElement<?>) {
@SuppressWarnings("unchecked")
T resT = (T) elem;
res = resT;
} else {
@SuppressWarnings("unchecked")
T resT = (T) elem.getValue();
res = resT;
}
return res;
} catch (JAXBException ex) {
throw new IllegalArgumentException(ex);
}
}
我们可以通过以下方式解决此问题:
JAXBElement<T> elem;
if (Context.getJaxbImplementation().equals(JAXBImplementation.ECLIPSELINK_MOXy)
&& value instanceof JAXBElement<?>) {
elem = (JAXBElement<T>) value;
Class<?> valueClass = elem.getDeclaredType();
Marshaller mar = jc.createMarshaller();
ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
mar.marshal(elem, bout);
Unmarshaller unmar = jc.createUnmarshaller();
elem = (JAXBElement<T>)unmar.unmarshal(new StreamSource(new ByteArrayInputStream(
bout.toByteArray())), valueClass);
}
JAXBElement元素;
if(Context.getJaxbImplementation().equals(JAXBImplementation.ECLIPSELINK_MOXy)
&&JAXBELENT的值实例){
elem=(JAXBElement)值;
Class valueClass=elem.getDeclaredType();
Marshaller mar=jc.createMarshaller();
ByteArrayOutputStream bout=新的ByteArrayOutputStream(256);
三月元帅(埃伦,布特);
Unmarshaller unmar=jc.createUnmarshaller();
elem=(JAXBElement)unmar.unmarshal(新的StreamSource(新的ByteArrayInputStream(
toByteArray()),valueClass);
}
但是有更好的方法吗?免责声明:我是这篇文章的作者,其中包括我认为非常适合这项任务的
可复制插件
您可能对可复制插件感兴趣,它生成无反射的策略复制方法
在Maven中激活(另请参见):
可能看起来有点奇怪/麻烦,但它考虑了相当多的JAXB特性。免责声明:我是这篇文章的作者,其中包括可复制插件,我认为它非常适合这项任务
您可能对可复制插件感兴趣,它生成无反射的策略复制方法
在Maven中激活(另请参见):
可能看起来有点奇怪/麻烦,但它考虑了相当多的JAXB特性。结果表明,在复制JAXBElement时引入的docx4j代码存在问题,无论是使用MOXy还是Sun/Oracle引用实现
修复了它发现在中引入的docx4j代码在复制JAXBElement时出现问题,无论是使用MOXy还是Sun/Oracle参考实现
修复它谢谢您的帮助。iirc,我在过去尝试同时使用多个扩展时遇到了麻烦。docx4j为此使用父指针插件。iirc,我在过去尝试同时使用多个扩展时遇到了麻烦。docx4j使用父指针插件
[Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class javax.xml.bind.JAXBElement was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:980)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:303)
at org.docx4j.XmlUtils.deepCopy(XmlUtils.java:974)
... 25 more
Caused by: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class javax.xml.bind.JAXBElement was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
at org.eclipse.persistence.exceptions.XMLMarshalException.descriptorNotFoundInProject(XMLMarshalException.java:140)
at org.eclipse.persistence.internal.oxm.Context$ContextState.getSession(Context.java:145)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:795)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.Context.getSession(Context.java:466)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:364)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:466)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:695)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
... 26 more
JAXBElement<T> elem;
if (Context.getJaxbImplementation().equals(JAXBImplementation.ECLIPSELINK_MOXy)
&& value instanceof JAXBElement<?>) {
elem = (JAXBElement<T>) value;
Class<?> valueClass = elem.getDeclaredType();
Marshaller mar = jc.createMarshaller();
ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
mar.marshal(elem, bout);
Unmarshaller unmar = jc.createUnmarshaller();
elem = (JAXBElement<T>)unmar.unmarshal(new StreamSource(new ByteArrayInputStream(
bout.toByteArray())), valueClass);
}
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<extension>true</extension>
<args>
<arg>-Xcopyable</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
</plugin>
</plugins>
</configuration>
</plugin>
public Object clone() {
return copyTo(createNewInstance());
}
public Object copyTo(Object target) {
final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
return copyTo(null, target, strategy);
}
public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) {
final Object draftCopy = ((target == null)?createNewInstance():target);
if (draftCopy instanceof IssueJIIB35) {
final IssueJIIB35 copy = ((IssueJIIB35) draftCopy);
{
Boolean nameShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, this.isSetName());
if (nameShouldBeCopiedAndSet == Boolean.TRUE) {
String sourceName;
sourceName = this.getName();
String copyName = ((String) strategy.copy(LocatorUtils.property(locator, "name", sourceName), sourceName, this.isSetName()));
copy.setName(copyName);
} else {
if (nameShouldBeCopiedAndSet == Boolean.FALSE) {
copy.name = null;
}
}
}
// ...
}
return draftCopy;
}
public Object createNewInstance() {
return new IssueJIIB35();
}