docx4j의 V3.3.0의 효율적인 딥 카피는 JAXB 객체를 복제하려면 다음 코드를 사용합니다 (이 자바 6 지원하기 때문에, 우리가 사용하는)MOXY : JAXBElement 첨부
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);
}
}
MOXY의 v2.5.2로를 최신 2.6.3, 예를 들어, JAXBElement 첨부를 복제하려고 :에
public void testIssue212() {
CTBookmark bookmark = Context.getWmlObjectFactory().createCTBookmark();
JAXBElement<CTBookmark> el =Context.getWmlObjectFactory().createBodyBookmarkStart(bookmark);
Object o = XmlUtils.deepCopy(el);
}
결과 :
[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
것은 우리는이 지혜를 해결할 수 있습니다 h는 다음과 같습니다.
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);
}
더 좋은 방법이 있습니까?
감사합니다. iirc, 과거에 여러 확장 프로그램을 한꺼번에 사용하려고 할 때 곤란했습니다. docx4j는 parent-pointer-plugin을 사용합니다. – JasonPlutext