From f72c431e8ad473b98f53d9cf980c23f7b509ef45 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Mon, 7 Jun 2010 13:15:07 +0000 Subject: [PATCH] SPR-7257 - AbstractMarshaller incorrectly expects DOMResult to already have a node --- .../oxm/support/AbstractMarshaller.java | 18 ++++++++++-- .../oxm/AbstractMarshallerTests.java | 29 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/org.springframework.oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java b/org.springframework.oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java index c6aa545eed5..cee37bb9b46 100644 --- a/org.springframework.oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java +++ b/org.springframework.oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -189,7 +189,21 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller { * @see #marshalDomNode(Object, org.w3c.dom.Node) */ protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMappingException { - Assert.notNull(domResult.getNode(), "DOMResult does not contain Node"); + if (domResult.getNode() == null) { + try { + synchronized (this.documentBuilderFactoryMonitor) { + if (this.documentBuilderFactory == null) { + this.documentBuilderFactory = createDocumentBuilderFactory(); + } + } + DocumentBuilder documentBuilder = createDocumentBuilder(this.documentBuilderFactory); + domResult.setNode(documentBuilder.newDocument()); + } + catch (ParserConfigurationException ex) { + throw new UnmarshallingFailureException( + "Could not create document placeholder for DOMResult: " + ex.getMessage(), ex); + } + } marshalDomNode(graph, domResult.getNode()); } diff --git a/org.springframework.oxm/src/test/java/org/springframework/oxm/AbstractMarshallerTests.java b/org.springframework.oxm/src/test/java/org/springframework/oxm/AbstractMarshallerTests.java index f69e71def9d..a214f2a27f2 100644 --- a/org.springframework.oxm/src/test/java/org/springframework/oxm/AbstractMarshallerTests.java +++ b/org.springframework.oxm/src/test/java/org/springframework/oxm/AbstractMarshallerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,8 +28,9 @@ import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stax.StAXResult; import javax.xml.transform.stream.StreamResult; -import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.custommonkey.xmlunit.XMLAssert.*; import org.custommonkey.xmlunit.XMLUnit; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Attr; @@ -86,6 +87,30 @@ public abstract class AbstractMarshallerTests { assertXMLEqual("Marshaller writes invalid DOMResult", expected, result); } + @Test + public void marshalEmptyDOMResult() throws Exception { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); + DOMResult domResult = new DOMResult(); + marshaller.marshal(flights, domResult); + assertTrue("DOMResult does not contain a Document", domResult.getNode() instanceof Document); + Document result = (Document) domResult.getNode(); + Document expected = builder.newDocument(); + Element flightsElement = expected.createElementNS("http://samples.springframework.org/flight", "tns:flights"); + Attr namespace = expected.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:tns"); + namespace.setNodeValue("http://samples.springframework.org/flight"); + flightsElement.setAttributeNode(namespace); + expected.appendChild(flightsElement); + Element flightElement = expected.createElementNS("http://samples.springframework.org/flight", "tns:flight"); + flightsElement.appendChild(flightElement); + Element numberElement = expected.createElementNS("http://samples.springframework.org/flight", "tns:number"); + flightElement.appendChild(numberElement); + Text text = expected.createTextNode("42"); + numberElement.appendChild(text); + assertXMLEqual("Marshaller writes invalid DOMResult", expected, result); + } + @Test public void marshalStreamResultWriter() throws Exception { StringWriter writer = new StringWriter();