mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
Merge pull request #867 from apache/WW-5391-velocity-ext-point
WW-5391 Add interface for VelocityManager extension point
This commit is contained in:
+2
-2
@@ -30,7 +30,7 @@ import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerManager;
|
||||
import org.apache.struts2.views.velocity.VelocityConstants;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -56,7 +56,7 @@ public class ShowBeansAction extends ActionNamesAction {
|
||||
bindings.put(ActionMapper.class.getName(), addBindings(container, ActionMapper.class, StrutsConstants.STRUTS_MAPPER_CLASS));
|
||||
bindings.put(MultiPartRequest.class.getName(), addBindings(container, MultiPartRequest.class, StrutsConstants.STRUTS_MULTIPART_PARSER));
|
||||
bindings.put(FreemarkerManager.class.getName(), addBindings(container, FreemarkerManager.class, StrutsConstants.STRUTS_FREEMARKER_MANAGER_CLASSNAME));
|
||||
bindings.put(VelocityManager.class.getName(), addBindings(container, VelocityManager.class, VelocityConstants.STRUTS_VELOCITY_MANAGER_CLASSNAME));
|
||||
bindings.put(VelocityManagerInterface.class.getName(), addBindings(container, VelocityManagerInterface.class, VelocityConstants.STRUTS_VELOCITY_MANAGER_CLASSNAME));
|
||||
bindings.put(UrlRenderer.class.getName(), addBindings(container, UrlRenderer.class, StrutsConstants.STRUTS_URL_RENDERER));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,15 @@ import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.PackageProvider;
|
||||
import com.opensymphony.xwork2.config.entities.PackageConfig;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.osgi.host.OsgiHost;
|
||||
import org.apache.struts2.osgi.loaders.VelocityBundleResourceLoader;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
@@ -40,7 +40,6 @@ import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@@ -255,9 +254,12 @@ public class OsgiConfigurationProvider implements PackageProvider, BundleListene
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManager vm) {
|
||||
LOG.trace("OSGi ConfigurationProvider - setVelocityManager() called - VelocityManager: [{}]", vm);
|
||||
|
||||
public void setVelocityManager(VelocityManagerInterface vmi) {
|
||||
LOG.trace("OSGi ConfigurationProvider - setVelocityManager() called - VelocityManager: [{}]", vmi);
|
||||
if (!(vmi instanceof VelocityManager)) {
|
||||
return;
|
||||
}
|
||||
VelocityManager vm = (VelocityManager) vmi;
|
||||
Properties props = new Properties();
|
||||
props.setProperty("osgi.resource.loader.description", "OSGI bundle loader");
|
||||
props.setProperty("osgi.resource.loader.class", VelocityBundleResourceLoader.class.getName());
|
||||
@@ -265,6 +267,14 @@ public class OsgiConfigurationProvider implements PackageProvider, BundleListene
|
||||
vm.setVelocityProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
LOG.trace("OSGi ConfigurationProvider - setServletContext() called - ServletContext: [{}]", servletContext);
|
||||
|
||||
+294
-270
@@ -1,270 +1,294 @@
|
||||
/*
|
||||
* 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.portlet.result;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
import org.apache.struts2.portlet.PortletConstants;
|
||||
import org.apache.struts2.portlet.PortletPhase;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.apache.struts2.views.JspSupportServlet;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.jsp.JspFactory;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
* Using the Servlet container's {@link JspFactory}, this result mocks a JSP
|
||||
* execution environment and then displays a Velocity template that will be
|
||||
* streamed directly to the servlet output.
|
||||
*
|
||||
* <!-- END SNIPPET: description -->
|
||||
* <p><b>This result type takes the following parameters: </b></p>
|
||||
*
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>location (default) </b>- the location of the template to process.
|
||||
* </li>
|
||||
*
|
||||
* <li><b>parse </b>- true by default. If set to false, the location param
|
||||
* will not be parsed for Ognl expressions.</li>
|
||||
*
|
||||
* </ul>
|
||||
* <p>
|
||||
* This result follows the same rules from {@link StrutsResultSupport}.
|
||||
* </p>
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
*
|
||||
* <p><b>Example: </b></p>
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <result name="success" type="velocity">
|
||||
* <param name="location">foo.vm</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class PortletVelocityResult extends StrutsResultSupport {
|
||||
|
||||
private static final long serialVersionUID = -8241086555872212274L;
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(PortletVelocityResult.class);
|
||||
|
||||
private String defaultEncoding;
|
||||
private VelocityManager velocityManager;
|
||||
private JspFactory jspFactory = JspFactory.getDefaultFactory();
|
||||
|
||||
public PortletVelocityResult() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PortletVelocityResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
this.velocityManager = mgr;
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setDefaultEncoding(String encoding) {
|
||||
this.defaultEncoding = encoding;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.struts2.result.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void doExecute(String location, ActionInvocation invocation) throws Exception {
|
||||
PortletPhase phase = PortletActionContext.getPhase();
|
||||
if (phase.isAction()) {
|
||||
executeActionResult(location, invocation);
|
||||
} else if (phase.isRender()) {
|
||||
executeRenderResult(location, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the result
|
||||
*
|
||||
* @param location The location string
|
||||
* @param invocation The action invocation
|
||||
*/
|
||||
private void executeActionResult(String location, ActionInvocation invocation) {
|
||||
ActionResponse res = PortletActionContext.getActionResponse();
|
||||
// View is rendered outside an action...uh oh...
|
||||
res.setRenderParameter(PortletConstants.ACTION_PARAM, "freemarkerDirect");
|
||||
res.setRenderParameter("location", location);
|
||||
res.setRenderParameter(PortletConstants.MODE_PARAM, PortletActionContext.getRequest().getPortletMode().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Velocity context from the action, loads a Velocity template and
|
||||
* executes the template. Output is written to the servlet output stream.
|
||||
*
|
||||
* @param finalLocation the location of the Velocity template
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @throws Exception if an error occurs when creating the Velocity context,
|
||||
* loading or executing the template or writing output to the
|
||||
* servlet response stream.
|
||||
*/
|
||||
public void executeRenderResult(String finalLocation, ActionInvocation invocation) throws Exception {
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
|
||||
HttpServletRequest request = ServletActionContext.getRequest();
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
ServletContext servletContext = ServletActionContext.getServletContext();
|
||||
Servlet servlet = JspSupportServlet.jspSupportServlet;
|
||||
|
||||
velocityManager.init(servletContext);
|
||||
|
||||
boolean usedJspFactory = false;
|
||||
PageContext pageContext = ActionContext.getContext().getPageContext();
|
||||
|
||||
if (pageContext == null && servlet != null) {
|
||||
pageContext = jspFactory.getPageContext(servlet, request, response, null, true, 8192, true);
|
||||
ActionContext.getContext().withPageContext(pageContext);
|
||||
usedJspFactory = true;
|
||||
}
|
||||
|
||||
try {
|
||||
String encoding = getEncoding(finalLocation);
|
||||
String contentType = getContentType(finalLocation);
|
||||
|
||||
if (encoding != null) {
|
||||
contentType = contentType + ";charset=" + encoding;
|
||||
}
|
||||
response.setContentType(contentType);
|
||||
Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding);
|
||||
|
||||
Context context = createContext(velocityManager, stack, request, response, finalLocation);
|
||||
Writer writer = new OutputStreamWriter(response.getOutputStream(), encoding);
|
||||
|
||||
t.merge(context, writer);
|
||||
|
||||
// always flush the writer (we used to only flush it if this was a
|
||||
// jspWriter, but someone asked
|
||||
// to do it all the time (WW-829). Since Velocity support is being
|
||||
// deprecated, we'll oblige :)
|
||||
writer.flush();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unable to render Velocity Template, '" + finalLocation + "'", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (usedJspFactory) {
|
||||
jspFactory.releasePageContext(pageContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the content type for this template. <br>People can override
|
||||
* this method if they want to provide specific content types for specific
|
||||
* templates (eg text/xml).
|
||||
*
|
||||
* @param templateLocation location of templates
|
||||
*
|
||||
* @return The content type associated with this template (default
|
||||
* "text/html")
|
||||
*/
|
||||
protected String getContentType(String templateLocation) {
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the encoding for this template. <br>People can override this
|
||||
* method if they want to provide specific encodings for specific templates.
|
||||
*
|
||||
* @param templateLocation location of templates
|
||||
*
|
||||
* @return The encoding associated with this template (defaults to the value
|
||||
* of 'struts.i18n.encoding' property)
|
||||
*/
|
||||
protected String getEncoding(String templateLocation) {
|
||||
String encoding = defaultEncoding;
|
||||
if (encoding == null) {
|
||||
encoding = System.getProperty("file.encoding");
|
||||
}
|
||||
if (encoding == null) {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value stack, a Velocity engine, and an action invocation, this
|
||||
* method returns the appropriate Velocity template to render.
|
||||
*
|
||||
* @param stack the value stack to resolve the location again (when parse
|
||||
* equals true)
|
||||
* @param velocity the velocity engine to process the request against
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @param location the location of the template
|
||||
* @param encoding the charset encoding of the template
|
||||
* @return the template to render
|
||||
* @throws Exception when the requested template could not be found
|
||||
*/
|
||||
protected Template getTemplate(ValueStack stack, VelocityEngine velocity, ActionInvocation invocation,
|
||||
String location, String encoding) throws Exception {
|
||||
if (!location.startsWith("/")) {
|
||||
location = invocation.getProxy().getNamespace() + "/" + location;
|
||||
}
|
||||
return velocity.getTemplate(location, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the VelocityContext that we'll use to render this page.
|
||||
*
|
||||
* @param velocityManager a reference to the velocityManager to use
|
||||
* @param stack the value stack to resolve the location against (when parse
|
||||
* equals true)
|
||||
* @param request servlet request
|
||||
* @param response servlet response
|
||||
* @param location the name of the template that is being used
|
||||
* @return the a minted Velocity context.
|
||||
*/
|
||||
protected Context createContext(VelocityManager velocityManager, ValueStack stack, HttpServletRequest request,
|
||||
HttpServletResponse response, String location) {
|
||||
return velocityManager.createContext(stack, request, response);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.portlet.result;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.portlet.PortletConstants;
|
||||
import org.apache.struts2.portlet.PortletPhase;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
import org.apache.struts2.views.JspSupportServlet;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.jsp.JspFactory;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
* Using the Servlet container's {@link JspFactory}, this result mocks a JSP
|
||||
* execution environment and then displays a Velocity template that will be
|
||||
* streamed directly to the servlet output.
|
||||
*
|
||||
* <!-- END SNIPPET: description -->
|
||||
* <p><b>This result type takes the following parameters: </b></p>
|
||||
*
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>location (default) </b>- the location of the template to process.
|
||||
* </li>
|
||||
*
|
||||
* <li><b>parse </b>- true by default. If set to false, the location param
|
||||
* will not be parsed for Ognl expressions.</li>
|
||||
*
|
||||
* </ul>
|
||||
* <p>
|
||||
* This result follows the same rules from {@link StrutsResultSupport}.
|
||||
* </p>
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
*
|
||||
* <p><b>Example: </b></p>
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <result name="success" type="velocity">
|
||||
* <param name="location">foo.vm</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class PortletVelocityResult extends StrutsResultSupport {
|
||||
|
||||
private static final long serialVersionUID = -8241086555872212274L;
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(PortletVelocityResult.class);
|
||||
|
||||
private String defaultEncoding;
|
||||
private transient VelocityManagerInterface velocityManager;
|
||||
private JspFactory jspFactory = JspFactory.getDefaultFactory();
|
||||
|
||||
public PortletVelocityResult() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PortletVelocityResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManagerInterface mgr) {
|
||||
this.velocityManager = mgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setDefaultEncoding(String encoding) {
|
||||
this.defaultEncoding = encoding;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.struts2.result.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void doExecute(String location, ActionInvocation invocation) throws Exception {
|
||||
PortletPhase phase = PortletActionContext.getPhase();
|
||||
if (phase.isAction()) {
|
||||
executeActionResult(location, invocation);
|
||||
} else if (phase.isRender()) {
|
||||
executeRenderResult(location, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the result
|
||||
*
|
||||
* @param location The location string
|
||||
* @param invocation The action invocation
|
||||
*/
|
||||
private void executeActionResult(String location, ActionInvocation invocation) {
|
||||
ActionResponse res = PortletActionContext.getActionResponse();
|
||||
// View is rendered outside an action...uh oh...
|
||||
res.setRenderParameter(PortletConstants.ACTION_PARAM, "freemarkerDirect");
|
||||
res.setRenderParameter("location", location);
|
||||
res.setRenderParameter(PortletConstants.MODE_PARAM, PortletActionContext.getRequest().getPortletMode().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Velocity context from the action, loads a Velocity template and
|
||||
* executes the template. Output is written to the servlet output stream.
|
||||
*
|
||||
* @param finalLocation the location of the Velocity template
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @throws Exception if an error occurs when creating the Velocity context,
|
||||
* loading or executing the template or writing output to the
|
||||
* servlet response stream.
|
||||
*/
|
||||
public void executeRenderResult(String finalLocation, ActionInvocation invocation) throws Exception {
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
|
||||
HttpServletRequest request = ServletActionContext.getRequest();
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
ServletContext servletContext = ServletActionContext.getServletContext();
|
||||
Servlet servlet = JspSupportServlet.jspSupportServlet;
|
||||
|
||||
velocityManager.init(servletContext);
|
||||
|
||||
boolean usedJspFactory = false;
|
||||
PageContext pageContext = ActionContext.getContext().getPageContext();
|
||||
|
||||
if (pageContext == null && servlet != null) {
|
||||
pageContext = jspFactory.getPageContext(servlet, request, response, null, true, 8192, true);
|
||||
ActionContext.getContext().withPageContext(pageContext);
|
||||
usedJspFactory = true;
|
||||
}
|
||||
|
||||
try {
|
||||
String encoding = getEncoding(finalLocation);
|
||||
String contentType = getContentType(finalLocation);
|
||||
|
||||
if (encoding != null) {
|
||||
contentType = contentType + ";charset=" + encoding;
|
||||
}
|
||||
response.setContentType(contentType);
|
||||
Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding);
|
||||
|
||||
Context context = createContext(velocityManager, stack, request, response, finalLocation);
|
||||
Writer writer = new OutputStreamWriter(response.getOutputStream(), encoding);
|
||||
|
||||
t.merge(context, writer);
|
||||
|
||||
// always flush the writer (we used to only flush it if this was a
|
||||
// jspWriter, but someone asked
|
||||
// to do it all the time (WW-829). Since Velocity support is being
|
||||
// deprecated, we'll oblige :)
|
||||
writer.flush();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unable to render Velocity Template, '" + finalLocation + "'", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (usedJspFactory) {
|
||||
jspFactory.releasePageContext(pageContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the content type for this template. <br>People can override
|
||||
* this method if they want to provide specific content types for specific
|
||||
* templates (eg text/xml).
|
||||
*
|
||||
* @param templateLocation location of templates
|
||||
*
|
||||
* @return The content type associated with this template (default
|
||||
* "text/html")
|
||||
*/
|
||||
protected String getContentType(String templateLocation) {
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the encoding for this template. <br>People can override this
|
||||
* method if they want to provide specific encodings for specific templates.
|
||||
*
|
||||
* @param templateLocation location of templates
|
||||
*
|
||||
* @return The encoding associated with this template (defaults to the value
|
||||
* of 'struts.i18n.encoding' property)
|
||||
*/
|
||||
protected String getEncoding(String templateLocation) {
|
||||
String encoding = defaultEncoding;
|
||||
if (encoding == null) {
|
||||
encoding = System.getProperty("file.encoding");
|
||||
}
|
||||
if (encoding == null) {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value stack, a Velocity engine, and an action invocation, this
|
||||
* method returns the appropriate Velocity template to render.
|
||||
*
|
||||
* @param stack the value stack to resolve the location again (when parse
|
||||
* equals true)
|
||||
* @param velocity the velocity engine to process the request against
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @param location the location of the template
|
||||
* @param encoding the charset encoding of the template
|
||||
* @return the template to render
|
||||
* @throws Exception when the requested template could not be found
|
||||
*/
|
||||
protected Template getTemplate(ValueStack stack, VelocityEngine velocity, ActionInvocation invocation,
|
||||
String location, String encoding) throws Exception {
|
||||
if (!location.startsWith("/")) {
|
||||
location = invocation.getProxy().getNamespace() + "/" + location;
|
||||
}
|
||||
return velocity.getTemplate(location, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the VelocityContext that we'll use to render this page.
|
||||
*
|
||||
* @param velocityManager a reference to the velocityManager to use
|
||||
* @param stack the value stack to resolve the location against (when parse
|
||||
* equals true)
|
||||
* @param request servlet request
|
||||
* @param response servlet response
|
||||
* @param location the name of the template that is being used
|
||||
* @return the a minted Velocity context.
|
||||
*/
|
||||
protected Context createContext(VelocityManagerInterface velocityManager,
|
||||
ValueStack stack,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String location) {
|
||||
return velocityManager.createContext(stack, request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
protected Context createContext(VelocityManager velocityManager,
|
||||
ValueStack stack,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String location) {
|
||||
return createContext((VelocityManagerInterface) velocityManager, stack, request, response, location);
|
||||
}
|
||||
}
|
||||
|
||||
+110
-101
@@ -1,101 +1,110 @@
|
||||
/*
|
||||
* 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.HTMLPage;
|
||||
import com.opensymphony.sitemesh.Content;
|
||||
import com.opensymphony.sitemesh.compatability.Content2HTMLPage;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Extends OldDecorator2NewStrutsDecorator to add Struts functionality for Velocity
|
||||
*/
|
||||
public class OldDecorator2NewStrutsVelocityDecorator extends OldDecorator2NewStrutsDecorator {
|
||||
private static final Logger LOG = LogManager.getLogger(OldDecorator2NewStrutsFreemarkerDecorator.class);
|
||||
|
||||
private static VelocityManager velocityManager;
|
||||
|
||||
@Inject(required = false)
|
||||
public static void setVelocityManager(VelocityManager mgr) {
|
||||
velocityManager = mgr;
|
||||
}
|
||||
|
||||
public OldDecorator2NewStrutsVelocityDecorator(com.opensymphony.module.sitemesh.Decorator oldDecorator) {
|
||||
this.oldDecorator = oldDecorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the decorator, using the relevent contexts
|
||||
*
|
||||
* @param content The content
|
||||
* @param request The servlet request
|
||||
* @param response The servlet response
|
||||
* @param servletContext The servlet context
|
||||
* @param ctx The action context for this request, populated with the server state
|
||||
*/
|
||||
protected void render(Content content, HttpServletRequest request, HttpServletResponse response, 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();
|
||||
|
||||
HTMLPage htmlPage = new Content2HTMLPage(content, request);
|
||||
|
||||
// get the template and context
|
||||
org.apache.velocity.Template template = velocityManager.getVelocityEngine().getTemplate(oldDecorator.getPage(), encoding);
|
||||
Context context = velocityManager.createContext(ctx.getValueStack(), request, response);
|
||||
|
||||
// put the page in the context
|
||||
context.put("page", htmlPage);
|
||||
context.put("head", htmlPage.getHead());
|
||||
context.put("title", htmlPage.getTitle());
|
||||
context.put("body", htmlPage.getBody());
|
||||
|
||||
// finally, render it
|
||||
PrintWriter writer = response.getWriter();
|
||||
template.merge(context, writer);
|
||||
writer.flush();
|
||||
} catch (Exception e) {
|
||||
String msg = "Error applying decorator to request: " + request.getRequestURL() + "?" + request.getQueryString() + " with message:" + e.getMessage();
|
||||
LOG.error(msg, e);
|
||||
throw new ServletException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.HTMLPage;
|
||||
import com.opensymphony.sitemesh.Content;
|
||||
import com.opensymphony.sitemesh.compatability.Content2HTMLPage;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Extends OldDecorator2NewStrutsDecorator to add Struts functionality for Velocity
|
||||
*/
|
||||
public class OldDecorator2NewStrutsVelocityDecorator extends OldDecorator2NewStrutsDecorator {
|
||||
private static final Logger LOG = LogManager.getLogger(OldDecorator2NewStrutsFreemarkerDecorator.class);
|
||||
|
||||
private static VelocityManagerInterface velocityManager;
|
||||
|
||||
@Inject(required = false)
|
||||
public static void setVelocityManager(VelocityManagerInterface mgr) {
|
||||
velocityManager = mgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
public OldDecorator2NewStrutsVelocityDecorator(com.opensymphony.module.sitemesh.Decorator oldDecorator) {
|
||||
this.oldDecorator = oldDecorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the decorator, using the relevent contexts
|
||||
*
|
||||
* @param content The content
|
||||
* @param request The servlet request
|
||||
* @param response The servlet response
|
||||
* @param servletContext The servlet context
|
||||
* @param ctx The action context for this request, populated with the server state
|
||||
*/
|
||||
protected void render(Content content, HttpServletRequest request, HttpServletResponse response, 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();
|
||||
|
||||
HTMLPage htmlPage = new Content2HTMLPage(content, request);
|
||||
|
||||
// get the template and context
|
||||
org.apache.velocity.Template template = velocityManager.getVelocityEngine().getTemplate(oldDecorator.getPage(), encoding);
|
||||
Context context = velocityManager.createContext(ctx.getValueStack(), request, response);
|
||||
|
||||
// put the page in the context
|
||||
context.put("page", htmlPage);
|
||||
context.put("head", htmlPage.getHead());
|
||||
context.put("title", htmlPage.getTitle());
|
||||
context.put("body", htmlPage.getBody());
|
||||
|
||||
// finally, render it
|
||||
PrintWriter writer = response.getWriter();
|
||||
template.merge(context, writer);
|
||||
writer.flush();
|
||||
} catch (Exception e) {
|
||||
String msg = "Error applying decorator to request: " + request.getRequestURL() + "?" + request.getQueryString() + " with message:" + e.getMessage();
|
||||
LOG.error(msg, e);
|
||||
throw new ServletException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+196
-193
@@ -1,193 +1,196 @@
|
||||
/*
|
||||
* 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.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.dispatcher.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.VelocityView;
|
||||
import org.apache.velocity.tools.view.VelocityViewServlet;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*/
|
||||
public class VelocityDecoratorServlet extends VelocityViewServlet {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(VelocityDecoratorServlet.class);
|
||||
|
||||
private static final long serialVersionUID = -6731485159371716918L;
|
||||
|
||||
protected VelocityManager velocityManager;
|
||||
protected String defaultContentType;
|
||||
|
||||
/**
|
||||
* <p>Initializes servlet, toolbox and Velocity template engine.
|
||||
* Called by the servlet container on loading.</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 configuration
|
||||
*/
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
Dispatcher dispatcher = Dispatcher.getInstance(getServletContext());
|
||||
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
|
||||
getVelocityView().setVelocityEngine(velocityManager.getVelocityEngine());
|
||||
// toolboxManager = velocityManager.getToolboxManager();
|
||||
|
||||
|
||||
// we can get these now that velocity is initialized
|
||||
defaultContentType = getVelocityProperty(VelocityView.CONTENT_TYPE_KEY, VelocityView.DEFAULT_CONTENT_TYPE);
|
||||
|
||||
String encoding = getVelocityProperty(RuntimeConstants.ENCODING_DEFAULT, VelocityView.DEFAULT_OUTPUT_ENCODING);
|
||||
|
||||
// For non Latin-1 encodings, ensure that the charset is
|
||||
// included in the Content-Type header.
|
||||
if (!VelocityView.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.
|
||||
getVelocityView().getVelocityEngine().getLog().warn("VelocityViewServlet: Charset was already " + "specified in the Content-Type property. " + "Output encoding property will be ignored.");
|
||||
}
|
||||
}
|
||||
|
||||
getVelocityView().getVelocityEngine().getLog().info("VelocityViewServlet: Default content-type is: " + defaultContentType);
|
||||
}
|
||||
|
||||
public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) {
|
||||
HTMLPage htmlPage = (HTMLPage) request.getAttribute(RequestConstants.PAGE);
|
||||
String template;
|
||||
|
||||
context.put("base", request.getContextPath());
|
||||
// For backwards compatibility 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 {
|
||||
try {
|
||||
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());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException handle request template", e);
|
||||
}
|
||||
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()));
|
||||
return factory.getDecoratorMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* <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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the content type of the response. This is available to be overridden
|
||||
* by a derived class.
|
||||
* </p>
|
||||
* <p>The default implementation is:</p>
|
||||
* <pre>
|
||||
*
|
||||
* response.setContentType(defaultContentType);
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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.Config;
|
||||
import com.opensymphony.module.sitemesh.Decorator;
|
||||
import com.opensymphony.module.sitemesh.DecoratorMapper;
|
||||
import com.opensymphony.module.sitemesh.Factory;
|
||||
import com.opensymphony.module.sitemesh.HTMLPage;
|
||||
import com.opensymphony.module.sitemesh.RequestConstants;
|
||||
import com.opensymphony.module.sitemesh.util.OutputConverter;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.dispatcher.listener.StrutsListener;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.context.Context;
|
||||
import org.apache.velocity.runtime.RuntimeConstants;
|
||||
import org.apache.velocity.tools.view.VelocityView;
|
||||
import org.apache.velocity.tools.view.VelocityViewServlet;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*/
|
||||
public class VelocityDecoratorServlet extends VelocityViewServlet {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(VelocityDecoratorServlet.class);
|
||||
|
||||
private static final long serialVersionUID = -6731485159371716918L;
|
||||
|
||||
protected VelocityManagerInterface velocityManager;
|
||||
protected String defaultContentType;
|
||||
|
||||
/**
|
||||
* <p>Initializes servlet, toolbox and Velocity template engine.
|
||||
* Called by the servlet container on loading.</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 configuration
|
||||
*/
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
Dispatcher dispatcher = Dispatcher.getInstance(getServletContext());
|
||||
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(VelocityManagerInterface.class);
|
||||
velocityManager.init(config.getServletContext());
|
||||
|
||||
// do whatever we have to do to init Velocity
|
||||
getVelocityView().setVelocityEngine(velocityManager.getVelocityEngine());
|
||||
// toolboxManager = velocityManager.getToolboxManager();
|
||||
|
||||
|
||||
// we can get these now that velocity is initialized
|
||||
defaultContentType = getVelocityProperty(VelocityView.CONTENT_TYPE_KEY, VelocityView.DEFAULT_CONTENT_TYPE);
|
||||
|
||||
String encoding = getVelocityProperty(RuntimeConstants.ENCODING_DEFAULT, VelocityView.DEFAULT_OUTPUT_ENCODING);
|
||||
|
||||
// For non Latin-1 encodings, ensure that the charset is
|
||||
// included in the Content-Type header.
|
||||
if (!VelocityView.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.
|
||||
getVelocityView().getVelocityEngine().getLog().warn("VelocityViewServlet: Charset was already " + "specified in the Content-Type property. " + "Output encoding property will be ignored.");
|
||||
}
|
||||
}
|
||||
|
||||
getVelocityView().getVelocityEngine().getLog().info("VelocityViewServlet: Default content-type is: " + defaultContentType);
|
||||
}
|
||||
|
||||
public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) {
|
||||
HTMLPage htmlPage = (HTMLPage) request.getAttribute(RequestConstants.PAGE);
|
||||
String template;
|
||||
|
||||
context.put("base", request.getContextPath());
|
||||
// For backwards compatibility 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 {
|
||||
try {
|
||||
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());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException handle request template", e);
|
||||
}
|
||||
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()));
|
||||
return factory.getDecoratorMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* <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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the content type of the response. This is available to be overridden
|
||||
* by a derived class.
|
||||
* </p>
|
||||
* <p>The default implementation is:</p>
|
||||
* <pre>
|
||||
*
|
||||
* response.setContentType(defaultContentType);
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
*/
|
||||
package org.apache.struts2.sitemesh;
|
||||
|
||||
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.module.sitemesh.Factory;
|
||||
import com.opensymphony.sitemesh.DecoratorSelector;
|
||||
import com.opensymphony.sitemesh.webapp.SiteMeshFilter;
|
||||
import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
|
||||
import javax.servlet.*;
|
||||
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
|
||||
/**
|
||||
* Core Filter for integrating SiteMesh into a Java web application.
|
||||
@@ -35,10 +35,18 @@ import org.apache.struts2.views.velocity.VelocityManager;
|
||||
public class VelocityPageFilter extends SiteMeshFilter {
|
||||
|
||||
@Inject(required=false)
|
||||
public static void setVelocityManager(VelocityManager mgr) {
|
||||
public static void setVelocityManager(VelocityManagerInterface mgr) {
|
||||
OldDecorator2NewStrutsVelocityDecorator.setVelocityManager(mgr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
private FilterConfig filterConfig;
|
||||
|
||||
public void init(FilterConfig filterConfig) {
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class VelocityBeanSelectionProvider extends AbstractBeanSelectionProvider
|
||||
|
||||
@Override
|
||||
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
|
||||
alias(VelocityManager.class, VelocityConstants.STRUTS_VELOCITY_MANAGER_CLASSNAME, builder, props);
|
||||
alias(VelocityManagerInterface.class, VelocityConstants.STRUTS_VELOCITY_MANAGER_CLASSNAME, builder, props);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-1
@@ -62,7 +62,7 @@ import static org.apache.struts2.views.util.ContextUtil.STRUTS;
|
||||
/**
|
||||
* Manages the environment for Velocity result types
|
||||
*/
|
||||
public class VelocityManager {
|
||||
public class VelocityManager implements VelocityManagerInterface {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(VelocityManager.class);
|
||||
|
||||
@@ -105,6 +105,7 @@ public class VelocityManager {
|
||||
* @return a reference to the VelocityEngine used by <strong>all</strong> Struts Velocity results except directly
|
||||
* accessed *.vm pages (unless otherwise configured)
|
||||
*/
|
||||
@Override
|
||||
public VelocityEngine getVelocityEngine() {
|
||||
return velocityEngine;
|
||||
}
|
||||
@@ -117,6 +118,7 @@ public class VelocityManager {
|
||||
* @param res the current HttpServletResponse
|
||||
* @return a new StrutsVelocityContext
|
||||
*/
|
||||
@Override
|
||||
public Context createContext(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
|
||||
Context context = buildToolContext();
|
||||
if (context == null) {
|
||||
@@ -182,6 +184,7 @@ public class VelocityManager {
|
||||
*
|
||||
* @param context the current servlet context
|
||||
*/
|
||||
@Override
|
||||
public synchronized void init(ServletContext context) {
|
||||
if (velocityEngine == null) {
|
||||
velocityEngine = newVelocityEngine(context);
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.views.velocity;
|
||||
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @since 6.4.0
|
||||
*/
|
||||
public interface VelocityManagerInterface {
|
||||
|
||||
Context createContext(ValueStack stack, HttpServletRequest req, HttpServletResponse res);
|
||||
|
||||
VelocityEngine getVelocityEngine();
|
||||
|
||||
void init(ServletContext context);
|
||||
}
|
||||
+31
-6
@@ -29,6 +29,7 @@ import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
import org.apache.struts2.views.JspSupportServlet;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
@@ -85,9 +86,9 @@ public class VelocityResult extends StrutsResultSupport {
|
||||
private static final long serialVersionUID = 7268830767762559424L;
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(VelocityResult.class);
|
||||
|
||||
|
||||
private String defaultEncoding;
|
||||
private VelocityManager velocityManager;
|
||||
private transient VelocityManagerInterface velocityManager;
|
||||
private JspFactory jspFactory = JspFactory.getDefaultFactory();
|
||||
|
||||
public VelocityResult() {
|
||||
@@ -97,17 +98,25 @@ public class VelocityResult extends StrutsResultSupport {
|
||||
public VelocityResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setDefaultEncoding(String val) {
|
||||
defaultEncoding = val;
|
||||
}
|
||||
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
public void setVelocityManager(VelocityManagerInterface mgr) {
|
||||
this.velocityManager = mgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Velocity context from the action, loads a Velocity template and executes the
|
||||
* template. Output is written to the servlet output stream.
|
||||
@@ -232,7 +241,23 @@ public class VelocityResult extends StrutsResultSupport {
|
||||
* @param location the name of the template that is being used
|
||||
* @return the a minted Velocity context.
|
||||
*/
|
||||
protected Context createContext(VelocityManager velocityManager, ValueStack stack, HttpServletRequest request, HttpServletResponse response, String location) {
|
||||
protected Context createContext(VelocityManagerInterface velocityManager,
|
||||
ValueStack stack,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String location) {
|
||||
return velocityManager.createContext(stack, request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
protected Context createContext(VelocityManager velocityManager,
|
||||
ValueStack stack,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String location) {
|
||||
return createContext((VelocityManagerInterface) velocityManager, stack, request, response, location);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -26,6 +26,7 @@ import org.apache.struts2.components.template.BaseTemplateEngine;
|
||||
import org.apache.struts2.components.template.Template;
|
||||
import org.apache.struts2.components.template.TemplateRenderingContext;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManagerInterface;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
@@ -41,14 +42,22 @@ import java.util.Map;
|
||||
*/
|
||||
public class VelocityTemplateEngine extends BaseTemplateEngine {
|
||||
private static final Logger LOG = LogManager.getLogger(VelocityTemplateEngine.class);
|
||||
|
||||
private VelocityManager velocityManager;
|
||||
|
||||
|
||||
private VelocityManagerInterface velocityManager;
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
public void setVelocityManager(VelocityManagerInterface mgr) {
|
||||
this.velocityManager = mgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 6.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
setVelocityManager((VelocityManagerInterface) mgr);
|
||||
}
|
||||
|
||||
public void renderTemplate(TemplateRenderingContext templateContext) throws Exception {
|
||||
// get the various items required from the stack
|
||||
Map actionContext = templateContext.getStack().getContext();
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
<struts>
|
||||
|
||||
<bean name="struts" type="org.apache.struts2.views.velocity.VelocityManagerInterface"
|
||||
class="org.apache.struts2.views.velocity.VelocityManager"/>
|
||||
|
||||
<!-- Deprecated since 6.4.0 -->
|
||||
<bean name="struts" class="org.apache.struts2.views.velocity.VelocityManager"/>
|
||||
|
||||
<bean type="org.apache.struts2.components.template.TemplateEngine" name="vm"
|
||||
|
||||
Reference in New Issue
Block a user