diff --git a/core/src/main/java/org/springframework/ws/soap/SoapMessage.java b/core/src/main/java/org/springframework/ws/soap/SoapMessage.java index 020b77cd..e66eaafc 100644 --- a/core/src/main/java/org/springframework/ws/soap/SoapMessage.java +++ b/core/src/main/java/org/springframework/ws/soap/SoapMessage.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -85,10 +85,9 @@ public interface SoapMessage extends MimeMessage, FaultAwareWebServiceMessage { Document getDocument(); /** - * Returns this message as a {@link Document}. + * Sets the contents of the message to the given {@link Document}. * - * Depending on the underlying implementation, this Document may be 'live' or not. - * @return this soap message as a DOM document + * @param document the soap message as a DOM document */ void setDocument(Document document); diff --git a/test/src/main/java/org/springframework/ws/test/client/RequestMatchers.java b/test/src/main/java/org/springframework/ws/test/client/RequestMatchers.java index cd2c41ff..9bff03f4 100644 --- a/test/src/main/java/org/springframework/ws/test/client/RequestMatchers.java +++ b/test/src/main/java/org/springframework/ws/test/client/RequestMatchers.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -27,6 +27,7 @@ import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.test.support.matcher.PayloadDiffMatcher; import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher; +import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher; import org.springframework.ws.test.support.matcher.SoapHeaderMatcher; import org.springframework.xml.transform.ResourceSource; @@ -54,6 +55,8 @@ public abstract class RequestMatchers { }; } + // Payload + /** * Expects the given {@link javax.xml.transform.Source} XML payload. * @@ -108,6 +111,32 @@ public abstract class RequestMatchers { return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping); } + // SOAP + + /** + * Expects the given {@link javax.xml.transform.Source} XML SOAP envelope. + * + * @param soapEnvelope the XML SOAP envelope + * @return the request matcher + * @since 2.1.1 + */ + public static RequestMatcher soapEnvelope(Source soapEnvelope) { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope)); + } + + /** + * Expects the given {@link org.springframework.core.io.Resource} XML SOAP envelope. + * + * @param soapEnvelope the XML SOAP envelope + * @return the request matcher + * @since 2.1.1 + */ + public static RequestMatcher soapEnvelope(Resource soapEnvelope) throws IOException { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return soapEnvelope(new ResourceSource(soapEnvelope)); + } + /** * Expects the given SOAP header in the outgoing message. * @@ -119,6 +148,8 @@ public abstract class RequestMatchers { return new WebServiceMessageMatcherAdapter(new SoapHeaderMatcher(soapHeaderName)); } + // Other + /** * Expects a connection to the given URI. * diff --git a/test/src/main/java/org/springframework/ws/test/client/ResponseCreators.java b/test/src/main/java/org/springframework/ws/test/client/ResponseCreators.java index 80852931..bfbd68a2 100644 --- a/test/src/main/java/org/springframework/ws/test/client/ResponseCreators.java +++ b/test/src/main/java/org/springframework/ws/test/client/ResponseCreators.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -27,6 +27,7 @@ import org.springframework.ws.WebServiceMessage; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.soap.SoapBody; import org.springframework.ws.test.support.creator.PayloadMessageCreator; +import org.springframework.ws.test.support.creator.SoapEnvelopeMessageCreator; import org.springframework.ws.test.support.creator.WebServiceMessageCreator; import org.springframework.xml.transform.ResourceSource; @@ -42,6 +43,8 @@ public abstract class ResponseCreators { private ResponseCreators() { } + // Payload + /** * Respond with the given {@link javax.xml.transform.Source} XML as payload response. * @@ -64,6 +67,8 @@ public abstract class ResponseCreators { return withPayload(new ResourceSource(payload)); } + // Error/Exception + /** * Respond with an error. * @@ -99,6 +104,33 @@ public abstract class ResponseCreators { return new ExceptionResponseCreator(ex); } + // SOAP + + /** + * Respond with the given {@link javax.xml.transform.Source} XML as SOAP envelope response. + * + * @param soapEnvelope the response SOAP envelope + * @return the response callback + * @since 2.1.1 + */ + public static ResponseCreator withSoapEnvelope(Source soapEnvelope) { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return new WebServiceMessageCreatorAdapter(new SoapEnvelopeMessageCreator(soapEnvelope)); + } + + /** + * Respond with the given {@link org.springframework.core.io.Resource} XML as SOAP envelope response. + * + * @param soapEnvelope the response SOAP envelope + * @return the response callback + * @since 2.1.1 + */ + public static ResponseCreator withSoapEnvelope(Resource soapEnvelope) throws IOException { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return withSoapEnvelope(new ResourceSource(soapEnvelope)); + } + + /** * Respond with a {@code MustUnderstand} fault. * diff --git a/test/src/main/java/org/springframework/ws/test/server/RequestCreators.java b/test/src/main/java/org/springframework/ws/test/server/RequestCreators.java index 8050b803..adee5123 100644 --- a/test/src/main/java/org/springframework/ws/test/server/RequestCreators.java +++ b/test/src/main/java/org/springframework/ws/test/server/RequestCreators.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -24,6 +24,7 @@ import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.test.support.creator.PayloadMessageCreator; +import org.springframework.ws.test.support.creator.SoapEnvelopeMessageCreator; import org.springframework.ws.test.support.creator.WebServiceMessageCreator; import org.springframework.xml.transform.ResourceSource; @@ -39,6 +40,8 @@ public abstract class RequestCreators { private RequestCreators() { } + // Payload + /** * Create a request with the given {@link Source} XML as payload. * @@ -61,6 +64,32 @@ public abstract class RequestCreators { return withPayload(new ResourceSource(payload)); } + // SOAP + + /** + * Create a request with the given {@link Source} XML as SOAP envelope. + * + * @param soapEnvelope the request SOAP envelope + * @return the request creator + * @since 2.1.1 + */ + public static RequestCreator withSoapEnvelope(Source soapEnvelope) { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return new WebServiceMessageCreatorAdapter(new SoapEnvelopeMessageCreator(soapEnvelope)); + } + + /** + * Create a request with the given {@link Resource} XML as SOAP envelope. + * + * @param soapEnvelope the request SOAP envelope + * @return the request creator + * @since 2.1.1 + */ + public static RequestCreator withSoapEnvelope(Resource soapEnvelope) throws IOException { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + return withSoapEnvelope(new ResourceSource(soapEnvelope)); + } + /** * Adapts a {@link WebServiceMessageCreator} to the {@link RequestCreator} contract. */ diff --git a/test/src/main/java/org/springframework/ws/test/server/ResponseMatchers.java b/test/src/main/java/org/springframework/ws/test/server/ResponseMatchers.java index d81763fc..c75aacc2 100644 --- a/test/src/main/java/org/springframework/ws/test/server/ResponseMatchers.java +++ b/test/src/main/java/org/springframework/ws/test/server/ResponseMatchers.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ import org.springframework.ws.WebServiceMessage; import org.springframework.ws.soap.SoapVersion; import org.springframework.ws.test.support.matcher.PayloadDiffMatcher; import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher; +import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher; import org.springframework.ws.test.support.matcher.SoapHeaderMatcher; import org.springframework.xml.transform.ResourceSource; @@ -45,7 +46,7 @@ public abstract class ResponseMatchers { private ResponseMatchers() { } - + // Payload /** @@ -100,9 +101,30 @@ public abstract class ResponseMatchers { return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping); } - // SOAP + /** + * Expects the given {@link Source} XML SOAP envelope. + * + * @param soapEnvelope the XML SOAP envelope + * @return the response matcher + * @since 2.1.1 + */ + public static ResponseMatcher soapEnvelope(Source soapEnvelope) { + return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope)); + } + + /** + * Expects the given {@link Resource} XML SOAP envelope. + * + * @param soapEnvelope the XML SOAP envelope + * @return the response matcher + * @since 2.1.1 + */ + public static ResponseMatcher soapEnvelope(Resource soapEnvelope) throws IOException { + return soapEnvelope(new ResourceSource(soapEnvelope)); + } + /** * Expects the given SOAP header in the outgoing message. * diff --git a/test/src/main/java/org/springframework/ws/test/support/creator/SoapEnvelopeMessageCreator.java b/test/src/main/java/org/springframework/ws/test/support/creator/SoapEnvelopeMessageCreator.java new file mode 100644 index 00000000..6572b5e0 --- /dev/null +++ b/test/src/main/java/org/springframework/ws/test/support/creator/SoapEnvelopeMessageCreator.java @@ -0,0 +1,70 @@ +/* + * Copyright 2005-2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.test.support.creator; + +import java.io.IOException; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; + +import org.springframework.util.Assert; +import org.springframework.ws.WebServiceMessage; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.xml.transform.TransformerHelper; + +import org.w3c.dom.Document; + +import static org.springframework.ws.test.support.AssertionErrors.assertTrue; +import static org.springframework.ws.test.support.AssertionErrors.fail; + +/** + * Implementation of {@link WebServiceMessageCreator} that creates a request based on a SOAP envelope {@link Source}. + * + * @author Alexander Shutyaev + * @since 2.1.1 + */ +public class SoapEnvelopeMessageCreator extends AbstractMessageCreator { + + private final Source soapEnvelope; + + private final TransformerHelper transformerHelper = new TransformerHelper(); + + /** + * Creates a new instance of the {@code SoapEnvelopeMessageCreator} with the given SOAP envelope source. + * + * @param soapEnvelope the SOAP envelope source + */ + public SoapEnvelopeMessageCreator(Source soapEnvelope) { + Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null"); + this.soapEnvelope = soapEnvelope; + } + + @Override + protected void doWithMessage(WebServiceMessage message) throws IOException { + assertTrue("Message created with factory is not a SOAP message", message instanceof SoapMessage); + SoapMessage soapMessage = (SoapMessage) message; + try { + DOMResult result = new DOMResult(); + transformerHelper.transform(soapEnvelope, result); + soapMessage.setDocument((Document) result.getNode()); + } + catch (TransformerException ex) { + fail("Could not transform request SOAP envelope to message: " + ex.getMessage()); + } + } + +} diff --git a/test/src/main/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcher.java b/test/src/main/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcher.java new file mode 100644 index 00000000..b2bc9ef1 --- /dev/null +++ b/test/src/main/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcher.java @@ -0,0 +1,71 @@ +/* + * Copyright 2005-2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.test.support.matcher; + +import java.io.IOException; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; + +import org.springframework.util.Assert; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.xml.transform.TransformerHelper; + +import org.custommonkey.xmlunit.Diff; +import org.w3c.dom.Document; + +import static org.springframework.ws.test.support.AssertionErrors.assertTrue; +import static org.springframework.ws.test.support.AssertionErrors.fail; + +/** + * Matches {@link Source} SOAP envelopes. + * + * @author Alexander Shutyaev + * @since 2.1.1 + */ +public class SoapEnvelopeDiffMatcher extends AbstractSoapMessageMatcher { + + private final Source expected; + + private final TransformerHelper transformerHelper = new TransformerHelper(); + + public SoapEnvelopeDiffMatcher(Source expected) { + Assert.notNull(expected, "'expected' must not be null"); + this.expected = expected; + } + + @Override + protected void match(SoapMessage soapMessage) throws IOException, AssertionError { + Document actualDocument = soapMessage.getDocument(); + Document expectedDocument = createDocumentFromSource(expected); + Diff diff = new Diff(expectedDocument, actualDocument); + assertTrue("Envelopes are different, " + diff.toString(), diff.similar()); + } + + private Document createDocumentFromSource(Source source) { + try { + DOMResult result = new DOMResult(); + transformerHelper.transform(source, result); + return (Document) result.getNode(); + } + catch (TransformerException ex) { + fail("Could not transform source to DOMResult" + ex.getMessage()); + return null; + } + } + +} diff --git a/test/src/test/java/org/springframework/ws/test/client/ResponseCreatorsTest.java b/test/src/test/java/org/springframework/ws/test/client/ResponseCreatorsTest.java index d634b708..b55c52ce 100644 --- a/test/src/test/java/org/springframework/ws/test/client/ResponseCreatorsTest.java +++ b/test/src/test/java/org/springframework/ws/test/client/ResponseCreatorsTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2012 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,7 @@ import java.util.Locale; import javax.xml.namespace.QName; import javax.xml.transform.Result; import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMSource; import org.springframework.core.io.ByteArrayResource; import org.springframework.ws.WebServiceMessage; @@ -71,6 +72,34 @@ public class ResponseCreatorsTest { assertXMLEqual(payload, getPayloadAsString(response)); } + + @Test + public void withSoapEnvelopeSource() throws Exception { + StringBuilder xmlBuilder = new StringBuilder(); + xmlBuilder.append(""); + xmlBuilder.append(""); + xmlBuilder.append("
"); + xmlBuilder.append(""); + xmlBuilder.append(""); + String envelope = xmlBuilder.toString(); + ResponseCreator responseCreator = ResponseCreators.withSoapEnvelope(new StringSource(envelope)); + WebServiceMessage response = responseCreator.createResponse(null, null, messageFactory); + assertXMLEqual(envelope, getSoapEnvelopeAsString((SoapMessage)response)); + } + + @Test + public void withSoapEnvelopeResource() throws Exception { + StringBuilder xmlBuilder = new StringBuilder(); + xmlBuilder.append(""); + xmlBuilder.append(""); + xmlBuilder.append("
"); + xmlBuilder.append(""); + xmlBuilder.append(""); + String envelope = xmlBuilder.toString(); + ResponseCreator responseCreator = ResponseCreators.withSoapEnvelope(new ByteArrayResource(envelope.getBytes("UTF-8"))); + WebServiceMessage response = responseCreator.createResponse(null, null, messageFactory); + assertXMLEqual(envelope, getSoapEnvelopeAsString((SoapMessage)response)); + } @Test public void withIOException() throws Exception { @@ -145,4 +174,11 @@ public class ResponseCreatorsTest { transformerHelper.transform(message.getPayloadSource(), result); return result.toString(); } + + private String getSoapEnvelopeAsString(SoapMessage message) throws TransformerException { + DOMSource source = new DOMSource(message.getDocument()); + Result result = new StringResult(); + transformerHelper.transform(source, result); + return result.toString(); + } } diff --git a/test/src/test/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcherTest.java b/test/src/test/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcherTest.java new file mode 100644 index 00000000..fb8c4aed --- /dev/null +++ b/test/src/test/java/org/springframework/ws/test/support/matcher/SoapEnvelopeDiffMatcherTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2005-2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.test.support.matcher; + +import javax.xml.transform.dom.DOMResult; + +import org.springframework.ws.soap.SoapMessage; +import org.springframework.xml.transform.StringSource; +import org.springframework.xml.transform.TransformerHelper; + +import org.junit.Test; +import org.w3c.dom.Document; + +import static org.easymock.EasyMock.*; + +public class SoapEnvelopeDiffMatcherTest { + + @Test + public void match() throws Exception { + StringBuilder xmlBuilder = new StringBuilder(); + xmlBuilder.append(""); + xmlBuilder.append(""); + xmlBuilder.append("
"); + xmlBuilder.append(""); + xmlBuilder.append(""); + String xml = xmlBuilder.toString(); + DOMResult result = new DOMResult(); + TransformerHelper transformerHelper = new TransformerHelper(); + transformerHelper.transform(new StringSource(xml), result); + SoapMessage message = createMock(SoapMessage.class); + expect(message.getDocument()).andReturn((Document)result.getNode()).once(); + replay(message); + + SoapEnvelopeDiffMatcher matcher = new SoapEnvelopeDiffMatcher(new StringSource(xml)); + matcher.match(message); + + verify(message); + } + + @Test(expected = AssertionError.class) + public void nonMatch() throws Exception { + StringBuilder xmlBuilder = new StringBuilder(); + xmlBuilder.append(""); + xmlBuilder.append(""); + xmlBuilder.append("
"); + xmlBuilder.append(""); + xmlBuilder.append(""); + String xml = xmlBuilder.toString(); + String actual = String.format(xml, "1"); + DOMResult result = new DOMResult(); + TransformerHelper transformerHelper = new TransformerHelper(); + transformerHelper.transform(new StringSource(actual), result); + SoapMessage message = createMock(SoapMessage.class); + expect(message.getDocument()).andReturn((Document)result.getNode()).once(); + replay(message); + + String expected = String.format(xml, "2"); + SoapEnvelopeDiffMatcher matcher = new SoapEnvelopeDiffMatcher(new StringSource(expected)); + matcher.match(message); + } + +}