mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-12 14:39:49 +00:00
8368172: Make java.time.format.DateTimePrintContext immutable
Reviewed-by: liach
This commit is contained in:
parent
723d6f83a2
commit
a588c120fc
@ -1904,11 +1904,11 @@ public final class DateTimeFormatter {
|
||||
try {
|
||||
DateTimePrintContext context = new DateTimePrintContext(temporal, this);
|
||||
if (appendable instanceof StringBuilder) {
|
||||
printerParser.format(context, (StringBuilder) appendable);
|
||||
printerParser.format(context, (StringBuilder) appendable, false);
|
||||
} else {
|
||||
// buffer output to avoid writing to appendable in case of error
|
||||
StringBuilder buf = new StringBuilder(32);
|
||||
printerParser.format(context, buf);
|
||||
printerParser.format(context, buf, false);
|
||||
appendable.append(buf);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2484,10 +2485,15 @@ public final class DateTimeFormatterBuilder {
|
||||
*
|
||||
* @param context the context to format using, not null
|
||||
* @param buf the buffer to append to, not null
|
||||
* @param optional whether the enclosing formatter is optional.
|
||||
* If true and this formatter is nested in an optional formatter
|
||||
* and the data is not available, then no error is returned and
|
||||
* nothing is appended to the buffer. If false and the data is not available
|
||||
* then an exception is thrown or false is returned as appropriate.
|
||||
* @return false if unable to query the value from the date-time, true otherwise
|
||||
* @throws DateTimeException if the date-time cannot be printed successfully
|
||||
*/
|
||||
boolean format(DateTimePrintContext context, StringBuilder buf);
|
||||
boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional);
|
||||
|
||||
/**
|
||||
* Parses text into date-time information.
|
||||
@ -2537,21 +2543,13 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
int length = buf.length();
|
||||
if (optional) {
|
||||
context.startOptional();
|
||||
}
|
||||
try {
|
||||
for (DateTimePrinterParser pp : printerParsers) {
|
||||
if (pp.format(context, buf) == false) {
|
||||
buf.setLength(length); // reset buffer
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (optional) {
|
||||
context.endOptional();
|
||||
boolean effectiveOptional = optional | this.optional;
|
||||
for (DateTimePrinterParser pp : printerParsers) {
|
||||
if (!pp.format(context, buf, effectiveOptional)) {
|
||||
buf.setLength(length); // reset buffer
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -2620,9 +2618,9 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
int preLen = buf.length();
|
||||
if (printerParser.format(context, buf) == false) {
|
||||
if (printerParser.format(context, buf, optional) == false) {
|
||||
return false;
|
||||
}
|
||||
int len = buf.length() - preLen;
|
||||
@ -2689,7 +2687,7 @@ public final class DateTimeFormatterBuilder {
|
||||
LENIENT;
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
return true; // nothing to do here
|
||||
}
|
||||
|
||||
@ -2731,7 +2729,7 @@ public final class DateTimeFormatterBuilder {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2757,7 +2755,7 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
buf.append(literal);
|
||||
return true;
|
||||
}
|
||||
@ -2807,7 +2805,7 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
buf.append(literal);
|
||||
return true;
|
||||
}
|
||||
@ -2919,8 +2917,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long valueLong = context.getValue(field);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long valueLong = context.getValue(field, optional);
|
||||
if (valueLong == null) {
|
||||
return false;
|
||||
}
|
||||
@ -3374,8 +3372,8 @@ public final class DateTimeFormatterBuilder {
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long value = context.getValue(field);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long value = context.getValue(field, optional);
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@ -3563,8 +3561,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long value = context.getValue(field);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long value = context.getValue(field, optional);
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@ -3711,8 +3709,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long value = context.getValue(field);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long value = context.getValue(field, optional);
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@ -3724,7 +3722,7 @@ public final class DateTimeFormatterBuilder {
|
||||
text = provider.getText(chrono, field, value, textStyle, context.getLocale());
|
||||
}
|
||||
if (text == null) {
|
||||
return numberPrinterParser().format(context, buf);
|
||||
return numberPrinterParser().format(context, buf, optional);
|
||||
}
|
||||
buf.append(text);
|
||||
return true;
|
||||
@ -3806,9 +3804,9 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
// use INSTANT_SECONDS, thus this code is not bound by Instant.MAX
|
||||
Long inSecs = context.getValue(INSTANT_SECONDS);
|
||||
Long inSecs = context.getValue(INSTANT_SECONDS, optional);
|
||||
Long inNanos = null;
|
||||
if (context.getTemporal().isSupported(NANO_OF_SECOND)) {
|
||||
inNanos = context.getTemporal().getLong(NANO_OF_SECOND);
|
||||
@ -3992,8 +3990,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long offsetSecs = context.getValue(OFFSET_SECONDS);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long offsetSecs = context.getValue(OFFSET_SECONDS, optional);
|
||||
if (offsetSecs == null) {
|
||||
return false;
|
||||
}
|
||||
@ -4291,8 +4289,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long offsetSecs = context.getValue(OFFSET_SECONDS);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long offsetSecs = context.getValue(OFFSET_SECONDS, optional);
|
||||
if (offsetSecs == null) {
|
||||
return false;
|
||||
}
|
||||
@ -4505,8 +4503,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
ZoneId zone = context.getValue(TemporalQueries.zoneId());
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
ZoneId zone = context.getValue(TemporalQueries.zoneId(), optional);
|
||||
if (zone == null) {
|
||||
return false;
|
||||
}
|
||||
@ -4627,8 +4625,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
ZoneId zone = context.getValue(query);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
ZoneId zone = context.getValue(query, optional);
|
||||
if (zone == null) {
|
||||
return false;
|
||||
}
|
||||
@ -5052,8 +5050,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Chronology chrono = context.getValue(TemporalQueries.chronology());
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Chronology chrono = context.getValue(TemporalQueries.chronology(), optional);
|
||||
if (chrono == null) {
|
||||
return false;
|
||||
}
|
||||
@ -5149,9 +5147,9 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Chronology chrono = Chronology.from(context.getTemporal());
|
||||
return formatter(context.getLocale(), chrono).toPrinterParser(false).format(context, buf);
|
||||
return formatter(context.getLocale(), chrono).toPrinterParser(false).format(context, buf, optional);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -5260,8 +5258,8 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
return printerParser(context.getLocale()).format(context, buf);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
return printerParser(context.getLocale()).format(context, buf, optional);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -5364,12 +5362,12 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
Long hod = context.getValue(HOUR_OF_DAY);
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf, boolean optional) {
|
||||
Long hod = context.getValue(HOUR_OF_DAY, optional);
|
||||
if (hod == null) {
|
||||
return false;
|
||||
}
|
||||
Long moh = context.getValue(MINUTE_OF_HOUR);
|
||||
Long moh = context.getValue(MINUTE_OF_HOUR, optional);
|
||||
long value = Math.floorMod(hod, 24) * 60 + (moh != null ? Math.floorMod(moh, 60) : 0);
|
||||
Locale locale = context.getLocale();
|
||||
LocaleStore store = findDayPeriodStore(locale);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -86,11 +87,6 @@ import java.util.Objects;
|
||||
* <p>
|
||||
* This class provides a single wrapper to items used in the format.
|
||||
*
|
||||
* @implSpec
|
||||
* This class is a mutable context intended for use from a single thread.
|
||||
* Usage of the class is thread-safe within standard printing as the framework creates
|
||||
* a new instance of the class for each format and printing is single-threaded.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
final class DateTimePrintContext {
|
||||
@ -103,10 +99,6 @@ final class DateTimePrintContext {
|
||||
* The formatter, not null.
|
||||
*/
|
||||
private final DateTimeFormatter formatter;
|
||||
/**
|
||||
* Whether the current formatter is optional.
|
||||
*/
|
||||
private int optional;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the context.
|
||||
@ -115,7 +107,6 @@ final class DateTimePrintContext {
|
||||
* @param formatter the formatter controlling the format, not null
|
||||
*/
|
||||
DateTimePrintContext(TemporalAccessor temporal, DateTimeFormatter formatter) {
|
||||
super();
|
||||
this.temporal = adjust(temporal, formatter);
|
||||
this.formatter = formatter;
|
||||
}
|
||||
@ -348,30 +339,17 @@ final class DateTimePrintContext {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Starts the printing of an optional segment of the input.
|
||||
*/
|
||||
void startOptional() {
|
||||
this.optional++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the printing of an optional segment of the input.
|
||||
*/
|
||||
void endOptional() {
|
||||
this.optional--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value using a query.
|
||||
*
|
||||
* @param query the query to use, not null
|
||||
* @param optional whether the query is optional, true if the query may be missing
|
||||
* @return the result, null if not found and optional is true
|
||||
* @throws DateTimeException if the type is not available and the section is not optional
|
||||
*/
|
||||
<R> R getValue(TemporalQuery<R> query) {
|
||||
<R> R getValue(TemporalQuery<R> query, boolean optional) {
|
||||
R result = temporal.query(query);
|
||||
if (result == null && optional == 0) {
|
||||
if (result == null && !optional) {
|
||||
throw new DateTimeException("Unable to extract " +
|
||||
query + " from temporal " + temporal);
|
||||
}
|
||||
@ -384,11 +362,12 @@ final class DateTimePrintContext {
|
||||
* This will return the value for the specified field.
|
||||
*
|
||||
* @param field the field to find, not null
|
||||
* @param optional whether the field is optional, true if the field may be missing
|
||||
* @return the value, null if not found and optional is true
|
||||
* @throws DateTimeException if the field is not available and the section is not optional
|
||||
*/
|
||||
Long getValue(TemporalField field) {
|
||||
if (optional > 0 && !temporal.isSupported(field)) {
|
||||
Long getValue(TemporalField field, boolean optional) {
|
||||
if (optional && !temporal.isSupported(field)) {
|
||||
return null;
|
||||
}
|
||||
return temporal.getLong(field);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user