1 /*
2 * $Id$
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 package org.apache.struts.chain.commands;
22
23 import org.apache.struts.chain.contexts.ActionContext;
24 import org.apache.struts.config.ActionConfig;
25 import org.apache.struts.config.ExceptionConfig;
26 import org.apache.struts.config.ForwardConfig;
27 import org.apache.struts.config.ModuleConfig;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32 * <p>Invoke the local or global exception handler configured for the
33 * exception class that occurred.</p>
34 *
35 * @version $Rev$ $Date: 2005-11-12 13:01:44 -0500 (Sat, 12 Nov 2005)
36 * $
37 */
38 public abstract class AbstractExceptionHandler extends ActionCommandBase {
39 // ------------------------------------------------------ Instance Variables
40
41 /**
42 * The {@code Log} instance for this class.
43 */
44 private final Logger log =
45 LoggerFactory.getLogger(AbstractExceptionHandler.class);
46
47 // ---------------------------------------------------------- Public Methods
48
49 /**
50 * <p>Invoke the appropriate <code>Action</code> for this request, and
51 * cache the returned <code>ActionForward</code>.</p>
52 *
53 * @param actionCtx The <code>Context</code> for the current request
54 * @return <code>false</code> if a <code>ForwardConfig</code> is returned,
55 * else <code>true</code> to complete processing
56 * @throws Exception if thrown by the Action class and not declared by an
57 * Exception Handler
58 */
59 @Override
60 protected boolean execute_(ActionContext actionCtx)
61 throws Exception {
62 // Look up the exception that was thrown
63 Exception exception = actionCtx.getException();
64
65 if (exception == null) {
66 log.warn("No Exception found in ActionContext");
67
68 return PROCESSING_COMPLETE;
69 }
70
71 // Look up the local or global exception handler configuration
72 ExceptionConfig exceptionConfig = null;
73 ActionConfig actionConfig = actionCtx.getActionConfig();
74 ModuleConfig moduleConfig = actionCtx.getModuleConfig();
75
76 if (actionConfig != null) {
77 log.debug("See if actionConfig {} has an exceptionConfig for {}",
78 actionConfig, exception.getClass().getName());
79
80 exceptionConfig = actionConfig.findException(exception.getClass());
81 } else if (moduleConfig != null) {
82 log.debug("No action yet, see if moduleConfig {} has an exceptionConfig {}",
83 moduleConfig, exception.getClass().getName());
84
85 exceptionConfig = moduleConfig.findException(exception.getClass());
86 }
87
88 // Handle the exception in the configured manner
89 if (exceptionConfig == null) {
90 log.warn("Unhandled exception", exception);
91 throw exception;
92 }
93
94 ForwardConfig forwardConfig =
95 handle(actionCtx, exception, exceptionConfig, actionConfig,
96 moduleConfig);
97
98 if (forwardConfig != null) {
99 actionCtx.setForwardConfig(forwardConfig);
100
101 return CONTINUE_PROCESSING;
102 } else {
103 return PROCESSING_COMPLETE;
104 }
105 }
106
107 // ------------------------------------------------------- Protected Methods
108
109 /**
110 * <p>Perform the required handling of the specified exception.</p>
111 *
112 * @param context The <code>Context</code> for this request
113 * @param exception The exception being handled
114 * @param exceptionConfig The corresponding {@link ExceptionConfig}
115 * @param actionConfig The {@link ActionConfig} for this request
116 * @param moduleConfig The {@link ModuleConfig} for this request
117 * @return the <code>ForwardConfig</code> to be processed next (if any),
118 * or <code>null</code> if processing has been completed
119 * @throws Exception if there are any problems handling the exception
120 */
121 protected abstract ForwardConfig handle(ActionContext context,
122 Exception exception, ExceptionConfig exceptionConfig,
123 ActionConfig actionConfig, ModuleConfig moduleConfig)
124 throws Exception;
125 }