Skip to content

Commit 6d6eab1

Browse files
committed
Complete nullability assignments in Java client
1 parent 657e37c commit 6d6eab1

File tree

13 files changed

+99
-72
lines changed

13 files changed

+99
-72
lines changed

client/src/main/java/org/strykeforce/deadeye/Deadeye.java

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@
4141
public class Deadeye<T extends TargetData> {
4242

4343
static final Logger logger = LoggerFactory.getLogger(Deadeye.class);
44-
private static volatile Link link;
45-
private final NetworkTable cameraTable;
46-
private final String id;
47-
private final DeadeyeJsonAdapter<T> jsonAdapter;
48-
private TargetDataListener<T> targetDataListener;
49-
private T targetData;
44+
private static volatile @Nullable Link link;
45+
private final @NotNull NetworkTable cameraTable;
46+
private final @NotNull String id;
47+
private final @NotNull DeadeyeJsonAdapter<T> jsonAdapter;
48+
private @NotNull TargetDataListener<T> targetDataListener = data -> {
49+
};
50+
private @NotNull T targetData;
5051

5152
/**
5253
* Constructs an instance of {@code Deadeye} and initializes a connection to the associated
@@ -55,11 +56,10 @@ public class Deadeye<T extends TargetData> {
5556
* @param id the camera id, i.e. the Deadeye unit letter followed by the camera number, for
5657
* example "A0".
5758
* @param cls the {@code TargetData} Java class corresponding to the Deadeye pipeline type.
58-
* @throws NullPointerException if the {@code cls} is {@code null}
5959
* @throws IllegalArgumentException if the {@code id} is not a letter followed by a 0-4 digit
6060
* @throws IllegalArgumentException if the {@code cls} is not a valid {@code TargetData} class
6161
*/
62-
public Deadeye(String id, Class<T> cls) {
62+
public Deadeye(@NotNull String id, @NotNull Class<T> cls) {
6363
this(id, cls, NetworkTableInstance.getDefault(), null);
6464
}
6565

@@ -78,13 +78,12 @@ public Deadeye(String id, Class<T> cls) {
7878
* @param linkAddress the IP address the Deadeye daemon should send data to. If null, this client
7979
* will reuse a previously configured address or attempt to automatically
8080
* detect the correct IP address.
81-
* @throws NullPointerException if the {@code cls} is {@code null}
8281
* @throws IllegalArgumentException if the {@code id} is not a letter followed by a 0-4 digit
8382
* @throws IllegalArgumentException if the {@code cls} is not a valid {@code TargetData} class
8483
* @throws IllegalArgumentException if the {@code linkAddress} supplied more than once and does
8584
* not match address already in use
8685
*/
87-
public Deadeye(String id, Class<T> cls, String linkAddress) {
86+
public Deadeye(@NotNull String id, @NotNull Class<T> cls, @Nullable String linkAddress) {
8887
this(id, cls, NetworkTableInstance.getDefault(), linkAddress);
8988
}
9089

@@ -98,11 +97,10 @@ public Deadeye(String id, Class<T> cls, String linkAddress) {
9897
* example "A0".
9998
* @param cls the {@code TargetData} Java class corresponding to the Deadeye pipeline type.
10099
* @param nti the NetworkTables instance to connect through.
101-
* @throws NullPointerException if the {@code cls} or {@code nti} is {@code null}
102100
* @throws IllegalArgumentException if the {@code id} is not a letter followed by a 0-4 digit
103101
* @throws IllegalArgumentException if the {@code cls} is not a valid {@code TargetData} class
104102
*/
105-
public Deadeye(String id, Class<T> cls, NetworkTableInstance nti) {
103+
public Deadeye(@NotNull String id, @NotNull Class<T> cls, @NotNull NetworkTableInstance nti) {
106104
this(id, cls, nti, null);
107105
}
108106

@@ -121,14 +119,15 @@ public Deadeye(String id, Class<T> cls, NetworkTableInstance nti) {
121119
* @param nti the NetworkTables instance to connect through.
122120
* @param linkAddress the IP address the Deadeye daemon should send data to. If null, this client
123121
* will attempt to automatically detect the correct IP address.
124-
* @throws NullPointerException if the {@code cls} or {@code nti} is {@code null}
125122
* @throws IllegalArgumentException if the {@code id} is not a letter followed by a 0-4 digit
126123
* @throws IllegalArgumentException if the {@code cls} is not a valid {@code TargetData} class
127124
* @throws IllegalArgumentException if the {@code linkAddress} supplied more than once and does
128125
* not match address already in use
129126
*/
130127
@SuppressWarnings("unchecked")
131-
public Deadeye(String id, Class<T> cls, NetworkTableInstance nti, String linkAddress) {
128+
public Deadeye(
129+
@NotNull String id, @NotNull Class<T> cls, @NotNull NetworkTableInstance nti,
130+
@Nullable String linkAddress) {
132131
Objects.requireNonNull(cls, "cls must not be null");
133132
Objects.requireNonNull(nti, "nti must not be null");
134133
if (!Pattern.matches("^[A-Za-z][0-4]$", id)) {
@@ -143,6 +142,7 @@ public Deadeye(String id, Class<T> cls, NetworkTableInstance nti, String linkAdd
143142
}
144143
}
145144

145+
Link link = Objects.requireNonNull(Deadeye.link);
146146
if (linkAddress != null && !link.getAddress().equals(linkAddress)) {
147147
throw new IllegalArgumentException(
148148
"supplied linkAddress does not match address already in use");
@@ -191,6 +191,7 @@ static JsonAdapter<Capture> getCaptureJsonAdapter() {
191191
*
192192
* @return the associated {@code TargetDataListener}.
193193
*/
194+
@NotNull
194195
public TargetDataListener<T> getTargetDataListener() {
195196
return targetDataListener;
196197
}
@@ -201,7 +202,7 @@ public TargetDataListener<T> getTargetDataListener() {
201202
*
202203
* @param targetDataListener class to receive target data
203204
*/
204-
public void setTargetDataListener(TargetDataListener<T> targetDataListener) {
205+
public void setTargetDataListener(@NotNull TargetDataListener<T> targetDataListener) {
205206
this.targetDataListener = targetDataListener;
206207
}
207208

@@ -215,16 +216,15 @@ public void setTargetDataListener(TargetDataListener<T> targetDataListener) {
215216
*/
216217
public void handleTargetData(BufferedSource source) throws IOException {
217218
targetData = jsonAdapter.fromJson(source);
218-
if (targetDataListener != null) {
219-
targetDataListener.onTargetData(targetData);
220-
}
219+
targetDataListener.onTargetData(targetData);
221220
}
222221

223222
/**
224223
* Gets the most recent {@code TargetData} received by this {@code Deadeye} instance.
225224
*
226225
* @return the last valid target data update.
227226
*/
227+
@NotNull
228228
public T getTargetData() {
229229
return targetData;
230230
}
@@ -323,7 +323,12 @@ public Capture getCapture() {
323323
return new Capture();
324324
}
325325

326-
Link getLink() {
326+
/**
327+
* Provide Link for testing.
328+
*
329+
* @return the {@code Link} or {@code null} if a Deadeye unit has not been initialized yet
330+
*/
331+
@Nullable Link getLink() {
327332
return link;
328333
}
329334

@@ -356,7 +361,7 @@ public Info(boolean logging, String pipeline, String version) {
356361
}
357362

358363
@Override
359-
public boolean equals(Object o) {
364+
public boolean equals(@Nullable Object o) {
360365
if (this == o) {
361366
return true;
362367
}
@@ -375,7 +380,7 @@ public int hashCode() {
375380
}
376381

377382
@Override
378-
public String toString() {
383+
public @NotNull String toString() {
379384
return "Info{"
380385
+ "logging="
381386
+ logging
@@ -417,7 +422,9 @@ public static class Capture {
417422
@Json(name = "h")
418423
public final int height;
419424

420-
public Capture() {this("ERROR",0,0,0);}
425+
public Capture() {
426+
this("ERROR", 0, 0, 0);
427+
}
421428

422429
public Capture(String type, int frameRate, int width, int height) {
423430
this.type = type;
@@ -427,7 +434,7 @@ public Capture(String type, int frameRate, int width, int height) {
427434
}
428435

429436
@Override
430-
public boolean equals(Object o) {
437+
public boolean equals(@Nullable Object o) {
431438
if (this == o) {
432439
return true;
433440
}
@@ -445,7 +452,7 @@ public int hashCode() {
445452
}
446453

447454
@Override
448-
public String toString() {
455+
public @NotNull String toString() {
449456
return "Capture{" +
450457
"type='" + type + '\'' +
451458
", frameRate=" + frameRate +

client/src/main/java/org/strykeforce/deadeye/DeadeyeJsonAdapter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ public interface DeadeyeJsonAdapter<T extends TargetData> {
1818
* @return a new {@code TargetData} object, initialized with supplied JSON.
1919
* @throws IOException if a deserialization error occurs.
2020
*/
21-
T fromJson(BufferedSource source) throws IOException;
21+
@NotNull T fromJson(@NotNull BufferedSource source) throws IOException;
2222

2323
/**
2424
* Serializes this {@code TargetData} to JSON.
2525
* @param targetData the object to serialize.
2626
* @return this object in JSON format.
2727
* @throws IOException if a serialization error occurs.
2828
*/
29-
String toJson(@NotNull T targetData) throws IOException;
29+
@NotNull String toJson(@NotNull T targetData) throws IOException;
3030
}

client/src/main/java/org/strykeforce/deadeye/Link.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void run() {
9090
*
9191
* @return the configured client address.
9292
*/
93-
public String getAddress() {
93+
String getAddress() {
9494
return address;
9595
}
9696

client/src/main/java/org/strykeforce/deadeye/LinkConfig.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616
import java.util.Objects;
1717
import java.util.stream.Collectors;
1818
import org.jetbrains.annotations.NotNull;
19+
import org.jetbrains.annotations.Nullable;
1920

2021
class LinkConfig {
2122

2223
static final LinkConfig DEFAULT = new LinkConfig("10.27.67.2", 5800, true);
2324
final int port;
2425
final boolean enabled;
25-
final String address;
26+
final @Nullable String address;
2627

27-
LinkConfig(@NotNull String address, int port, boolean enabled) {
28+
LinkConfig(@Nullable String address, int port, boolean enabled) {
2829
this.address = address;
2930
this.port = port;
3031
this.enabled = enabled;
@@ -48,6 +49,7 @@ static LinkConfig getConfig(@NotNull NetworkTable deadeyeTable) {
4849
Link.logger.warn("more than one entry unsupported, using first:\n\t{}", json);
4950
}
5051

52+
// only use first config for now
5153
var config = configs.get(0);
5254
if (config.address == null || config.port == 0 || !config.address.equals(
5355
addressToInetAddress(config.address).getHostAddress())) {
@@ -84,6 +86,7 @@ static List<InetAddress> getSiteLocalAddresses() {
8486
}
8587
}
8688

89+
@NotNull
8790
static InetAddress addressToInetAddress(String address) {
8891
InetAddress inetAddress = null;
8992
var invalid = true;
@@ -110,7 +113,7 @@ static private InetAddress getDefaultInetAddress() {
110113
}
111114
}
112115

113-
LinkConfig withAddress(String address) {
116+
@NotNull LinkConfig withAddress(@NotNull String address) {
114117
return new LinkConfig(address, this.port, this.enabled);
115118
}
116119

@@ -137,7 +140,7 @@ boolean isValid() {
137140
return addressValid && portValid;
138141
}
139142

140-
void save(NetworkTable deadeyeTable) {
143+
void save(@NotNull NetworkTable deadeyeTable) {
141144
JsonAdapter<List<LinkConfig>> jsonAdapter = getConfigJsonAdapter();
142145
deadeyeTable.getEntry(Link.LINK_ENTRY)
143146
.setString(jsonAdapter.toJson(Collections.singletonList(this)));
@@ -152,8 +155,9 @@ public boolean equals(Object o) {
152155
if (o == null || getClass() != o.getClass()) {
153156
return false;
154157
}
155-
LinkConfig config = (LinkConfig) o;
156-
return port == config.port && enabled == config.enabled && address.equals(config.address);
158+
LinkConfig that = (LinkConfig) o;
159+
return port == that.port && enabled == that.enabled && Objects.equals(address,
160+
that.address);
157161
}
158162

159163
@Override
@@ -162,7 +166,7 @@ public int hashCode() {
162166
}
163167

164168
@Override
165-
public String toString() {
169+
public @NotNull String toString() {
166170
return "LinkConfig{" +
167171
"port=" + port +
168172
", enabled=" + enabled +

client/src/main/java/org/strykeforce/deadeye/MinAreaRectTargetData.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import okio.Buffer;
99
import okio.BufferedSource;
1010
import org.jetbrains.annotations.NotNull;
11+
import org.jetbrains.annotations.Nullable;
1112

1213
/**
1314
* A <code>MinAreaRectTargetData</code> represents data returned from a Deadeye
@@ -89,18 +90,19 @@ public MinAreaRectTargetData(
8990
*
9091
* @return the area of the bounding box.
9192
*/
93+
@SuppressWarnings("unused")
9294
public double area() {
9395
return width * height;
9496
}
9597

9698
@SuppressWarnings("rawtypes")
9799
@Override
98-
public DeadeyeJsonAdapter getJsonAdapter() {
100+
public @NotNull DeadeyeJsonAdapter getJsonAdapter() {
99101
return new JsonAdapterImpl();
100102
}
101103

102104
@Override
103-
public boolean equals(Object o) {
105+
public boolean equals(@Nullable Object o) {
104106
if (this == o) {
105107
return true;
106108
}
@@ -126,7 +128,7 @@ public int hashCode() {
126128
}
127129

128130
@Override
129-
public String toString() {
131+
public @NotNull String toString() {
130132
return "MinAreaRectTargetData{"
131133
+ "angle="
132134
+ angle
@@ -161,9 +163,9 @@ private static class JsonAdapterImpl implements DeadeyeJsonAdapter<MinAreaRectTa
161163
private static final JsonReader.Options OPTIONS = JsonReader.Options.of("id", "sn", "v", "d");
162164

163165
@Override
164-
public MinAreaRectTargetData fromJson(BufferedSource source) throws IOException {
166+
public @NotNull MinAreaRectTargetData fromJson(@NotNull BufferedSource source) throws IOException {
165167
JsonReader reader = JsonReader.of(source);
166-
String id = null;
168+
String id = "Z0";
167169
int serial = -1;
168170
boolean valid = false;
169171
double[] data = new double[DATA_LENGTH];
@@ -208,7 +210,7 @@ public MinAreaRectTargetData fromJson(BufferedSource source) throws IOException
208210
}
209211

210212
@Override
211-
public String toJson(@NotNull MinAreaRectTargetData targetData) throws IOException {
213+
public @NotNull String toJson(@NotNull MinAreaRectTargetData targetData) throws IOException {
212214
Buffer buffer = new Buffer();
213215
JsonWriter writer = JsonWriter.of(buffer);
214216
writer.beginObject();

client/src/main/java/org/strykeforce/deadeye/Point.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import java.util.Objects;
44
import org.jetbrains.annotations.NotNull;
5+
import org.jetbrains.annotations.Nullable;
56

67
/**
78
* A point representing a location in (x,y) coordinate space, specified in integer precision.
89
*/
10+
@SuppressWarnings("unused")
911
public final class Point {
1012

1113
/**
@@ -35,7 +37,7 @@ public Point(int x, int y) {
3537
* @param bottomRight the bottom right corner of the bounding box.
3638
* @return the {@code Point} at the center of this bounding box.
3739
*/
38-
public static Point boundingBoxCenterFrom(@NotNull Point topLeft, @NotNull Point bottomRight) {
40+
public static @NotNull Point boundingBoxCenterFrom(@NotNull Point topLeft, @NotNull Point bottomRight) {
3941
// Rect constructor checks for nulls
4042
return new Rect(topLeft, bottomRight, 0).center();
4143
}
@@ -71,7 +73,7 @@ public double distanceTo(@NotNull Point that) {
7173
}
7274

7375
@Override
74-
public boolean equals(Object o) {
76+
public boolean equals(@Nullable Object o) {
7577
if (this == o) {
7678
return true;
7779
}
@@ -88,7 +90,7 @@ public int hashCode() {
8890
}
8991

9092
@Override
91-
public String toString() {
93+
public @NotNull String toString() {
9294
return "(" + x + ", " + y + ")";
9395
}
9496
}

0 commit comments

Comments
 (0)