From a7f602e2ad900f3d217e77aa81b279a85dbb35f9 Mon Sep 17 00:00:00 2001 From: MD <1917406+mdcfe@users.noreply.github.com> Date: Tue, 7 Jun 2022 14:04:46 -0400 Subject: [PATCH] Remove commons-lang3 dependency `commons-lang3` is scheduled for removal by Spigot. This commit reimplements the methods we use from StringUtils in StringUtil, and replaces NumberUtils.isDigits(String) with NumberUtil.isLong(String). --- .../essentials/items/LegacyItemDb.java | 8 +-- .../earth2me/essentials/utils/StringUtil.java | 49 +++++++++++++++++++ .../essentials/utils/StringUtilTest.java | 48 ++++++++++++++++++ EssentialsDiscord/build.gradle | 3 -- .../discord/JDADiscordService.java | 3 +- .../discord/listeners/DiscordListener.java | 4 +- 6 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 Essentials/src/test/java/com/earth2me/essentials/utils/StringUtilTest.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/items/LegacyItemDb.java b/Essentials/src/main/java/com/earth2me/essentials/items/LegacyItemDb.java index e0de483b3..5698fc9d7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/items/LegacyItemDb.java +++ b/Essentials/src/main/java/com/earth2me/essentials/items/LegacyItemDb.java @@ -3,9 +3,9 @@ package com.earth2me.essentials.items; import com.earth2me.essentials.ManagedFile; import com.earth2me.essentials.utils.EnumUtil; import com.earth2me.essentials.utils.NumberUtil; +import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.VersionUtil; import net.ess3.api.IEssentials; -import org.apache.commons.lang.StringUtils; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; @@ -68,10 +68,10 @@ public class LegacyItemDb extends AbstractItemDb { final Matcher matcher = csvSplitPattern.matcher(line); while (matcher.find()) { String match = matcher.group(1); - if (StringUtils.stripToNull(match) == null) { + if (StringUtil.stripToNull(match) == null) { continue; } - match = StringUtils.strip(match.trim(), "\""); + match = StringUtil.strip(match.trim(), "\""); switch (col) { case 0: itemName = match.toLowerCase(Locale.ENGLISH); @@ -83,7 +83,7 @@ public class LegacyItemDb extends AbstractItemDb { data = Short.parseShort(match); break; case 3: - nbt = StringUtils.stripToNull(match); + nbt = StringUtil.stripToNull(match); break; default: continue; diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/StringUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/StringUtil.java index 1598de680..b9ba37df0 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/StringUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/StringUtil.java @@ -1,8 +1,12 @@ package com.earth2me.essentials.utils; +import com.google.common.primitives.Chars; + import java.util.Collection; +import java.util.List; import java.util.Locale; import java.util.UUID; +import java.util.function.Function; import java.util.regex.Pattern; public final class StringUtil { @@ -85,4 +89,49 @@ public final class StringUtil { return null; } + + public static String abbreviate(final String input, final int length) { + if (input == null) return null; + if (length < 4) throw new IllegalArgumentException("Invalid length " + length); + + if (input.length() <= length) return input; + return input.substring(0, length - 3) + "..."; + } + + // Replacement for org.apache.commons.lang3.StringUtils.stripToNull(String) + public static String stripToNull(final String input) { + if (input == null) return null; + + final String result = strip(input); + return result.isEmpty() ? null : result; + } + + // Replacement for org.apache.commons.lang3.StringUtils.strip(String) + public static String strip(final String input) { + return strip(input, Character::isWhitespace); + } + + // Replacement for org.apache.commons.lang3.StringUtils.strip(String, String) + public static String strip(final String input, final String stripChars) { + if (stripChars == null) return strip(input); + final List toStrip = Chars.asList(stripChars.toCharArray()); + return strip(input, toStrip::contains); + } + + public static String strip(final String input, Function shouldStrip) { + if (input == null) return null; + + int startIndex = 0; + int endIndex = input.length(); + + for (; startIndex < endIndex; startIndex++) { + if (!shouldStrip.apply(input.charAt(startIndex))) break; + } + + for (; endIndex > startIndex; endIndex--) { + if (!shouldStrip.apply(input.charAt(endIndex - 1))) break; + } + + return input.substring(startIndex, endIndex); + } } diff --git a/Essentials/src/test/java/com/earth2me/essentials/utils/StringUtilTest.java b/Essentials/src/test/java/com/earth2me/essentials/utils/StringUtilTest.java new file mode 100644 index 000000000..e4b0cde74 --- /dev/null +++ b/Essentials/src/test/java/com/earth2me/essentials/utils/StringUtilTest.java @@ -0,0 +1,48 @@ +package com.earth2me.essentials.utils; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class StringUtilTest { + static final String ABBREVIATE = "The quick brown fox jumps over the lazy dog"; + static final String STRIP_1 = " \"JRoy\" "; + static final String STRIP_2 = "mdcfe"; + static final String STRIP_3 = "\" \""; + static final String STRIP_4 = " "; + + @Test + public void testAbbreviate() { + assertEquals("The quick brown fox jumps over the lazy dog", StringUtil.abbreviate(ABBREVIATE, ABBREVIATE.length() + 5), "Should not abbreviate when input string shorter than length"); + assertEquals("The quick brown fox jumps over the lazy dog", StringUtil.abbreviate(ABBREVIATE, ABBREVIATE.length()), "Should not abbreviate when input string equal to length"); + assertEquals("The quick brown fox jumps over the laz...", StringUtil.abbreviate(ABBREVIATE, ABBREVIATE.length() - 2), "Should abbreviate when input string longer than length"); + assertEquals("T...", StringUtil.abbreviate(ABBREVIATE, 4), "Should abbreviate to single letter"); + assertEquals("", StringUtil.abbreviate("", 4), "Should return empty string"); + assertThrows(IllegalArgumentException.class, () -> StringUtil.abbreviate(ABBREVIATE, 3), "Should throw exception when length is less than 4"); + assertNull(StringUtil.abbreviate(null, 10), "Should return null when input is null"); + } + + @Test + public void testStrip() { + assertEquals("\"JRoy\"", StringUtil.strip(STRIP_1), "Should strip whitespace"); + assertEquals("", StringUtil.strip(STRIP_4), "Should strip whitespace to empty string"); + assertEquals(STRIP_2, StringUtil.strip(STRIP_2), "Should not strip non-whitespace"); + + assertEquals("Roy", StringUtil.strip(STRIP_1, " \"J"), "Should strip characters"); + assertEquals(" \"JRoy\" ", StringUtil.strip(STRIP_1, "abc"), "Should not strip any characters"); + assertEquals(" ", StringUtil.strip(STRIP_3, "\""), "Should strip characters only"); + + assertEquals("", StringUtil.strip(STRIP_1, c -> true), "Should strip all characters to empty string"); + assertEquals(STRIP_1, StringUtil.strip(STRIP_1, c -> false), "Should not strip any characters"); + } + + @Test + public void testStripToNull() { + assertEquals("\"JRoy\"", StringUtil.stripToNull(STRIP_1), "Should strip whitespace"); + assertNotNull(StringUtil.stripToNull(STRIP_3), "Should not strip string to null"); + assertNull(StringUtil.stripToNull(STRIP_4), "Should strip whitespace-only string to null"); + } +} diff --git a/EssentialsDiscord/build.gradle b/EssentialsDiscord/build.gradle index 86a0f7094..9a8e7fe1f 100644 --- a/EssentialsDiscord/build.gradle +++ b/EssentialsDiscord/build.gradle @@ -54,7 +54,4 @@ shadowJar { // discord-webhooks relocate 'club.minnced.discord.webhook', 'net.essentialsx.dep.club.minnced.discord.webhook' - - // Lang3 from Main Module - relocate 'org.apache.commons.lang3', 'com.earth2me.essentials.libs.commons.lang3' } diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java index 5a0dfe87d..bc700670d 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java @@ -38,7 +38,6 @@ import net.essentialsx.discord.listeners.DiscordListener; import net.essentialsx.discord.util.ConsoleInjector; import net.essentialsx.discord.util.DiscordUtil; import net.essentialsx.discord.util.MessageUtil; -import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; @@ -247,7 +246,7 @@ public class JDADiscordService implements DiscordService, IEssentialsModule { @Override public void sendMessage(MessageType type, String message, boolean allowGroupMentions) { - if (!registeredTypes.containsKey(type.getKey()) && !NumberUtils.isDigits(type.getKey())) { + if (!registeredTypes.containsKey(type.getKey()) && !NumberUtil.isLong(type.getKey())) { logger.warning("Sending message to channel \"" + type.getKey() + "\" which is an unregistered type! If you are a plugin author, you should be registering your MessageType before using them."); } final DiscordMessageEvent event = new DiscordMessageEvent(type, FormatUtil.stripFormat(message), allowGroupMentions); diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java index 616888c66..bc227f8df 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java @@ -1,6 +1,7 @@ package net.essentialsx.discord.listeners; import com.earth2me.essentials.utils.FormatUtil; +import com.earth2me.essentials.utils.StringUtil; import com.vdurmont.emoji.EmojiParser; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; @@ -14,7 +15,6 @@ import net.essentialsx.discord.interactions.InteractionChannelImpl; import net.essentialsx.discord.interactions.InteractionMemberImpl; import net.essentialsx.discord.util.DiscordUtil; import net.essentialsx.discord.util.MessageUtil; -import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; @@ -76,7 +76,7 @@ public class DiscordListener extends ListenerAdapter { } // Strip message - final String strippedMessage = StringUtils.abbreviate( + final String strippedMessage = StringUtil.abbreviate( messageBuilder.toString() .replace(plugin.getSettings().isChatFilterNewlines() ? '\n' : ' ', ' ') .trim(), plugin.getSettings().getChatDiscordMaxLength());