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