NullUtil.java
package swingtree;
import org.jspecify.annotations.Nullable;
import sprouts.Val;
import org.slf4j.helpers.MessageFormatter;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* A utility class for message formatting.
*/
final class NullUtil
{
private NullUtil() {} // This is a utility class!
/**
* Unfortunately, NullAway does not support nullability annotations on type parameters.
* It always assumes that type parameters are non-null, irrespective if
* the user provides a nullability annotation or not.
* This is a problem in the sprouts library, which also uses nullability annotations.
* This method is a workaround for this issue.
*
* @param var The variable to be faked as non-null.
* @return The same variable as the input, but with a non-null type.
* @param <T> The type of the variable.
*/
@SuppressWarnings("NullAway")
static <T> T fakeNonNull( @Nullable T var ) {
return var;
}
/**
* Formats a {@link String} with placeholders "{}" and replaces them with the
* {@link String} representations of the given {@link Object}s.
* This is essentially just a delegate to {@link MessageFormatter#arrayFormat(String, Object[])}.
*
* @param withPlaceholders The {@link String} which may or may not contain placeholder in the for of "{}".
* @param toBePutAtPlaceholders Arbitrary {@link Object}s which will be turned into
* {@link String}s instead of the placeholder brackets.
*
* @return A {@link String} containing the actual {@link String} representations of th {@link Object}s
* instead of the placeholder brackets within the first argument.
*/
static String format( String withPlaceholders, Object... toBePutAtPlaceholders ) {
return MessageFormatter.arrayFormat( withPlaceholders, toBePutAtPlaceholders ).getMessage();
}
public static <T> void nullArgCheck( @Nullable T var, String thing, Class<?> type, String... notes ) {
if ( var == null ) {
String postfix = Arrays.stream(notes).collect(Collectors.joining(" "));
postfix = ( postfix.trim().equals("") ? "" : " " ) + postfix;
throw new IllegalArgumentException(
format(
"Argument '{}' of type '{}' was null!{}",
thing, type.getSimpleName(), postfix
)
);
}
}
public static <T> void nullPropertyCheck( Val<T> property, String thing, String... notes ) {
nullArgCheck( property, thing, Val.class, "Properties are not supposed to be null, they may wrap null values though." );
if ( property.allowsNull() ) {
Class<T> type = property.type();
String message = "Property '{}' of type '{}' may not be null, but it was.";
if ( notes.length > 0 )
message += " " + String.join(" ", notes);
throw new IllegalArgumentException( format( message, thing, type.getSimpleName() ) );
}
}
}