Skip to content

Commit 95a6a0c

Browse files
committed
Merge branch '6.2.x'
# Conflicts: # spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java
2 parents cc31bf3 + 15364cf commit 95a6a0c

File tree

3 files changed

+83
-81
lines changed

3 files changed

+83
-81
lines changed

buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void apply(Project project) {
5050
project.getPlugins().apply(CheckstylePlugin.class);
5151
project.getTasks().withType(Checkstyle.class).forEach(checkstyle -> checkstyle.getMaxHeapSize().set("1g"));
5252
CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class);
53-
checkstyle.setToolVersion("10.26.0");
53+
checkstyle.setToolVersion("10.26.1");
5454
checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle"));
5555
String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion();
5656
DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies();

spring-context/src/main/java/org/springframework/format/annotation/DurationFormat.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,19 @@
5353
*/
5454
Unit defaultUnit() default Unit.MILLIS;
5555

56+
5657
/**
5758
* {@link Duration} format styles.
5859
*/
5960
enum Style {
6061

62+
/**
63+
* ISO-8601 formatting.
64+
* <p>This is what the JDK uses in {@link Duration#parse(CharSequence)}
65+
* and {@link Duration#toString()}.
66+
*/
67+
ISO8601,
68+
6169
/**
6270
* Simple formatting based on a short suffix, for example '1s'.
6371
* <p>Supported unit suffixes include: {@code ns, us, ms, s, m, h, d}.
@@ -72,13 +80,6 @@ enum Style {
7280
*/
7381
SIMPLE,
7482

75-
/**
76-
* ISO-8601 formatting.
77-
* <p>This is what the JDK uses in {@link Duration#parse(CharSequence)}
78-
* and {@link Duration#toString()}.
79-
*/
80-
ISO8601,
81-
8283
/**
8384
* Like {@link #SIMPLE}, but allows multiple segments ordered from
8485
* largest-to-smallest units of time, like {@code 1h12m27s}.
@@ -90,6 +91,7 @@ enum Style {
9091
COMPOSITE
9192
}
9293

94+
9395
/**
9496
* {@link Duration} format unit, which mirrors a subset of {@link ChronoUnit} and
9597
* allows conversion to and from a supported {@code ChronoUnit} as well as
@@ -227,7 +229,6 @@ public static Unit fromSuffix(String suffix) {
227229
}
228230
throw new IllegalArgumentException("'" + suffix + "' is not a valid simple duration Unit");
229231
}
230-
231232
}
232233

233234
}

spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java

Lines changed: 73 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
/**
3030
* Support {@code Duration} parsing and printing in several styles, as listed in
3131
* {@link DurationFormat.Style}.
32+
*
3233
* <p>Some styles may not enforce any unit to be present, defaulting to {@code DurationFormat.Unit#MILLIS}
3334
* in that case. Methods in this class offer overloads that take a {@link DurationFormat.Unit} to
3435
* be used as a fall-back instead of the ultimate MILLIS default.
@@ -40,36 +41,13 @@
4041
*/
4142
public abstract class DurationFormatterUtils {
4243

43-
private DurationFormatterUtils() {
44-
// singleton
45-
}
44+
private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$");
4645

47-
/**
48-
* Parse the given value to a duration.
49-
* @param value the value to parse
50-
* @param style the style in which to parse
51-
* @return a duration
52-
*/
53-
public static Duration parse(String value, DurationFormat.Style style) {
54-
return parse(value, style, null);
55-
}
46+
private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$");
47+
48+
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" +
49+
"\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
5650

57-
/**
58-
* Parse the given value to a duration.
59-
* @param value the value to parse
60-
* @param style the style in which to parse
61-
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
62-
* will default to ms)
63-
* @return a duration
64-
*/
65-
public static Duration parse(String value, DurationFormat.Style style, DurationFormat.@Nullable Unit unit) {
66-
Assert.hasText(value, () -> "Value must not be empty");
67-
return switch (style) {
68-
case ISO8601 -> parseIso8601(value);
69-
case SIMPLE -> parseSimple(value, unit);
70-
case COMPOSITE -> parseComposite(value);
71-
};
72-
}
7351

7452
/**
7553
* Print the specified duration in the specified style.
@@ -98,27 +76,30 @@ public static String print(Duration value, DurationFormat.Style style, DurationF
9876
}
9977

10078
/**
101-
* Detect the style then parse the value to return a duration.
79+
* Parse the given value to a duration.
10280
* @param value the value to parse
103-
* @return the parsed duration
104-
* @throws IllegalArgumentException if the value is not a known style or cannot be
105-
* parsed
81+
* @param style the style in which to parse
82+
* @return a duration
10683
*/
107-
public static Duration detectAndParse(String value) {
108-
return detectAndParse(value, null);
84+
public static Duration parse(String value, DurationFormat.Style style) {
85+
return parse(value, style, null);
10986
}
11087

11188
/**
112-
* Detect the style then parse the value to return a duration.
89+
* Parse the given value to a duration.
11390
* @param value the value to parse
91+
* @param style the style in which to parse
11492
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
11593
* will default to ms)
116-
* @return the parsed duration
117-
* @throws IllegalArgumentException if the value is not a known style or cannot be
118-
* parsed
94+
* @return a duration
11995
*/
120-
public static Duration detectAndParse(String value, DurationFormat.@Nullable Unit unit) {
121-
return parse(value, detect(value), unit);
96+
public static Duration parse(String value, DurationFormat.Style style, DurationFormat.@Nullable Unit unit) {
97+
Assert.hasText(value, () -> "Value must not be empty");
98+
return switch (style) {
99+
case ISO8601 -> parseIso8601(value);
100+
case SIMPLE -> parseSimple(value, unit);
101+
case COMPOSITE -> parseComposite(value);
102+
};
122103
}
123104

124105
/**
@@ -142,10 +123,30 @@ public static DurationFormat.Style detect(String value) {
142123
throw new IllegalArgumentException("'" + value + "' is not a valid duration, cannot detect any known style");
143124
}
144125

145-
private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$");
146-
private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$");
147-
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" +
148-
"\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
126+
/**
127+
* Detect the style then parse the value to return a duration.
128+
* @param value the value to parse
129+
* @return the parsed duration
130+
* @throws IllegalArgumentException if the value is not a known style or cannot be
131+
* parsed
132+
*/
133+
public static Duration detectAndParse(String value) {
134+
return detectAndParse(value, null);
135+
}
136+
137+
/**
138+
* Detect the style then parse the value to return a duration.
139+
* @param value the value to parse
140+
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
141+
* will default to ms)
142+
* @return the parsed duration
143+
* @throws IllegalArgumentException if the value is not a known style or cannot be
144+
* parsed
145+
*/
146+
public static Duration detectAndParse(String value, DurationFormat.@Nullable Unit unit) {
147+
return parse(value, detect(value), unit);
148+
}
149+
149150

150151
private static Duration parseIso8601(String value) {
151152
try {
@@ -156,6 +157,11 @@ private static Duration parseIso8601(String value) {
156157
}
157158
}
158159

160+
private static String printSimple(Duration duration, DurationFormat.@Nullable Unit unit) {
161+
unit = (unit == null ? DurationFormat.Unit.MILLIS : unit);
162+
return unit.print(duration);
163+
}
164+
159165
private static Duration parseSimple(String text, DurationFormat.@Nullable Unit fallbackUnit) {
160166
try {
161167
Matcher matcher = SIMPLE_PATTERN.matcher(text);
@@ -172,34 +178,6 @@ private static Duration parseSimple(String text, DurationFormat.@Nullable Unit f
172178
}
173179
}
174180

175-
private static String printSimple(Duration duration, DurationFormat.@Nullable Unit unit) {
176-
unit = (unit == null ? DurationFormat.Unit.MILLIS : unit);
177-
return unit.print(duration);
178-
}
179-
180-
private static Duration parseComposite(String text) {
181-
try {
182-
Matcher matcher = COMPOSITE_PATTERN.matcher(text);
183-
Assert.state(matcher.matches() && matcher.groupCount() > 1, "Does not match composite duration pattern");
184-
String sign = matcher.group(1);
185-
boolean negative = sign != null && sign.equals("-");
186-
187-
Duration result = Duration.ZERO;
188-
DurationFormat.Unit[] units = DurationFormat.Unit.values();
189-
for (int i = 2; i < matcher.groupCount() + 1; i++) {
190-
String segment = matcher.group(i);
191-
if (StringUtils.hasText(segment)) {
192-
DurationFormat.Unit unit = units[units.length - i + 1];
193-
result = result.plus(unit.parse(segment.replace(unit.asSuffix(), "")));
194-
}
195-
}
196-
return negative ? result.negated() : result;
197-
}
198-
catch (Exception ex) {
199-
throw new IllegalArgumentException("'" + text + "' is not a valid composite duration", ex);
200-
}
201-
}
202-
203181
private static String printComposite(Duration duration) {
204182
if (duration.isZero()) {
205183
return DurationFormat.Unit.SECONDS.print(duration);
@@ -244,4 +222,27 @@ private static String printComposite(Duration duration) {
244222
return result.toString();
245223
}
246224

225+
private static Duration parseComposite(String text) {
226+
try {
227+
Matcher matcher = COMPOSITE_PATTERN.matcher(text);
228+
Assert.state(matcher.matches() && matcher.groupCount() > 1, "Does not match composite duration pattern");
229+
String sign = matcher.group(1);
230+
boolean negative = sign != null && sign.equals("-");
231+
232+
Duration result = Duration.ZERO;
233+
DurationFormat.Unit[] units = DurationFormat.Unit.values();
234+
for (int i = 2; i < matcher.groupCount() + 1; i++) {
235+
String segment = matcher.group(i);
236+
if (StringUtils.hasText(segment)) {
237+
DurationFormat.Unit unit = units[units.length - i + 1];
238+
result = result.plus(unit.parse(segment.replace(unit.asSuffix(), "")));
239+
}
240+
}
241+
return negative ? result.negated() : result;
242+
}
243+
catch (Exception ex) {
244+
throw new IllegalArgumentException("'" + text + "' is not a valid composite duration", ex);
245+
}
246+
}
247+
247248
}

0 commit comments

Comments
 (0)