Skip to content

Commit 08fffa3

Browse files
committed
refactor: simplify link filtering with helper method
Use streams thraughout and extract replacement logic into a separate method for better readbility
1 parent 7118454 commit 08fffa3

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

application/src/main/java/org/togetherjava/tjbot/features/utils/LinkDetection.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.net.http.HttpRequest;
1010
import java.net.http.HttpResponse;
1111
import java.util.List;
12+
import java.util.Objects;
1213
import java.util.Optional;
1314
import java.util.Set;
1415
import java.util.concurrent.CompletableFuture;
@@ -210,35 +211,35 @@ public static CompletableFuture<Boolean> isLinkBroken(String url) {
210211
* text if no broken links were found
211212
*/
212213

213-
214214
public static CompletableFuture<String> replaceBrokenLinks(String text, String replacement) {
215215
List<String> links = extractLinks(text, DEFAULT_FILTERS);
216216

217217
if (links.isEmpty()) {
218218
return CompletableFuture.completedFuture(text);
219219
}
220220

221-
List<String> distinctLinks = links.stream().distinct().toList();
222-
List<CompletableFuture<Boolean>> brokenCheckFutures =
223-
distinctLinks.stream().map(LinkDetection::isLinkBroken).toList();
221+
// Can't filter yet - we won't know which links are broken until the futures complete
222+
List<CompletableFuture<String>> brokenLinkFutures = links.stream()
223+
.distinct()
224+
.map(link -> isLinkBroken(link)
225+
.thenApply(isBroken -> Boolean.TRUE.equals(isBroken) ? link : null))
226+
.toList();
224227

225-
return CompletableFuture.allOf(brokenCheckFutures.toArray(new CompletableFuture[0]))
226-
.thenApply(_ -> {
227-
List<String> brokenLinks = new java.util.ArrayList<>();
228-
for (int i = 0; i < distinctLinks.size(); i++) {
229-
if (Boolean.TRUE.equals(brokenCheckFutures.get(i).join())) {
230-
brokenLinks.add(distinctLinks.get(i));
231-
}
232-
}
233-
return brokenLinks;
234-
})
235-
.thenApply(brokenLinks -> {
236-
String result = text;
237-
for (String brokenLink : brokenLinks) {
238-
result = result.replace(brokenLink, replacement);
239-
}
240-
return result;
241-
});
228+
return CompletableFuture.allOf(brokenLinkFutures.toArray(CompletableFuture[]::new))
229+
.thenApply(_ -> brokenLinkFutures.stream()
230+
.map(CompletableFuture::join)
231+
.filter(Objects::nonNull)
232+
.toList())
233+
.thenApply(brokenLinks -> replaceLinks(brokenLinks, text, replacement));
234+
}
235+
236+
private static String replaceLinks(List<String> linksToReplace, String text,
237+
String replacement) {
238+
String result = text;
239+
for (String link : linksToReplace) {
240+
result = result.replace(link, replacement);
241+
}
242+
return result;
242243
}
243244

244245
/**
@@ -260,7 +261,8 @@ private static Optional<String> toLink(Url url, Set<LinkFilter> filter) {
260261
// URL escapes, such as "<http://example.com>" should be skipped
261262
return Optional.empty();
262263
}
263-
// Not interested in other schemes, also to filter out matches without scheme.
264+
// Not interested in other schemes, also to filter out matches without scheme (Skip non-HTTP
265+
// schemes)
264266
// It detects a lot of such false-positives in Java snippets
265267
if (filter.contains(LinkFilter.NON_HTTP_SCHEME) && !raw.startsWith("http")) {
266268
return Optional.empty();

0 commit comments

Comments
 (0)