diff --git a/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/AbstractSoap11Wsdl4jDefinitionBuilder.java b/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/AbstractSoap11Wsdl4jDefinitionBuilder.java index 810b33b1..85978b05 100644 --- a/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/AbstractSoap11Wsdl4jDefinitionBuilder.java +++ b/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/AbstractSoap11Wsdl4jDefinitionBuilder.java @@ -33,6 +33,7 @@ import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; +import javax.wsdl.extensions.soap.SOAPFault; import javax.wsdl.extensions.soap.SOAPOperation; import javax.xml.namespace.QName; @@ -180,9 +181,9 @@ public abstract class AbstractSoap11Wsdl4jDefinitionBuilder extends AbstractBind */ protected void populateBindingFault(BindingFault bindingFault, Fault fault) throws WSDLException { super.populateBindingFault(bindingFault, fault); - SOAPBody soapBody = (SOAPBody) createSoapExtension(BindingOutput.class, "body"); - populateSoapBody(soapBody); - bindingFault.addExtensibilityElement(soapBody); + SOAPFault soapFault = (SOAPFault) createSoapExtension(BindingFault.class, "fault"); + populateSoapFault(bindingFault, soapFault); + bindingFault.addExtensibilityElement(soapFault); } /** @@ -197,6 +198,20 @@ public abstract class AbstractSoap11Wsdl4jDefinitionBuilder extends AbstractBind soapBody.setUse("literal"); } + /** + * Called after the SOAPFault has been created. Default implementation sets the use style to + * "literal", and sets the name equal to the binding fault. Subclasses can override this behavior. + * + * @param bindingFault the WSDL4J BindingFault + * @param soapFault the WSDL4J SOAPFault + * @throws WSDLException in case of errors + * @see javax.wsdl.extensions.soap.SOAPBody#setUse(String) + */ + protected void populateSoapFault(BindingFault bindingFault, SOAPFault soapFault) throws WSDLException { + soapFault.setName(bindingFault.getName()); + soapFault.setUse("literal"); + } + /** * Creates a SOAPAddress, and calls populateSoapAddress(). * diff --git a/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/XsdBasedSoap11Wsdl4jDefinitionBuilder.java b/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/XsdBasedSoap11Wsdl4jDefinitionBuilder.java index 95e7b902..d1883a8f 100644 --- a/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/XsdBasedSoap11Wsdl4jDefinitionBuilder.java +++ b/core/src/main/java/org/springframework/ws/wsdl/wsdl11/builder/XsdBasedSoap11Wsdl4jDefinitionBuilder.java @@ -19,9 +19,11 @@ package org.springframework.ws.wsdl.wsdl11.builder; import java.io.IOException; import java.util.Iterator; import javax.wsdl.Definition; +import javax.wsdl.Fault; import javax.wsdl.Input; import javax.wsdl.Message; import javax.wsdl.Operation; +import javax.wsdl.OperationType; import javax.wsdl.Output; import javax.wsdl.Part; import javax.wsdl.PortType; @@ -71,6 +73,9 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD /** The default suffix used to detect response elements in the schema. */ public static final String DEFAULT_RESPONSE_SUFFIX = "Response"; + /** The default suffix used to detect fault elements in the schema. */ + public static final String DEFAULT_FAULT_SUFFIX = "Fault"; + /** The default prefix used to register the schema namespace in the WSDL. */ public static final String DEFAULT_SCHEMA_PREFIX = "schema"; @@ -96,6 +101,8 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD private String responseSuffix = DEFAULT_RESPONSE_SUFFIX; + private String faultSuffix = DEFAULT_FAULT_SUFFIX; + /** * Sets the suffix used to detect request elements in the schema. * @@ -114,6 +121,15 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD this.responseSuffix = responseSuffix; } + /** + * Sets the suffix used to detect fault elements in the schema. + * + * @see #DEFAULT_FAULT_SUFFIX + */ + public void setFaultSuffix(String faultSuffix) { + this.faultSuffix = faultSuffix; + } + /** Sets the port type name used for this definition. Required. */ public void setPortTypeName(String portTypeName) { this.portTypeName = portTypeName; @@ -207,20 +223,22 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD } /** - * Creates messages for each element found in the schema for which isRequestMessage() or - * isResponseMessage() is true. + * Creates messages for each element found in the schema for which isRequestMessage(), + * isResponseMessage(), or isFaultMessage() is true. * * @param definition the WSDL4J Definition * @throws WSDLException in case of errors * @see #isRequestMessage(javax.xml.namespace.QName) * @see #isResponseMessage(javax.xml.namespace.QName) + * @see #isFaultMessage(javax.xml.namespace.QName) */ protected void buildMessages(Definition definition) throws WSDLException { NodeList elements = schemaElement.getElementsByTagNameNS(SCHEMA_NAMESPACE_URI, "element"); for (int i = 0; i < elements.getLength(); i++) { Element element = (Element) elements.item(i); QName elementName = getSchemaElementName(element); - if (elementName != null && (isRequestMessage(elementName) || isResponseMessage(elementName))) { + if (elementName != null && + (isRequestMessage(elementName) || isResponseMessage(elementName) || isFaultMessage(elementName))) { Message message = definition.createMessage(); populateMessage(message, element); Part part = definition.createPart(); @@ -256,6 +274,18 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD return name.getLocalPart().endsWith(responseSuffix); } + /** + * Indicates whether the given name should be included as Message in the definition. Default + * implementation checks whether the local part ends with the fault suffix. + * + * @param name the name of the element elligable for being a message + * @return true if to be included as message; false otherwise + * @see #setFaultSuffix(String) + */ + protected boolean isFaultMessage(QName name) { + return name.getLocalPart().endsWith(faultSuffix); + } + /** * Called after the Message has been created. *

@@ -305,19 +335,22 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD portType.setQName(new QName(targetNamespace, portTypeName)); } + /** @noinspection UnnecessaryLocalVariable */ private void createOperations(Definition definition, PortType portType) throws WSDLException { for (Iterator messageIterator = definition.getMessages().values().iterator(); messageIterator.hasNext();) { Message message = (Message) messageIterator.next(); for (Iterator partIterator = message.getParts().values().iterator(); partIterator.hasNext();) { Part part = (Part) partIterator.next(); if (isRequestMessage(part.getElementName())) { - Message responseMessage = definition.getMessage(getResponseMessageName(message.getQName())); + Message requestMessage = message; + Message responseMessage = definition.getMessage(getResponseMessageName(requestMessage.getQName())); + Message faultMessage = definition.getMessage(getFaultMessageName(requestMessage.getQName())); Operation operation = definition.createOperation(); - populateOperation(operation, message, responseMessage); - if (message != null) { + populateOperation(operation, requestMessage, responseMessage); + if (requestMessage != null) { Input input = definition.createInput(); - input.setMessage(message); - input.setName(message.getQName().getLocalPart()); + input.setMessage(requestMessage); + input.setName(requestMessage.getQName().getLocalPart()); operation.setInput(input); } if (responseMessage != null) { @@ -326,6 +359,21 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD output.setName(responseMessage.getQName().getLocalPart()); operation.setOutput(output); } + if (faultMessage != null) { + Fault fault = definition.createFault(); + fault.setMessage(faultMessage); + fault.setName(faultMessage.getQName().getLocalPart()); + operation.addFault(fault); + } + if (requestMessage != null && responseMessage != null) { + operation.setStyle(OperationType.REQUEST_RESPONSE); + } + else if (requestMessage != null && responseMessage == null) { + operation.setStyle(OperationType.ONE_WAY); + } + else if (requestMessage == null && responseMessage != null) { + operation.setStyle(OperationType.NOTIFICATION); + } operation.setUndefined(false); portType.addOperation(operation); } @@ -352,6 +400,25 @@ public class XsdBasedSoap11Wsdl4jDefinitionBuilder extends AbstractSoap11Wsdl4jD } } + /** + * Given an request message name, return the corresponding fault message name. + *

+ * Default implementation removes the request suffix, and appends the fault suffix. + * + * @param requestMessageName the name of the request message + * @return the name of the corresponding response message, or null + */ + protected QName getFaultMessageName(QName requestMessageName) { + String localPart = requestMessageName.getLocalPart(); + if (localPart.endsWith(requestSuffix)) { + String prefix = localPart.substring(0, localPart.length() - requestSuffix.length()); + return new QName(requestMessageName.getNamespaceURI(), prefix + faultSuffix); + } + else { + return null; + } + } + /** * Called after the Operation has been created. *

diff --git a/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/expected.wsdl b/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/expected.wsdl index d15fbb70..8ffe9377 100644 --- a/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/expected.wsdl +++ b/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/expected.wsdl @@ -29,6 +29,14 @@ + + + + + + + + @@ -123,47 +131,39 @@ - - + - - + - - + + + + - - + - - + - - + - - - - + + + - - - - + + - - - - + + @@ -176,6 +176,9 @@ + + + diff --git a/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/schema.xsd b/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/schema.xsd index 2a9dddc1..fdc4d9a8 100644 --- a/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/schema.xsd +++ b/core/src/test/resources/org/springframework/ws/wsdl/wsdl11/builder/schema.xsd @@ -23,6 +23,14 @@ + + + + + + + + diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 1d8cbb81..2ab3faac 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -6,6 +6,7 @@ + Add faults into dynamically created WSDL Added MethodEndpoint functionality, invoking methods for incoming requests