Added: struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
URL:
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java?rev=835248&view=auto==============================================================================
--- struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java (added)
+++ struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java Thu Nov 12 06:06:40 2009
@@ -0,0 +1,182 @@
+/**
+ * <p>This is a SiteMesh Velocity view servlet.</p>
+ *
+ * <p>It overrides the SiteMesh servlet to rely on the
+ * Velocity Manager in Struts instead of creating it's
+ * own manager</p>
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.sitemesh;
+
+
+import com.opensymphony.module.sitemesh.*;
+import com.opensymphony.module.sitemesh.util.OutputConverter;
+import com.opensymphony.xwork2.ActionContext;
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.StrutsStatics;
+import org.apache.struts2.dispatcher.Dispatcher;
+import org.apache.struts2.dispatcher.ng.listener.StrutsListener;
+import org.apache.struts2.views.velocity.VelocityManager;
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.tools.view.servlet.VelocityViewServlet;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.StringWriter;
+
+/**
+ * <p>This is a SiteMesh Velocity view servlet.</p>
+ * <p/>
+ * <p>It overrides the SiteMesh servlet to rely on the
+ * Velocity Manager in Struts instead of creating it's
+ * own manager</p>
+ */
+public class VelocityDecoratorServlet extends VelocityViewServlet {
+
+ protected VelocityManager velocityManager;
+ protected String defaultContentType;
+
+ /**
+ * <p>Initializes servlet, toolbox and Velocity template engine.
+ * Called by the servlet container on loading.</p>
+ * <p/>
+ * <p>NOTE: If no charset is specified in the default.contentType
+ * property (in your velocity.properties) and you have specified
+ * an output.encoding property, then that will be used as the
+ * charset for the default content-type of pages served by this
+ * servlet.</p>
+ *
+ * @param config servlet configuation
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ Dispatcher dispatcher = (Dispatcher) getServletContext().getAttribute(StrutsStatics.SERVLET_DISPATCHER);
+ if (dispatcher == null)
+ throw new IllegalStateException("Unable to find the Dispatcher in the Servlet Context. Is '" + StrutsListener.class.getName() + "' missing in web.xml?");
+ velocityManager = dispatcher.getContainer().getInstance(VelocityManager.class);
+ velocityManager.init(config.getServletContext());
+
+ // do whatever we have to do to init Velocity
+ setVelocityEngine(velocityManager.getVelocityEngine());
+ toolboxManager = velocityManager.getToolboxManager();
+
+ // we can get these now that velocity is initialized
+ defaultContentType = (String) getVelocityProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
+
+ String encoding = (String) getVelocityProperty(RuntimeConstants.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING);
+
+ // For non Latin-1 encodings, ensure that the charset is
+ // included in the Content-Type header.
+ if (!DEFAULT_OUTPUT_ENCODING.equalsIgnoreCase(encoding)) {
+ int index = defaultContentType.lastIndexOf("charset");
+ if (index < 0) {
+ // the charset specifier is not yet present in header.
+ // append character encoding to default content-type
+ defaultContentType += "; charset=" + encoding;
+ } else {
+ // The user may have configuration issues.
+ getVelocityEngine().warn("VelocityViewServlet: Charset was already " + "specified in the Content-Type property. " + "Output encoding property will be ignored.");
+ }
+ }
+
+ getVelocityEngine().info("VelocityViewServlet: Default content-type is: " + defaultContentType);
+ }
+
+ public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws Exception {
+ HTMLPage htmlPage = (HTMLPage) request.getAttribute(RequestConstants.PAGE);
+ String template;
+
+ context.put("base", request.getContextPath());
+ // For backwards compatability with apps that used the old VelocityDecoratorServlet
+ // that extended VelocityServlet instead of VelocityViewServlet
+ context.put("req", request);
+ context.put("res", response);
+
+ if (htmlPage == null) {
+ context.put("title", "Title?");
+ context.put("body", "<p>Body?</p>");
+ context.put("head", "<!-- head -->");
+ template = request.getServletPath();
+ } else {
+ context.put("title", OutputConverter.convert(htmlPage.getTitle()));
+ {
+ StringWriter buffer = new StringWriter();
+ htmlPage.writeBody(OutputConverter.getWriter(buffer));
+ context.put("body", buffer.toString());
+ }
+ {
+ StringWriter buffer = new StringWriter();
+ htmlPage.writeHead(OutputConverter.getWriter(buffer));
+ context.put("head", buffer.toString());
+ }
+ context.put("page", htmlPage);
+ DecoratorMapper decoratorMapper = getDecoratorMapper();
+ Decorator decorator = decoratorMapper.getDecorator(request, htmlPage);
+ template = decorator.getPage();
+ }
+
+ return getTemplate(template);
+ }
+
+ private DecoratorMapper getDecoratorMapper() {
+ Factory factory = Factory.getInstance(new Config(getServletConfig()));
+ DecoratorMapper decoratorMapper = factory.getDecoratorMapper();
+ return decoratorMapper;
+ }
+
+ /**
+ * <p>Creates and returns an initialized Velocity context.</p>
+ *
+ * @param request servlet request from client
+ * @param response servlet reponse to client
+ */
+ protected Context createContext(HttpServletRequest request, HttpServletResponse response) {
+ Context context = (Context) request.getAttribute(VelocityManager.KEY_VELOCITY_STRUTS_CONTEXT);
+ if (context == null) {
+ ActionContext ctx = ServletActionContext.getActionContext(request);
+ context = velocityManager.createContext(ctx.getValueStack(), request, response);
+ }
+ return context;
+ }
+
+ /**
+ * Sets the content type of the response. This is available to be overriden
+ * by a derived class.
+ * <p/>
+ * <p>The default implementation is :
+ * <pre>
+ * <p/>
+ * response.setContentType(defaultContentType);
+ * <p/>
+ * </pre>
+ * where defaultContentType is set to the value of the default.contentType
+ * property, or "text/html" if that is not set.</p>
+ *
+ * @param request servlet request from client
+ * @param response servlet reponse to client
+ */
+ protected void setContentType(HttpServletRequest request, HttpServletResponse response) {
+ response.setContentType(defaultContentType);
+ }
+
+}
Added: struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityMapper2DecoratorSelector.java
URL:
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityMapper2DecoratorSelector.java?rev=835248&view=auto==============================================================================
--- struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityMapper2DecoratorSelector.java (added)
+++ struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityMapper2DecoratorSelector.java Thu Nov 12 06:06:40 2009
@@ -0,0 +1,64 @@
+/*
+ * $Id: NoneDecoratorMapper.java 651946 2008-04-27 13:41:38Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts2.sitemesh;
+
+import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
+import com.opensymphony.module.sitemesh.Decorator;
+import com.opensymphony.module.sitemesh.Page;
+import com.opensymphony.module.sitemesh.DecoratorMapper;
+import com.opensymphony.sitemesh.DecoratorSelector;
+import com.opensymphony.sitemesh.Content;
+import com.opensymphony.sitemesh.SiteMeshContext;
+import com.opensymphony.sitemesh.compatability.Content2HTMLPage;
+import com.opensymphony.sitemesh.compatability.OldDecorator2NewDecorator;
+import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext;
+import com.opensymphony.sitemesh.webapp.decorator.NoDecorator;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Returns a {@link OldDecorator2NewStrutsVelocityDecorator} decorator
+ * for a velocity request.
+ *
+ * Won't decorate the output if it finds a "decorator" flag in the request
+ */
+public class VelocityMapper2DecoratorSelector implements DecoratorSelector {
+
+ private final DecoratorMapper decoratorMapper;
+
+ public VelocityMapper2DecoratorSelector(DecoratorMapper decoratorMapper) {
+ this.decoratorMapper = decoratorMapper;
+ }
+
+ public com.opensymphony.sitemesh.Decorator selectDecorator(Content content, SiteMeshContext context) {
+ SiteMeshWebAppContext webAppContext = (SiteMeshWebAppContext) context;
+ HttpServletRequest request = webAppContext.getRequest();
+ Decorator decorator =
+ decoratorMapper.getDecorator(request, new Content2HTMLPage(content, request));
+ if (decorator == null || decorator.getPage() == null) {
+ return new NoDecorator();
+ } else {
+ return new OldDecorator2NewStrutsVelocityDecorator(decorator);
+ }
+ }
+}
+
Modified: struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
URL:
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java?rev=835248&r1=835247&r2=835248&view=diff==============================================================================
--- struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java (original)
+++ struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java Thu Nov 12 06:06:40 2009
@@ -18,92 +18,42 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.struts2.sitemesh;
-import java.io.IOException;
-import java.io.PrintWriter;
+import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext;
+import com.opensymphony.sitemesh.webapp.SiteMeshFilter;
+import com.opensymphony.sitemesh.DecoratorSelector;
+import com.opensymphony.module.sitemesh.Factory;
+import com.opensymphony.module.sitemesh.Config;
+import com.opensymphony.xwork2.inject.Inject;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import javax.servlet.*;
import org.apache.struts2.views.velocity.VelocityManager;
-import org.apache.velocity.Template;
-import org.apache.velocity.context.Context;
-
-import com.opensymphony.module.sitemesh.Decorator;
-import com.opensymphony.module.sitemesh.HTMLPage;
-import com.opensymphony.module.sitemesh.Page;
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
-
/**
- * Applies Velocity-based decorators
- *
+ * Core Filter for integrating SiteMesh into a Java web application.
*/
-public class VelocityPageFilter extends TemplatePageFilter {
- private static final Logger LOG = LoggerFactory.getLogger(VelocityPageFilter.class);
+public class VelocityPageFilter extends SiteMeshFilter {
- private static VelocityManager velocityManager;
-
@Inject(required=false)
public static void setVelocityManager(VelocityManager mgr) {
- velocityManager = mgr;
+ OldDecorator2NewStrutsVelocityDecorator.setVelocityManager(mgr);
}
-
- /**
- * Applies the decorator, using the relevent contexts
- *
- * @param page The page
- * @param decorator The decorator
- * @param req The servlet request
- * @param res The servlet response
- * @param servletContext The servlet context
- * @param ctx The action context for this request, populated with the server state
- */
- protected void applyDecorator(Page page, Decorator decorator,
- HttpServletRequest req, HttpServletResponse res,
- ServletContext servletContext, ActionContext ctx)
- throws ServletException, IOException {
-
- if (velocityManager == null) {
- throw new ServletException("Missing freemarker dependency");
- }
-
- try {
-
- // init (if needed)
- velocityManager.init(servletContext);
-
- // get encoding
- String encoding = getEncoding();
-
- // get the template and context
- Template template = velocityManager.getVelocityEngine().getTemplate(decorator.getPage(), encoding);
- Context context = velocityManager.createContext(ctx.getValueStack(), req, res);
-
- // put the page in the context
- context.put("page", page);
- if (page instanceof HTMLPage) {
- HTMLPage htmlPage = ((HTMLPage) page);
- context.put("head", htmlPage.getHead());
- }
- context.put("title",page.getTitle());
- context.put("body",page.getBody());
-
- // finally, render it
- PrintWriter writer = res.getWriter();
- template.merge(context, writer);
- writer.flush();
- } catch (Exception e) {
- String msg = "Error applying decorator: " + e.getMessage();
- LOG.error(msg, e);
- throw new ServletException(msg, e);
- }
+
+ private FilterConfig filterConfig;
+
+ public void init(FilterConfig filterConfig) {
+ this.filterConfig = filterConfig;
+ super.init(filterConfig);
+ }
+
+ protected DecoratorSelector initDecoratorSelector(SiteMeshWebAppContext webAppContext) {
+ // TODO: Remove heavy coupling on horrible SM2 Factory
+ Factory factory = Factory.getInstance(new Config(filterConfig));
+ factory.refresh();
+ return new FreeMarkerMapper2DecoratorSelector(factory.getDecoratorMapper());
}
+
}
+