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

lukaszlenart pushed a commit to branch merge-master-to-7xx-2024-02-16
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 45b06dd69c875cbde943b77fc77c7fd608a5cfe1
Merge: 7edcac886 a84f85798
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Fri Feb 16 09:27:16 2024 +0100

    Merge remote-tracking branch 'origin/master' into 
merge-master-to-7xx-2024-02-16
    
    # Conflicts:
    #       
plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
    #       
plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
    #       
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/OldDecorator2NewStrutsVelocityDecorator.java
    #       
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
    #       
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
    #       pom.xml

 .github/workflows/scorecards-analysis.yaml         |   2 +-
 .../java/org/apache/struts2/components/File.java   |   6 +
 core/src/site/resources/tags/file-attributes.html  |   2 +-
 .../struts2/config_browser/ShowBeansAction.java    |   4 +-
 .../struts2/views/java/simple/FileHandler.java     |   1 -
 .../apache/struts2/views/java/simple/FileTest.java |   3 +-
 .../struts2/rest/ContentTypeInterceptor.java       |   3 +-
 .../struts2/rest/ContentTypeInterceptorTest.java   | 154 ++++++++
 .../OldDecorator2NewStrutsVelocityDecorator.java   | 211 +++++------
 .../struts2/sitemesh/VelocityDecoratorServlet.java | 390 +++++++++++----------
 .../struts2/sitemesh/VelocityPageFilter.java       |  22 +-
 .../velocity/VelocityBeanSelectionProvider.java    |   2 +-
 .../struts2/views/velocity/VelocityManager.java    |   5 +-
 .../views/velocity/VelocityManagerInterface.java   |  38 ++
 .../views/velocity/result/VelocityResult.java      |  37 +-
 .../velocity/template/VelocityTemplateEngine.java  |  17 +-
 .../velocity/src/main/resources/struts-plugin.xml  |   4 +
 pom.xml                                            |  22 +-
 18 files changed, 591 insertions(+), 332 deletions(-)

diff --cc 
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/OldDecorator2NewStrutsVelocityDecorator.java
index 57564f47e,33d5b1f3a..6168b29c0
--- 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/OldDecorator2NewStrutsVelocityDecorator.java
+++ 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/OldDecorator2NewStrutsVelocityDecorator.java
@@@ -1,101 -1,110 +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 jakarta.servlet.ServletContext;
- import jakarta.servlet.ServletException;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.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 jakarta.servlet.ServletContext;
++import jakarta.servlet.ServletException;
++import jakarta.servlet.http.HttpServletRequest;
++import jakarta.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);
+         }
+     }
+ 
+ }
+ 
diff --cc 
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
index 56af9c61a,b2079c2f2..255571aff
--- 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
+++ 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
@@@ -1,193 -1,196 +1,197 @@@
- /*
-  * 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 jakarta.servlet.ServletConfig;
- import jakarta.servlet.ServletException;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.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 jakarta.servlet.ServletConfig;
++import jakarta.servlet.ServletException;
++import jakarta.servlet.http.HttpServletRequest;
++import jakarta.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);
+     }
+ 
+ }
diff --cc 
plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
index fa309ea27,d4a2314df..71e04b329
--- 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
+++ 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
@@@ -18,17 -18,17 +18,17 @@@
   */
  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 org.apache.struts2.views.velocity.VelocityManager;
+ import org.apache.struts2.views.velocity.VelocityManagerInterface;
  
 -import javax.servlet.FilterConfig;
 +import jakarta.servlet.*;
  
- import org.apache.struts2.views.velocity.VelocityManager;
- 
  /**
   * Core Filter for integrating SiteMesh into a Java web application.
   */
diff --cc 
plugins/velocity/src/main/java/org/apache/struts2/views/velocity/VelocityManagerInterface.java
index 000000000,66a9f46fe..4e6b7b69a
mode 000000,100644..100644
--- 
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
@@@ -1,0 -1,39 +1,38 @@@
+ /*
+  * 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 jakarta.servlet.ServletContext;
++import jakarta.servlet.http.HttpServletRequest;
++import jakarta.servlet.http.HttpServletResponse;
+ 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 --cc pom.xml
index 217a65b1b,80bb602a6..e65e85a24
--- a/pom.xml
+++ b/pom.xml
@@@ -111,20 -110,16 +111,20 @@@
  
          <!-- dependency versions in alphanumeric order -->
          <asm.version>9.6</asm.version>
 -        <jackson.version>2.16.1</jackson.version>
 -        <log4j2.version>2.21.1</log4j2.version>
 +        <byte-buddy.version>1.14.11</byte-buddy.version>
 +        <freemarker.version>2.3.32</freemarker.version>
 +        <hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
 +        <jackson.version>2.16.0</jackson.version>
 +        <log4j2.version>2.22.1</log4j2.version>
-         <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
++        <maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
 +        <mockito.version>5.8.0</mockito.version>
          <ognl.version>3.3.4</ognl.version>
 +        <sitemesh.version>2.5.0</sitemesh.version>
-         <slf4j.version>2.0.9</slf4j.version>
+         <slf4j.version>2.0.11</slf4j.version>
 -        <spring.platformVersion>5.3.31</spring.platformVersion>
 +        <spring.platformVersion>6.0.13</spring.platformVersion>
          <tiles.version>3.0.8</tiles.version>
          <tiles-request.version>1.0.7</tiles-request.version>
 -        
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
 -        <hibernate-validator.version>6.2.4.Final</hibernate-validator.version>
 -        <freemarker.version>2.3.32</freemarker.version>
 +        <velocity-tools.version>3.1</velocity-tools.version>
  
          <!-- Site generation -->
          <fluido-skin.version>1.9</fluido-skin.version>

Reply via email to