You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by nb...@apache.org on 2003/07/24 06:59:22 UTC
cvs commit: jakarta-velocity-tools/src/java/org/apache/velocity/tools/struts TilesTool.java
nbubna 2003/07/23 21:59:21
Added: src/java/org/apache/velocity/tools/struts TilesTool.java
Log:
Initial revision. (contributed by Marin� A. J�nsson)
Revision Changes Path
1.1 jakarta-velocity-tools/src/java/org/apache/velocity/tools/struts/TilesTool.java
Index: TilesTool.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Velocity", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.velocity.tools.struts;
import java.util.Stack;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletContext;
import java.io.StringWriter;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.Template;
import org.apache.struts.tiles.ComponentContext;
import org.apache.struts.tiles.ComponentDefinition;
import org.apache.struts.tiles.AttributeDefinition;
import org.apache.struts.tiles.DirectStringAttribute;
import org.apache.struts.tiles.DefinitionAttribute;
import org.apache.struts.tiles.DefinitionNameAttribute;
import org.apache.struts.tiles.PathAttribute;
import org.apache.struts.tiles.TilesUtil;
import org.apache.struts.tiles.DefinitionsFactoryException;
import org.apache.struts.tiles.Controller;
import org.apache.velocity.tools.view.context.ViewContext;
import org.apache.velocity.tools.view.tools.ViewTool;
/**
* <p>Title: TilesTool</p>
* <p>Description: A tool to use struts-tiles with Velocity</p>
* <p>Usage:
*
* Just call $tiles.name_of_tile_definition from the template to insert
* the tile.
*
* $tiles.getString("name_of_tile_attribute") fetches a named attribute-value
* from the current tiles-context.
*
* @author <a href="mailto:marinoj@centrum.is">Marino A. Jonsson</a>
* @version $Revision: 1.1 $ $Date: 2003/07/24 04:59:21 $
*/
public class TilesTool implements ViewTool
{
protected ViewContext context;
protected ServletContext application;
protected HttpServletRequest request;
protected HttpServletResponse response;
/**
* A stack to hold ComponentContexts while nested tile-definitions
* are rendered.
*/
protected Stack contextStack;
/******************************* Constructors ****************************/
/**
* Default constructor. Tool must be initialized before use.
*/
public TilesTool() {}
/**
* Initializes this tool.
*
* @param obj the current ViewContext
* @throws IllegalArgumentException if the param is not a ViewContext
*/
public void init(Object obj)
{
if (!(obj instanceof ViewContext))
{
throw new IllegalArgumentException("Tool can only be initialized with a ViewContext");
}
this.context = (ViewContext)obj;
this.request = context.getRequest();
this.response = context.getResponse();
this.application = context.getServletContext();
}
/***************************** View Helpers ******************************/
/**
* Fetches a named attribute value from the current tiles-context.
*
* <p>This is functionally equivalent to
* <code><tiles:getAsString name="title" /></code>.</p>
*
* @param name the name of the tiles-attribute to fetch
* @return the attribute value as String
*/
public String getString(String name)
{
ComponentContext context = ComponentContext.getContext(request);
Object attrValue = context.getAttribute(name);
if (attrValue == null)
{
return null;
}
return attrValue.toString();
}
/**
* <p>A generic tiles insert function</p>
*
* <p>This is functionally equivalent to
* <code><tiles:insert attribute="menu" /></code>.</p>
*
* @param attr - can be any of the following:
* AttributeDefinition,
* tile-definition name,
* tile-attribute name,
* regular uri.
* (checked in that order)
* @return the rendered template or value as a String
* @throws Exception on failure
*/
public String get(Object attr) throws Exception
{
ComponentContext currentContext = ComponentContext.getContext(request);
Object attrValue = currentContext.getAttribute(attr.toString());
if (attrValue != null)
{
return processObjectValue(attrValue);
}
return processAsDefinitionOrURL(attr.toString());
}
/************************** Protected Methods ****************************/
/**
* Process an object retrieved as a bean or attribute.
*
* @param value - Object can be a typed attribute, a String, or anything
* else. If typed attribute, use associated type. Otherwise, apply
* toString() on object, and use returned string as a name.
* @throws Exception - Throws by underlying nested call to
* processDefinitionName()
* @return the fully processed value as String
*/
protected String processObjectValue(Object value) throws Exception
{
/* First, check if value is one of the Typed Attribute */
if (value instanceof AttributeDefinition)
{
/* We have a type => return appropriate IncludeType */
return processTypedAttribute((AttributeDefinition)value);
}
else if (value instanceof ComponentDefinition)
{
return processDefinition((ComponentDefinition)value);
}
/* Value must denote a valid String */
return processAsDefinitionOrURL(value.toString());
}
/**
* Process typed attribute according to its type.
*
* @param value Typed attribute to process.
* @return the fully processed attribute value as String.
* @throws Exception - Throws by underlying nested call to processDefinitionName()
*/
protected String processTypedAttribute(AttributeDefinition value) throws Exception {
if (value instanceof DirectStringAttribute)
{
return (String)value.getValue();
}
else if (value instanceof DefinitionAttribute)
{
return processDefinition((ComponentDefinition)value.getValue());
}
else if (value instanceof DefinitionNameAttribute)
{
return processAsDefinitionOrURL((String)value.getValue());
}
/* else if( value instanceof PathAttribute ) */
return doInsert((String)value.getValue(), null, null);
}
/**
* Try to process name as a definition, or as an URL if not found.
*
* @param name Name to process.
* @return the fully processed definition or URL
* @throws Exception
*/
protected String processAsDefinitionOrURL(String name) throws Exception {
try
{
ComponentDefinition definition =
TilesUtil.getDefinition(name, request, application);
if (definition != null)
{
return processDefinition(definition);
}
}
catch (DefinitionsFactoryException ex)
{
/* silently failed, because we can choose to not define a factory. */
}
/* no definition found, try as url */
return processUrl(name);
}
/**
* End of Process for definition.
*
* @param definition Definition to process.
* @return the fully processed definition.
* @throws Exception from InstantiationException Can't create requested controller
*/
protected String processDefinition(ComponentDefinition definition) throws Exception
{
Controller controller = null;
try
{
controller = definition.getOrCreateController();
String role = definition.getRole();
String page = definition.getTemplate();
return doInsert(definition.getAttributes(),
page,
role,
controller);
}
catch (InstantiationException ex)
{
throw new Exception(ex.getMessage());
}
}
/**
* Processes an url
*
* @param url the URI to process.
* @return the rendered template as String.
* @throws Exception
*/
protected String processUrl(String url) throws Exception
{
return doInsert(url, null, null);
}
/**
* Use this if there is no nested tile.
*
* @param page the page to process.
* @param role possible user-role
* @param controller possible tiles-controller
* @return the rendered template as String.
* @throws Exception
*/
protected String doInsert(String page, String role, Controller controller) throws Exception
{
if (role != null && !request.isUserInRole(role))
{
return null;
}
ComponentContext subCompContext = new ComponentContext();
return doInsert(subCompContext, page, role, controller);
}
/**
* Use this if there is a nested tile.
*
* @param attributes attributes for the sub-context
* @param page the page to process.
* @param role possible user-role
* @param controller possible tiles-controller
* @return the rendered template as String.
* @throws Exception
*/
protected String doInsert(Map attributes,
String page,
String role,
Controller controller) throws Exception
{
if (role != null && !request.isUserInRole(role))
{
return null;
}
ComponentContext subCompContext = new ComponentContext(attributes);
return doInsert(subCompContext, page, role, controller);
}
/**
* An extension of the other two doInsert functions
*
* @param subCompContext the sub-context to set in scope when the
* template is rendered.
* @param page the page to process.
* @param role possible user-role
* @param controller possible tiles-controller
* @return the rendered template as String.
* @throws Exception
*/
protected String doInsert(ComponentContext subCompContext,
String page,
String role,
Controller controller) throws Exception
{
pushTilesContext();
try
{
ComponentContext.setContext(subCompContext, request);
/* Call controller if any */
if (controller != null)
{
controller.perform(subCompContext,
request,
response,
application);
}
return parse(page);
}
finally
{
popTilesContext();
}
}
/**
* <p>pushes the current tiles context onto the context-stack.
* preserving the context is necessary so that a sub-context can be
* put into request scope and lower level tiles can be rendered</p>
*/
protected void pushTilesContext()
{
if (contextStack == null)
{
contextStack = new Stack();
}
contextStack.push(ComponentContext.getContext(request));
}
/**
* <p>pops the tiles sub-context off the context-stack after the lower level
* tiles have been rendered</p>
*/
protected void popTilesContext()
{
ComponentContext.setContext((ComponentContext)contextStack.pop(), request);
}
/**
* <p>Renders a template</p>
*
* @param templateName - name of template to be rendered
* @throws Exception if it fails
* @return the rendered template as a String
*/
protected String parse(String templateName) throws Exception
{
StringWriter sw = new StringWriter();
Template template = Velocity.getTemplate(templateName);
template.merge(context.getVelocityContext(), sw);
return sw.toString();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org