From 49ebcee70c5c3501804294c358ae14b799f72c92 Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Wed, 14 Aug 2024 22:23:48 +0200 Subject: [PATCH 1/3] [java] JSpecify annotations for capabilities --- java/src/org/openqa/selenium/Capabilities.java | 7 +++++-- java/src/org/openqa/selenium/HasCapabilities.java | 3 +++ java/src/org/openqa/selenium/ImmutableCapabilities.java | 7 +++++-- java/src/org/openqa/selenium/MutableCapabilities.java | 9 ++++++--- java/src/org/openqa/selenium/PersistentCapabilities.java | 7 +++++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/java/src/org/openqa/selenium/Capabilities.java b/java/src/org/openqa/selenium/Capabilities.java index 683e5e4e41b7d..053cdd971fc75 100644 --- a/java/src/org/openqa/selenium/Capabilities.java +++ b/java/src/org/openqa/selenium/Capabilities.java @@ -24,15 +24,18 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** Describes a series of key/value pairs that encapsulate aspects of a browser. */ +@NullMarked public interface Capabilities extends Serializable { default String getBrowserName() { return String.valueOf(Optional.ofNullable(getCapability("browserName")).orElse("")); } - default Platform getPlatformName() { + default @Nullable Platform getPlatformName() { return Stream.of("platformName") .map(this::getCapability) .filter(Objects::nonNull) @@ -67,7 +70,7 @@ default String getBrowserVersion() { * @return The value, or null if not set. * @see org.openqa.selenium.remote.CapabilityType */ - Object getCapability(String capabilityName); + @Nullable Object getCapability(String capabilityName); /** * @param capabilityName The capability to check. diff --git a/java/src/org/openqa/selenium/HasCapabilities.java b/java/src/org/openqa/selenium/HasCapabilities.java index bd8f9ef44a52b..af0cf7213f236 100644 --- a/java/src/org/openqa/selenium/HasCapabilities.java +++ b/java/src/org/openqa/selenium/HasCapabilities.java @@ -17,10 +17,13 @@ package org.openqa.selenium; +import org.jspecify.annotations.NullMarked; + /** * Used by classes to indicate that they can describe the {@link org.openqa.selenium.Capabilities} * they possess. This can be used for run-time detection of features. */ +@NullMarked public interface HasCapabilities { /** * @return The capabilities of the current driver. diff --git a/java/src/org/openqa/selenium/ImmutableCapabilities.java b/java/src/org/openqa/selenium/ImmutableCapabilities.java index ee800049fc345..d49c9999701ce 100644 --- a/java/src/org/openqa/selenium/ImmutableCapabilities.java +++ b/java/src/org/openqa/selenium/ImmutableCapabilities.java @@ -22,8 +22,11 @@ import java.util.Collections; import java.util.Map; import java.util.TreeMap; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; +@NullMarked public class ImmutableCapabilities implements Capabilities { private final Map delegate; @@ -156,7 +159,7 @@ public ImmutableCapabilities(Map capabilities) { } @Override - public Object getCapability(String capabilityName) { + public @Nullable Object getCapability(String capabilityName) { Require.nonNull("Capability name", capabilityName); return delegate.get(capabilityName); } @@ -172,7 +175,7 @@ public int hashCode() { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (!(o instanceof Capabilities)) { return false; } diff --git a/java/src/org/openqa/selenium/MutableCapabilities.java b/java/src/org/openqa/selenium/MutableCapabilities.java index 16c56b5536d60..143c32680149b 100644 --- a/java/src/org/openqa/selenium/MutableCapabilities.java +++ b/java/src/org/openqa/selenium/MutableCapabilities.java @@ -22,8 +22,11 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; +@NullMarked public class MutableCapabilities implements Capabilities { private static final Set OPTION_KEYS; @@ -81,7 +84,7 @@ public void setCapability(String capabilityName, Platform value) { setCapability(capabilityName, (Object) value); } - public void setCapability(String key, Object value) { + public void setCapability(String key, @Nullable Object value) { Require.nonNull("Capability name", key); // We have to special-case some keys and values because of the popular idiom of calling @@ -107,7 +110,7 @@ public Map asMap() { } @Override - public Object getCapability(String capabilityName) { + public @Nullable Object getCapability(String capabilityName) { return caps.get(capabilityName); } @@ -126,7 +129,7 @@ public int hashCode() { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (!(o instanceof Capabilities)) { return false; } diff --git a/java/src/org/openqa/selenium/PersistentCapabilities.java b/java/src/org/openqa/selenium/PersistentCapabilities.java index d42e08229b6a5..8411c6cf4d313 100644 --- a/java/src/org/openqa/selenium/PersistentCapabilities.java +++ b/java/src/org/openqa/selenium/PersistentCapabilities.java @@ -24,8 +24,11 @@ import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; +@NullMarked public class PersistentCapabilities implements Capabilities { private final ImmutableCapabilities caps; @@ -62,7 +65,7 @@ public Map asMap() { } @Override - public Object getCapability(String capabilityName) { + public @Nullable Object getCapability(String capabilityName) { Require.nonNull("Capability name", capabilityName); Object capability = overrides.getCapability(capabilityName); if (capability != null) { @@ -107,7 +110,7 @@ public int hashCode() { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (!(o instanceof Capabilities)) { return false; } From 6decde4dc7155d7c58e01f9519cd3fffb502f276 Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Tue, 14 Jan 2025 19:04:51 +0100 Subject: [PATCH 2/3] [java] Fixed NullAway errors in capabilities --- java/src/org/openqa/selenium/ImmutableCapabilities.java | 3 +-- java/src/org/openqa/selenium/PersistentCapabilities.java | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java/src/org/openqa/selenium/ImmutableCapabilities.java b/java/src/org/openqa/selenium/ImmutableCapabilities.java index d49c9999701ce..a617134fca3cb 100644 --- a/java/src/org/openqa/selenium/ImmutableCapabilities.java +++ b/java/src/org/openqa/selenium/ImmutableCapabilities.java @@ -148,10 +148,9 @@ public ImmutableCapabilities(Map capabilities) { capabilities.forEach( (key, value) -> { Require.argument("Capability key", key).instanceOf(String.class); - Object v = capabilities.get(key); Require.nonNull("Capability value", value); - setCapability(delegate, (String) key, v); + setCapability(delegate, (String) key, value); }); this.delegate = Collections.unmodifiableMap(delegate); diff --git a/java/src/org/openqa/selenium/PersistentCapabilities.java b/java/src/org/openqa/selenium/PersistentCapabilities.java index 8411c6cf4d313..6f443482bbbb7 100644 --- a/java/src/org/openqa/selenium/PersistentCapabilities.java +++ b/java/src/org/openqa/selenium/PersistentCapabilities.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -60,8 +61,10 @@ public PersistentCapabilities setCapability(String name, Object value) { @Override public Map asMap() { - return getCapabilityNames().stream() - .collect(toUnmodifiableMap(Function.identity(), this::getCapability)); + Map toReturn = new TreeMap<>(); + toReturn.putAll(caps.asMap()); + toReturn.putAll(overrides.asMap()); + return Collections.unmodifiableMap(toReturn); } @Override From 6fab3bb23abf434aa4047f8e424fc8dbda766dd3 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Mon, 7 Jul 2025 17:26:02 +0000 Subject: [PATCH 3/3] Format script --- java/src/org/openqa/selenium/PersistentCapabilities.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/src/org/openqa/selenium/PersistentCapabilities.java b/java/src/org/openqa/selenium/PersistentCapabilities.java index 24b35a3e44358..f5d52cec5f079 100644 --- a/java/src/org/openqa/selenium/PersistentCapabilities.java +++ b/java/src/org/openqa/selenium/PersistentCapabilities.java @@ -19,7 +19,6 @@ import java.util.Map; import java.util.Set; -import java.util.TreeMap; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream;