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