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
|
|
|