Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||
ResponseBuilder |
|
| 1.0;1 |
1 | // Copyright 2004, 2005 The Apache Software Foundation |
|
2 | // |
|
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
|
4 | // you may not use this file except in compliance with the License. |
|
5 | // You may obtain a copy of the License at |
|
6 | // |
|
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
|
8 | // |
|
9 | // Unless required by applicable law or agreed to in writing, software |
|
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
|
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
12 | // See the License for the specific language governing permissions and |
|
13 | // limitations under the License. |
|
14 | package org.apache.tapestry.services; |
|
15 | ||
16 | import org.apache.tapestry.*; |
|
17 | import org.apache.tapestry.services.impl.DojoAjaxResponseBuilder; |
|
18 | ||
19 | import java.io.IOException; |
|
20 | ||
21 | /** |
|
22 | * Represents the service responsible for managing all content output that is sent |
|
23 | * to the client. In the case of normal http responses this management would inlude |
|
24 | * handing out {@link IMarkupWriter} instances to render components with, as well as |
|
25 | * managing any javascript written to the output using Script templates. |
|
26 | * |
|
27 | * <p> |
|
28 | * This is a major internal change in terms of the way tapestry renders pages/components. |
|
29 | * Traditionally a response has been rendered via: |
|
30 | * <em> |
|
31 | * IPage.render(writer, cycle); |
|
32 | * </em> |
|
33 | * The logic has now changed somewhat, while the IPage.render(writer, cycle) does still happen, this |
|
34 | * service is the primary invoker of all renders, even nested component bodies. That means that in the majority |
|
35 | * of cases the ResponseBuilder service is used to invoke IComponent.render() throught the entire render |
|
36 | * cycle, creating a great deal of flexibility in terms of what can be done to control the output of a given |
|
37 | * response. |
|
38 | * </p> |
|
39 | * |
|
40 | * <p> |
|
41 | * This service was primarily created to help bolster support for more dynamic content responses, such |
|
42 | * as XHR/JSON/etc - where controlling individual component output (and javascript) becomes very important |
|
43 | * when managaing client side browser state. |
|
44 | * </p> |
|
45 | * |
|
46 | * @since 4.1 |
|
47 | */ |
|
48 | public interface ResponseBuilder extends PageRenderSupport { |
|
49 | ||
50 | /** |
|
51 | * Inside a {@link org.apache.tapestry.util.ContentType}, the output encoding is called |
|
52 | * "charset". |
|
53 | */ |
|
54 | String ENCODING_KEY = "charset"; |
|
55 | ||
56 | /** |
|
57 | * The content type of the response that will be returned. |
|
58 | */ |
|
59 | String CONTENT_TYPE = "text/xml"; |
|
60 | ||
61 | /** |
|
62 | * The response element type. |
|
63 | */ |
|
64 | String ELEMENT_TYPE = "element"; |
|
65 | ||
66 | /** |
|
67 | * The response exception type. |
|
68 | */ |
|
69 | String EXCEPTION_TYPE = "exception"; |
|
70 | ||
71 | /** |
|
72 | * The response element type denoting a brand new page render. |
|
73 | */ |
|
74 | String PAGE_TYPE = "page"; |
|
75 | ||
76 | String SCRIPT_TYPE = "script"; |
|
77 | ||
78 | String BODY_SCRIPT = "bodyscript"; |
|
79 | ||
80 | String INCLUDE_SCRIPT = "includescript"; |
|
81 | ||
82 | String INITIALIZATION_SCRIPT = "initializationscript"; |
|
83 | ||
84 | /** |
|
85 | * Implementors that manage content writes dynamically (ie {@link DojoAjaxResponseBuilder}) should |
|
86 | * return true to denote that dynamic behaviour is on for a particular response. |
|
87 | * |
|
88 | * @return Whether or not request is dynamic. |
|
89 | */ |
|
90 | boolean isDynamic(); |
|
91 | ||
92 | /** |
|
93 | * Causes the output stream to be flushed, used primarily in concert with {@link IRequestCycle} to sync |
|
94 | * up flushing of headers to the browser once any page changes have been committed. |
|
95 | * |
|
96 | * @throws IOException During io error. |
|
97 | */ |
|
98 | void flush() |
|
99 | throws IOException; |
|
100 | ||
101 | /** |
|
102 | * Renders the response to a client. Handles transitioning logic |
|
103 | * for setting up page and associated components for response. |
|
104 | * |
|
105 | * @param cycle |
|
106 | * The main request cycle object for this request. |
|
107 | * |
|
108 | * @throws IOException During io error. |
|
109 | */ |
|
110 | ||
111 | void renderResponse(IRequestCycle cycle) |
|
112 | throws IOException; |
|
113 | ||
114 | /** |
|
115 | * Invoked to render a renderable object. Performs any necessary |
|
116 | * under the hood type logic involving ajax/json/normal responses, where |
|
117 | * needed. |
|
118 | * |
|
119 | * @param writer |
|
120 | * The markup writer to use, this may be ignored or swapped |
|
121 | * out for a different writer depending on the implementation being used. |
|
122 | * @param render The renderable object to render |
|
123 | * @param cycle Render request cycle |
|
124 | */ |
|
125 | ||
126 | void render(IMarkupWriter writer, IRender render, IRequestCycle cycle); |
|
127 | ||
128 | /** |
|
129 | * If the component identified by the specified id isn't already set to |
|
130 | * be updated, will add it to the response for updating. (Only applicable |
|
131 | * in dynamic responses such as XHR/JSON ). |
|
132 | * |
|
133 | * @param id |
|
134 | * The {@link IComponent} id to update. |
|
135 | */ |
|
136 | void updateComponent(String id); |
|
137 | ||
138 | /** |
|
139 | * Checks if the rendered response contains a particular component. Contains |
|
140 | * can mean many things. In the instance of a dynamic response it could potentially |
|
141 | * mean a component explicitly set to be updated - or a component that has a containing |
|
142 | * component explicitly set to be updated. |
|
143 | * |
|
144 | * @param target The component to check containment of. |
|
145 | * @return True if response contains the specified component, false otherwise. |
|
146 | */ |
|
147 | boolean contains(IComponent target); |
|
148 | ||
149 | /** |
|
150 | * Similar to {@link #contains(IComponent)}, but only returns true if the component |
|
151 | * has been marked for update directly via an <code>updateComponents</code> property |
|
152 | * or by calling {@link ResponseBuilder#updateComponent(String)} directly. |
|
153 | * |
|
154 | * <p> |
|
155 | * <b>IMPORTANT!:</b> This will not return true for components contained by a component |
|
156 | * marked for update. If you want that kind of behaviour use {@link #contains(IComponent)}. |
|
157 | * </p> |
|
158 | * |
|
159 | * @param target The component to check. |
|
160 | * @return True if the component as listed as one to be updated, false otherwise. |
|
161 | */ |
|
162 | boolean explicitlyContains(IComponent target); |
|
163 | ||
164 | /** |
|
165 | * Invoked by components that know "when" the method should be called. Causes all queued up |
|
166 | * body related javascript data to be written out to the response. |
|
167 | * |
|
168 | * @param writer |
|
169 | * The writer to use . (may / may not be ignored depending on the response type) |
|
170 | * @param cycle |
|
171 | * Associated request. |
|
172 | */ |
|
173 | void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
|
174 | ||
175 | /** |
|
176 | * Invoked by components that know "when" the method should be called. Causes all queued up |
|
177 | * initialization related javascript data to be written out to the response. |
|
178 | * |
|
179 | * @param writer |
|
180 | * The writer to use . (may / may not be ignored depending on the response type) |
|
181 | */ |
|
182 | void writeInitializationScript(IMarkupWriter writer); |
|
183 | ||
184 | /** |
|
185 | * Invoked by {@link PageRenderSupport} to write external js package |
|
186 | * includes. This method will be invoked for each external script requesting |
|
187 | * inclusion in the response. |
|
188 | * |
|
189 | * These will typically be written out as |
|
190 | * <code> |
|
191 | * <script type="text/javascript" src="url"></script> |
|
192 | * </code>. |
|
193 | * |
|
194 | * @param writer |
|
195 | * The markup writer to use, this may be ignored or swapped |
|
196 | * out for a different writer depending on the implementation being used. |
|
197 | * @param url |
|
198 | * The absolute url to the .js package to be included. |
|
199 | * @param cycle |
|
200 | * The associated request. |
|
201 | */ |
|
202 | void writeExternalScript(IMarkupWriter writer, String url, IRequestCycle cycle); |
|
203 | ||
204 | /** |
|
205 | * Marks the beginning of the core body script. |
|
206 | * |
|
207 | * @param writer |
|
208 | * The markup writer to use, this may be ignored or swapped |
|
209 | * out for a different writer depending on the implementation being used. |
|
210 | * @param cycle |
|
211 | * The associated request. |
|
212 | */ |
|
213 | void beginBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
|
214 | ||
215 | /** |
|
216 | * Intended to be written within the confines of the body script, should |
|
217 | * be invoked once just after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} is called |
|
218 | * to include any image initializations. This method should only be called if |
|
219 | * there are actually images that need pre-initialization. Ie in many instances |
|
220 | * it will not be called at all. |
|
221 | * |
|
222 | * @param writer |
|
223 | * The markup writer to use, this may be ignored or swapped |
|
224 | * out for a different writer depending on the implementation being used. |
|
225 | * @param script |
|
226 | * The non null value of the script images to include. |
|
227 | * @param preloadName |
|
228 | * The global variable name to give to the preloaded images array. |
|
229 | * @param cycle |
|
230 | * The associated request. |
|
231 | */ |
|
232 | void writeImageInitializations(IMarkupWriter writer, String script, String preloadName, IRequestCycle cycle); |
|
233 | ||
234 | /** |
|
235 | * Called after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} to write the containing |
|
236 | * body script. This method may not be called at all if there is no js body |
|
237 | * to write into the response. |
|
238 | * |
|
239 | * @param writer |
|
240 | * The markup writer to use, this may be ignored or swapped |
|
241 | * out for a different writer depending on the implementation being used. |
|
242 | * @param script |
|
243 | * The script to write into the body response. |
|
244 | * @param cycle |
|
245 | * The associated request. |
|
246 | */ |
|
247 | void writeBodyScript(IMarkupWriter writer, String script, IRequestCycle cycle); |
|
248 | ||
249 | /** |
|
250 | * Marks the end of the body block being called. This method will |
|
251 | * always be called if {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} was previously |
|
252 | * called. |
|
253 | * |
|
254 | * @param writer |
|
255 | * The markup writer to use, this may be ignored or swapped |
|
256 | * out for a different writer depending on the implementation being used. |
|
257 | * @param cycle |
|
258 | * The associated request. |
|
259 | */ |
|
260 | void endBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
|
261 | ||
262 | /** |
|
263 | * Writes any javascript that should only execute after all other items |
|
264 | * on a page have completed rendering. This is typically implemented via |
|
265 | * wrapping the executing of the code to some sort of <code>window.onload</code> |
|
266 | * event, but will vary depending on the implementation of the builder being used. |
|
267 | * |
|
268 | * This method will ~only~ be called if there is any queued intialization script |
|
269 | * to write. |
|
270 | * |
|
271 | * @param writer |
|
272 | * The markup writer to use, this may be ignored or swapped |
|
273 | * out for a different writer depending on the implementation being used. |
|
274 | * @param script |
|
275 | * The initialzation script to write. |
|
276 | */ |
|
277 | void writeInitializationScript(IMarkupWriter writer, String script); |
|
278 | ||
279 | /** |
|
280 | * Returns the IMarkupWriter associated with this response, it may or may |
|
281 | * not be a NullWriter instance depending on the response type or stage |
|
282 | * of the render cycle. (specifically during rewind) |
|
283 | * |
|
284 | * @return A validly writable markup writer, even if the content is sometimes |
|
285 | * ignored. |
|
286 | */ |
|
287 | ||
288 | IMarkupWriter getWriter(); |
|
289 | ||
290 | /** |
|
291 | * Gets a write that will output its content in a <code>response</code> |
|
292 | * element with the given id and type. |
|
293 | * |
|
294 | * @param id |
|
295 | * The response element id to give writer. |
|
296 | * @param type |
|
297 | * Optional - If specified will give the response element a type |
|
298 | * attribute. |
|
299 | * @return A valid {@link IMarkupWriter} instance to write content to. |
|
300 | */ |
|
301 | IMarkupWriter getWriter(String id, String type); |
|
302 | ||
303 | /** |
|
304 | * Determines if the specified component should have any asset image URL |
|
305 | * references embedded in the response. |
|
306 | * |
|
307 | * @param target |
|
308 | * The component to allow/disallow image initialization script content from. |
|
309 | * @return True if the component script should be allowed. |
|
310 | */ |
|
311 | boolean isImageInitializationAllowed(IComponent target); |
|
312 | ||
313 | /** |
|
314 | * Adds a status message to the current response. |
|
315 | * |
|
316 | * @param writer |
|
317 | * The markup writer to use, this may be ignored or swapped |
|
318 | * out for a different writer depending on the implementation being used. |
|
319 | * @param category |
|
320 | * Allows setting a category that best describes the type of the status message, |
|
321 | * i.e. info, error, e.t.c. |
|
322 | * @param text |
|
323 | * The status message. |
|
324 | */ |
|
325 | void addStatusMessage(IMarkupWriter writer, String category, String text); |
|
326 | } |