From 1219e0d7b00fdb1a92cdad1d838269dc55122dde Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Thu, 31 Mar 2022 16:31:13 -0700 Subject: [PATCH] InternalUtils: replace Guava Joiner and Splitter with native JDK equivalent Also deprecate the old Joiner and Splitter related members of Utils. --- .../org/bitcoinj/core/AddressV1Message.java | 4 +- .../org/bitcoinj/core/AddressV2Message.java | 4 +- .../main/java/org/bitcoinj/core/Block.java | 4 +- .../java/org/bitcoinj/core/BlockLocator.java | 4 +- .../bitcoinj/core/TransactionBroadcast.java | 4 +- .../org/bitcoinj/core/TransactionInput.java | 5 +- .../org/bitcoinj/core/TransactionWitness.java | 3 +- .../main/java/org/bitcoinj/core/Utils.java | 17 +++- .../org/bitcoinj/core/VersionMessage.java | 4 +- .../bitcoinj/core/internal/InternalUtils.java | 96 +++++++++++++++++++ .../main/java/org/bitcoinj/crypto/HDPath.java | 11 ++- .../org/bitcoinj/crypto/MnemonicCode.java | 3 +- .../java/org/bitcoinj/crypto/X509Utils.java | 6 +- .../main/java/org/bitcoinj/script/Script.java | 3 +- .../wallet/DeterministicKeyChain.java | 3 +- .../bitcoinj/wallet/DeterministicSeed.java | 6 +- .../java/org/bitcoinj/crypto/BIP32Test.java | 6 +- .../org/bitcoinj/crypto/MnemonicCodeTest.java | 2 +- .../crypto/MnemonicCodeVectorsTest.java | 4 +- .../examples/BackupToMnemonicSeed.java | 4 +- .../WalletSettingsController.java | 9 +- .../org/bitcoinj/wallettool/WalletTool.java | 14 ++- 22 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 core/src/main/java/org/bitcoinj/core/internal/InternalUtils.java diff --git a/core/src/main/java/org/bitcoinj/core/AddressV1Message.java b/core/src/main/java/org/bitcoinj/core/AddressV1Message.java index 0ca6e6c85..525ab5b3f 100644 --- a/core/src/main/java/org/bitcoinj/core/AddressV1Message.java +++ b/core/src/main/java/org/bitcoinj/core/AddressV1Message.java @@ -17,6 +17,8 @@ package org.bitcoinj.core; +import org.bitcoinj.core.internal.InternalUtils; + import java.util.ArrayList; /** @@ -92,6 +94,6 @@ public class AddressV1Message extends AddressMessage { @Override public String toString() { - return "addr: " + Utils.SPACE_JOINER.join(addresses); + return "addr: " + InternalUtils.SPACE_JOINER.join(addresses); } } diff --git a/core/src/main/java/org/bitcoinj/core/AddressV2Message.java b/core/src/main/java/org/bitcoinj/core/AddressV2Message.java index 7b214287b..df39c2e05 100644 --- a/core/src/main/java/org/bitcoinj/core/AddressV2Message.java +++ b/core/src/main/java/org/bitcoinj/core/AddressV2Message.java @@ -16,6 +16,8 @@ package org.bitcoinj.core; +import org.bitcoinj.core.internal.InternalUtils; + import java.util.ArrayList; /** @@ -89,6 +91,6 @@ public class AddressV2Message extends AddressMessage { @Override public String toString() { - return "addrv2: " + Utils.SPACE_JOINER.join(addresses); + return "addrv2: " + InternalUtils.SPACE_JOINER.join(addresses); } } diff --git a/core/src/main/java/org/bitcoinj/core/Block.java b/core/src/main/java/org/bitcoinj/core/Block.java index a827d96d0..d91576ea4 100644 --- a/core/src/main/java/org/bitcoinj/core/Block.java +++ b/core/src/main/java/org/bitcoinj/core/Block.java @@ -19,6 +19,7 @@ package org.bitcoinj.core; import com.google.common.annotations.*; import com.google.common.base.*; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.params.AbstractBitcoinNetParams; import org.bitcoinj.script.*; import org.slf4j.*; @@ -494,8 +495,7 @@ public class Block extends Message { s.append(" block: \n"); s.append(" hash: ").append(getHashAsString()).append('\n'); s.append(" version: ").append(version); - String bips = Joiner.on(", ").skipNulls().join(isBIP34() ? "BIP34" : null, isBIP66() ? "BIP66" : null, - isBIP65() ? "BIP65" : null); + String bips = InternalUtils.commaJoin(isBIP34() ? "BIP34" : null, isBIP66() ? "BIP66" : null, isBIP65() ? "BIP65" : null); if (!bips.isEmpty()) s.append(" (").append(bips).append(')'); s.append('\n'); diff --git a/core/src/main/java/org/bitcoinj/core/BlockLocator.java b/core/src/main/java/org/bitcoinj/core/BlockLocator.java index a075b93fb..85edb78b1 100644 --- a/core/src/main/java/org/bitcoinj/core/BlockLocator.java +++ b/core/src/main/java/org/bitcoinj/core/BlockLocator.java @@ -16,6 +16,8 @@ package org.bitcoinj.core; +import org.bitcoinj.core.internal.InternalUtils; + import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -75,7 +77,7 @@ public final class BlockLocator { @Override public String toString() { - return "Block locator with " + size() + " blocks\n " + Utils.SPACE_JOINER.join(hashes); + return "Block locator with " + size() + " blocks\n " + InternalUtils.SPACE_JOINER.join(hashes); } @Override diff --git a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java index 4303276d6..5bf5684bf 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java @@ -17,8 +17,8 @@ package org.bitcoinj.core; import com.google.common.annotations.*; -import com.google.common.base.*; import com.google.common.util.concurrent.Uninterruptibles; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.utils.*; import org.bitcoinj.wallet.Wallet; import org.slf4j.*; @@ -156,7 +156,7 @@ public class TransactionBroadcast { Collections.shuffle(peers, random); peers = peers.subList(0, numToBroadcastTo); log.info("broadcastTransaction: We have {} peers, adding {} to the memory pool", numConnected, tx.getTxId()); - log.info("Sending to {} peers, will wait for {}, sending to: {}", numToBroadcastTo, numWaitingFor, Joiner.on(",").join(peers)); + log.info("Sending to {} peers, will wait for {}, sending to: {}", numToBroadcastTo, numWaitingFor, InternalUtils.joiner(",").join(peers)); for (final Peer peer : peers) { try { CompletableFuture future = peer.sendMessage(tx); diff --git a/core/src/main/java/org/bitcoinj/core/TransactionInput.java b/core/src/main/java/org/bitcoinj/core/TransactionInput.java index e3dd05779..9ce0389de 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionInput.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionInput.java @@ -17,14 +17,13 @@ package org.bitcoinj.core; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptException; import org.bitcoinj.wallet.DefaultRiskAnalysis; import org.bitcoinj.wallet.KeyBag; import org.bitcoinj.wallet.RedeemData; -import com.google.common.base.Joiner; - import javax.annotation.Nullable; import java.io.IOException; import java.io.OutputStream; @@ -539,7 +538,7 @@ public class TransactionInput extends ChildMessage { s.append(": COINBASE"); } else { s.append(" for [").append(outpoint).append("]: ").append(getScriptSig()); - String flags = Joiner.on(", ").skipNulls().join(hasWitness() ? "witness" : null, + String flags = InternalUtils.commaJoin(hasWitness() ? "witness" : null, hasSequence() ? "sequence: " + Long.toHexString(sequence) : null, isOptInFullRBF() ? "opts into full RBF" : null); if (!flags.isEmpty()) diff --git a/core/src/main/java/org/bitcoinj/core/TransactionWitness.java b/core/src/main/java/org/bitcoinj/core/TransactionWitness.java index e5898a471..7ae54c08d 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionWitness.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionWitness.java @@ -24,6 +24,7 @@ import java.util.List; import javax.annotation.Nullable; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.crypto.TransactionSignature; import org.bitcoinj.script.Script; @@ -97,7 +98,7 @@ public class TransactionWitness { stringPushes.add(Utils.HEX.encode(push)); } } - return Utils.SPACE_JOINER.join(stringPushes); + return InternalUtils.SPACE_JOINER.join(stringPushes); } @Override diff --git a/core/src/main/java/org/bitcoinj/core/Utils.java b/core/src/main/java/org/bitcoinj/core/Utils.java index bdc0717b5..9e68790b7 100644 --- a/core/src/main/java/org/bitcoinj/core/Utils.java +++ b/core/src/main/java/org/bitcoinj/core/Utils.java @@ -30,6 +30,7 @@ import java.util.Locale; import java.util.TimeZone; import java.util.regex.Pattern; +import org.bitcoinj.core.internal.InternalUtils; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,10 +48,20 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup */ public class Utils { - /** Joiner for concatenating words with a space inbetween. */ + /** + * Joiner for concatenating words with a space inbetween. + * @deprecated Use @link java.util.StringJoiner} or a direct Guava dependency + */ + @Deprecated public static final Joiner SPACE_JOINER = Joiner.on(" "); - /** Splitter for splitting words on whitespaces. */ + + /** + * Splitter for splitting words on whitespaces. + * @deprecated Use {@link java.lang.String#split(String)} or a direct Guava dependency + */ + @Deprecated public static final Splitter WHITESPACE_SPLITTER = Splitter.on(Pattern.compile("\\s+")); + /** Hex encoding used throughout the framework. Use with HEX.encode(byte[]) or HEX.decode(CharSequence). */ public static final BaseEncoding HEX = BaseEncoding.base16().lowerCase(); @@ -550,6 +561,6 @@ public class Utils { List parts = new ArrayList<>(stack.size()); for (byte[] push : stack) parts.add('[' + HEX.encode(push) + ']'); - return SPACE_JOINER.join(parts); + return InternalUtils.SPACE_JOINER.join(parts); } } diff --git a/core/src/main/java/org/bitcoinj/core/VersionMessage.java b/core/src/main/java/org/bitcoinj/core/VersionMessage.java index dadaefb9d..f5ce3b402 100644 --- a/core/src/main/java/org/bitcoinj/core/VersionMessage.java +++ b/core/src/main/java/org/bitcoinj/core/VersionMessage.java @@ -16,8 +16,8 @@ package org.bitcoinj.core; -import com.google.common.base.Joiner; import com.google.common.net.InetAddresses; +import org.bitcoinj.core.internal.InternalUtils; import javax.annotation.Nullable; import java.io.IOException; @@ -323,6 +323,6 @@ public class VersionMessage extends Message { } if (services != 0) strings.add("remaining: " + Long.toBinaryString(services)); - return Joiner.on(", ").join(strings); + return InternalUtils.joiner(", ").join(strings); } } diff --git a/core/src/main/java/org/bitcoinj/core/internal/InternalUtils.java b/core/src/main/java/org/bitcoinj/core/internal/InternalUtils.java new file mode 100644 index 000000000..2825c33f1 --- /dev/null +++ b/core/src/main/java/org/bitcoinj/core/internal/InternalUtils.java @@ -0,0 +1,96 @@ +/* + * Copyright by the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoinj.core.internal; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Utilities for internal use only. + */ +public class InternalUtils { + + /** + * A functional interface for joining {@link String}s or {@code Object}s via {@link Object#toString()} using + * a pre-configured delimiter. + *

+ * In previous versions of bitcoinj this functionality was provided by Guava's {@code Joiner}. + */ + @FunctionalInterface + public interface Joiner { + /** + * @param objects A list of objects to join (after calling {@link Object#toString()}) + * The components joined into a single {@code String} separated by the pre-configured delimiter. + */ + String join(List objects); + } + + /** + * A functional interface for splitting {@link String}s using a pre-configured regular expression. + *

+ * In previous versions of bitcoinj this functionality was provided by Guava's {@code Splitter}. + */ + @FunctionalInterface + public interface Splitter { + /** + * @param string The {@code String} to split + * @return A list of split {@code String components} + */ + List splitToList(String string); + } + + /** + * Return a lambda for joining {@code String}s or {@code Object}s via {@link Object#toString()}. + * @param delimiter The delimiter used to join the {@code String} components + * @return A {@code Joiner} (lambda) instance + */ + public static Joiner joiner(String delimiter) { + return list -> list.stream() + .map(Object::toString) + .collect(Collectors.joining(delimiter)); + } + + /** + * Return a lambda for splitting a string into components + * @param regex regular expression used to split components + * @return A {@code Splitter} (lambda) instance + */ + public static Splitter splitter(String regex) { + return s -> Arrays.asList(s.split(regex)); + } + + /** + * A {@link Joiner} for joining strings into a single string delimited by a space character. + */ + public static final Joiner SPACE_JOINER = joiner(" "); + + /** + * A {@link Splitter} for splitting a string into components by whitespace. + */ + public static final Splitter WHITESPACE_SPLITTER = splitter("\\s+"); + + /** + * Join strings with ", " skipping nulls + * @param strings varargs strings + * @return A joined string + */ + public static String commaJoin(String... strings) { + return Arrays.stream(strings).filter(Objects::nonNull).collect(Collectors.joining(", ")); + } +} diff --git a/core/src/main/java/org/bitcoinj/crypto/HDPath.java b/core/src/main/java/org/bitcoinj/crypto/HDPath.java index ff71ad43e..0eea05990 100644 --- a/core/src/main/java/org/bitcoinj/crypto/HDPath.java +++ b/core/src/main/java/org/bitcoinj/crypto/HDPath.java @@ -16,15 +16,16 @@ package org.bitcoinj.crypto; -import com.google.common.base.Splitter; +import org.bitcoinj.core.internal.InternalUtils; import javax.annotation.Nonnull; import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * HD Key derivation path. {@code HDPath} can be used to represent a full path or a relative path. @@ -45,7 +46,9 @@ public class HDPath extends AbstractList { private static final char PREFIX_PRIVATE = 'm'; private static final char PREFIX_PUBLIC = 'M'; private static final char SEPARATOR = '/'; - private static final Splitter SEPARATOR_SPLITTER = Splitter.on(SEPARATOR).trimResults(); + private static final InternalUtils.Splitter SEPARATOR_SPLITTER = s -> Stream.of(s.split("/")) + .map(String::trim) + .collect(Collectors.toList()); protected final boolean hasPrivateKey; protected final List unmodifiableList; @@ -155,7 +158,7 @@ public class HDPath extends AbstractList { * Where a letter "H" means hardened key. Spaces are ignored. */ public static HDPath parsePath(@Nonnull String path) { - List parsedNodes = new LinkedList<>(SEPARATOR_SPLITTER.splitToList(path)); + List parsedNodes = SEPARATOR_SPLITTER.splitToList(path); boolean hasPrivateKey = false; if (!parsedNodes.isEmpty()) { final String firstNode = parsedNodes.get(0); diff --git a/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java b/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java index 53b62e108..af20eabbe 100644 --- a/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java +++ b/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java @@ -19,6 +19,7 @@ package org.bitcoinj.crypto; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Utils; +import org.bitcoinj.core.internal.InternalUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -130,7 +131,7 @@ public class MnemonicCode { // used as a pseudo-random function. Desired length of the // derived key is 512 bits (= 64 bytes). // - String pass = Utils.SPACE_JOINER.join(words); + String pass = InternalUtils.SPACE_JOINER.join(words); String salt = "mnemonic" + passphrase; final Stopwatch watch = Stopwatch.createStarted(); diff --git a/core/src/main/java/org/bitcoinj/crypto/X509Utils.java b/core/src/main/java/org/bitcoinj/crypto/X509Utils.java index a07f5e760..ca6226046 100644 --- a/core/src/main/java/org/bitcoinj/crypto/X509Utils.java +++ b/core/src/main/java/org/bitcoinj/crypto/X509Utils.java @@ -16,7 +16,6 @@ package org.bitcoinj.crypto; -import com.google.common.base.Joiner; import org.bitcoinj.protocols.payments.PaymentSession; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1String; @@ -36,6 +35,9 @@ import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * X509Utils provides tools for working with X.509 certificates and keystores, as used in the BIP 70 payment protocol. @@ -78,7 +80,7 @@ public class X509Utils { } if (org != null) { - return withLocation ? Joiner.on(", ").skipNulls().join(org, location, country) : org; + return withLocation ? Stream.of(org, location, country).filter(Objects::nonNull).collect(Collectors.joining()) : org; } else if (commonName != null) { return commonName; } else { diff --git a/core/src/main/java/org/bitcoinj/script/Script.java b/core/src/main/java/org/bitcoinj/script/Script.java index dd4a934ca..8eac9c738 100644 --- a/core/src/main/java/org/bitcoinj/script/Script.java +++ b/core/src/main/java/org/bitcoinj/script/Script.java @@ -20,6 +20,7 @@ package org.bitcoinj.script; import org.bitcoinj.core.*; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.crypto.TransactionSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -148,7 +149,7 @@ public class Script { @Override public String toString() { if (!chunks.isEmpty()) - return Utils.SPACE_JOINER.join(chunks); + return InternalUtils.SPACE_JOINER.join(chunks); else return ""; } diff --git a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java index 8b971b4b2..de9c2f12b 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java @@ -20,6 +20,7 @@ import org.bitcoinj.core.BloomFilter; import org.bitcoinj.core.ECKey; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Utils; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.crypto.*; import org.bitcoinj.script.Script; import org.bitcoinj.utils.ListenerRegistration; @@ -1390,7 +1391,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { ? seed.decrypt(getKeyCrypter(), DEFAULT_PASSPHRASE_FOR_MNEMONIC, aesKey) : seed; final List words = decryptedSeed.getMnemonicCode(); - builder.append("Seed as words: ").append(Utils.SPACE_JOINER.join(words)).append('\n'); + builder.append("Seed as words: ").append(InternalUtils.SPACE_JOINER.join(words)).append('\n'); builder.append("Seed as hex: ").append(decryptedSeed.toHexString()).append('\n'); } else { if (seed.isEncrypted()) diff --git a/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java b/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java index 6b858c4d1..7a8983f6a 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java +++ b/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java @@ -18,11 +18,11 @@ package org.bitcoinj.wallet; import org.bitcoinj.core.Utils; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.crypto.*; import com.google.common.base.MoreObjects; import java.util.Objects; -import com.google.common.base.Splitter; import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; @@ -250,7 +250,7 @@ public class DeterministicSeed implements EncryptableItem { /** Get the mnemonic code as string, or null if unknown. */ @Nullable public String getMnemonicString() { - return mnemonicCode != null ? Utils.SPACE_JOINER.join(mnemonicCode) : null; + return mnemonicCode != null ? InternalUtils.SPACE_JOINER.join(mnemonicCode) : null; } private static List decodeMnemonicCode(byte[] mnemonicCode) { @@ -258,6 +258,6 @@ public class DeterministicSeed implements EncryptableItem { } private static List decodeMnemonicCode(String mnemonicCode) { - return Splitter.on(" ").splitToList(mnemonicCode); + return InternalUtils.WHITESPACE_SPLITTER.splitToList(mnemonicCode); } } diff --git a/core/src/test/java/org/bitcoinj/crypto/BIP32Test.java b/core/src/test/java/org/bitcoinj/crypto/BIP32Test.java index 1a2da3604..9775ee2f6 100644 --- a/core/src/test/java/org/bitcoinj/crypto/BIP32Test.java +++ b/core/src/test/java/org/bitcoinj/crypto/BIP32Test.java @@ -18,10 +18,8 @@ package org.bitcoinj.crypto; import org.bitcoinj.core.Base58; -import com.google.common.base.Functions; -import com.google.common.base.Joiner; -import com.google.common.collect.Iterables; import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.params.MainNetParams; import org.junit.Test; import org.slf4j.Logger; @@ -219,7 +217,7 @@ public class BIP32Test { } String getPathDescription() { - return "m/" + Joiner.on("/").join(Iterables.transform(Arrays.asList(path), Functions.toStringFunction())); + return "m/" + InternalUtils.joiner("/").join(Arrays.asList(path)); } } } diff --git a/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeTest.java b/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeTest.java index ffbd8a023..464100136 100644 --- a/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeTest.java @@ -25,7 +25,7 @@ import org.junit.Before; import org.junit.Test; import static org.bitcoinj.core.Utils.HEX; -import static org.bitcoinj.core.Utils.WHITESPACE_SPLITTER; +import static org.bitcoinj.core.internal.InternalUtils.WHITESPACE_SPLITTER; /** * Test the various guard clauses of {@link MnemonicCode}. diff --git a/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeVectorsTest.java b/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeVectorsTest.java index c84d52243..760756684 100644 --- a/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeVectorsTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/MnemonicCodeVectorsTest.java @@ -28,8 +28,8 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import static org.bitcoinj.core.Utils.HEX; -import static org.bitcoinj.core.Utils.SPACE_JOINER; -import static org.bitcoinj.core.Utils.WHITESPACE_SPLITTER; +import static org.bitcoinj.core.internal.InternalUtils.SPACE_JOINER; +import static org.bitcoinj.core.internal.InternalUtils.WHITESPACE_SPLITTER; import static org.junit.Assert.assertEquals; /** diff --git a/examples/src/main/java/org/bitcoinj/examples/BackupToMnemonicSeed.java b/examples/src/main/java/org/bitcoinj/examples/BackupToMnemonicSeed.java index dd4661254..ad4f5a8ab 100644 --- a/examples/src/main/java/org/bitcoinj/examples/BackupToMnemonicSeed.java +++ b/examples/src/main/java/org/bitcoinj/examples/BackupToMnemonicSeed.java @@ -17,7 +17,7 @@ package org.bitcoinj.examples; import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Utils; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.params.TestNet3Params; import org.bitcoinj.script.Script; import org.bitcoinj.wallet.DeterministicSeed; @@ -42,6 +42,6 @@ public class BackupToMnemonicSeed { System.out.println("seed: " + seed.toString()); System.out.println("creation time: " + seed.getCreationTimeSeconds()); - System.out.println("mnemonicCode: " + Utils.SPACE_JOINER.join(seed.getMnemonicCode())); + System.out.println("mnemonicCode: " + InternalUtils.SPACE_JOINER.join(seed.getMnemonicCode())); } } diff --git a/wallettemplate/src/main/java/wallettemplate/WalletSettingsController.java b/wallettemplate/src/main/java/wallettemplate/WalletSettingsController.java index 0a8350bb5..df2c22a5b 100644 --- a/wallettemplate/src/main/java/wallettemplate/WalletSettingsController.java +++ b/wallettemplate/src/main/java/wallettemplate/WalletSettingsController.java @@ -16,10 +16,9 @@ package wallettemplate; -import org.bitcoinj.core.Utils; +import org.bitcoinj.core.internal.InternalUtils; import org.bitcoinj.crypto.MnemonicCode; import org.bitcoinj.wallet.DeterministicSeed; -import com.google.common.base.Splitter; import com.google.common.util.concurrent.Service; import javafx.application.Platform; import javafx.beans.binding.BooleanBinding; @@ -96,13 +95,13 @@ public class WalletSettingsController implements OverlayController mnemonicCode = seed.getMnemonicCode(); checkNotNull(mnemonicCode); // Already checked for encryption. - String origWords = Utils.SPACE_JOINER.join(mnemonicCode); + String origWords = InternalUtils.SPACE_JOINER.join(mnemonicCode); wordsArea.setText(origWords); // Validate words as they are being typed. MnemonicCode codec = unchecked(MnemonicCode::new); TextFieldValidator validator = new TextFieldValidator(wordsArea, text -> - !didThrow(() -> codec.check(Splitter.on(' ').splitToList(text))) + !didThrow(() -> codec.check(InternalUtils.splitter(" ").splitToList(text))) ); // Clear the date picker if the user starts editing the words, if it contained the current wallets date. @@ -181,7 +180,7 @@ public class WalletSettingsController implements OverlayController { if (seedStr != null) { DeterministicSeed seed; // Parse as mnemonic code. - final List split = Collections - .unmodifiableList(Splitter.on(CharMatcher.anyOf(" :;,")).omitEmptyStrings().splitToList(seedStr)); + final List split = splitMnemonic(seedStr); String passphrase = ""; // TODO allow user to specify a passphrase seed = new DeterministicSeed(split, null, passphrase, creationTimeSecs); try { @@ -1137,6 +1137,12 @@ public class WalletTool implements Callable { wallet.saveToFile(walletFile); } + private List splitMnemonic(String seedStr) { + return Stream.of(seedStr.split("[ :;,]")) // anyOf(" :;,") + .filter(s -> !s.isEmpty()) + .collect(Collectors.toUnmodifiableList()); + } + private void saveWallet(File walletFile) { try { // This will save the new state of the wallet to a temp file then rename, in case anything goes wrong.