|
1
|
|
/*
|
|
2
|
|
* Angkor Web Framework
|
|
3
|
|
*
|
|
4
|
|
* Distributable under LGPL license.
|
|
5
|
|
* See terms of license at gnu.org.
|
|
6
|
|
*/
|
|
7
|
|
|
|
8
|
|
package com.tirsen.angkor.process;
|
|
9
|
|
|
|
10
|
|
import com.tirsen.angkor.Application;
|
|
11
|
|
import com.tirsen.angkor.RenderContext;
|
|
12
|
|
|
|
13
|
|
import javax.servlet.ServletException;
|
|
14
|
|
import java.io.IOException;
|
|
15
|
|
import java.util.ArrayList;
|
|
16
|
|
import java.util.HashMap;
|
|
17
|
|
import java.util.Iterator;
|
|
18
|
|
import java.util.List;
|
|
19
|
|
import java.util.Map;
|
|
20
|
|
|
|
21
|
|
/**
|
|
22
|
|
* <!-- $Id: Pipeline.java,v 1.4 2002/10/13 13:37:26 tirsen Exp $ -->
|
|
23
|
|
* <!-- $Author: tirsen $ -->
|
|
24
|
|
*
|
|
25
|
|
* @author Jon Tirs´n (tirsen@users.sourceforge.net)
|
|
26
|
|
* @version $Revision: 1.4 $
|
|
27
|
|
*/
|
|
28
|
|
public abstract class Pipeline
|
|
29
|
|
{
|
|
30
|
|
private List valves = new ArrayList();
|
|
31
|
|
|
|
32
|
|
protected static class BasicExecuteContext implements ExecuteContext
|
|
33
|
|
{
|
|
34
|
|
private Iterator valves;
|
|
35
|
|
private ExecuteContext parent;
|
|
36
|
|
private Map attributes = new HashMap();
|
|
37
|
|
|
|
38
|
47
|
public BasicExecuteContext(Iterator valves)
|
|
39
|
|
{
|
|
40
|
47
|
this.valves = valves;
|
|
41
|
|
}
|
|
42
|
|
|
|
43
|
6
|
public BasicExecuteContext(Iterator valves, ExecuteContext parent)
|
|
44
|
|
{
|
|
45
|
6
|
this.valves = valves;
|
|
46
|
6
|
this.parent = parent;
|
|
47
|
|
}
|
|
48
|
|
|
|
49
|
94
|
public void executeNext() throws Exception
|
|
50
|
|
{
|
|
51
|
|
// check for fatal error, don't continue in case we got one
|
|
52
|
94
|
Application application = (Application) getAttribute(ApplicationAttribute);
|
|
53
|
|
// TODO change error processing from Throwable to Exception
|
|
54
|
0
|
if (application.getError() != null) throw (Exception) application.getError();
|
|
55
|
94
|
if (valves.hasNext())
|
|
56
|
|
{
|
|
57
|
74
|
Valve next = (Valve) valves.next();
|
|
58
|
74
|
next.execute(this);
|
|
59
|
|
}
|
|
60
|
|
}
|
|
61
|
|
|
|
62
|
130
|
public void setAttribute(ExecuteContext.Attribute attribute, Object value)
|
|
63
|
|
{
|
|
64
|
130
|
attributes.put(attribute, value);
|
|
65
|
|
}
|
|
66
|
|
|
|
67
|
284
|
public Object getAttribute(ExecuteContext.Attribute attribute)
|
|
68
|
|
{
|
|
69
|
284
|
Object value;
|
|
70
|
284
|
if (!attributes.containsKey(attribute))
|
|
71
|
|
{
|
|
72
|
20
|
if (parent != null)
|
|
73
|
|
{
|
|
74
|
12
|
value = parent.getAttribute(attribute);
|
|
75
|
|
}
|
|
76
|
|
else
|
|
77
|
|
{
|
|
78
|
|
// throw error?
|
|
79
|
8
|
value = null;
|
|
80
|
|
}
|
|
81
|
|
}
|
|
82
|
|
else
|
|
83
|
264
|
value = attributes.get(attribute);
|
|
84
|
284
|
return value;
|
|
85
|
|
}
|
|
86
|
|
|
|
87
|
8
|
public String toString()
|
|
88
|
|
{
|
|
89
|
8
|
StringBuffer result = new StringBuffer();
|
|
90
|
8
|
result.append("ExecuteContext[");
|
|
91
|
8
|
for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();)
|
|
92
|
|
{
|
|
93
|
16
|
Map.Entry entry = (Map.Entry) iterator.next();
|
|
94
|
16
|
result.append(((Attribute) entry.getKey()).getName());
|
|
95
|
16
|
result.append("=");
|
|
96
|
16
|
result.append(entry.getValue());
|
|
97
|
8
|
if (iterator.hasNext()) result.append(",");
|
|
98
|
|
}
|
|
99
|
8
|
result.append("]");
|
|
100
|
8
|
return result.toString();
|
|
101
|
|
}
|
|
102
|
|
}
|
|
103
|
|
|
|
104
|
47
|
protected void initContext(ExecuteContext exec, RenderContext renderContext) throws ServletException, IOException
|
|
105
|
|
{
|
|
106
|
47
|
exec.setAttribute(ExecuteContext.RenderContextAttribute, renderContext);
|
|
107
|
47
|
exec.setAttribute(ExecuteContext.ApplicationAttribute, renderContext.getApplication());
|
|
108
|
|
}
|
|
109
|
|
|
|
110
|
14
|
public void execute(RenderContext renderContext) throws Exception
|
|
111
|
|
{
|
|
112
|
14
|
ExecuteContext exec = createExecuteContext(renderContext);
|
|
113
|
14
|
execute(exec);
|
|
114
|
|
}
|
|
115
|
|
|
|
116
|
|
/**
|
|
117
|
|
* Used in unit tests to set up ExecuteContext differently.
|
|
118
|
|
*/
|
|
119
|
35
|
public void execute(ExecuteContext exec) throws Exception
|
|
120
|
|
{
|
|
121
|
35
|
setCurrentExecuteContext(exec);
|
|
122
|
35
|
try
|
|
123
|
|
{
|
|
124
|
35
|
exec.executeNext();
|
|
125
|
|
}
|
|
126
|
|
finally
|
|
127
|
|
{
|
|
128
|
35
|
setCurrentExecuteContext(null);
|
|
129
|
|
}
|
|
130
|
|
}
|
|
131
|
|
|
|
132
|
|
/**
|
|
133
|
|
* Used in unit tests to set up ExecuteContext differently.
|
|
134
|
|
*/
|
|
135
|
47
|
public ExecuteContext createExecuteContext(RenderContext renderContext) throws Exception
|
|
136
|
|
{
|
|
137
|
47
|
Iterator it = valves.iterator();
|
|
138
|
47
|
ExecuteContext exec = new BasicExecuteContext(it);
|
|
139
|
47
|
initContext(exec, renderContext);
|
|
140
|
47
|
return exec;
|
|
141
|
|
}
|
|
142
|
|
|
|
143
|
6
|
public ExecuteContext createSubContext(ExecuteContext context)
|
|
144
|
|
{
|
|
145
|
6
|
Iterator it = valves.iterator();
|
|
146
|
6
|
ExecuteContext sub = new BasicExecuteContext(it, context);
|
|
147
|
6
|
return sub;
|
|
148
|
|
}
|
|
149
|
|
|
|
150
|
87
|
public void addValve(Valve valve)
|
|
151
|
|
{
|
|
152
|
87
|
valves.add(valve);
|
|
153
|
|
}
|
|
154
|
|
|
|
155
|
0
|
public Valve findValve(Class valveClass)
|
|
156
|
|
{
|
|
157
|
0
|
Valve found = null;
|
|
158
|
0
|
for (Iterator iterator = valves.iterator(); iterator.hasNext();)
|
|
159
|
|
{
|
|
160
|
0
|
Valve valve = (Valve) iterator.next();
|
|
161
|
0
|
if (valveClass.isInstance(valve))
|
|
162
|
|
{
|
|
163
|
0
|
if (found == null)
|
|
164
|
0
|
found = valve;
|
|
165
|
|
else
|
|
166
|
0
|
throw new IllegalStateException("Several valves of type " + valveClass);
|
|
167
|
|
}
|
|
168
|
|
}
|
|
169
|
0
|
return found;
|
|
170
|
|
}
|
|
171
|
|
|
|
172
|
0
|
public void insertBefore(Valve insertBefore, Valve valveToInsert)
|
|
173
|
|
{
|
|
174
|
0
|
valves.add(valves.indexOf(insertBefore) - 1, valveToInsert);
|
|
175
|
|
}
|
|
176
|
|
|
|
177
|
0
|
public void replaceValve(Valve valveToReplace, Valve valveToReplaceWith)
|
|
178
|
|
{
|
|
179
|
0
|
valves.set(valves.indexOf(valveToReplace), valveToReplaceWith);
|
|
180
|
|
}
|
|
181
|
|
|
|
182
|
|
private static ThreadLocal currentExecuteContext = new ThreadLocal();
|
|
183
|
|
|
|
184
|
81
|
public static ExecuteContext getCurrentExecuteContext()
|
|
185
|
|
{
|
|
186
|
81
|
ExecuteContext exec = (ExecuteContext) currentExecuteContext.get();
|
|
187
|
81
|
if (exec == null)
|
|
188
|
|
{
|
|
189
|
0
|
throw new IllegalStateException("Doing things outside the pipeline, all processing in Angkor must be running from the pipeline.");
|
|
190
|
|
}
|
|
191
|
81
|
return exec;
|
|
192
|
|
}
|
|
193
|
|
|
|
194
|
100
|
protected static void setCurrentExecuteContext(ExecuteContext context)
|
|
195
|
|
{
|
|
196
|
100
|
currentExecuteContext.set(context);
|
|
197
|
|
}
|
|
198
|
|
}
|
|
199
|
|
|