/*
* Copyright 2005-2014 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.server.endpoint;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.Ordered;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointExceptionResolver;
/**
* Abstract base class for {@link EndpointExceptionResolver EndpointExceptionResolvers}.
*
* <p>Provides a set of mapped endpoints that the resolver should map.
*
* @author Arjen Poutsma
* @author Tareq Abed Rabbo
* @since 1.0.0
*/
public abstract class AbstractEndpointExceptionResolver implements EndpointExceptionResolver, Ordered {
/** Shared {@link Log} for subclasses to use. */
protected final Log logger = LogFactory.getLog(getClass());
private int order = Integer.MAX_VALUE; // default: same as non-Ordered
private Set<?> mappedEndpoints;
private Log warnLogger;
/**
* Specify the set of endpoints that this exception resolver should map. <p>The exception mappings and the default
* fault will only apply to the specified endpoints.
*
* <p>If no endpoints are set, both the exception mappings and the default fault will apply to all handlers. This means
* that a specified default fault will be used as fallback for all exceptions; any further
* {@code EndpointExceptionResolvers} in the chain will be ignored in this case.
*/
public void setMappedEndpoints(Set<?> mappedEndpoints) {
this.mappedEndpoints = mappedEndpoints;
}
/**
* Set the log category for warn logging. The name will be passed to the underlying logger implementation through
* Commons Logging, getting interpreted as log category according to the logger's configuration.
*
* <p>Default is no warn logging. Specify this setting to activate warn logging into a specific category.
* Alternatively, override the {@link #logException} method for custom logging.
*
* @see org.apache.commons.logging.LogFactory#getLog(String)
* @see org.apache.log4j.Logger#getLogger(String)
* @see java.util.logging.Logger#getLogger(String)
*/
public void setWarnLogCategory(String loggerName) {
this.warnLogger = LogFactory.getLog(loggerName);
}
/**
* Specify the order value for this mapping.
*
* <p>Default value is {@link Integer#MAX_VALUE}, meaning that it's non-ordered.
*
* @see org.springframework.core.Ordered#getOrder()
*/
public final void setOrder(int order) {
this.order = order;
}
@Override
public final int getOrder() {
return order;
}
/**
* Default implementation that checks whether the given {@code endpoint} is in the set of {@link
* #setMappedEndpoints mapped endpoints}.
*
* @see #resolveExceptionInternal(MessageContext,Object,Exception)
*/
@Override
public final boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex) {
Object mappedEndpoint = endpoint instanceof MethodEndpoint ? ((MethodEndpoint) endpoint).getBean() : endpoint;
if (mappedEndpoints != null && !mappedEndpoints.contains(mappedEndpoint)) {
return false;
}
// Log exception, both at debug log level and at warn level, if desired.
if (logger.isDebugEnabled()) {
logger.debug("Resolving exception from endpoint [" + endpoint + "]: " + ex);
}
logException(ex, messageContext);
return resolveExceptionInternal(messageContext, endpoint, ex);
}
/**
* Log the given exception at warn level, provided that warn logging has been activated through the {@link
* #setWarnLogCategory "warnLogCategory"} property.
*
* <p>Calls {@link #buildLogMessage} in order to determine the concrete message to log. Always passes the full
* exception to the logger.
*
* @param ex the exception that got thrown during handler execution
* @param messageContext current message context request
* @see #setWarnLogCategory
* @see #buildLogMessage
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
protected void logException(Exception ex, MessageContext messageContext) {
if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) {
this.warnLogger.warn(buildLogMessage(ex, messageContext), ex);
}
}
/**
* Build a log message for the given exception, occured during processing the given message context.
*
* @param ex the exception that got thrown during handler execution
* @param messageContext the message context
* @return the log message to use
*/
protected String buildLogMessage(Exception ex, MessageContext messageContext) {
return "Endpoint execution resulted in exception";
}
/**
* Template method for resolving exceptions that is called by {@link #resolveException}.
*
* @param messageContext current message context
* @param endpoint the executed endpoint, or {@code null} if none chosen at the time of the exception
* @param ex the exception that got thrown during endpoint execution
* @return {@code true} if resolved; {@code false} otherwise
* @see #resolveException(MessageContext,Object,Exception)
*/
protected abstract boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception ex);
}