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
015package org.apache.tapestry.components;
016
017import org.apache.tapestry.IMarkupWriter;
018import org.apache.tapestry.IRender;
019import org.apache.tapestry.IRequestCycle;
020
021/**
022 * An implementation of IRender that renders a Block component.
023 * 
024 * <p>The BlockRenderer allows the contents of a {@link Block} to be rendered
025 * via {@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. 
027 * To provide a complicated view, it could be defined in a {@link Block} and then
028 * returned encapsulated in a BlockRenderer.
029 * 
030 * <p>It is important to note that a special care has to be taken if 
031 * the BlockRenderer is used within an inner class of a component or a page. 
032 * In such a case the instance of the component that created the inner class 
033 * may not be the currently active instance in the RequestCycle when the 
034 * BlockRenderer is required. Thus, calling getComponent("blockName") to get the
035 * block component may return a Block component that is not initialized for this 
036 * RequestCycle.
037 * 
038 * <p>To avoid similar problems, the ComponentAddress class could be used in
039 * conjunction with BlockRenderer. 
040 * Here is a quick example of how BlockRenderer could be used with ComponentAddress:
041 * <p>
042 * <code>
043 * <br>// Create a component address for the current component
044 * <br>final ComponentAddress address = new ComponentAddress(this);
045 * <br>return new SomeClass() {
046 * <br>&nbsp;&nbsp;IRender getRenderer(IRequestCycle cycle) {
047 * <br>&nbsp;&nbsp;&nbsp;&nbsp;MyComponent component = (MyComponent) address.findComponent(cycle);
048 * <br>&nbsp;&nbsp;&nbsp;&nbsp;// initialize variables in the component that will be used by the block here
049 * <br>&nbsp;&nbsp;&nbsp;&nbsp;return new BlockRenderer(component.getComponent("block"));
050 * <br>&nbsp;&nbsp;}
051 * <br>}
052 * </code>
053 * 
054 * @author mindbridge
055 * @since 2.2
056 */
057public class BlockRenderer implements IRender
058{
059        private Block m_objBlock;
060
061        /**
062         * Creates a new BlockRenderer that will render the content of the argument
063         * @param objBlock the Block to be rendered
064         */
065        public BlockRenderer(Block objBlock)
066        {
067                m_objBlock = objBlock;
068        }
069
070        /**
071         * @see org.apache.tapestry.IRender#render(IMarkupWriter, IRequestCycle)
072         */
073        public void render(IMarkupWriter writer, IRequestCycle cycle)
074        {
075                m_objBlock.renderBody(writer, cycle);
076        }
077
078}