1 /*
2 * Copyright 2005-2010 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.server.endpoint;
18
19 import java.util.Set;
20
21 import org.springframework.core.Ordered;
22 import org.springframework.ws.context.MessageContext;
23 import org.springframework.ws.server.EndpointExceptionResolver;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /**
29 * Abstract base class for {@link EndpointExceptionResolver EndpointExceptionResolvers}.
30 * <p/>
31 * <p>Provides a set of mapped endpoints that the resolver should map.
32 *
33 * @author Arjen Poutsma
34 * @author Tareq Abed Rabbo
35 * @since 1.0.0
36 */
37 public abstract class AbstractEndpointExceptionResolver implements EndpointExceptionResolver, Ordered {
38
39 /** Shared {@link Log} for subclasses to use. */
40 protected final Log logger = LogFactory.getLog(getClass());
41
42 private int order = Integer.MAX_VALUE; // default: same as non-Ordered
43
44 private Set<?> mappedEndpoints;
45
46 private Log warnLogger;
47
48 /**
49 * Specify the set of endpoints that this exception resolver should map. <p>The exception mappings and the default
50 * fault will only apply to the specified endpoints.
51 * <p/>
52 * If no endpoints are set, both the exception mappings and the default fault will apply to all handlers. This means
53 * that a specified default fault will be used as fallback for all exceptions; any further
54 * <code>EndpointExceptionResolvers</code> in the chain will be ignored in this case.
55 */
56 public void setMappedEndpoints(Set<?> mappedEndpoints) {
57 this.mappedEndpoints = mappedEndpoints;
58 }
59
60 /**
61 * Set the log category for warn logging. The name will be passed to the underlying logger implementation through
62 * Commons Logging, getting interpreted as log category according to the logger's configuration.
63 * <p/>
64 * Default is no warn logging. Specify this setting to activate warn logging into a specific category.
65 * Alternatively, override the {@link #logException} method for custom logging.
66 *
67 * @see org.apache.commons.logging.LogFactory#getLog(String)
68 * @see org.apache.log4j.Logger#getLogger(String)
69 * @see java.util.logging.Logger#getLogger(String)
70 */
71 public void setWarnLogCategory(String loggerName) {
72 this.warnLogger = LogFactory.getLog(loggerName);
73 }
74
75 /**
76 * Specify the order value for this mapping.
77 * <p/>
78 * Default value is {@link Integer#MAX_VALUE}, meaning that it's non-ordered.
79 *
80 * @see org.springframework.core.Ordered#getOrder()
81 */
82 public final void setOrder(int order) {
83 this.order = order;
84 }
85
86 public final int getOrder() {
87 return order;
88 }
89
90 /**
91 * Default implementation that checks whether the given <code>endpoint</code> is in the set of {@link
92 * #setMappedEndpoints mapped endpoints}.
93 *
94 * @see #resolveExceptionInternal(MessageContext,Object,Exception)
95 */
96 public final boolean resolveException(MessageContext messageContext, Object endpoint, Exception ex) {
97 Object mappedEndpoint = endpoint instanceof MethodEndpoint ? ((MethodEndpoint) endpoint).getBean() : endpoint;
98 if (mappedEndpoints != null && !mappedEndpoints.contains(mappedEndpoint)) {
99 return false;
100 }
101 // Log exception, both at debug log level and at warn level, if desired.
102 if (logger.isDebugEnabled()) {
103 logger.debug("Resolving exception from endpoint [" + endpoint + "]: " + ex);
104 }
105 logException(ex, messageContext);
106 return resolveExceptionInternal(messageContext, endpoint, ex);
107 }
108
109 /**
110 * Log the given exception at warn level, provided that warn logging has been activated through the {@link
111 * #setWarnLogCategory "warnLogCategory"} property.
112 * <p/>
113 * Calls {@link #buildLogMessage} in order to determine the concrete message to log. Always passes the full
114 * exception to the logger.
115 *
116 * @param ex the exception that got thrown during handler execution
117 * @param messageContext current message context request
118 * @see #setWarnLogCategory
119 * @see #buildLogMessage
120 * @see org.apache.commons.logging.Log#warn(Object, Throwable)
121 */
122 protected void logException(Exception ex, MessageContext messageContext) {
123 if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) {
124 this.warnLogger.warn(buildLogMessage(ex, messageContext), ex);
125 }
126 }
127
128 /**
129 * Build a log message for the given exception, occured during processing the given message context.
130 *
131 * @param ex the exception that got thrown during handler execution
132 * @param messageContext the message context
133 * @return the log message to use
134 */
135 protected String buildLogMessage(Exception ex, MessageContext messageContext) {
136 return "Endpoint execution resulted in exception";
137 }
138
139 /**
140 * Template method for resolving exceptions that is called by {@link #resolveException}.
141 *
142 * @param messageContext current message context
143 * @param endpoint the executed endpoint, or <code>null</code> if none chosen at the time of the exception
144 * @param ex the exception that got thrown during endpoint execution
145 * @return <code>true</code> if resolved; <code>false</code> otherwise
146 * @see #resolveException(MessageContext,Object,Exception)
147 */
148 protected abstract boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception ex);
149
150 }