Package com.samskivert.velocity

Source Code of com.samskivert.velocity.ImportDirective

//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2012 Michael Bayne, et al.
// http://github.com/samskivert/samskivert/blob/master/COPYING

package com.samskivert.velocity;

import java.io.IOException;
import java.io.Writer;

import org.apache.velocity.context.InternalContextAdapter;

import org.apache.velocity.Template;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.resource.Resource;

import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.util.StringUtil;

/**
* Pluggable directive that handles the #import() statement in VTL. Import is like #parse() except
* that it creates a compound key (<code>siteId:template_path</code>) based on information from the
* current request when fetching the imported template.
*/
public class ImportDirective extends Directive
{
    /**
     * Returns name of this directive.
     */
    @Override
    public String getName ()
    {
        return "import";
    }

    /**
     * Return type of this directive.
     */
    @Override
    public int getType ()
    {
        return LINE;
    }

    /**
     * Loads and renders the imported template.
     */
    @Override
    public boolean render (
        InternalContextAdapter context, Writer writer, Node node)
        throws IOException, ResourceNotFoundException, ParseErrorException,
               MethodInvocationException
    {
        // make sure an argument was supplied to the directive
        if (node.jjtGetChild(0) == null) {
            rsvc.getLog().error("#import() error :  null argument");
            return false;
        }

        // make sure that argument has a value
        Object value = node.jjtGetChild(0).value(context);
        if (value == null) {
            rsvc.getLog().error("#import() error :  null argument");
            return false;
        }

        // obtain the path to the desired template
        String path = value.toString();

        // make sure we haven't exceeded the configured parse depth
        Object[] templateStack = context.getTemplateNameStack();
        int maxlen = rsvc.getInt(
            RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 20);
        if (templateStack.length >= maxlen) {
            rsvc.getLog().error("Max recursion depth reached (" + maxlen + "). "  +
                                "File stack: " + StringUtil.toString(templateStack) + ".");
            return false;
        }

        // inherit the current encoding if there is a current template,
        // otherwise use the configured encoding
        String encoding = null;
        Resource current = context.getCurrentResource();
        if (current != null) {
            encoding = current.getEncoding();
        } else {
            encoding = (String)
                rsvc.getProperty(RuntimeConstants.INPUT_ENCODING);
        }

        // adjust the template path with the site information in the current
        // context if available. the siteid is shoved into the context by the
        // dispatcher servlet when we're using the site resource loader. this
        // is a hack, i know, but i couldn't convince the velocity peeps that
        // we should have access to a request context in places like this
        Object siteIdVal = context.get("__siteid__");
        if (siteIdVal != null) {
            int siteId = SiteIdentifier.DEFAULT_SITE_ID;
            try {
                siteId = ((Integer)siteIdVal).intValue();
            } catch (Exception e) {
                rsvc.getLog().error("#import() error: No siteId information in context.");
            }
            path = siteId + ":" + path;
        }

        // locate the requested template
        Template t = null;
        try {
            t = rsvc.getTemplate(path, encoding);

        } catch (ResourceNotFoundException rnfe) {
            rsvc.getLog().error("#import(): cannot find template '" + path +
                                "', called from template " + context.getCurrentTemplateName() +
                                " at (" + getLine() + ", " + getColumn() + ")");
            throw rnfe;

        } catch (ParseErrorException pee) {
            rsvc.getLog().error("#import(): syntax error in #import()-ed template '" + path +
                                "', called from template " + context.getCurrentTemplateName() +
                                " at (" + getLine() + ", " + getColumn() + ")");
            throw pee;

        } catch (Exception e) {
            rsvc.getLog().error("#import(): Error [path=" + path + ", error=" + e + "].");
            return false;
        }

        // finally render the template
        try {
            context.pushCurrentTemplateName(path);
            ((SimpleNode)t.getData()).render(context, writer);

        } catch (Throwable th) {
            rsvc.getLog().error("Exception rendering #import(" + path + "): " + th);
            // we want to pass method invocation exceptions through
            if (th instanceof MethodInvocationException) {
                throw (MethodInvocationException)th;
            }
            return false;

        } finally {
            context.popCurrentTemplateName();
        }

        return true;
    }
}
TOP

Related Classes of com.samskivert.velocity.ImportDirective

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.