Checkstyle
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/72043711 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/72043711 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/72043711 Branch: refs/heads/LOG4J2-1136 Commit: 720437116b3c29dbff9af4087490f06f729dfb58 Parents: decf01d Author: rpopma <[email protected]> Authored: Thu Sep 24 17:40:48 2015 +0200 Committer: Ralph Goers <[email protected]> Committed: Sun Sep 27 10:49:28 2015 -0700 ---------------------------------------------------------------------- .../log4j/core/util/NanoClockFactory.java | 6 +- .../log4j/core/util/datetime/DateParser.java | 34 +- .../log4j/core/util/datetime/DatePrinter.java | 2 +- .../core/util/datetime/FastDateFormat.java | 471 +++++++++--------- .../core/util/datetime/FastDateParser.java | 488 ++++++++++--------- .../core/util/datetime/FastDatePrinter.java | 346 +++++++------ .../core/util/datetime/FixedDateFormat.java | 35 +- .../log4j/core/util/datetime/FormatCache.java | 163 ++++--- .../log4j/core/util/datetime/package-info.java | 20 + 9 files changed, 854 insertions(+), 711 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/72043711/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NanoClockFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NanoClockFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NanoClockFactory.java index 3ec37c2..2a714ee 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NanoClockFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NanoClockFactory.java @@ -23,9 +23,6 @@ import java.util.Objects; * Creates the appropriate {@link NanoClock} instance for the current configuration. */ public final class NanoClockFactory { - - private NanoClockFactory() { - } /** * Enum over the different kinds of nano clocks this factory can create. @@ -55,6 +52,9 @@ public final class NanoClockFactory { private static volatile Mode mode = Mode.Dummy; + private NanoClockFactory() { + } + /** * Returns a new {@code NanoClock} determined by the mode of this factory. * http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/72043711/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DateParser.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DateParser.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DateParser.java index 666ef81..7c45bb7 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DateParser.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DateParser.java @@ -23,50 +23,48 @@ import java.util.Locale; import java.util.TimeZone; /** - * Copied from Commons Lang 3 + * Copied from Commons Lang 3. */ public interface DateParser { /** - * Equivalent to DateFormat.parse(String). + * Equivalent to DateFormat.parse(String). * - * See {@link java.text.DateFormat#parse(String)} for more information. - * @param source A <code>String</code> whose beginning should be parsed. + * See {@link java.text.DateFormat#parse(String)} for more information. + * + * @param source A <code>String</code> whose beginning should be parsed. * @return A <code>Date</code> parsed from the string * @throws ParseException if the beginning of the specified string cannot be parsed. */ Date parse(String source) throws ParseException; /** - * Equivalent to DateFormat.parse(String, ParsePosition). + * Equivalent to DateFormat.parse(String, ParsePosition). * - * See {@link java.text.DateFormat#parse(String, ParsePosition)} for more information. + * See {@link java.text.DateFormat#parse(String, ParsePosition)} for more information. * * @param source A <code>String</code>, part of which should be parsed. - * @param pos A <code>ParsePosition</code> object with index and error index information - * as described above. - * @return A <code>Date</code> parsed from the string. In case of error, returns null. + * @param pos A <code>ParsePosition</code> object with index and error index information as described above. + * @return A <code>Date</code> parsed from the string. In case of error, returns null. * @throws NullPointerException if text or pos is null. */ Date parse(String source, ParsePosition pos); // Accessors - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Get the pattern used by this parser.</p> + * Get the pattern used by this parser. * * @return the pattern, {@link java.text.SimpleDateFormat} compatible */ String getPattern(); /** - * <p> * Get the time zone used by this parser. - * </p> * * <p> - * The default {@link TimeZone} used to create a {@link Date} when the {@link TimeZone} is not specified by - * the format pattern. + * The default {@link TimeZone} used to create a {@link Date} when the {@link TimeZone} is not specified by the + * format pattern. * </p> * * @return the time zone @@ -74,7 +72,7 @@ public interface DateParser { TimeZone getTimeZone(); /** - * <p>Get the locale used by this parser.</p> + * Get the locale used by this parser. * * @return the locale */ @@ -86,7 +84,7 @@ public interface DateParser { * @param source A <code>String</code> whose beginning should be parsed. * @return a <code>java.util.Date</code> object * @throws ParseException if the beginning of the specified string cannot be parsed. - * @see java.text.DateFormat#parseObject(String) + * @see java.text.DateFormat#parseObject(String) */ Object parseObject(String source) throws ParseException; @@ -96,7 +94,7 @@ public interface DateParser { * @param source A <code>String</code> whose beginning should be parsed. * @param pos the parse position * @return a <code>java.util.Date</code> object - * @see java.text.DateFormat#parseObject(String, ParsePosition) + * @see java.text.DateFormat#parseObject(String, ParsePosition) */ Object parseObject(String source, ParsePosition pos); } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/72043711/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DatePrinter.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DatePrinter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DatePrinter.java index 34919f3..5de0405 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DatePrinter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/DatePrinter.java @@ -23,7 +23,7 @@ import java.util.Locale; import java.util.TimeZone; /** - * Copied from Commons Lang 3 + * Copied from Commons Lang 3. */ public interface DatePrinter { http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/72043711/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateFormat.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateFormat.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateFormat.java index 79a07d0..85df633 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateFormat.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateFormat.java @@ -30,12 +30,6 @@ import java.util.TimeZone; * This is a copy of Commons Lang's Fast Date Formatter. */ public class FastDateFormat extends Format implements DatePrinter, DateParser, Serializable { - /** - * Required for serialization support. - * - * @see java.io.Serializable - */ - private static final long serialVersionUID = 2L; /** * FULL locale dependent date or time style. @@ -54,7 +48,14 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S */ public static final int SHORT = DateFormat.SHORT; - private static final FormatCache<FastDateFormat> cache= new FormatCache<FastDateFormat>() { + /** + * Required for serialization support. + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = 2L; + + private static final FormatCache<FastDateFormat> CACHE = new FormatCache<FastDateFormat>() { @Override protected FastDateFormat createInstance(final String pattern, final TimeZone timeZone, final Locale locale) { return new FastDateFormat(pattern, timeZone, locale); @@ -64,305 +65,306 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S private final FastDatePrinter printer; private final FastDateParser parser; - //----------------------------------------------------------------------- + // Constructor + // ----------------------------------------------------------------------- /** - * <p>Gets a formatter instance using the default pattern in the - * default locale.</p> + * <p> + * Constructs a new FastDateFormat. + * </p> + * + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone non-null time zone to use + * @param locale non-null locale to use + * @throws NullPointerException if pattern, timeZone, or locale is null. + */ + protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale) { + this(pattern, timeZone, locale, null); + } + + // Constructor + // ----------------------------------------------------------------------- + /** + * <p> + * Constructs a new FastDateFormat. + * </p> + * + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone non-null time zone to use + * @param locale non-null locale to use + * @param centuryStart The start of the 100 year period to use as the "default century" for 2 digit year parsing. + * If centuryStart is null, defaults to now - 80 years + * @throws NullPointerException if pattern, timeZone, or locale is null. + */ + protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale, + final Date centuryStart) { + printer = new FastDatePrinter(pattern, timeZone, locale); + parser = new FastDateParser(pattern, timeZone, locale, centuryStart); + } + + // ----------------------------------------------------------------------- + /** + * <p> + * Gets a formatter instance using the default pattern in the default locale. + * </p> * * @return a date/time formatter */ public static FastDateFormat getInstance() { - return cache.getInstance(); + return CACHE.getInstance(); } /** - * <p>Gets a formatter instance using the specified pattern in the - * default locale.</p> + * <p> + * Gets a formatter instance using the specified pattern in the default locale. + * </p> * - * @param pattern {@link java.text.SimpleDateFormat} compatible - * pattern + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern * @return a pattern based date/time formatter * @throws IllegalArgumentException if pattern is invalid */ public static FastDateFormat getInstance(final String pattern) { - return cache.getInstance(pattern, null, null); + return CACHE.getInstance(pattern, null, null); } /** - * <p>Gets a formatter instance using the specified pattern and - * time zone.</p> + * <p> + * Gets a formatter instance using the specified pattern and time zone. + * </p> * - * @param pattern {@link java.text.SimpleDateFormat} compatible - * pattern - * @param timeZone optional time zone, overrides time zone of - * formatted date + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone optional time zone, overrides time zone of formatted date * @return a pattern based date/time formatter * @throws IllegalArgumentException if pattern is invalid */ public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone) { - return cache.getInstance(pattern, timeZone, null); + return CACHE.getInstance(pattern, timeZone, null); } /** - * <p>Gets a formatter instance using the specified pattern and - * locale.</p> + * <p> + * Gets a formatter instance using the specified pattern and locale. + * </p> * - * @param pattern {@link java.text.SimpleDateFormat} compatible - * pattern - * @param locale optional locale, overrides system locale + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern + * @param locale optional locale, overrides system locale * @return a pattern based date/time formatter * @throws IllegalArgumentException if pattern is invalid */ public static FastDateFormat getInstance(final String pattern, final Locale locale) { - return cache.getInstance(pattern, null, locale); + return CACHE.getInstance(pattern, null, locale); } /** - * <p>Gets a formatter instance using the specified pattern, time zone - * and locale.</p> + * <p> + * Gets a formatter instance using the specified pattern, time zone and locale. + * </p> * - * @param pattern {@link java.text.SimpleDateFormat} compatible - * pattern - * @param timeZone optional time zone, overrides time zone of - * formatted date - * @param locale optional locale, overrides system locale + * @param pattern {@link java.text.SimpleDateFormat} compatible pattern + * @param timeZone optional time zone, overrides time zone of formatted date + * @param locale optional locale, overrides system locale * @return a pattern based date/time formatter - * @throws IllegalArgumentException if pattern is invalid - * or {@code null} + * @throws IllegalArgumentException if pattern is invalid or {@code null} */ public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone, final Locale locale) { - return cache.getInstance(pattern, timeZone, locale); + return CACHE.getInstance(pattern, timeZone, locale); } - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Gets a date formatter instance using the specified style in the - * default time zone and locale.</p> + * <p> + * Gets a date formatter instance using the specified style in the default time zone and locale. + * </p> * - * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param style date style: FULL, LONG, MEDIUM, or SHORT * @return a localized standard date formatter - * @throws IllegalArgumentException if the Locale has no date - * pattern defined + * @throws IllegalArgumentException if the Locale has no date pattern defined * @since 2.1 */ public static FastDateFormat getDateInstance(final int style) { - return cache.getDateInstance(style, null, null); + return CACHE.getDateInstance(style, null, null); } /** - * <p>Gets a date formatter instance using the specified style and - * locale in the default time zone.</p> + * <p> + * Gets a date formatter instance using the specified style and locale in the default time zone. + * </p> * - * @param style date style: FULL, LONG, MEDIUM, or SHORT - * @param locale optional locale, overrides system locale + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param locale optional locale, overrides system locale * @return a localized standard date formatter - * @throws IllegalArgumentException if the Locale has no date - * pattern defined + * @throws IllegalArgumentException if the Locale has no date pattern defined * @since 2.1 */ public static FastDateFormat getDateInstance(final int style, final Locale locale) { - return cache.getDateInstance(style, null, locale); + return CACHE.getDateInstance(style, null, locale); } /** - * <p>Gets a date formatter instance using the specified style and - * time zone in the default locale.</p> + * <p> + * Gets a date formatter instance using the specified style and time zone in the default locale. + * </p> * - * @param style date style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted date + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date * @return a localized standard date formatter - * @throws IllegalArgumentException if the Locale has no date - * pattern defined + * @throws IllegalArgumentException if the Locale has no date pattern defined * @since 2.1 */ public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone) { - return cache.getDateInstance(style, timeZone, null); + return CACHE.getDateInstance(style, timeZone, null); } /** - * <p>Gets a date formatter instance using the specified style, time - * zone and locale.</p> + * <p> + * Gets a date formatter instance using the specified style, time zone and locale. + * </p> * - * @param style date style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted date - * @param locale optional locale, overrides system locale + * @param style date style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date + * @param locale optional locale, overrides system locale * @return a localized standard date formatter - * @throws IllegalArgumentException if the Locale has no date - * pattern defined + * @throws IllegalArgumentException if the Locale has no date pattern defined */ public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone, final Locale locale) { - return cache.getDateInstance(style, timeZone, locale); + return CACHE.getDateInstance(style, timeZone, locale); } - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Gets a time formatter instance using the specified style in the - * default time zone and locale.</p> + * <p> + * Gets a time formatter instance using the specified style in the default time zone and locale. + * </p> * - * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param style time style: FULL, LONG, MEDIUM, or SHORT * @return a localized standard time formatter - * @throws IllegalArgumentException if the Locale has no time - * pattern defined + * @throws IllegalArgumentException if the Locale has no time pattern defined * @since 2.1 */ public static FastDateFormat getTimeInstance(final int style) { - return cache.getTimeInstance(style, null, null); + return CACHE.getTimeInstance(style, null, null); } /** - * <p>Gets a time formatter instance using the specified style and - * locale in the default time zone.</p> + * <p> + * Gets a time formatter instance using the specified style and locale in the default time zone. + * </p> * - * @param style time style: FULL, LONG, MEDIUM, or SHORT - * @param locale optional locale, overrides system locale + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param locale optional locale, overrides system locale * @return a localized standard time formatter - * @throws IllegalArgumentException if the Locale has no time - * pattern defined + * @throws IllegalArgumentException if the Locale has no time pattern defined * @since 2.1 */ public static FastDateFormat getTimeInstance(final int style, final Locale locale) { - return cache.getTimeInstance(style, null, locale); + return CACHE.getTimeInstance(style, null, locale); } /** - * <p>Gets a time formatter instance using the specified style and - * time zone in the default locale.</p> + * <p> + * Gets a time formatter instance using the specified style and time zone in the default locale. + * </p> * - * @param style time style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted time + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted time * @return a localized standard time formatter - * @throws IllegalArgumentException if the Locale has no time - * pattern defined + * @throws IllegalArgumentException if the Locale has no time pattern defined * @since 2.1 */ public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone) { - return cache.getTimeInstance(style, timeZone, null); + return CACHE.getTimeInstance(style, timeZone, null); } /** - * <p>Gets a time formatter instance using the specified style, time - * zone and locale.</p> + * <p> + * Gets a time formatter instance using the specified style, time zone and locale. + * </p> * - * @param style time style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted time - * @param locale optional locale, overrides system locale + * @param style time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted time + * @param locale optional locale, overrides system locale * @return a localized standard time formatter - * @throws IllegalArgumentException if the Locale has no time - * pattern defined + * @throws IllegalArgumentException if the Locale has no time pattern defined */ public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone, final Locale locale) { - return cache.getTimeInstance(style, timeZone, locale); + return CACHE.getTimeInstance(style, timeZone, locale); } - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Gets a date/time formatter instance using the specified style - * in the default time zone and locale.</p> + * <p> + * Gets a date/time formatter instance using the specified style in the default time zone and locale. + * </p> * - * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT - * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT * @return a localized standard date/time formatter - * @throws IllegalArgumentException if the Locale has no date/time - * pattern defined + * @throws IllegalArgumentException if the Locale has no date/time pattern defined * @since 2.1 */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle) { - return cache.getDateTimeInstance(dateStyle, timeStyle, null, null); + return CACHE.getDateTimeInstance(dateStyle, timeStyle, null, null); } /** - * <p>Gets a date/time formatter instance using the specified style and - * locale in the default time zone.</p> + * <p> + * Gets a date/time formatter instance using the specified style and locale in the default time zone. + * </p> * - * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT - * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT - * @param locale optional locale, overrides system locale + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param locale optional locale, overrides system locale * @return a localized standard date/time formatter - * @throws IllegalArgumentException if the Locale has no date/time - * pattern defined + * @throws IllegalArgumentException if the Locale has no date/time pattern defined * @since 2.1 */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final Locale locale) { - return cache.getDateTimeInstance(dateStyle, timeStyle, null, locale); + return CACHE.getDateTimeInstance(dateStyle, timeStyle, null, locale); } /** - * <p>Gets a date/time formatter instance using the specified style and - * time zone in the default locale.</p> + * <p> + * Gets a date/time formatter instance using the specified style and time zone in the default locale. + * </p> * - * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT - * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted date + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date * @return a localized standard date/time formatter - * @throws IllegalArgumentException if the Locale has no date/time - * pattern defined + * @throws IllegalArgumentException if the Locale has no date/time pattern defined * @since 2.1 */ - public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone) { + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, + final TimeZone timeZone) { return getDateTimeInstance(dateStyle, timeStyle, timeZone, null); } - /** - * <p>Gets a date/time formatter instance using the specified style, - * time zone and locale.</p> - * - * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT - * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT - * @param timeZone optional time zone, overrides time zone of - * formatted date - * @param locale optional locale, overrides system locale - * @return a localized standard date/time formatter - * @throws IllegalArgumentException if the Locale has no date/time - * pattern defined - */ - public static FastDateFormat getDateTimeInstance( - final int dateStyle, final int timeStyle, final TimeZone timeZone, final Locale locale) { - return cache.getDateTimeInstance(dateStyle, timeStyle, timeZone, locale); - } - // Constructor - //----------------------------------------------------------------------- /** - * <p>Constructs a new FastDateFormat.</p> + * <p> + * Gets a date/time formatter instance using the specified style, time zone and locale. + * </p> * - * @param pattern {@link java.text.SimpleDateFormat} compatible pattern - * @param timeZone non-null time zone to use - * @param locale non-null locale to use - * @throws NullPointerException if pattern, timeZone, or locale is null. - */ - protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale) { - this(pattern, timeZone, locale, null); - } - - // Constructor - //----------------------------------------------------------------------- - /** - * <p>Constructs a new FastDateFormat.</p> - * - * @param pattern {@link java.text.SimpleDateFormat} compatible pattern - * @param timeZone non-null time zone to use - * @param locale non-null locale to use - * @param centuryStart The start of the 100 year period to use as the "default century" for 2 digit year parsing. If centuryStart is null, defaults to now - 80 years - * @throws NullPointerException if pattern, timeZone, or locale is null. + * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT + * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT + * @param timeZone optional time zone, overrides time zone of formatted date + * @param locale optional locale, overrides system locale + * @return a localized standard date/time formatter + * @throws IllegalArgumentException if the Locale has no date/time pattern defined */ - protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) { - printer= new FastDatePrinter(pattern, timeZone, locale); - parser= new FastDateParser(pattern, timeZone, locale, centuryStart); + public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, + final TimeZone timeZone, final Locale locale) { + return CACHE.getDateTimeInstance(dateStyle, timeStyle, timeZone, locale); } // Format methods - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Formats a {@code Date}, {@code Calendar} or - * {@code Long} (milliseconds) object.</p> + * <p> + * Formats a {@code Date}, {@code Calendar} or {@code Long} (milliseconds) object. + * </p> * - * @param obj the object to format - * @param toAppendTo the buffer to append to - * @param pos the position - ignored + * @param obj the object to format + * @param toAppendTo the buffer to append to + * @param pos the position - ignored * @return the buffer passed in */ @Override @@ -371,9 +373,11 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a millisecond {@code long} value.</p> + * <p> + * Formats a millisecond {@code long} value. + * </p> * - * @param millis the millisecond value to format + * @param millis the millisecond value to format * @return the formatted string * @since 2.1 */ @@ -383,9 +387,11 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a {@code Date} object using a {@code GregorianCalendar}.</p> + * <p> + * Formats a {@code Date} object using a {@code GregorianCalendar}. + * </p> * - * @param date the date to format + * @param date the date to format * @return the formatted string */ @Override @@ -394,9 +400,11 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a {@code Calendar} object.</p> + * <p> + * Formats a {@code Calendar} object. + * </p> * - * @param calendar the calendar to format + * @param calendar the calendar to format * @return the formatted string */ @Override @@ -405,11 +413,12 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a millisecond {@code long} value into the - * supplied {@code StringBuilder}.</p> + * <p> + * Formats a millisecond {@code long} value into the supplied {@code StringBuilder}. + * </p> * - * @param millis the millisecond value to format - * @param buf the buffer to format into + * @param millis the millisecond value to format + * @param buf the buffer to format into * @return the specified string buffer * @since 2.1 */ @@ -419,11 +428,12 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a {@code Date} object into the - * supplied {@code StringBuilder} using a {@code GregorianCalendar}.</p> + * <p> + * Formats a {@code Date} object into the supplied {@code StringBuilder} using a {@code GregorianCalendar}. + * </p> * - * @param date the date to format - * @param buf the buffer to format into + * @param date the date to format + * @param buf the buffer to format into * @return the specified string buffer */ @Override @@ -432,11 +442,12 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Formats a {@code Calendar} object into the - * supplied {@code StringBuilder}.</p> + * <p> + * Formats a {@code Calendar} object into the supplied {@code StringBuilder}. + * </p> * - * @param calendar the calendar to format - * @param buf the buffer to format into + * @param calendar the calendar to format + * @param buf the buffer to format into * @return the specified string buffer */ @Override @@ -445,10 +456,11 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } // Parsing - //----------------------------------------------------------------------- - + // ----------------------------------------------------------------------- - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see DateParser#parse(java.lang.String) */ @Override @@ -456,7 +468,9 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S return parser.parse(source); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see DateParser#parse(java.lang.String, java.text.ParsePosition) */ @Override @@ -464,7 +478,9 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S return parser.parse(source, pos); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) */ @Override @@ -473,9 +489,11 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } // Accessors - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Gets the pattern used by this formatter.</p> + * <p> + * Gets the pattern used by this formatter. + * </p> * * @return the pattern, {@link java.text.SimpleDateFormat} compatible */ @@ -485,9 +503,13 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Gets the time zone used by this formatter.</p> + * <p> + * Gets the time zone used by this formatter. + * </p> * - * <p>This zone is always used for {@code Date} formatting. </p> + * <p> + * This zone is always used for {@code Date} formatting. + * </p> * * @return the time zone */ @@ -497,7 +519,9 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Gets the locale used by this formatter.</p> + * <p> + * Gets the locale used by this formatter. + * </p> * * @return the locale */ @@ -507,11 +531,13 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Gets an estimate for the maximum string length that the - * formatter will produce.</p> + * <p> + * Gets an estimate for the maximum string length that the formatter will produce. + * </p> * - * <p>The actual formatted length will almost always be less than or - * equal to this amount.</p> + * <p> + * The actual formatted length will almost always be less than or equal to this amount. + * </p> * * @return the maximum formatted length */ @@ -524,16 +550,18 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } // Basics - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Compares two objects for equality.</p> + * <p> + * Compares two objects for equality. + * </p> * - * @param obj the object to compare to + * @param obj the object to compare to * @return {@code true} if equal */ @Override public boolean equals(final Object obj) { - if (obj instanceof FastDateFormat == false) { + if (!(obj instanceof FastDateFormat)) { return false; } final FastDateFormat other = (FastDateFormat) obj; @@ -542,7 +570,9 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Returns a hashcode compatible with equals.</p> + * <p> + * Returns a hashcode compatible with equals. + * </p> * * @return a hashcode compatible with equals */ @@ -552,28 +582,29 @@ public class FastDateFormat extends Format implements DatePrinter, DateParser, S } /** - * <p>Gets a debugging string version of this formatter.</p> + * <p> + * Gets a debugging string version of this formatter. + * </p> * * @return a debugging string */ @Override public String toString() { - return "FastDateFormat[" + printer.getPattern() + "," + printer.getLocale() + "," + printer.getTimeZone().getID() + "]"; + return "FastDateFormat[" + printer.getPattern() + "," + printer.getLocale() + "," + + printer.getTimeZone().getID() + "]"; } - /** - * <p>Performs the formatting by applying the rules to the - * specified calendar.</p> + * <p> + * Performs the formatting by applying the rules to the specified calendar. + * </p> * - * @param calendar the calendar to format - * @param buf the buffer to format into + * @param calendar the calendar to format + * @param buf the buffer to format into * @return the specified string buffer */ protected StringBuilder applyRules(final Calendar calendar, final StringBuilder buf) { return printer.applyRules(calendar, buf); } - } - http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/72043711/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateParser.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateParser.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateParser.java index f259e4a..37e049b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateParser.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDateParser.java @@ -36,9 +36,15 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Copied from Commons Lang 3 + * Copied from Commons Lang 3. */ public class FastDateParser implements DateParser, Serializable { + + /** + * Japanese locale support. + */ + static final Locale JAPANESE_IMPERIAL = new Locale("ja", "JP", "JP"); + /** * Required for serialization support. * @@ -46,7 +52,51 @@ public class FastDateParser implements DateParser, Serializable { */ private static final long serialVersionUID = 3L; - static final Locale JAPANESE_IMPERIAL = new Locale("ja","JP","JP"); + private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH) { + @Override + int modify(final int iValue) { + return iValue - 1; + } + }; + + private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR) { + /** + * {@inheritDoc} + */ + @Override + void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { + int iValue = Integer.parseInt(value); + if (iValue < 100) { + iValue = parser.adjustYear(iValue); + } + cal.set(Calendar.YEAR, iValue); + } + }; + + private static final Strategy LITERAL_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR); + private static final Strategy WEEK_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_YEAR); + private static final Strategy WEEK_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_MONTH); + private static final Strategy DAY_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.DAY_OF_YEAR); + private static final Strategy DAY_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_MONTH); + private static final Strategy DAY_OF_WEEK_IN_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK_IN_MONTH); + private static final Strategy HOUR_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY); + private static final Strategy HOUR24_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY) { + @Override + int modify(final int iValue) { + return iValue == 24 ? 0 : iValue; + } + }; + private static final Strategy HOUR12_STRATEGY = new NumberStrategy(Calendar.HOUR) { + @Override + int modify(final int iValue) { + return iValue == 12 ? 0 : iValue; + } + }; + private static final Strategy HOUR_STRATEGY = new NumberStrategy(Calendar.HOUR); + private static final Strategy MINUTE_STRATEGY = new NumberStrategy(Calendar.MINUTE); + private static final Strategy SECOND_STRATEGY = new NumberStrategy(Calendar.SECOND); + private static final Strategy MILLISECOND_STRATEGY = new NumberStrategy(Calendar.MILLISECOND); + private static final Strategy ISO_8601_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}(?::?\\d{2})?))"); // defining fields private final String pattern; @@ -65,13 +115,14 @@ public class FastDateParser implements DateParser, Serializable { private transient Strategy nextStrategy; /** - * <p>Constructs a new FastDateParser.</p> + * <p> + * Constructs a new FastDateParser. + * </p> * - * Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the - * factory methods of {@link FastDateFormat} to get a cached FastDateParser instance. + * Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the factory methods of + * {@link FastDateFormat} to get a cached FastDateParser instance. * - * @param pattern non-null {@link java.text.SimpleDateFormat} compatible - * pattern + * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern * @param timeZone non-null time zone to use * @param locale non-null locale */ @@ -80,10 +131,11 @@ public class FastDateParser implements DateParser, Serializable { } /** - * <p>Constructs a new FastDateParser.</p> + * <p> + * Constructs a new FastDateParser. + * </p> * - * @param pattern non-null {@link java.text.SimpleDateFormat} compatible - * pattern + * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern * @param timeZone non-null time zone to use * @param locale non-null locale * @param centuryStart The start of the century for 2 digit year parsing @@ -95,15 +147,16 @@ public class FastDateParser implements DateParser, Serializable { } /** - * <p>Constructs a new FastDateParser.</p> + * <p> + * Constructs a new FastDateParser. + * </p> * - * @param pattern non-null {@link java.text.SimpleDateFormat} compatible - * pattern + * @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern * @param timeZone non-null time zone to use * @param locale non-null locale * @param centuryStart The start of the century for 2 digit year parsing - * @param lenient if true, non-standard values for Calendar fields should be accepted; - * if false, non-standard values will cause a ParseException to be thrown {@link Calendar#setLenient(boolean)} + * @param lenient if true, non-standard values for Calendar fields should be accepted; if false, non-standard values + * will cause a ParseException to be thrown {@link Calendar#setLenient(boolean)} * * @since 3.5 */ @@ -117,71 +170,72 @@ public class FastDateParser implements DateParser, Serializable { final Calendar definingCalendar = Calendar.getInstance(timeZone, locale); int centuryStartYear; - if(centuryStart!=null) { + if (centuryStart != null) { definingCalendar.setTime(centuryStart); - centuryStartYear= definingCalendar.get(Calendar.YEAR); - } - else if(locale.equals(JAPANESE_IMPERIAL)) { - centuryStartYear= 0; - } - else { + centuryStartYear = definingCalendar.get(Calendar.YEAR); + } else if (locale.equals(JAPANESE_IMPERIAL)) { + centuryStartYear = 0; + } else { // from 80 years ago to 20 years from now definingCalendar.setTime(new Date()); - centuryStartYear= definingCalendar.get(Calendar.YEAR)-80; + centuryStartYear = definingCalendar.get(Calendar.YEAR) - 80; } - century= centuryStartYear / 100 * 100; - startYear= centuryStartYear - century; + century = centuryStartYear / 100 * 100; + startYear = centuryStartYear - century; init(definingCalendar); } /** - * Initialize derived fields from defining fields. - * This is called from constructor and from readObject (de-serialization) + * Initialize derived fields from defining fields. This is called from constructor and from readObject + * (de-serialization) * * @param definingCalendar the {@link java.util.Calendar} instance used to initialize this FastDateParser */ private void init(final Calendar definingCalendar) { - final StringBuilder regex= new StringBuilder(); + final StringBuilder regex = new StringBuilder(); final List<Strategy> collector = new ArrayList<Strategy>(); - final Matcher patternMatcher= formatPattern.matcher(pattern); - if(!patternMatcher.lookingAt()) { - throw new IllegalArgumentException( - "Illegal pattern character '" + pattern.charAt(patternMatcher.regionStart()) + "'"); + final Matcher patternMatcher = formatPattern.matcher(pattern); + if (!patternMatcher.lookingAt()) { + throw new IllegalArgumentException("Illegal pattern character '" + + pattern.charAt(patternMatcher.regionStart()) + "'"); } - currentFormatField= patternMatcher.group(); - Strategy currentStrategy= getStrategy(currentFormatField, definingCalendar); - for(;;) { + currentFormatField = patternMatcher.group(); + Strategy currentStrategy = getStrategy(currentFormatField, definingCalendar); + for (;;) { patternMatcher.region(patternMatcher.end(), patternMatcher.regionEnd()); - if(!patternMatcher.lookingAt()) { + if (!patternMatcher.lookingAt()) { nextStrategy = null; break; } - final String nextFormatField= patternMatcher.group(); + final String nextFormatField = patternMatcher.group(); nextStrategy = getStrategy(nextFormatField, definingCalendar); - if(currentStrategy.addRegex(this, regex)) { + if (currentStrategy.addRegex(this, regex)) { collector.add(currentStrategy); } - currentFormatField= nextFormatField; - currentStrategy= nextStrategy; + currentFormatField = nextFormatField; + currentStrategy = nextStrategy; } if (patternMatcher.regionStart() != patternMatcher.regionEnd()) { - throw new IllegalArgumentException("Failed to parse \""+pattern+"\" ; gave up at index "+patternMatcher.regionStart()); + throw new IllegalArgumentException("Failed to parse \"" + pattern + "\" ; gave up at index " + + patternMatcher.regionStart()); } - if(currentStrategy.addRegex(this, regex)) { + if (currentStrategy.addRegex(this, regex)) { collector.add(currentStrategy); } - currentFormatField= null; - strategies= collector.toArray(new Strategy[collector.size()]); - parsePattern= Pattern.compile(regex.toString()); + currentFormatField = null; + strategies = collector.toArray(new Strategy[collector.size()]); + parsePattern = Pattern.compile(regex.toString()); } // Accessors - //----------------------------------------------------------------------- - /* (non-Javadoc) + // ----------------------------------------------------------------------- + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#getPattern() */ @Override @@ -189,7 +243,9 @@ public class FastDateParser implements DateParser, Serializable { return pattern; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#getTimeZone() */ @Override @@ -197,7 +253,9 @@ public class FastDateParser implements DateParser, Serializable { return timeZone; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#getLocale() */ @Override @@ -215,26 +273,28 @@ public class FastDateParser implements DateParser, Serializable { } // Basics - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * <p>Compare another object for equality with this object.</p> + * <p> + * Compare another object for equality with this object. + * </p> * - * @param obj the object to compare to + * @param obj the object to compare to * @return <code>true</code>if equal to this instance */ @Override public boolean equals(final Object obj) { - if (! (obj instanceof FastDateParser) ) { + if (!(obj instanceof FastDateParser)) { return false; } final FastDateParser other = (FastDateParser) obj; - return pattern.equals(other.pattern) - && timeZone.equals(other.timeZone) - && locale.equals(other.locale); + return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale); } /** - * <p>Return a hashcode compatible with equals.</p> + * <p> + * Return a hashcode compatible with equals. + * </p> * * @return a hashcode compatible with equals */ @@ -244,7 +304,9 @@ public class FastDateParser implements DateParser, Serializable { } /** - * <p>Get a string version of this formatter.</p> + * <p> + * Get a string version of this formatter. + * </p> * * @return a debugging string */ @@ -254,10 +316,9 @@ public class FastDateParser implements DateParser, Serializable { } // Serializing - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /** - * Create the object after serialization. This implementation reinitializes the - * transient properties. + * Create the object after serialization. This implementation reinitializes the transient properties. * * @param in ObjectInputStream from which the object is being deserialized. * @throws IOException if there is an IO issue. @@ -270,7 +331,9 @@ public class FastDateParser implements DateParser, Serializable { init(definingCalendar); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#parseObject(java.lang.String) */ @Override @@ -278,25 +341,28 @@ public class FastDateParser implements DateParser, Serializable { return parse(source); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#parse(java.lang.String) */ @Override public Date parse(final String source) throws ParseException { - final Date date= parse(source, new ParsePosition(0)); - if(date==null) { + final Date date = parse(source, new ParsePosition(0)); + if (date == null) { // Add a note re supported date range if (locale.equals(JAPANESE_IMPERIAL)) { - throw new ParseException( - "(The " +locale + " locale does not support dates before 1868 AD)\n" + - "Unparseable date: \""+source+"\" does not match "+parsePattern.pattern(), 0); + throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" + + "Unparseable date: \"" + source + "\" does not match " + parsePattern.pattern(), 0); } - throw new ParseException("Unparseable date: \""+source+"\" does not match "+parsePattern.pattern(), 0); + throw new ParseException("Unparseable date: \"" + source + "\" does not match " + parsePattern.pattern(), 0); } return date; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.apache.commons.lang3.time.DateParser#parseObject(java.lang.String, java.text.ParsePosition) */ @Override @@ -305,43 +371,43 @@ public class FastDateParser implements DateParser, Serializable { } /** - * This implementation updates the ParsePosition if the parse succeeeds. - * However, unlike the method {@link java.text.SimpleDateFormat#parse(String, ParsePosition)} - * it is not able to set the error Index - i.e. {@link ParsePosition#getErrorIndex()} - if the parse fails. + * This implementation updates the ParsePosition if the parse succeeeds. However, unlike the method + * {@link java.text.SimpleDateFormat#parse(String, ParsePosition)} it is not able to set the error Index - i.e. + * {@link ParsePosition#getErrorIndex()} - if the parse fails. * <p> - * To determine if the parse has succeeded, the caller must check if the current parse position - * given by {@link ParsePosition#getIndex()} has been updated. If the input buffer has been fully - * parsed, then the index will point to just after the end of the input buffer. + * To determine if the parse has succeeded, the caller must check if the current parse position given by + * {@link ParsePosition#getIndex()} has been updated. If the input buffer has been fully parsed, then the index will + * point to just after the end of the input buffer. * * {@inheritDoc} */ @Override public Date parse(final String source, final ParsePosition pos) { - final int offset= pos.getIndex(); - final Matcher matcher= parsePattern.matcher(source.substring(offset)); - if(!matcher.lookingAt()) { + final int offset = pos.getIndex(); + final Matcher matcher = parsePattern.matcher(source.substring(offset)); + if (!matcher.lookingAt()) { return null; } // timing tests indicate getting new instance is 19% faster than cloning - final Calendar cal= Calendar.getInstance(timeZone, locale); + final Calendar cal = Calendar.getInstance(timeZone, locale); cal.clear(); cal.setLenient(lenient); - for(int i=0; i<strategies.length;) { - final Strategy strategy= strategies[i++]; + for (int i = 0; i < strategies.length;) { + final Strategy strategy = strategies[i++]; strategy.setCalendar(this, cal, matcher.group(i)); } - pos.setIndex(offset+matcher.end()); + pos.setIndex(offset + matcher.end()); return cal.getTime(); } // Support for strategies - //----------------------------------------------------------------------- + // ----------------------------------------------------------------------- private static StringBuilder simpleQuote(final StringBuilder sb, final String value) { - for(int i= 0; i<value.length(); ++i) { - final char c= value.charAt(i); - switch(c) { + for (int i = 0; i < value.length(); ++i) { + final char c = value.charAt(i); + switch (c) { case '\\': case '^': case '$': @@ -364,6 +430,7 @@ public class FastDateParser implements DateParser, Serializable { /** * Escape constant fields into regular expression + * * @param regex The destination regex * @param value The source field * @param unquote If true, replace two success quotes ('') with single quote (') @@ -371,33 +438,33 @@ public class FastDateParser implements DateParser, Serializable { */ private static StringBuilder escapeRegex(final StringBuilder regex, final String value, final boolean unquote) { regex.append("\\Q"); - for(int i= 0; i<value.length(); ++i) { - char c= value.charAt(i); - switch(c) { + for (int i = 0; i < value.length(); ++i) { + char c = value.charAt(i); + switch (c) { case '\'': - if(unquote) { - if(++i==value.length()) { + if (unquote) { + if (++i == value.length()) { return regex; } - c= value.charAt(i); + c = value.charAt(i); } break; case '\\': - if(++i==value.length()) { + if (++i == value.length()) { break; } /* - * If we have found \E, we replace it with \E\\E\Q, i.e. we stop the quoting, - * quote the \ in \E, then restart the quoting. - * - * Otherwise we just output the two characters. - * In each case the initial \ needs to be output and the final char is done at the end + * If we have found \E, we replace it with \E\\E\Q, i.e. we stop the quoting, quote the \ in \E, then + * restart the quoting. + * + * Otherwise we just output the two characters. In each case the initial \ needs to be output and the + * final char is done at the end */ regex.append(c); // we always want the original \ c = value.charAt(i); // Is it followed by E ? if (c == 'E') { // \E detected - regex.append("E\\\\E\\"); // see comment above - c = 'Q'; // appended below + regex.append("E\\\\E\\"); // see comment above + c = 'Q'; // appended below } break; default: @@ -409,38 +476,42 @@ public class FastDateParser implements DateParser, Serializable { return regex; } - /** * Get the short and long values displayed for a field + * * @param field The field of interest * @param definingCalendar The calendar to obtain the short and long values * @param locale The locale of display names * @return A Map of the field key / value pairs */ - private static Map<String, Integer> getDisplayNames(final int field, final Calendar definingCalendar, final Locale locale) { + private static Map<String, Integer> getDisplayNames(final int field, final Calendar definingCalendar, + final Locale locale) { return definingCalendar.getDisplayNames(field, Calendar.ALL_STYLES, locale); } /** * Adjust dates to be within appropriate century + * * @param twoDigitYear The year to adjust * @return A value between centuryStart(inclusive) to centuryStart+100(exclusive) */ private int adjustYear(final int twoDigitYear) { - final int trial= century + twoDigitYear; - return twoDigitYear>=startYear ?trial :trial+100; + final int trial = century + twoDigitYear; + return twoDigitYear >= startYear ? trial : trial + 100; } /** * Is the next field a number? + * * @return true, if next field will be a number */ boolean isNextNumber() { - return nextStrategy!=null && nextStrategy.isNumber(); + return nextStrategy != null && nextStrategy.isNumber(); } /** * What is the width of the current field? + * * @return The number of characters in the current format field */ int getFieldWidth() { @@ -451,17 +522,16 @@ public class FastDateParser implements DateParser, Serializable { * A strategy to parse a single field from the parsing pattern */ private static abstract class Strategy { - + /** - * Is this field a number? - * The default implementation returns false. + * Is this field a number? The default implementation returns false. * * @return true, if field is a number */ boolean isNumber() { return false; } - + /** * Set the Calendar with the parsed field. * @@ -474,14 +544,14 @@ public class FastDateParser implements DateParser, Serializable { void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { } - + /** - * Generate a <code>Pattern</code> regular expression to the <code>StringBuilder</code> - * which will accept this field + * Generate a <code>Pattern</code> regular expression to the <code>StringBuilder</code> which will accept this + * field + * * @param parser The parser calling this strategy * @param regex The <code>StringBuilder</code> to append to - * @return true, if this field will set the calendar; - * false, if this field is a constant value + * @return true, if this field will set the calendar; false, if this field is a constant value */ abstract boolean addRegex(FastDateParser parser, StringBuilder regex); @@ -490,20 +560,21 @@ public class FastDateParser implements DateParser, Serializable { /** * A <code>Pattern</code> to parse the user supplied SimpleDateFormat pattern */ - private static final Pattern formatPattern= Pattern.compile( - "D+|E+|F+|G+|H+|K+|M+|S+|W+|X+|Z+|a+|d+|h+|k+|m+|s+|w+|y+|z+|''|'[^']++(''[^']*+)*+'|[^'A-Za-z]++"); + private static final Pattern formatPattern = Pattern + .compile("D+|E+|F+|G+|H+|K+|M+|S+|W+|X+|Z+|a+|d+|h+|k+|m+|s+|w+|y+|z+|''|'[^']++(''[^']*+)*+'|[^'A-Za-z]++"); /** * Obtain a Strategy given a field from a SimpleDateFormat pattern + * * @param formatField A sub-sequence of the SimpleDateFormat pattern * @param definingCalendar The calendar to obtain the short and long values * @return The Strategy that will handle parsing for the field */ private Strategy getStrategy(final String formatField, final Calendar definingCalendar) { - switch(formatField.charAt(0)) { + switch (formatField.charAt(0)) { case '\'': - if(formatField.length()>2) { - return new CopyQuotedStrategy(formatField.substring(1, formatField.length()-1)); + if (formatField.length() > 2) { + return new CopyQuotedStrategy(formatField.substring(1, formatField.length() - 1)); } //$FALL-THROUGH$ default: @@ -516,12 +587,13 @@ public class FastDateParser implements DateParser, Serializable { return DAY_OF_WEEK_IN_MONTH_STRATEGY; case 'G': return getLocaleSpecificStrategy(Calendar.ERA, definingCalendar); - case 'H': // Hour in day (0-23) + case 'H': // Hour in day (0-23) return HOUR_OF_DAY_STRATEGY; - case 'K': // Hour in am/pm (0-11) + case 'K': // Hour in am/pm (0-11) return HOUR_STRATEGY; case 'M': - return formatField.length()>=3 ?getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) :NUMBER_MONTH_STRATEGY; + return formatField.length() >= 3 ? getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) + : NUMBER_MONTH_STRATEGY; case 'S': return MILLISECOND_STRATEGY; case 'W': @@ -530,9 +602,9 @@ public class FastDateParser implements DateParser, Serializable { return getLocaleSpecificStrategy(Calendar.AM_PM, definingCalendar); case 'd': return DAY_OF_MONTH_STRATEGY; - case 'h': // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0 + case 'h': // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0 return HOUR12_STRATEGY; - case 'k': // Hour in day (1-24), i.e. midnight is 24, not 0 + case 'k': // Hour in day (1-24), i.e. midnight is 24, not 0 return HOUR24_OF_DAY_STRATEGY; case 'm': return MINUTE_STRATEGY; @@ -541,7 +613,7 @@ public class FastDateParser implements DateParser, Serializable { case 'w': return WEEK_OF_YEAR_STRATEGY; case 'y': - return formatField.length()>2 ?LITERAL_YEAR_STRATEGY :ABBREVIATED_YEAR_STRATEGY; + return formatField.length() > 2 ? LITERAL_YEAR_STRATEGY : ABBREVIATED_YEAR_STRATEGY; case 'X': return ISO8601TimeZoneStrategy.getStrategy(formatField.length()); case 'Z': @@ -554,18 +626,20 @@ public class FastDateParser implements DateParser, Serializable { } } - @SuppressWarnings("unchecked") // OK because we are creating an array with no entries + @SuppressWarnings("unchecked") + // OK because we are creating an array with no entries private static final ConcurrentMap<Locale, Strategy>[] caches = new ConcurrentMap[Calendar.FIELD_COUNT]; /** * Get a cache of Strategies for a particular field + * * @param field The Calendar field * @return a cache of Locale to Strategy */ private static ConcurrentMap<Locale, Strategy> getCache(final int field) { - synchronized(caches) { - if(caches[field]==null) { - caches[field]= new ConcurrentHashMap<Locale,Strategy>(3); + synchronized (caches) { + if (caches[field] == null) { + caches[field] = new ConcurrentHashMap<Locale, Strategy>(3); } return caches[field]; } @@ -573,19 +647,19 @@ public class FastDateParser implements DateParser, Serializable { /** * Construct a Strategy that parses a Text field + * * @param field The Calendar field * @param definingCalendar The calendar to obtain the short and long values * @return a TextStrategy for the field and Locale */ private Strategy getLocaleSpecificStrategy(final int field, final Calendar definingCalendar) { - final ConcurrentMap<Locale,Strategy> cache = getCache(field); - Strategy strategy= cache.get(locale); - if(strategy==null) { - strategy= field==Calendar.ZONE_OFFSET - ? new TimeZoneStrategy(locale) - : new CaseInsensitiveTextStrategy(field, definingCalendar, locale); - final Strategy inCache= cache.putIfAbsent(locale, strategy); - if(inCache!=null) { + final ConcurrentMap<Locale, Strategy> cache = getCache(field); + Strategy strategy = cache.get(locale); + if (strategy == null) { + strategy = field == Calendar.ZONE_OFFSET ? new TimeZoneStrategy(locale) : new CaseInsensitiveTextStrategy( + field, definingCalendar, locale); + final Strategy inCache = cache.putIfAbsent(locale, strategy); + if (inCache != null) { return inCache; } } @@ -600,10 +674,11 @@ public class FastDateParser implements DateParser, Serializable { /** * Construct a Strategy that ensures the formatField has literal text + * * @param formatField The literal text to match */ CopyQuotedStrategy(final String formatField) { - this.formatField= formatField; + this.formatField = formatField; } /** @@ -611,9 +686,9 @@ public class FastDateParser implements DateParser, Serializable { */ @Override boolean isNumber() { - char c= formatField.charAt(0); - if(c=='\'') { - c= formatField.charAt(1); + char c = formatField.charAt(0); + if (c == '\'') { + c = formatField.charAt(1); } return Character.isDigit(c); } @@ -631,24 +706,25 @@ public class FastDateParser implements DateParser, Serializable { /** * A strategy that handles a text field in the parsing pattern */ - private static class CaseInsensitiveTextStrategy extends Strategy { + private static class CaseInsensitiveTextStrategy extends Strategy { private final int field; private final Locale locale; private final Map<String, Integer> lKeyValues; /** * Construct a Strategy that parses a Text field - * @param field The Calendar field - * @param definingCalendar The Calendar to use - * @param locale The Locale to use + * + * @param field The Calendar field + * @param definingCalendar The Calendar to use + * @param locale The Locale to use */ CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) { - this.field= field; - this.locale= locale; + this.field = field; + this.locale = locale; final Map<String, Integer> keyValues = getDisplayNames(field, definingCalendar, locale); - this.lKeyValues= new HashMap<String,Integer>(); + this.lKeyValues = new HashMap<String, Integer>(); - for(final Map.Entry<String, Integer> entry : keyValues.entrySet()) { + for (final Map.Entry<String, Integer> entry : keyValues.entrySet()) { lKeyValues.put(entry.getKey().toLowerCase(locale), entry.getValue()); } } @@ -659,10 +735,10 @@ public class FastDateParser implements DateParser, Serializable { @Override boolean addRegex(final FastDateParser parser, final StringBuilder regex) { regex.append("((?iu)"); - for(final String textKeyValue : lKeyValues.keySet()) { + for (final String textKeyValue : lKeyValues.keySet()) { simpleQuote(regex, textKeyValue).append('|'); } - regex.setCharAt(regex.length()-1, ')'); + regex.setCharAt(regex.length() - 1, ')'); return true; } @@ -672,20 +748,19 @@ public class FastDateParser implements DateParser, Serializable { @Override void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { final Integer iVal = lKeyValues.get(value.toLowerCase(locale)); - if(iVal == null) { - final StringBuilder sb= new StringBuilder(value); + if (iVal == null) { + final StringBuilder sb = new StringBuilder(value); sb.append(" not in ("); - for(final String textKeyValue : lKeyValues.keySet()) { + for (final String textKeyValue : lKeyValues.keySet()) { sb.append(textKeyValue).append(' '); } - sb.setCharAt(sb.length()-1, ')'); + sb.setCharAt(sb.length() - 1, ')'); throw new IllegalArgumentException(sb.toString()); } cal.set(field, iVal.intValue()); } } - /** * A strategy that handles a number field in the parsing pattern */ @@ -694,10 +769,11 @@ public class FastDateParser implements DateParser, Serializable { /** * Construct a Strategy that parses a Number field + * * @param field The Calendar field */ NumberStrategy(final int field) { - this.field= field; + this.field = field; } /** @@ -714,10 +790,9 @@ public class FastDateParser implements DateParser, Serializable { @Override boolean addRegex(final FastDateParser parser, final StringBuilder regex) { // See LANG-954: We use {Nd} rather than {IsNd} because Android does not support the Is prefix - if(parser.isNextNumber()) { + if (parser.isNextNumber()) { regex.append("(\\p{Nd}{").append(parser.getFieldWidth()).append("}+)"); - } - else { + } else { regex.append("(\\p{Nd}++)"); } return true; @@ -733,6 +808,7 @@ public class FastDateParser implements DateParser, Serializable { /** * Make any modifications to parsed integer + * * @param iValue The parsed integer * @return The modified value */ @@ -741,29 +817,15 @@ public class FastDateParser implements DateParser, Serializable { } } - private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR) { - /** - * {@inheritDoc} - */ - @Override - void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { - int iValue= Integer.parseInt(value); - if(iValue<100) { - iValue= parser.adjustYear(iValue); - } - cal.set(Calendar.YEAR, iValue); - } - }; - /** * A strategy that handles a timezone field in the parsing pattern */ static class TimeZoneStrategy extends Strategy { private static final String RFC_822_TIME_ZONE = "[+-]\\d{4}"; - private static final String GMT_OPTION= "GMT[+-]\\d{1,2}:\\d{2}"; - + private static final String GMT_OPTION = "GMT[+-]\\d{1,2}:\\d{2}"; + private final Locale locale; - private final Map<String, TimeZone> tzNames= new HashMap<String, TimeZone>(); + private final Map<String, TimeZone> tzNames = new HashMap<String, TimeZone>(); private final String validTimeZoneChars; /** @@ -773,13 +835,14 @@ public class FastDateParser implements DateParser, Serializable { /** * Construct a Strategy that parses a TimeZone + * * @param locale The Locale */ TimeZoneStrategy(final Locale locale) { this.locale = locale; final StringBuilder sb = new StringBuilder(); - sb.append('(' + RFC_822_TIME_ZONE + "|(?iu)" + GMT_OPTION ); + sb.append('(' + RFC_822_TIME_ZONE + "|(?iu)" + GMT_OPTION); final String[][] zones = DateFormatSymbols.getInstance(locale).getZoneStrings(); for (final String[] zoneNames : zones) { @@ -788,9 +851,9 @@ public class FastDateParser implements DateParser, Serializable { continue; } final TimeZone tz = TimeZone.getTimeZone(tzId); - for(int i= 1; i<zoneNames.length; ++i) { + for (int i = 1; i < zoneNames.length; ++i) { final String zoneName = zoneNames[i].toLowerCase(locale); - if (!tzNames.containsKey(zoneName)){ + if (!tzNames.containsKey(zoneName)) { tzNames.put(zoneName, tz); simpleQuote(sb.append('|'), zoneName); } @@ -816,34 +879,33 @@ public class FastDateParser implements DateParser, Serializable { @Override void setCalendar(final FastDateParser parser, final Calendar cal, final String value) { TimeZone tz; - if(value.charAt(0)=='+' || value.charAt(0)=='-') { - tz= TimeZone.getTimeZone("GMT"+value); - } - else if(value.regionMatches(true, 0, "GMT", 0, 3)) { - tz= TimeZone.getTimeZone(value.toUpperCase()); - } - else { - tz= tzNames.get(value.toLowerCase(locale)); - if(tz==null) { + if (value.charAt(0) == '+' || value.charAt(0) == '-') { + tz = TimeZone.getTimeZone("GMT" + value); + } else if (value.regionMatches(true, 0, "GMT", 0, 3)) { + tz = TimeZone.getTimeZone(value.toUpperCase()); + } else { + tz = tzNames.get(value.toLowerCase(locale)); + if (tz == null) { throw new IllegalArgumentException(value + " is not a supported timezone name"); } } cal.setTimeZone(tz); } } - + private static class ISO8601TimeZoneStrategy extends Strategy { - // Z, +hh, -hh, +hhmm, -hhmm, +hh:mm or -hh:mm + // Z, +hh, -hh, +hhmm, -hhmm, +hh:mm or -hh:mm private final String pattern; /** * Construct a Strategy that parses a TimeZone + * * @param pattern The Pattern */ ISO8601TimeZoneStrategy(final String pattern) { this.pattern = pattern; } - + /** * {@inheritDoc} */ @@ -852,7 +914,7 @@ public class FastDateParser implements DateParser, Serializable { regex.append(pattern); return true; } - + /** * {@inheritDoc} */ @@ -864,7 +926,7 @@ public class FastDateParser implements DateParser, Serializable { cal.setTimeZone(TimeZone.getTimeZone("GMT" + value)); } } - + private static final Strategy ISO_8601_1_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}))"); private static final Strategy ISO_8601_2_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}\\d{2}))"); private static final Strategy ISO_8601_3_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}(?::)\\d{2}))"); @@ -874,10 +936,10 @@ public class FastDateParser implements DateParser, Serializable { * * @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 - * strategy exists, an IllegalArgumentException will be thrown. + * strategy exists, an IllegalArgumentException will be thrown. */ static Strategy getStrategy(final int tokenLen) { - switch(tokenLen) { + switch (tokenLen) { case 1: return ISO_8601_1_STRATEGY; case 2: @@ -890,36 +952,4 @@ public class FastDateParser implements DateParser, Serializable { } } - private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH) { - @Override - int modify(final int iValue) { - return iValue-1; - } - }; - private static final Strategy LITERAL_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR); - private static final Strategy WEEK_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_YEAR); - private static final Strategy WEEK_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_MONTH); - private static final Strategy DAY_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.DAY_OF_YEAR); - private static final Strategy DAY_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_MONTH); - private static final Strategy DAY_OF_WEEK_IN_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK_IN_MONTH); - private static final Strategy HOUR_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY); - private static final Strategy HOUR24_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY) { - @Override - int modify(final int iValue) { - return iValue == 24 ? 0 : iValue; - } - }; - private static final Strategy HOUR12_STRATEGY = new NumberStrategy(Calendar.HOUR) { - @Override - int modify(final int iValue) { - return iValue == 12 ? 0 : iValue; - } - }; - private static final Strategy HOUR_STRATEGY = new NumberStrategy(Calendar.HOUR); - private static final Strategy MINUTE_STRATEGY = new NumberStrategy(Calendar.MINUTE); - private static final Strategy SECOND_STRATEGY = new NumberStrategy(Calendar.SECOND); - private static final Strategy MILLISECOND_STRATEGY = new NumberStrategy(Calendar.MILLISECOND); - private static final Strategy ISO_8601_STRATEGY = new ISO8601TimeZoneStrategy("(Z|(?:[+-]\\d{2}(?::?\\d{2})?))"); - - }
