From 38cc319907fda322e1f5976c528b260ae6f7be2c Mon Sep 17 00:00:00 2001 From: Mark Rotteveel Date: Fri, 20 Sep 2024 18:57:20 +0200 Subject: [PATCH] Annotate nullability for most utility methods/classes --- .../jaybird/util/FbDatetimeConversion.java | 16 +++++++++------- ...tionWrappingSQLExceptionThrowingFunction.java | 3 +++ .../jaybird/util/LegacyDatetimeConversions.java | 14 ++++++++------ .../firebirdsql/jaybird/util/PluginLoader.java | 8 +++++--- .../jaybird/util/ReflectionHelper.java | 3 ++- .../jaybird/util/SQLExceptionChainBuilder.java | 3 +++ .../util/SQLExceptionThrowingFunction.java | 4 +++- ...xceptionThrowingFunctionWrappingFunction.java | 3 +++ .../firebirdsql/jaybird/util/StringUtils.java | 8 +++++--- .../firebirdsql/jaybird/util/package-info.java | 4 +++- .../firebirdsql/util/FirebirdSupportInfo.java | 7 +++---- src/main/org/firebirdsql/util/package-info.java | 5 ++++- 12 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/main/org/firebirdsql/jaybird/util/FbDatetimeConversion.java b/src/main/org/firebirdsql/jaybird/util/FbDatetimeConversion.java index 04a06d49a..c9b1e1617 100644 --- a/src/main/org/firebirdsql/jaybird/util/FbDatetimeConversion.java +++ b/src/main/org/firebirdsql/jaybird/util/FbDatetimeConversion.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.Nullable; + import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDate; @@ -238,7 +240,7 @@ public static R updateFbTimeUnits(R datetime, int timeUnits * if {@code datetimeString} cannot be parsed * @see #parseSqlTimestamp(String) */ - public static LocalDateTime parseIsoOrSqlTimestamp(String datetimeString) { + public static @Nullable LocalDateTime parseIsoOrSqlTimestamp(@Nullable String datetimeString) { if (datetimeString == null) return null; if (datetimeString.length() >= 16 && (datetimeString.charAt(10) == 'T' || datetimeString.charAt(10) == 't')) { return LocalDateTime.parse(datetimeString); @@ -257,7 +259,7 @@ public static LocalDateTime parseIsoOrSqlTimestamp(String datetimeString) { * @see #parseIsoOrSqlTimestamp(String) * @see java.sql.Timestamp#valueOf(String) */ - public static LocalDateTime parseSqlTimestamp(String datetimeString) { + public static @Nullable LocalDateTime parseSqlTimestamp(@Nullable String datetimeString) { return datetimeString != null ? LocalDateTime.parse(datetimeString, SQL_TIMESTAMP_PARSE) : null; } @@ -268,7 +270,7 @@ public static LocalDateTime parseSqlTimestamp(String datetimeString) { * local date time * @return formatted string, or {@code null} if {@code localDateTime} is {@code null} */ - public static String formatSqlTimestamp(LocalDateTime localDateTime) { + public static @Nullable String formatSqlTimestamp(@Nullable LocalDateTime localDateTime) { return localDateTime != null ? localDateTime.format(SQL_TIMESTAMP_FORMAT) : null; } @@ -285,7 +287,7 @@ public static String formatSqlTimestamp(LocalDateTime localDateTime) { * if {@code timeString} cannot be parsed * @see java.sql.Time#valueOf(String) */ - public static LocalTime parseSqlTime(String timeString) { + public static @Nullable LocalTime parseSqlTime(@Nullable String timeString) { return timeString != null ? LocalTime.parse(timeString) : null; } @@ -296,7 +298,7 @@ public static LocalTime parseSqlTime(String timeString) { * local time * @return formatted string, or {@code null} if {@code localTime} is {@code null} */ - public static String formatSqlTime(LocalTime localTime) { + public static @Nullable String formatSqlTime(@Nullable LocalTime localTime) { return localTime != null ? localTime.format(ISO_LOCAL_TIME) : null; } @@ -310,7 +312,7 @@ public static String formatSqlTime(LocalTime localTime) { * if {@code dateString} cannot be parsed * @see java.sql.Date#valueOf(String) */ - public static LocalDate parseSqlDate(String dateString) { + public static @Nullable LocalDate parseSqlDate(@Nullable String dateString) { return dateString != null ? LocalDate.parse(dateString, SQL_DATE_PARSE) : null; } @@ -321,7 +323,7 @@ public static LocalDate parseSqlDate(String dateString) { * local date * @return formatted string, or {@code null} if {@code localDate} is {@code null} */ - public static String formatSqlDate(LocalDate localDate) { + public static @Nullable String formatSqlDate(@Nullable LocalDate localDate) { return localDate != null ? localDate.toString() : null; } diff --git a/src/main/org/firebirdsql/jaybird/util/FunctionWrappingSQLExceptionThrowingFunction.java b/src/main/org/firebirdsql/jaybird/util/FunctionWrappingSQLExceptionThrowingFunction.java index f6e97fc1e..a399a4f4f 100644 --- a/src/main/org/firebirdsql/jaybird/util/FunctionWrappingSQLExceptionThrowingFunction.java +++ b/src/main/org/firebirdsql/jaybird/util/FunctionWrappingSQLExceptionThrowingFunction.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.NullUnmarked; + import java.sql.SQLException; import java.util.function.Function; @@ -33,6 +35,7 @@ * @author Mark Rotteveel * @since 6 */ +@NullUnmarked final class FunctionWrappingSQLExceptionThrowingFunction implements Function { private final SQLExceptionThrowingFunction wrapped; diff --git a/src/main/org/firebirdsql/jaybird/util/LegacyDatetimeConversions.java b/src/main/org/firebirdsql/jaybird/util/LegacyDatetimeConversions.java index c0324467a..264bfea58 100644 --- a/src/main/org/firebirdsql/jaybird/util/LegacyDatetimeConversions.java +++ b/src/main/org/firebirdsql/jaybird/util/LegacyDatetimeConversions.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.Nullable; + import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; @@ -55,7 +57,7 @@ private LegacyDatetimeConversions() { * calendar * @return local date time */ - public static LocalDateTime toLocalDateTime(Timestamp val, Calendar c) { + public static LocalDateTime toLocalDateTime(Timestamp val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return val.toLocalDateTime(); c.setTime(val); return toLocalDateTime(c, val.getNanos()); @@ -74,7 +76,7 @@ public static LocalDateTime toLocalDateTime(Timestamp val, Calendar c) { * calendar * @return timestamp */ - public static Timestamp toTimestamp(LocalDateTime val, Calendar c) { + public static Timestamp toTimestamp(LocalDateTime val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return Timestamp.valueOf(val); LegacyDatetimeConversions.updateCalendar(c, val); var timestamp = new Timestamp(c.getTimeInMillis()); @@ -95,7 +97,7 @@ public static Timestamp toTimestamp(LocalDateTime val, Calendar c) { * calendar * @return local time */ - public static LocalTime toLocalTime(Time val, Calendar c) { + public static LocalTime toLocalTime(Time val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return val.toLocalTime(); c.setTime(val); return toLocalTime(c, 0); @@ -114,7 +116,7 @@ public static LocalTime toLocalTime(Time val, Calendar c) { * calendar * @return time */ - public static Time toTime(LocalTime val, Calendar c) { + public static Time toTime(LocalTime val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return Time.valueOf(val); LegacyDatetimeConversions.updateCalendar(c, LocalDate.EPOCH, val); return new Time(c.getTimeInMillis()); @@ -133,7 +135,7 @@ public static Time toTime(LocalTime val, Calendar c) { * calendar * @return local time */ - public static LocalDate toLocalDate(Date val, Calendar c) { + public static LocalDate toLocalDate(Date val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return val.toLocalDate(); c.setTime(val); return toLocalDate(c); @@ -152,7 +154,7 @@ public static LocalDate toLocalDate(Date val, Calendar c) { * calendar * @return time */ - public static Date toDate(LocalDate val, Calendar c) { + public static Date toDate(LocalDate val, @Nullable Calendar c) { if (c == null || Objects.equals(c.getTimeZone(), TimeZone.getDefault())) return Date.valueOf(val); updateCalendar(c, val, LocalTime.MIDNIGHT); return new Date(c.getTimeInMillis()); diff --git a/src/main/org/firebirdsql/jaybird/util/PluginLoader.java b/src/main/org/firebirdsql/jaybird/util/PluginLoader.java index 9785f839a..cf3915e6d 100644 --- a/src/main/org/firebirdsql/jaybird/util/PluginLoader.java +++ b/src/main/org/firebirdsql/jaybird/util/PluginLoader.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.Nullable; + import java.lang.System.Logger.Level; import java.util.*; @@ -208,14 +210,14 @@ private static Collection classLoadersForLoading(Class spiClass, public enum ClassSource { PLUGIN_CLASS_LOADER { @Override - ClassLoader getClassLoader(Class spiClass) { + @Nullable ClassLoader getClassLoader(Class spiClass) { ClassLoader cl = spiClass.getClassLoader(); return cl != null ? cl : ClassLoader.getSystemClassLoader(); } }, CONTEXT_CLASS_LOADER { @Override - ClassLoader getClassLoader(Class spiClass) { + @Nullable ClassLoader getClassLoader(Class spiClass) { return Thread.currentThread().getContextClassLoader(); } }; @@ -227,6 +229,6 @@ ClassLoader getClassLoader(Class spiClass) { * service provider interface (SPI) of the plugin * @return class loader to use (can be {@code null}) */ - abstract ClassLoader getClassLoader(Class spiClass); + abstract @Nullable ClassLoader getClassLoader(Class spiClass); } } diff --git a/src/main/org/firebirdsql/jaybird/util/ReflectionHelper.java b/src/main/org/firebirdsql/jaybird/util/ReflectionHelper.java index 2f4b95992..f884ab579 100644 --- a/src/main/org/firebirdsql/jaybird/util/ReflectionHelper.java +++ b/src/main/org/firebirdsql/jaybird/util/ReflectionHelper.java @@ -19,6 +19,7 @@ package org.firebirdsql.jaybird.util; import org.firebirdsql.util.InternalApi; +import org.jspecify.annotations.Nullable; import java.lang.reflect.Method; import java.util.Collections; @@ -65,7 +66,7 @@ public static Class[] getAllInterfaces(Class clazz) { * @return instance of {@link Method} corresponding to specified name and * param types. */ - public static Method findMethod(Class clazz, String name, Class[] args) { + public static @Nullable Method findMethod(Class clazz, String name, Class[] args) { try { return clazz.getMethod(name, args); } catch (NoSuchMethodException nmex) { diff --git a/src/main/org/firebirdsql/jaybird/util/SQLExceptionChainBuilder.java b/src/main/org/firebirdsql/jaybird/util/SQLExceptionChainBuilder.java index ba4f4b9e7..646393fc8 100644 --- a/src/main/org/firebirdsql/jaybird/util/SQLExceptionChainBuilder.java +++ b/src/main/org/firebirdsql/jaybird/util/SQLExceptionChainBuilder.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.NullUnmarked; + import java.sql.SQLException; /** @@ -30,6 +32,7 @@ * @author Mark Rotteveel * @since 2.2 */ +@NullUnmarked public final class SQLExceptionChainBuilder { private SQLException root; diff --git a/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunction.java b/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunction.java index 5a69f5573..45f43ba71 100644 --- a/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunction.java +++ b/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunction.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.NullUnmarked; + import java.sql.SQLException; import java.util.function.Function; @@ -31,8 +33,8 @@ * @author Mark Rotteveel * @since 6 */ - @FunctionalInterface +@NullUnmarked public interface SQLExceptionThrowingFunction { R apply(T t) throws SQLException; diff --git a/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunctionWrappingFunction.java b/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunctionWrappingFunction.java index f5c6d621c..0ca7fef89 100644 --- a/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunctionWrappingFunction.java +++ b/src/main/org/firebirdsql/jaybird/util/SQLExceptionThrowingFunctionWrappingFunction.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.NullUnmarked; + import java.sql.SQLException; import java.util.function.Function; @@ -33,6 +35,7 @@ * @author Mark Rotteveel * @since 6 */ +@NullUnmarked final class SQLExceptionThrowingFunctionWrappingFunction implements SQLExceptionThrowingFunction { private final Function wrapped; diff --git a/src/main/org/firebirdsql/jaybird/util/StringUtils.java b/src/main/org/firebirdsql/jaybird/util/StringUtils.java index 2353f80c3..f56bde34e 100644 --- a/src/main/org/firebirdsql/jaybird/util/StringUtils.java +++ b/src/main/org/firebirdsql/jaybird/util/StringUtils.java @@ -18,6 +18,8 @@ */ package org.firebirdsql.jaybird.util; +import org.jspecify.annotations.Nullable; + /** * Helper class for string operations * @@ -39,7 +41,7 @@ private StringUtils() { * @return Trimmed string {@code value}, or {@code null} when null, or empty after trim. * @see String#trim() */ - public static String trimToNull(String value) { + public static @Nullable String trimToNull(@Nullable String value) { if (value != null) { String newValue = value.trim(); if (!newValue.isEmpty()) { @@ -57,7 +59,7 @@ public static String trimToNull(String value) { * @return {@code true} if {@code value} is {@code null} or emoty, {@code false} for non-empty strings * @since 6 */ - public static boolean isNullOrEmpty(String value) { + public static boolean isNullOrEmpty(@Nullable String value) { return value == null || value.isEmpty(); } @@ -69,7 +71,7 @@ public static boolean isNullOrEmpty(String value) { * @return result of {@code stringToTrim.trim()} (or {@code null} if {@code stringToTrim} was null * @since 6 */ - public static String trim(String stringToTrim) { + public static @Nullable String trim(@Nullable String stringToTrim) { return stringToTrim == null ? null : stringToTrim.trim(); } diff --git a/src/main/org/firebirdsql/jaybird/util/package-info.java b/src/main/org/firebirdsql/jaybird/util/package-info.java index 210b7593f..fa9cc416b 100644 --- a/src/main/org/firebirdsql/jaybird/util/package-info.java +++ b/src/main/org/firebirdsql/jaybird/util/package-info.java @@ -24,6 +24,8 @@ * @since 6 */ @InternalApi +@NullMarked package org.firebirdsql.jaybird.util; -import org.firebirdsql.util.InternalApi; \ No newline at end of file +import org.firebirdsql.util.InternalApi; +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/org/firebirdsql/util/FirebirdSupportInfo.java b/src/main/org/firebirdsql/util/FirebirdSupportInfo.java index 19bd042c3..cea0516aa 100644 --- a/src/main/org/firebirdsql/util/FirebirdSupportInfo.java +++ b/src/main/org/firebirdsql/util/FirebirdSupportInfo.java @@ -32,6 +32,8 @@ import java.sql.SQLException; +import static java.util.Objects.requireNonNull; + /** * Helper class that reports if a Firebird version supports a specific feature. *

@@ -54,10 +56,7 @@ public final class FirebirdSupportInfo { private final GDSServerVersion serverVersion; private FirebirdSupportInfo(GDSServerVersion serverVersion) { - if (serverVersion == null) { - throw new NullPointerException("serverVersion"); - } - if (serverVersion.equals(GDSServerVersion.INVALID_VERSION)) { + if (requireNonNull(serverVersion, "serverVersion").equals(GDSServerVersion.INVALID_VERSION)) { throw new IllegalArgumentException("serverVersion is an invalid version (GDSServerVersion.INVALID_VERSION)"); } this.serverVersion = serverVersion; diff --git a/src/main/org/firebirdsql/util/package-info.java b/src/main/org/firebirdsql/util/package-info.java index a422ce541..63288b5b8 100644 --- a/src/main/org/firebirdsql/util/package-info.java +++ b/src/main/org/firebirdsql/util/package-info.java @@ -6,4 +6,7 @@ *

*/ @InternalApi -package org.firebirdsql.util; \ No newline at end of file +@NullMarked +package org.firebirdsql.util; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file