net.javacrumbs.springws.test.helper.MessageValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-ws-test Show documentation
Show all versions of spring-ws-test Show documentation
Spring WS Test is a tool to simplify Spring WS client
functional testing.
/**
* Copyright 2009-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.
* 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 net.javacrumbs.springws.test.helper;
import java.io.IOException;
import java.util.Map;
import java.util.regex.Pattern;
import net.javacrumbs.springws.test.WsTestException;
import net.javacrumbs.springws.test.common.DefaultMessageComparator;
import net.javacrumbs.springws.test.common.ExpressionEvaluator;
import net.javacrumbs.springws.test.common.MessageComparator;
import net.javacrumbs.springws.test.common.SchemaValidator;
import net.javacrumbs.springws.test.common.XPathExpressionEvaluator;
import net.javacrumbs.springws.test.template.FreeMarkerTemplateProcessor;
import net.javacrumbs.springws.test.template.TemplateProcessor;
import net.javacrumbs.springws.test.template.XsltTemplateProcessor;
import net.javacrumbs.springws.test.util.DefaultXmlUtil;
import net.javacrumbs.springws.test.util.XmlUtil;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapEnvelopeException;
import org.springframework.ws.soap.SoapFault;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.xml.namespace.SimpleNamespaceContext;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
/**
* Contains methods simplifying message validation.
* @author Lukas Krecan
*
*/
public class MessageValidator {
private static final String TRUE = Boolean.TRUE.toString();
private final WebServiceMessage message;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
private TemplateProcessor templateProcessor = new XsltTemplateProcessor();
private SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
private MessageComparator messageComparator = new DefaultMessageComparator();
private SchemaValidator schemaValidator = new SchemaValidator();
private String schemaLanguage = XmlValidatorFactory.SCHEMA_W3C_XML;
private ExpressionEvaluator expressionEvaluator = new XPathExpressionEvaluator();
private XmlUtil xmlUtil = DefaultXmlUtil.getInstance();
public MessageValidator(WebServiceMessage message) {
this.message = message;
}
public MessageValidator compare(String controlResourcePath) {
return compare(getResource(controlResourcePath));
}
public MessageValidator compare(Resource controlResource) {
try {
messageComparator.compareMessage(message, preprocessResource(controlResource));
} catch (IOException e) {
processIOException(e);
}
return this;
}
protected void processIOException(IOException e) {
throw new WsTestException("Error when comparing messages", e);
}
/**
* Validates if the message corresponds to given XSDs.
* @param message
*/
public MessageValidator validate(String schemaPath, String... schemaPaths) throws IOException {
Resource[] schemas = new Resource[schemaPaths.length];
for (int i = 0; i < schemas.length; i++) {
schemas[i] = resourceLoader.getResource(schemaPaths[i]);
}
return validate(resourceLoader.getResource(schemaPath), schemas);
}
/**
* Validates if the message corresponds to given XSD.
* @param message
*/
public MessageValidator validate(Resource schema, Resource... schemas) throws IOException {
Resource[] joinedSchemas = new Resource[schemas.length+1];
joinedSchemas[0] = schema;
System.arraycopy(schemas, 0, joinedSchemas, 1, schemas.length);
validate(schemaValidator.createValidatorFromSchemas(joinedSchemas, schemaLanguage ));
return this;
}
/**
* Validates message using generic {@link XmlValidator}. See {@link XmlValidatorFactory} for more details.
* @param validator
*/
public MessageValidator validate(XmlValidator xmlValidator) {
try {
schemaValidator.validate(message, xmlValidator);
} catch (IOException e) {
processIOException(e);
}
return this;
}
/**
* Sets namespace mapping for all XPath validations like {@link #assertXPath(String)}
* @param namespaceMapping
* @return
*/
public MessageValidator useNamespaceMapping(Map namespaceMapping) {
namespaceContext = new SimpleNamespaceContext();
namespaceContext.setBindings(namespaceMapping);
return this;
}
/**
* Adds mapping between prefix and namespace.
* @param prefix
* @param namespace
* @return
*/
public MessageValidator addNamespaceMapping(String prefix, String namespace)
{
namespaceContext.bindNamespaceUri(prefix, namespace);
return this;
}
/**
* Asserts XPath expression. If the expression is not evaluated to true, throws {@link WsTestException}.
* It is possible to set namespace mapping using {@link #useNamespaceMapping(Map)}.
* @param xpath
* @return
*/
public MessageValidator assertXPath(String xpath) {
return assertXPath(xpath, "Expression \""+xpath+"\" does not evaluate to true.");
}
/**
* Asserts XPath expression. If the expression is not evaluated to true, throws {@link WsTestException}.
* It is possible to set namespace mapping using {@link #useNamespaceMapping(Map)}.
* @param xpath
* @return
*/
public MessageValidator assertXPath(String xpath, String errorMessage) {
if (!TRUE.equals(evaluateExpression(xpath)))
{
throw new WsTestException(errorMessage, message);
}
return this;
}
/**
* Evaluates expression
* @param expression
* @return
*/
protected String evaluateExpression(String expression) {
return expressionEvaluator.evaluateExpression(xmlUtil.loadDocument(message), expression, null, namespaceContext);
}
/**
* Asserts that message is not SOAP fault.
* @return
*/
public MessageValidator assertNotSoapFault() {
if (isSoapFault())
{
throw new WsTestException("Message is SOAP fault", message);
}
return this;
}
/**
* Assert that message is SOAP message (wrapped in SOAP envelope).
*/
public MessageValidator assertSoapMessage() {
SoapMessage soapMessage = getSoapMessage();
try
{
soapMessage.getEnvelope();
}
catch(SoapEnvelopeException e)
{
throw new WsTestException("Message is not a SOAP message",e);
}
return this;
}
/**
* Assert that message is SOAP fault.
*/
public MessageValidator assertSoapFault() {
if (!isSoapFault())
{
throw new WsTestException("Message is not SOAP fault", message);
}
return this;
}
/**
* Returns true if message is SOAP fault.
* @return
*/
protected boolean isSoapFault() {
if (getSoapMessage().hasFault())
{
return true;
}
else
{
return false;
}
}
/**
* Returns soap message.
* @return
*/
public SoapMessage getSoapMessage() {
if (message instanceof SoapMessage)
{
return (SoapMessage)message;
}
else
{
throw new WsTestException("The message is not SOAP message");
}
}
/**
* Returns SOAP fault.
* @return
*/
public SoapFault getSoapFault() {
assertSoapFault();
return getSoapMessage().getSoapBody().getFault();
}
/**
* Compares fault code.
* @param expectedFaultCode
* @return
*/
public MessageValidator assertFaultCode(String expectedFaultCode) {
String faultCode = getSoapFault().getFaultCode().getLocalPart();
if (!expectedFaultCode.equals(faultCode))
{
throw new WsTestException("Expected fault code \""+expectedFaultCode+"\", get \""+faultCode+"\"", message);
}
return this;
}
/**
* Compares fault string or reason. See {@link SoapFault#getFaultStringOrReason()}.
* @param expectedStringOrReason
* @return
*/
public MessageValidator assertFaultStringOrReason(String expectedStringOrReason) {
String faultStringOrReason = getSoapFault().getFaultStringOrReason();
if (!expectedStringOrReason.equals(faultStringOrReason))
{
throw new WsTestException("Expected fault string or reason \""+expectedStringOrReason+"\", get \""+faultStringOrReason+"\"", message);
}
return this;
}
/**
* Compares fault actor or role. See {@link SoapFault#getFaultActorOrRole()}.
* @param expectedActorOrRole
* @return
*/
public MessageValidator assertFaultActorOrRole(String expectedActorOrRole) {
String faultActorOrRole = getSoapFault().getFaultActorOrRole();
if (!expectedActorOrRole.equals(faultActorOrRole))
{
throw new WsTestException("Expected fault actor or role \""+expectedActorOrRole+"\", get \""+faultActorOrRole+"\"", message);
}
return this;
}
/**
* Asserts that the message contains element with given name. Namespace is ignored.
* @param elementName
* @return
*/
public MessageValidator assertContainElement(String elementName) {
return assertXPath("count(//*[local-name()='"+elementName+"'])>0", "Element \""+elementName+"\" not found.");
}
/**
* Asserts that message does not contain given element. Namespace is ignored.
* @param string
* @return
*/
public MessageValidator assertNotContainElement(String elementName) {
return assertXPath("count(//*[local-name()='"+elementName+"'])=0", "Element \""+elementName+"\" found.");
}
/**
* Asserts that the message contains given reqular expression. The message is processed as text, so whitespaces are taken into account
* @param string
* @return
*/
public MessageValidator assertContain(String regexp) {
if (!contains(regexp))
{
throw new WsTestException("Message does not contain regular expression \""+regexp+"\"", message);
}
return this;
}
/**
* Asserts that the message does not contain given reqular expression. The message is processed as text, so whitespaces are taken into account
* @param string
* @return
* @return
*/
public MessageValidator assertNotContain(String regexp) {
if (contains(regexp))
{
throw new WsTestException("Message contains regular expression \""+regexp+"\"", message);
}
return this;
}
/**
* Returns true if message contains regexp.
* @param regexp
* @return
*/
private boolean contains(String regexp) {
String messageAsText = xmlUtil.serializeDocument(message);
Pattern pattern = Pattern.compile(regexp);
return pattern.matcher(messageAsText).find();
}
/**
* Does resource preprocessing. In default implementation just evaluates a template.
* @param resource
* @return
* @throws IOException
*/
protected Resource preprocessResource(Resource resource) throws IOException {
return templateProcessor.processTemplate(resource, null);
}
protected Resource getResource(String resourcePath) {
return resourceLoader.getResource(resourcePath);
}
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public TemplateProcessor getTemplateProcessor() {
return templateProcessor;
}
public void setTemplateProcessor(TemplateProcessor templateProcessor) {
this.templateProcessor = templateProcessor;
}
public MessageValidator useTemplateProcessor(TemplateProcessor templateProcessor) {
setTemplateProcessor(templateProcessor);
return this;
}
/**
* From now on use FreeMarker for templates.
* @return
*/
public MessageValidator useFreeMarkerTemplateProcessor() {
FreeMarkerTemplateProcessor freemarkerTemplateProcessor = new FreeMarkerTemplateProcessor();
freemarkerTemplateProcessor.setResourceLoader(resourceLoader);
freemarkerTemplateProcessor.afterPropertiesSet();
return useTemplateProcessor(freemarkerTemplateProcessor);
}
/**
* From now on use XSLT for templates.
* @return
*/
public MessageValidator useXsltTemplateProcessor() {
return useTemplateProcessor(new XsltTemplateProcessor());
}
public WebServiceMessage getMessage() {
return message;
}
public MessageComparator getMessageComparator() {
return messageComparator;
}
public void setMessageComparator(MessageComparator messageComparator) {
this.messageComparator = messageComparator;
}
public MessageValidator useMessageComparator(MessageComparator messageComparator) {
setMessageComparator(messageComparator);
return this;
}
public SchemaValidator getSchemaValidator() {
return schemaValidator;
}
public void setSchemaValidator(SchemaValidator schemaValidator) {
this.schemaValidator = schemaValidator;
}
public MessageValidator useSchemaValidator(SchemaValidator schemaValidator) {
setSchemaValidator(schemaValidator);
return this;
}
public String getSchemaLanguage() {
return schemaLanguage;
}
public void setSchemaLanguage(String schemaLanguage) {
this.schemaLanguage = schemaLanguage;
}
public MessageValidator useSchemaLanguage(String schemaLanguage) {
setSchemaLanguage(schemaLanguage);
return this;
}
public ExpressionEvaluator getExpressionEvaluator() {
return expressionEvaluator;
}
public void setExpressionEvaluator(ExpressionEvaluator expressionEvaluator) {
this.expressionEvaluator = expressionEvaluator;
}
public MessageValidator useExpressionEvaluator(ExpressionEvaluator expressionEvaluator) {
setExpressionEvaluator(expressionEvaluator);
return this;
}
}