Skip to content

Commit

Permalink
refact: improve null safety
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Jun 12, 2024
1 parent 04a9104 commit 6253af9
Show file tree
Hide file tree
Showing 62 changed files with 328 additions and 267 deletions.
144 changes: 71 additions & 73 deletions jstuff-core/src/main/java/net/sf/jstuff/core/Strings.java

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions jstuff-core/src/main/java/net/sf/jstuff/core/SystemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public abstract class SystemUtils extends org.apache.commons.lang3.SystemUtils {

private static final Collection<String> WINDOWS_EXE_FILE_EXTENSIONS = List.of(Strings.splitByWholeSeparator( //
IS_OS_WINDOWS //
? getEnvironmentVariable("PATHEXT", "") //
: ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC", //
? getEnvironmentVariable("PATHEXT", "") //
: ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC", //
";" //
));

Expand Down Expand Up @@ -119,8 +119,8 @@ public static String getEnvironmentVariable(final String name, final String defa
public static int getJavaMajorVersion() {
final String version = asNonNull(System.getProperty("java.version"));
return Integer.parseInt(version.startsWith("1.") //
? version.substring(2, 3) //
: Strings.substringBefore(version, '.') //
? version.substring(2, 3) //
: Strings.substringBefore(version, '.') //
);
}

Expand Down Expand Up @@ -170,7 +170,9 @@ public static boolean isRunningAsAdmin() {
}

final java.util.logging.Logger prefsLogger = LogManager.getLogManager().getLogger("java.util.prefs.WindowsPreferences");
prefsLogger.setLevel(Level.SEVERE);
if (prefsLogger != null) {
prefsLogger.setLevel(Level.SEVERE);
}
try {
// https://stackoverflow.com/a/23538961/5116073
final Preferences prefs = Preferences.systemRoot();
Expand All @@ -182,7 +184,9 @@ public static boolean isRunningAsAdmin() {
isRunningAsAdmin = true;
return true;
} finally {
prefsLogger.setLevel(Level.INFO);
if (prefsLogger != null) {
prefsLogger.setLevel(Level.INFO);
}
}
} catch (final Exception ex) {
LOG.debug(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*
* @author Sebastian Thomschke
*/
@NonNullByDefault
@NonNullByDefault({ARRAY_CONTENTS, FIELD, PARAMETER, RETURN_TYPE, TYPE_ARGUMENT, TYPE_BOUND, TYPE_PARAMETER})
package net.sf.jstuff.core.benchmark;

import static org.eclipse.jdt.annotation.DefaultLocation.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.Set;

import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import net.sf.jstuff.core.Strings;
Expand All @@ -32,7 +31,7 @@
/**
* @author <a href="https://sebthom.de/">Sebastian Thomschke</a>
*/
public class BuilderFactory<TARGET_CLASS, @NonNull BLDR_IFACE extends Builder<? extends TARGET_CLASS>> {
public class BuilderFactory<TARGET_CLASS, BLDR_IFACE extends Builder<? extends TARGET_CLASS>> {

private static final class BuilderImpl implements InvocationHandler {

Expand All @@ -47,7 +46,7 @@ private static final class BuilderImpl implements InvocationHandler {
/**
* ordered list of the values of all wither/setter invocations on the builder instance
*/
private final List<Tuple2<String, Object[]>> properties = new ArrayList<>();
private final List<Tuple2<String, @Nullable Object[]>> properties = new ArrayList<>();

BuilderImpl(final Class<?> builderInterface, final Class<?> targetClass, final Object... constructorArgs) {
this.builderInterface = builderInterface;
Expand Down Expand Up @@ -124,14 +123,13 @@ protected Object buildTarget() throws Throwable { // CHECKSTYLE:IGNORE .*
final Object target = Types.newInstance(targetClass, constructorArgs);

// setting properties
for (final Tuple2<String, Object[]> property : properties) {
@NonNull
for (final Tuple2<String, @Nullable Object[]> property : properties) {
String propName = property.get1();
// remove "with" prefix from withSomeProperty(...) named properties
if (propName.length() > 4 && propName.startsWith("with")) {
propName = Strings.lowerCaseFirstChar(propName.substring(4));
}
final Object[] propArgs = property.get2();
final @Nullable Object[] propArgs = property.get2();
final String setterName = "set" + Strings.upperCaseFirstChar(propName);
final Method setterMethod = Methods.findAnyCompatible(targetClass, setterName, propArgs);
// if no setter found then directly try to set the field
Expand All @@ -151,7 +149,7 @@ protected Object buildTarget() throws Throwable { // CHECKSTYLE:IGNORE .*
final Builder.Property propConfig = prop.getValue();

boolean wasPropertySet = false;
for (final Tuple2<String, Object[]> property : properties) {
for (final Tuple2<String, @Nullable Object[]> property : properties) {
if (propName.equals(property.get1())) {
final boolean isNullable = propConfig == null ? propertyDefaults.nullable() : propConfig.nullable();
if (!isNullable && property.get2()[0] == null)
Expand Down Expand Up @@ -189,7 +187,7 @@ protected Object buildTarget() throws Throwable { // CHECKSTYLE:IGNORE .*
* handles invocation of withXYZ on builder interface
*/
@Override
public @Nullable Object invoke(final Object proxy, final Method method, final Object @Nullable [] args) throws Throwable {
public @Nullable Object invoke(final Object proxy, final Method method, final @Nullable Object @Nullable [] args) throws Throwable {
final boolean isBuildMethod = "build".equals(method.getName()) //
&& method.getParameterTypes().length == 0 //
&& method.getReturnType().isAssignableFrom(targetClass);
Expand All @@ -202,7 +200,7 @@ protected Object buildTarget() throws Throwable { // CHECKSTYLE:IGNORE .*

// collect values from setter invocations
if (method.getReturnType().isAssignableFrom(builderInterface)) {
properties.add(Tuple2.create(method.getName(), args == null ? ArrayUtils.EMPTY_OBJECT_ARRAY : args));
properties.add(new Tuple2<>(method.getName(), args == null ? new @Nullable Object[0] : args));
return proxy;
}
throw new UnsupportedOperationException(method.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*
* @author Sebastian Thomschke
*/
@NonNullByDefault
@NonNullByDefault({ARRAY_CONTENTS, FIELD, PARAMETER, RETURN_TYPE, TYPE_ARGUMENT, TYPE_BOUND, TYPE_PARAMETER})
package net.sf.jstuff.core.builder;

import static org.eclipse.jdt.annotation.DefaultLocation.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*
* @author Sebastian Thomschke
*/
@NonNullByDefault
@NonNullByDefault({ARRAY_CONTENTS, FIELD, PARAMETER, RETURN_TYPE, TYPE_ARGUMENT, TYPE_BOUND, TYPE_PARAMETER})
package net.sf.jstuff.core.classloader;

import static org.eclipse.jdt.annotation.DefaultLocation.*;

import org.eclipse.jdt.annotation.NonNullByDefault;
34 changes: 19 additions & 15 deletions jstuff-core/src/main/java/net/sf/jstuff/core/collection/Maps.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
package net.sf.jstuff.core.collection;

import static net.sf.jstuff.core.validation.NullAnalysisHelper.asNonNullUnsafe;
import static net.sf.jstuff.core.validation.NullAnalysisHelper.*;

import java.io.Serializable;
import java.util.ArrayList;
Expand All @@ -21,6 +21,8 @@
import java.util.WeakHashMap;

import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;

import net.sf.jstuff.core.Strings;
Expand Down Expand Up @@ -49,7 +51,7 @@ public static class EntryValueDiff<K, V> implements Serializable {
public final @Nullable V rightValue;

public EntryValueDiff(final Map<K, V> leftMap, final Map<K, V> rightMap, final K key, final @Nullable V leftValue,
final @Nullable V rightValue) {
final @Nullable V rightValue) {
this.leftMap = leftMap;
this.rightMap = rightMap;
this.key = key;
Expand Down Expand Up @@ -84,7 +86,7 @@ public boolean isDifferent() {
@Override
public String toString() {
return MapDiff.class.getSimpleName() + " [entryValueDiffs=" + entryValueDiffs + ", leftOnlyEntries=" + leftOnlyEntries
+ ", rightOnlyEntries=" + rightOnlyEntries + "]";
+ ", rightOnlyEntries=" + rightOnlyEntries + "]";
}
}

Expand Down Expand Up @@ -186,7 +188,7 @@ public static <K, V> HashMap<K, V> newHashMap(final int initialSize) {
}

public static <K, V, KK extends K, VV extends V> HashMap<K, V> newHashMap(final KK firstKey, final VV firstValue,
final Object... moreInitialKeysAndValues) {
final Object... moreInitialKeysAndValues) {
return putAll(new HashMap<>(1 + moreInitialKeysAndValues.length / 2), firstKey, firstValue, moreInitialKeysAndValues);
}

Expand All @@ -210,7 +212,7 @@ public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(final int initialSize)
}

public static <K, V, KK extends K, VV extends V> LinkedHashMap<K, V> newLinkedHashMap(final KK firstKey, final VV firstValue,
final Object... moreInitialKeysAndValues) {
final Object... moreInitialKeysAndValues) {
return putAll(new LinkedHashMap<>(1 + moreInitialKeysAndValues.length / 2), firstKey, firstValue, moreInitialKeysAndValues);
}

Expand Down Expand Up @@ -238,20 +240,20 @@ public static <K, V> TreeMap<K, V> newTreeMap(final Comparator<? super K> keyCom
}

public static <K, V, KK extends K, VV extends V> TreeMap<K, V> newTreeMap(final Comparator<? super K> keyComparator, final KK firstKey,
final VV firstValue, final Object... moreInitialKeysAndValues) {
final VV firstValue, final Object... moreInitialKeysAndValues) {
return putAll(new TreeMap<>(keyComparator), firstKey, firstValue, moreInitialKeysAndValues);
}

public static <K, V, KK extends K, VV extends V> TreeMap<K, V> newTreeMap(final Comparator<? super K> keyComparator,
final Object @Nullable [] initialKeysAndValues) {
final Object @Nullable [] initialKeysAndValues) {
if (initialKeysAndValues == null)
return new TreeMap<>(keyComparator);

return putAll(new TreeMap<>(keyComparator), initialKeysAndValues);
}

public static <K, V, KK extends K, VV extends V> TreeMap<K, V> newTreeMap(final KK firstKey, final VV firstValue,
final Object... moreInitialKeysAndValues) {
final Object... moreInitialKeysAndValues) {
return putAll(new TreeMap<>(), firstKey, firstValue, moreInitialKeysAndValues);
}

Expand All @@ -271,7 +273,7 @@ public static <K, V, M extends Map<K, V>> M putAll(final M map, final K[] keys,

@SuppressWarnings("unchecked")
public static <K, V, KK extends K, VV extends V, M extends Map<K, V>> M putAll(final M map, final KK firstKey, final VV firstValue,
final Object... moreKeysAndValues) {
final Object... moreKeysAndValues) {
Args.notNull("map", map);

map.put(firstKey, firstValue);
Expand Down Expand Up @@ -338,7 +340,7 @@ public static <K, V, M extends Map<K, V>> M putAllIfAbsent(final M map, final K[

@SuppressWarnings("unchecked")
public static <K, V, KK extends K, VV extends V, M extends Map<K, V>> M putAllIfAbsent(final M map, final KK firstKey,
final VV firstValue, final Object... moreKeysAndValues) {
final VV firstValue, final Object... moreKeysAndValues) {
Args.notNull("map", map);

map.put(firstKey, firstValue);
Expand Down Expand Up @@ -378,7 +380,8 @@ public static <K, V, M extends Map<K, V>> M putAllIfAbsent(final M map, final Ob
return map;
}

public static <K, V extends Comparable<V>> Map<K, V> sortByValue(final Map<K, V> map) {
@NonNullByDefault({})
public static <K, V extends Comparable<V>> @NonNull Map<K, V> sortByValue(final @NonNull Map<K, V> map) {
return sortByValue(map, SortDirection.ASC);
}

Expand All @@ -400,7 +403,9 @@ public static <K, V> Map<K, V> sortByValue(final Map<K, V> map, final Comparator
return sortedMap;
}

public static <K, V extends Comparable<V>> Map<K, V> sortByValue(final Map<K, V> map, final SortDirection direction) {
@NonNullByDefault({})
public static <K, V extends Comparable<V>> @NonNull Map<K, V> sortByValue(final @NonNull Map<K, V> map,
final @NonNull SortDirection direction) {
Args.notNull("map", map);

if (map.isEmpty())
Expand Down Expand Up @@ -460,14 +465,13 @@ public static <T> Map<T, T> toMap(final T... keysAndValues) {

final var result = new HashMap<T, T>();
boolean isKey = true;
@Nullable
T key = null;
T key = lazyNonNull();
for (final T item : keysAndValues)
if (isKey) {
key = item;
isKey = false;
} else {
result.put(key, item);
result.put(asNonNullUnsafe(key), item);
isKey = true;
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ public DebouncingEventDispatcher(final Duration delay) {
}

private DebouncingEventDispatcher( //
final Duration delay, //
final @Nullable EventDispatcher<EVENT> delegate, //
final @Nullable Function<EVENT, Object> eventKeyProvider, //
final @Nullable ScheduledExecutorService scheduler //
final Duration delay, //
final @Nullable EventDispatcher<EVENT> delegate, //
final @Nullable Function<EVENT, Object> eventKeyProvider, //
final @Nullable ScheduledExecutorService scheduler //
) {
super(delegate, eventKeyProvider, scheduler);

Expand All @@ -115,8 +115,8 @@ private DebouncingEventDispatcher( //
@Override
public CompletableFuture<Integer> fire(final EVENT event) {
final long deadline = System.currentTimeMillis() + delayMS;
return rateLimitedEvents.compute(eventKeyProvider.apply(event), (k, debouncedEvent) -> {
if (asNullable(debouncedEvent) == null) {
return asNonNull(rateLimitedEvents.compute(eventKeyProvider.apply(event), (k, debouncedEvent) -> {
if (debouncedEvent == null) {
debouncedEvent = new DebouncedEvent(event, deadline);
final var remainingMS = Math.max(0, debouncedEvent.deadline - System.currentTimeMillis());
debouncedEvent.scheduledFuture = scheduler.schedule(debouncedEvent::fireEvent, remainingMS, TimeUnit.MILLISECONDS);
Expand All @@ -126,11 +126,11 @@ public CompletableFuture<Integer> fire(final EVENT event) {

final var remainingMS = debouncedEvent.deadline - System.currentTimeMillis();
debouncedEvent.scheduledFuture = remainingMS < 1 //
? scheduler.submit(debouncedEvent::fireEvent) //
: scheduler.schedule(debouncedEvent::fireEvent, //
remainingMS, TimeUnit.MILLISECONDS);
? scheduler.submit(debouncedEvent::fireEvent) //
: scheduler.schedule(debouncedEvent::fireEvent, //
remainingMS, TimeUnit.MILLISECONDS);
}
return debouncedEvent;
}).resultFuture;
})).resultFuture;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
public abstract class JMXUtils {
private static final Logger LOG = Logger.create();

@Nullable
private static MBeanServer mbeanServer;
private static @Nullable MBeanServer mbeanServer;

public static synchronized MBeanServer getMBeanServer() {
var mbeanServer = JMXUtils.mbeanServer;
Expand Down Expand Up @@ -77,7 +76,7 @@ public static boolean isDebugModeEnabled() {
final List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
for (final String arg : args) {
if (arg.startsWith("-agentlib:jdwp") && args.contains("-Xdebug") //
|| arg.startsWith("-Xrunjdwp"))
|| arg.startsWith("-Xrunjdwp"))
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@ public static long getLastModified(final URL resourceURL) throws IOException {
* Get the resource URL via this.getClass().getResource("....").
*/
public static long getLastModified(final URLConnection resourceConnection) throws IOException {
if (resourceConnection instanceof JarURLConnection)
return ((JarURLConnection) resourceConnection).getJarEntry().getTime();
if (resourceConnection instanceof JarURLConnection) {
final var jarURL = (JarURLConnection) resourceConnection;
final var entry = jarURL.getJarEntry();
if (entry != null)
return entry.getTime();
}

/*
* Because of a bug in Suns VM regarding FileURLConnection, which for some reason causes 0 to be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,12 @@ public void run() {
protected TcpTunnel(final Socket clientSocket) throws SocketException {
this.clientSocket = clientSocket;
tunnelName = clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort() + " > " //
+ clientSocket.getLocalAddress().getHostName() + ":" + clientSocket.getLocalPort() + " > " //
+ (Strings.isBlank(proxyAddress) ? "" : proxyAddress + ":" + proxyPort + " > ") //
+ targetAddress + ":" + targetPort;
+ clientSocket.getLocalAddress().getHostName() + ":" + clientSocket.getLocalPort() + " > " //
+ (Strings.isBlank(proxyAddress) ? "" : proxyAddress + ":" + proxyPort + " > ") //
+ targetAddress + ":" + targetPort;

if (Strings.isBlank(proxyAddress)) {
final var proxyType = TcpTunnelService.this.proxyType;
if (proxyType == null || Strings.isBlank(proxyAddress)) {
targetSocket = new Socket();
} else {
targetSocket = new Socket(new Proxy(proxyType, new InetSocketAddress(proxyAddress, proxyPort)));
Expand Down Expand Up @@ -121,7 +122,7 @@ public void run() {
}

public interface TcpProxyServerBuilder<THIS extends TcpProxyServerBuilder<THIS, T>, T extends TcpTunnelService> extends
net.sf.jstuff.core.builder.Builder<TcpTunnelService> {
net.sf.jstuff.core.builder.Builder<TcpTunnelService> {

/**
* Default is -1, i.e. unlimited
Expand Down
Loading

0 comments on commit 6253af9

Please sign in to comment.