Lukasz Lenart created WW-5770:
---------------------------------

             Summary: Make struts.convention.result.path scopable per package
                 Key: WW-5770
                 URL: https://issues.apache.org/jira/browse/WW-5770
             Project: Struts 2
          Issue Type: Improvement
          Components: Plugin - Convention
            Reporter: Lukasz Lenart


A follow-up to the package-scoped constants from 
[WW-3476|https://issues.apache.org/jira/browse/WW-3476], whose first adopter 
was [WW-5768|https://issues.apache.org/jira/browse/WW-5768] 
({{struts.ui.theme}}, {{struts.ui.templateDir}}).

h2. Goal

Allow a parent package to set the Convention result path for the actions placed 
under it:

{code:xml}<package name="admin-base" extends="convention-default">
    <scoped-constant name="struts.convention.result.path" 
value="/WEB-INF/admin/"/>
</package>
{code}

Today the same effect needs {{@ResultPath}} on every action class or package.

h2. Why it needs more than WW-5768

{{ScopedConstantProvider.getValue(name)}} resolves the package from the current 
{{ActionInvocation}}. The Convention plugin reads the result path in two places:
# *At startup*, in {{DefaultResultMapBuilder.build(...)}} via 
{{ConventionsService.determineResultPath(Class)}}. There is no invocation, so 
{{getValue(name)}} always returns the global value. However, {{build()}} 
receives the action's {{PackageConfig}}. {{PackageBasedActionConfigBuilder}} 
passes {{pkgCfg.build()}}, which was created with {{addParent(parentPkg)}}, so 
{{getAllScopedConstants()}} already includes the parent's overrides.
# *At runtime*, in {{ConventionUnknownHandler.determinePath(...)}} via 
{{determineResultPath(ActionConfig)}}, for action-less results. 
{{actionConfig}} may be {{null}} there.

Both need a lookup by package rather than by invocation. One option is a 
{{getValue(String name, PackageConfig packageConfig)}} on 
{{ScopedConstantProvider}}, with {{getValue(name)}} delegating to it for the 
current invocation's package.

h2. Proposed change
* Register a {{ScopableConstants}} bean in the Convention plugin's 
{{struts-plugin.xml}} returning {{struts.convention.result.path}}.
* Resolve the result path from the action's package in both places, keeping 
this precedence:
## {{@ResultPath}} on the action class or package
## the package's scoped constant (including inherited ones)
## the global {{struts.convention.result.path}}

h2. Tests
* A scoped override on the parent package changes the location of results built 
at startup.
* {{@ResultPath}} still wins over the override.
* An action-less result resolved by {{ConventionUnknownHandler}} uses the 
override.
* With no override, the global path is used.

h2. Docs

On the struts-site, list the constant on the scoped-constants section of 
{{core-developers/package-configuration.md}}, and mention it on the Convention 
plugin page.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to