1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.chain.impl;
17
18
19 import java.util.Collection;
20 import java.util.Iterator;
21 import org.apache.commons.chain.Chain;
22 import org.apache.commons.chain.Command;
23 import org.apache.commons.chain.Context;
24 import org.apache.commons.chain.Filter;
25
26
27 /***
28 * <p>Convenience base class for {@link Chain} implementations.</p>
29 *
30 * @author Craig R. McClanahan
31 * @version $Revision: 411876 $ $Date: 2006-06-05 19:02:19 +0100 (Mon, 05 Jun 2006) $
32 */
33
34 public class ChainBase implements Chain {
35
36
37
38
39
40 /***
41 * <p>Construct a {@link Chain} with no configured {@link Command}s.</p>
42 */
43 public ChainBase() {
44
45 }
46
47
48 /***
49 * <p>Construct a {@link Chain} configured with the specified
50 * {@link Command}.</p>
51 *
52 * @param command The {@link Command} to be configured
53 *
54 * @exception IllegalArgumentException if <code>command</code>
55 * is <code>null</code>
56 */
57 public ChainBase(Command command) {
58
59 addCommand(command);
60
61 }
62
63
64 /***
65 * <p>Construct a {@link Chain} configured with the specified
66 * {@link Command}s.</p>
67 *
68 * @param commands The {@link Command}s to be configured
69 *
70 * @exception IllegalArgumentException if <code>commands</code>,
71 * or one of the individual {@link Command} elements,
72 * is <code>null</code>
73 */
74 public ChainBase(Command[] commands) {
75
76 if (commands == null) {
77 throw new IllegalArgumentException();
78 }
79 for (int i = 0; i < commands.length; i++) {
80 addCommand(commands[i]);
81 }
82
83 }
84
85
86 /***
87 * <p>Construct a {@link Chain} configured with the specified
88 * {@link Command}s.</p>
89 *
90 * @param commands The {@link Command}s to be configured
91 *
92 * @exception IllegalArgumentException if <code>commands</code>,
93 * or one of the individual {@link Command} elements,
94 * is <code>null</code>
95 */
96 public ChainBase(Collection commands) {
97
98 if (commands == null) {
99 throw new IllegalArgumentException();
100 }
101 Iterator elements = commands.iterator();
102 while (elements.hasNext()) {
103 addCommand((Command) elements.next());
104 }
105
106 }
107
108
109
110
111
112 /***
113 * <p>The list of {@link Command}s configured for this {@link Chain}, in
114 * the order in which they may delegate processing to the remainder of
115 * the {@link Chain}.</p>
116 */
117 protected Command[] commands = new Command[0];
118
119
120 /***
121 * <p>Flag indicating whether the configuration of our commands list
122 * has been frozen by a call to the <code>execute()</code> method.</p>
123 */
124 protected boolean frozen = false;
125
126
127
128
129
130 /***
131 * See the {@link Chain} JavaDoc.
132 *
133 * @param command The {@link Command} to be added
134 *
135 * @exception IllegalArgumentException if <code>command</code>
136 * is <code>null</code>
137 * @exception IllegalStateException if no further configuration is allowed
138 */
139 public void addCommand(Command command) {
140
141 if (command == null) {
142 throw new IllegalArgumentException();
143 }
144 if (frozen) {
145 throw new IllegalStateException();
146 }
147 Command[] results = new Command[commands.length + 1];
148 System.arraycopy(commands, 0, results, 0, commands.length);
149 results[commands.length] = command;
150 commands = results;
151
152 }
153
154
155 /***
156 * See the {@link Chain} JavaDoc.
157 *
158 * @param context The {@link Context} to be processed by this
159 * {@link Chain}
160 *
161 * @throws Exception if thrown by one of the {@link Command}s
162 * in this {@link Chain} but not handled by a <code>postprocess()</code>
163 * method of a {@link Filter}
164 * @throws IllegalArgumentException if <code>context</code>
165 * is <code>null</code>
166 *
167 * @return <code>true</code> if the processing of this {@link Context}
168 * has been completed, or <code>false</code> if the processing
169 * of this {@link Context} should be delegated to a subsequent
170 * {@link Command} in an enclosing {@link Chain}
171 */
172 public boolean execute(Context context) throws Exception {
173
174
175 if (context == null) {
176 throw new IllegalArgumentException();
177 }
178
179
180 frozen = true;
181
182
183
184 boolean saveResult = false;
185 Exception saveException = null;
186 int i = 0;
187 int n = commands.length;
188 for (i = 0; i < n; i++) {
189 try {
190 saveResult = commands[i].execute(context);
191 if (saveResult) {
192 break;
193 }
194 } catch (Exception e) {
195 saveException = e;
196 break;
197 }
198 }
199
200
201 if (i >= n) {
202 i--;
203 }
204 boolean handled = false;
205 boolean result = false;
206 for (int j = i; j >= 0; j--) {
207 if (commands[j] instanceof Filter) {
208 try {
209 result =
210 ((Filter) commands[j]).postprocess(context,
211 saveException);
212 if (result) {
213 handled = true;
214 }
215 } catch (Exception e) {
216
217 }
218 }
219 }
220
221
222 if ((saveException != null) && !handled) {
223 throw saveException;
224 } else {
225 return (saveResult);
226 }
227
228 }
229
230
231
232
233
234 /***
235 * <p>Return an array of the configured {@link Command}s for this
236 * {@link Chain}. This method is package private, and is used only
237 * for the unit tests.</p>
238 */
239 Command[] getCommands() {
240
241 return (commands);
242
243 }
244
245
246 }