Skip to content

Commit

Permalink
Merge branch '4.0' into issue_5543
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Feb 1, 2025
2 parents e57b5c7 + 5f7d9a7 commit 6388bce
Show file tree
Hide file tree
Showing 7 changed files with 688 additions and 52 deletions.
98 changes: 46 additions & 52 deletions impl/src/main/java/jakarta/faces/convert/DateTimeConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,20 @@
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQuery;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;

import jakarta.faces.component.PartialStateHolder;
import jakarta.faces.component.UIComponent;
Expand Down Expand Up @@ -169,6 +175,17 @@ public class DateTimeConverter implements Converter, PartialStateHolder {

private static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT");

private static final Map<String, TemporalQuery<Object>> JAVA_TIME_TYPES = Map.of(
"localDate", LocalDate::from,
"localDateTime", LocalDateTime::from,
"localTime", LocalTime::from,
"offsetTime", OffsetTime::from,
"offsetDateTime", OffsetDateTime::from,
"zonedDateTime", ZonedDateTime::from
);

private static final Pattern ESCAPED_DATE_TIME_PATTERN = Pattern.compile("'[^']*+'");

// ------------------------------------------------------ Instance Variables

private String dateStyle = "default";
Expand Down Expand Up @@ -507,83 +524,60 @@ private FormatWrapper getDateFormat(Locale locale) {
}

DateFormat df = null;
DateTimeFormatterBuilder dtfBuilder = null;
DateTimeFormatter dtf = null;
TemporalQuery from = null;
if (pattern != null && !isJavaTimeType(type)) {
df = new SimpleDateFormat(pattern, locale);
TemporalQuery<Object> fromJavaTime = JAVA_TIME_TYPES.get(type);

if (pattern != null) {
if (fromJavaTime == null) {
df = new SimpleDateFormat(pattern, locale);
} else {
dtfBuilder = new DateTimeFormatterBuilder().appendPattern(pattern);
}
} else if (type.equals("both")) {
df = DateFormat.getDateTimeInstance(getStyle(dateStyle), getStyle(timeStyle), locale);
} else if (type.equals("date")) {
df = DateFormat.getDateInstance(getStyle(dateStyle), locale);
} else if (type.equals("time")) {
df = DateFormat.getTimeInstance(getStyle(timeStyle), locale);
} else if (type.equals("localDate")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ofLocalizedDate(getFormatStyle(dateStyle)).withLocale(locale);
}
from = LocalDate::from;
dtfBuilder = new DateTimeFormatterBuilder().appendLocalized(getFormatStyle(dateStyle), null);
} else if (type.equals("localDateTime")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ofLocalizedDateTime(getFormatStyle(dateStyle), getFormatStyle(timeStyle)).withLocale(locale);
}
from = LocalDateTime::from;
dtfBuilder = new DateTimeFormatterBuilder().appendLocalized(getFormatStyle(dateStyle), getFormatStyle(timeStyle));
} else if (type.equals("localTime")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ofLocalizedTime(getFormatStyle(timeStyle)).withLocale(locale);
}
from = LocalTime::from;
dtfBuilder = new DateTimeFormatterBuilder().appendLocalized(null, getFormatStyle(timeStyle));
} else if (type.equals("offsetTime")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ISO_OFFSET_TIME.withLocale(locale);
}
from = OffsetTime::from;
dtf = DateTimeFormatter.ISO_OFFSET_TIME.withLocale(locale);
} else if (type.equals("offsetDateTime")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME.withLocale(locale);
}
from = OffsetDateTime::from;
dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME.withLocale(locale);
} else if (type.equals("zonedDateTime")) {
if (null != pattern) {
dtf = DateTimeFormatter.ofPattern(pattern, locale);
} else {
dtf = DateTimeFormatter.ISO_ZONED_DATE_TIME.withLocale(locale);
}
from = ZonedDateTime::from;
dtf = DateTimeFormatter.ISO_ZONED_DATE_TIME.withLocale(locale);
} else {
// PENDING(craigmcc) - i18n
throw new IllegalArgumentException("Invalid type: " + type);
}
if (null != df) {

if (df != null) {
df.setLenient(false);
return new FormatWrapper(df);
} else if (null != dtf) {
return new FormatWrapper(dtf, from);
} else {
if (dtfBuilder != null) {
if (pattern == null || !ESCAPED_DATE_TIME_PATTERN.matcher(pattern).replaceAll("").contains("uu")) {
dtfBuilder.parseDefaulting(ChronoField.ERA, 1);
}

dtf = dtfBuilder.toFormatter(locale).withChronology(IsoChronology.INSTANCE).withResolverStyle(ResolverStyle.STRICT);
}

if (dtf != null) {
return new FormatWrapper(dtf, fromJavaTime);
}
}

// PENDING(craigmcc) - i18n
throw new IllegalArgumentException("Invalid type: " + type);
}

private static boolean isJavaTimeType(String type) {
boolean result = false;
if (null != type && type.length() > 1) {
char c = type.charAt(0);
result = c == 'l' || c == 'o' || c == 'z';
}

return result;
}

/**
* <p>
* Return the <code>Locale</code> we will use for localizing our formatting and parsing processing.
Expand Down
41 changes: 41 additions & 0 deletions test/issue5541/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) Contributors to Eclipse Foundation.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception, which is available at
https://www.gnu.org/software/classpath/license.html.
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.eclipse.mojarra.test</groupId>
<artifactId>pom</artifactId>
<version>4.0.10-SNAPSHOT</version>
</parent>

<artifactId>issue5541</artifactId>
<packaging>war</packaging>

<name>Mojarra ${project.version} - INTEGRATION TESTS - ${project.artifactId}</name>

<dependencies>
<dependency>
<groupId>org.eclipse.mojarra.test</groupId>
<artifactId>base</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) Contributors to the Eclipse Foundation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GPL-2.0 with Classpath-exception-2.0 which
* is available at https://openjdk.java.net/legal/gplv2+ce.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 or Apache-2.0
*/
package org.eclipse.mojarra.test.issue5541;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.Date;

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;

@Named
@RequestScoped
public class Issue5541Bean {

private Date date;
private Date dateTime;
private LocalDate localDate;
private LocalTime localTime;
private LocalDateTime localDateTime;
private ZonedDateTime zonedDateTime;

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

public Date getDateTime() {
return dateTime;
}

public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}

public LocalDate getLocalDate() {
return localDate;
}

public void setLocalDate(LocalDate localDate) {
this.localDate = localDate;
}

public LocalTime getLocalTime() {
return localTime;
}

public void setLocalTime(LocalTime localTime) {
this.localTime = localTime;
}

public LocalDateTime getLocalDateTime() {
return localDateTime;
}

public void setLocalDateTime(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}

public ZonedDateTime getZonedDateTime() {
return zonedDateTime;
}

public void setZonedDateTime(ZonedDateTime zonedDateTime) {
this.zonedDateTime = zonedDateTime;
}
}
34 changes: 34 additions & 0 deletions test/issue5541/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) Contributors to Eclipse Foundation.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception, which is available at
https://www.gnu.org/software/classpath/license.html.
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-->
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
77 changes: 77 additions & 0 deletions test/issue5541/src/main/webapp/issue5541.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<!--
Copyright (c) Contributors to Eclipse Foundation.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception, which is available at
https://www.gnu.org/software/classpath/license.html.
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-->
<html lang="en"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core"
xmlns:ui="jakarta.faces.facelets"
xmlns:c="jakarta.tags.core"
>
<h:head>
<title>issue5541</title>
</h:head>
<h:body>
<c:set var="yearPattern" value="#{param.acceptBce ? 'uuuu' : 'yyyy'}" />

<h:form id="form">
<h:inputText id="inputDate" value="#{issue5541Bean.date}">
<f:convertDateTime pattern="yyyy-MM-dd" />
</h:inputText>
<h:inputText id="inputDateTime" value="#{issue5541Bean.dateTime}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss" />
</h:inputText>
<h:inputText id="inputLocalDate" value="#{issue5541Bean.localDate}">
<f:convertDateTime type="localDate" pattern="#{yearPattern}-MM-dd" />
</h:inputText>
<h:inputText id="inputLocalTime" value="#{issue5541Bean.localTime}">
<f:convertDateTime type="localTime" pattern="HH:mm:ss" />
</h:inputText>
<h:inputText id="inputLocalDateTime" value="#{issue5541Bean.localDateTime}">
<f:convertDateTime type="localDateTime" pattern="#{yearPattern}-MM-dd HH:mm:ss" />
</h:inputText>
<h:inputText id="inputZonedDateTime" value="#{issue5541Bean.zonedDateTime}">
<f:convertDateTime type="zonedDateTime" pattern="#{yearPattern}-MM-dd HH 'uur' mm 'min' X" />
</h:inputText>

<h:commandButton id="submit" value="submit">
<f:param name="acceptBce" value="#{param.acceptBce}" />
</h:commandButton>

<h:outputText id="outputDate" value="#{issue5541Bean.date}">
<f:convertDateTime pattern="#{yearPattern}-MM-dd" />
</h:outputText>
<h:outputText id="outputDateTime" value="#{issue5541Bean.dateTime}">
<f:convertDateTime pattern="#{yearPattern}-MM-dd HH:mm:ss" />
</h:outputText>
<h:outputText id="outputLocalDate" value="#{issue5541Bean.localDate}">
<f:convertDateTime type="localDate" pattern="#{yearPattern}-MM-dd" />
</h:outputText>
<h:outputText id="outputLocalTime" value="#{issue5541Bean.localTime}">
<f:convertDateTime type="localTime" pattern="HH:mm:ss" />
</h:outputText>
<h:outputText id="outputLocalDateTime" value="#{issue5541Bean.localDateTime}">
<f:convertDateTime type="localDateTime" pattern="#{yearPattern}-MM-dd HH:mm:ss" />
</h:outputText>
<h:outputText id="outputZonedDateTime" value="#{issue5541Bean.zonedDateTime}">
<f:convertDateTime type="zonedDateTime" pattern="#{yearPattern}-MM-dd HH 'uur' mm 'min' X" />
</h:outputText>

<h:messages id="messages" />
</h:form>
</h:body>
</html>
Loading

0 comments on commit 6388bce

Please sign in to comment.