Package org.apache.struts2.convention
Class PackageBasedActionConfigBuilder
java.lang.Object
org.apache.struts2.convention.PackageBasedActionConfigBuilder
- All Implemented Interfaces:
ActionConfigBuilder
This class implements the ActionConfigBuilder interface.
-
Constructor Summary
ConstructorDescriptionPackageBasedActionConfigBuilder
(Configuration configuration, Container container, ObjectFactory objectFactory, String redirectToSlash, String defaultParentPackage, String enableSmiInheritance) Constructs actions based on a list of packages. -
Method Summary
Modifier and TypeMethodDescriptionvoid
Builds the action configurations by loading all classes in the packages specified by the property struts.convention.action.packages and then figuring out which classes implement Action or have Action in their name.protected ClassFinder
buildClassFinder
(Test<String> classPackageTest, List<URL> urls) protected void
buildConfiguration
(Set<Class<?>> classes) protected List<ExceptionMappingConfig>
buildExceptionMappings
(ExceptionMapping[] exceptions, String actionName) protected void
buildIndexActions
(Map<String, PackageConfig.Builder> packageConfigs) Determine all the index handling actions and results based on this logic:protected boolean
cannotInstantiate
(Class<?> actionClass) Interfaces, enums, annotations, and abstract classes cannot be instantiated.protected boolean
checkActionPackages
(String classPackageName) Checks if class package match provided list of action packagescheckActionsAnnotation
(Actions actionsAnnotation) Builds a list of actions from an @Actions annotation, and check that they are not all emptyprotected boolean
checkExcludePackages
(String classPackageName) Checks if provided class package is on the exclude listprotected boolean
checkPackageLocators
(String classPackageName) Checks if class package match provided list of package locatorsprotected void
createActionConfig
(PackageConfig.Builder pkgCfg, Class<?> actionClass, String actionName, String actionMethod, Action annotation, Set<String> allowedMethods) Creates a single ActionConfig object.void
destroy()
protected String
determineActionName
(Class<?> actionClass) Converts the class name into an action name using the ActionNameBuilder.determineActionNamespace
(Class<?> actionClass) Determines the namespace(s) for the action based on the action class.getActionAnnotations
(Class<?> actionClass) protected Test<ClassFinder.ClassInfo>
Construct aTest
Object that determines if a specified class should be included in the package scan based on the fullClassFinder.ClassInfo
of the class.protected ClassLoader
protected ClassLoaderInterface
Construct aTest
object that determines if a specified class name should be included in the package scan based on the clazz's package name.protected PackageConfig.Builder
getPackageConfig
(Map<String, PackageConfig.Builder> packageConfigs, String actionNamespace, String actionPackage, Class<?> actionClass, Action action) protected boolean
includeClassNameInActionScan
(String className) Note that we can't include the test foractionSuffix
here because a class is included if its name ends inactionSuffix
OR it implementsAction
.protected void
protected boolean
boolean
void
setActionPackages
(String actionPackages) void
setActionSuffix
(String actionSuffix) void
setAlwaysMapExecute
(String alwaysMapExecute) void
setCheckImplementsAction
(String checkImplementsAction) void
setClassFinderFactory
(ClassFinderFactory classFinderFactory) void
setDevMode
(String mode) void
setDisableActionScanning
(String disableActionScanning) void
setDisablePackageLocatorsScanning
(String disablePackageLocatorsScanning) void
setEagerLoading
(String eagerLoading) void
setExcludePackages
(String excludePackages) void
setExcludeParentClassLoader
(String exclude) void
setFileManagerFactory
(FileManagerFactory fileManagerFactory) void
setFileProtocols
(String fileProtocols) File URLs whose protocol are in these list will be processed as jars containing classesvoid
setIncludeJars
(String includeJars) void
setMapAllMatches
(String mapAllMatches) void
setPackageLocators
(String packageLocators) void
setPackageLocatorsBase
(String packageLocatorsBasePackage) void
setProviderAllowlist
(ProviderAllowlist providerAllowlist) void
void
setSlashesInActionNames
(String slashesInActionNames)
-
Constructor Details
-
PackageBasedActionConfigBuilder
public PackageBasedActionConfigBuilder(Configuration configuration, Container container, ObjectFactory objectFactory, String redirectToSlash, String defaultParentPackage, String enableSmiInheritance) Constructs actions based on a list of packages.- Parameters:
configuration
- The XWork configuration that the new package configs and action configs are added to.container
- Xwork ContainerobjectFactory
- The ObjectFactory used to create the actions and such.redirectToSlash
- A boolean parameter that controls whether or not this will create an action for indexes. If this is set to true, index actions are not created because the unknown handler will redirect from /foo to /foo/. The only action that is created is to the empty action in the namespace (e.g. the namespace /foo and the action "").enableSmiInheritance
- A boolean parameter, which determines if a newly created package config inherits the SMI value of its parent package configdefaultParentPackage
- The default parent package for all the configuration.
-
-
Method Details
-
setDevMode
-
setProviderAllowlist
-
setReload
- Parameters:
reload
- Reload configuration when classes change. Defaults to "false" and should not be used in production.
-
setSlashesInActionNames
-
setExcludeParentClassLoader
- Parameters:
exclude
- Exclude URLs found by the parent class loader. Defaults to "true", set to true for JBoss
-
setAlwaysMapExecute
- Parameters:
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
-
setFileProtocols
File URLs whose protocol are in these list will be processed as jars containing classes- Parameters:
fileProtocols
- Comma separated list of file protocols that will be considered as jar files and scanned
-
setDisableActionScanning
- Parameters:
disableActionScanning
- Disable scanning for actions
-
setIncludeJars
- Parameters:
includeJars
- Comma separated list of regular expressions of jars to be included.
-
setDisablePackageLocatorsScanning
- Parameters:
disablePackageLocatorsScanning
- If set to true, only the named packages will be scanned
-
setActionPackages
- Parameters:
actionPackages
- (Optional) An optional list of action packages that this should create configuration for.
-
setCheckImplementsAction
- Parameters:
checkImplementsAction
- (Optional) Map classes that implement org.apache.struts2.Action as actions
-
setActionSuffix
- Parameters:
actionSuffix
- (Optional) Classes that end with these value will be mapped as actions (defaults to "Action")
-
setExcludePackages
- Parameters:
excludePackages
- (Optional) A list of packages that should be skipped when building configuration.
-
setPackageLocators
- Parameters:
packageLocators
- (Optional) A list of names used to find action packages.
-
setPackageLocatorsBase
- Parameters:
packageLocatorsBasePackage
- (Optional) If set, only packages that start with this name will be scanned for actions.
-
setMapAllMatches
- Parameters:
mapAllMatches
- (Optional) Map actions that match the "*${Suffix}" pattern even if they don't have a default method. The mapping from the url to the action will be delegated the action mapper.
-
setEagerLoading
- Parameters:
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
-
setFileManagerFactory
-
setClassFinderFactory
-
initReloadClassLoader
protected void initReloadClassLoader() -
getClassLoader
-
buildActionConfigs
public void buildActionConfigs()Builds the action configurations by loading all classes in the packages specified by the property struts.convention.action.packages and then figuring out which classes implement Action or have Action in their name. Next, if this class is in a Java package that hasn't been inspected a new PackageConfig (XWork) is created for that Java package using the Java package name. This will contain all the ActionConfigs for all the Action classes that are discovered within that Java package. Next, each class is inspected for theParentPackage
annotation which is used to control the parent package for a specific action. Lastly, theResultMapBuilder
is used to create ResultConfig instances of the action.- Specified by:
buildActionConfigs
in interfaceActionConfigBuilder
-
getClassLoaderInterface
-
isReloadEnabled
protected boolean isReloadEnabled() -
findActions
-
buildClassFinder
-
includeClassNameInActionScan
Note that we can't include the test foractionSuffix
here because a class is included if its name ends inactionSuffix
OR it implementsAction
. Since the whole goal is to avoid loading the class if we don't have to, the (actionSuffix || implements Action) test will have to remain until later. SeegetActionClassTest()
for the test performed on the loadedClassFinder.ClassInfo
structure.- Parameters:
className
- the name of the class to test- Returns:
- true if the specified class should be included in the package-based action scan
-
checkExcludePackages
Checks if provided class package is on the exclude list- Parameters:
classPackageName
- name of class package- Returns:
- false if class package is on the
excludePackages
list
-
checkActionPackages
Checks if class package match provided list of action packages- Parameters:
classPackageName
- name of class package- Returns:
- true if class package is on the
actionPackages
list
-
checkPackageLocators
Checks if class package match provided list of package locators- Parameters:
classPackageName
- name of class package- Returns:
- true if class package is on the
packageLocators
list
-
getClassPackageTest
Construct aTest
object that determines if a specified class name should be included in the package scan based on the clazz's package name. Note that the goal is to avoid loading the class, so the test should only rely on information in the class name itself. The default implementation is to return the result ofincludeClassNameInActionScan(String)
.- Returns:
- a
Test
object that returns true if the specified class name should be included in the package scan
-
getActionClassTest
Construct aTest
Object that determines if a specified class should be included in the package scan based on the fullClassFinder.ClassInfo
of the class. At this point, the class has been loaded, so it's ok to perform tests such as checking annotations or looking at interfaces or super-classes of the specified class.- Returns:
- a
Test
object that returns true if the specified class should be included in the package scan
-
buildConfiguration
-
cannotInstantiate
Interfaces, enums, annotations, and abstract classes cannot be instantiated.- Parameters:
actionClass
- class to check- Returns:
- returns true if the class cannot be instantiated or should be ignored
-
determineActionNamespace
Determines the namespace(s) for the action based on the action class. If there is aNamespace
annotation on the class (including parent classes) or on the package that the class is in, than it is used. Otherwise, the Java package name that the class is in is used in conjunction with either the struts.convention.action.packages or struts.convention.package.locators configuration values. These are used to determine which part of the Java package name should be converted into the namespace for the XWork PackageConfig.- Parameters:
actionClass
- The action class.- Returns:
- The namespace or an empty string.
-
determineActionName
Converts the class name into an action name using the ActionNameBuilder.- Parameters:
actionClass
- The action class.- Returns:
- The action name.
-
getActionAnnotations
Locates all of theActions
andAction
annotations on methods within the Action class and its parent classes.- Parameters:
actionClass
- The action class.- Returns:
- The list of annotations or an empty list if there are none.
-
checkActionsAnnotation
Builds a list of actions from an @Actions annotation, and check that they are not all empty- Parameters:
actionsAnnotation
- Actions annotation- Returns:
- a list of Actions
-
createActionConfig
protected void createActionConfig(PackageConfig.Builder pkgCfg, Class<?> actionClass, String actionName, String actionMethod, Action annotation, Set<String> allowedMethods) Creates a single ActionConfig object.- Parameters:
pkgCfg
- The package the action configuration instance will belong to.actionClass
- The action class.actionName
- The name of the action.actionMethod
- The method that the annotation was on (if the annotation is not null) or the default method (execute).annotation
- The ActionName annotation that might override the action name and possibly
-
buildExceptionMappings
protected List<ExceptionMappingConfig> buildExceptionMappings(ExceptionMapping[] exceptions, String actionName) -
getPackageConfig
protected PackageConfig.Builder getPackageConfig(Map<String, PackageConfig.Builder> packageConfigs, String actionNamespace, String actionPackage, Class<?> actionClass, Action action) -
buildIndexActions
Determine all the index handling actions and results based on this logic:1. Loop over all the namespaces such as /foo and see if it has an action named index 2. If an action doesn't exists in the parent namespace of the same name, create an action in the parent namespace of the same name as the namespace that points to the index action in the namespace. e.g. /foo -> /foo/index 3. Create the action in the namespace for empty string if it doesn't exist. e.g. /foo/ the action is "" and the namespace is /foo
- Parameters:
packageConfigs
- Used to store the actions.
-
destroy
public void destroy()- Specified by:
destroy
in interfaceActionConfigBuilder
-
needsReload
public boolean needsReload()- Specified by:
needsReload
in interfaceActionConfigBuilder
-