1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.struts.flow.core;
17
18 import java.util.List;
19
20 import org.apache.struts.flow.core.location.LocatedException;
21 import org.apache.struts.flow.core.location.LocatedRuntimeException;
22 import org.apache.struts.flow.core.location.Location;
23 import org.apache.struts.flow.core.location.MultiLocatable;
24
25 /***
26 * This Exception is thrown every time there is a problem in processing
27 * a request.
28 *
29 * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
30 * (Apache Software Foundation)
31 * @version CVS $Id: FlowException.java 280632 2005-09-13 19:35:46Z sylvain $
32 */
33 public class FlowException extends LocatedRuntimeException implements MultiLocatable {
34
35 /***
36 * Construct a new <code>FlowException</code> instance.
37 */
38 public FlowException(String message) {
39 super(message);
40 }
41
42 /***
43 * Creates a new <code>FlowException</code> instance.
44 *
45 * @param ex an <code>Exception</code> value
46 */
47 public FlowException(Exception ex) {
48 super(ex.getMessage(), ex);
49 }
50
51 /***
52 * Construct a new <code>FlowException</code> that references
53 * a parent Exception.
54 */
55 public FlowException(String message, Throwable t) {
56 super(message, t);
57 }
58
59 /***
60 * Construct a new <code>FlowException</code> that has an associated location.
61 */
62 public FlowException(String message, Location location) {
63 super(message, location);
64 }
65
66 /***
67 * Construct a new <code>FlowException</code> that has a parent exception
68 * and an associated location.
69 * <p>
70 * This constructor is protected to enforce the use of {@link #throwLocated(String, Throwable, Location)}
71 * which limits exception nesting as far as possible.
72 */
73 protected FlowException(String message, Throwable t, Location location) {
74 super(message, t, location);
75 }
76
77 /***
78 * Throw a located exception given an existing exception and the location where
79 * this exception was catched.
80 * <p>
81 * If the exception is already a <code>FlowException</code> or a {@link LocatedRuntimeException},
82 * the location is added to the original exception's location chain and the original exception
83 * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
84 * <code>FlowException</code> is thrown, wrapping the original exception.
85 * <p>
86 * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
87 * semantics in the caller code, i.e. write<br>
88 * <code> throw FlowException.throwLocated(...);</code><br>
89 * instead of<br>
90 * <code> FlowException.throwLocated(...);</code><br>
91 * <code> return;</code>
92 *
93 * @param message a message (can be <code>null</code>)
94 * @param thr the original exception (can be <code>null</code>)
95 * @param location the location (can be <code>null</code>)
96 * @return a (fake) located exception
97 * @throws FlowException or <code>LocatedRuntimeException</code>
98 */
99 public static FlowException throwLocated(String message, Throwable thr, Location location) throws FlowException {
100 if (thr instanceof FlowException) {
101 FlowException pe = (FlowException)thr;
102 pe.addLocation(location);
103 throw pe;
104
105 } else if (thr instanceof LocatedRuntimeException) {
106 LocatedRuntimeException re = (LocatedRuntimeException)thr;
107 re.addLocation(location);
108
109 throw re;
110 }
111
112 throw new FlowException(message, thr, location);
113 }
114
115 /***
116 * Throw a located exception given an existing exception and the locations where
117 * this exception was catched.
118 * <p>
119 * If the exception is already a <code>FlowException</code> or a {@link LocatedRuntimeException},
120 * the locations are added to the original exception's location chain and the original exception
121 * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
122 * <code>FlowException</code> is thrown, wrapping the original exception.
123 * <p>
124 * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
125 * semantics in the caller code, i.e. write<br>
126 * <code> throw FlowException.throwLocated(...);</code><br>
127 * instead of<br>
128 * <code> FlowException.throwLocated(...);</code><br>
129 * <code> return;</code>
130 *
131 * @param message a message (can be <code>null</code>)
132 * @param thr the original exception (can be <code>null</code>)
133 * @param locations the locations (can be <code>null</code>)
134 * @return a (fake) located exception
135 * @throws FlowException or <code>LocatedRuntimeException</code>
136 */
137 public static FlowException throwLocated(String message, Throwable thr, List locations) throws FlowException {
138 MultiLocatable multiloc;
139 if (thr instanceof FlowException) {
140 multiloc = (FlowException)thr;
141 } else if (thr instanceof LocatedRuntimeException) {
142 multiloc = (LocatedRuntimeException)thr;
143 } else {
144 multiloc = new FlowException(message, thr);
145 }
146
147 if (locations != null) {
148 for (int i = 0; i < locations.size(); i++) {
149 multiloc.addLocation((Location)locations.get(i));
150 }
151 }
152
153 if (multiloc instanceof LocatedRuntimeException) {
154 throw (LocatedRuntimeException)multiloc;
155 } else {
156 throw (FlowException)multiloc;
157 }
158 }
159 }