1/*2 * $Id: RenderTag.java 749983 2009-03-04 12:41:31Z apetrelli $3 *4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */21package org.apache.tiles.jsp.taglib;
2223import java.io.IOException;
2425import javax.servlet.jsp.PageContext;
2627import org.apache.commons.logging.Log;
28import org.apache.commons.logging.LogFactory;
29import org.apache.tiles.Attribute;
30import org.apache.tiles.AttributeContext;
31import org.apache.tiles.ListAttribute;
32import org.apache.tiles.TilesContainer;
33import org.apache.tiles.jsp.context.JspUtil;
3435/***36 * <p>37 * Abstracts class for all tags which render (an attribute, a template, or38 * definition).39 * </p>40 * <p>41 * Properly invokes the defined preparer and invokes the abstract render method42 * upon completion.43 * </p>44 * This tag takes special care to ensure that the attribute context is reset to45 * it's original state after the execution of the tag is complete. This ensures46 * that all all included attributes in subsequent tiles are scoped properly and47 * do not bleed outside their intended scope.48 *49 * @since 2.1.150 * @version $Rev: 749983 $ $Date: 2009-03-04 13:41:31 +0100 (mer, 04 mar 2009) $51 */52publicabstractclassRenderTagextendsTilesBodyTag implements
53 PutAttributeTagParent, PutListAttributeTagParent {
5455/***56 * The log instance for this tag.57 */58privatefinal Log log = LogFactory.getLog(RenderTag.class);
5960/***61 * The role to check. If the user is in the specified role, the tag is taken62 * into account; otherwise, the tag is ignored (skipped).63 *64 * @since 2.1.165 */66protected String role;
6768/***69 * The view preparer to use before the rendering.70 *71 * @since 2.1.172 */73protected String preparer;
7475/***76 * This flag, if <code>true</code>, flushes the content before rendering.77 *78 * @since 2.1.179 */80protectedboolean flush;
8182/***83 * This flag, if <code>true</code>, ignores exception thrown by preparers84 * and those caused by problems with definitions.85 *86 * @since 2.1.187 */88protectedboolean ignore;
8990/***91 * The Tiles container that can be used inside the tag.92 *93 * @since 2.1.194 */95protected TilesContainer container;
9697/***98 * The attribute context to use to store and read attribute values.99 *100 * @since 2.1.1101 */102protected AttributeContext attributeContext;
103104/***105 * Returns the role to check. If the user is in the specified role, the tag is106 * taken into account; otherwise, the tag is ignored (skipped).107 *108 * @return The role to check.109 * @since 2.1.1110 */111public String getRole() {
112return role;
113 }
114115/***116 * Sets the role to check. If the user is in the specified role, the tag is117 * taken into account; otherwise, the tag is ignored (skipped).118 *119 * @param role The role to check.120 * @since 2.1.1121 */122publicvoid setRole(String role) {
123this.role = role;
124 }
125126/***127 * Returns the preparer name.128 *129 * @return The preparer name.130 * @since 2.1.1131 */132public String getPreparer() {
133return preparer;
134 }
135136/***137 * Sets the preparer name.138 *139 * @param preparer The preparer name.140 * @since 2.1.1141 */142publicvoid setPreparer(String preparer) {
143this.preparer = preparer;
144 }
145146/***147 * Returns the flush flag. If <code>true</code>, current page out stream148 * is flushed before insertion.149 *150 * @return The flush flag.151 * @since 2.1.1152 */153publicboolean isFlush() {
154return flush;
155 }
156157/***158 * Sets the flush flag. If <code>true</code>, current page out stream159 * is flushed before insertion.160 *161 * @param flush The flush flag.162 * @since 2.1.1163 */164publicvoid setFlush(boolean flush) {
165this.flush = flush;
166 }
167168/***169 * Returns the ignore flag. If it is set to true, and the attribute170 * specified by the name does not exist, simply return without writing171 * anything. The default value is false, which will cause a runtime172 * exception to be thrown.173 *174 * @return The ignore flag.175 * @since 2.1.1176 */177publicboolean isIgnore() {
178return ignore;
179 }
180181/***182 * Sets the ignore flag. If this attribute is set to true, and the attribute183 * specified by the name does not exist, simply return without writing184 * anything. The default value is false, which will cause a runtime185 * exception to be thrown.186 *187 * @param ignore The ignore flag.188 * @since 2.1.1189 */190publicvoid setIgnore(boolean ignore) {
191this.ignore = ignore;
192 }
193194/*** {@inheritDoc} */195 @Override
196protectedvoid reset() {
197super.reset();
198 preparer = null;
199 flush = false;
200 ignore = false;
201 container = null;
202 attributeContext = null;
203 role = null;
204 }
205206/*** {@inheritDoc} */207publicint doStartTag() throws TilesJspException {
208 container = JspUtil.getCurrentContainer(pageContext);
209if (container != null) {
210 startContext(pageContext);
211return EVAL_BODY_BUFFERED;
212 } else {
213thrownewTilesJspException("TilesContainer not initialized");
214 }
215 }
216217/*** {@inheritDoc} */218publicint doEndTag() throws TilesJspException {
219try {
220 render();
221if (flush) {
222 pageContext.getOut().flush();
223 }
224225return EVAL_PAGE;
226 } catch (IOException io) {
227 String message = "IO Error executing tag: " + io.getMessage();
228 log.error(message, io);
229thrownewTilesJspException(message, io);
230 } finally {
231 endContext(pageContext);
232 }
233 }
234235/***236 * Render the specified content.237 *238 * @throws TilesJspException if a jsp exception occurs.239 * @throws IOException if an io exception occurs.240 */241protectedabstractvoid render() throws TilesJspException, IOException;
242243/***244 * Starts the context when entering the tag.245 *246 * @param context The page context to use.247 */248protectedvoid startContext(PageContext context) {
249if (container != null) {
250 attributeContext = container.startContext(pageContext);
251 }
252 }
253254/***255 * Ends the context when exiting the tag.256 *257 * @param context The page context to use.258 */259protectedvoid endContext(PageContext context) {
260if (attributeContext != null && container != null) {
261 container.endContext(pageContext);
262 }
263 }
264265/***266 * <p>267 * Process nested ≶put> tag.268 * <p/>269 * <p>270 * Places the value of the nested tag within the271 * {@link org.apache.tiles.AttributeContext}.It is the responsibility272 * of the descendent to check security. Security will be managed by273 * called tags.274 * </p>275 *276 * @param nestedTag the put tag desciendent.277 */278publicvoid processNestedTag(PutAttributeTag nestedTag) {
279 Attribute attribute = new Attribute(
280 nestedTag.getValue(), null,
281 nestedTag.getRole(), nestedTag.getType());
282283 attributeContext.putAttribute(nestedTag.getName(), attribute, nestedTag
284 .isCascade());
285 }
286287/*** {@inheritDoc} */288publicvoid processNestedTag(PutListAttributeTag nestedTag) {
289 ListAttribute attribute = new ListAttribute(nestedTag.getAttributes());
290 attribute.setRole(nestedTag.getRole());
291 attribute.setInherit(nestedTag.getInherit());
292293 attributeContext.putAttribute(nestedTag.getName(), attribute, nestedTag
294 .isCascade());
295 }
296 }