Package com.opensymphony.webwork.portlet.velocity

Source Code of com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective$DirectiveStack

package com.opensymphony.webwork.portlet.velocity;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Category;
import org.apache.velocity.context.Context;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.Node;

import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.Factory;
import com.opensymphony.module.sitemesh.HTMLPage;
import com.opensymphony.module.sitemesh.parser.FastPageParser;
import com.opensymphony.module.sitemesh.util.OutputConverter;
import com.opensymphony.webwork.portlet.context.PortletContext;
import com.opensymphony.webwork.portlet.sitemesh.VelocityUtils;
import com.opensymphony.webwork.views.velocity.VelocityManager;
import com.opensymphony.xwork.ActionContext;

/**
* @author Henry Hu  -- hu_pengfei@yahoo.com.cn
* @since 2005-7-6
*/
public final class ApplyDecoratorDirective extends Directive {
    private static final Category log;

    public static final String STACK_KEY;

    private DirectiveStack stack;

    private Map params;

    static {
        log = Category.getInstance(com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective.class);
        STACK_KEY = (com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective.DirectiveStack.class).getName();
    }

    public class DirectiveStack {

        public ApplyDecoratorDirective pop() {
            try {
                return (ApplyDecoratorDirective) stack.pop();
            } catch (EmptyStackException e) {
                ApplyDecoratorDirective.log.info("Someone's been popping out of order! " + e.getMessage(), e);
                return null;
            }
        }

        public void push(ApplyDecoratorDirective directive) {
            stack.push(directive);
        }

        public ApplyDecoratorDirective peek() {
            if (stack.size() > 0)
                return (ApplyDecoratorDirective) stack.peek();
            else
                return null;
        }

        Stack stack;

        public DirectiveStack() {
            stack = new Stack();
        }
    }

    public ApplyDecoratorDirective() {
        params = new HashMap();
    }

    public String getName() {
        return "applyDecorator";
    }

    public int getType() {
        return 1;
    }

    public void init(RuntimeServices services, InternalContextAdapter adapter, Node node) throws Exception {
        super.init(services, adapter, node);
        int numArgs = node.jjtGetNumChildren();
        if (numArgs < 2)
            services.error("#applyDecorator error: You need a decorator name in order to use this tag");
        else if (numArgs > 3)
            services.error("#applyDecorator error: Too many parameters");
    }

    public boolean render(InternalContextAdapter adapter, Writer writer, Node node) throws IOException, ResourceNotFoundException,
            ParseErrorException, MethodInvocationException {

        stack = (DirectiveStack) adapter.get(STACK_KEY);
        if (stack == null) {
            stack = new DirectiveStack();
            adapter.put(STACK_KEY, stack);
        }
        stack.push(this);

        boolean flag;
        HttpServletRequest request = (HttpServletRequest) adapter.get("req");
        if (request == null)
            throw new IOException("No request object in context.");

        HttpServletResponse response = (HttpServletResponse) adapter.get("res");
        if (response == null)
            throw new IOException("No response object in context.");

        try {
            String decoratorName = (String) node.jjtGetChild(0).value(adapter);
            StringWriter bodyContent = new StringWriter(1024);

            int bodyNode = 1;
            if (node.jjtGetNumChildren() == 3)
                bodyNode = 2;
            node.jjtGetChild(bodyNode).render(adapter, bodyContent);

            Factory factory = PortletContext.getContext().getSiteMeshFactory();
            Decorator decorator = factory.getDecoratorMapper().getNamedDecorator(request, decoratorName);
            if (decorator != null) {
                com.opensymphony.module.sitemesh.PageParser parser = factory.getPageParser("text/html");
                HTMLPage page = (HTMLPage) ((FastPageParser) parser).parse(new StringReader(bodyContent.toString()));
                Context context = VelocityManager.getInstance()
                        .createContext(ActionContext.getContext().getValueStack(), request, response);
                context.put("page", page);
                if (node.jjtGetNumChildren() == 3)
                    context.put("title", (String) node.jjtGetChild(1).value(adapter));
                else
                    context.put("title", page.getTitle());
                StringWriter buffer = new StringWriter();
                page.writeBody(OutputConverter.getWriter(buffer));
                context.put("body", buffer.toString());
                buffer = new StringWriter();
                page.writeHead(OutputConverter.getWriter(buffer));
                context.put("head", buffer.toString());
                context.put("params", params);
                writer.write(VelocityUtils.getRenderedTemplate(decorator.getPage(), context));
            } else {
                throw new IOException("could not find decorator with name: " + decoratorName);
            }
            flag = true;
            stack.pop();

            return flag;
        } catch (Exception exception) {

            stack.pop();
            throw new IOException(exception.toString());
        }
    }

    public void addParameter(String paramName, Object paramValue) {
        params.put(paramName, paramValue);
    }

}
TOP

Related Classes of com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective$DirectiveStack

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.