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: 1.6 $ $Date: 2004/11/30 05:52:23 $
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 public void addCommand(Command command) {
132
133 if (command == null) {
134 throw new IllegalArgumentException();
135 }
136 if (frozen) {
137 throw new IllegalStateException();
138 }
139 Command[] results = new Command[commands.length + 1];
140 System.arraycopy(commands, 0, results, 0, commands.length);
141 results[commands.length] = command;
142 commands = results;
143
144 }
145
146
147
148 public boolean execute(Context context) throws Exception {
149
150
151 if (context == null) {
152 throw new IllegalArgumentException();
153 }
154
155
156 frozen = true;
157
158
159
160 boolean saveResult = false;
161 Exception saveException = null;
162 int i = 0;
163 int n = commands.length;;
164 for (i = 0; i < n; i++) {
165 try {
166 saveResult = commands[i].execute(context);
167 if (saveResult) {
168 break;
169 }
170 } catch (Exception e) {
171 saveException = e;
172 break;
173 }
174 }
175
176
177 if (i >= n) {
178 i--;
179 }
180 boolean handled = false;
181 boolean result = false;
182 for (int j = i; j >= 0; j--) {
183 if (commands[j] instanceof Filter) {
184 try {
185 result =
186 ((Filter) commands[j]).postprocess(context,
187 saveException);
188 if (result) {
189 handled = true;
190 }
191 } catch (Exception e) {
192 ;
193 }
194 }
195 }
196
197
198 if ((saveException != null) && !handled) {
199 throw saveException;
200 } else {
201 return (saveResult);
202 }
203
204 }
205
206
207
208
209
210 /***
211 * <p>Return an array of the configured {@link Command}s for this
212 * {@link Chain}. This method is package private, and is used only
213 * for the unit tests.</p>
214 */
215 Command[] getCommands() {
216
217 return (commands);
218
219 }
220
221
222 }