sitemesh + ww1 + velocity

"Jan Berkel" <[email protected]>
Newsgroups gmane.comp.web.sitemesh.general
Message-ID <[email protected]>
Hi,

I adapted the VelocityDecoratorServlet from CVS to work with Webwork1. It
will use the velocity config from webwork (basically a cut and paste
from VelocityHelper).

I wanted to be able to access the action from the decorator page, for
error messages display etc.

The problem is that at decorating-time the action is no longer on the
value stack, and the VelocityDecoratorServlet doesn't use webwork's own
context. A workaround was to grab the action from the attribute
"webwork.valuestack.head" and to setup a valuestack containing just this
action. The static class WebWorkVelocityContext is also a cut'n'paste
from VelocityHelper (it has package access there, unfortunately).

Is there are better way ? Or shouldn't the decorator page have access to
framework internals ?

        Jan
WebWorkVelocityDecoratorServlet.java (text/x-java, 2.7 KB)
import com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import webwork.config.Configuration;
import webwork.dispatcher.ServletDispatcher;
import webwork.util.ServletValueStack;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;

/**
 * WebWork specific decorator for sitemesh.
 */
public class WebWorkVelocityDecoratorServlet extends VelocityDecoratorServlet {

    protected Properties loadConfiguration(ServletConfig config) throws IOException, FileNotFoundException {
        // WebWork configuration provides main config
        final Properties conf = new Properties() {
            public Object get(Object key) {
                return Configuration.get(key.toString());
            }

            public String getProperty(String key) {
                return Configuration.getString(key.toString());
            }

            public Enumeration keys() {
                final Iterator list = Configuration.list();
                return new Enumeration() {
                    public Object nextElement() {
                        return list.next();
                    }

                    public boolean hasMoreElements() {
                        return list.hasNext();
                    }
                };
            }
        };

        return conf;
    }

    protected Context createContext(HttpServletRequest request, HttpServletResponse response) {
        Context ctxt;
        ServletValueStack vs = new ServletValueStack();
        // push last action on stack on new vs
        vs.pushValue(request.getAttribute(ServletDispatcher.STACK_HEAD));
        ctxt = new WebWorkVelocityContext(vs);

        ctxt.put(REQUEST,  request);
        ctxt.put(RESPONSE, response);
        return ctxt;
    }

    /**
     * WebWork specific Velocity context implementation.
     */
    public static class WebWorkVelocityContext extends VelocityContext {
        ServletValueStack stack;

        WebWorkVelocityContext(ServletValueStack aStack) {
            stack = aStack;
        }

        public boolean internalContainsKey(java.lang.Object key) {
            boolean contains = super.internalContainsKey(key);
            return contains ? true : stack.test(key.toString());
        }

        public Object internalGet(String key) {
            return super.internalContainsKey(key) ? super.internalGet(key) : stack.findValue(key);
        }
    }
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.