View Javadoc

1   /*
2    * Copyright 2005-2012 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.test.server;
18  
19  import java.io.IOException;
20  import java.util.Locale;
21  import java.util.Map;
22  import javax.xml.namespace.QName;
23  import javax.xml.transform.Source;
24  
25  import org.springframework.core.io.Resource;
26  import org.springframework.util.Assert;
27  import org.springframework.ws.FaultAwareWebServiceMessage;
28  import org.springframework.ws.WebServiceMessage;
29  import org.springframework.ws.soap.SoapVersion;
30  import org.springframework.ws.test.support.matcher.PayloadDiffMatcher;
31  import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher;
32  import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher;
33  import org.springframework.ws.test.support.matcher.SoapHeaderMatcher;
34  import org.springframework.xml.transform.ResourceSource;
35  
36  import static org.springframework.ws.test.support.AssertionErrors.fail;
37  
38  /**
39   * Factory methods for {@link ResponseMatcher} classes. Typically used to provide input for {@link
40   * ResponseActions#andExpect(ResponseMatcher)}.
41   *
42   * @author Arjen Poutsma
43   * @since 2.0
44   */
45  public abstract class ResponseMatchers {
46  
47      private ResponseMatchers() {
48      }
49      
50      // Payload
51  
52      /**
53       * Expects the given {@link Source} XML payload.
54       *
55       * @param payload the XML payload
56       * @return the response matcher
57       */
58      public static ResponseMatcher payload(Source payload) {
59          return new WebServiceMessageMatcherAdapter(new PayloadDiffMatcher(payload));
60      }
61  
62      /**
63       * Expects the given {@link Resource} XML payload.
64       *
65       * @param payload the XML payload
66       * @return the response matcher
67       */
68      public static ResponseMatcher payload(Resource payload) throws IOException {
69          return payload(new ResourceSource(payload));
70      }
71  
72      /**
73       * Expects the payload to validate against the given XSD schema(s).
74       *
75       * @param schema         the schema
76       * @param furtherSchemas further schemas, if necessary
77       * @return the response matcher
78       */
79      public static ResponseMatcher validPayload(Resource schema, Resource... furtherSchemas) throws IOException {
80          return new WebServiceMessageMatcherAdapter(new SchemaValidatingMatcher(schema, furtherSchemas));
81      }
82  
83      /**
84       * Expects the given XPath expression to (not) exist or be evaluated to a value.
85       *
86       * @param xpathExpression the XPath expression
87       * @return the XPath expectations, to be further configured
88       */
89      public static ResponseXPathExpectations xpath(String xpathExpression) {
90          return new XPathExpectationsHelperAdapter(xpathExpression, null);
91      }
92  
93      /**
94       * Expects the given XPath expression to (not) exist or be evaluated to a value.
95       *
96       * @param xpathExpression  the XPath expression
97       * @param namespaceMapping the namespaces
98       * @return the XPath expectations, to be further configured
99       */
100     public static ResponseXPathExpectations xpath(String xpathExpression, Map<String, String> namespaceMapping) {
101         return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping);
102     }
103 
104     // SOAP
105 
106     /**
107      * Expects the given {@link Source} XML SOAP envelope.
108      *
109      * @param soapEnvelope the XML SOAP envelope
110      * @return the response matcher
111      * @since 2.1.1
112      */
113     public static ResponseMatcher soapEnvelope(Source soapEnvelope) {
114         return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope));
115     }
116 
117     /**
118      * Expects the given {@link Resource} XML SOAP envelope.
119      *
120      * @param soapEnvelope the XML SOAP envelope
121      * @return the response matcher
122      * @since 2.1.1
123      */
124     public static ResponseMatcher soapEnvelope(Resource soapEnvelope) throws IOException {
125         return soapEnvelope(new ResourceSource(soapEnvelope));
126     }
127 
128     /**
129      * Expects the given SOAP header in the outgoing message.
130      *
131      * @param soapHeaderName the qualified name of the SOAP header to expect
132      * @return the request matcher
133      */
134     public static ResponseMatcher soapHeader(QName soapHeaderName) {
135         Assert.notNull(soapHeaderName, "'soapHeaderName' must not be null");
136         return new WebServiceMessageMatcherAdapter(new SoapHeaderMatcher(soapHeaderName));
137     }
138 
139     /**
140      * Expects the response <strong>not</strong> to contain a SOAP fault.
141      *
142      * @return the response matcher
143      */
144     public static ResponseMatcher noFault() {
145         return new ResponseMatcher() {
146             public void match(WebServiceMessage request, WebServiceMessage response)
147                     throws IOException, AssertionError {
148                 if (response instanceof FaultAwareWebServiceMessage) {
149                     FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) response;
150                     if (faultMessage.hasFault()) {
151                         fail("Response has a SOAP Fault: \"" + faultMessage.getFaultReason() + "\"");
152                     }
153                 }
154             }
155 
156         };
157     }
158 
159     /**
160      * Expects a {@code MustUnderstand} fault.
161      *
162      * @see org.springframework.ws.soap.SoapBody#addMustUnderstandFault(String, Locale)
163      */
164     public static ResponseMatcher mustUnderstandFault() {
165         return mustUnderstandFault(null);
166     }
167 
168     /**
169      * Expects a {@code MustUnderstand} fault with a particular fault string or reason.
170      *
171      * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
172      * reason text will not be verified
173      * @see org.springframework.ws.soap.SoapBody#addMustUnderstandFault(String, Locale)
174      */
175     public static ResponseMatcher mustUnderstandFault(String faultStringOrReason) {
176         return new SoapFaultResponseMatcher(faultStringOrReason) {
177             @Override
178             protected QName getExpectedFaultCode(SoapVersion version) {
179                 return version.getMustUnderstandFaultName();
180             }
181         };
182     }
183 
184     /**
185      * Expects a {@code Client} (SOAP 1.1) or {@code Sender} (SOAP 1.2) fault.
186      *
187      * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
188      */
189     public static ResponseMatcher clientOrSenderFault() {
190         return clientOrSenderFault(null);
191     }
192 
193     /**
194      * Expects a {@code Client} (SOAP 1.1) or {@code Sender} (SOAP 1.2) fault with a particular fault string or reason.
195      *
196      * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
197      * reason text will not be verified
198      * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
199      */
200     public static ResponseMatcher clientOrSenderFault(String faultStringOrReason) {
201         return new SoapFaultResponseMatcher(faultStringOrReason) {
202             @Override
203             protected QName getExpectedFaultCode(SoapVersion version) {
204                 return version.getClientOrSenderFaultName();
205             }
206         };
207     }
208 
209     /**
210      * Expects a {@code Server} (SOAP 1.1) or {@code Receiver} (SOAP 1.2) fault.
211      *
212      * @see org.springframework.ws.soap.SoapBody#addServerOrReceiverFault(String, java.util.Locale)
213      */
214     public static ResponseMatcher serverOrReceiverFault() {
215         return serverOrReceiverFault(null);
216     }
217 
218     /**
219      * Expects a {@code Server} (SOAP 1.1) or {@code Receiver} (SOAP 1.2) fault with a particular fault string or reason.
220      *
221      * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
222      * reason text will not be verified
223      * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
224      */
225     public static ResponseMatcher serverOrReceiverFault(String faultStringOrReason) {
226         return new SoapFaultResponseMatcher(faultStringOrReason) {
227             @Override
228             protected QName getExpectedFaultCode(SoapVersion version) {
229                 return version.getServerOrReceiverFaultName();
230             }
231         };
232     }
233 
234     /**
235      * Expects a {@code VersionMismatch} fault.
236      *
237      * @see org.springframework.ws.soap.SoapBody#addVersionMismatchFault(String, java.util.Locale)
238      */
239     public static ResponseMatcher versionMismatchFault() {
240         return versionMismatchFault(null);
241     }
242 
243     /**
244      * Expects a {@code VersionMismatch} fault with a particular fault string or reason.
245      *
246      * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
247      * reason text will not be verified
248      * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
249      */
250     public static ResponseMatcher versionMismatchFault(String faultStringOrReason) {
251         return new SoapFaultResponseMatcher(faultStringOrReason) {
252             @Override
253             protected QName getExpectedFaultCode(SoapVersion version) {
254                 return version.getVersionMismatchFaultName();
255             }
256         };
257     }
258 
259 }