Better local variable name

This commit is contained in:
Gary Gregory 2023-08-10 14:27:38 -04:00
parent 075b3e1a40
commit b3eebfae44
1 changed files with 95 additions and 89 deletions

View File

@ -44,32 +44,37 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.LocaleUtils; import org.apache.commons.lang3.LocaleUtils;
/** /**
* FastDateParser is a fast and thread-safe version of * FastDateParser is a fast and thread-safe version of {@link java.text.SimpleDateFormat}.
* {@link java.text.SimpleDateFormat}.
* *
* <p>To obtain a proxy to a FastDateParser, use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} * <p>
* or another variation of the factory methods of {@link FastDateFormat}.</p> * To obtain a proxy to a FastDateParser, use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the factory methods of
* {@link FastDateFormat}.
* </p>
* *
* <p>Since FastDateParser is thread safe, you can use a static member instance:</p> * <p>
* Since FastDateParser is thread safe, you can use a static member instance:
* </p>
* <code> * <code>
* private static final DateParser DATE_PARSER = FastDateFormat.getInstance("yyyy-MM-dd"); * private static final DateParser DATE_PARSER = FastDateFormat.getInstance("yyyy-MM-dd");
* </code> * </code>
* *
* <p>This class can be used as a direct replacement for * <p>
* {@link SimpleDateFormat} in most parsing situations. * This class can be used as a direct replacement for {@link SimpleDateFormat} in most parsing situations. This class is especially useful in multi-threaded
* This class is especially useful in multi-threaded server environments. * server environments. {@link SimpleDateFormat} is not thread-safe in any JDK version, nor will it be as Sun has closed the
* {@link SimpleDateFormat} is not thread-safe in any JDK version,
* nor will it be as Sun has closed the
* <a href="https://bugs.openjdk.org/browse/JDK-4228335">bug</a>/RFE. * <a href="https://bugs.openjdk.org/browse/JDK-4228335">bug</a>/RFE.
* </p> * </p>
* *
* <p>Only parsing is supported by this class, but all patterns are compatible with * <p>
* SimpleDateFormat.</p> * Only parsing is supported by this class, but all patterns are compatible with SimpleDateFormat.
* </p>
* *
* <p>The class operates in lenient mode, so for example a time of 90 minutes is treated as 1 hour 30 minutes.</p> * <p>
* The class operates in lenient mode, so for example a time of 90 minutes is treated as 1 hour 30 minutes.
* </p>
* *
* <p>Timing tests indicate this class is as about as fast as SimpleDateFormat * <p>
* in single thread applications and about 25% faster in multi-thread applications.</p> * Timing tests indicate this class is as about as fast as SimpleDateFormat in single thread applications and about 25% faster in multi-thread applications.
* </p>
* *
* @since 3.2 * @since 3.2
* @see FastDatePrinter * @see FastDatePrinter
@ -108,21 +113,20 @@ public class FastDateParser implements DateParser, Serializable {
private transient List<StrategyAndWidth> patterns; private transient List<StrategyAndWidth> patterns;
/** /**
* comparator used to sort regex alternatives. Alternatives should be ordered longer first, and shorter last. * comparator used to sort regex alternatives. Alternatives should be ordered longer first, and shorter last. ('february' before 'feb'). All entries must be
* ('february' before 'feb'). All entries must be lower-case by locale. * lower-case by locale.
*/ */
private static final Comparator<String> LONGER_FIRST_LOWERCASE = Comparator.reverseOrder(); private static final Comparator<String> LONGER_FIRST_LOWERCASE = Comparator.reverseOrder();
/** /**
* Constructs a new FastDateParser. * Constructs a new FastDateParser.
* *
* Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the * Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the factory methods of {@link FastDateFormat} to get a cached
* factory methods of {@link FastDateFormat} to get a cached FastDateParser instance. * FastDateParser instance.
* *
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* pattern
* @param timeZone non-null time zone to use * @param timeZone non-null time zone to use
* @param locale non-null locale * @param locale non-null locale
*/ */
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale) { protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale) {
this(pattern, timeZone, locale, null); this(pattern, timeZone, locale, null);
@ -131,16 +135,14 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Constructs a new FastDateParser. * Constructs a new FastDateParser.
* *
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* pattern * @param timeZone non-null time zone to use
* @param timeZone non-null time zone to use * @param locale locale, null maps to the default Locale.
* @param locale locale, null maps to the default Locale.
* @param centuryStart The start of the century for 2 digit year parsing * @param centuryStart The start of the century for 2 digit year parsing
* *
* @since 3.5 * @since 3.5
*/ */
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) {
final Date centuryStart) {
this.pattern = Objects.requireNonNull(pattern, "pattern"); this.pattern = Objects.requireNonNull(pattern, "pattern");
this.timeZone = Objects.requireNonNull(timeZone, "timeZone"); this.timeZone = Objects.requireNonNull(timeZone, "timeZone");
this.locale = LocaleUtils.toLocale(locale); this.locale = LocaleUtils.toLocale(locale);
@ -165,17 +167,16 @@ public class FastDateParser implements DateParser, Serializable {
} }
/** /**
* Initializes derived fields from defining fields. * Initializes derived fields from defining fields. This is called from constructor and from readObject (de-serialization)
* This is called from constructor and from readObject (de-serialization)
* *
* @param definingCalendar the {@link java.util.Calendar} instance used to initialize this FastDateParser * @param definingCalendar the {@link java.util.Calendar} instance used to initialize this FastDateParser
*/ */
private void init(final Calendar definingCalendar) { private void init(final Calendar definingCalendar) {
patterns = new ArrayList<>(); patterns = new ArrayList<>();
final StrategyParser fm = new StrategyParser(definingCalendar); final StrategyParser strategyParser = new StrategyParser(definingCalendar);
for (;;) { for (;;) {
final StrategyAndWidth field = fm.getNextStrategy(); final StrategyAndWidth field = strategyParser.getNextStrategy();
if (field == null) { if (field == null) {
break; break;
} }
@ -279,7 +280,9 @@ public class FastDateParser implements DateParser, Serializable {
} }
// Accessors // Accessors
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#getPattern() * @see org.apache.commons.lang3.time.DateParser#getPattern()
*/ */
@Override @Override
@ -287,7 +290,9 @@ public class FastDateParser implements DateParser, Serializable {
return pattern; return pattern;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#getTimeZone() * @see org.apache.commons.lang3.time.DateParser#getTimeZone()
*/ */
@Override @Override
@ -295,7 +300,9 @@ public class FastDateParser implements DateParser, Serializable {
return timeZone; return timeZone;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#getLocale() * @see org.apache.commons.lang3.time.DateParser#getLocale()
*/ */
@Override @Override
@ -303,12 +310,11 @@ public class FastDateParser implements DateParser, Serializable {
return locale; return locale;
} }
// Basics // Basics
/** /**
* Compares another object for equality with this object. * Compares another object for equality with this object.
* *
* @param obj the object to compare to * @param obj the object to compare to
* @return {@code true}if equal to this instance * @return {@code true}if equal to this instance
*/ */
@Override @Override
@ -347,17 +353,16 @@ public class FastDateParser implements DateParser, Serializable {
* @since 3.12.0 * @since 3.12.0
*/ */
public String toStringAll() { public String toStringAll() {
return "FastDateParser [pattern=" + pattern + ", timeZone=" + timeZone + ", locale=" + locale + ", century=" return "FastDateParser [pattern=" + pattern + ", timeZone=" + timeZone + ", locale=" + locale + ", century=" + century + ", startYear=" + startYear
+ century + ", startYear=" + startYear + ", patterns=" + patterns + "]"; + ", patterns=" + patterns + "]";
} }
// Serializing // Serializing
/** /**
* Creates the object after serialization. This implementation reinitializes the * Creates the object after serialization. This implementation reinitializes the transient properties.
* transient properties.
* *
* @param in ObjectInputStream from which the object is being deserialized. * @param in ObjectInputStream from which the object is being deserialized.
* @throws IOException if there is an IO issue. * @throws IOException if there is an IO issue.
* @throws ClassNotFoundException if a class cannot be found. * @throws ClassNotFoundException if a class cannot be found.
*/ */
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
@ -367,7 +372,9 @@ public class FastDateParser implements DateParser, Serializable {
init(definingCalendar); init(definingCalendar);
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#parseObject(String) * @see org.apache.commons.lang3.time.DateParser#parseObject(String)
*/ */
@Override @Override
@ -375,7 +382,9 @@ public class FastDateParser implements DateParser, Serializable {
return parse(source); return parse(source);
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#parse(String) * @see org.apache.commons.lang3.time.DateParser#parse(String)
*/ */
@Override @Override
@ -385,15 +394,17 @@ public class FastDateParser implements DateParser, Serializable {
if (date == null) { if (date == null) {
// Add a note regarding supported date range // Add a note regarding supported date range
if (locale.equals(JAPANESE_IMPERIAL)) { if (locale.equals(JAPANESE_IMPERIAL)) {
throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" + "Unparseable date: \"" + source,
+ "Unparseable date: \"" + source, pp.getErrorIndex()); pp.getErrorIndex());
} }
throw new ParseException("Unparseable date: " + source, pp.getErrorIndex()); throw new ParseException("Unparseable date: " + source, pp.getErrorIndex());
} }
return date; return date;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.apache.commons.lang3.time.DateParser#parseObject(String, java.text.ParsePosition) * @see org.apache.commons.lang3.time.DateParser#parseObject(String, java.text.ParsePosition)
*/ */
@Override @Override
@ -402,14 +413,11 @@ public class FastDateParser implements DateParser, Serializable {
} }
/** /**
* This implementation updates the ParsePosition if the parse succeeds. * This implementation updates the ParsePosition if the parse succeeds. However, it sets the error index to the position before the failed field unlike the
* However, it sets the error index to the position before the failed field unlike * method {@link java.text.SimpleDateFormat#parse(String, ParsePosition)} which sets the error index to after the failed field.
* the method {@link java.text.SimpleDateFormat#parse(String, ParsePosition)} which sets
* the error index to after the failed field.
* <p> * <p>
* To determine if the parse has succeeded, the caller must check if the current parse position * To determine if the parse has succeeded, the caller must check if the current parse position given by {@link ParsePosition#getIndex()} has been updated.
* given by {@link ParsePosition#getIndex()} has been updated. If the input buffer has been fully * If the input buffer has been fully parsed, then the index will point to just after the end of the input buffer.
* parsed, then the index will point to just after the end of the input buffer.
* *
* @see org.apache.commons.lang3.time.DateParser#parse(String, java.text.ParsePosition) * @see org.apache.commons.lang3.time.DateParser#parse(String, java.text.ParsePosition)
*/ */
@ -423,17 +431,15 @@ public class FastDateParser implements DateParser, Serializable {
} }
/** /**
* Parses a formatted date string according to the format. Updates the Calendar with parsed fields. * Parses a formatted date string according to the format. Updates the Calendar with parsed fields. Upon success, the ParsePosition index is updated to
* Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed. * indicate how much of the source text was consumed. Not all source text needs to be consumed. Upon parse failure, ParsePosition error index is updated to
* Not all source text needs to be consumed. Upon parse failure, ParsePosition error index is updated to
* the offset of the source text which does not match the supplied format. * the offset of the source text which does not match the supplied format.
* *
* @param source The text to parse. * @param source The text to parse.
* @param pos On input, the position in the source to start parsing, on output, updated position. * @param pos On input, the position in the source to start parsing, on output, updated position.
* @param calendar The calendar into which to set parsed fields. * @param calendar The calendar into which to set parsed fields.
* @return true, if source has been parsed (pos parsePosition is updated); otherwise false (and pos errorIndex is updated) * @return true, if source has been parsed (pos parsePosition is updated); otherwise false (and pos errorIndex is updated)
* @throws IllegalArgumentException when Calendar has been set to be not lenient, and a parsed field is * @throws IllegalArgumentException when Calendar has been set to be not lenient, and a parsed field is out of range.
* out of range.
*/ */
@Override @Override
public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) { public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) {
@ -480,14 +486,14 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Gets the short and long values displayed for a field * Gets the short and long values displayed for a field
*
* @param calendar The calendar to obtain the short and long values * @param calendar The calendar to obtain the short and long values
* @param locale The locale of display names * @param locale The locale of display names
* @param field The field of interest * @param field The field of interest
* @param regex The regular expression to build * @param regex The regular expression to build
* @return The map of string display names to field values * @return The map of string display names to field values
*/ */
private static Map<String, Integer> appendDisplayNames(final Calendar calendar, final Locale locale, final int field, private static Map<String, Integer> appendDisplayNames(final Calendar calendar, final Locale locale, final int field, final StringBuilder regex) {
final StringBuilder regex) {
Objects.requireNonNull(calendar, "calendar"); Objects.requireNonNull(calendar, "calendar");
final Map<String, Integer> values = new HashMap<>(); final Map<String, Integer> values = new HashMap<>();
final Locale actualLocale = LocaleUtils.toLocale(locale); final Locale actualLocale = LocaleUtils.toLocale(locale);
@ -505,6 +511,7 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Adjusts dates to be within appropriate century * Adjusts dates to be within appropriate century
*
* @param twoDigitYear The year to adjust * @param twoDigitYear The year to adjust
* @return A value between centuryStart(inclusive) to centuryStart+100(exclusive) * @return A value between centuryStart(inclusive) to centuryStart+100(exclusive)
*/ */
@ -527,8 +534,7 @@ public class FastDateParser implements DateParser, Serializable {
return false; return false;
} }
abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos, abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos, int maxWidth);
int maxWidth);
} }
/** /**
@ -557,8 +563,7 @@ public class FastDateParser implements DateParser, Serializable {
} }
@Override @Override
boolean parse(final FastDateParser parser, final Calendar calendar, final String source, boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
final ParsePosition pos, final int maxWidth) {
final Matcher matcher = pattern.matcher(source.substring(pos.getIndex())); final Matcher matcher = pattern.matcher(source.substring(pos.getIndex()));
if (!matcher.lookingAt()) { if (!matcher.lookingAt()) {
pos.setErrorIndex(pos.getIndex()); pos.setErrorIndex(pos.getIndex());
@ -581,12 +586,13 @@ public class FastDateParser implements DateParser, Serializable {
return getClass().getSimpleName() + " [pattern=" + pattern + "]"; return getClass().getSimpleName() + " [pattern=" + pattern + "]";
} }
} }
/** /**
* Gets a Strategy given a field from a SimpleDateFormat pattern * Gets a Strategy given a field from a SimpleDateFormat pattern
* @param f A sub-sequence of the SimpleDateFormat pattern *
* @param width formatting width * @param f A sub-sequence of the SimpleDateFormat pattern
* @param width formatting width
* @param definingCalendar The calendar to obtain the short and long values * @param definingCalendar The calendar to obtain the short and long values
* @return The Strategy that will handle parsing for the field * @return The Strategy that will handle parsing for the field
*/ */
@ -649,6 +655,7 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Gets a cache of Strategies for a particular field * Gets a cache of Strategies for a particular field
*
* @param field The Calendar field * @param field The Calendar field
* @return a cache of Locale to Strategy * @return a cache of Locale to Strategy
*/ */
@ -663,13 +670,15 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Constructs a Strategy that parses a Text field * Constructs a Strategy that parses a Text field
* @param field The Calendar field *
* @param field The Calendar field
* @param definingCalendar The calendar to obtain the short and long values * @param definingCalendar The calendar to obtain the short and long values
* @return a TextStrategy for the field and Locale * @return a TextStrategy for the field and Locale
*/ */
private Strategy getLocaleSpecificStrategy(final int field, final Calendar definingCalendar) { private Strategy getLocaleSpecificStrategy(final int field, final Calendar definingCalendar) {
final ConcurrentMap<Locale, Strategy> cache = getCache(field); final ConcurrentMap<Locale, Strategy> cache = getCache(field);
return cache.computeIfAbsent(locale, k -> field == Calendar.ZONE_OFFSET ? new TimeZoneStrategy(locale) : new CaseInsensitiveTextStrategy(field, definingCalendar, locale)); return cache.computeIfAbsent(locale,
k -> field == Calendar.ZONE_OFFSET ? new TimeZoneStrategy(locale) : new CaseInsensitiveTextStrategy(field, definingCalendar, locale));
} }
/** /**
@ -697,8 +706,7 @@ public class FastDateParser implements DateParser, Serializable {
} }
@Override @Override
boolean parse(final FastDateParser parser, final Calendar calendar, final String source, boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
final ParsePosition pos, final int maxWidth) {
for (int idx = 0; idx < formatField.length(); ++idx) { for (int idx = 0; idx < formatField.length(); ++idx) {
final int sIdx = idx + pos.getIndex(); final int sIdx = idx + pos.getIndex();
if (sIdx == source.length()) { if (sIdx == source.length()) {
@ -736,9 +744,9 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Constructs a Strategy that parses a Text field * Constructs a Strategy that parses a Text field
* *
* @param field The Calendar field * @param field The Calendar field
* @param definingCalendar The Calendar to use * @param definingCalendar The Calendar to use
* @param locale The Locale to use * @param locale The Locale to use
*/ */
CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) { CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) {
this.field = field; this.field = field;
@ -763,7 +771,7 @@ public class FastDateParser implements DateParser, Serializable {
// match missing the optional trailing period // match missing the optional trailing period
iVal = lKeyValues.get(lowerCase + '.'); iVal = lKeyValues.get(lowerCase + '.');
} }
//LANG-1669: Mimic fix done in OpenJDK 17 to resolve issue with parsing newly supported day periods added in OpenJDK 16 // LANG-1669: Mimic fix done in OpenJDK 17 to resolve issue with parsing newly supported day periods added in OpenJDK 16
if (Calendar.AM_PM != this.field || iVal <= 1) { if (Calendar.AM_PM != this.field || iVal <= 1) {
calendar.set(field, iVal.intValue()); calendar.set(field, iVal.intValue());
} }
@ -776,12 +784,10 @@ public class FastDateParser implements DateParser, Serializable {
*/ */
@Override @Override
public String toString() { public String toString() {
return "CaseInsensitiveTextStrategy [field=" + field + ", locale=" + locale + ", lKeyValues=" + lKeyValues return "CaseInsensitiveTextStrategy [field=" + field + ", locale=" + locale + ", lKeyValues=" + lKeyValues + ", pattern=" + pattern + "]";
+ ", pattern=" + pattern + "]";
} }
} }
/** /**
* A strategy that handles a number field in the parsing pattern * A strategy that handles a number field in the parsing pattern
*/ */
@ -807,8 +813,7 @@ public class FastDateParser implements DateParser, Serializable {
} }
@Override @Override
boolean parse(final FastDateParser parser, final Calendar calendar, final String source, boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) {
final ParsePosition pos, final int maxWidth) {
int idx = pos.getIndex(); int idx = pos.getIndex();
int last = source.length(); int last = source.length();
@ -1000,6 +1005,7 @@ public class FastDateParser implements DateParser, Serializable {
/** /**
* Constructs a Strategy that parses a TimeZone * Constructs a Strategy that parses a TimeZone
*
* @param pattern The Pattern * @param pattern The Pattern
*/ */
ISO8601TimeZoneStrategy(final String pattern) { ISO8601TimeZoneStrategy(final String pattern) {
@ -1022,11 +1028,11 @@ public class FastDateParser implements DateParser, Serializable {
* Factory method for ISO8601TimeZoneStrategies. * Factory method for ISO8601TimeZoneStrategies.
* *
* @param tokenLen a token indicating the length of the TimeZone String to be formatted. * @param tokenLen a token indicating the length of the TimeZone String to be formatted.
* @return a ISO8601TimeZoneStrategy that can format TimeZone String of length {@code tokenLen}. If no such * @return a ISO8601TimeZoneStrategy that can format TimeZone String of length {@code tokenLen}. If no such strategy exists, an IllegalArgumentException
* strategy exists, an IllegalArgumentException will be thrown. * will be thrown.
*/ */
static Strategy getStrategy(final int tokenLen) { static Strategy getStrategy(final int tokenLen) {
switch(tokenLen) { switch (tokenLen) {
case 1: case 1:
return ISO_8601_1_STRATEGY; return ISO_8601_1_STRATEGY;
case 2: case 2:
@ -1042,7 +1048,7 @@ public class FastDateParser implements DateParser, Serializable {
private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH) { private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH) {
@Override @Override
int modify(final FastDateParser parser, final int iValue) { int modify(final FastDateParser parser, final int iValue) {
return iValue-1; return iValue - 1;
} }
}; };