| // Copyright 2004, 2005 The Apache Software Foundation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package org.apache.tapestry.services; |
| |
| import org.apache.tapestry.*; |
| import org.apache.tapestry.services.impl.DojoAjaxResponseBuilder; |
| |
| import java.io.IOException; |
| |
| /** |
| * Represents the service responsible for managing all content output that is sent |
| * to the client. In the case of normal http responses this management would inlude |
| * handing out {@link IMarkupWriter} instances to render components with, as well as |
| * managing any javascript written to the output using Script templates. |
| * |
| * <p> |
| * This is a major internal change in terms of the way tapestry renders pages/components. |
| * Traditionally a response has been rendered via: |
| * <em> |
| * IPage.render(writer, cycle); |
| * </em> |
| * The logic has now changed somewhat, while the IPage.render(writer, cycle) does still happen, this |
| * service is the primary invoker of all renders, even nested component bodies. That means that in the majority |
| * of cases the ResponseBuilder service is used to invoke IComponent.render() throught the entire render |
| * cycle, creating a great deal of flexibility in terms of what can be done to control the output of a given |
| * response. |
| * </p> |
| * |
| * <p> |
| * This service was primarily created to help bolster support for more dynamic content responses, such |
| * as XHR/JSON/etc - where controlling individual component output (and javascript) becomes very important |
| * when managaing client side browser state. |
| * </p> |
| * |
| * @since 4.1 |
| */ |
| public interface ResponseBuilder extends PageRenderSupport { |
| |
| /** |
| * Inside a {@link org.apache.tapestry.util.ContentType}, the output encoding is called |
| * "charset". |
| */ |
| String ENCODING_KEY = "charset"; |
| |
| /** |
| * The content type of the response that will be returned. |
| */ |
| String CONTENT_TYPE = "text/xml"; |
| |
| /** |
| * The response element type. |
| */ |
| String ELEMENT_TYPE = "element"; |
| |
| /** |
| * The response exception type. |
| */ |
| String EXCEPTION_TYPE = "exception"; |
| |
| /** |
| * The response element type denoting a brand new page render. |
| */ |
| String PAGE_TYPE = "page"; |
| |
| String SCRIPT_TYPE = "script"; |
| |
| String BODY_SCRIPT = "bodyscript"; |
| |
| String INCLUDE_SCRIPT = "includescript"; |
| |
| String INITIALIZATION_SCRIPT = "initializationscript"; |
| |
| /** |
| * Implementors that manage content writes dynamically (ie {@link DojoAjaxResponseBuilder}) should |
| * return true to denote that dynamic behaviour is on for a particular response. |
| * |
| * @return Whether or not request is dynamic. |
| */ |
| boolean isDynamic(); |
| |
| /** |
| * Causes the output stream to be flushed, used primarily in concert with {@link IRequestCycle} to sync |
| * up flushing of headers to the browser once any page changes have been committed. |
| * |
| * @throws IOException During io error. |
| */ |
| void flush() |
| throws IOException; |
| |
| /** |
| * Renders the response to a client. Handles transitioning logic |
| * for setting up page and associated components for response. |
| * |
| * @param cycle |
| * The main request cycle object for this request. |
| * |
| * @throws IOException During io error. |
| */ |
| |
| void renderResponse(IRequestCycle cycle) |
| throws IOException; |
| |
| /** |
| * Invoked to render a renderable object. Performs any necessary |
| * under the hood type logic involving ajax/json/normal responses, where |
| * needed. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param render The renderable object to render |
| * @param cycle Render request cycle |
| */ |
| |
| void render(IMarkupWriter writer, IRender render, IRequestCycle cycle); |
| |
| /** |
| * If the component identified by the specified id isn't already set to |
| * be updated, will add it to the response for updating. (Only applicable |
| * in dynamic responses such as XHR/JSON ). |
| * |
| * @param id |
| * The {@link IComponent} id to update. |
| */ |
| void updateComponent(String id); |
| |
| /** |
| * Checks if the rendered response contains a particular component. Contains |
| * can mean many things. In the instance of a dynamic response it could potentially |
| * mean a component explicitly set to be updated - or a component that has a containing |
| * component explicitly set to be updated. |
| * |
| * @param target The component to check containment of. |
| * @return True if response contains the specified component, false otherwise. |
| */ |
| boolean contains(IComponent target); |
| |
| /** |
| * Similar to {@link #contains(IComponent)}, but only returns true if the component |
| * has been marked for update directly via an <code>updateComponents</code> property |
| * or by calling {@link ResponseBuilder#updateComponent(String)} directly. |
| * |
| * <p> |
| * <b>IMPORTANT!:</b> This will not return true for components contained by a component |
| * marked for update. If you want that kind of behaviour use {@link #contains(IComponent)}. |
| * </p> |
| * |
| * @param target The component to check. |
| * @return True if the component as listed as one to be updated, false otherwise. |
| */ |
| boolean explicitlyContains(IComponent target); |
| |
| /** |
| * Invoked by components that know "when" the method should be called. Causes all queued up |
| * body related javascript data to be written out to the response. |
| * |
| * @param writer |
| * The writer to use . (may / may not be ignored depending on the response type) |
| * @param cycle |
| * Associated request. |
| */ |
| void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
| |
| /** |
| * Invoked by components that know "when" the method should be called. Causes all queued up |
| * initialization related javascript data to be written out to the response. |
| * |
| * @param writer |
| * The writer to use . (may / may not be ignored depending on the response type) |
| */ |
| void writeInitializationScript(IMarkupWriter writer); |
| |
| /** |
| * Invoked by {@link PageRenderSupport} to write external js package |
| * includes. This method will be invoked for each external script requesting |
| * inclusion in the response. |
| * |
| * These will typically be written out as |
| * <code> |
| * <script type="text/javascript" src="url"></script> |
| * </code>. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param url |
| * The absolute url to the .js package to be included. |
| * @param cycle |
| * The associated request. |
| */ |
| void writeExternalScript(IMarkupWriter writer, String url, IRequestCycle cycle); |
| |
| /** |
| * Marks the beginning of the core body script. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param cycle |
| * The associated request. |
| */ |
| void beginBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
| |
| /** |
| * Intended to be written within the confines of the body script, should |
| * be invoked once just after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} is called |
| * to include any image initializations. This method should only be called if |
| * there are actually images that need pre-initialization. Ie in many instances |
| * it will not be called at all. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param script |
| * The non null value of the script images to include. |
| * @param preloadName |
| * The global variable name to give to the preloaded images array. |
| * @param cycle |
| * The associated request. |
| */ |
| void writeImageInitializations(IMarkupWriter writer, String script, String preloadName, IRequestCycle cycle); |
| |
| /** |
| * Called after {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} to write the containing |
| * body script. This method may not be called at all if there is no js body |
| * to write into the response. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param script |
| * The script to write into the body response. |
| * @param cycle |
| * The associated request. |
| */ |
| void writeBodyScript(IMarkupWriter writer, String script, IRequestCycle cycle); |
| |
| /** |
| * Marks the end of the body block being called. This method will |
| * always be called if {@link #beginBodyScript(IMarkupWriter, IRequestCycle)} was previously |
| * called. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param cycle |
| * The associated request. |
| */ |
| void endBodyScript(IMarkupWriter writer, IRequestCycle cycle); |
| |
| /** |
| * Writes any javascript that should only execute after all other items |
| * on a page have completed rendering. This is typically implemented via |
| * wrapping the executing of the code to some sort of <code>window.onload</code> |
| * event, but will vary depending on the implementation of the builder being used. |
| * |
| * This method will ~only~ be called if there is any queued intialization script |
| * to write. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param script |
| * The initialzation script to write. |
| */ |
| void writeInitializationScript(IMarkupWriter writer, String script); |
| |
| /** |
| * Returns the IMarkupWriter associated with this response, it may or may |
| * not be a NullWriter instance depending on the response type or stage |
| * of the render cycle. (specifically during rewind) |
| * |
| * @return A validly writable markup writer, even if the content is sometimes |
| * ignored. |
| */ |
| |
| IMarkupWriter getWriter(); |
| |
| /** |
| * Gets a write that will output its content in a <code>response</code> |
| * element with the given id and type. |
| * |
| * @param id |
| * The response element id to give writer. |
| * @param type |
| * Optional - If specified will give the response element a type |
| * attribute. |
| * @return A valid {@link IMarkupWriter} instance to write content to. |
| */ |
| IMarkupWriter getWriter(String id, String type); |
| |
| /** |
| * Determines if the specified component should have any asset image URL |
| * references embedded in the response. |
| * |
| * @param target |
| * The component to allow/disallow image initialization script content from. |
| * @return True if the component script should be allowed. |
| */ |
| boolean isImageInitializationAllowed(IComponent target); |
| |
| /** |
| * Adds a status message to the current response. |
| * |
| * @param writer |
| * The markup writer to use, this may be ignored or swapped |
| * out for a different writer depending on the implementation being used. |
| * @param category |
| * Allows setting a category that best describes the type of the status message, |
| * i.e. info, error, e.t.c. |
| * @param text |
| * The status message. |
| */ |
| void addStatusMessage(IMarkupWriter writer, String category, String text); |
| } |