1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts.chain.commands;
22
23 import org.apache.commons.chain.Catalog;
24 import org.apache.commons.chain.CatalogFactory;
25 import org.apache.commons.chain.Command;
26 import org.apache.commons.chain.Context;
27 import org.apache.commons.chain.Filter;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.struts.chain.contexts.ActionContext;
31
32 /**
33 * <p>Intercept any exception thrown by a subsequent <code>Command</code> in
34 * this processing chain, and fire the configured exception handler chain
35 * after storing the exception that has occurred into the
36 * <code>Context</code>. </p>
37 *
38 * @version $Rev: 471754 $ $Date: 2005-11-12 13:01:44 -0500 (Sat, 12 Nov 2005)
39 * $
40 */
41 public class ExceptionCatcher extends ActionCommandBase implements Filter {
42 /**
43 * <p> Provide Commons Logging instance for this class. </p>
44 */
45 private static final Log LOG = LogFactory.getLog(ExceptionCatcher.class);
46
47
48
49 /**
50 * <p> Field for CatalogName property. </p>
51 */
52 private String catalogName = null;
53
54 /**
55 * <p> Field for ExceptionCommand property. </p>
56 */
57 private String exceptionCommand = null;
58
59
60
61 /**
62 * <p> Return the name of the <code>Catalog</code> in which to perform
63 * lookups, or <code>null</code> for the default <code>Catalog</code>.
64 * </p>
65 *
66 * @return Name of catalog to use, or null
67 */
68 public String getCatalogName() {
69 return (this.catalogName);
70 }
71
72 /**
73 * <p>Set the name of the <code>Catalog</code> in which to perform
74 * lookups, or <code>null</code> for the default <code>Catalog</code>.</p>
75 *
76 * @param catalogName The new catalog name or <code>null</code>
77 */
78 public void setCatalogName(String catalogName) {
79 this.catalogName = catalogName;
80 }
81
82 /**
83 * <p> Return the name of the command to be executed if an exception
84 * occurs. </p>
85 *
86 * @return The name of the command to be executed on an exception
87 */
88 public String getExceptionCommand() {
89 return (this.exceptionCommand);
90 }
91
92 /**
93 * <p>Set the name of the command to be executed if an exception
94 * occurs.</p>
95 *
96 * @param exceptionCommand The name of the chain to be executed
97 */
98 public void setExceptionCommand(String exceptionCommand) {
99 this.exceptionCommand = exceptionCommand;
100 }
101
102
103
104 /**
105 * <p>Clear any existing stored exception and pass the
106 * <code>context</code> on to the remainder of the current chain.</p>
107 *
108 * @param actionCtx The <code>Context</code> for the current request
109 * @return <code>false</code> so that processing continues
110 * @throws Exception On any error
111 */
112 public boolean execute(ActionContext actionCtx)
113 throws Exception {
114 actionCtx.setException(null);
115
116 return (false);
117 }
118
119 /**
120 * <p>If an exception was thrown by a subsequent <code>Command</code>,
121 * pass it on to the specified exception handling chain. Otherwise, do
122 * nothing.</p>
123 *
124 * @param context The {@link Context} to be processed by this {@link
125 * Filter}
126 * @param exception The <code>Exception</code> (if any) that was thrown by
127 * the last {@link Command} that was executed; otherwise
128 * <code>null</code>
129 * @return TRUE if post processing an exception occurred and the exception
130 * processing chain invoked
131 * @throws IllegalStateException If exception throws exception
132 */
133 public boolean postprocess(Context context, Exception exception) {
134
135 if (exception == null) {
136 return (false);
137 }
138
139
140 if (LOG.isDebugEnabled()) {
141 LOG.debug("Attempting to handle a thrown exception");
142 }
143
144 ActionContext actionCtx = (ActionContext) context;
145
146 actionCtx.setException(exception);
147
148
149 try {
150 Command command = lookupExceptionCommand();
151
152 if (command == null) {
153 LOG.error("Cannot find exceptionCommand '" + exceptionCommand
154 + "'");
155 throw new IllegalStateException(
156 "Cannot find exceptionCommand '" + exceptionCommand + "'");
157 }
158
159 if (LOG.isTraceEnabled()) {
160 LOG.trace("Calling exceptionCommand '" + exceptionCommand + "'");
161 }
162
163 command.execute(context);
164 } catch (Exception e) {
165 LOG.warn("Exception from exceptionCommand '" + exceptionCommand
166 + "'", e);
167 throw new IllegalStateException("Exception chain threw exception");
168 }
169
170 return (true);
171 }
172
173 /**
174 * <p> Return the command to be executed if an exception occurs. </p>
175 *
176 * @return The command to be executed if an exception occurs
177 * @throws IllegalArgumentException If catalog cannot be found
178 * @throws IllegalStateException If command property is not specified
179 */
180 protected Command lookupExceptionCommand() {
181 String catalogName = getCatalogName();
182 Catalog catalog;
183
184 if (catalogName == null) {
185 catalog = CatalogFactory.getInstance().getCatalog();
186
187 if (catalog == null) {
188 LOG.error("Cannot find default catalog");
189 throw new IllegalArgumentException(
190 "Cannot find default catalog");
191 }
192 } else {
193 catalog = CatalogFactory.getInstance().getCatalog(catalogName);
194
195 if (catalog == null) {
196 LOG.error("Cannot find catalog '" + catalogName + "'");
197 throw new IllegalArgumentException("Cannot find catalog '"
198 + catalogName + "'");
199 }
200 }
201
202 String exceptionCommand = getExceptionCommand();
203
204 if (exceptionCommand == null) {
205 LOG.error("No exceptionCommand property specified");
206 throw new IllegalStateException(
207 "No exceptionCommand property specfied");
208 }
209
210 return catalog.getCommand(exceptionCommand);
211 }
212 }