View Javadoc

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 }