001: /*
002: * Copyright 2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.ws.soap.server.endpoint;
018:
019: import org.springframework.util.Assert;
020: import org.springframework.util.StringUtils;
021: import org.springframework.ws.context.MessageContext;
022: import org.springframework.ws.server.EndpointExceptionResolver;
023: import org.springframework.ws.server.endpoint.AbstractEndpointExceptionResolver;
024: import org.springframework.ws.soap.SoapBody;
025: import org.springframework.ws.soap.SoapFault;
026: import org.springframework.ws.soap.SoapMessage;
027: import org.springframework.ws.soap.soap11.Soap11Body;
028:
029: /**
030: * Abstract base class for SOAP-based {@link EndpointExceptionResolver} implementations that depend on {@link
031: * SoapFaultDefinition}. Provides a default endpoint property, and a template method that provides the definition for a
032: * given exception.
033: *
034: * @author Arjen Poutsma
035: * @see #setDefaultFault(SoapFaultDefinition)
036: * @see #getFaultDefinition(Object,Exception)
037: * @since 1.0.0
038: */
039: public abstract class AbstractSoapFaultDefinitionExceptionResolver
040: extends AbstractEndpointExceptionResolver {
041:
042: private SoapFaultDefinition defaultFault;
043:
044: /** Set the default fault. This fault will be returned if no specific mapping was found. */
045: public void setDefaultFault(SoapFaultDefinition defaultFault) {
046: this .defaultFault = defaultFault;
047: }
048:
049: /**
050: * Template method that returns the {@link SoapFaultDefinition} for the given exception.
051: *
052: * @param endpoint the executed endpoint, or <code>null</code> if none chosen at the time of the exception
053: * @param ex the exception to be handled
054: * @return the definition mapped to the exception, or <code>null</code> if none is found.
055: */
056: protected abstract SoapFaultDefinition getFaultDefinition(
057: Object endpoint, Exception ex);
058:
059: protected final boolean resolveExceptionInternal(
060: MessageContext messageContext, Object endpoint, Exception ex) {
061: Assert
062: .isTrue(
063: messageContext.getResponse() instanceof SoapMessage,
064: "AbstractSoapFaultDefinitionExceptionResolver requires a SoapMessage");
065:
066: SoapFaultDefinition definition = getFaultDefinition(endpoint,
067: ex);
068: if (definition == null) {
069: definition = defaultFault;
070: }
071: if (definition == null) {
072: return false;
073: }
074: if (!StringUtils.hasLength(definition.getFaultStringOrReason())) {
075: definition.setFaultStringOrReason(ex.getMessage());
076: }
077: SoapBody soapBody = ((SoapMessage) messageContext.getResponse())
078: .getSoapBody();
079: SoapFault fault = null;
080:
081: if (SoapFaultDefinition.SERVER
082: .equals(definition.getFaultCode())
083: || SoapFaultDefinition.RECEIVER.equals(definition
084: .getFaultCode())) {
085: fault = soapBody.addServerOrReceiverFault(definition
086: .getFaultStringOrReason(), definition.getLocale());
087: } else if (SoapFaultDefinition.CLIENT.equals(definition
088: .getFaultCode())
089: || SoapFaultDefinition.SENDER.equals(definition
090: .getFaultCode())) {
091: fault = soapBody.addClientOrSenderFault(definition
092: .getFaultStringOrReason(), definition.getLocale());
093: } else {
094: // custom code, only supported for SOAP 1.1
095: if (soapBody instanceof Soap11Body) {
096: Soap11Body soap11Body = (Soap11Body) soapBody;
097: fault = soap11Body.addFault(definition.getFaultCode(),
098: definition.getFaultStringOrReason(), definition
099: .getLocale());
100: } else {
101: logger
102: .warn("SOAP 1.2 does not allow custom FaultCodes, only SENDER or RECEIVER.");
103: }
104: }
105: if (fault != null) {
106: customizeFault(endpoint, ex, fault);
107: }
108: return true;
109: }
110:
111: /**
112: * Customize the {@link SoapFault} created by this resolver. Called for each created fault
113: * <p/>
114: * The default implementation is empty. Can be overridden in subclasses to customize the properties of the fault,
115: * such as adding details, etc.
116: *
117: * @param endpoint the executed endpoint, or <code>null</code> if none chosen at the time of the exception
118: * @param ex the exception to be handled
119: * @param fault the created fault
120: */
121: protected void customizeFault(Object endpoint, Exception ex,
122: SoapFault fault) {
123: }
124:
125: }
|