WW-4808 Allows define multiple suffixes when using

Convention plugin
This commit is contained in:
Lukasz Lenart
2017-08-01 15:50:24 +02:00
19 changed files with 171 additions and 125 deletions
@@ -0,0 +1,63 @@
/*
* 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.convention;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.TextParseUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.Set;
public abstract class AbstractActionNameBuilder implements ActionNameBuilder {
private Set<String> actionSuffix = Collections.singleton("Action");
/**
* @param actionSuffix (Optional) Classes that end with these value will be mapped as actions
* (defaults to "Action")
*/
@Inject(value = ConventionConstants.CONVENTION_ACTION_SUFFIX, required = false)
public void setActionSuffix(String actionSuffix) {
if (StringUtils.isNotBlank(actionSuffix)) {
this.actionSuffix = TextParseUtil.commaDelimitedStringToSet(actionSuffix);
}
}
protected void checkActionName(String actionName) {
for (String suffix : actionSuffix) {
if (actionName.equals(suffix)) {
throw new IllegalStateException("The action name cannot be the same as the action suffix [" + suffix + "]");
}
}
}
protected String truncateSuffixIfMatches(String name) {
String actionName = name;
for (String suffix : actionSuffix) {
if (actionName.endsWith(suffix)) {
actionName = actionName.substring(0, actionName.length() - suffix.length());
}
}
return actionName;
}
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -53,7 +51,7 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider, Di
this.devMode = BooleanUtils.toBoolean(mode);
}
@Inject("struts.convention.classes.reload")
@Inject(ConventionConstants.CONVENTION_CLASSES_RELOAD)
public void setReload(String reload) {
this.reload = BooleanUtils.toBoolean(reload);
}
@@ -1,6 +1,4 @@
/*
* $Id: ClasspathConfigurationProvider.java 655902 2008-05-13 15:15:12Z bpontarelli $
*
* 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
@@ -17,7 +15,8 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/package org.apache.struts2.convention;
*/
package org.apache.struts2.convention;
import com.opensymphony.xwork2.config.PackageProvider;
import com.opensymphony.xwork2.config.Configuration;
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -21,7 +19,7 @@
package org.apache.struts2.convention;
/**
* Constants used to extend the COnvention plugin
* Constants used to extend the Convention plugin
*/
public class ConventionConstants {
public static final String CONVENTION_ACTION_CONFIG_BUILDER = "struts.convention.actionConfigBuilder";
@@ -29,4 +27,26 @@ public class ConventionConstants {
public static final String CONVENTION_RESULT_MAP_BUILDER = "struts.convention.resultMapBuilder";
public static final String CONVENTION_INTERCEPTOR_MAP_BUILDER = "struts.convention.interceptorMapBuilder";
public static final String CONVENTION_CONVENTIONS_SERVICE = "struts.convention.conventionsService";
public static final String CONVENTION_ACTION_NAME_LOWERCASE = "struts.convention.action.name.lowercase";
public static final String CONVENTION_ACTION_NAME_SEPARATOR = "struts.convention.action.name.separator";
public static final String CONVENTION_ACTION_SUFFIX = "struts.convention.action.suffix";
public static final String CONVENTION_CLASSES_RELOAD = "struts.convention.classes.reload";
public static final String CONVENTION_RESULT_PATH = "struts.convention.result.path";
public static final String CONVENTION_DEFAULT_PARENT_PACKAGE = "struts.convention.default.parent.package";
public static final String CONVENTION_REDIRECT_TO_SLASH = "struts.convention.redirect.to.slash";
public static final String CONVENTION_RELATIVE_RESULT_TYPES = "struts.convention.relative.result.types";
public static final String CONVENTION_EXCLUDE_PARENT_CLASS_LOADER = "struts.convention.exclude.parentClassLoader";
public static final String CONVENTION_ACTION_ALWAYS_MAP_EXECUTE = "struts.convention.action.alwaysMapExecute";
public static final String CONVENTION_ACTION_FILE_PROTOCOLS = "struts.convention.action.fileProtocols";
public static final String CONVENTION_ACTION_DISABLE_SCANNING = "struts.convention.action.disableScanning";
public static final String CONVENTION_ACTION_INCLUDE_JARS = "struts.convention.action.includeJars";
public static final String CONVENTION_PACKAGE_LOCATORS_DISABLE = "struts.convention.package.locators.disable";
public static final String CONVENTION_ACTION_PACKAGES = "struts.convention.action.packages";
public static final String CONVENTION_ACTION_CHECK_IMPLEMENTS_ACTION = "struts.convention.action.checkImplementsAction";
public static final String CONVENTION_EXCLUDE_PACKAGES = "struts.convention.exclude.packages";
public static final String CONVENTION_PACKAGE_LOCATORS = "struts.convention.package.locators";
public static final String CONVENTION_PACKAGE_LOCATORS_BASE_PACKAGE = "struts.convention.package.locators.basePackage";
public static final String CONVENTION_ACTION_MAP_ALL_MATCHES = "struts.convention.action.mapAllMatches";
public static final String CONVENTION_ACTION_EAGER_LOADING = "struts.convention.action.eagerLoading";
public static final String CONVENTION_RESULT_FLAT_LAYOUT = "struts.convention.result.flatLayout";
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -94,9 +92,9 @@ public class ConventionUnknownHandler implements UnknownHandler {
@Inject
public ConventionUnknownHandler(Configuration configuration, ObjectFactory objectFactory,
ServletContext servletContext, Container container,
@Inject("struts.convention.default.parent.package") String defaultParentPackageName,
@Inject("struts.convention.redirect.to.slash") String redirectToSlash,
@Inject("struts.convention.action.name.separator") String nameSeparator) {
@Inject(ConventionConstants.CONVENTION_DEFAULT_PARENT_PACKAGE) String defaultParentPackageName,
@Inject(ConventionConstants.CONVENTION_REDIRECT_TO_SLASH) String redirectToSlash,
@Inject(ConventionConstants.CONVENTION_ACTION_NAME_SEPARATOR) String nameSeparator) {
this.configuration = configuration;
this.objectFactory = objectFactory;
this.servletContext = servletContext;
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -49,7 +47,7 @@ public class ConventionsServiceImpl implements ConventionsService {
* the constant name of <strong>struts.convention.result.path</strong>.
*/
@Inject
public ConventionsServiceImpl(@Inject("struts.convention.result.path") String resultPath) {
public ConventionsServiceImpl(@Inject(ConventionConstants.CONVENTION_RESULT_PATH) String resultPath) {
this.resultPath = resultPath;
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -21,7 +19,8 @@
package org.apache.struts2.convention;
import com.opensymphony.xwork2.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* <p>
@@ -32,44 +31,36 @@ import org.apache.commons.lang3.StringUtils;
* action names.
* </p>
*/
public class DefaultActionNameBuilder implements ActionNameBuilder {
private String actionSuffix = "Action";
public class DefaultActionNameBuilder extends AbstractActionNameBuilder {
private static final Logger LOG = LogManager.getLogger(DefaultActionNameBuilder.class);
private boolean lowerCase;
@Inject
public DefaultActionNameBuilder(@Inject(value="struts.convention.action.name.lowercase") String lowerCase) {
public DefaultActionNameBuilder(
@Inject(ConventionConstants.CONVENTION_ACTION_NAME_LOWERCASE) String lowerCase
) {
this.lowerCase = Boolean.parseBoolean(lowerCase);
}
/**
* @param actionSuffix (Optional) Classes that end with these value will be mapped as actions
* (defaults to "Action")
*/
@Inject(value = "struts.convention.action.suffix", required = false)
public void setActionSuffix(String actionSuffix) {
if (StringUtils.isNotBlank(actionSuffix)) {
this.actionSuffix = actionSuffix;
}
}
public String build(String className) {
String actionName = className;
// Truncate Action suffix if found
if (actionName.endsWith(actionSuffix)) {
actionName = actionName.substring(0, actionName.length() - actionSuffix.length());
}
checkActionName(actionName);
// Force initial letter of action to lowercase, if desired
LOG.trace("Truncate Action suffix if found");
actionName = truncateSuffixIfMatches(actionName);
LOG.trace("Force initial letter of action to lowercase, if desired");
if ((lowerCase) && (actionName.length() > 1)) {
int lowerPos = actionName.lastIndexOf('/') + 1;
StringBuilder sb = new StringBuilder();
sb.append(actionName.substring(0, lowerPos));
sb.append(Character.toLowerCase(actionName.charAt(lowerPos)));
sb.append(actionName.substring(lowerPos + 1));
actionName = sb.toString();
actionName = actionName.substring(0, lowerPos) +
Character.toLowerCase(actionName.charAt(lowerPos)) +
actionName.substring(lowerPos + 1);
}
return actionName;
}
}
@@ -1,17 +1,20 @@
/*
* Copyright 2002-2003,2009 The Apache Software Foundation.
*
* Licensed 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.
* 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.convention;
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -131,7 +129,7 @@ public class DefaultResultMapBuilder implements ResultMapBuilder {
*/
@Inject
public DefaultResultMapBuilder(ServletContext servletContext, Container container,
@Inject("struts.convention.relative.result.types") String relativeResultTypes) {
@Inject(ConventionConstants.CONVENTION_RELATIVE_RESULT_TYPES) String relativeResultTypes) {
this.servletContext = servletContext;
this.relativeResultTypes = new HashSet<>(Arrays.asList(relativeResultTypes.split("\\s*[,]\\s*")));
this.conventionsService = container.getInstance(ConventionsService.class, container.getInstance(String.class, ConventionConstants.CONVENTION_CONVENTIONS_SERVICE));
@@ -142,7 +140,7 @@ public class DefaultResultMapBuilder implements ResultMapBuilder {
* ${namespace}/${actionName}-${result}.${extension}, otherwise in the form
* ${namespace}/${actionName}/${result}.${extension}
*/
@Inject("struts.convention.result.flatLayout")
@Inject(ConventionConstants.CONVENTION_RESULT_FLAT_LAYOUT)
public void setFlatResultLayout(String flatResultLayout) {
this.flatResultLayout = BooleanUtils.toBoolean(flatResultLayout);
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -75,7 +73,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
private String packageLocatorsBasePackage;
private boolean disableActionScanning = false;
private boolean disablePackageLocatorsScanning = false;
private String actionSuffix = "Action";
private Set<String> actionSuffix = Collections.singleton("Action");
private boolean checkImplementsAction = true;
private boolean mapAllMatches = false;
private Set<String> loadedFileUrls = new HashSet<>();
@@ -108,8 +106,8 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
*/
@Inject
public PackageBasedActionConfigBuilder(Configuration configuration, Container container, ObjectFactory objectFactory,
@Inject("struts.convention.redirect.to.slash") String redirectToSlash,
@Inject("struts.convention.default.parent.package") String defaultParentPackage) {
@Inject(ConventionConstants.CONVENTION_REDIRECT_TO_SLASH) String redirectToSlash,
@Inject(ConventionConstants.CONVENTION_DEFAULT_PARENT_PACKAGE) String defaultParentPackage) {
// Validate that the parameters are okay
this.configuration = configuration;
@@ -135,7 +133,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param reload Reload configuration when classes change. Defaults to "false" and should not be used
* in production.
*/
@Inject("struts.convention.classes.reload")
@Inject(ConventionConstants.CONVENTION_CLASSES_RELOAD)
public void setReload(String reload) {
this.reload = BooleanUtils.toBoolean(reload);
}
@@ -149,7 +147,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* @param exclude Exclude URLs found by the parent class loader. Defaults to "true", set to true for JBoss
*/
@Inject("struts.convention.exclude.parentClassLoader")
@Inject(ConventionConstants.CONVENTION_EXCLUDE_PARENT_CLASS_LOADER)
public void setExcludeParentClassLoader(String exclude) {
this.excludeParentClassLoader = BooleanUtils.toBoolean(exclude);
}
@@ -158,7 +156,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param alwaysMapExecute If this constant is true, and there is an "execute" method(not annotated), a mapping will be added
* pointing to it, even if there are other mapping in the class
*/
@Inject("struts.convention.action.alwaysMapExecute")
@Inject(ConventionConstants.CONVENTION_ACTION_ALWAYS_MAP_EXECUTE)
public void setAlwaysMapExecute(String alwaysMapExecute) {
this.alwaysMapExecute = BooleanUtils.toBoolean(alwaysMapExecute);
}
@@ -167,7 +165,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* File URLs whose protocol are in these list will be processed as jars containing classes
* @param fileProtocols Comma separated list of file protocols that will be considered as jar files and scanned
*/
@Inject("struts.convention.action.fileProtocols")
@Inject(ConventionConstants.CONVENTION_ACTION_FILE_PROTOCOLS)
public void setFileProtocols(String fileProtocols) {
if (StringUtils.isNotBlank(fileProtocols)) {
this.fileProtocols = TextParseUtil.commaDelimitedStringToSet(fileProtocols);
@@ -177,7 +175,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* @param disableActionScanning Disable scanning for actions
*/
@Inject(value = "struts.convention.action.disableScanning", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_DISABLE_SCANNING, required = false)
public void setDisableActionScanning(String disableActionScanning) {
this.disableActionScanning = BooleanUtils.toBoolean(disableActionScanning);
}
@@ -185,7 +183,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* @param includeJars Comma separated list of regular expressions of jars to be included.
*/
@Inject(value = "struts.convention.action.includeJars", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_INCLUDE_JARS, required = false)
public void setIncludeJars(String includeJars) {
if (StringUtils.isNotEmpty(includeJars)) {
this.includeJars = includeJars.split("\\s*[,]\\s*");
@@ -195,7 +193,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* @param disablePackageLocatorsScanning If set to true, only the named packages will be scanned
*/
@Inject(value = "struts.convention.package.locators.disable", required = false)
@Inject(value = ConventionConstants.CONVENTION_PACKAGE_LOCATORS_DISABLE, required = false)
public void setDisablePackageLocatorsScanning(String disablePackageLocatorsScanning) {
this.disablePackageLocatorsScanning = BooleanUtils.toBoolean(disablePackageLocatorsScanning);
}
@@ -204,7 +202,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param actionPackages (Optional) An optional list of action packages that this should create
* configuration for.
*/
@Inject(value = "struts.convention.action.packages", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_PACKAGES, required = false)
public void setActionPackages(String actionPackages) {
if (StringUtils.isNotBlank(actionPackages)) {
this.actionPackages = actionPackages.split("\\s*[,]\\s*");
@@ -215,7 +213,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param checkImplementsAction (Optional) Map classes that implement com.opensymphony.xwork2.Action
* as actions
*/
@Inject(value = "struts.convention.action.checkImplementsAction", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_CHECK_IMPLEMENTS_ACTION, required = false)
public void setCheckImplementsAction(String checkImplementsAction) {
this.checkImplementsAction = BooleanUtils.toBoolean(checkImplementsAction);
}
@@ -224,10 +222,10 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param actionSuffix (Optional) Classes that end with these value will be mapped as actions
* (defaults to "Action")
*/
@Inject(value = "struts.convention.action.suffix", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_SUFFIX, required = false)
public void setActionSuffix(String actionSuffix) {
if (StringUtils.isNotBlank(actionSuffix)) {
this.actionSuffix = actionSuffix;
this.actionSuffix = TextParseUtil.commaDelimitedStringToSet(actionSuffix);
}
}
@@ -235,7 +233,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param excludePackages (Optional) A list of packages that should be skipped when building
* configuration.
*/
@Inject(value = "struts.convention.exclude.packages", required = false)
@Inject(value = ConventionConstants.CONVENTION_EXCLUDE_PACKAGES, required = false)
public void setExcludePackages(String excludePackages) {
if (StringUtils.isNotBlank(excludePackages)) {
this.excludePackages = excludePackages.split("\\s*[,]\\s*");
@@ -245,7 +243,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* @param packageLocators (Optional) A list of names used to find action packages.
*/
@Inject(value = "struts.convention.package.locators", required = false)
@Inject(value = ConventionConstants.CONVENTION_PACKAGE_LOCATORS, required = false)
public void setPackageLocators(String packageLocators) {
this.packageLocators = packageLocators.split("\\s*[,]\\s*");
}
@@ -254,7 +252,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param packageLocatorsBasePackage (Optional) If set, only packages that start with this
* name will be scanned for actions.
*/
@Inject(value = "struts.convention.package.locators.basePackage", required = false)
@Inject(value = ConventionConstants.CONVENTION_PACKAGE_LOCATORS_BASE_PACKAGE, required = false)
public void setPackageLocatorsBase(String packageLocatorsBasePackage) {
this.packageLocatorsBasePackage = packageLocatorsBasePackage;
}
@@ -264,7 +262,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* even if they don't have a default method. The mapping from
* the url to the action will be delegated the action mapper.
*/
@Inject(value = "struts.convention.action.mapAllMatches", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_MAP_ALL_MATCHES, required = false)
public void setMapAllMatches(String mapAllMatches) {
this.mapAllMatches = BooleanUtils.toBoolean(mapAllMatches);
}
@@ -273,7 +271,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* @param eagerLoading (Optional) If set, found action classes will be instantiated by the ObjectFactory to accelerate future use
* setting it up can clash with Spring managed beans
*/
@Inject(value = "struts.convention.action.eagerLoading", required = false)
@Inject(value = ConventionConstants.CONVENTION_ACTION_EAGER_LOADING, required = false)
public void setEagerLoading(String eagerLoading) {
this.eagerLoading = BooleanUtils.toBoolean(eagerLoading);
}
@@ -615,7 +613,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
// such as com.opensymphony.xwork2.ActionSupport. We repeat the
// package filter here to filter out such results.
boolean inPackage = includeClassNameInActionScan(classInfo.getName());
boolean nameMatches = classInfo.getName().endsWith(actionSuffix);
boolean nameMatches = matchesSuffix(classInfo.getName());
try {
return inPackage && (nameMatches || (checkImplementsAction && com.opensymphony.xwork2.Action.class.isAssignableFrom(classInfo.get())));
@@ -624,6 +622,15 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
return false;
}
}
private boolean matchesSuffix(String name) {
for (String suffix : actionSuffix) {
if (name.endsWith(suffix)) {
return true;
}
}
return false;
}
};
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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
@@ -23,7 +21,6 @@ package org.apache.struts2.convention;
import com.opensymphony.xwork2.inject.Inject;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.commons.lang3.StringUtils;
/**
* <p>
@@ -33,42 +30,31 @@ import org.apache.commons.lang3.StringUtils;
* from the class name.
* </p>
*/
public class SEOActionNameBuilder implements ActionNameBuilder {
public class SEOActionNameBuilder extends AbstractActionNameBuilder {
private static final Logger LOG = LogManager.getLogger(SEOActionNameBuilder.class);
private String actionSuffix = "Action";
private boolean lowerCase;
private String separator;
@Inject
public SEOActionNameBuilder(@Inject(value="struts.convention.action.name.lowercase") String lowerCase,
@Inject(value="struts.convention.action.name.separator") String separator) {
public SEOActionNameBuilder(
@Inject(ConventionConstants.CONVENTION_ACTION_NAME_LOWERCASE) String lowerCase,
@Inject(ConventionConstants.CONVENTION_ACTION_NAME_SEPARATOR) String separator
) {
this.lowerCase = Boolean.parseBoolean(lowerCase);
this.separator = separator;
}
/**
* @param actionSuffix (Optional) Classes that end with these value will be mapped as actions
* (defaults to "Action")
*/
@Inject(value = "struts.convention.action.suffix", required = false)
public void setActionSuffix(String actionSuffix) {
if (StringUtils.isNotBlank(actionSuffix)) {
this.actionSuffix = actionSuffix;
}
}
public String build(String className) {
String actionName = className;
if (actionName.equals(actionSuffix))
throw new IllegalStateException("The action name cannot be the same as the action suffix [" + actionSuffix + "]");
// Truncate Action suffix if found
if (actionName.endsWith(actionSuffix)) {
actionName = actionName.substring(0, actionName.length() - actionSuffix.length());
}
checkActionName(actionName);
// Convert to underscores
LOG.trace("Truncate Action suffix if found");
actionName = truncateSuffixIfMatches(actionName);
LOG.trace("Convert to underscores");
char[] ca = actionName.toCharArray();
StringBuilder build = new StringBuilder("" + ca[0]);
boolean lower = true;
@@ -93,4 +79,5 @@ public class SEOActionNameBuilder implements ActionNameBuilder {
return actionName;
}
}
@@ -1,6 +1,4 @@
/*
* $Id$
*
* 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