Coverage Report - org.apache.tapestry.services.ResponseBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
ResponseBuilder
N/A 
N/A 
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
 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  
     
 109  
     void renderResponse(IRequestCycle cycle)
 110  
     throws IOException;
 111  
     
 112  
     /**
 113  
      * Invoked to render a renderable object. Performs any necessary
 114  
      * under the hood type logic involving ajax/json/normal responses, where
 115  
      * needed.
 116  
      * 
 117  
      * @param writer 
 118  
      *          The markup writer to use, this may be ignored or swapped
 119  
      *          out for a different writer depending on the implementation being used.
 120  
      * @param render The renderable object to render
 121  
      * @param cycle Render request cycle
 122  
      */
 123  
     
 124  
     void render(IMarkupWriter writer, IRender render, IRequestCycle cycle);
 125  
     
 126  
     /**
 127  
      * If the component identified by the specified id isn't already set to
 128  
      * be updated, will add it to the response for updating. (Only applicable
 129  
      * in dynamic responses such as XHR/JSON ).
 130  
      * 
 131  
      * @param id
 132  
      *          The {@link IComponent} id to update.
 133  
      */
 134  
     void updateComponent(String id);
 135  
     
 136  
     /**
 137  
      * Checks if the rendered response contains a particular component. Contains
 138  
      * can mean many things. In the instance of a dynamic response it could potentially
 139  
      * mean a component explicitly set to be updated - or a component that has a containing
 140  
      * component explicitly set to be updated.
 141  
      * 
 142  
      * @param target The component to check containment of.
 143  
      * @return True if response contains the specified component, false otherwise.
 144  
      */
 145  
     boolean contains(IComponent target);
 146  
     
 147  
     /**
 148  
      * Similar to {@link #contains(IComponent)}, but only returns true if the component
 149  
      * has been marked for update directly via an <code>updateComponents</code> property 
 150  
      * or by calling {@link ResponseBuilder#updateComponent(String)} directly. 
 151  
      * 
 152  
      * <p>
 153  
      * <b>IMPORTANT!:</b> This will not return true for components contained by a component
 154  
      *  marked for update. If you want that kind of behaviour use {@link #contains(IComponent)}. 
 155  
      * </p>
 156  
      * 
 157  
      * @param target The component to check.
 158  
      * @return True if the component as listed as one to be updated, false otherwise.
 159  
      */
 160  
     boolean explicitlyContains(IComponent target);
 161  
     
 162  
     /**
 163  
      * Invoked by components that know "when" the method should be called. Causes all queued up
 164  
      * body related javascript data to be written out to the response.
 165  
      * 
 166  
      * @param writer
 167  
      *          The writer to use . (may / may not be ignored depending on the response type)
 168  
      * @param cycle
 169  
      *          Associated request.
 170  
      */
 171  
     void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle);
 172  
     
 173  
     /**
 174  
      * Invoked by components that know "when" the method should be called. Causes all queued up
 175  
      * initialization related javascript data to be written out to the response.
 176  
      * 
 177  
      * @param writer
 178  
      *          The writer to use . (may / may not be ignored depending on the response type)
 179  
      */
 180  
     void writeInitializationScript(IMarkupWriter writer);
 181  
     
 182  
     /**
 183  
      * Invoked by {@link PageRenderSupport} to write external js package
 184  
      * includes. This method will be invoked for each external script requesting
 185  
      * inclusion in the response.
 186  
      * 
 187  
      * These will typically be written out as 
 188  
      * <code>
 189  
      * <script type="text/javascript" src="url"></script>
 190  
      * </code>.
 191  
      *
 192  
      * @param writer
 193  
      *          The markup writer to use, this may be ignored or swapped
 194  
      *          out for a different writer depending on the implementation being used.
 195  
      * @param url
 196  
      *          The absolute url to the .js package to be included.
 197  
      * @param cycle
 198  
      *          The associated request.
 199  
      */    
 200  
     void writeExternalScript(IMarkupWriter writer, String url, IRequestCycle cycle);
 201  
     
 202  
     /**
 203  
      * Marks the beginning of the core body script.
 204  
      *
 205  
      * @param writer
 206  
      *          The markup writer to use, this may be ignored or swapped
 207  
      *          out for a different writer depending on the implementation being used.
 208  
      * @param cycle
 209  
      *          The associated request.
 210  
      */
 211  
     void beginBodyScript(IMarkupWriter writer, IRequestCycle cycle);
 212  
     
 213  
     /**
 214  
      * Intended to be written within the confines of the body script, should
 215  
      * be invoked once just after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} is called
 216  
      * to include any image initializations. This method should only be called if
 217  
      * there are actually images that need pre-initialization. Ie in many instances 
 218  
      * it will not be called at all.
 219  
      *
 220  
      * @param writer
 221  
      *          The markup writer to use, this may be ignored or swapped
 222  
      *          out for a different writer depending on the implementation being used.
 223  
      * @param script
 224  
      *          The non null value of the script images to include. 
 225  
      * @param preloadName 
 226  
      *          The global variable name to give to the preloaded images array.
 227  
      * @param cycle
 228  
      *          The associated request.
 229  
      */
 230  
     void writeImageInitializations(IMarkupWriter writer, String script, String preloadName, IRequestCycle cycle);
 231  
     
 232  
     /**
 233  
      * Called after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} to write the containing
 234  
      * body script. This method may not be called at all if there is no js body 
 235  
      * to write into the response.
 236  
      *
 237  
      * @param writer
 238  
      *          The markup writer to use, this may be ignored or swapped
 239  
      *          out for a different writer depending on the implementation being used.
 240  
      * @param script
 241  
      *          The script to write into the body response.
 242  
      * @param cycle
 243  
      *          The associated request.
 244  
      */
 245  
     void writeBodyScript(IMarkupWriter writer, String script, IRequestCycle cycle);
 246  
     
 247  
     /**
 248  
      * Marks the end of the body block being called. This method will 
 249  
      * always be called if {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} was previously
 250  
      * called. 
 251  
      *
 252  
      * @param writer
 253  
      *          The markup writer to use, this may be ignored or swapped
 254  
      *          out for a different writer depending on the implementation being used.
 255  
      * @param cycle
 256  
      *          The associated request.
 257  
      */
 258  
     void endBodyScript(IMarkupWriter writer, IRequestCycle cycle);
 259  
     
 260  
     /**
 261  
      * Writes any javascript that should only execute after all other items
 262  
      * on a page have completed rendering. This is typically implemented via
 263  
      * wrapping the executing of the code to some sort of <code>window.onload</code> 
 264  
      * event, but will vary depending on the implementation of the builder being used.
 265  
      * 
 266  
      * This method will ~only~ be called if there is any queued intialization script 
 267  
      * to write.
 268  
      *
 269  
      * @param writer
 270  
      *          The markup writer to use, this may be ignored or swapped
 271  
      *          out for a different writer depending on the implementation being used.
 272  
      * @param script
 273  
      *          The initialzation script to write.
 274  
      */
 275  
     void writeInitializationScript(IMarkupWriter writer, String script);
 276  
     
 277  
     /**
 278  
      * Returns the IMarkupWriter associated with this response, it may or may
 279  
      * not be a NullWriter instance depending on the response type or stage 
 280  
      * of the render cycle. (specifically during rewind)
 281  
      * 
 282  
      * @return A validly writable markup writer, even if the content is sometimes
 283  
      * ignored.
 284  
      */
 285  
     
 286  
     IMarkupWriter getWriter();
 287  
     
 288  
     /**
 289  
      * Gets a write that will output its content in a <code>response</code>
 290  
      * element with the given id and type. 
 291  
      * 
 292  
      * @param id 
 293  
      *          The response element id to give writer.
 294  
      * @param type
 295  
      *          Optional - If specified will give the response element a type
 296  
      *          attribute.
 297  
      * @return A valid {@link IMarkupWriter} instance to write content to.
 298  
      */
 299  
     IMarkupWriter getWriter(String id, String type);
 300  
     
 301  
     /**
 302  
      * Determines if the specified component should have any asset image URL
 303  
      * references embedded in the response.
 304  
      * 
 305  
      * @param target
 306  
      *          The component to allow/disallow image initialization script content from.
 307  
      * @return True if the component script should be allowed.
 308  
      */
 309  
     boolean isImageInitializationAllowed(IComponent target);
 310  
     
 311  
     /**
 312  
      * Adds a status message to the current response.
 313  
      *
 314  
      * @param writer
 315  
      *          The markup writer to use, this may be ignored or swapped
 316  
      *          out for a different writer depending on the implementation being used.
 317  
      * @param category
 318  
      *          Allows setting a category that best describes the type of the status message,
 319  
      *          i.e. info, error, e.t.c.
 320  
      * @param text
 321  
      *          The status message. 
 322  
      */
 323  
     void addStatusMessage(IMarkupWriter writer, String category, String text);
 324  
 }