Differences between revisions 1 and 2
Revision 1 as of 2005-03-22 05:48:35
Size: 12922
Editor: anonymous
Comment: missing edit-log entry for this revision
Revision 2 as of 2009-09-20 23:12:36
Size: 12922
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

July 23, 2003

Here is the much anticipated TilesTool, to use with Velocity Tools and Struts 1.1 :)

I personally use the nested tiles and tile-controllers features, but I haven't tried other features you might be interested in.

Any comments are welcome on the Velocity Developer's List <velocity-dev@jakarta.apache.org>.

Marinó A. Jónsson


{ { { 

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; /**

    protected Stack contextStack; /******************************* Constructors ****************************/ /**
    • Default constructor. Tool must be initialized before use.
    • /

    public TilesTool() {} /**

    public void init(Object obj) { } /***************************** 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 { } /**
    • 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 {

    } /**
    • 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) {

      }

      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);

        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() { } /**
    • <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();

    } }}}

}

{{{ } } }

  • }}}

TilesTool (last edited 2009-09-20 23:12:36 by localhost)