lukaszlenart opened a new pull request, #1813:
URL: https://github.com/apache/struts/pull/1813

   Fixes [WW-3784](https://issues.apache.org/jira/browse/WW-3784)
   
   ## Problem
   
   Wildcard action patterns are matched **first-match-wins, in insertion 
order** (`AbstractMatcher.match()` iterates `compiledPatterns` and breaks on 
the first hit). In XML you control precedence by physically ordering mappings 
(specific before general). Annotation-based configs (Convention plugin 
`@Action` wildcards) have **no ordering guarantee** — registration order comes 
from `Set<Class<?>>` class-scan order, which is arbitrary and non-deterministic 
across JVMs/classloaders. So when two annotated wildcard patterns genuinely 
overlap, the general one can be evaluated first and shadow the specific one, 
leaving the specific action unreachable.
   
   ## Solution
   
   Order each Convention-built package's wildcard action patterns 
**most-specific-first**, so first-match-wins does the right thing — without 
touching XML or core matchers.
   
   - **`ActionNameSpecificityComparator`** (convention) — a 
`Comparator<String>` ranking action-name patterns by: (1) fewer wildcard 
tokens, (2) more literal characters, (3) fewer path-spanning `**` tokens, (4) 
natural order (deterministic tiebreak). Matcher-agnostic: recognises both 
`*`/`**` (`WildcardHelper`) and `{var}` (`NamedVariablePatternMatcher`).
   - **`PackageConfig.Builder.reorderActionConfigs(Comparator<String>)`** 
(core) — a neutral, generic helper that re-inserts the action-config 
`LinkedHashMap` in comparator order. Core does not depend on the plugin; XML 
providers never call it.
   - **`PackageBasedActionConfigBuilder`** — applies the comparator to every 
package in `buildConfiguration(...)`, after `buildIndexActions(...)` and before 
registration.
   
   **Scope:** annotation-sourced configs only. XML keeps its explicit 
file-order semantics untouched. No config flag — always on for Convention 
(safe, since the prior order was non-deterministic). A welcome side effect is 
that Convention action ordering is now **deterministic**.
   
   ## Known limitations (documented in the design spec)
   
   - Ordering is **per-package**. Convention places all actions of a namespace 
into one package, so the common case is covered; competing wildcards spread 
across different convention packages sharing a namespace remain in 
package-registration order.
   - The comparator's primary key (fewer wildcard tokens) can rank a broad `**` 
(one token) ahead of a narrower `*/*` (two tokens). Accepted as a known 
limitation and noted for a possible future refinement.
   
   ## Testing
   
   - `ActionNameSpecificityComparatorTest` — ranking rules incl. the ticket 
case, `*` vs `**`, `{var}`, literals, shuffle-invariance, and the alphabetical 
tiebreak.
   - `PackageConfigBuilderReorderTest` (core) — the reorder helper genuinely 
re-sorts by the supplied comparator.
   - `PackageBasedActionConfigBuilderReorderTest` — the wiring orders 
general-before-specific input into specific-first output.
   - Full suites green: `core` 3053/0, `plugins/convention` 51/0; apache-rat 
clean.
   
   Design and plan: `docs/superpowers/specs/2026-07-26-WW-3784-...-design.md`, 
`docs/superpowers/plans/2026-07-26-WW-3784-...md`.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to