This is an automated email from the ASF dual-hosted git repository.

kusal pushed a commit to branch WW-5391-velocity-ext-point
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 9328ae7ec10f23c5ad0fb2e8a4a1c555a2094a17
Author: Kusal Kithul-Godage <g...@kusal.io>
AuthorDate: Fri Feb 2 17:25:17 2024 +1100

    WW-5391 Add interface for VelocityManager extension point
---
 .../struts2/osgi/OsgiConfigurationProvider.java    |  24 +-
 .../portlet/result/PortletVelocityResult.java      | 564 +++++++++++----------
 .../velocity/VelocityBeanSelectionProvider.java    |   2 +-
 .../struts2/views/velocity/VelocityManager.java    |   5 +-
 .../views/velocity/VelocityManagerInterface.java   |  39 ++
 .../views/velocity/result/VelocityResult.java      |  37 +-
 .../velocity/template/VelocityTemplateEngine.java  |  17 +-
 7 files changed, 399 insertions(+), 289 deletions(-)

diff --git 
a/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
 
b/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
index 61b22c281..ba56b4e6d 100644
--- 
a/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
+++ 
b/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
@@ -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);
diff --git 
a/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
 
b/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
index fcae67c45..d40ce9331 100644
--- 
a/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
+++ 
b/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
@@ -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>
- * &lt;!-- START SNIPPET: example --&gt;
- *  &lt;result name=&quot;success&quot; type=&quot;velocity&quot;&gt;
- *    &lt;param name=&quot;location&quot;&gt;foo.vm&lt;/param&gt;
- *  &lt;/result&gt;
- *  &lt;!-- END SNIPPET: example --&gt;
- * </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>
+ * &lt;!-- START SNIPPET: example --&gt;
+ *  &lt;result name=&quot;success&quot; type=&quot;velocity&quot;&gt;
+ *    &lt;param name=&quot;location&quot;&gt;foo.vm&lt;/param&gt;
+ *  &lt;/result&gt;
+ *  &lt;!-- END SNIPPET: example --&gt;
+ * </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 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);
+    }
+}
diff --git 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityBeanSelectionProvider.java
 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityBeanSelectionProvider.java
index f53ec6607..d2c195b0f 100644
--- 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityBeanSelectionProvider.java
+++ 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityBeanSelectionProvider.java
@@ -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);
     }
 
 }
diff --git 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java
 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java
index 2b9e00191..e1764afc4 100644
--- 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java
+++ 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java
@@ -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);
diff --git 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManagerInterface.java
 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManagerInterface.java
new file mode 100644
index 000000000..66a9f46fe
--- /dev/null
+++ 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManagerInterface.java
@@ -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);
+}
diff --git 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/result/VelocityResult.java
 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/result/VelocityResult.java
index 68b56451b..e65efd4f6 100644
--- 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/result/VelocityResult.java
+++ 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/result/VelocityResult.java
@@ -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 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);
+    }
 }
diff --git 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/template/VelocityTemplateEngine.java
 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/template/VelocityTemplateEngine.java
index 423029e32..56641487c 100644
--- 
a/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/template/VelocityTemplateEngine.java
+++ 
b/plugins/velocity/src/main/java/org/apache/struts2/views/velocity/template/VelocityTemplateEngine.java
@@ -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();


Reply via email to