/* * $Id: DefinitionTag.java 471754 2006-11-06 14:55:09Z husted $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.struts.tiles.taglib; import javax.servlet.jsp.JspException; import org.apache.struts.tiles.taglib.util.TagUtils; import org.apache.struts.tiles.AttributeDefinition; import org.apache.struts.tiles.ComponentDefinition; import org.apache.struts.tiles.UntypedAttribute; /** * This is the tag handler for <tiles:definition>, which defines * a tiles (or template / component). Definition is put in requested context and can be * used in <tiles:insert>. * * @version $Rev: 471754 $ $Date: 2006-11-06 15:55:09 +0100 (Mon, 06 Nov 2006) $ */ public class DefinitionTag extends DefinitionTagSupport implements PutTagParent, PutListTagParent { /* JSP Tag attributes */ /** * Definition identifier. */ private String id = null; /** * Scope into which definition will be saved. */ private String scope = null; /** * Extends attribute value. */ private String extendsDefinition = null; /* Internal properties */ /** * Template definition */ private ComponentDefinition definition = null; /** * Reset member values for reuse. This method calls super.release(), * which invokes TagSupport.release(), which typically does nothing. */ public void release() { super.release(); id = null; page = null; scope = null; role = null; extendsDefinition = null; } /** * Release internal references. */ protected void releaseInternal() { definition = null; } /** * This method is a convenience for other tags for * putting content into the tile definition. * Content is already typed by caller. */ public void putAttribute(String name, Object content) { definition.putAttribute(name, content); } /** * Process nested ≶put> tag. * Method is called from nested ≶put> tags. * Nested list is added to current list. * If role is defined, nested attribute is wrapped into an untyped definition * containing attribute value and role. */ public void processNestedTag(PutTag nestedTag) throws JspException { // Get real value and check role // If role is set, add it in attribute definition if any. // If no attribute definition, create untyped one and set role. Object attributeValue = nestedTag.getRealValue(); AttributeDefinition def; if (nestedTag.getRole() != null) { try { def = ((AttributeDefinition) attributeValue); } catch (ClassCastException ex) { def = new UntypedAttribute(attributeValue); } def.setRole(nestedTag.getRole()); attributeValue = def; } // now add attribute to enclosing parent (i.e. : this object) putAttribute(nestedTag.getName(), attributeValue); } /** * Process nested ≶putList> tag. * Method is called from nested ≶putList> tags. * Nested list is added to current list. * If role is defined, nested attribute is wrapped into an untyped definition * containing attribute value and role. */ public void processNestedTag(PutListTag nestedTag) throws JspException { // Get real value and check role // If role is set, add it in attribute definition if any. // If no attribute definition, create untyped one and set role. Object attributeValue = nestedTag.getList(); if (nestedTag.getRole() != null) { AttributeDefinition def = new UntypedAttribute(attributeValue); def.setRole(nestedTag.getRole()); attributeValue = def; } // Check if a name is defined if (nestedTag.getName() == null) { throw new JspException("Error - PutList : attribute name is not defined. It is mandatory as the list is added to a 'definition'."); } // now add attribute to enclosing parent (i.e. : this object). putAttribute(nestedTag.getName(), attributeValue); } /** * Get the ID. * @return ID */ public String getId() { return id; } /** * Set the ID. * @param id New ID. */ public void setId(String id) { this.id = id; } /** * Get the scope. * @return Scope. */ public String getScope() { return scope; } /** * Set the scope. * @param aScope Scope. */ public void setScope(String aScope) { scope = aScope; } /** * Set <code>extends</code> (parent) definition name. * @param definitionName Name of parent definition. */ public void setExtends(String definitionName) { this.extendsDefinition = definitionName; } /** * Get <code>extends</code> (parent) definition name. * @return Name of parent definition. */ public String getExtends() { return extendsDefinition; } /** * Process the start tag by creating a new definition. * @throws JspException On errors processing tag. */ public int doStartTag() throws JspException { // Do we extend a definition ? if (extendsDefinition != null && !extendsDefinition.equals("")) { ComponentDefinition parentDef = TagUtils.getComponentDefinition(extendsDefinition, pageContext); definition = new ComponentDefinition(parentDef); } else { definition = new ComponentDefinition(); } // Set definitions attributes if (page != null) { definition.setTemplate(page); } if (role != null) { definition.setRole(role); } return EVAL_BODY_INCLUDE; } /** * Process the end tag by putting the definition in appropriate context. * @throws JspException On errors processing tag. */ public int doEndTag() throws JspException { TagUtils.setAttribute(pageContext, id, definition, scope); releaseInternal(); return EVAL_PAGE; } }