001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.components;
016    
017    import org.apache.tapestry.IMarkupWriter;
018    import org.apache.tapestry.IRender;
019    import org.apache.tapestry.IRequestCycle;
020    
021    /**
022     * An implementation of IRender that renders a Block component.
023     * <p>
024     * The BlockRenderer allows the contents of a {@link Block} to be rendered via
025     * {@link IRender}. It can be used in cases when an {@link IRender} object is
026     * required as an argument or a binding to render a part of a Component. To
027     * provide a complicated view, it could be defined in a {@link Block} and then
028     * returned encapsulated in a BlockRenderer.
029     * <p>
030     * It is important to note that a special care has to be taken if the
031     * BlockRenderer is used within an inner class of a component or a page. In such
032     * a case the instance of the component that created the inner class may not be
033     * the currently active instance in the RequestCycle when the BlockRenderer is
034     * required. Thus, calling getComponent("blockName") to get the block component
035     * may return a Block component that is not initialized for this RequestCycle.
036     * <p>
037     * To avoid similar problems, the ComponentAddress class could be used in
038     * conjunction with BlockRenderer. Here is a quick example of how BlockRenderer
039     * could be used with ComponentAddress:
040     * <p>
041     * <code>
042     * <br>// Create a component address for the current component
043     * <br>final ComponentAddress address = new ComponentAddress(this);
044     * <br>return new SomeClass() {
045     * <br>&nbsp;&nbsp;IRender getRenderer(IRequestCycle cycle) {
046     * <br>&nbsp;&nbsp;&nbsp;&nbsp;MyComponent component = (MyComponent) address.findComponent(cycle);
047     * <br>&nbsp;&nbsp;&nbsp;&nbsp;// initialize variables in the component that will be used by the block here
048     * <br>&nbsp;&nbsp;&nbsp;&nbsp;return new BlockRenderer(component.getComponent("block"));
049     * <br>&nbsp;&nbsp;}
050     * <br>}
051     * </code>
052     * 
053     * @author mindbridge
054     * @since 2.2
055     */
056    public class BlockRenderer implements IRender
057    {
058    
059        private Block m_objBlock;
060    
061        /**
062         * Creates a new BlockRenderer that will render the content of the argument.
063         * 
064         * @param objBlock
065         *            the Block to be rendered
066         */
067        public BlockRenderer(Block objBlock)
068        {
069            m_objBlock = objBlock;
070        }
071        
072        /**
073         * @see org.apache.tapestry.IRender#render(IMarkupWriter, IRequestCycle)
074         */
075        public void render(IMarkupWriter writer, IRequestCycle cycle)
076        {
077            m_objBlock.renderBody(writer, cycle);
078        }
079    
080    }