Skip to content

Commit 6c7953f

Browse files
committed
Add NotNull/Nullable annotations.
1 parent d759c6e commit 6c7953f

37 files changed

+464
-214
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ replay_pid*
2727
.gradle/*
2828
.idea/*
2929
.DS_Store
30+
*/build/*

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ allprojects {
2828
implementation("org.mozilla:rhino-engine:1.7.14")
2929
implementation("com.grack:nanojson:1.7")
3030
compileOnly("org.slf4j:slf4j-api:1.7.25")
31+
compileOnly("org.jetbrains:annotations:24.1.0")
3132
}
3233
}

common/src/main/java/dev/lavalink/youtube/CannotBeLoaded.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.lavalink.youtube;
22

3+
import org.jetbrains.annotations.NotNull;
4+
35
public class CannotBeLoaded extends Throwable {
46
// This is a 'cheap' exception used to tell the source manager to stop trying
57
// to load a track as it's unloadable, e.g. if a video doesn't exist/is private etc...
@@ -9,7 +11,7 @@ public class CannotBeLoaded extends Throwable {
911
* in the chain.
1012
* @param original The original exception that triggered this exception.
1113
*/
12-
public CannotBeLoaded(Throwable original) {
14+
public CannotBeLoaded(@NotNull Throwable original) {
1315
super("The URL could not be loaded.", original, false, false);
1416
}
1517
}

common/src/main/java/dev/lavalink/youtube/UrlTools.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
44
import org.apache.http.NameValuePair;
55
import org.apache.http.client.utils.URIBuilder;
6+
import org.jetbrains.annotations.NotNull;
67

78
import java.net.URISyntaxException;
89
import java.util.Map;
@@ -11,7 +12,9 @@
1112
import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON;
1213

1314
public class UrlTools {
14-
public static UrlInfo getUrlInfo(String url, boolean retryValidPart) {
15+
@NotNull
16+
public static UrlInfo getUrlInfo(@NotNull String url,
17+
boolean retryValidPart) {
1518
try {
1619
if (!url.startsWith("http://") && !url.startsWith("https://")) {
1720
url = "https://" + url;
@@ -34,7 +37,8 @@ public static class UrlInfo {
3437
public final String path;
3538
public final Map<String, String> parameters;
3639

37-
private UrlInfo(String path, Map<String, String> parameters) {
40+
private UrlInfo(@NotNull String path,
41+
@NotNull Map<String, String> parameters) {
3842
this.path = path;
3943
this.parameters = parameters;
4044
}

common/src/main/java/dev/lavalink/youtube/YoutubeAudioSourceManager.java

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import dev.lavalink.youtube.track.YoutubeAudioTrack;
2525
import org.apache.http.client.methods.CloseableHttpResponse;
2626
import org.apache.http.client.methods.HttpGet;
27+
import org.jetbrains.annotations.NotNull;
28+
import org.jetbrains.annotations.Nullable;
2729
import org.slf4j.Logger;
2830
import org.slf4j.LoggerFactory;
2931

@@ -39,7 +41,6 @@
3941

4042
@SuppressWarnings("RegExpUnnecessaryNonCapturingGroup")
4143
public class YoutubeAudioSourceManager implements AudioSourceManager {
42-
// TODO: consider adding notnull/nullable annotations
4344
// TODO: connect timeout = 16000ms, read timeout = 8000ms (as observed from scraped youtube config)
4445
// TODO: look at possibly scraping jsUrl from WEB config to save a request
4546
// TODO: search providers use cookieless httpinterfacemanagers. should this do the same?
@@ -58,12 +59,11 @@ public class YoutubeAudioSourceManager implements AudioSourceManager {
5859
private static final Pattern mainDomainPattern = Pattern.compile("^" + PROTOCOL_REGEX + DOMAIN_REGEX + "/.*");
5960
private static final Pattern shortHandPattern = Pattern.compile("^" + PROTOCOL_REGEX + "(?:" + DOMAIN_REGEX + "/(?:live|embed|shorts)|" + SHORT_DOMAIN_REGEX + ")/(?<id>.*)");
6061

62+
protected final HttpInterfaceManager httpInterfaceManager;
63+
protected final boolean allowSearch;
64+
protected final Client[] clients;
6165

62-
protected HttpInterfaceManager httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
63-
protected boolean allowSearch;
64-
protected Client[] clients;
65-
66-
protected SignatureCipherManager cipherManager;
66+
protected final SignatureCipherManager cipherManager;
6767

6868
public YoutubeAudioSourceManager() {
6969
this(true);
@@ -80,7 +80,7 @@ public YoutubeAudioSourceManager(boolean allowSearch) {
8080
* @param clients The clients to use for track loading. They will be queried in
8181
* the order they are provided.
8282
*/
83-
public YoutubeAudioSourceManager(Client... clients) {
83+
public YoutubeAudioSourceManager(@NotNull Client... clients) {
8484
this(true, clients);
8585
}
8686

@@ -92,7 +92,8 @@ public YoutubeAudioSourceManager(Client... clients) {
9292
* @param clients The clients to use for track loading. They will be queried in
9393
* the order they are provided.
9494
*/
95-
public YoutubeAudioSourceManager(boolean allowSearch, Client... clients) {
95+
public YoutubeAudioSourceManager(boolean allowSearch, @NotNull Client... clients) {
96+
this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
9697
this.allowSearch = allowSearch;
9798
this.clients = clients == null ? new Client[0] : clients;
9899
this.cipherManager = new SignatureCipherManager();
@@ -115,7 +116,8 @@ public void setPlaylistPageCount(int count) {
115116
}
116117

117118
@Override
118-
public AudioItem loadItem(AudioPlayerManager manager, AudioReference reference) {
119+
@Nullable
120+
public AudioItem loadItem(@NotNull AudioPlayerManager manager, @NotNull AudioReference reference) {
119121
try {
120122
return loadItemOnce(reference);
121123
} catch (FriendlyException exception) {
@@ -128,11 +130,12 @@ public AudioItem loadItem(AudioPlayerManager manager, AudioReference reference)
128130
}
129131
}
130132

131-
public AudioItem loadItemOnce(AudioReference reference) {
133+
@Nullable
134+
protected AudioItem loadItemOnce(@NotNull AudioReference reference) {
132135
Throwable lastException = null;
133136

134137
try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) {
135-
Router router = getRouter(reference.identifier, httpInterface);
138+
Router router = getRouter(httpInterface, reference.identifier);
136139

137140
if (router == null) {
138141
return null;
@@ -173,7 +176,8 @@ public AudioItem loadItemOnce(AudioReference reference) {
173176
return null;
174177
}
175178

176-
protected Router getRouter(String identifier, HttpInterface httpInterface) {
179+
@Nullable
180+
protected Router getRouter(@NotNull HttpInterface httpInterface, @NotNull String identifier) {
177181
if (identifier.startsWith(SEARCH_PREFIX)) {
178182
if (allowSearch) return (client) -> client.loadSearch(this, httpInterface, identifier.substring(SEARCH_PREFIX.length()).trim());
179183
} else if (identifier.startsWith(MUSIC_SEARCH_PREFIX)) {
@@ -187,7 +191,7 @@ protected Router getRouter(String identifier, HttpInterface httpInterface) {
187191
if ("/watch".equals(urlInfo.path)) {
188192
String videoId = urlInfo.parameters.get("v");
189193

190-
if (videoId != null) return routeFromVideoId(videoId, urlInfo, httpInterface);
194+
if (videoId != null) return routeFromVideoId(httpInterface, videoId, urlInfo);
191195
} else if ("/playlist".equals(urlInfo.path)) {
192196
String playlistId = urlInfo.parameters.get("list");
193197

@@ -201,7 +205,7 @@ protected Router getRouter(String identifier, HttpInterface httpInterface) {
201205
List<URI> redirects = httpInterface.getContext().getRedirectLocations();
202206

203207
if (redirects != null && !redirects.isEmpty()) {
204-
return getRouter(redirects.get(0).toString(), httpInterface);
208+
return getRouter(httpInterface, redirects.get(0).toString());
205209
}
206210

207211
throw new FriendlyException("Unable to process youtube watch_videos link", SUSPICIOUS,
@@ -215,20 +219,23 @@ protected Router getRouter(String identifier, HttpInterface httpInterface) {
215219
Matcher shortHandMatcher = shortHandPattern.matcher(identifier);
216220

217221
if (shortHandMatcher.matches()) {
218-
return routeFromVideoId(shortHandMatcher.group("videoId"), null, httpInterface);
222+
return routeFromVideoId(httpInterface, shortHandMatcher.group("videoId"), null);
219223
}
220224
}
221225
}
222226

223227
return null;
224228
}
225229

226-
protected Router routeFromVideoId(String videoId, UrlInfo urlInfo, HttpInterface httpInterface) {
230+
@Nullable
231+
protected Router routeFromVideoId(@NotNull HttpInterface httpInterface,
232+
@NotNull String videoId,
233+
@Nullable UrlInfo urlInfo) {
227234
String trimmedId = videoId.length() > 11 ? videoId.substring(0, 11) : videoId;
228235

229236
if (!directVideoIdPattern.matcher(trimmedId).matches()) {
230237
return Router.none;
231-
} else if (urlInfo.parameters.containsKey("list")) {
238+
} else if (urlInfo != null && urlInfo.parameters.containsKey("list")) {
232239
String playlistId = urlInfo.parameters.get("list");
233240

234241
if (playlistId.startsWith("RD")) {
@@ -241,10 +248,12 @@ protected Router routeFromVideoId(String videoId, UrlInfo urlInfo, HttpInterface
241248
return (client) -> client.loadVideo(this, httpInterface, trimmedId);
242249
}
243250

251+
@NotNull
244252
public YoutubeAudioTrack buildAudioTrack(AudioTrackInfo trackInfo) {
245253
return new YoutubeAudioTrack(trackInfo, this);
246254
}
247255

256+
@NotNull
248257
public SignatureCipherManager getCipherManager() {
249258
return cipherManager;
250259
}
@@ -254,7 +263,8 @@ public SignatureCipherManager getCipherManager() {
254263
* @param cls The class of the client to return.
255264
* @return The client instance, or null if it's not registered.
256265
*/
257-
public <T extends Client> T getClient(Class<T> cls) {
266+
@Nullable
267+
public <T extends Client> T getClient(@NotNull Class<T> cls) {
258268
for (Client client : clients) {
259269
if (cls.isAssignableFrom(client.getClass())) {
260270
return cls.cast(client);
@@ -264,14 +274,17 @@ public <T extends Client> T getClient(Class<T> cls) {
264274
return null;
265275
}
266276

277+
@NotNull
267278
public Client[] getClients() {
268279
return clients;
269280
}
270281

282+
@NotNull
271283
public HttpInterfaceManager getHttpInterfaceManager() {
272284
return httpInterfaceManager;
273285
}
274286

287+
@NotNull
275288
public HttpInterface getInterface() {
276289
return httpInterfaceManager.getInterface();
277290
}
@@ -287,7 +300,8 @@ public void encodeTrack(AudioTrack track, DataOutput output) {
287300
}
288301

289302
@Override
290-
public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) {
303+
@NotNull
304+
public AudioTrack decodeTrack(@NotNull AudioTrackInfo trackInfo, @NotNull DataInput input) {
291305
return new YoutubeAudioTrack(trackInfo, this);
292306
}
293307

@@ -300,6 +314,7 @@ public void shutdown() {
300314
protected interface Router {
301315
Router none = (unused) -> AudioReference.NO_TRACK;
302316

303-
AudioItem route(Client client) throws CannotBeLoaded, IOException;
317+
@Nullable
318+
AudioItem route(@NotNull Client client) throws CannotBeLoaded, IOException;
304319
}
305320
}

common/src/main/java/dev/lavalink/youtube/cipher/CipherOperation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.lavalink.youtube.cipher;
22

3+
import org.jetbrains.annotations.NotNull;
4+
35
/**
46
* One cipher operation definition.
57
*/
@@ -17,7 +19,7 @@ public class CipherOperation {
1719
* @param type The type of the operation.
1820
* @param parameter The parameter for the operation.
1921
*/
20-
public CipherOperation(CipherOperationType type, int parameter) {
22+
public CipherOperation(@NotNull CipherOperationType type, int parameter) {
2123
this.type = type;
2224
this.parameter = parameter;
2325
}

common/src/main/java/dev/lavalink/youtube/cipher/SignatureCipher.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.lavalink.youtube.cipher;
22

3+
import org.jetbrains.annotations.NotNull;
4+
35
import javax.script.Invocable;
46
import javax.script.ScriptEngine;
57
import javax.script.ScriptException;
@@ -15,7 +17,9 @@ public class SignatureCipher {
1517
public final String scriptTimestamp;
1618
public final String rawScript;
1719

18-
public SignatureCipher(String nFunction, String timestamp, String rawScript) {
20+
public SignatureCipher(@NotNull String nFunction,
21+
@NotNull String timestamp,
22+
@NotNull String rawScript) {
1923
this.nFunction = nFunction;
2024
this.scriptTimestamp = timestamp;
2125
this.rawScript = rawScript;
@@ -25,7 +29,7 @@ public SignatureCipher(String nFunction, String timestamp, String rawScript) {
2529
* @param text Text to apply the cipher on
2630
* @return The result of the cipher on the input text
2731
*/
28-
public String apply(String text) {
32+
public String apply(@NotNull String text) {
2933
StringBuilder builder = new StringBuilder(text);
3034

3135
for (CipherOperation operation : operations) {
@@ -56,7 +60,7 @@ public String apply(String text) {
5660
* @param scriptEngine JavaScript engine to execute function
5761
* @return The result of the n parameter transformation
5862
*/
59-
public String transform(String text, ScriptEngine scriptEngine) throws ScriptException, NoSuchMethodException {
63+
public String transform(@NotNull String text, @NotNull ScriptEngine scriptEngine) throws ScriptException, NoSuchMethodException {
6064
String transformed;
6165

6266
scriptEngine.eval("n=" + nFunction);
@@ -68,7 +72,7 @@ public String transform(String text, ScriptEngine scriptEngine) throws ScriptExc
6872
/**
6973
* @param operation The operation to add to this cipher
7074
*/
71-
public void addOperation(CipherOperation operation) {
75+
public void addOperation(@NotNull CipherOperation operation) {
7276
operations.add(operation);
7377
}
7478

0 commit comments

Comments
 (0)