blob: ff0a3ba6933f20b841addcb38489c8b69bc86643 [file] [log] [blame]
/*
* 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.taglib.tiles;
import javax.servlet.jsp.JspException;
import org.apache.taglib.tiles.util.TagUtils;
import org.apache.tiles.AttributeDefinition;
import org.apache.tiles.ComponentDefinition;
import org.apache.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&gt.
*
* @author Cedric Dumoulin
* @author David Geary
* $Id$
*/
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;
}
}