mirror of
https://github.com/apache/struts.git
synced 2026-08-07 07:37:20 +00:00
WW-5449 Make Velocity Tools dependency optional for Velocity plugin
This commit is contained in:
@@ -44,6 +44,16 @@
|
||||
<artifactId>struts2-velocity-plugin</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-tools-view-jakarta</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-tools-jsp-jakarta</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<properties>
|
||||
|
||||
@@ -42,11 +42,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-tools-view-jakarta</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-tools-jsp-jakarta</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+143
-229
@@ -22,10 +22,12 @@ import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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.StrutsException;
|
||||
import org.apache.struts2.views.TagLibraryDirectiveProvider;
|
||||
@@ -34,13 +36,7 @@ import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
import org.apache.velocity.tools.ToolContext;
|
||||
import org.apache.velocity.tools.ToolManager;
|
||||
import org.apache.velocity.tools.ToolboxFactory;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -48,16 +44,17 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.struts2.views.util.ContextUtil.STRUTS;
|
||||
import static org.apache.velocity.runtime.DeprecatedRuntimeConstants.OLD_CUSTOM_DIRECTIVES;
|
||||
|
||||
/**
|
||||
* Manages the environment for Velocity result types
|
||||
@@ -72,11 +69,7 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
|
||||
private VelocityEngine velocityEngine;
|
||||
|
||||
/**
|
||||
* A reference to the toolbox manager.
|
||||
*/
|
||||
protected ToolManager toolboxManager = null;
|
||||
private String toolBoxLocation;
|
||||
private VelocityTools velocityTools;
|
||||
|
||||
/**
|
||||
* Names of contexts that will be chained on every request
|
||||
@@ -96,9 +89,8 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
|
||||
@Inject
|
||||
public void setContainer(Container container) {
|
||||
List<TagLibraryDirectiveProvider> list = container.getInstanceNames(TagLibraryDirectiveProvider.class).stream()
|
||||
.map(prefix -> container.getInstance(TagLibraryDirectiveProvider.class, prefix)).collect(toList());
|
||||
this.tagLibraries = Collections.unmodifiableList(list);
|
||||
this.tagLibraries = container.getInstanceNames(TagLibraryDirectiveProvider.class).stream()
|
||||
.map(prefix -> container.getInstance(TagLibraryDirectiveProvider.class, prefix)).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +112,10 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
*/
|
||||
@Override
|
||||
public Context createContext(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
|
||||
Context context = buildToolContext();
|
||||
Context context = null;
|
||||
if (velocityTools != null) {
|
||||
context = velocityTools.createContext();
|
||||
}
|
||||
if (context == null) {
|
||||
context = buildContext(stack, req, res);
|
||||
}
|
||||
@@ -137,42 +132,25 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
return context;
|
||||
}
|
||||
|
||||
protected Context buildToolContext() {
|
||||
if (toolboxManager == null) {
|
||||
return null;
|
||||
}
|
||||
ServletContext ctx;
|
||||
try {
|
||||
ctx = ServletActionContext.getServletContext();
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
if (ctx == null) {
|
||||
return null;
|
||||
}
|
||||
ToolContext toolContext = new ToolContext(velocityEngine);
|
||||
toolContext.addToolbox(toolboxManager.getToolboxFactory().createToolbox(ToolboxFactory.DEFAULT_SCOPE));
|
||||
return toolContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs contexts for chaining on this request. This method does not
|
||||
* perform any initialization of the contexts. All that must be done in the
|
||||
* context itself.
|
||||
* Constructs contexts for chaining on this request. This method does not perform any initialization of the
|
||||
* contexts. All that must be done in the context itself.
|
||||
*
|
||||
* @param servletRequest the servlet request object
|
||||
* @param servletResponse the servlet response object
|
||||
* @param extraContext map with extra context
|
||||
* @return a List of contexts to chain or an empty list
|
||||
*/
|
||||
protected List<VelocityContext> prepareChainedContexts(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Map<String, Object> extraContext) {
|
||||
protected List<VelocityContext> prepareChainedContexts(HttpServletRequest servletRequest,
|
||||
HttpServletResponse servletResponse,
|
||||
Map<String, Object> extraContext) {
|
||||
List<VelocityContext> contextList = new ArrayList<>();
|
||||
for (String className : chainedContextNames) {
|
||||
try {
|
||||
VelocityContext velocityContext = (VelocityContext) objectFactory.buildBean(className, extraContext);
|
||||
contextList.add(velocityContext);
|
||||
} catch (Exception e) {
|
||||
LOG.warn(format("Unable to instantiate chained VelocityContext %s, skipping", className), e);
|
||||
LOG.warn("Unable to instantiate chained VelocityContext {}, skipping", className, e);
|
||||
}
|
||||
}
|
||||
return contextList;
|
||||
@@ -186,154 +164,118 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
*/
|
||||
@Override
|
||||
public synchronized void init(ServletContext context) {
|
||||
if (velocityEngine == null) {
|
||||
velocityEngine = newVelocityEngine(context);
|
||||
if (velocityEngine != null) {
|
||||
return;
|
||||
}
|
||||
velocityEngine = newVelocityEngine(context);
|
||||
if (velocityTools != null) {
|
||||
velocityTools.init(context, velocityEngine);
|
||||
}
|
||||
this.initToolbox(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* load optional velocity properties using the following loading strategy
|
||||
* <ul>
|
||||
* <li>relative to the servlet context path</li>
|
||||
* <li>relative to the WEB-INF directory</li>
|
||||
* <li>on the classpath</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param context the current ServletContext. may <b>not</b> be null
|
||||
* @return the optional properties if struts.velocity.configfile was specified, an empty Properties file otherwise
|
||||
*/
|
||||
public Properties loadConfiguration(ServletContext context) {
|
||||
if (context == null) {
|
||||
String gripe = "Error attempting to create a loadConfiguration from a null ServletContext!";
|
||||
LOG.error(gripe);
|
||||
throw new IllegalArgumentException(gripe);
|
||||
throw new IllegalArgumentException("Error attempting to create a loadConfiguration from a null ServletContext!");
|
||||
}
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
||||
// now apply our systemic defaults, then allow user to override
|
||||
applyDefaultConfiguration(context, properties);
|
||||
|
||||
applyDefaultConfiguration(context, properties); // Apply defaults before loading user overrides
|
||||
String defaultUserDirective = properties.getProperty("userdirective");
|
||||
|
||||
/*
|
||||
if the user has specified an external velocity configuration file, we'll want to search for it in the
|
||||
following order
|
||||
applyUserConfiguration(context, properties);
|
||||
|
||||
1. relative to the context path
|
||||
2. relative to /WEB-INF
|
||||
3. in the class path
|
||||
*/
|
||||
String configfile;
|
||||
|
||||
if (customConfigFile != null) {
|
||||
configfile = customConfigFile;
|
||||
} else {
|
||||
configfile = "velocity.properties";
|
||||
}
|
||||
configfile = configfile.trim();
|
||||
|
||||
InputStream in = null;
|
||||
String resourceLocation = null;
|
||||
|
||||
try {
|
||||
if (context.getRealPath(configfile) != null) {
|
||||
// 1. relative to context path, i.e. /velocity.properties
|
||||
String filename = context.getRealPath(configfile);
|
||||
|
||||
if (filename != null) {
|
||||
File file = new File(filename);
|
||||
|
||||
if (file.isFile()) {
|
||||
resourceLocation = file.getCanonicalPath() + " from file system";
|
||||
in = new FileInputStream(file);
|
||||
}
|
||||
|
||||
// 2. if nothing was found relative to the context path, search relative to the WEB-INF directory
|
||||
if (in == null) {
|
||||
file = new File(context.getRealPath("/WEB-INF/" + configfile));
|
||||
|
||||
if (file.isFile()) {
|
||||
resourceLocation = file.getCanonicalPath() + " from file system";
|
||||
in = new FileInputStream(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. finally, if there's no physical file, how about something in our classpath
|
||||
if (in == null) {
|
||||
in = VelocityManager.class.getClassLoader().getResourceAsStream(configfile);
|
||||
if (in != null) {
|
||||
resourceLocation = configfile + " from classloader";
|
||||
}
|
||||
}
|
||||
|
||||
// if we've got something, load 'er up
|
||||
if (in != null) {
|
||||
LOG.info("Initializing velocity using {}", resourceLocation);
|
||||
properties.load(in);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to load velocity configuration {}", resourceLocation, e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
if (velocityProperties != null) { // Apply additional overriding properties if any
|
||||
velocityProperties.stringPropertyNames().forEach(k -> properties.setProperty(k, velocityProperties.getProperty(k)));
|
||||
}
|
||||
|
||||
// overide with programmatically set properties
|
||||
if (velocityProperties != null) {
|
||||
for (Object o : velocityProperties.keySet()) {
|
||||
String key = (String) o;
|
||||
properties.setProperty(key, this.velocityProperties.getProperty(key));
|
||||
}
|
||||
}
|
||||
String userDirective = properties.getProperty(OLD_CUSTOM_DIRECTIVES);
|
||||
String newDirective = isBlank(userDirective) ? defaultUserDirective : userDirective.strip() + "," + defaultUserDirective;
|
||||
properties.setProperty(OLD_CUSTOM_DIRECTIVES, newDirective);
|
||||
|
||||
String userdirective = properties.getProperty("userdirective");
|
||||
if (userdirective == null || userdirective.trim().isEmpty()) {
|
||||
userdirective = defaultUserDirective;
|
||||
} else {
|
||||
userdirective = userdirective.trim() + "," + defaultUserDirective;
|
||||
}
|
||||
properties.setProperty("userdirective", userdirective);
|
||||
|
||||
// for debugging purposes, allows users to dump out the properties that have been configured
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Initializing Velocity with the following properties ...");
|
||||
|
||||
for (Object o : properties.keySet()) {
|
||||
String key = (String) o;
|
||||
String value = properties.getProperty(key);
|
||||
LOG.debug(" '{}' = '{}'", key, value);
|
||||
}
|
||||
properties.stringPropertyNames().forEach(k -> LOG.debug(" '{}' = '{}'", k, properties.getProperty(k)));
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load optional velocity properties using the following loading strategy
|
||||
* <ul>
|
||||
* <li>relative to the servlet context path</li>
|
||||
* <li>relative to the WEB-INF directory</li>
|
||||
* <li>on the classpath</li>
|
||||
* </ul>
|
||||
*/
|
||||
private void applyUserConfiguration(ServletContext context, Properties properties) {
|
||||
String configFile = requireNonNullElse(customConfigFile, "velocity.properties").trim();
|
||||
boolean isLoaded = false;
|
||||
try {
|
||||
isLoaded = loadFile(properties, context.getRealPath(configFile));
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to load Velocity configuration from servlet context path", e);
|
||||
}
|
||||
if (!isLoaded) {
|
||||
try {
|
||||
isLoaded = loadFile(properties, context.getRealPath("/WEB-INF/" + configFile));
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to load Velocity configuration from WEB-INF path", e);
|
||||
}
|
||||
}
|
||||
if (!isLoaded) {
|
||||
try {
|
||||
isLoaded = loadClassPathFile(properties, configFile);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to load Velocity configuration from classpath", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean loadClassPathFile(Properties properties, String configFile) throws IOException {
|
||||
try (InputStream is = VelocityManager.class.getClassLoader().getResourceAsStream(configFile)) {
|
||||
if (is == null) {
|
||||
return false;
|
||||
}
|
||||
properties.load(is);
|
||||
LOG.info("Initializing Velocity using {} from classpath", configFile);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean loadFile(Properties properties, String fileName) throws IOException {
|
||||
if (fileName == null) {
|
||||
return false;
|
||||
}
|
||||
File file = new File(fileName);
|
||||
if (!file.isFile()) {
|
||||
return false;
|
||||
}
|
||||
try (InputStream is = new FileInputStream(file)) {
|
||||
properties.load(is);
|
||||
LOG.info("Initializing Velocity using {}", file.getCanonicalPath() + " from file system");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_VELOCITY_CONFIGFILE)
|
||||
public void setCustomConfigFile(String val) {
|
||||
this.customConfigFile = val;
|
||||
public void setCustomConfigFile(String customConfigFile) {
|
||||
this.customConfigFile = customConfigFile;
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_VELOCITY_TOOLBOXLOCATION)
|
||||
public void setToolBoxLocation(String toolboxLocation) {
|
||||
this.toolBoxLocation = toolboxLocation;
|
||||
if (!isBlank(toolboxLocation)) {
|
||||
this.velocityTools = new VelocityTools(toolboxLocation);
|
||||
}
|
||||
}
|
||||
|
||||
public ToolManager getToolboxManager() {
|
||||
return toolboxManager;
|
||||
public VelocityTools getVelocityTools() {
|
||||
return velocityTools;
|
||||
}
|
||||
|
||||
/**
|
||||
* allow users to specify via the struts.properties file a set of additional VelocityContexts to chain to the
|
||||
* the StrutsVelocityContext. The intent is to allow these contexts to store helper objects that the ui
|
||||
* developer may want access to. Examples of reasonable VelocityContexts would be an IoCVelocityContext, a
|
||||
* Allow users to specify via the struts.properties file a set of additional VelocityContexts to chain to the
|
||||
* StrutsVelocityContext. The intent is to allow these contexts to store helper objects that the ui developer may
|
||||
* want access to. Examples of reasonable VelocityContexts would be an IoCVelocityContext, a
|
||||
* SpringReferenceVelocityContext, and a ToolboxVelocityContext
|
||||
*
|
||||
* @param contexts comma separated velocity context's
|
||||
@@ -344,38 +286,17 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the ServletToolboxManager for this servlet's
|
||||
* toolbox (if any).
|
||||
*/
|
||||
protected void initToolbox(ServletContext servletContext) {
|
||||
if (StringUtils.isBlank(toolBoxLocation)) {
|
||||
LOG.debug("Skipping ToolManager initialisation, [{}] was not defined", StrutsConstants.STRUTS_VELOCITY_TOOLBOXLOCATION);
|
||||
return;
|
||||
}
|
||||
LOG.debug("Configuring Velocity ToolManager with {}", toolBoxLocation);
|
||||
toolboxManager = new ToolManager();
|
||||
toolboxManager.configure(toolBoxLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Instantiates a new VelocityEngine.
|
||||
* </p>
|
||||
* <p>
|
||||
* The following is the default Velocity configuration
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* resource.loader = file, class
|
||||
* file.resource.loader.path = real path of webapp
|
||||
* class.resource.loader.description = Velocity Classpath Resource Loader
|
||||
* class.resource.loader.class = org.apache.struts2.views.velocity.StrutsResourceLoader
|
||||
* </pre>
|
||||
* <p>
|
||||
* this default configuration can be overridden by specifying a struts.velocity.configfile property in the
|
||||
* This default configuration can be overridden by specifying a struts.velocity.configfile property in the
|
||||
* struts.properties file. the specified config file will be searched for in the following order:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>relative to the servlet context path</li>
|
||||
* <li>relative to the WEB-INF directory</li>
|
||||
@@ -389,21 +310,18 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("Error attempting to create a new VelocityEngine from a null ServletContext!");
|
||||
}
|
||||
|
||||
VelocityEngine velocityEngine = new VelocityEngine();
|
||||
// Set the velocity attribute for the servlet context, if this is not set the webapp loader WILL NOT WORK
|
||||
velocityEngine.setApplicationAttribute(ServletContext.class.getName(), context);
|
||||
velocityEngine.setApplicationAttribute(ServletContext.class.getName(), context); // Required for webapp loader
|
||||
try {
|
||||
velocityEngine.init(loadConfiguration(context));
|
||||
} catch (Exception e) {
|
||||
throw new StrutsException("Unable to instantiate VelocityEngine!", e);
|
||||
}
|
||||
|
||||
return velocityEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* once we've loaded up the user defined configurations, we will want to apply Struts specification configurations.
|
||||
* Once we've loaded up the user defined configurations, we will want to apply Struts specification configurations.
|
||||
* <ul>
|
||||
* <li>if Velocity.RESOURCE_LOADER has not been defined, then we will use the defaults which is a joined file,
|
||||
* class loader for unpackaed wars and a straight class loader otherwise</li>
|
||||
@@ -414,60 +332,56 @@ public class VelocityManager implements VelocityManagerInterface {
|
||||
* @param properties velocity properties
|
||||
*/
|
||||
private void applyDefaultConfiguration(ServletContext context, Properties properties) {
|
||||
// ensure that caching isn't overly aggressive
|
||||
|
||||
LOG.debug("Load a default resource loader definition if there isn't one present.");
|
||||
if (properties.getProperty(Velocity.RESOURCE_LOADER) == null) {
|
||||
properties.setProperty(Velocity.RESOURCE_LOADER, "strutsfile, strutsclass");
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's a "real" path add it for the strutsfile resource loader.
|
||||
* If there's no real path and they haven't configured a loader then we change
|
||||
* resource loader property to just use the strutsclass loader
|
||||
* Ben Hall (22/08/2003)
|
||||
*/
|
||||
if (context.getRealPath("") != null) {
|
||||
properties.setProperty("strutsfile.resource.loader.description", "Velocity File Resource Loader");
|
||||
properties.setProperty("strutsfile.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
|
||||
properties.setProperty("strutsfile.resource.loader.path", context.getRealPath(""));
|
||||
properties.setProperty("strutsfile.resource.loader.modificationCheckInterval", "2");
|
||||
properties.setProperty("strutsfile.resource.loader.cache", "true");
|
||||
// If there's a "real" path add it for the strutsfile resource loader. If there's no real path, and they haven't
|
||||
// configured a loader then we change resource loader property to just use the strutsclass loader
|
||||
String realPath = context.getRealPath("");
|
||||
if (realPath != null) {
|
||||
setStrutsFileResourceLoader(properties, realPath);
|
||||
} else {
|
||||
// remove strutsfile from resource loader property
|
||||
String prop = properties.getProperty(Velocity.RESOURCE_LOADER);
|
||||
if (prop.contains("strutsfile,")) {
|
||||
prop = prop.replace("strutsfile,", "");
|
||||
} else if (prop.contains(", strutsfile")) {
|
||||
prop = prop.replace(", strutsfile", "");
|
||||
} else if (prop.contains("strutsfile")) {
|
||||
prop = prop.replace("strutsfile", "");
|
||||
}
|
||||
|
||||
properties.setProperty(Velocity.RESOURCE_LOADER, prop);
|
||||
clearStrutsFileResourceLoader(properties);
|
||||
}
|
||||
|
||||
/*
|
||||
* Refactored the Velocity templates for the Struts taglib into the classpath from the web path. This will
|
||||
* enable Struts projects to have access to the templates by simply including the Struts jar file.
|
||||
* Unfortunately, there does not appear to be a macro for the class loader keywords
|
||||
*/
|
||||
setStrutsClasspathResourceLoader(properties);
|
||||
|
||||
String directives = tagLibraries.stream().map(TagLibraryDirectiveProvider::getDirectiveClasses)
|
||||
.flatMap(Collection::stream).map(directive -> directive.getName() + ",").collect(joining());
|
||||
|
||||
String userDirective = properties.getProperty(OLD_CUSTOM_DIRECTIVES);
|
||||
String newDirective = isBlank(userDirective) ? directives : userDirective.strip() + "," + directives;
|
||||
properties.setProperty(OLD_CUSTOM_DIRECTIVES, newDirective);
|
||||
}
|
||||
|
||||
private void setStrutsFileResourceLoader(Properties properties, String realPath) {
|
||||
properties.setProperty("strutsfile.resource.loader.description", "Velocity File Resource Loader");
|
||||
properties.setProperty("strutsfile.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
|
||||
properties.setProperty("strutsfile.resource.loader.path", realPath);
|
||||
properties.setProperty("strutsfile.resource.loader.modificationCheckInterval", "2");
|
||||
properties.setProperty("strutsfile.resource.loader.cache", "true");
|
||||
}
|
||||
|
||||
private void clearStrutsFileResourceLoader(Properties properties) {
|
||||
String prop = properties.getProperty(Velocity.RESOURCE_LOADER)
|
||||
.replace("strutsfile,", "")
|
||||
.replace(", strutsfile", "")
|
||||
.replace("strutsfile", "");
|
||||
properties.setProperty(Velocity.RESOURCE_LOADER, prop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactored the Velocity templates for the Struts taglib into the classpath from the web path. This will
|
||||
* enable Struts projects to have access to the templates by simply including the Struts jar file.
|
||||
* Unfortunately, there does not appear to be a macro for the class loader keywords
|
||||
*/
|
||||
private void setStrutsClasspathResourceLoader(Properties properties) {
|
||||
properties.setProperty("strutsclass.resource.loader.description", "Velocity Classpath Resource Loader");
|
||||
properties.setProperty("strutsclass.resource.loader.class", "org.apache.struts2.views.velocity.StrutsResourceLoader");
|
||||
properties.setProperty("strutsclass.resource.loader.modificationCheckInterval", "2");
|
||||
properties.setProperty("strutsclass.resource.loader.cache", "true");
|
||||
|
||||
// components
|
||||
String directives = tagLibraries.stream().map(TagLibraryDirectiveProvider::getDirectiveClasses).flatMap(
|
||||
Collection::stream).map(directive -> directive.getName() + ",").collect(joining());
|
||||
|
||||
String userdirective = properties.getProperty("userdirective");
|
||||
if (userdirective == null || userdirective.trim().isEmpty()) {
|
||||
userdirective = directives;
|
||||
} else {
|
||||
userdirective = userdirective.trim() + "," + directives;
|
||||
}
|
||||
properties.setProperty("userdirective", userdirective);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.ActionContext;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
import org.apache.velocity.tools.ToolContext;
|
||||
import org.apache.velocity.tools.ToolManager;
|
||||
import org.apache.velocity.tools.ToolboxFactory;
|
||||
|
||||
import static org.apache.commons.lang3.ObjectUtils.requireNonEmpty;
|
||||
|
||||
/**
|
||||
* @since 7.0
|
||||
*/
|
||||
public class VelocityTools {
|
||||
|
||||
private final String toolLocation;
|
||||
private ToolManager toolManager;
|
||||
private VelocityEngine velocityEngine;
|
||||
|
||||
public VelocityTools(String toolLocation) {
|
||||
this.toolLocation = requireNonEmpty(toolLocation);
|
||||
}
|
||||
|
||||
public void init(ServletContext servletContext, VelocityEngine velocityEngine) {
|
||||
this.toolManager = new ToolManager();
|
||||
this.toolManager.configure(toolLocation);
|
||||
this.velocityEngine = velocityEngine;
|
||||
}
|
||||
|
||||
public Context createContext() {
|
||||
if (toolManager == null || velocityEngine == null ||
|
||||
ActionContext.getContext() == null || ActionContext.getContext().getServletContext() == null) {
|
||||
return null;
|
||||
}
|
||||
var toolContext = new ToolContext(velocityEngine);
|
||||
toolContext.addToolbox(toolManager.getToolboxFactory().createToolbox(ToolboxFactory.DEFAULT_SCOPE));
|
||||
return toolContext;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -20,6 +20,8 @@ package org.apache.struts2.views.velocity;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.junit.StrutsJUnit4TestCase;
|
||||
import org.apache.velocity.context.Context;
|
||||
@@ -28,8 +30,6 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.apache.struts2.views.velocity.VelocityManager.KEY_VELOCITY_STRUTS_CONTEXT;
|
||||
@@ -75,7 +75,7 @@ public class VelocityManagerTest extends StrutsJUnit4TestCase {
|
||||
velocityManager.init(servletContext);
|
||||
|
||||
assertNotNull(velocityManager.getVelocityEngine());
|
||||
assertNotNull(velocityManager.getToolboxManager());
|
||||
assertNotNull(velocityManager.getVelocityTools());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user