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