diff --git a/pom.xml b/pom.xml index 0e3c29ee..ddfc1a38 100644 --- a/pom.xml +++ b/pom.xml @@ -15,9 +15,7 @@ 3.27.7 5.21.0 8.14.0 - - com.bucket4j @@ -70,14 +68,17 @@ brotli4j 1.20.0 - + + org.jspecify + jspecify + 1.0.0 + ch.qos.logback logback-classic 1.5.32 compile - diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 0189e1f3..f4502ea9 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -2,8 +2,8 @@ import org.example.config.AppConfig; import org.example.config.ConfigLoader; +import org.jspecify.annotations.Nullable; -import java.net.Socket; import java.nio.file.Path; public class App { @@ -30,7 +30,7 @@ static int resolvePort(String[] args, int configPort) { return validatePort(configPort, "configuration server.port"); } - static Integer parsePortFromCli(String[] args) { + static @Nullable Integer parsePortFromCli(String[] args) { if (args == null) return null; for (int i = 0; i < args.length; i++) { diff --git a/src/main/java/org/example/config/package-info.java b/src/main/java/org/example/config/package-info.java new file mode 100644 index 00000000..ef22a5c0 --- /dev/null +++ b/src/main/java/org/example/config/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.config; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/example/filter/CompressionFilter.java b/src/main/java/org/example/filter/CompressionFilter.java index f4a89127..415e3744 100644 --- a/src/main/java/org/example/filter/CompressionFilter.java +++ b/src/main/java/org/example/filter/CompressionFilter.java @@ -4,6 +4,7 @@ import org.example.http.HttpResponseBuilder; import org.example.httpparser.HttpRequest; import com.aayushatharva.brotli4j.encoder.Encoder; +import org.jspecify.annotations.Nullable; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -186,7 +187,7 @@ private boolean shouldCompress(String contentType) { baseType.startsWith("text/"); } - private String getHeader(HttpRequest request, String headerName) { + private @Nullable String getHeader(HttpRequest request, String headerName) { Map headers = request.getHeaders(); String value = headers.get(headerName); diff --git a/src/main/java/org/example/filter/IpFilter.java b/src/main/java/org/example/filter/IpFilter.java index e9c877f2..f22c192a 100644 --- a/src/main/java/org/example/filter/IpFilter.java +++ b/src/main/java/org/example/filter/IpFilter.java @@ -3,6 +3,7 @@ import org.example.http.HttpResponseBuilder; import org.example.httpparser.HttpRequest; +import org.jspecify.annotations.Nullable; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -84,7 +85,7 @@ private boolean isIpAllowed(String ip) { * @param ip the IP address * @return the trimmed IP address, or {@code null} if the input is {@code null} */ - private String normalizeIp(String ip) { + private @Nullable String normalizeIp(@Nullable String ip) { return ip == null ? null : ip.trim(); } @@ -92,14 +93,14 @@ public void setMode(FilterMode mode) { this.mode = mode; } - public void addBlockedIp(String ip) { + public void addBlockedIp(@Nullable String ip) { if (ip == null) { throw new IllegalArgumentException("IP address cannot be null"); } blockedIps.add(normalizeIp(ip)); } - public void addAllowedIp(String ip) { + public void addAllowedIp(@Nullable String ip) { if (ip == null) { throw new IllegalArgumentException("IP address cannot be null"); } diff --git a/src/main/java/org/example/filter/LocaleFilter.java b/src/main/java/org/example/filter/LocaleFilter.java new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/org/example/filter/LocaleFilterWithCookie.java b/src/main/java/org/example/filter/LocaleFilterWithCookie.java index 28f452ca..fa1849c9 100644 --- a/src/main/java/org/example/filter/LocaleFilterWithCookie.java +++ b/src/main/java/org/example/filter/LocaleFilterWithCookie.java @@ -2,6 +2,7 @@ import org.example.http.HttpResponseBuilder; import org.example.httpparser.HttpRequest; +import org.jspecify.annotations.Nullable; import java.util.Map; @@ -74,7 +75,7 @@ private String resolveLocale(HttpRequest request) { *

* If the cookie header is missing, blank, or malformed, returns null. */ - private String extractLocaleFromCookie(HttpRequest request) { + private @Nullable String extractLocaleFromCookie(HttpRequest request) { Map headers = request.getHeaders(); if (headers == null) { return null; @@ -111,7 +112,7 @@ private String extractLocaleFromCookie(HttpRequest request) { * If the header is missing, blank, or malformed, returns null. * The first language tag is used and any optional quality value (e.g., ";q=0.9") is stripped. */ - private String extractLocaleFromHeader(HttpRequest request) { + private @Nullable String extractLocaleFromHeader(HttpRequest request) { Map headers = request.getHeaders(); if (headers == null) { return null; diff --git a/src/main/java/org/example/filter/package-info.java b/src/main/java/org/example/filter/package-info.java new file mode 100644 index 00000000..457b18e2 --- /dev/null +++ b/src/main/java/org/example/filter/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.filter; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/example/http/MimeTypeDetector.java b/src/main/java/org/example/http/MimeTypeDetector.java index 9005078a..48a1892e 100644 --- a/src/main/java/org/example/http/MimeTypeDetector.java +++ b/src/main/java/org/example/http/MimeTypeDetector.java @@ -1,5 +1,7 @@ package org.example.http; +import org.jspecify.annotations.Nullable; + import java.util.Map; /** @@ -56,7 +58,7 @@ private MimeTypeDetector() { */ - public static String detectMimeType(String filename) { + public static String detectMimeType(@Nullable String filename) { String octet = "application/octet-stream"; diff --git a/src/main/java/org/example/http/package-info.java b/src/main/java/org/example/http/package-info.java new file mode 100644 index 00000000..af2ca5fb --- /dev/null +++ b/src/main/java/org/example/http/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.http; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/example/httpparser/HttpRequest.java b/src/main/java/org/example/httpparser/HttpRequest.java index 18f0e561..2f467708 100644 --- a/src/main/java/org/example/httpparser/HttpRequest.java +++ b/src/main/java/org/example/httpparser/HttpRequest.java @@ -1,5 +1,7 @@ package org.example.httpparser; +import org.jspecify.annotations.Nullable; + import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -15,14 +17,14 @@ public class HttpRequest { private final String path; private final String version; private final Map headers; - private final String body; + private final @Nullable String body; private final Map attributes = new HashMap<>(); public HttpRequest(String method, String path, String version, Map headers, - String body) { + @Nullable String body) { this.method = method; this.path = path; this.version = version; @@ -38,7 +40,7 @@ public String getVersion() { return version; } public Map getHeaders() { return headers; } - public String getBody() { + public @Nullable String getBody() { return body; } public void setAttribute(String key, Object value) { attributes.put(key, value); diff --git a/src/main/java/org/example/httpparser/package-info.java b/src/main/java/org/example/httpparser/package-info.java new file mode 100644 index 00000000..7e93c6ac --- /dev/null +++ b/src/main/java/org/example/httpparser/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.httpparser; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/example/package-info.java b/src/main/java/org/example/package-info.java new file mode 100644 index 00000000..81843380 --- /dev/null +++ b/src/main/java/org/example/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/example/server/FilterRegistration.java b/src/main/java/org/example/server/FilterRegistration.java index a9578161..ac9687e1 100644 --- a/src/main/java/org/example/server/FilterRegistration.java +++ b/src/main/java/org/example/server/FilterRegistration.java @@ -1,6 +1,7 @@ package org.example.server; import org.example.filter.Filter; +import org.jspecify.annotations.Nullable; import java.util.List; import java.util.Objects; @@ -8,7 +9,7 @@ public record FilterRegistration( Filter filter, int order, - List routePatterns + @Nullable List routePatterns ) { public FilterRegistration { filter = Objects.requireNonNull(filter, "filter must not be null"); diff --git a/src/main/java/org/example/server/package-info.java b/src/main/java/org/example/server/package-info.java new file mode 100644 index 00000000..0b81fd98 --- /dev/null +++ b/src/main/java/org/example/server/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.server; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/config/package-info.java b/src/test/java/org/example/config/package-info.java new file mode 100644 index 00000000..ef22a5c0 --- /dev/null +++ b/src/test/java/org/example/config/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.config; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/filter/package-info.java b/src/test/java/org/example/filter/package-info.java new file mode 100644 index 00000000..457b18e2 --- /dev/null +++ b/src/test/java/org/example/filter/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.filter; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/http/package-info.java b/src/test/java/org/example/http/package-info.java new file mode 100644 index 00000000..af2ca5fb --- /dev/null +++ b/src/test/java/org/example/http/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.http; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/httpparser/HttpParseRequestLineTest.java b/src/test/java/org/example/httpparser/HttpParseRequestLineTest.java index 8ff289f3..cd812e1b 100644 --- a/src/test/java/org/example/httpparser/HttpParseRequestLineTest.java +++ b/src/test/java/org/example/httpparser/HttpParseRequestLineTest.java @@ -6,7 +6,6 @@ import java.io.*; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.*; class HttpParseRequestLineTest { @@ -30,12 +29,6 @@ void testParserWithTestRequestLine() throws IOException { assertThat(httpParseRequestLine.getVersion()).isEqualTo("HTTP/1.1"); } - @Test - void testParserThrowErrorWhenNull(){ - assertThatThrownBy(() -> httpParseRequestLine.setReader(null)).isInstanceOf(NullPointerException.class); - } - - @Test void testParserThrowErrorWhenEmpty(){ InputStream in = new ByteArrayInputStream("".getBytes()); diff --git a/src/test/java/org/example/httpparser/package-info.java b/src/test/java/org/example/httpparser/package-info.java new file mode 100644 index 00000000..7e93c6ac --- /dev/null +++ b/src/test/java/org/example/httpparser/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.httpparser; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/package-info.java b/src/test/java/org/example/package-info.java new file mode 100644 index 00000000..81843380 --- /dev/null +++ b/src/test/java/org/example/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/test/java/org/example/server/package-info.java b/src/test/java/org/example/server/package-info.java new file mode 100644 index 00000000..0b81fd98 --- /dev/null +++ b/src/test/java/org/example/server/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.example.server; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file