[ 
https://issues.apache.org/jira/browse/WW-5811?focusedWorklogId=1050039&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1050039
 ]

ASF GitHub Bot logged work on WW-5811:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 25/Oct/26 14:41
            Start Date: 25/Oct/26 14:41
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #2061:
URL: https://github.com/apache/struts/pull/2061

   Fixes [WW-5811](https://issues.apache.org/jira/browse/WW-5811)
   
   ## What changes
   
   HTML5 constraint derivation (`struts.ui.html5.constraints`, html5 theme) now 
covers temporal controls:
   
   - **`min`/`max` on `date` controls** from a range validator whose bounds are 
`LocalDate` (`localdate`, WW-5816) or `java.util.Date` (`date`), written as 
`yyyy-MM-dd`.
     - A `java.util.Date` bound is reduced to its calendar date in the default 
time zone, which is the zone `DateConverter` parses the submitted `yyyy-MM-dd` 
in.
     - Dropping the time never makes the browser stricter than the server. With 
a `min` of 10:00 on the 1st, the browser allows the 1st and the server rejects 
it, which is the permitted direction. A `max` day submits as midnight, which is 
≤ `max`.
     - Years outside 0001–9999 are skipped. `LocalDate.toString()` writes 
`+10000-…`, which is not a valid HTML date.
   - **`required` on temporal controls** (`date`, `month`, `week`, `time`, 
`datetime-local`) from a `required` validator, when the bound property's 
declared type converts `""` to null:
     - The types are `java.util.Date` and its subclasses, `Calendar`, 
`LocalDate`, `LocalDateTime`, `LocalTime` and `OffsetDateTime`.
     - An empty submit then fails on both sides.
     - A `String` property keeps `""` and so still gets no `required`.
   
   ## Design decisions (agreed on the ticket discussion)
   
   - **Scope is cut to the `date` control for ranges.** No built-in converter 
and range validator pair round-trips the other temporal controls:
     - `datetime-local` submits without seconds, which `java.util.Date` does 
not parse.
     - `time` has no `LocalTime` range validator.
     - `month` and `week` have no converter at all.
     - Emitting attributes nothing on the server matches would be untestable, 
so these controls are left for a future ticket if wanted.
   - **SPI compatibility.** `HtmlConstraintProvider` (public since 7.4.0) gains 
a `default` `constraintsFor(..., Class<?> propertyType)` overload that 
delegates to the 7.4.0 method, so existing providers compile and behave 
unchanged. `UIBean` calls the new overload.
   - **Fixed list of types, not a trial conversion.** The list lives in the 
protected `convertsBlankToNull(Class)`, so an app whose own converter maps `""` 
to a value can override one method.
   - **Property type lookup.** `Form.getPropertyType` resolves the type on the 
object parameter binding writes to (the pushed model, then the action). It then 
walks *declared* types, so a null intermediate object such as a not-yet-created 
`user` does not hide it. An indexed or unknown path gives null, which means no 
`required`.
   - Existing protected method signatures are untouched. The new behaviour 
lives in new methods (`addDateRange`, `addTemporalRequired`, 
`convertsBlankToNull`), so subclass overrides keep being called.
   
   ## Migration note for 7.5.0
   
   A **subclass of `StrutsHtmlConstraintProvider`** that overrides the public 
4-argument `constraintsFor` is now bypassed, because the framework calls the 
5-argument overload. Such a subclass should override the 5-argument method 
instead. Providers that implement the interface directly are unaffected.
   
   ## Tests
   
   - `StrutsHtmlConstraintProviderTest`:
     - `LocalDate` and `java.util.Date` bounds. The `Date` case pins 
`Asia/Tokyo` with a bound whose UTC date differs, so it cannot pass vacuously 
on a UTC machine.
     - Years out of range, and the other temporal controls getting no 
`min`/`max`.
     - `required` for each listed type on each temporal control.
     - No `required` for `String`, for an unknown type, or on a text control.
     - A provider implementing only the 4-argument method still receives the 
call.
   - `ConstraintAttributesTest`: the property type handed to the provider for a 
top-level field, a nested field through null objects, a model-driven field, and 
indexed and unknown fields.
   - `Html5ConstraintRenderingTest`:
     - Replaces `testRendersNoRequiredOnADateTextField`, as the ticket asks.
     - Covers `datetextfield` and `textfield type="date"` rendering `required`, 
`min` and `max`, and a `String`-bound date input rendering no `required`.
   - The rendering tests were checked by mutation: disabling the type check or 
the date-range branch fails them.
   - Full `core` suite passes on JDK 17 and JDK 25 (3610 tests).
   
   Docs: a struts-site PR follows for 
`core-developers/client-side-validation.md`, whose mapping table still says 
date ranges are deferred.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1050039)
    Remaining Estimate: 0h
            Time Spent: 10m

> Derive HTML5 min/max and required constraints for temporal controls
> -------------------------------------------------------------------
>
>                 Key: WW-5811
>                 URL: https://issues.apache.org/jira/browse/WW-5811
>             Project: Struts 2
>          Issue Type: Improvement
>          Components: Core Tags
>            Reporter: Lukasz Lenart
>            Assignee: Lukasz Lenart
>            Priority: Major
>             Fix For: 7.5.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> h2. Problem
> HTML5 constraint derivation ({{struts.ui.html5.constraints}}) maps range 
> validators to {{min}}/{{max}} only for {{number}} and {{range}} controls. 
> {{HtmlControlType.supportsRange()}} already includes the temporal controls 
> ({{date}}, {{month}}, {{week}}, {{time}}, {{datetime-local}}), but 
> {{StrutsHtmlConstraintProvider}} deliberately skips them, because their 
> {{min}}/{{max}} values need per-control ISO formatting. As a result, 
> {{DateRangeFieldValidator}} emits nothing.
> The {{required}} validator has a related gap. {{addRequiredField}} emits 
> {{required}} only for {{radio}} and {{file}}, because other controls submit 
> an empty string, which the {{required}} validator accepts. A temporal control 
> bound to a {{java.util.Date}} (or {{java.time}}) property is different: 
> {{DateConverter}} turns {{""}} into null, so the server rejects the empty 
> value just as the browser would. These controls currently get only 
> {{data-msg-required}}.
> This affects {{textfield type="date"}} (and the other temporal types) today, 
> and {{datetextfield}} in the html5 theme (WW-5778).
> h2. Proposal
> In {{StrutsHtmlConstraintProvider}}, map {{DateRangeFieldValidator}} min/max 
> to {{min}}/{{max}} for temporal controls, formatted per control:
> * {{date}} → {{yyyy-MM-dd}}
> * {{month}} → {{yyyy-MM}}
> * {{week}} → {{YYYY-'W'ww}} (ISO week-based year)
> * {{time}} → {{HH:mm}} (or {{HH:mm:ss}})
> * {{datetime-local}} → {{yyyy-MM-dd'T'HH:mm}}
> Emit {{required}} from a {{required}} validator on a temporal control only 
> when the bound property's type converts an empty string to null. A 
> {{textfield type="date"}} bound to a {{String}} property must not get it, 
> because the server accepts {{""}} there. The provider currently sees only the 
> control type and the value, so it needs the property type as well.
> Requirements:
> * Format the bounds the same way the server compares them, so the browser 
> never rejects a value the server accepts (time zone and truncation for 
> {{java.util.Date}} bounds)
> * Skip the attribute for controls/value types that cannot be represented 
> exactly, as the numeric path does for fractional {{min}}
> * Tests for each temporal control, including {{datetextfield}} (replace 
> {{Html5ConstraintRenderingTest.testRendersNoRequiredOnADateTextField}}), and 
> the tag reference updated
> Related: WW-5778 (datetextfield in the html5 theme), WW-5810 (java.time 
> support in datetextfield)



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to