Skip to content

Commit

Permalink
WW-5190 Extracts method name from config for known action name
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszlenart committed Jun 15, 2022
1 parent ba041e1 commit 5af840b
Showing 1 changed file with 70 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
Expand All @@ -29,7 +30,6 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.RequestUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.util.PrefixTrie;

Expand Down Expand Up @@ -115,7 +115,7 @@ public class DefaultActionMapper implements ActionMapper {
protected boolean allowDynamicMethodCalls = false;
protected boolean allowSlashesInActionNames = false;
protected boolean alwaysSelectFullNamespace = false;
protected PrefixTrie prefixTrie = null;
protected PrefixTrie prefixTrie;

protected Pattern allowedNamespaceNames = Pattern.compile("[a-zA-Z0-9._/\\-]*");
protected String defaultNamespaceName = "/";
Expand All @@ -139,39 +139,35 @@ public class DefaultActionMapper implements ActionMapper {
public DefaultActionMapper() {
prefixTrie = new PrefixTrie() {
{
put(METHOD_PREFIX, new ParameterAction() {
public void execute(String key, ActionMapping mapping) {
if (allowDynamicMethodCalls) {
mapping.setMethod(cleanupMethodName(key.substring(METHOD_PREFIX.length())));
}
put(METHOD_PREFIX, (ParameterAction) (key, mapping) -> {
if (allowDynamicMethodCalls) {
mapping.setMethod(cleanupMethodName(key.substring(METHOD_PREFIX.length())));
}
});

put(ACTION_PREFIX, new ParameterAction() {
public void execute(final String key, ActionMapping mapping) {
if (allowActionPrefix) {
String name = key.substring(ACTION_PREFIX.length());
if (allowDynamicMethodCalls) {
int bang = name.indexOf('!');
if (bang != -1) {
String method = cleanupMethodName(name.substring(bang + 1));
mapping.setMethod(method);
name = name.substring(0, bang);
}
put(ACTION_PREFIX, (ParameterAction) (key, mapping) -> {
if (allowActionPrefix) {
String name = key.substring(ACTION_PREFIX.length());
if (allowDynamicMethodCalls) {
int bang = name.indexOf('!');
if (bang != -1) {
String method = cleanupMethodName(name.substring(bang + 1));
mapping.setMethod(method);
name = name.substring(0, bang);
}
String actionName = cleanupActionName(name);
if (allowSlashesInActionNames && !allowActionCrossNamespaceAccess) {
if (actionName.startsWith("/")) {
actionName = actionName.substring(1);
}
}
String actionName = cleanupActionName(name);
if (allowSlashesInActionNames && !allowActionCrossNamespaceAccess) {
if (actionName.startsWith("/")) {
actionName = actionName.substring(1);
}
if (!allowSlashesInActionNames && !allowActionCrossNamespaceAccess) {
if (actionName.lastIndexOf('/') != -1) {
actionName = actionName.substring(actionName.lastIndexOf('/') + 1);
}
}
if (!allowSlashesInActionNames && !allowActionCrossNamespaceAccess) {
if (actionName.lastIndexOf('/') != -1) {
actionName = actionName.substring(actionName.lastIndexOf('/') + 1);
}
mapping.setName(actionName);
}
mapping.setName(actionName);
}
});

Expand Down Expand Up @@ -293,6 +289,7 @@ public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager
}

parseNameAndNamespace(uri, mapping, configManager);
extractMethodName(mapping, configManager);
handleSpecialParameters(request, mapping);
return parseActionName(mapping);
}
Expand Down Expand Up @@ -324,9 +321,8 @@ protected ActionMapping parseActionName(ActionMapping mapping) {
public void handleSpecialParameters(HttpServletRequest request, ActionMapping mapping) {
// handle special parameter prefixes.
Set<String> uniqueParameters = new HashSet<>();
Map parameterMap = request.getParameterMap();
for (Object o : parameterMap.keySet()) {
String key = (String) o;
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {

// Strip off the image button location info, if found
if (key.endsWith(".x") || key.endsWith(".y")) {
Expand All @@ -353,57 +349,57 @@ public void handleSpecialParameters(HttpServletRequest request, ActionMapping ma
* @param configManager configuration manager
*/
protected void parseNameAndNamespace(String uri, ActionMapping mapping, ConfigurationManager configManager) {
String namespace, name;
String actionNamespace, actionName;
int lastSlash = uri.lastIndexOf('/');
if (lastSlash == -1) {
namespace = "";
name = uri;
actionNamespace = "";
actionName = uri;
} else if (lastSlash == 0) {
// ww-1046, assume it is the root namespace, it will fallback to
// default
// namespace anyway if not found in root namespace.
namespace = "/";
name = uri.substring(lastSlash + 1);
actionNamespace = "/";
actionName = uri.substring(lastSlash + 1);
} else if (alwaysSelectFullNamespace) {
// Simply select the namespace as everything before the last slash
namespace = uri.substring(0, lastSlash);
name = uri.substring(lastSlash + 1);
actionNamespace = uri.substring(0, lastSlash);
actionName = uri.substring(lastSlash + 1);
} else {
// Try to find the namespace in those defined, defaulting to ""
Configuration config = configManager.getConfiguration();
String prefix = uri.substring(0, lastSlash);
namespace = "";
actionNamespace = "";
boolean rootAvailable = false;
// Find the longest matching namespace, defaulting to the default
for (PackageConfig cfg : config.getPackageConfigs().values()) {
String ns = cfg.getNamespace();
if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == '/')) {
if (ns.length() > namespace.length()) {
namespace = ns;
if (ns.length() > actionNamespace.length()) {
actionNamespace = ns;
}
}
if ("/".equals(ns)) {
rootAvailable = true;
}
}

name = uri.substring(namespace.length() + 1);
actionName = uri.substring(actionNamespace.length() + 1);

// Still none found, use root namespace if found
if (rootAvailable && "".equals(namespace)) {
namespace = "/";
if (rootAvailable && "".equals(actionNamespace)) {
actionNamespace = "/";
}
}

if (!allowSlashesInActionNames) {
int pos = name.lastIndexOf('/');
if (pos > -1 && pos < name.length() - 1) {
name = name.substring(pos + 1);
int pos = actionName.lastIndexOf('/');
if (pos > -1 && pos < actionName.length() - 1) {
actionName = actionName.substring(pos + 1);
}
}

mapping.setNamespace(cleanupNamespaceName(namespace));
mapping.setName(cleanupActionName(name));
mapping.setNamespace(cleanupNamespaceName(actionNamespace));
mapping.setName(cleanupActionName(actionName));
}

/**
Expand Down Expand Up @@ -454,6 +450,30 @@ protected String cleanupMethodName(final String rawMethodName) {
}
}

/**
* Reads defined method name for a given action from configuration
*
* @param mapping current instance of {@link ActionMapping}
* @param configurationManager current instance of {@link ConfigurationManager}
*/
protected void extractMethodName(ActionMapping mapping, ConfigurationManager configurationManager) {
String methodName = null;
for (PackageConfig cfg : configurationManager.getConfiguration().getPackageConfigs().values()) {
if (cfg.getNamespace().equals(mapping.getNamespace())) {
ActionConfig actionCfg = cfg.getActionConfigs().get(mapping.getName());
if (actionCfg != null) {
methodName = actionCfg.getMethodName();
LOG.trace("Using method: {} for action mapping: {}", methodName, mapping);
} else {
LOG.debug("No action config for action mapping: {}", mapping);
}
break;
}
}

mapping.setMethod(methodName);
}

/**
* Drops the extension from the action name, storing it in the mapping for later use
*
Expand Down Expand Up @@ -551,7 +571,7 @@ protected void handleExtension(ActionMapping mapping, StringBuilder uri) {
String extension = lookupExtension(mapping.getExtension());

if (extension != null) {
if (extension.length() == 0 || (extension.length() > 0 && uri.indexOf('.' + extension) == -1)) {
if (extension.length() == 0 || uri.indexOf('.' + extension) == -1) {
if (extension.length() > 0) {
uri.append(".").append(extension);
}
Expand Down

0 comments on commit 5af840b

Please sign in to comment.