1 package com.tirsen.angkor;
2
3 import com.tirsen.angkor.event.EventQueue;
4 import com.tirsen.angkor.process.ExecuteContext;
5 import com.tirsen.angkor.process.Pipeline;
6 import org.apache.log4j.Category;
7
8 import javax.servlet.ServletException;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import javax.servlet.http.HttpSession;
12 import javax.servlet.jsp.PageContext;
13 import java.io.IOException;
14 import java.io.PrintWriter;
15 import java.util.Iterator;
16
17 /***
18 * The RenderContext encapsulates the current processing state of the request, the partitioning of responsibilities
19 * between Application, RenderContext and ExecuteContext is not yet fully resolved and this needs some refactoring.
20 *
21 * This is the main engine of Angkor responsible for invoking and mainting the rest of the framework,
22 * it's name may be a little inaccurate by now since it ended up being the main engine while
23 * <a href="http://www.martinfowler.com">refactoring</a>.
24 *
25 * It will become instantiated now and then to do some work. It can actually only keep cached state
26 * since the same instance will not be used at all times (not even within one request). To get
27 * around this save its state in the request (for state only maintained within one request) or
28 * within the session (for state with a lifetime spanning several requests).
29 * To avoid name-clashes (several applications may be running within the same servlet-context) it prefixes
30 * each name with the path to the application. TODO well, it actually doesn't do this yet, but it's a good idea!
31 * It relies on the ApplicationFilter to instantiate an application accessible via the session and for call backs
32 * for the parse phase. For this reason the ApplicationFilter need to filter all pages using angkor.
33 *
34 * TODO refactoring: This class has too many responsibities. Move many of the processing attributes that doesn't
35 * directly have to do with rendering and put them as attributes into ExecuteContext, implement much of the
36 * functionality in Valves instead.
37 *
38 * <!-- $Id: RenderContext.java,v 1.5 2002/10/09 21:37:37 tirsen Exp $ -->
39 *
40 * @author $Author: tirsen $
41 * @version $Revision: 1.5 $
42 */
43 public class RenderContext
44 {
45 private static final Category logger = Debug.getCategory();
46
47 private HttpServletRequest request;
48 private HttpServletResponse response;
49 private EventQueue queue = new EventQueue();
50 protected int indent;
51
52 public RenderContext(HttpServletRequest request, HttpServletResponse response)
53 {
54 this.request = request;
55 this.response = response;
56 }
57
58 public RenderContext(PageContext pageContext)
59 {
60 this((HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse());
61 }
62
63 public EventQueue getEventQueue()
64 {
65 return queue;
66 }
67
68 public Application getApplication()
69 {
70 Application application = null;
71 try
72 {
73 application = (Application) getSessionAttribute(getApplicationSessionAttributeName());
74 }
75 catch (Exception e)
76 {
77 throw new RuntimeException("Failed to access application:" + e.getMessage());
78 }
79 if (application == null)
80 {
81 throw new IllegalStateException("Application has not been initialized for this context: " + getRequestPath() +
82 ", you need to deploy the ApplicationFilter correctly.");
83 }
84 return application;
85 }
86
87 private String getApplicationSessionAttributeName()
88 {
89 //return getApplicationPath() + "/application";
90 // TODO
91 return "application";
92 }
93
94 public void ensureApplicationInit(Class applicationClass) throws IOException, ServletException
95 {
96 Application application = (Application) getSessionAttribute(getApplicationSessionAttributeName());
97 if (application == null)
98 {
99 try
100 {
101 application = (Application) applicationClass.newInstance();
102 }
103 catch (Exception e)
104 {
105 logger.error("could not instantiate application");
106 throw new ServletException("could not instantiate application: " + e.getMessage());
107 }
108 setSessionAttribute(getApplicationSessionAttributeName(), application);
109 }
110 }
111
112 protected void setRequestAttribute(String name, Object value)
113 {
114 getRequest().setAttribute(name, value);
115 }
116
117 protected Object getRequestAttribute(String name)
118 {
119 return getRequest().getAttribute(name);
120 }
121
122 public HttpServletRequest getRequest()
123 {
124 if (request == null) throw new IllegalStateException("Tried to access non existent ServletRequest.");
125 return request;
126 }
127
128 public HttpServletResponse getResponse()
129 {
130 if (response == null) throw new IllegalStateException("Tried to access non existent ServletResponse.");
131 return response;
132 }
133
134 private void increaseIndent()
135 {
136 indent++;
137 }
138
139 private void decreaseIndent()
140 {
141 indent--;
142 }
143
144 protected void indent() throws IOException
145 {
146 for (int j = 0; j < indent; j++)
147 print("\t");
148 }
149
150 private void print(String s) throws IOException
151 {
152 getWriter().write(s);
153 }
154
155 public PrintWriter getWriter() throws IOException
156 {
157 return response.getWriter();
158 }
159
160 public void emptyTag(String tag) throws IOException
161 {
162 println("<" + tag + ">");
163 }
164
165 public void startTag(String tag) throws IOException
166 {
167 println("<" + tag + ">");
168 increaseIndent();
169 }
170
171 public void endTag(String tag) throws IOException
172 {
173 decreaseIndent();
174 println("</" + tag + ">");
175 }
176
177 public void println(String line) throws IOException
178 {
179 indent();
180 getWriter().println(line);
181 }
182
183 /***
184 * Returns an absolute uri useful for sending requests which should end up in an action.
185 * The angkor:header-tag renders a HTML base-tag to make all urls in angkor is relative to the application.
186 * For that reason links that should end up to be processed correctly by the ApplicationFilter also need to be
187 * relative to the context-root.
188 */
189 public String getRequestPath()
190 {
191 return getRequest().getRequestURI();
192 }
193
194 /***
195 * Constructs an url used to send requests back to the originating component.
196 */
197 public String requestURL(String url)
198 {
199 return encodeURL(getRequestPath() + "?" + url);
200 }
201
202 public String encodeURL(String url)
203 {
204 return getResponse().encodeURL(url);
205 }
206
207 public void resetParsingComponents()
208 {
209 getApplication().resetParsingComponents();
210 }
211
212 /***
213 * Returns a tread-safe iterator of the parsing components. Parsing components can be registered
214 * while using the returned iterator.
215 */
216 public Iterator iterateParsingComponents()
217 {
218 return getApplication().iterateParsingComponents();
219 }
220
221 public void registerParsingComponent(View view)
222 {
223 getApplication().registerParsingComponent(view);
224 }
225
226 protected void setSessionAttribute(String attribute, Object value)
227 {
228 HttpSession session = getRequest().getSession();
229 session.setAttribute(attribute, value);
230 }
231
232 protected Object getSessionAttribute(String attribute)
233 {
234 try
235 {
236 HttpSession session = getRequest().getSession();
237 return session.getAttribute(attribute);
238 }
239 catch (IllegalStateException e)
240 {
241 return null;
242 }
243 }
244
245 public String nextUniqueID()
246 {
247 return getApplication().nextUniqueID();
248 }
249
250 public String getRequestParameter(String name)
251 {
252 return getRequest().getParameter(name);
253 }
254
255 public void beforeRequest() throws IOException, ServletException
256 {
257 getApplication().beforeRequest(this);
258 }
259
260 public void afterRequest() throws IOException, ServletException
261 {
262 getApplication().afterRequest(this);
263 getEventQueue().reset();
264 }
265
266 /***
267 * Gets the render context of the currently running pipeline.
268 */
269 public static RenderContext getRenderContext()
270 {
271 return (RenderContext) Pipeline.getCurrentExecuteContext().getAttribute(ExecuteContext.RenderContextAttribute);
272 }
273 }
This page was automatically generated by Maven