add @Nullable/NotNull annotations, cleanup with intellij inspections

This commit is contained in:
Manfred Karrer 2014-06-30 02:17:26 +02:00
parent 2def1f5971
commit ebf2c559db
101 changed files with 2181 additions and 1613 deletions

View File

@ -70,8 +70,8 @@ public class BitSquare extends Application
final User user = injector.getInstance(User.class);
final Settings settings = injector.getInstance(Settings.class);
final Storage storage = injector.getInstance(Storage.class);
storage.init();
user.updateFromStorage((User) storage.read(user.getClass().getName()));
settings.updateFromStorage((Settings) storage.read(settings.getClass().getName()));
if (ID.isEmpty())
@ -88,9 +88,9 @@ public class BitSquare extends Application
try
{
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()), Localisation.getResourceBundle());
final Parent mainView = loader.load();
final Scene scene = new Scene(mainView, 800, 600);
@NotNull final Scene scene = new Scene(mainView, 800, 600);
stage.setScene(scene);
final String bitsquare = getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm();

View File

@ -3,24 +3,26 @@ package io.bitsquare;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerMaker;
import net.tomp2p.peers.Number160;
import org.jetbrains.annotations.Nullable;
/**
* Network node for relaying p2p msg
*/
public class RelayNode
class RelayNode
{
public static final Number160 ID = Number160.createHash(1);
private static final Number160 ID = Number160.createHash(1);
@Nullable
private static Peer masterPeer = null;
public static void main(String[] args) throws Exception
public static void main(@Nullable String[] args) throws Exception
{
if (args.length == 1)
if (args != null && args.length == 1)
INSTANCE(new Integer(args[0]));
else
INSTANCE(5000);
}
public static Peer INSTANCE(int port) throws Exception
private static void INSTANCE(int port) throws Exception
{
if (masterPeer == null)
{
@ -28,6 +30,5 @@ public class RelayNode
// masterPeer = new PeerMaker(ID).setPorts(port).setBagSize(100).makeAndListen(); // setBagSize cause sync problems...
masterPeer.getBroadcastRPC().getConnectionBean().getConnectionReservation().reserve(3).awaitUninterruptibly();
}
return masterPeer;
}
}

View File

@ -4,29 +4,39 @@ import io.bitsquare.locale.Country;
import java.io.Serializable;
import java.util.Currency;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BankAccount implements Serializable
{
private static final long serialVersionUID = 1792577576443221268L;
private final BankAccountTypeInfo bankAccountTypeInfo;
@NotNull
private final BankAccountType bankAccountType;
@NotNull
private final String accountPrimaryID;
@NotNull
private final String accountSecondaryID;
@NotNull
private final String accountHolderName;
@NotNull
private final Country country;
@NotNull
private final Currency currency;
@NotNull
private final String uid;
@NotNull
private final String accountTitle;
public BankAccount(BankAccountTypeInfo bankAccountTypeInfo,
Currency currency,
Country country,
String accountTitle,
String accountHolderName,
String accountPrimaryID,
String accountSecondaryID)
public BankAccount(@NotNull BankAccountType bankAccountType,
@NotNull Currency currency,
@NotNull Country country,
@NotNull String accountTitle,
@NotNull String accountHolderName,
@NotNull String accountPrimaryID,
@NotNull String accountSecondaryID)
{
this.bankAccountTypeInfo = bankAccountTypeInfo;
this.bankAccountType = bankAccountType;
this.currency = currency;
this.country = country;
this.accountTitle = accountTitle;
@ -42,62 +52,71 @@ public class BankAccount implements Serializable
return Objects.hashCode(uid);
}
public boolean equals(Object obj)
public boolean equals(@Nullable Object obj)
{
if (!(obj instanceof BankAccount))
return false;
if (obj == this)
return true;
BankAccount other = (BankAccount) obj;
return other.getUid().equals(uid);
final BankAccount other = (BankAccount) obj;
return uid.equals(other.getUid());
}
@NotNull
public String getAccountPrimaryID()
{
return accountPrimaryID;
}
@NotNull
public String getAccountSecondaryID()
{
return accountSecondaryID;
}
@NotNull
public String getAccountHolderName()
{
return accountHolderName;
}
public BankAccountTypeInfo getBankAccountTypeInfo()
@NotNull
public BankAccountType getBankAccountType()
{
return bankAccountTypeInfo;
return bankAccountType;
}
@NotNull
public Currency getCurrency()
{
return currency;
}
@NotNull
public Country getCountry()
{
return country;
}
@NotNull
public String getUid()
{
return uid;
}
@NotNull
public String getAccountTitle()
{
return accountTitle;
}
@NotNull
@Override
public String toString()
{
return "BankAccount{" +
"bankAccountType=" + bankAccountTypeInfo.getType() +
"bankAccountType=" + bankAccountType +
", accountPrimaryID='" + accountPrimaryID + '\'' +
", accountSecondaryID='" + accountSecondaryID + '\'' +
", accountHolderName='" + accountHolderName + '\'' +

View File

@ -0,0 +1,45 @@
package io.bitsquare.bank;
import java.util.ArrayList;
import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
public enum BankAccountType
{
SEPA("IBAN", "BIC"),
WIRE("primary ID", "secondary ID"),
INTERNATIONAL("primary ID", "secondary ID"),
OK_PAY("primary ID", "secondary ID"),
NET_TELLER("primary ID", "secondary ID"),
PERFECT_MONEY("primary ID", "secondary ID"),
OTHER("primary ID", "secondary ID");
@NotNull
private final String primaryId;
@NotNull
private final String secondaryId;
BankAccountType(@NotNull String primaryId, @NotNull String secondaryId)
{
this.primaryId = primaryId;
this.secondaryId = secondaryId;
}
@NotNull
public static ArrayList<BankAccountType> getAllBankAccountTypes()
{
return new ArrayList<>(Arrays.asList(BankAccountType.values()));
}
@NotNull
public String getPrimaryId()
{
return primaryId;
}
@NotNull
public String getSecondaryId()
{
return secondaryId;
}
}

View File

@ -1,69 +0,0 @@
package io.bitsquare.bank;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Objects;
public class BankAccountTypeInfo implements Serializable
{
private static final long serialVersionUID = -8772708150197835288L;
private final BankAccountType type;
private final String primaryIDName;
private final String secondaryIDName;
public BankAccountTypeInfo(BankAccountType type, String primaryIDName, String secondaryIDName)
{
this.type = type;
this.primaryIDName = primaryIDName;
this.secondaryIDName = secondaryIDName;
}
public static ArrayList<BankAccountTypeInfo> getAllBankAccountTypeInfoObjects()
{
ArrayList<BankAccountTypeInfo> bankTransferTypes = new ArrayList<>();
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.SEPA, "IBAN", "BIC"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.WIRE, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.INTERNATIONAL, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.OK_PAY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.NET_TELLER, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.PERFECT_MONEY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountTypeInfo(BankAccountType.OTHER, "Prim_todo", "Sec_todo"));
return bankTransferTypes;
}
public int hashCode()
{
return Objects.hashCode(type);
}
public boolean equals(Object obj)
{
if (!(obj instanceof BankAccountTypeInfo))
return false;
if (obj == this)
return true;
BankAccountTypeInfo other = (BankAccountTypeInfo) obj;
return other.getType().equals(type);
}
public BankAccountType getType()
{
return type;
}
public String getPrimaryIDName()
{
return primaryIDName;
}
public String getSecondaryIDName()
{
return secondaryIDName;
}
public static enum BankAccountType
{
SEPA, WIRE, INTERNATIONAL, OK_PAY, NET_TELLER, PERFECT_MONEY, OTHER
}
}

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -18,7 +19,7 @@ import org.slf4j.LoggerFactory;
* possible. This means that the transaction is the most likely to get confirmed. Note that this means we may end up
* "spending" more priority than would be required to get the transaction we are creating confirmed.
*/
public class AddressBasedCoinSelector extends DefaultCoinSelector
class AddressBasedCoinSelector extends DefaultCoinSelector
{
private static final Logger log = LoggerFactory.getLogger(AddressBasedCoinSelector.class);
private final NetworkParameters params;
@ -41,8 +42,9 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
this.includePending = includePending;
}
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static void sortOutputs(ArrayList<TransactionOutput> outputs)
static void sortOutputs(@NotNull ArrayList<TransactionOutput> outputs)
{
Collections.sort(outputs, (a, b) -> {
int depth1 = 0;
@ -69,7 +71,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
});
}
private static boolean isInBlockChainOrPending(Transaction tx)
private static boolean isInBlockChainOrPending(@NotNull Transaction tx)
{
// Pick chain-included transactions and transactions that are pending.
TransactionConfidence confidence = tx.getConfidence();
@ -81,7 +83,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
(confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get());
}
private static boolean isInBlockChain(Transaction tx)
private static boolean isInBlockChain(@NotNull Transaction tx)
{
// Only pick chain-included transactions.
TransactionConfidence confidence = tx.getConfidence();
@ -92,7 +94,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
/**
* Sub-classes can override this to just customize whether transactions are usable, but keep age sorting.
*/
protected boolean shouldSelect(Transaction tx)
protected boolean shouldSelect(@NotNull Transaction tx)
{
if (includePending)
return isInBlockChainOrPending(tx);
@ -100,7 +102,8 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
return isInBlockChain(tx);
}
protected boolean matchesRequiredAddress(TransactionOutput transactionOutput)
@SuppressWarnings("WeakerAccess")
protected boolean matchesRequiredAddress(@NotNull TransactionOutput transactionOutput)
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
@ -113,13 +116,14 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
return false;
}
public CoinSelection select(BigInteger biTarget, LinkedList<TransactionOutput> candidates)
@NotNull
public CoinSelection select(@NotNull BigInteger biTarget, @NotNull LinkedList<TransactionOutput> candidates)
{
long target = biTarget.longValue();
HashSet<TransactionOutput> selected = new HashSet<>();
@NotNull HashSet<TransactionOutput> selected = new HashSet<>();
// Sort the inputs by age*value so we get the highest "coindays" spent.
// TODO: Consider changing the wallets internal format to track just outputs and keep them ordered.
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);
@NotNull ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
// them in order to improve performance.
if (!biTarget.equals(NetworkParameters.MAX_MONEY))
@ -129,7 +133,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
// Now iterate over the sorted outputs until we have got as close to the target as possible or a little
// bit over (excessive value will be change).
long total = 0;
for (TransactionOutput output : sortedOutputs)
for (@NotNull TransactionOutput output : sortedOutputs)
{
if (total >= target) break;
// Only pick chain-included transactions, or transactions that are ours and pending.

View File

@ -5,6 +5,7 @@ import com.google.bitcoin.core.ECKey;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.Utils;
import java.io.Serializable;
import org.jetbrains.annotations.Nullable;
public class AddressEntry implements Serializable
{
@ -12,6 +13,7 @@ public class AddressEntry implements Serializable
private final ECKey key;
private final NetworkParameters params;
private final AddressContext addressContext;
@Nullable
private String tradeId = null;
public AddressEntry(ECKey key, NetworkParameters params, AddressContext addressContext)
@ -21,12 +23,13 @@ public class AddressEntry implements Serializable
this.addressContext = addressContext;
}
@Nullable
public String getTradeId()
{
return tradeId;
}
public void setTradeId(String tradeId)
public void setTradeId(@Nullable String tradeId)
{
this.tradeId = tradeId;
}

View File

@ -7,7 +7,7 @@ import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BitSquareWallet extends Wallet implements Serializable
class BitSquareWallet extends Wallet implements Serializable
{
private static final Logger log = LoggerFactory.getLogger(BitSquareWallet.class);
private static final long serialVersionUID = -6231929674475881549L;
@ -17,7 +17,7 @@ public class BitSquareWallet extends Wallet implements Serializable
super(params);
}
public BitSquareWallet(NetworkParameters params, KeyCrypter keyCrypter)
private BitSquareWallet(NetworkParameters params, KeyCrypter keyCrypter)
{
super(params, keyCrypter);
}

View File

@ -12,13 +12,15 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BitSquareWalletAppKit extends WalletAppKit
{
public BitSquareWalletAppKit(NetworkParameters params, File directory, String filePrefix)
public BitSquareWalletAppKit(NetworkParameters params, File directory)
{
super(params, directory, filePrefix);
super(params, directory, WalletFacade.WALLET_PREFIX);
}
@Override
@ -32,10 +34,10 @@ public class BitSquareWalletAppKit extends WalletAppKit
throw new IOException("Could not create named directory.");
}
}
FileInputStream walletStream = null;
@Nullable FileInputStream walletStream = null;
try
{
File chainFile = new File(directory, filePrefix + ".spvchain");
@NotNull File chainFile = new File(directory, filePrefix + ".spvchain");
boolean chainFileExists = chainFile.exists();
vWalletFile = new File(directory, filePrefix + ".wallet");
boolean shouldReplayWallet = vWalletFile.exists() && !chainFileExists;
@ -50,8 +52,8 @@ public class BitSquareWalletAppKit extends WalletAppKit
long time = Long.MAX_VALUE;
if (vWalletFile.exists())
{
Wallet wallet = new BitSquareWallet(params);
FileInputStream stream = new FileInputStream(vWalletFile);
@NotNull Wallet wallet = new BitSquareWallet(params);
@NotNull FileInputStream stream = new FileInputStream(vWalletFile);
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(stream), wallet);
time = wallet.getEarliestKeyCreationTime();
}
@ -102,23 +104,24 @@ public class BitSquareWalletAppKit extends WalletAppKit
// Make sure we shut down cleanly.
installShutdownHook();
// TODO: Be able to use the provided download listener when doing a blocking startup.
final DownloadListener listener = new DownloadListener();
@NotNull final DownloadListener listener = new DownloadListener();
vPeerGroup.startBlockChainDownload(listener);
listener.await();
}
else
{
//TODO
Futures.addCallback(vPeerGroup.start(), new FutureCallback<State>()
{
@Override
public void onSuccess(State result)
{
final PeerEventListener l = downloadListener == null ? new DownloadListener() : downloadListener;
@NotNull final PeerEventListener l = downloadListener == null ? new DownloadListener() : downloadListener;
vPeerGroup.startBlockChainDownload(l);
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
throw new RuntimeException(t);
}

View File

@ -2,10 +2,12 @@ package io.bitsquare.btc;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccount;
import org.jetbrains.annotations.Nullable;
/**
* That facade delivers blockchain functionality from the bitcoinJ library
*/
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
public class BlockChainFacade
{
@Inject
@ -41,6 +43,7 @@ public class BlockChainFacade
return true;
}
@Nullable
private byte[] getDataForTxWithAddress(String address)
{
// TODO

View File

@ -2,18 +2,19 @@ package io.bitsquare.btc;
import com.google.bitcoin.core.Utils;
import io.bitsquare.gui.util.BitSquareConverter;
import io.bitsquare.gui.util.BitSquareFormatter;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO
public class BtcFormatter
{
public static final BigInteger BTC = new BigInteger("100000000");
private static final BigInteger BTC = new BigInteger("100000000");
private static final Logger log = LoggerFactory.getLogger(BtcFormatter.class);
@NotNull
public static BigInteger mBTC = new BigInteger("100000");
@ -23,7 +24,7 @@ public class BtcFormatter
}
//TODO
public static double satoshiToBTC(BigInteger satoshis)
public static double satoshiToBTC(@NotNull BigInteger satoshis)
{
return satoshis.doubleValue() / BTC.doubleValue();
}
@ -38,7 +39,7 @@ public class BtcFormatter
try
{
// only "." as decimal sep supported by Utils.toNanoCoins
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
@NotNull DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
decimalFormat.setMaximumFractionDigits(10);
decimalFormat.setMinimumFractionDigits(10);
String stringValue = decimalFormat.format(value);
@ -49,12 +50,4 @@ public class BtcFormatter
return BigInteger.ZERO;
}
}
public static String formatSatoshis(BigInteger satoshis, boolean useBTC)
{
if (useBTC)
return BitSquareFormatter.formatDouble(satoshiToBTC(satoshis), 8) + " BTC";
else
return BitSquareFormatter.formatDouble(satoshiToBTC(satoshis), 8);
}
}

View File

@ -6,6 +6,7 @@ import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.Transaction;
import com.google.inject.Inject;
import java.math.BigInteger;
import org.jetbrains.annotations.Nullable;
public class BtcValidator
{
@ -17,7 +18,7 @@ public class BtcValidator
BtcValidator.params = params;
}
public static boolean isMinSpendableAmount(BigInteger amount)
public static boolean isMinSpendableAmount(@Nullable BigInteger amount)
{
return amount != null && amount.compareTo(FeePolicy.TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)) > 0;
}

View File

@ -3,6 +3,7 @@ package io.bitsquare.btc;
import com.google.bitcoin.core.*;
import com.google.inject.Inject;
import java.math.BigInteger;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -26,6 +27,7 @@ public class FeePolicy
}
//TODO other users or dev address? use donation option list? (dev, other users, wikileaks, tor, sub projects (bitcoinj, tomp2p,...)...)
@Nullable
public Address getAddressForRegistrationFee()
{
try
@ -39,6 +41,7 @@ public class FeePolicy
}
//TODO get address form arbitrator list
@Nullable
public Address getAddressForCreateOfferFee()
{
try
@ -52,6 +55,7 @@ public class FeePolicy
}
//TODO get address form the intersection of both traders arbitrator lists
@Nullable
public Address getAddressForTakeOfferFee()
{
try

View File

@ -19,6 +19,7 @@ import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.btc.listeners.ConfidenceListener;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.storage.Storage;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
@ -26,6 +27,8 @@ import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.util.Pair;
import javax.annotation.concurrent.GuardedBy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -46,6 +49,7 @@ public class WalletFacade
private final ReentrantLock lock = Threading.lock("lock");
@NotNull
private final String saveAddressEntryListId;
private final NetworkParameters params;
private final BitSquareWalletAppKit walletAppKit;
@ -57,6 +61,7 @@ public class WalletFacade
private final List<BalanceListener> balanceListeners = new ArrayList<>();
private BitSquareWallet wallet;
private WalletEventListener walletEventListener;
@NotNull
@GuardedBy("lock")
private List<AddressEntry> addressEntryList = new ArrayList<>();
@ -131,11 +136,11 @@ public class WalletFacade
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
{
notifyBalanceListeners(tx);
notifyBalanceListeners();
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
public void onTransactionConfidenceChanged(Wallet wallet, @NotNull Transaction tx)
{
notifyConfidenceListeners(tx);
}
@ -143,7 +148,7 @@ public class WalletFacade
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
{
notifyBalanceListeners(tx);
notifyBalanceListeners();
}
@Override
@ -168,30 +173,20 @@ public class WalletFacade
};
wallet.addEventListener(walletEventListener);
Object object = storage.read(saveAddressEntryListId);
if (object instanceof List)
Serializable serializable = storage.read(saveAddressEntryListId);
List<AddressEntry> savedAddressEntryList = (List<AddressEntry>) serializable;
if (serializable instanceof List)
{
List<AddressEntry> savedAddressEntryList = (List<AddressEntry>) object;
if (savedAddressEntryList != null)
{
addressEntryList = savedAddressEntryList;
}
else
{
lock.lock();
try
{
ECKey registrationKey = wallet.getKeys().get(0);
AddressEntry registrationAddressEntry = new AddressEntry(registrationKey, params, AddressEntry.AddressContext.REGISTRATION_FEE);
addressEntryList.add(registrationAddressEntry);
} finally
{
lock.unlock();
}
saveAddressInfoList();
getNewTradeAddressEntry();
}
addressEntryList = savedAddressEntryList;
}
else
{
lock.lock();
ECKey registrationKey = wallet.getKeys().get(0);
addressEntryList.add(new AddressEntry(registrationKey, params, AddressEntry.AddressContext.REGISTRATION_FEE));
lock.unlock();
saveAddressInfoList();
getNewTradeAddressEntry();
}
}
@ -214,6 +209,7 @@ public class WalletFacade
// Listener
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("UnusedReturnValue")
public DownloadListener addDownloadListener(DownloadListener listener)
{
downloadListeners.add(listener);
@ -257,49 +253,55 @@ public class WalletFacade
return ImmutableList.copyOf(addressEntryList);
}
@Nullable
public AddressEntry getRegistrationAddressInfo()
{
return getAddressInfoByAddressContext(AddressEntry.AddressContext.REGISTRATION_FEE);
}
@NotNull
public AddressEntry getArbitratorDepositAddressInfo()
{
AddressEntry arbitratorDepositAddressEntry = getAddressInfoByAddressContext(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
@Nullable AddressEntry arbitratorDepositAddressEntry = getAddressInfoByAddressContext(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
if (arbitratorDepositAddressEntry == null)
arbitratorDepositAddressEntry = getNewArbitratorDepositAddressEntry();
return arbitratorDepositAddressEntry;
}
public AddressEntry getUnusedTradeAddressInfo()
@Nullable
AddressEntry getUnusedTradeAddressInfo()
{
List<AddressEntry> filteredList = Lists.newArrayList(Collections2.filter(ImmutableList.copyOf(addressEntryList), addressInfo -> (addressInfo != null && addressInfo.getAddressContext().equals(AddressEntry.AddressContext.TRADE) && addressInfo.getTradeId() == null)));
if (filteredList != null && filteredList.size() > 0)
if (filteredList != null && !filteredList.isEmpty())
return filteredList.get(0);
else
return getNewTradeAddressEntry();
}
private AddressEntry getAddressInfoByAddressContext(AddressEntry.AddressContext addressContext)
@Nullable
private AddressEntry getAddressInfoByAddressContext(@NotNull AddressEntry.AddressContext addressContext)
{
List<AddressEntry> filteredList = Lists.newArrayList(Collections2.filter(ImmutableList.copyOf(addressEntryList), addressInfo -> (addressInfo != null && addressContext != null && addressInfo.getAddressContext() != null && addressInfo.getAddressContext().equals(addressContext))));
List<AddressEntry> filteredList = Lists.newArrayList(Collections2.filter(ImmutableList.copyOf(addressEntryList), addressInfo -> (addressInfo != null && addressInfo.getAddressContext() != null && addressInfo.getAddressContext().equals(addressContext))));
if (filteredList != null && filteredList.size() > 0)
if (filteredList != null && !filteredList.isEmpty())
return filteredList.get(0);
else
return null;
}
@Nullable
public AddressEntry getAddressInfoByTradeID(String tradeId)
{
for (AddressEntry addressEntry : ImmutableList.copyOf(addressEntryList))
for (@NotNull AddressEntry addressEntry : ImmutableList.copyOf(addressEntryList))
{
if (addressEntry.getTradeId() != null && addressEntry.getTradeId().equals(tradeId))
return addressEntry;
}
AddressEntry addressEntry = getUnusedTradeAddressInfo();
@Nullable AddressEntry addressEntry = getUnusedTradeAddressInfo();
assert addressEntry != null;
addressEntry.setTradeId(tradeId);
return addressEntry;
}
@ -309,41 +311,38 @@ public class WalletFacade
// Create new AddressInfo objects
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public AddressEntry getNewTradeAddressEntry()
{
return getNewAddressEntry(AddressEntry.AddressContext.TRADE);
}
@NotNull
private AddressEntry getNewAddressEntry(AddressEntry.AddressContext addressContext)
{
AddressEntry addressEntry = null;
lock.lock();
wallet.getLock().lock();
try
{
ECKey key = new ECKey();
wallet.addKey(key);
wallet.addWatchedAddress(key.toAddress(params));
addressEntry = new AddressEntry(key, params, addressContext);
addressEntryList.add(addressEntry);
saveAddressInfoList();
} finally
{
lock.unlock();
wallet.getLock().unlock();
}
@NotNull ECKey key = new ECKey();
wallet.addKey(key);
wallet.addWatchedAddress(key.toAddress(params));
AddressEntry addressEntry = new AddressEntry(key, params, addressContext);
addressEntryList.add(addressEntry);
saveAddressInfoList();
lock.unlock();
wallet.getLock().unlock();
return addressEntry;
}
@NotNull
private AddressEntry getNewArbitratorDepositAddressEntry()
{
return getNewAddressEntry(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
}
@Nullable
private AddressEntry getAddressEntryByAddressString(String address)
{
for (AddressEntry addressEntry : addressEntryList)
for (@NotNull AddressEntry addressEntry : addressEntryList)
{
if (addressEntry.getAddressString().equals(address))
return addressEntry;
@ -355,9 +354,10 @@ public class WalletFacade
// TransactionConfidence
///////////////////////////////////////////////////////////////////////////////////////////
public TransactionConfidence getConfidenceForAddress(Address address)
@Nullable
public TransactionConfidence getConfidenceForAddress(@NotNull Address address)
{
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
@NotNull List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
Set<Transaction> transactions = wallet.getTransactions(true);
if (transactions != null)
{
@ -372,22 +372,23 @@ public class WalletFacade
return getMostRecentConfidence(transactionConfidenceList);
}
private void notifyConfidenceListeners(Transaction tx)
private void notifyConfidenceListeners(@NotNull Transaction tx)
{
for (ConfidenceListener confidenceListener : confidenceListeners)
for (@NotNull ConfidenceListener confidenceListener : confidenceListeners)
{
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
@NotNull List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
transactionConfidenceList.add(getTransactionConfidence(tx, confidenceListener.getAddress()));
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
@Nullable TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
confidenceListener.onTransactionConfidenceChanged(transactionConfidence);
}
}
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address)
@Nullable
private TransactionConfidence getTransactionConfidence(@NotNull Transaction tx, @NotNull Address address)
{
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
@NotNull List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
@NotNull List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
mergedOutputs.stream().filter(transactionOutput -> transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()).forEach(transactionOutput -> {
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
@ -413,30 +414,32 @@ public class WalletFacade
return getMostRecentConfidence(transactionConfidenceList);
}
private List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx)
@NotNull
private List<TransactionOutput> getOutputsWithConnectedOutputs(@NotNull Transaction tx)
{
List<TransactionOutput> transactionOutputs = tx.getOutputs();
List<TransactionOutput> connectedOutputs = new ArrayList<>();
@NotNull List<TransactionOutput> connectedOutputs = new ArrayList<>();
// add all connected outputs from any inputs as well
List<TransactionInput> transactionInputs = tx.getInputs();
for (TransactionInput transactionInput : transactionInputs)
for (@NotNull TransactionInput transactionInput : transactionInputs)
{
TransactionOutput transactionOutput = transactionInput.getConnectedOutput();
@Nullable TransactionOutput transactionOutput = transactionInput.getConnectedOutput();
if (transactionOutput != null)
connectedOutputs.add(transactionOutput);
}
List<TransactionOutput> mergedOutputs = new ArrayList<>();
@NotNull List<TransactionOutput> mergedOutputs = new ArrayList<>();
mergedOutputs.addAll(transactionOutputs);
mergedOutputs.addAll(connectedOutputs);
return mergedOutputs;
}
private TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList)
@Nullable
private TransactionConfidence getMostRecentConfidence(@NotNull List<TransactionConfidence> transactionConfidenceList)
{
TransactionConfidence transactionConfidence = null;
for (TransactionConfidence confidence : transactionConfidenceList)
@Nullable TransactionConfidence transactionConfidence = null;
for (@Nullable TransactionConfidence confidence : transactionConfidenceList)
{
if (confidence != null)
{
@ -457,7 +460,9 @@ public class WalletFacade
public boolean isRegistrationFeeConfirmed()
{
TransactionConfidence transactionConfidence = getConfidenceForAddress(getRegistrationAddressInfo().getAddress());
@Nullable TransactionConfidence transactionConfidence = null;
if (getRegistrationAddressInfo() != null)
transactionConfidence = getConfidenceForAddress(getRegistrationAddressInfo().getAddress());
return transactionConfidence != null && transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING);
}
@ -471,10 +476,10 @@ public class WalletFacade
return getBalance(wallet.calculateAllSpendCandidates(true), address);
}
private BigInteger getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address)
private BigInteger getBalance(@NotNull LinkedList<TransactionOutput> transactionOutputs, Address address)
{
BigInteger balance = BigInteger.ZERO;
for (TransactionOutput transactionOutput : transactionOutputs)
for (@NotNull TransactionOutput transactionOutput : transactionOutputs)
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
@ -488,9 +493,9 @@ public class WalletFacade
return balance;
}
private void notifyBalanceListeners(Transaction tx)
private void notifyBalanceListeners()
{
for (BalanceListener balanceListener : balanceListeners)
for (@NotNull BalanceListener balanceListener : balanceListeners)
{
BigInteger balance;
if (balanceListener.getAddress() != null)
@ -507,7 +512,7 @@ public class WalletFacade
return wallet.getBalance(Wallet.BalanceType.ESTIMATED);
}
public BigInteger getRegistrationBalance()
BigInteger getRegistrationBalance()
{
return getBalanceForAddress(getRegistrationAddressInfo().getAddress());
}
@ -529,14 +534,14 @@ public class WalletFacade
public boolean isUnusedTradeAddressBalanceAboveCreationFee()
{
AddressEntry unUsedAddressEntry = getUnusedTradeAddressInfo();
@Nullable AddressEntry unUsedAddressEntry = getUnusedTradeAddressInfo();
BigInteger unUsedAddressInfoBalance = getBalanceForAddress(unUsedAddressEntry.getAddress());
return unUsedAddressInfoBalance.compareTo(FeePolicy.CREATE_OFFER_FEE) > 0;
}
public boolean isUnusedTradeAddressBalanceAboveTakeOfferFee()
{
AddressEntry unUsedAddressEntry = getUnusedTradeAddressInfo();
@Nullable AddressEntry unUsedAddressEntry = getUnusedTradeAddressInfo();
BigInteger unUsedAddressInfoBalance = getBalanceForAddress(unUsedAddressEntry.getAddress());
return unUsedAddressInfoBalance.compareTo(FeePolicy.TAKE_OFFER_FEE) > 0;
}
@ -547,6 +552,7 @@ public class WalletFacade
//TODO
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
public int getNumOfPeersSeenTx(String txID)
{
// TODO check from blockchain
@ -559,12 +565,12 @@ public class WalletFacade
// Transactions
///////////////////////////////////////////////////////////////////////////////////////////
public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback<Transaction> callback) throws InsufficientMoneyException
public void payRegistrationFee(String stringifiedBankAccounts, @NotNull FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
log.debug("payRegistrationFee");
log.trace("stringifiedBankAccounts " + stringifiedBankAccounts);
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts);
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build());
@ -580,13 +586,14 @@ public class WalletFacade
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
Futures.addCallback(sendResult.broadcastComplete, callback);
log.debug("Registration transaction: " + tx.toString());
log.debug("Registration transaction: " + tx);
printInputs("payRegistrationFee", tx);
}
public String payCreateOfferFee(String offerId, FutureCallback<Transaction> callback) throws InsufficientMoneyException
@SuppressWarnings("UnusedReturnValue")
public String payCreateOfferFee(String offerId, @NotNull FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
BigInteger fee = FeePolicy.CREATE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
log.trace("fee: " + BtcFormatter.satoshiToString(fee));
tx.addOutput(fee, feePolicy.getAddressForCreateOfferFee());
@ -599,14 +606,15 @@ public class WalletFacade
Futures.addCallback(sendResult.broadcastComplete, callback);
printInputs("payTakeOfferFee", tx);
log.debug("tx=" + tx.toString());
log.debug("tx=" + tx);
return tx.getHashAsString();
}
public String payTakeOfferFee(String offerId, FutureCallback<Transaction> callback) throws InsufficientMoneyException
@SuppressWarnings("UnusedReturnValue")
public String payTakeOfferFee(String offerId, @NotNull FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
BigInteger fee = FeePolicy.TAKE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
log.trace("fee: " + BtcFormatter.satoshiToString(fee));
tx.addOutput(fee, feePolicy.getAddressForTakeOfferFee());
@ -619,7 +627,7 @@ public class WalletFacade
Futures.addCallback(sendResult.broadcastComplete, callback);
printInputs("payTakeOfferFee", tx);
log.debug("tx=" + tx.toString());
log.debug("tx=" + tx);
return tx.getHashAsString();
}
@ -629,13 +637,14 @@ public class WalletFacade
// Withdrawal
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("UnusedReturnValue")
public String sendFunds(String withdrawFromAddress,
String withdrawToAddress,
String changeAddress,
BigInteger amount,
FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException
@NotNull BigInteger amount,
@NotNull FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException
{
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
tx.addOutput(amount.subtract(FeePolicy.TX_FEE), new Address(params, withdrawToAddress));
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
@ -648,7 +657,7 @@ public class WalletFacade
Futures.addCallback(sendResult.broadcastComplete, callback);
printInputs("sendFunds", tx);
log.debug("tx=" + tx.toString());
log.debug("tx=" + tx);
return tx.getHashAsString();
}
@ -660,6 +669,7 @@ public class WalletFacade
// 1. step: deposit tx
// Offerer creates the 2of3 multiSig deposit tx with his unsigned input and change output
@NotNull
public Transaction offererCreatesMSTxAndAddPayment(BigInteger offererInputAmount, String offererPubKey, String takerPubKey, String arbitratorPubKey, String tradeId) throws InsufficientMoneyException
{
log.debug("offererCreatesMSTxAndAddPayment");
@ -675,12 +685,12 @@ public class WalletFacade
// We don't commit that tx to the wallet as it will be changed later and it's not signed yet.
// So it will not change the wallet balance.
// The btc tx fee will be included by the completeTx() call, so we don't need to add it manually.
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey);
tx.addOutput(offererInputAmount, multiSigOutputScript);
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
@Nullable AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
addressEntry.setTradeId(tradeId);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true);
@ -704,12 +714,13 @@ public class WalletFacade
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
printInputs("offererCreatesMSTxAndAddPayment", tx);
log.debug("tx = " + tx.toString());
log.debug("tx = " + tx);
return tx;
}
// 2. step: deposit tx
// Taker adds his input and change output, changes the multiSig amount to the correct value and sign his input
@NotNull
public Transaction takerAddPaymentAndSignTx(BigInteger takerInputAmount,
BigInteger msOutputAmount,
String offererPubKey,
@ -734,12 +745,12 @@ public class WalletFacade
// Both traders pay 1 times a fee, so it is equally split between them
// We do exactly the same as in the 1. step but with the takers input.
Transaction tempTx = new Transaction(params);
@NotNull Transaction tempTx = new Transaction(params);
Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey);
tempTx.addOutput(takerInputAmount, multiSigOutputScript);
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tempTx);
AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
@Nullable AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
addressEntry.setTradeId(tradeId);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true);
@ -760,7 +771,7 @@ public class WalletFacade
// Now we construct the real 2of3 multiSig tx from the serialized offerers tx
Transaction tx = new Transaction(params, Utils.parseAsHexOrBase58(offerersPartialDepositTxAsHex));
@NotNull Transaction tx = new Transaction(params, Utils.parseAsHexOrBase58(offerersPartialDepositTxAsHex));
log.trace("offerersPartialDepositTx=" + tx);
// The serialized offerers tx looks like:
@ -786,10 +797,10 @@ public class WalletFacade
log.error("input or input.getConnectedOutput() is null: " + input);
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
@Nullable ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
Sha256Hash hash = tx.hashForSignature(1, scriptPubKey, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
@NotNull TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
if (scriptPubKey.isSentToRawPubKey())
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
else if (scriptPubKey.isSentToAddress())
@ -818,20 +829,21 @@ public class WalletFacade
log.trace("Check if wallet is consistent before commit: result=" + wallet.isConsistent());
printInputs("takerAddPaymentAndSignTx", tx);
log.debug("tx = " + tx.toString());
log.debug("tx = " + tx);
return tx;
}
// 3. step: deposit tx
// Offerer signs tx and publishes it
@NotNull
public Transaction offererSignAndPublishTx(String offerersFirstTxAsHex,
String takersSignedTxAsHex,
String takersSignedConnOutAsHex,
String takersSignedScriptSigAsHex,
long offererTxOutIndex,
long takerTxOutIndex,
FutureCallback<Transaction> callback)
@NotNull FutureCallback<Transaction> callback)
{
log.debug("offererSignAndPublishTx");
log.trace("inputs: ");
@ -839,35 +851,35 @@ public class WalletFacade
log.trace("takersSignedTxAsHex=" + takersSignedTxAsHex);
log.trace("takersSignedConnOutAsHex=" + takersSignedConnOutAsHex);
log.trace("takersSignedScriptSigAsHex=" + takersSignedScriptSigAsHex);
log.trace("callback=" + callback.toString());
log.trace("callback=" + callback);
// We create an empty tx (did not find a way to manipulate a tx input, otherwise the takers tx could be used directly and add the offerers input and output)
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
// offerers first tx
Transaction offerersFirstTx = new Transaction(params, Utils.parseAsHexOrBase58(offerersFirstTxAsHex));
@NotNull Transaction offerersFirstTx = new Transaction(params, Utils.parseAsHexOrBase58(offerersFirstTxAsHex));
printInputs("offerersFirstTx", offerersFirstTx);
log.trace("offerersFirstTx = " + offerersFirstTx.toString());
log.trace("offerersFirstTx = " + offerersFirstTx);
// add input
Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash()); // pass that around!
TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex, offerersFirstTxConnOut);
@Nullable Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash()); // pass that around!
@NotNull TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex, offerersFirstTxConnOut);
//TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, offerersFirstTx.getInput(0).getScriptBytes(), offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array
TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array
@NotNull TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array
offerersFirstTxInput.setParent(tx);
tx.addInput(offerersFirstTxInput);
// takers signed tx
Transaction takersSignedTx = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedTxAsHex));
@NotNull Transaction takersSignedTx = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedTxAsHex));
printInputs("takersSignedTxInput", takersSignedTx);
log.trace("takersSignedTx = " + takersSignedTx.toString());
log.trace("takersSignedTx = " + takersSignedTx);
// add input
Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex));
TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex, takersSignedTxConnOut);
TransactionInput takersSignedTxInput = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint);
@NotNull Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex));
@NotNull TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex, takersSignedTxConnOut);
@NotNull TransactionInput takersSignedTxInput = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint);
takersSignedTxInput.setParent(tx);
tx.addInput(takersSignedTxInput);
@ -880,7 +892,7 @@ public class WalletFacade
tx.addOutput(takersSignedTx.getOutput(2));
printInputs("tx", tx);
log.trace("tx = " + tx.toString());
log.trace("tx = " + tx);
log.trace("Wallet balance before signing: " + wallet.getBalance());
// sign the input
@ -889,10 +901,10 @@ public class WalletFacade
log.error("input or input.getConnectedOutput() is null: " + input);
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
@Nullable ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
Sha256Hash hash = tx.hashForSignature(0, scriptPubKey, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
@NotNull TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
if (scriptPubKey.isSentToRawPubKey())
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
else if (scriptPubKey.isSentToAddress())
@ -921,7 +933,7 @@ public class WalletFacade
tx.verify();
printInputs("tx", tx);
log.debug("tx = " + tx.toString());
log.debug("tx = " + tx);
log.trace("Wallet balance before broadcastTransaction: " + wallet.getBalance());
log.trace("Check if wallet is consistent before broadcastTransaction: result=" + wallet.isConsistent());
@ -931,7 +943,7 @@ public class WalletFacade
Futures.addCallback(broadcastComplete, callback);
printInputs("tx", tx);
log.debug("tx = " + tx.toString());
log.debug("tx = " + tx);
return tx;
}
@ -941,7 +953,7 @@ public class WalletFacade
log.trace("takerCommitDepositTx");
log.trace("inputs: ");
log.trace("depositTxID=" + depositTxAsHex);
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
@NotNull Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
log.trace("depositTx=" + depositTx);
// boolean isAlreadyInWallet = wallet.maybeCommitTx(depositTx);
//log.trace("isAlreadyInWallet=" + isAlreadyInWallet);
@ -961,6 +973,7 @@ public class WalletFacade
}
// 5. step payout tx: Offerer creates payout tx and signs it
@NotNull
public Pair<ECKey.ECDSASignature, String> offererCreatesAndSignsPayoutTx(String depositTxID,
BigInteger offererPaybackAmount,
BigInteger takerPaybackAmount,
@ -975,27 +988,29 @@ public class WalletFacade
log.trace("takerAddress=" + takerAddress);
// Offerer has published depositTx earlier, so he has it in his wallet
Transaction depositTx = wallet.getTransaction(new Sha256Hash(depositTxID));
@Nullable Transaction depositTx = wallet.getTransaction(new Sha256Hash(depositTxID));
String depositTxAsHex = Utils.bytesToHexString(depositTx.bitcoinSerialize());
// We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getAddressInfoByTradeID(tradeID).getAddressString(), takerAddress);
@NotNull Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getAddressInfoByTradeID(tradeID).getAddressString(), takerAddress);
// We create the signature for that tx
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
@Nullable TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
Script multiSigScript = multiSigOutput.getScriptPubKey();
Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature offererSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash);
TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
@NotNull TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig));
tx.getInput(0).setScriptSig(inputScript);
log.trace("sigHash=" + sigHash.toString());
log.trace("sigHash=" + sigHash);
return new Pair<>(offererSignature, depositTxAsHex);
}
// 6. step payout tx: Taker signs and publish tx
@SuppressWarnings("UnusedReturnValue")
@NotNull
public Transaction takerSignsAndSendsTx(String depositTxAsHex,
String offererSignatureR,
String offererSignatureS,
@ -1003,7 +1018,7 @@ public class WalletFacade
BigInteger takerPaybackAmount,
String offererAddress,
String tradeID,
FutureCallback<Transaction> callback) throws AddressFormatException
@NotNull FutureCallback<Transaction> callback) throws AddressFormatException
{
log.debug("takerSignsAndSendsTx");
log.trace("inputs: ");
@ -1013,22 +1028,22 @@ public class WalletFacade
log.trace("offererPaybackAmount=" + BtcFormatter.satoshiToString(offererPaybackAmount));
log.trace("takerPaybackAmount=" + BtcFormatter.satoshiToString(takerPaybackAmount));
log.trace("offererAddress=" + offererAddress);
log.trace("callback=" + callback.toString());
log.trace("callback=" + callback);
// We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getAddressInfoByTradeID(tradeID).getAddressString());
@NotNull Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getAddressInfoByTradeID(tradeID).getAddressString());
// We sign that tx with our key and apply the signature form the offerer
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
@Nullable TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
Script multiSigScript = multiSigOutput.getScriptPubKey();
Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
log.trace("sigHash=" + sigHash.toString());
log.trace("sigHash=" + sigHash);
ECKey.ECDSASignature takerSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash);
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
@NotNull TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature offererSignature = new ECKey.ECDSASignature(new BigInteger(offererSignatureR), new BigInteger(offererSignatureS));
TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
@NotNull ECKey.ECDSASignature offererSignature = new ECKey.ECDSASignature(new BigInteger(offererSignatureR), new BigInteger(offererSignatureS));
@NotNull TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig));
tx.getInput(0).setScriptSig(inputScript);
@ -1048,7 +1063,7 @@ public class WalletFacade
log.trace("getTransactions.size=" + wallet.getTransactions(true).size());
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
printInputs("takerSignsAndSendsTx", tx);
log.debug("tx = " + tx.toString());
log.debug("tx = " + tx);
return tx;
}
@ -1072,15 +1087,16 @@ public class WalletFacade
private Script getMultiSigScript(String offererPubKey, String takerPubKey, String arbitratorPubKey)
{
ECKey offererKey = new ECKey(null, Utils.parseAsHexOrBase58(offererPubKey));
ECKey takerKey = new ECKey(null, Utils.parseAsHexOrBase58(takerPubKey));
ECKey arbitratorKey = new ECKey(null, Utils.parseAsHexOrBase58(arbitratorPubKey));
@NotNull ECKey offererKey = new ECKey(null, Utils.parseAsHexOrBase58(offererPubKey));
@NotNull ECKey takerKey = new ECKey(null, Utils.parseAsHexOrBase58(takerPubKey));
@NotNull ECKey arbitratorKey = new ECKey(null, Utils.parseAsHexOrBase58(arbitratorPubKey));
List<ECKey> keys = ImmutableList.of(offererKey, takerKey, arbitratorKey);
return ScriptBuilder.createMultiSigOutputScript(2, keys);
}
@NotNull
private Transaction createPayoutTx(String depositTxAsHex,
BigInteger offererPaybackAmount,
BigInteger takerPaybackAmount,
@ -1095,9 +1111,9 @@ public class WalletFacade
log.trace("offererAddress=" + offererAddress);
log.trace("takerAddress=" + takerAddress);
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
@NotNull Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
TransactionOutput multiSigOutput = depositTx.getOutput(0);
Transaction tx = new Transaction(params);
@NotNull Transaction tx = new Transaction(params);
tx.addInput(multiSigOutput);
tx.addOutput(offererPaybackAmount, new Address(params, offererAddress));
tx.addOutput(takerPaybackAmount, new Address(params, takerAddress));
@ -1105,9 +1121,9 @@ public class WalletFacade
return tx;
}
private void printInputs(String tracePrefix, Transaction tx)
private void printInputs(String tracePrefix, @NotNull Transaction tx)
{
for (TransactionInput input : tx.getInputs())
for (@NotNull TransactionInput input : tx.getInputs())
if (input.getConnectedOutput() != null)
log.trace(tracePrefix + ": " + BtcFormatter.satoshiToString(input.getConnectedOutput().getValue()));
else
@ -1121,7 +1137,7 @@ public class WalletFacade
public static interface DownloadListener
{
void progress(double percent, int blocksSoFar, Date date);
void progress(double percent);
void doneDownload();
}
@ -1144,13 +1160,13 @@ public class WalletFacade
private void onProgressInUserThread(double percent, int blocksSoFar, final Date date)
{
for (DownloadListener downloadListener : downloadListeners)
downloadListener.progress(percent, blocksSoFar, date);
for (@NotNull DownloadListener downloadListener : downloadListeners)
downloadListener.progress(percent);
}
private void onDoneDownloadInUserThread()
{
for (DownloadListener downloadListener : downloadListeners)
for (@NotNull DownloadListener downloadListener : downloadListeners)
downloadListener.doneDownload();
}
}

View File

@ -5,6 +5,7 @@ import com.google.bitcoin.core.Utils;
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import java.security.SignatureException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,13 +23,13 @@ public class CryptoFacade
}
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts)
public byte[] getEmbeddedAccountRegistrationData(@NotNull ECKey registrationKey, String stringifiedBankAccounts)
{
String signedBankAccountIDs = registrationKey.signMessage(stringifiedBankAccounts);
return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8));
}
public String signContract(ECKey key, String contractAsJson)
public String signContract(@NotNull ECKey key, String contractAsJson)
{
return key.signMessage(contractAsJson);
}
@ -38,7 +39,7 @@ public class CryptoFacade
{
try
{
ECKey key = new ECKey(null, pubKey, true);
@NotNull ECKey key = new ECKey(null, pubKey, true);
key.verifyMessage(msg, sig);
return true;
} catch (SignatureException e)
@ -55,10 +56,11 @@ public class CryptoFacade
private byte[] createHash(String msg, String sig)
{
byte[] hashBytes = concatenateChunks(msg, sig).getBytes(Charsets.UTF_8);
@NotNull byte[] hashBytes = concatenateChunks(msg, sig).getBytes(Charsets.UTF_8);
return Utils.sha256hash160(hashBytes);
}
@NotNull
private String concatenateChunks(String stringifiedBankAccounts, String signedBankAccountIDs)
{
return stringifiedBankAccounts + signedBankAccountIDs;

View File

@ -22,8 +22,9 @@ import io.bitsquare.trade.Trading;
import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
import io.bitsquare.util.Utilities;
import java.io.File;
import io.bitsquare.util.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BitSquareModule extends AbstractModule
{
@ -66,9 +67,10 @@ class BitSquareWalletAppKitProvider implements Provider<BitSquareWalletAppKit>
this.networkParameters = networkParameters;
}
@NotNull
public BitSquareWalletAppKit get()
{
return new BitSquareWalletAppKit(networkParameters, new File(Utilities.getRootDir()), WalletFacade.WALLET_PREFIX);
return new BitSquareWalletAppKit(networkParameters, FileUtil.getRootDirectory());
}
}
@ -82,9 +84,10 @@ class NetworkParametersProvider implements Provider<NetworkParameters>
this.networkType = networkType;
}
@Nullable
public NetworkParameters get()
{
NetworkParameters result = null;
@Nullable NetworkParameters result = null;
switch (networkType)
{

View File

@ -11,7 +11,7 @@ import javafx.util.Callback;
* Once set, make sure you do <b>not</b> use the static methods on
* {@link javafx.fxml.FXMLLoader} when creating your JavaFX node.
*/
public class GuiceControllerFactory implements Callback<Class<?>, Object>
class GuiceControllerFactory implements Callback<Class<?>, Object>
{
private final Injector injector;

View File

@ -4,7 +4,7 @@ import com.google.inject.Injector;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXMLLoader;
import javafx.util.BuilderFactory;
import org.jetbrains.annotations.Nullable;
/**
* Guice support for fxml controllers
@ -12,9 +12,11 @@ import javafx.util.BuilderFactory;
public class GuiceFXMLLoader extends FXMLLoader
{
@Nullable
private static Injector injector = null;
public GuiceFXMLLoader()
// not used yet
/* public GuiceFXMLLoader()
{
super();
setupControllerFactory();
@ -26,19 +28,20 @@ public class GuiceFXMLLoader extends FXMLLoader
setupControllerFactory();
}
public GuiceFXMLLoader(URL url, ResourceBundle resourceBundle, BuilderFactory builderFactory)
{
super(url, resourceBundle, builderFactory);
setupControllerFactory();
} */
public GuiceFXMLLoader(URL url, ResourceBundle resourceBundle)
{
super(url, resourceBundle);
setupControllerFactory();
}
public GuiceFXMLLoader(URL url, ResourceBundle resourceBundle, BuilderFactory builderFactory)
{
super(url, resourceBundle, builderFactory);
setupControllerFactory();
}
public static void setInjector(Injector injector)
public static void setInjector(@Nullable Injector injector)
{
GuiceFXMLLoader.injector = injector;
}

View File

@ -1,8 +1,10 @@
package io.bitsquare.gui;
import org.jetbrains.annotations.NotNull;
public interface ChildController
{
void setNavigationController(NavigationController navigationController);
void setNavigationController(@NotNull NavigationController navigationController);
void cleanup();
}

View File

@ -9,6 +9,7 @@ import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.components.NetworkSyncPane;
import io.bitsquare.gui.market.MarketController;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.Transitions;
import io.bitsquare.locale.Localisation;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.msg.TradeMessage;
@ -19,7 +20,6 @@ import io.bitsquare.user.User;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.util.Date;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.collections.FXCollections;
@ -36,6 +36,8 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import net.tomp2p.peers.PeerAddress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -44,23 +46,19 @@ public class MainController implements Initializable, NavigationController
private static final Logger log = LoggerFactory.getLogger(MainController.class);
private static MainController mainController;
private final User user;
private final WalletFacade walletFacade;
private final MessageFacade messageFacade;
private final Trading trading;
private final Storage storage;
private final String selectedNavigationItemStorageId;
private final ToggleGroup toggleGroup = new ToggleGroup();
@Nullable
private ChildController childController;
private NavigationItem selectedNavigationItem;
private NetworkSyncPane networkSyncPane;
private ToggleButton prevToggleButton;
private Image prevToggleButtonIcon;
private ToggleButton buyButton, sellButton, homeButton, msgButton, ordersButton, fundsButton, settingsButton;
private Pane msgButtonHolder, ordersButtonButtonHolder;
private TextField balanceTextField;
private Pane ordersButtonButtonHolder;
@FXML
private Pane contentPane;
@ -72,6 +70,8 @@ public class MainController implements Initializable, NavigationController
private AnchorPane rootPane;
@FXML
private Label loadingLabel;
@FXML
private NetworkSyncPane networkSyncPane;
///////////////////////////////////////////////////////////////////////////////////////////
@ -79,7 +79,7 @@ public class MainController implements Initializable, NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade, Trading trading, Storage storage)
private MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade, Trading trading, Storage storage)
{
this.user = user;
this.walletFacade = walletFacade;
@ -88,11 +88,14 @@ public class MainController implements Initializable, NavigationController
this.storage = storage;
MainController.mainController = this;
selectedNavigationItemStorageId = this.getClass().getName() + ".selectedNavigationItem";
}
public static MainController getInstance()
///////////////////////////////////////////////////////////////////////////////////////////
// Static
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public static MainController INSTANCE()
{
return mainController;
}
@ -108,81 +111,14 @@ public class MainController implements Initializable, NavigationController
Platform.runLater(this::init);
}
public void init()
{
networkSyncPane = new NetworkSyncPane();
networkSyncPane.setSpacing(10);
networkSyncPane.setPrefHeight(20);
messageFacade.init();
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
{
@Override
public void progress(double percent, int blocksSoFar, Date date)
{
networkSyncPane.setProgress(percent);
}
@Override
public void doneDownload()
{
networkSyncPane.doneDownload();
}
});
walletFacade.initWallet();
buildNavigation();
Object f = storage.read(selectedNavigationItemStorageId);
selectedNavigationItem = (NavigationItem) storage.read(selectedNavigationItemStorageId);
if (selectedNavigationItem == null)
selectedNavigationItem = NavigationItem.HOME;
navigateToView(selectedNavigationItem);
AnchorPane.setBottomAnchor(networkSyncPane, 0.0);
AnchorPane.setLeftAnchor(networkSyncPane, 0.0);
messageFacade.addTakeOfferRequestListener(this::showTakeOfferRequest);
loadingBar.setProgress(-1);
rootPane.getChildren().removeAll(loadingLabel, loadingBar);
leftNavPane.setVisible(true);
rightNavPane.setVisible(true);
contentPane.setVisible(true);
}
private void showTakeOfferRequest(final TradeMessage tradeMessage, PeerAddress sender)
{
trading.createOffererPaymentProtocol(tradeMessage, sender);
try
{
ImageView newTradeRequestIcon = Icons.getIconImageView(Icons.MSG_ALERT);
Button alertButton = new Button("", newTradeRequestIcon);
alertButton.setId("nav-alert-button");
alertButton.relocate(36, 19);
Tooltip.install(alertButton, new Tooltip("Someone accepted your offer"));
alertButton.setOnAction((e) -> ordersButton.fire());
ordersButtonButtonHolder.getChildren().add(alertButton);
} catch (NullPointerException e)
{
log.warn("showTakeOfferRequest failed because of a NullPointerException");
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
switch (navigationItem)
{
@ -208,10 +144,11 @@ public class MainController implements Initializable, NavigationController
buyButton.fire();
break;
}
return null;
return childController;
}
private ChildController loadView(NavigationItem navigationItem)
@Nullable
private ChildController loadView(@NotNull NavigationItem navigationItem)
{
if (childController != null)
childController.cleanup();
@ -223,18 +160,68 @@ public class MainController implements Initializable, NavigationController
contentPane.getChildren().setAll(view);
childController = loader.getController();
childController.setNavigationController(this);
return childController;
} catch (IOException e)
{
e.printStackTrace();
log.error("Loading view failed. " + navigationItem.getFxmlUrl());
}
return null;
return childController;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void init()
{
messageFacade.init();
messageFacade.addTakeOfferRequestListener(this::showTakeOfferRequest);
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
{
@Override
public void progress(double percent)
{
networkSyncPane.setProgress(percent);
}
@Override
public void doneDownload()
{
networkSyncPane.doneDownload();
}
});
walletFacade.initWallet();
buildNavigation();
Transitions.fadeOutAndRemove(loadingLabel);
Transitions.fadeOutAndRemove(loadingBar);
Transitions.fadeIn(leftNavPane);
Transitions.fadeIn(rightNavPane);
Transitions.fadeIn(contentPane);
NavigationItem selectedNavigationItem = (NavigationItem) storage.read(this, "selectedNavigationItem");
if (selectedNavigationItem == null)
selectedNavigationItem = NavigationItem.HOME;
navigateToView(selectedNavigationItem);
}
private void showTakeOfferRequest(@NotNull TradeMessage tradeMessage, @NotNull PeerAddress sender)
{
trading.createOffererPaymentProtocol(tradeMessage, sender);
final Button alertButton = new Button("", Icons.getIconImageView(Icons.MSG_ALERT));
alertButton.setId("nav-alert-button");
alertButton.relocate(36, 19);
alertButton.setOnAction((e) -> ordersButton.fire());
Tooltip.install(alertButton, new Tooltip("Someone accepted your offer"));
ordersButtonButtonHolder.getChildren().add(alertButton);
}
private void buildNavigation()
{
homeButton = addNavButton(leftNavPane, "Overview", NavigationItem.HOME);
@ -249,7 +236,7 @@ public class MainController implements Initializable, NavigationController
fundsButton = addNavButton(leftNavPane, "Funds", NavigationItem.FUNDS);
msgButtonHolder = new Pane();
final Pane msgButtonHolder = new Pane();
msgButton = addNavButton(msgButtonHolder, "Message", NavigationItem.MSG);
leftNavPane.getChildren().add(msgButtonHolder);
@ -259,11 +246,12 @@ public class MainController implements Initializable, NavigationController
settingsButton = addNavButton(rightNavPane, "Settings", NavigationItem.SETTINGS);
}
private ToggleButton addNavButton(Pane parent, String title, NavigationItem navigationItem)
@NotNull
private ToggleButton addNavButton(@NotNull Pane parent, @NotNull String title, @NotNull NavigationItem navigationItem)
{
Pane pane = new Pane();
final Pane pane = new Pane();
pane.setPrefSize(50, 50);
ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(navigationItem.getIcon()));
final ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(navigationItem.getIcon()));
toggleButton.setToggleGroup(toggleGroup);
toggleButton.setId("nav-button");
toggleButton.setPrefSize(50, 50);
@ -280,13 +268,12 @@ public class MainController implements Initializable, NavigationController
if (childController instanceof MarketController)
((MarketController) childController).setDirection(navigationItem == NavigationItem.BUY ? Direction.BUY : Direction.SELL);
storage.write(selectedNavigationItemStorageId, navigationItem);
storage.write(this, "selectedNavigationItem", navigationItem);
prevToggleButton = toggleButton;
});
Label titleLabel = new Label(title);
final Label titleLabel = new Label(title);
titleLabel.setPrefWidth(60);
titleLabel.setLayoutY(40);
titleLabel.setId("nav-button-label");
@ -298,34 +285,13 @@ public class MainController implements Initializable, NavigationController
return toggleButton;
}
private TextField addBalanceInfo(Pane parent)
private void addBalanceInfo(@NotNull Pane parent)
{
balanceTextField = new TextField();
final TextField balanceTextField = new TextField();
balanceTextField.setEditable(false);
balanceTextField.setPrefWidth(90);
balanceTextField.setId("nav-balance-label");
balanceTextField.setText(BtcFormatter.formatSatoshis(walletFacade.getWalletBalance(), false));
Label balanceCurrencyLabel = new Label("BTC");
balanceCurrencyLabel.setPadding(new Insets(6, 0, 0, 0));
HBox hBox = new HBox();
hBox.setSpacing(2);
hBox.getChildren().setAll(balanceTextField, balanceCurrencyLabel);
VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 0, 0, 0));
vBox.setSpacing(2);
Label titleLabel = new Label("Balance");
titleLabel.setMouseTransparent(true);
titleLabel.setPrefWidth(90);
titleLabel.setId("nav-button-label");
vBox.getChildren().setAll(hBox, titleLabel);
parent.getChildren().add(vBox);
balanceTextField.setText(BtcFormatter.satoshiToString(walletFacade.getWalletBalance()));
walletFacade.addBalanceListener(new BalanceListener()
{
@Override
@ -335,24 +301,43 @@ public class MainController implements Initializable, NavigationController
}
});
return balanceTextField;
final Label balanceCurrencyLabel = new Label("BTC");
balanceCurrencyLabel.setPadding(new Insets(6, 0, 0, 0));
final HBox hBox = new HBox();
hBox.setSpacing(2);
hBox.getChildren().setAll(balanceTextField, balanceCurrencyLabel);
final Label titleLabel = new Label("Balance");
titleLabel.setMouseTransparent(true);
titleLabel.setPrefWidth(90);
titleLabel.setId("nav-button-label");
final VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 0, 0, 0));
vBox.setSpacing(2);
vBox.getChildren().setAll(hBox, titleLabel);
parent.getChildren().add(vBox);
}
private void addAccountComboBox(Pane parent)
private void addAccountComboBox(@NotNull Pane parent)
{
if (user.getBankAccounts().size() > 1)
{
ComboBox<BankAccount> accountComboBox = new ComboBox(FXCollections.observableArrayList(user.getBankAccounts()));
final ComboBox<BankAccount> accountComboBox = new ComboBox<>(FXCollections.observableArrayList(user.getBankAccounts()));
accountComboBox.setLayoutY(12);
accountComboBox.setValue(user.getCurrentBankAccount());
accountComboBox.valueProperty().addListener((ov, oldValue, newValue) -> user.setCurrentBankAccount(newValue));
accountComboBox.setConverter(new StringConverter<BankAccount>()
{
@NotNull
@Override
public String toString(BankAccount bankAccount)
public String toString(@NotNull BankAccount bankAccount)
{
return bankAccount.getAccountTitle();
}
@Nullable
@Override
public BankAccount fromString(String s)
{
@ -360,21 +345,17 @@ public class MainController implements Initializable, NavigationController
}
});
VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 0, 0, 0));
vBox.setSpacing(2);
Label titleLabel = new Label("Bank account");
final Label titleLabel = new Label("Bank account");
titleLabel.setMouseTransparent(true);
titleLabel.setPrefWidth(90);
titleLabel.setId("nav-button-label");
final VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 0, 0, 0));
vBox.setSpacing(2);
vBox.getChildren().setAll(accountComboBox, titleLabel);
parent.getChildren().add(vBox);
accountComboBox.valueProperty().addListener((ov, oldValue, newValue) -> user.setCurrentBankAccount(newValue));
}
}
}

View File

@ -1,14 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import io.bitsquare.gui.components.NetworkSyncPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:id="rootPane" id="root-pane" fx:controller="io.bitsquare.gui.MainController"
stylesheets="/io/bitsquare/gui/bitsquare.css" xmlns="http://javafx.com/javafx/8">
<HBox fx:id="leftNavPane" visible="false" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
<HBox fx:id="rightNavPane" visible="false" spacing="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="0"/>
<AnchorPane fx:id="contentPane" id="content-pane" visible="false" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/>
<HBox fx:id="leftNavPane" opacity="0" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
<HBox fx:id="rightNavPane" opacity="0" spacing="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="0"/>
<AnchorPane fx:id="contentPane" id="content-pane" opacity="0" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/>
<NetworkSyncPane fx:id="networkSyncPane" spacing="10" prefHeight="20" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
<ProgressBar fx:id="loadingBar" prefHeight="20" prefWidth="200" AnchorPane.topAnchor="250" AnchorPane.leftAnchor="300"/>
<ProgressBar fx:id="loadingBar" progress="-1" prefHeight="20" prefWidth="200" AnchorPane.topAnchor="250" AnchorPane.leftAnchor="300"/>
<Label fx:id="loadingLabel" text="Loading..." textAlignment="CENTER" alignment="CENTER" prefHeight="20" prefWidth="200" AnchorPane.topAnchor="280" AnchorPane.leftAnchor="300"/>
</AnchorPane>

View File

@ -1,6 +1,10 @@
package io.bitsquare.gui;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface NavigationController
{
ChildController navigateToView(NavigationItem navigationItem);
@Nullable
ChildController navigateToView(@NotNull NavigationItem navigationItem);
}

View File

@ -4,48 +4,45 @@ import io.bitsquare.gui.util.Icons;
public enum NavigationItem
{
MAIN("MAIN", "/io/bitsquare/gui/MainView.fxml"),
HOME("HOME", "/io/bitsquare/gui/home/HomeView.fxml", Icons.HOME, Icons.HOME_ACTIVE),
BUY("BUY", "/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE),
SELL("SELL", "/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE),
ORDERS("ORDERS", "/io/bitsquare/gui/orders/OrdersView.fxml", Icons.ORDERS, Icons.ORDERS_ACTIVE),
FUNDS("FUNDS", "/io/bitsquare/gui/funds/FundsView.fxml", Icons.FUNDS, Icons.FUNDS_ACTIVE),
MSG("MSG", "/io/bitsquare/gui/msg/MsgView.fxml", Icons.MSG, Icons.MSG_ACTIVE),
SETTINGS("SETTINGS", "/io/bitsquare/gui/settings/SettingsView.fxml", Icons.SETTINGS, Icons.SETTINGS_ACTIVE),
MAIN("/io/bitsquare/gui/MainView.fxml"),
HOME("/io/bitsquare/gui/home/HomeView.fxml", Icons.HOME, Icons.HOME_ACTIVE),
BUY("/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE),
SELL("/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE),
ORDERS("/io/bitsquare/gui/orders/OrdersView.fxml", Icons.ORDERS, Icons.ORDERS_ACTIVE),
FUNDS("/io/bitsquare/gui/funds/FundsView.fxml", Icons.FUNDS, Icons.FUNDS_ACTIVE),
MSG("/io/bitsquare/gui/msg/MsgView.fxml", Icons.MSG, Icons.MSG_ACTIVE),
SETTINGS("/io/bitsquare/gui/settings/SettingsView.fxml", Icons.SETTINGS, Icons.SETTINGS_ACTIVE),
ORDER_BOOK("ORDER_BOOK", "/io/bitsquare/gui/market/orderbook/OrderBookView.fxml"),
TAKER_TRADE("TAKER_TRADE", "/io/bitsquare/gui/market/trade/TakerTradeView.fxml"),
OFFERER_TRADE("OFFERER_TRADE", "/io/bitsquare/gui/orders/OffererTradeView.fxml"),
CREATE_OFFER("CREATE_OFFER", "/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml"),
ORDER_BOOK("/io/bitsquare/gui/market/orderbook/OrderBookView.fxml"),
CREATE_OFFER("/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml"),
TAKER_TRADE("/io/bitsquare/gui/market/trade/TakerTradeView.fxml"),
//OFFERER_TRADE("/io/bitsquare/gui/orders/OffererTradeView.fxml"),
CLOSED_TRADE("CLOSED_TRADE", "/io/bitsquare/gui/orders/closed/ClosedTradeView.fxml"),
OFFER("OFFER", "/io/bitsquare/gui/orders/offer/OfferView.fxml"),
PENDING_TRADE("PENDING_TRADE", "/io/bitsquare/gui/orders/pending/PendingTradeView.fxml"),
OFFER("/io/bitsquare/gui/orders/offer/OfferView.fxml"),
PENDING_TRADE("/io/bitsquare/gui/orders/pending/PendingTradeView.fxml"),
CLOSED_TRADE("/io/bitsquare/gui/orders/closed/ClosedTradeView.fxml"),
DEPOSIT("DEPOSIT", "/io/bitsquare/gui/funds/deposit/DepositView.fxml"),
WITHDRAWAL("WITHDRAWAL", "/io/bitsquare/gui/funds/withdrawal/WithdrawalView.fxml"),
TRANSACTIONS("TRANSACTIONS", "/io/bitsquare/gui/funds/transactions/TransactionsView.fxml"),
DEPOSIT("/io/bitsquare/gui/funds/deposit/DepositView.fxml"),
WITHDRAWAL("/io/bitsquare/gui/funds/withdrawal/WithdrawalView.fxml"),
TRANSACTIONS("/io/bitsquare/gui/funds/transactions/TransactionsView.fxml"),
ARBITRATOR_PROFILE("ARBITRATOR_PROFILE", "/io/bitsquare/gui/arbitrators/profile/ArbitratorProfileView.fxml"),
ARBITRATOR_OVERVIEW("ARBITRATOR_OVERVIEW", "/io/bitsquare/gui/arbitrators/overview/ArbitratorOverviewView.fxml"),
ARBITRATOR_REGISTRATION("ARBITRATOR_REGISTRATION", "/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml");
ARBITRATOR_PROFILE("/io/bitsquare/gui/arbitrators/profile/ArbitratorProfileView.fxml"),
ARBITRATOR_OVERVIEW("/io/bitsquare/gui/arbitrators/overview/ArbitratorOverviewView.fxml"),
ARBITRATOR_REGISTRATION("/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml");
private String fxmlUrl;
private String id;
private final String fxmlUrl;
private String icon;
private String activeIcon;
NavigationItem(String id, String fxmlUrl, String icon, String activeIcon)
NavigationItem(String fxmlUrl, String icon, String activeIcon)
{
this.id = id;
this.fxmlUrl = fxmlUrl;
this.icon = icon;
this.activeIcon = activeIcon;
}
NavigationItem(String id, String fxmlUrl)
NavigationItem(String fxmlUrl)
{
this.id = id;
this.fxmlUrl = fxmlUrl;
}
@ -54,11 +51,6 @@ public enum NavigationItem
return fxmlUrl;
}
public String getId()
{
return id;
}
public String getIcon()
{
return icon;

View File

@ -29,11 +29,15 @@ import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import net.tomp2p.peers.Number160;
import net.tomp2p.storage.Data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings({"ALL", "UnusedParameters"})
public class ArbitratorOverviewController implements Initializable, ChildController, NavigationController, ArbitratorListener
{
private final Settings settings;
private final Storage storage;
@NotNull
private final MessageFacade messageFacade;
private final List<Arbitrator> allArbitrators = new ArrayList<>();
private Arbitrator currentArbitrator;
@ -53,7 +57,7 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorOverviewController(Settings settings, Storage storage, MessageFacade messageFacade)
public ArbitratorOverviewController(Settings settings, Storage storage, @NotNull MessageFacade messageFacade)
{
this.settings = settings;
@ -82,7 +86,7 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -98,13 +102,14 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
if (arbitratorProfileController != null)
arbitratorProfileController.cleanup();
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
try
{
final Node view = loader.load();
@ -131,23 +136,23 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
}
@Override
public void onArbitratorsReceived(Map<Number160, Data> dataMap, boolean success)
public void onArbitratorsReceived(@Nullable Map<Number160, Data> dataMap, boolean success)
{
if (success && dataMap != null)
{
allArbitrators.clear();
for (Data arbitratorData : dataMap.values())
for (@NotNull Data arbitratorData : dataMap.values())
{
try
{
Object arbitratorDataObject = arbitratorData.getObject();
if (arbitratorDataObject instanceof Arbitrator && arbitratorDataObject != null)
if (arbitratorDataObject instanceof Arbitrator)
{
Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
@NotNull Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
allArbitrators.add(arbitrator);
}
} catch (ClassNotFoundException | IOException e)
} catch (@NotNull ClassNotFoundException | IOException e)
{
e.printStackTrace();
}
@ -158,7 +163,7 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
allArbitrators.clear();
}
if (allArbitrators.size() > 0)
if (!allArbitrators.isEmpty())
{
index = 0;
currentArbitrator = allArbitrators.get(index);
@ -211,7 +216,7 @@ public class ArbitratorOverviewController implements Initializable, ChildControl
@FXML
public void onClose(ActionEvent actionEvent)
{
Stage stage = (Stage) rootContainer.getScene().getWindow();
@NotNull Stage stage = (Stage) rootContainer.getScene().getWindow();
stage.close();
}

View File

@ -14,10 +14,15 @@ import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("ALL")
public class ArbitratorProfileController implements Initializable, ChildController
{
@NotNull
private final Settings settings;
@NotNull
private final Storage storage;
private Arbitrator arbitrator;
private NavigationController navigationController;
@ -36,15 +41,13 @@ public class ArbitratorProfileController implements Initializable, ChildControll
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorProfileController(Settings settings, Storage storage)
public ArbitratorProfileController(@NotNull Settings settings, @NotNull Storage storage)
{
this.settings = settings;
this.storage = storage;
Settings savedSettings = (Settings) storage.read(settings.getClass().getName());
if (savedSettings != null)
settings.updateFromStorage(savedSettings);
// @NotNull Settings savedSettings = (Settings) storage.read(settings.getClass().getName());
// settings.updateFromStorage(savedSettings);
}
@ -52,11 +55,11 @@ public class ArbitratorProfileController implements Initializable, ChildControll
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void applyArbitrator(Arbitrator arbitrator)
public void applyArbitrator(@Nullable Arbitrator arbitrator)
{
if (arbitrator != null)
{
String name = "";
@NotNull String name = "";
switch (arbitrator.getIdType())
{
case REAL_LIFE_ID:
@ -99,7 +102,7 @@ public class ArbitratorProfileController implements Initializable, ChildControll
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -38,9 +38,12 @@ import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"ALL", "EmptyMethod", "UnusedParameters"})
public class ArbitratorRegistrationController implements Initializable, ChildController
{
private static final Logger log = LoggerFactory.getLogger(ArbitratorRegistrationController.class);
@ -48,11 +51,14 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
private final Storage storage;
private final WalletFacade walletFacade;
private final MessageFacade messageFacade;
private Arbitrator arbitrator;
private Arbitrator arbitrator = new Arbitrator();
private ArbitratorProfileController arbitratorProfileController;
private boolean isEditMode;
@NotNull
private List<Locale> languageList = new ArrayList<>();
@NotNull
private List<Arbitrator.METHOD> methodList = new ArrayList<>();
@NotNull
private List<Arbitrator.ID_VERIFICATION> idVerificationList = new ArrayList<>();
private Arbitrator.ID_TYPE idType;
private ConfidenceDisplay confidenceDisplay;
@ -89,7 +95,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorRegistrationController(Storage storage, WalletFacade walletFacade, MessageFacade messageFacade)
private ArbitratorRegistrationController(Storage storage, WalletFacade walletFacade, MessageFacade messageFacade)
{
this.storage = storage;
this.walletFacade = walletFacade;
@ -101,7 +107,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setEditMode(boolean isEditMode)
public void setEditMode(@SuppressWarnings("SameParameterValue") boolean isEditMode)
{
this.isEditMode = isEditMode;
@ -123,7 +129,6 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
{
accordion.setExpandedPane(profileTitledPane);
arbitrator = new Arbitrator();
Arbitrator savedArbitrator = (Arbitrator) storage.read(arbitrator.getClass().getName());
if (savedArbitrator != null)
{
@ -140,11 +145,12 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
languageComboBox.setConverter(new StringConverter<Locale>()
{
@Override
public String toString(Locale locale)
public String toString(@NotNull Locale locale)
{
return locale.getDisplayLanguage();
}
@Nullable
@Override
public Locale fromString(String s)
{
@ -155,12 +161,14 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
idTypeComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class))));
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>()
{
@NotNull
@Override
public String toString(Arbitrator.ID_TYPE item)
public String toString(@NotNull Arbitrator.ID_TYPE item)
{
return Localisation.get(item.toString());
}
@Nullable
@Override
public Arbitrator.ID_TYPE fromString(String s)
{
@ -171,12 +179,14 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD.class))));
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>()
{
@NotNull
@Override
public String toString(Arbitrator.METHOD item)
public String toString(@NotNull Arbitrator.METHOD item)
{
return Localisation.get(item.toString());
}
@Nullable
@Override
public Arbitrator.METHOD fromString(String s)
{
@ -187,12 +197,14 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
idVerificationsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class))));
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>()
{
@NotNull
@Override
public String toString(Arbitrator.ID_VERIFICATION item)
public String toString(@NotNull Arbitrator.ID_VERIFICATION item)
{
return Localisation.get(item.toString());
}
@Nullable
@Override
public Arbitrator.ID_VERIFICATION fromString(String s)
{
@ -207,7 +219,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@ -229,7 +241,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
{
idTypeTextField.setText(Localisation.get(idType.toString()));
String name = "";
@NotNull String name = "";
switch (idType)
{
case REAL_LIFE_ID:
@ -358,24 +370,25 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
"depending on the overall relation of negative to positive ratings you received after a dispute resolution.\n\n" +
"Please pay in " + arbitrator.getMaxTradeVolume() * 10 + " BTC");
String collateralAddress = walletFacade.getRegistrationAddressInfo().toString();
String collateralAddress = walletFacade.getRegistrationAddressInfo() != null ? walletFacade.getRegistrationAddressInfo().toString() : "";
collateralAddressTextField.setText(collateralAddress);
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
@NotNull ClipboardContent content = new ClipboardContent();
content.putString(collateralAddress);
clipboard.setContent(content);
});
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, balanceTextField, progressIndicator);
paymentDoneButton.setDisable(walletFacade.getArbitratorDepositBalance().compareTo(BigInteger.ZERO) == 0);
log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance().toString());
log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance());
walletFacade.getWallet().addEventListener(new WalletEventListener()
{
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, @NotNull BigInteger newBalance)
{
paymentDoneButton.setDisable(newBalance.compareTo(BigInteger.ZERO) == 0);
}
@ -416,7 +429,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
{
if (arbitrator != null)
{
String name = "";
@NotNull String name = "";
switch (arbitrator.getIdType())
{
case REAL_LIFE_ID:
@ -451,6 +464,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
}
}
@Nullable
private Arbitrator getEditedArbitrator()
{
try
@ -494,7 +508,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon
private void close()
{
Stage stage = (Stage) rootContainer.getScene().getWindow();
@NotNull Stage stage = (Stage) rootContainer.getScene().getWindow();
stage.close();
}

View File

@ -158,7 +158,7 @@
#form-entry-value {
}
/* tabpane */
/* tab pane */
.tab-pane .tab-label {
-fx-font-size: 15;
}

View File

@ -3,13 +3,14 @@ package io.bitsquare.gui.components;
import javafx.scene.layout.Pane;
@SuppressWarnings("WeakerAccess")
public class HSpacer extends Pane
{
public HSpacer()
{
}
public HSpacer(double width)
public HSpacer(@SuppressWarnings("SameParameterValue") double width)
{
setPrefWidth(width);
}

View File

@ -13,12 +13,14 @@ import javafx.scene.Node;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LazyLoadingTabPane extends TabPane
{
private final Map<Integer, Node> views = new HashMap<>();
private final Map<Integer, ChildController> controllers = new HashMap<>();
SingleSelectionModel<Tab> selectionModel;
private SingleSelectionModel<Tab> selectionModel;
private String storageId;
private NavigationController navigationController;
private String[] tabContentFXMLUrls;
@ -35,7 +37,7 @@ public class LazyLoadingTabPane extends TabPane
super();
}
public void initialize(NavigationController navigationController, Storage storage, String... tabContentFXMLUrls)
public void initialize(@NotNull NavigationController navigationController, @NotNull Storage storage, @NotNull String... tabContentFXMLUrls)
{
if (tabContentFXMLUrls.length == 0)
throw new IllegalArgumentException("No tabContentFXMLUrls defined");
@ -63,6 +65,7 @@ public class LazyLoadingTabPane extends TabPane
childController.cleanup();
}
@Nullable
public ChildController navigateToView(String fxmlView)
{
for (int i = 0; i < tabContentFXMLUrls.length; i++)
@ -85,7 +88,7 @@ public class LazyLoadingTabPane extends TabPane
if (childController != null)
((Hibernate) childController).sleep();
Node view = null;
@Nullable Node view = null;
if (index < views.size())
{
view = views.get(index);
@ -94,7 +97,7 @@ public class LazyLoadingTabPane extends TabPane
if (view == null)
{
String fxmlView = tabContentFXMLUrls[index];
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
try
{
view = loader.load();

View File

@ -6,10 +6,13 @@ import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.util.Duration;
import org.jetbrains.annotations.NotNull;
public class NetworkSyncPane extends HBox
{
@NotNull
private final ProgressBar networkSyncProgressBar;
@NotNull
private final Label networkSyncInfoLabel;
public NetworkSyncPane()
@ -34,7 +37,7 @@ public class NetworkSyncPane extends HBox
networkSyncInfoLabel.setText("Sync with network: Done");
networkSyncProgressBar.setProgress(1);
FadeTransition fade = new FadeTransition(Duration.millis(700), this);
@NotNull FadeTransition fade = new FadeTransition(Duration.millis(700), this);
fade.setToValue(0.0);
fade.setCycleCount(1);
fade.setInterpolator(Interpolator.EASE_BOTH);

View File

@ -2,7 +2,7 @@ package io.bitsquare.gui.components;
import javafx.scene.control.ScrollPane;
public class NoFocusScrollPane extends ScrollPane
class NoFocusScrollPane extends ScrollPane
{
public NoFocusScrollPane()
{

View File

@ -9,6 +9,7 @@ public class VSpacer extends Pane
{
}
@SuppressWarnings("SameParameterValue")
public VSpacer(double height)
{
setPrefHeight(height);

View File

@ -34,6 +34,7 @@ import javafx.css.PseudoClass;
import javafx.css.StyleableProperty;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import org.jetbrains.annotations.NotNull;
/**
@ -64,6 +65,7 @@ import javafx.scene.control.Skin;
* @since JavaFX 2.0
*/
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
public class ConfidenceProgressIndicator extends Control
{
@ -175,12 +177,14 @@ public class ConfidenceProgressIndicator extends Control
pseudoClassStateChanged(PSEUDO_CLASS_DETERMINATE, !active);
}
@NotNull
@Override
public Object getBean()
{
return ConfidenceProgressIndicator.this;
}
@NotNull
@Override
public String getName()
{
@ -229,12 +233,14 @@ public class ConfidenceProgressIndicator extends Control
setIndeterminate(getProgress() < 0.0);
}
@NotNull
@Override
public Object getBean()
{
return ConfidenceProgressIndicator.this;
}
@NotNull
@Override
public String getName()
{
@ -248,6 +254,7 @@ public class ConfidenceProgressIndicator extends Control
/**
* {@inheritDoc}
*/
@NotNull
@Override
protected Skin<?> createDefaultSkin()
{
@ -259,8 +266,6 @@ public class ConfidenceProgressIndicator extends Control
* this method to return true, but ProgressIndicator returns false for
* focusTraversable's initial value; hence the override of the override.
* This method is called from CSS code to get the correct initial value.
*
* @treatAsPrivate implementation detail
*/
@Deprecated
@Override

View File

@ -59,7 +59,10 @@ import javafx.scene.shape.ArcType;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Scale;
import javafx.util.Duration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings({"WeakerAccess", "SameReturnValue"})
public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<ConfidenceProgressIndicator, ConfidenceProgressIndicatorBehavior<ConfidenceProgressIndicator>>
{
@ -81,10 +84,12 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
doneText.getStyleClass().add("text");
} */
@Nullable
private IndeterminateSpinner spinner;
/**
* The number of segments in the spinner.
*/
@Nullable
private final IntegerProperty indeterminateSegmentCount =
new StyleableIntegerProperty(8)
{
@ -95,18 +100,21 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
if (spinner != null) spinner.rebuild();
}
@NotNull
@Override
public Object getBean()
{
return ConfidenceProgressIndicatorSkin.this;
}
@NotNull
@Override
public String getName()
{
return "indeterminateSegmentCount";
}
@Nullable
@Override
public CssMetaData<ConfidenceProgressIndicator, Number> getCssMetaData()
{
@ -116,6 +124,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
/**
* True if the progress indicator should rotate as well as animate opacity.
*/
@Nullable
private final BooleanProperty spinEnabled = new StyleableBooleanProperty(false)
{
@Override
@ -124,28 +133,33 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
if (spinner != null) spinner.setSpinEnabled(get());
}
@Nullable
@Override
public CssMetaData<ConfidenceProgressIndicator, Boolean> getCssMetaData()
{
return StyleableProperties.SPIN_ENABLED;
}
@NotNull
@Override
public Object getBean()
{
return ConfidenceProgressIndicatorSkin.this;
}
@NotNull
@Override
public String getName()
{
return "spinEnabled";
}
};
@Nullable
private DeterminateIndicator determinateIndicator;
/**
* The colour of the progress segment.
*/
@Nullable
private final ObjectProperty<Paint> progressColor =
new StyleableObjectProperty<Paint>(null)
{
@ -153,7 +167,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
@Override
public void set(Paint newProgressColor)
{
final Paint color = (newProgressColor instanceof Color)
@Nullable final Paint color = (newProgressColor instanceof Color)
? newProgressColor
: null;
super.set(color);
@ -166,18 +180,21 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
if (determinateIndicator != null) determinateIndicator.setFillOverride(get());
}
@NotNull
@Override
public Object getBean()
{
return ConfidenceProgressIndicatorSkin.this;
}
@NotNull
@Override
public String getName()
{
return "progressColorProperty";
}
@Nullable
@Override
public CssMetaData<ConfidenceProgressIndicator, Paint> getCssMetaData()
{
@ -194,14 +211,14 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* ************************************************************************
*/
@SuppressWarnings("deprecation")
public ConfidenceProgressIndicatorSkin(ConfidenceProgressIndicator control)
public ConfidenceProgressIndicatorSkin(@NotNull ConfidenceProgressIndicator control)
{
super(control, new ConfidenceProgressIndicatorBehavior<>(control));
InvalidationListener indeterminateListener = valueModel -> initialize();
@NotNull InvalidationListener indeterminateListener = valueModel -> initialize();
control.indeterminateProperty().addListener(indeterminateListener);
InvalidationListener visibilityListener = new InvalidationListener()
@NotNull InvalidationListener visibilityListener = new InvalidationListener()
{
@Override
public void invalidated(Observable valueModel)
@ -232,7 +249,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
control.visibleProperty().addListener(visibilityListener);
control.parentProperty().addListener(visibilityListener);
InvalidationListener sceneListener = new InvalidationListener()
@NotNull InvalidationListener sceneListener = new InvalidationListener()
{
@Override
public void invalidated(Observable valueModel)
@ -362,23 +379,30 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* ************************************************************************
*/
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
static class DeterminateIndicator extends Region
{
//private double textGap = 2.0F;
@NotNull
private final ConfidenceProgressIndicator control;
//private Text text;
@NotNull
private final StackPane indicator;
@NotNull
private final StackPane progress;
@NotNull
private final StackPane tick;
@NotNull
private final Arc arcShape;
@NotNull
private final Circle indicatorCircle;
// only update progress text on whole percentages
private int intProgress;
// only update pie arc to nearest degree
private int degProgress;
public DeterminateIndicator(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, Paint fillOverride)
public DeterminateIndicator(@NotNull ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, Paint fillOverride)
{
this.control = control;
@ -387,7 +411,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
intProgress = (int) Math.round(control.getProgress() * 100.0);
degProgress = (int) (360 * control.getProgress());
InvalidationListener progressListener = valueModel -> updateProgress();
@NotNull InvalidationListener progressListener = valueModel -> updateProgress();
control.progressProperty().addListener(progressListener);
getChildren().clear();
@ -430,7 +454,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
{
if (fillOverride instanceof Color)
{
Color c = (Color) fillOverride;
@NotNull Color c = (Color) fillOverride;
progress.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");");
}
else
@ -602,17 +626,21 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* ************************************************************************
*/
@SuppressWarnings("ConstantConditions")
static class IndeterminateSpinner extends Region
{
private final ConfidenceProgressIndicator control;
private final ConfidenceProgressIndicatorSkin skin;
@NotNull
private final IndicatorPaths pathsG;
@NotNull
private final Timeline indeterminateTimeline;
private final List<Double> opacities = new ArrayList<>();
private boolean spinEnabled = false;
@Nullable
private Paint fillOverride = null;
public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, boolean spinEnabled, Paint fillOverride)
public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, boolean spinEnabled, @Nullable Paint fillOverride)
{
this.control = control;
this.skin = s;
@ -632,7 +660,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
rebuild();
}
public void setFillOverride(Paint fillOverride)
public void setFillOverride(@Nullable Paint fillOverride)
{
this.fillOverride = fillOverride;
rebuild();
@ -704,13 +732,13 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
final double step = 0.8 / (segments - 1);
for (int i = 0; i < segments; i++)
{
Region region = new Region();
@NotNull Region region = new Region();
region.setScaleShape(false);
region.setCenterShape(false);
region.getStyleClass().addAll("segment", "segment" + i);
if (fillOverride instanceof Color)
{
Color c = (Color) fillOverride;
@NotNull Color c = (Color) fillOverride;
region.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");");
}
else
@ -742,7 +770,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
{
super();
piSkin = pi;
InvalidationListener treeVisibilityListener = valueModel -> {
@NotNull InvalidationListener treeVisibilityListener = valueModel -> {
if (piSkin.skin.getSkinnable().impl_isTreeVisible())
{
piSkin.pauseIndicator(false);
@ -763,7 +791,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
{
if (child instanceof Region)
{
Region region = (Region) child;
@NotNull Region region = (Region) child;
if (region.getShape() != null)
{
w = Math.max(w, region.getShape().getLayoutBounds().getMaxX());
@ -785,7 +813,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
{
if (child instanceof Region)
{
Region region = (Region) child;
@NotNull Region region = (Region) child;
if (region.getShape() != null)
{
h = Math.max(h, region.getShape().getLayoutBounds().getMaxY());
@ -805,7 +833,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
// calculate scale
double scale = getWidth() / computePrefWidth(-1);
getChildren().stream().filter(child -> child instanceof Region).forEach(child -> {
Region region = (Region) child;
@NotNull Region region = (Region) child;
if (region.getShape() != null)
{
region.resize(
@ -825,83 +853,87 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
/**
* Super-lazy instantiation pattern from Bill Pugh.
*
* @treatAsPrivate implementation detail
*/
@SuppressWarnings({"deprecation", "unchecked"})
@SuppressWarnings({"deprecation", "unchecked", "ConstantConditions"})
private static class StyleableProperties
{
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
@Nullable
private static final CssMetaData<ConfidenceProgressIndicator, Paint> PROGRESS_COLOR =
new CssMetaData<ConfidenceProgressIndicator, Paint>("-fx-progress-color",
PaintConverter.getInstance(), null)
{
@Override
public boolean isSettable(ConfidenceProgressIndicator n)
public boolean isSettable(@NotNull ConfidenceProgressIndicator n)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return skin.progressColor == null ||
!skin.progressColor.isBound();
}
@Nullable
@Override
public StyleableProperty<Paint> getStyleableProperty(ConfidenceProgressIndicator n)
public StyleableProperty<Paint> getStyleableProperty(@NotNull ConfidenceProgressIndicator n)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return (StyleableProperty<Paint>) skin.progressColor;
}
};
@Nullable
private static final CssMetaData<ConfidenceProgressIndicator, Number> INDETERMINATE_SEGMENT_COUNT =
new CssMetaData<ConfidenceProgressIndicator, Number>("-fx-indeterminate-segment-count",
SizeConverter.getInstance(), 8)
{
@Override
public void set(ConfidenceProgressIndicator node, Number value, StyleOrigin origin)
public void set(ConfidenceProgressIndicator node, @NotNull Number value, StyleOrigin origin)
{
super.set(node, value.intValue(), origin);
}
@Override
public boolean isSettable(ConfidenceProgressIndicator n)
public boolean isSettable(@NotNull ConfidenceProgressIndicator n)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return skin.indeterminateSegmentCount == null ||
!skin.indeterminateSegmentCount.isBound();
}
@Nullable
@Override
public StyleableProperty<Number> getStyleableProperty(ConfidenceProgressIndicator n)
public StyleableProperty<Number> getStyleableProperty(@NotNull ConfidenceProgressIndicator n)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return (StyleableProperty<Number>) skin.indeterminateSegmentCount;
}
};
@Nullable
private static final CssMetaData<ConfidenceProgressIndicator, Boolean> SPIN_ENABLED =
new CssMetaData<ConfidenceProgressIndicator, Boolean>("-fx-spin-enabled",
BooleanConverter.getInstance(), Boolean.FALSE)
{
@Override
public boolean isSettable(ConfidenceProgressIndicator node)
public boolean isSettable(@NotNull ConfidenceProgressIndicator node)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
return skin.spinEnabled == null || !skin.spinEnabled.isBound();
}
@Nullable
@Override
public StyleableProperty<Boolean> getStyleableProperty(ConfidenceProgressIndicator node)
public StyleableProperty<Boolean> getStyleableProperty(@NotNull ConfidenceProgressIndicator node)
{
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
@NotNull final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
return (StyleableProperty<Boolean>) skin.spinEnabled;
}
};
static
{
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData());
@NotNull final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData());
styleables.add(PROGRESS_COLOR);
styleables.add(INDETERMINATE_SEGMENT_COUNT);
styleables.add(SPIN_ENABLED);

View File

@ -3,11 +3,14 @@ package io.bitsquare.gui.components.processbar;
import java.util.List;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ProcessStepBar<T> extends Control
{
@Nullable
private List<ProcessStepItem> processStepItems = null;
public ProcessStepBar()
@ -15,23 +18,25 @@ public class ProcessStepBar<T> extends Control
}
public ProcessStepBar(List<ProcessStepItem> processStepItems)
public ProcessStepBar(@Nullable List<ProcessStepItem> processStepItems)
{
this.processStepItems = processStepItems;
}
@NotNull
@Override
protected Skin<?> createDefaultSkin()
{
return new ProcessStepBarSkin<>(this);
}
@Nullable
List<ProcessStepItem> getProcessStepItems()
{
return processStepItems;
}
public void setProcessStepItems(List<ProcessStepItem> processStepItems)
public void setProcessStepItems(@Nullable List<ProcessStepItem> processStepItems)
{
this.processStepItems = processStepItems;
if (getSkin() != null)

View File

@ -16,15 +16,15 @@ import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import org.jetbrains.annotations.NotNull;
public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>>
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>>
{
final ProcessStepBar<T> controller;
LabelWithBorder currentLabelWithBorder;
LabelWithBorder prevLabelWithBorder;
int index;
List<LabelWithBorder> labelWithBorders;
private final ProcessStepBar<T> controller;
private LabelWithBorder currentLabelWithBorder;
private LabelWithBorder prevLabelWithBorder;
private int index;
private List<LabelWithBorder> labelWithBorders;
public ProcessStepBarSkin(final ProcessStepBar<T> control)
{
@ -47,9 +47,9 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
int i = 0;
labelWithBorders = new ArrayList<>();
int size = controller.getProcessStepItems().size();
for (ProcessStepItem processStepItem : controller.getProcessStepItems())
for (@NotNull ProcessStepItem processStepItem : controller.getProcessStepItems())
{
LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
@NotNull LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
getChildren().add(labelWithBorder);
labelWithBorders.add(labelWithBorder);
if (i == 0)
@ -100,16 +100,18 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
}
@SuppressWarnings("EmptyMethod")
public static class LabelWithBorder extends Label
{
final double borderWidth = 1;
private final double arrowWidth = 10;
private final double arrowHeight = 30;
@NotNull
private final ProcessStepItem processStepItem;
private final boolean isFirst;
private final boolean isLast;
public LabelWithBorder(ProcessStepItem processStepItem, boolean isFirst, boolean isLast)
public LabelWithBorder(@NotNull ProcessStepItem processStepItem, boolean isFirst, boolean isLast)
{
super(processStepItem.getLabel());
this.processStepItem = processStepItem;
@ -123,14 +125,14 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
this.setShape(createButtonShape());
BorderStroke borderStroke = new BorderStroke(Color.LIGHTGRAY, BorderStrokeStyle.SOLID, null,
@NotNull BorderStroke borderStroke = new BorderStroke(Color.LIGHTGRAY, BorderStrokeStyle.SOLID, null,
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke));
}
public void select()
{
BorderStroke borderStroke = new BorderStroke(processStepItem.getColor(), BorderStrokeStyle.SOLID, null,
@NotNull BorderStroke borderStroke = new BorderStroke(processStepItem.getColor(), BorderStrokeStyle.SOLID, null,
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke));
setTextFill(processStepItem.getColor());
@ -150,6 +152,7 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
return arrowWidth;
}
@NotNull
private Path createButtonShape()
{
// build the following shape (or home without left arrow)
@ -158,14 +161,14 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
// \ \
// / /
// --------
Path path = new Path();
@NotNull Path path = new Path();
// begin in the upper left corner
MoveTo e1 = new MoveTo(0, 0);
@NotNull MoveTo e1 = new MoveTo(0, 0);
path.getElements().add(e1);
// draw a horizontal line that defines the width of the shape
HLineTo e2 = new HLineTo();
@NotNull HLineTo e2 = new HLineTo();
// bind the width of the shape to the width of the button
e2.xProperty().bind(this.widthProperty().subtract(arrowWidth));
path.getElements().add(e2);
@ -173,7 +176,7 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
if (!isLast)
{
// draw upper part of right arrow
LineTo e3 = new LineTo();
@NotNull LineTo e3 = new LineTo();
// the x endpoint of this line depends on the x property of line e2
e3.xProperty().bind(e2.xProperty().add(arrowWidth));
e3.setY(arrowHeight / 2.0);
@ -182,24 +185,24 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
// draw lower part of right arrow
LineTo e4 = new LineTo();
@NotNull LineTo e4 = new LineTo();
// the x endpoint of this line depends on the x property of line e2
e4.xProperty().bind(e2.xProperty());
e4.setY(arrowHeight);
path.getElements().add(e4);
// draw lower horizontal line
HLineTo e5 = new HLineTo(0);
@NotNull HLineTo e5 = new HLineTo(0);
path.getElements().add(e5);
if (!isFirst)
{
LineTo e6 = new LineTo(arrowWidth, arrowHeight / 2.0);
@NotNull LineTo e6 = new LineTo(arrowWidth, arrowHeight / 2.0);
path.getElements().add(e6);
}
// close path
ClosePath e7 = new ClosePath();
@NotNull ClosePath e7 = new ClosePath();
path.getElements().add(e7);
// this is a dummy color to fill the shape, it won't be visible
path.setFill(Color.BLACK);

View File

@ -19,7 +19,7 @@ public class ProcessStepItem
this(label, color, false);
}
public ProcessStepItem(String label, Paint color, boolean hasProgressIndicator)
private ProcessStepItem(String label, Paint color, @SuppressWarnings("SameParameterValue") boolean hasProgressIndicator)
{
this.label = label;
this.color = color;

View File

@ -10,6 +10,7 @@ import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,7 +28,7 @@ public class FundsController implements Initializable, ChildController, Navigati
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public FundsController(Storage storage)
private FundsController(Storage storage)
{
this.storage = storage;
}
@ -49,7 +50,7 @@ public class FundsController implements Initializable, ChildController, Navigati
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@ -64,7 +65,7 @@ public class FundsController implements Initializable, ChildController, Navigati
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
return tabPane.navigateToView(navigationItem.getFxmlUrl());
}

View File

@ -11,16 +11,18 @@ import io.bitsquare.gui.NavigationController;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.util.Callback;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -29,7 +31,7 @@ public class DepositController implements Initializable, ChildController, Hibern
private static final Logger log = LoggerFactory.getLogger(DepositController.class);
private final WalletFacade walletFacade;
protected ObservableList<DepositListItem> addressList;
private ObservableList<DepositListItem> addressList;
@FXML
private TableView<DepositListItem> tableView;
@ -44,7 +46,7 @@ public class DepositController implements Initializable, ChildController, Hibern
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public DepositController(WalletFacade walletFacade)
private DepositController(WalletFacade walletFacade)
{
this.walletFacade = walletFacade;
}
@ -72,14 +74,14 @@ public class DepositController implements Initializable, ChildController, Hibern
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@Override
public void cleanup()
{
for (DepositListItem anAddressList : addressList)
for (@NotNull DepositListItem anAddressList : addressList)
{
anAddressList.cleanup();
}
@ -101,10 +103,7 @@ public class DepositController implements Initializable, ChildController, Hibern
{
List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList();
addressList = FXCollections.observableArrayList();
for (AddressEntry anAddressEntryList : addressEntryList)
{
addressList.add(new DepositListItem(anAddressEntryList, walletFacade));
}
addressList.addAll(addressEntryList.stream().map(anAddressEntryList -> new DepositListItem(anAddressEntryList, walletFacade)).collect(Collectors.toList()));
tableView.setItems(addressList);
}
@ -115,7 +114,7 @@ public class DepositController implements Initializable, ChildController, Hibern
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onAddNewTradeAddress(ActionEvent actionEvent)
public void onAddNewTradeAddress()
{
addressList.add(new DepositListItem(walletFacade.getNewTradeAddressEntry(), walletFacade));
}
@ -135,15 +134,17 @@ public class DepositController implements Initializable, ChildController, Hibern
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
@Nullable
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
@Nullable
Hyperlink hyperlink;
@Override
public void updateItem(final DepositListItem item, boolean empty)
public void updateItem(@Nullable final DepositListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -153,7 +154,7 @@ public class DepositController implements Initializable, ChildController, Hibern
hyperlink.setId("id-link");
if (item.getAddressEntry().getTradeId() != null)
{
Tooltip tooltip = new Tooltip(item.getAddressEntry().getTradeId());
@NotNull Tooltip tooltip = new Tooltip(item.getAddressEntry().getTradeId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getTradeId()));
@ -176,13 +177,14 @@ public class DepositController implements Initializable, ChildController, Hibern
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
@Nullable
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
@Override
public void updateItem(final DepositListItem item, boolean empty)
public void updateItem(@Nullable final DepositListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -205,6 +207,7 @@ public class DepositController implements Initializable, ChildController, Hibern
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
@Nullable
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
@ -219,7 +222,7 @@ public class DepositController implements Initializable, ChildController, Hibern
}
@Override
public void updateItem(final DepositListItem item, boolean empty)
public void updateItem(@Nullable final DepositListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -228,7 +231,7 @@ public class DepositController implements Initializable, ChildController, Hibern
setGraphic(copyIcon);
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
@NotNull ClipboardContent content = new ClipboardContent();
content.putString(item.addressStringProperty().get());
clipboard.setContent(content);
});
@ -249,6 +252,7 @@ public class DepositController implements Initializable, ChildController, Hibern
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
@Nullable
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
@ -256,7 +260,7 @@ public class DepositController implements Initializable, ChildController, Hibern
{
@Override
public void updateItem(final DepositListItem item, boolean empty)
public void updateItem(@Nullable final DepositListItem item, boolean empty)
{
super.updateItem(item, empty);

View File

@ -3,10 +3,11 @@ package io.bitsquare.gui.funds.deposit;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.funds.withdrawal.WithdrawalListItem;
import org.jetbrains.annotations.NotNull;
public class DepositListItem extends WithdrawalListItem
{
public DepositListItem(AddressEntry addressEntry, WalletFacade walletFacade)
public DepositListItem(@NotNull AddressEntry addressEntry, @NotNull WalletFacade walletFacade)
{
super(addressEntry, walletFacade);
}

View File

@ -14,7 +14,7 @@
<TableColumn text="Label" fx:id="labelColumn" minWidth="100" sortable="false"/>
<TableColumn text="Address" fx:id="addressColumn" minWidth="240" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="address"/>
<PropertyValueFactory property="addressString"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Balance" fx:id="balanceColumn" minWidth="50" sortable="false"/>

View File

@ -17,6 +17,8 @@ import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.util.Callback;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -25,7 +27,7 @@ public class TransactionsController implements Initializable, ChildController, H
private static final Logger log = LoggerFactory.getLogger(TransactionsController.class);
private final WalletFacade walletFacade;
protected ObservableList<TransactionsListItem> transactionsListItems;
private ObservableList<TransactionsListItem> transactionsListItems;
@FXML
private TableView<TransactionsListItem> tableView;
@ -40,7 +42,7 @@ public class TransactionsController implements Initializable, ChildController, H
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TransactionsController(WalletFacade walletFacade)
private TransactionsController(WalletFacade walletFacade)
{
this.walletFacade = walletFacade;
}
@ -66,14 +68,14 @@ public class TransactionsController implements Initializable, ChildController, H
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@Override
public void cleanup()
{
for (TransactionsListItem transactionsListItem : transactionsListItems)
for (@NotNull TransactionsListItem transactionsListItem : transactionsListItems)
{
transactionsListItem.cleanup();
}
@ -120,6 +122,7 @@ public class TransactionsController implements Initializable, ChildController, H
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
addressColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>()
{
@Nullable
@Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column)
{
@ -128,7 +131,7 @@ public class TransactionsController implements Initializable, ChildController, H
Hyperlink hyperlink;
@Override
public void updateItem(final TransactionsListItem item, boolean empty)
public void updateItem(@Nullable final TransactionsListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -155,6 +158,7 @@ public class TransactionsController implements Initializable, ChildController, H
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>()
{
@Nullable
@Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column)
{
@ -162,7 +166,7 @@ public class TransactionsController implements Initializable, ChildController, H
{
@Override
public void updateItem(final TransactionsListItem item, boolean empty)
public void updateItem(@Nullable final TransactionsListItem item, boolean empty)
{
super.updateItem(item, empty);

View File

@ -13,6 +13,8 @@ import java.math.BigInteger;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Tooltip;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,26 +24,27 @@ public class TransactionsListItem
private final StringProperty date = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
private final StringProperty type = new SimpleStringProperty();
private final Transaction transaction;
@NotNull
private final WalletFacade walletFacade;
@NotNull
private final ConfidenceProgressIndicator progressIndicator;
@NotNull
private final Tooltip tooltip;
private String addressString;
private ConfidenceListener confidenceListener;
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade)
public TransactionsListItem(@NotNull Transaction transaction, @NotNull WalletFacade walletFacade)
{
this.transaction = transaction;
this.walletFacade = walletFacade;
BigInteger valueSentToMe = transaction.getValueSentToMe(walletFacade.getWallet());
BigInteger valueSentFromMe = transaction.getValueSentFromMe(walletFacade.getWallet());
Address address = null;
@Nullable Address address = null;
if (valueSentToMe.compareTo(BigInteger.ZERO) == 0)
{
amount.set("-" + BtcFormatter.satoshiToString(valueSentFromMe));
for (TransactionOutput transactionOutput : transaction.getOutputs())
for (@NotNull TransactionOutput transactionOutput : transaction.getOutputs())
{
if (!transactionOutput.isMine(walletFacade.getWallet()))
{
@ -64,7 +67,7 @@ public class TransactionsListItem
amount.set(BtcFormatter.satoshiToString(valueSentToMe));
type.set("Received with");
for (TransactionOutput transactionOutput : transaction.getOutputs())
for (@NotNull TransactionOutput transactionOutput : transaction.getOutputs())
{
if (transactionOutput.isMine(walletFacade.getWallet()))
{
@ -85,7 +88,7 @@ public class TransactionsListItem
amount.set(BtcFormatter.satoshiToString(valueSentToMe.subtract(valueSentFromMe)));
boolean outgoing = false;
for (TransactionOutput transactionOutput : transaction.getOutputs())
for (@NotNull TransactionOutput transactionOutput : transaction.getOutputs())
{
if (!transactionOutput.isMine(walletFacade.getWallet()))
{
@ -145,7 +148,7 @@ public class TransactionsListItem
walletFacade.removeConfidenceListener(confidenceListener);
}
private void updateConfidence(TransactionConfidence confidence)
private void updateConfidence(@Nullable TransactionConfidence confidence)
{
if (confidence != null)
{
@ -175,21 +178,25 @@ public class TransactionsListItem
}
@NotNull
public ConfidenceProgressIndicator getProgressIndicator()
{
return progressIndicator;
}
@NotNull
public final StringProperty dateProperty()
{
return this.date;
}
@NotNull
public final StringProperty amountProperty()
{
return this.amount;
}
@NotNull
public final StringProperty typeProperty()
{
return this.type;

View File

@ -21,7 +21,6 @@ import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
@ -30,6 +29,8 @@ import javafx.scene.input.ClipboardContent;
import javafx.util.Callback;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -39,7 +40,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
private final WalletFacade walletFacade;
protected ObservableList<WithdrawalListItem> addressList;
private ObservableList<WithdrawalListItem> addressList;
@FXML
private TableView<WithdrawalListItem> tableView;
@ -56,7 +57,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public WithdrawalController(WalletFacade walletFacade)
private WithdrawalController(WalletFacade walletFacade)
{
this.walletFacade = walletFacade;
}
@ -82,7 +83,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
{
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
if (newValue.getBalance().compareTo(BigInteger.ZERO) > 0)
if (BigInteger.ZERO.compareTo(newValue.getBalance()) <= 0)
{
amountTextField.setText(BtcFormatter.satoshiToString(newValue.getBalance()));
withdrawFromTextField.setText(newValue.getAddressEntry().getAddressString());
@ -105,14 +106,14 @@ public class WithdrawalController implements Initializable, ChildController, Hib
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@Override
public void cleanup()
{
for (WithdrawalListItem anAddressList : addressList)
for (@NotNull WithdrawalListItem anAddressList : addressList)
{
anAddressList.cleanup();
}
@ -145,7 +146,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onWithdraw(ActionEvent actionEvent)
public void onWithdraw()
{
try
{
@ -155,17 +156,17 @@ public class WithdrawalController implements Initializable, ChildController, Hib
BigInteger amount = BtcFormatter.stringValueToSatoshis(amountTextField.getText());
if (BtcValidator.isMinSpendableAmount(amount))
{
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
@Override
public void onSuccess(Transaction transaction)
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString());
if (transaction != null) log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString());
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
log.debug("onWithdraw onFailure");
}
@ -223,15 +224,17 @@ public class WithdrawalController implements Initializable, ChildController, Hib
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
@Nullable
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
@Nullable
Hyperlink hyperlink;
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
public void updateItem(@Nullable final WithdrawalListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -241,7 +244,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
hyperlink.setId("id-link");
if (item.getAddressEntry().getTradeId() != null)
{
Tooltip tooltip = new Tooltip(item.getAddressEntry().getTradeId());
@NotNull Tooltip tooltip = new Tooltip(item.getAddressEntry().getTradeId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getTradeId()));
@ -264,13 +267,14 @@ public class WithdrawalController implements Initializable, ChildController, Hib
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
@NotNull
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
public void updateItem(@Nullable final WithdrawalListItem item, boolean empty)
{
super.updateItem(item, empty);
setGraphic((item != null && !empty) ? item.getBalanceLabel() : null);
@ -285,6 +289,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
@Nullable
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
@ -299,7 +304,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
}
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
public void updateItem(@Nullable final WithdrawalListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -308,7 +313,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
setGraphic(copyIcon);
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
@NotNull ClipboardContent content = new ClipboardContent();
content.putString(item.addressStringProperty().get());
clipboard.setContent(content);
});
@ -329,6 +334,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
@Nullable
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
@ -336,7 +342,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
{
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
public void updateItem(@Nullable final WithdrawalListItem item, boolean empty)
{
super.updateItem(item, empty);

View File

@ -13,20 +13,28 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class WithdrawalListItem
{
private final StringProperty addressString = new SimpleStringProperty();
private final BalanceListener balanceListener;
@NotNull
private final Label balanceLabel;
@NotNull
private final AddressEntry addressEntry;
@NotNull
private final WalletFacade walletFacade;
private final ConfidenceListener confidenceListener;
@NotNull
private final ConfidenceProgressIndicator progressIndicator;
@NotNull
private final Tooltip tooltip;
@Nullable
private BigInteger balance;
public WithdrawalListItem(AddressEntry addressEntry, WalletFacade walletFacade)
public WithdrawalListItem(@NotNull AddressEntry addressEntry, @NotNull WalletFacade walletFacade)
{
this.addressEntry = addressEntry;
this.walletFacade = walletFacade;
@ -73,7 +81,7 @@ public class WithdrawalListItem
walletFacade.removeBalanceListener(balanceListener);
}
private void updateBalance(BigInteger balance)
private void updateBalance(@Nullable BigInteger balance)
{
this.balance = balance;
if (balance != null)
@ -82,7 +90,7 @@ public class WithdrawalListItem
}
}
private void updateConfidence(TransactionConfidence confidence)
private void updateConfidence(@Nullable TransactionConfidence confidence)
{
if (confidence != null)
{
@ -111,6 +119,7 @@ public class WithdrawalListItem
}
}
@Nullable
public final String getLabel()
{
switch (addressEntry.getAddressContext())
@ -128,31 +137,36 @@ public class WithdrawalListItem
return "";
}
@NotNull
public final StringProperty addressStringProperty()
{
return this.addressString;
}
public Address getAddress()
Address getAddress()
{
return addressEntry.getAddress();
}
@NotNull
public AddressEntry getAddressEntry()
{
return addressEntry;
}
@NotNull
public ConfidenceProgressIndicator getProgressIndicator()
{
return progressIndicator;
}
@NotNull
public Label getBalanceLabel()
{
return balanceLabel;
}
@Nullable
public BigInteger getBalance()
{
return balance;

View File

@ -14,7 +14,7 @@
<TableColumn text="Label" fx:id="labelColumn" minWidth="100" sortable="false"/>
<TableColumn text="Address" fx:id="addressColumn" minWidth="240" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="address"/>
<PropertyValueFactory property="addressString"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Balance" fx:id="balanceColumn" minWidth="50" sortable="false"/>

View File

@ -10,7 +10,6 @@ import io.bitsquare.locale.Localisation;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
@ -19,12 +18,13 @@ import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class HomeController implements Initializable, ChildController, NavigationController
{
@FXML
public Pane rootContainer;
private NavigationController navigationController;
private ArbitratorRegistrationController arbitratorRegistrationController;
@Override
@ -34,9 +34,8 @@ public class HomeController implements Initializable, ChildController, Navigatio
}
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@Override
@ -48,13 +47,14 @@ public class HomeController implements Initializable, ChildController, Navigatio
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
if (arbitratorRegistrationController != null)
arbitratorRegistrationController.cleanup();
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
try
{
final Node view = loader.load();
@ -62,7 +62,7 @@ public class HomeController implements Initializable, ChildController, Navigatio
arbitratorRegistrationController.setNavigationController(this);
final Stage rootStage = BitSquare.getStage();
final Stage stage = new Stage();
@NotNull final Stage stage = new Stage();
stage.setTitle("Arbitrator");
stage.setMinWidth(800);
stage.setMinHeight(400);
@ -72,7 +72,7 @@ public class HomeController implements Initializable, ChildController, Navigatio
stage.setY(rootStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(rootStage);
Scene scene = new Scene((Parent) view, 800, 600);
@NotNull Scene scene = new Scene((Parent) view, 800, 600);
stage.setScene(scene);
stage.show();
@ -85,13 +85,13 @@ public class HomeController implements Initializable, ChildController, Navigatio
}
@FXML
public void onArbitratorRegistration(ActionEvent actionEvent)
public void onArbitratorRegistration()
{
navigateToView(NavigationItem.ARBITRATOR_REGISTRATION);
}
@FXML
public void onArbitratorEdit(ActionEvent actionEvent)
public void onArbitratorEdit()
{
navigateToView(NavigationItem.ARBITRATOR_REGISTRATION);
arbitratorRegistrationController.setEditMode(true);

View File

@ -15,12 +15,13 @@ import javafx.fxml.Initializable;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MarketController implements Initializable, NavigationController, ChildController
{
private ChildController childController;
private boolean orderbookCreated;
private NavigationController navigationController;
@Nullable
private OrderBookController orderBookController;
@FXML
@ -42,8 +43,9 @@ public class MarketController implements Initializable, NavigationController, Ch
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
if (navigationItem == NavigationItem.ORDER_BOOK && orderbookCreated)
@ -52,17 +54,17 @@ public class MarketController implements Initializable, NavigationController, Ch
return null;
}
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
try
{
Pane view = loader.load();
childController = loader.getController();
ChildController childController = loader.getController();
childController.setNavigationController(this);
if (childController instanceof OrderBookController)
orderBookController = (OrderBookController) childController;
Tab tab = new Tab("Orderbook");
@NotNull Tab tab = new Tab("Orderbook");
tab.setContent(view);
tabPane.getTabs().add(tab);
@ -88,10 +90,9 @@ public class MarketController implements Initializable, NavigationController, Ch
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@Override

View File

@ -4,6 +4,7 @@ import com.google.bitcoin.core.InsufficientMoneyException;
import com.google.bitcoin.core.Transaction;
import com.google.common.util.concurrent.FutureCallback;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
@ -15,9 +16,7 @@ import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.popups.Popups;
import io.bitsquare.gui.util.BitSquareConverter;
import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.gui.util.ConfidenceDisplay;
import io.bitsquare.locale.Localisation;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.Offer;
@ -30,7 +29,6 @@ import java.math.BigInteger;
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
@ -38,21 +36,24 @@ import javafx.scene.control.Label;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreateOfferController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class);
@NotNull
private final Trading trading;
@NotNull
private final WalletFacade walletFacade;
private final MessageFacade messageFacade;
@NotNull
private final Settings settings;
@NotNull
private final User user;
private NavigationController navigationController;
private Direction direction;
private Offer offer;
private ConfidenceDisplay confidenceDisplay;
@FXML
private AnchorPane rootContainer;
@ -74,11 +75,10 @@ public class CreateOfferController implements Initializable, ChildController, Hi
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public CreateOfferController(Trading trading, WalletFacade walletFacade, MessageFacade messageFacade, Settings settings, User user)
private CreateOfferController(@NotNull Trading trading, @NotNull WalletFacade walletFacade, @NotNull Settings settings, @NotNull User user)
{
this.trading = trading;
this.walletFacade = walletFacade;
this.messageFacade = messageFacade;
this.settings = settings;
this.user = user;
}
@ -88,7 +88,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setOrderBookFilter(OrderBookFilter orderBookFilter)
public void setOrderBookFilter(@NotNull OrderBookFilter orderBookFilter)
{
direction = orderBookFilter.getDirection();
amountTextField.setText(BitSquareFormatter.formatPrice(orderBookFilter.getAmount()));
@ -119,9 +119,13 @@ public class CreateOfferController implements Initializable, ChildController, Hi
@Override
public void initialize(URL url, ResourceBundle rb)
{
bankAccountTypeTextField.setText(Localisation.get(user.getCurrentBankAccount().getBankAccountTypeInfo().getType().toString()));
bankAccountCurrencyTextField.setText(user.getCurrentBankAccount().getCurrency().getCurrencyCode());
bankAccountCountyTextField.setText(user.getCurrentBankAccount().getCountry().getName());
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
bankAccountTypeTextField.setText(Localisation.get(currentBankAccount.getBankAccountType().toString()));
bankAccountCurrencyTextField.setText(currentBankAccount.getCurrency().getCurrencyCode());
bankAccountCountyTextField.setText(currentBankAccount.getCountry().getName());
}
acceptedCountriesTextField.setText(BitSquareFormatter.countryLocalesToString(settings.getAcceptedCountries()));
acceptedLanguagesTextField.setText(BitSquareFormatter.languageLocalesToString(settings.getAcceptedLanguageLocales()));
feeLabel.setText(BtcFormatter.satoshiToString(FeePolicy.CREATE_OFFER_FEE));
@ -133,7 +137,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -164,7 +168,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////
public void onPlaceOffer(ActionEvent actionEvent)
public void onPlaceOffer()
{
if (!inputValid())
{
@ -182,60 +186,68 @@ public class CreateOfferController implements Initializable, ChildController, Hi
log.debug("create offer pubkey " + user.getMessagePubKeyAsHex());
offer = new Offer(user.getMessagePubKeyAsHex(),
direction,
BitSquareConverter.stringToDouble2(priceTextField.getText()),
BtcFormatter.stringValueToSatoshis(amountTextField.getText()),
BtcFormatter.stringValueToSatoshis(minAmountTextField.getText()),
user.getCurrentBankAccount().getBankAccountTypeInfo().getType(),
user.getCurrentBankAccount().getCurrency(),
user.getCurrentBankAccount().getCountry(),
user.getCurrentBankAccount().getUid(),
arbitrator,
collateral,
settings.getAcceptedCountries(),
settings.getAcceptedLanguageLocales());
FutureCallback callback = new FutureCallback<Transaction>()
if (user.getCurrentBankAccount() != null)
{
@Override
public void onSuccess(Transaction transaction)
offer = new Offer(user.getMessagePubKeyAsHex(),
direction,
BitSquareConverter.stringToDouble2(priceTextField.getText()),
BtcFormatter.stringValueToSatoshis(amountTextField.getText()),
BtcFormatter.stringValueToSatoshis(minAmountTextField.getText()),
user.getCurrentBankAccount().getBankAccountType(),
user.getCurrentBankAccount().getCurrency(),
user.getCurrentBankAccount().getCountry(),
user.getCurrentBankAccount().getUid(),
arbitrator,
collateral,
settings.getAcceptedCountries(),
settings.getAcceptedLanguageLocales());
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
log.info("sendResult onSuccess:" + transaction.toString());
offer.setOfferFeePaymentTxID(transaction.getHashAsString());
setupSuccessScreen(transaction);
placeOfferTitle.setText("Transaction sent:");
try
@Override
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
trading.addOffer(offer);
} catch (IOException e)
{
Popups.openErrorPopup("Error on adding offer", "Could not add offer to orderbook. " + e.getMessage());
log.info("sendResult onSuccess:" + transaction);
if (transaction != null)
{
offer.setOfferFeePaymentTxID(transaction.getHashAsString());
setupSuccessScreen(transaction);
placeOfferTitle.setText("Transaction sent:");
try
{
trading.addOffer(offer);
} catch (IOException e)
{
Popups.openErrorPopup("Error on adding offer", "Could not add offer to orderbook. " + e.getMessage());
}
}
}
}
@Override
public void onFailure(Throwable t)
@Override
public void onFailure(@NotNull Throwable t)
{
log.warn("sendResult onFailure:" + t);
Popups.openErrorPopup("Fee payment failed", "Fee payment failed. " + t);
placeOfferButton.setDisable(false);
}
};
try
{
log.warn("sendResult onFailure:" + t.toString());
Popups.openErrorPopup("Fee payment failed", "Fee payment failed. " + t.toString());
placeOfferButton.setDisable(false);
walletFacade.payCreateOfferFee(offer.getId(), callback);
placeOfferButton.setDisable(true);
} catch (InsufficientMoneyException e1)
{
Popups.openInsufficientMoneyPopup();
}
};
try
{
walletFacade.payCreateOfferFee(offer.getId(), callback);
placeOfferButton.setDisable(true);
} catch (InsufficientMoneyException e1)
{
Popups.openInsufficientMoneyPopup();
}
}
public void onClose(ActionEvent actionEvent)
public void onClose()
{
TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
@NotNull TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigationController.navigateToView(NavigationItem.ORDER_BOOK);
@ -246,7 +258,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupSuccessScreen(Transaction newTransaction)
private void setupSuccessScreen(@NotNull Transaction newTransaction)
{
placeOfferButton.setVisible(false);
@ -258,7 +270,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
txTextField.setText(newTransaction.getHashAsString());
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, newTransaction, progressIndicator);
// ConfidenceDisplay confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, newTransaction, progressIndicator);
}
private void updateVolume()
@ -279,6 +291,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
}
//TODO
@SuppressWarnings("UnusedAssignment")
private boolean inputValid()
{
double priceAsDouble = BitSquareConverter.stringToDouble2(priceTextField.getText());

View File

@ -4,7 +4,7 @@ import com.google.bitcoin.core.InsufficientMoneyException;
import com.google.bitcoin.core.Transaction;
import com.google.common.util.concurrent.FutureCallback;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccountTypeInfo;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
@ -54,6 +54,8 @@ import javafx.util.Callback;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -83,6 +85,7 @@ public class OrderBookController implements Initializable, ChildController
public Button createOfferButton;
private NavigationController navigationController;
private SortedList<OrderBookListItem> offerList;
@Nullable
private AnimationTimer pollingTimer;
@FXML
private TableColumn<String, OrderBookListItem> directionColumn, countryColumn, bankAccountTypeColumn;
@ -93,7 +96,7 @@ public class OrderBookController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Storage storage)
private OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Storage storage)
{
this.orderBook = orderBook;
this.orderBookFilter = orderBookFilter;
@ -153,7 +156,7 @@ public class OrderBookController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -198,9 +201,9 @@ public class OrderBookController implements Initializable, ChildController
private boolean areSettingsValid()
{
return settings.getAcceptedLanguageLocales().size() > 0 &&
settings.getAcceptedCountries().size() > 0 &&
settings.getAcceptedArbitrators().size() > 0 &&
return !settings.getAcceptedLanguageLocales().isEmpty() &&
!settings.getAcceptedCountries().isEmpty() &&
!settings.getAcceptedArbitrators().isEmpty() &&
user.getCurrentBankAccount() != null;
}
@ -222,7 +225,7 @@ public class OrderBookController implements Initializable, ChildController
Action response = Popups.openErrorPopup("Registration fee not confirmed yet", "The registration fee transaction has not been confirmed yet in the blockchain. Please wait until it has at least 1 confirmation.");
if (response == Dialog.Actions.OK)
{
MainController.getInstance().navigateToView(NavigationItem.FUNDS);
MainController.INSTANCE().navigateToView(NavigationItem.FUNDS);
}
}
}
@ -231,7 +234,7 @@ public class OrderBookController implements Initializable, ChildController
Action response = Popups.openErrorPopup("Missing registration fee", "You have not funded the full registration fee of " + BtcFormatter.satoshiToString(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC.");
if (response == Dialog.Actions.OK)
{
MainController.getInstance().navigateToView(NavigationItem.FUNDS);
MainController.INSTANCE().navigateToView(NavigationItem.FUNDS);
}
}
}
@ -247,18 +250,18 @@ public class OrderBookController implements Initializable, ChildController
if (selectedIndex >= 0)
{
Dialogs.CommandLink settingsCommandLink = new Dialogs.CommandLink("Open settings", "You need to configure your settings before you can actively trade.");
Dialogs.CommandLink depositFeeCommandLink = new Dialogs.CommandLink("Deposit funds", "You need to pay the registration fee before you can actively trade. That is needed as prevention against fraud.");
Dialogs.CommandLink sendRegistrationCommandLink = new Dialogs.CommandLink("Publish registration", "When settings are configured and the fee deposit is done your registration transaction will be published to the Bitcoin \nnetwork.");
List<Dialogs.CommandLink> commandLinks = Arrays.asList(settingsCommandLink, depositFeeCommandLink, sendRegistrationCommandLink);
@NotNull Dialogs.CommandLink settingsCommandLink = new Dialogs.CommandLink("Open settings", "You need to configure your settings before you can actively trade.");
@NotNull Dialogs.CommandLink depositFeeCommandLink = new Dialogs.CommandLink("Deposit funds", "You need to pay the registration fee before you can actively trade. That is needed as prevention against fraud.");
@NotNull Dialogs.CommandLink sendRegistrationCommandLink = new Dialogs.CommandLink("Publish registration", "When settings are configured and the fee deposit is done your registration transaction will be published to the Bitcoin \nnetwork.");
@NotNull List<Dialogs.CommandLink> commandLinks = Arrays.asList(settingsCommandLink, depositFeeCommandLink, sendRegistrationCommandLink);
Action registrationMissingAction = Popups.openRegistrationMissingPopup("Not registered yet", "Please follow these steps:", "You need to register before you can place an offer.", commandLinks, selectedIndex);
if (registrationMissingAction == settingsCommandLink)
{
MainController.getInstance().navigateToView(NavigationItem.SETTINGS);
MainController.INSTANCE().navigateToView(NavigationItem.SETTINGS);
}
else if (registrationMissingAction == depositFeeCommandLink)
{
MainController.getInstance().navigateToView(NavigationItem.FUNDS);
MainController.INSTANCE().navigateToView(NavigationItem.FUNDS);
}
else if (registrationMissingAction == sendRegistrationCommandLink)
{
@ -269,17 +272,17 @@ public class OrderBookController implements Initializable, ChildController
private void payRegistrationFee()
{
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
@Override
public void onSuccess(Transaction transaction)
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
log.debug("payRegistrationFee onSuccess");
log.info("payRegistrationFee onSuccess txid:" + transaction.getHashAsString());
if (transaction != null) log.info("payRegistrationFee onSuccess tx id:" + transaction.getHashAsString());
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
log.debug("payRegistrationFee onFailure");
}
@ -287,8 +290,9 @@ public class OrderBookController implements Initializable, ChildController
try
{
walletFacade.payRegistrationFee(user.getStringifiedBankAccounts(), callback);
user.setAccountID(walletFacade.getRegistrationAddressInfo().toString());
user.setMessagePubKeyAsHex(DSAKeyUtil.getHexStringFromPublicKey(messageFacade.getPubKey()));
if (walletFacade.getRegistrationAddressInfo() != null)
user.setAccountID(walletFacade.getRegistrationAddressInfo().toString());
if (messageFacade != null && messageFacade.getPubKey() != null) user.setMessagePubKeyAsHex(DSAKeyUtil.getHexStringFromPublicKey(messageFacade.getPubKey()));
storage.write(user.getClass().getName(), user);
} catch (InsufficientMoneyException e1)
@ -305,14 +309,15 @@ public class OrderBookController implements Initializable, ChildController
if (walletFacade.isUnusedTradeAddressBalanceAboveCreationFee())
{
ChildController nextController = navigationController.navigateToView(NavigationItem.CREATE_OFFER);
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
if (nextController != null)
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
}
else
{
Action response = Popups.openErrorPopup("No funds for a trade", "You have to add some funds before you create a new offer.");
if (response == Dialog.Actions.OK)
{
MainController.getInstance().navigateToView(NavigationItem.FUNDS);
MainController.INSTANCE().navigateToView(NavigationItem.FUNDS);
}
}
}
@ -322,18 +327,18 @@ public class OrderBookController implements Initializable, ChildController
}
}
private void takeOffer(Offer offer)
private void takeOffer(@NotNull Offer offer)
{
if (isRegistered())
{
String title = offer.getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin";
TakerTradeController takerTradeController = (TakerTradeController) navigationController.navigateToView(NavigationItem.TAKER_TRADE);
@Nullable TakerTradeController takerTradeController = (TakerTradeController) navigationController.navigateToView(NavigationItem.TAKER_TRADE);
BigInteger requestedAmount = offer.getAmount();
if (!amount.getText().equals(""))
if (!"".equals(amount.getText()))
requestedAmount = BtcFormatter.stringValueToSatoshis(amount.getText());
takerTradeController.initWithData(offer, requestedAmount);
if (takerTradeController != null)
takerTradeController.initWithData(offer, requestedAmount);
}
else
{
@ -341,7 +346,7 @@ public class OrderBookController implements Initializable, ChildController
}
}
private void removeOffer(Offer offer)
private void removeOffer(@NotNull Offer offer)
{
orderBook.removeOffer(offer);
}
@ -354,19 +359,19 @@ public class OrderBookController implements Initializable, ChildController
orderBookTable.sort();
if (orderBookTable.getItems() != null)
createOfferButton.setDefaultButton(orderBookTable.getItems().size() == 0);
createOfferButton.setDefaultButton(orderBookTable.getItems().isEmpty());
}
private void setupPolling()
{
pollingTimer = Utilities.setInterval(1000, (AnimationTimer animationTimer) -> {
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
if (user.getCurrentBankAccount() != null)
messageFacade.getDirtyFlag(user.getCurrentBankAccount().getCurrency());
else
messageFacade.getDirtyFlag(CurrencyUtil.getDefaultCurrency());
return null;
});
messageFacade.getIsDirtyProperty().addListener((observableValue, oldValue, newValue) -> orderBook.loadOffers());
}
@ -380,6 +385,7 @@ public class OrderBookController implements Initializable, ChildController
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
@Nullable
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
@ -394,7 +400,7 @@ public class OrderBookController implements Initializable, ChildController
}
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
public void updateItem(@Nullable final OrderBookListItem orderBookListItem, boolean empty)
{
super.updateItem(orderBookListItem, empty);
@ -402,7 +408,7 @@ public class OrderBookController implements Initializable, ChildController
{
String title;
Image icon;
Offer offer = orderBookListItem.getOffer();
@NotNull Offer offer = orderBookListItem.getOffer();
if (offer.getMessagePubKeyAsHex().equals(user.getMessagePubKeyAsHex()))
{
@ -447,6 +453,7 @@ public class OrderBookController implements Initializable, ChildController
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
@Nullable
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
@ -461,7 +468,7 @@ public class OrderBookController implements Initializable, ChildController
}
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
public void updateItem(@Nullable final OrderBookListItem orderBookListItem, boolean empty)
{
super.updateItem(orderBookListItem, empty);
@ -490,19 +497,20 @@ public class OrderBookController implements Initializable, ChildController
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
@Nullable
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
return new TableCell<String, OrderBookListItem>()
{
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
public void updateItem(@Nullable final OrderBookListItem orderBookListItem, boolean empty)
{
super.updateItem(orderBookListItem, empty);
if (orderBookListItem != null)
{
BankAccountTypeInfo.BankAccountType bankAccountType = orderBookListItem.getOffer().getBankAccountType();
BankAccountType bankAccountType = orderBookListItem.getOffer().getBankAccountType();
setText(Localisation.get(bankAccountType.toString()));
}
else
@ -520,15 +528,15 @@ public class OrderBookController implements Initializable, ChildController
// Utils
///////////////////////////////////////////////////////////////////////////////////////////
private double textInputToNumber(String oldValue, String newValue)
private double textInputToNumber(String oldValue, @NotNull String newValue)
{
//TODO use regex.... or custom textfield component
double d = 0.0;
if (!newValue.equals(""))
if (!"".equals(newValue))
{
try
{
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
@NotNull DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
d = decimalFormat.parse(newValue).doubleValue();
} catch (ParseException e)
{

View File

@ -5,17 +5,19 @@ import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.trade.Offer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.jetbrains.annotations.NotNull;
public class OrderBookListItem
{
protected final StringProperty price = new SimpleStringProperty();
protected final StringProperty amount = new SimpleStringProperty();
protected final StringProperty volume = new SimpleStringProperty();
private final StringProperty price = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
private final StringProperty volume = new SimpleStringProperty();
protected final Offer offer;
@NotNull
private final Offer offer;
public OrderBookListItem(Offer offer)
public OrderBookListItem(@NotNull Offer offer)
{
this.offer = offer;
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
@ -27,22 +29,26 @@ public class OrderBookListItem
this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getVolume(), offer.getMinVolume()));
}
@NotNull
public Offer getOffer()
{
return offer;
}
// called form table columns
@NotNull
public final StringProperty priceProperty()
{
return this.price;
}
@NotNull
public final StringProperty amountProperty()
{
return this.amount;
}
@NotNull
public final StringProperty volumeProperty()
{
return this.volume;

View File

@ -2,7 +2,10 @@ package io.bitsquare.gui.market.trade;
import com.google.bitcoin.core.Transaction;
import com.google.inject.Inject;
import io.bitsquare.btc.*;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.NavigationItem;
@ -34,31 +37,32 @@ import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("UnusedParameters")
public class TakerTradeController implements Initializable, ChildController
{
private static final Logger log = LoggerFactory.getLogger(TakerTradeController.class);
private final Trading trading;
private final WalletFacade walletFacade;
private final BlockChainFacade blockChainFacade;
private final MessageFacade messageFacade;
private final List<ProcessStepItem> processStepItems = new ArrayList<>();
private Offer offer;
private Trade trade;
private BigInteger requestedAmount;
private boolean offererIsOnline;
private int row;
private NavigationController navigationController;
private TextField amountTextField, totalToPayLabel, totalLabel, collateralTextField, isOnlineTextField;
private Label statusTextField, infoLabel;
private Label infoLabel;
private Button nextButton;
private ProgressBar progressBar;
@Nullable
private AnimationTimer checkOnlineStatusTimer;
private Pane isOnlineCheckerHolder;
private TakerPaymentProtocol takerPaymentProtocol;
private Label headerLabel;
@FXML
@ -74,11 +78,10 @@ public class TakerTradeController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TakerTradeController(Trading trading, WalletFacade walletFacade, BlockChainFacade blockChainFacade, MessageFacade messageFacade)
private TakerTradeController(Trading trading, WalletFacade walletFacade, MessageFacade messageFacade)
{
this.trading = trading;
this.walletFacade = walletFacade;
this.blockChainFacade = blockChainFacade;
this.messageFacade = messageFacade;
}
@ -87,7 +90,7 @@ public class TakerTradeController implements Initializable, ChildController
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void initWithData(Offer offer, BigInteger requestedAmount)
public void initWithData(@NotNull Offer offer, @NotNull BigInteger requestedAmount)
{
this.offer = offer;
this.requestedAmount = requestedAmount.compareTo(BigInteger.ZERO) > 0 ? requestedAmount : offer.getAmount();
@ -120,7 +123,7 @@ public class TakerTradeController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -152,14 +155,14 @@ public class TakerTradeController implements Initializable, ChildController
row = -1;
FormBuilder.addHeaderLabel(gridPane, "Take offer:", ++row);
amountTextField = FormBuilder.addTextField(gridPane, "Amount (BTC):", BtcFormatter.formatSatoshis(requestedAmount, false), ++row, true, true);
amountTextField = FormBuilder.addTextField(gridPane, "Amount (BTC):", BtcFormatter.satoshiToString(requestedAmount), ++row, true, true);
amountTextField.textProperty().addListener(e -> {
applyVolume();
applyCollateral();
totalToPayLabel.setText(getTotalToPayAsString());
});
Label amountRangeLabel = new Label("(" + BtcFormatter.formatSatoshis(offer.getMinAmount(), false) + " - " + BtcFormatter.formatSatoshis(offer.getAmount(), false) + ")");
@NotNull Label amountRangeLabel = new Label("(" + BtcFormatter.satoshiToString(offer.getMinAmount()) + " - " + BtcFormatter.satoshiToString(offer.getAmount()) + ")");
gridPane.add(amountRangeLabel, 2, row);
FormBuilder.addTextField(gridPane, "Price (" + offer.getCurrency() + "/BTC):", BitSquareFormatter.formatPrice(offer.getPrice()), ++row);
@ -170,7 +173,7 @@ public class TakerTradeController implements Initializable, ChildController
totalToPayLabel = FormBuilder.addTextField(gridPane, "Total to pay (BTC):", getTotalToPayAsString(), ++row);
isOnlineTextField = FormBuilder.addTextField(gridPane, "Online status:", "Checking offerers online status...", ++row);
ConfidenceProgressIndicator isOnlineChecker = new ConfidenceProgressIndicator();
@NotNull ConfidenceProgressIndicator isOnlineChecker = new ConfidenceProgressIndicator();
isOnlineChecker.setPrefSize(20, 20);
isOnlineChecker.setLayoutY(3);
isOnlineCheckerHolder = new Pane();
@ -181,6 +184,7 @@ public class TakerTradeController implements Initializable, ChildController
messageFacade.pingPeer(offer.getMessagePubKeyAsHex());
checkOnlineStatusTimer = Utilities.setTimeout(1000, (AnimationTimer animationTimer) -> {
setIsOnlineStatus(true);
//noinspection ReturnOfNull
return null;
});
@ -194,13 +198,14 @@ public class TakerTradeController implements Initializable, ChildController
FormBuilder.addTextField(gridPane, "Bank account type:", offer.getBankAccountType().toString(), ++row);
FormBuilder.addTextField(gridPane, "Country:", offer.getBankAccountCountry().getName(), ++row);
FormBuilder.addTextField(gridPane, "Arbitrator:", offer.getArbitrator().getName(), ++row);
Label arbitratorLink = new Label(offer.getArbitrator().getWebUrl());
@NotNull Label arbitratorLink = new Label(offer.getArbitrator().getWebUrl());
arbitratorLink.setId("label-url");
gridPane.add(arbitratorLink, 2, row);
arbitratorLink.setOnMouseClicked(e -> {
try
{
Utilities.openURL(offer.getArbitrator().getWebUrl());
if (offer.getArbitrator() != null && offer.getArbitrator().getWebUrl() != null)
Utilities.openURL(offer.getArbitrator().getWebUrl());
} catch (Exception e1)
{
log.warn(e1.toString());
@ -221,9 +226,9 @@ public class TakerTradeController implements Initializable, ChildController
// offerId = tradeId
// we don't want to create the trade before the balance check
AddressEntry addressEntry = walletFacade.getAddressInfoByTradeID(offer.getId());
log.debug("balance " + walletFacade.getBalanceForAddress(addressEntry.getAddress()).toString());
if (getTotalToPay().compareTo(walletFacade.getBalanceForAddress(addressEntry.getAddress())) > 0)
@Nullable AddressEntry addressEntry = walletFacade.getAddressInfoByTradeID(offer.getId());
// log.debug("balance " + walletFacade.getBalanceForAddress(addressEntry.getAddress()).toString());
if (getTotalToPay().compareTo(walletFacade.getBalanceForAddress(addressEntry != null ? addressEntry.getAddress() : null)) > 0)
{
Popups.openErrorPopup("Insufficient money", "You don't have enough funds for that trade.");
return;
@ -251,7 +256,7 @@ public class TakerTradeController implements Initializable, ChildController
row = -1;
FormBuilder.addHeaderLabel(gridPane, "Trade request inited", ++row, 0);
statusTextField = FormBuilder.addLabel(gridPane, "Current activity:", "Request confirmation from offerer to take that offer.", ++row);
Label statusTextField = FormBuilder.addLabel(gridPane, "Current activity:", "Request confirmation from offerer to take that offer.", ++row);
GridPane.setColumnSpan(statusTextField, 2);
FormBuilder.addLabel(gridPane, "Progress:", "", ++row);
progressBar = new ProgressBar();
@ -261,14 +266,14 @@ public class TakerTradeController implements Initializable, ChildController
gridPane.add(progressBar, 1, row);
FormBuilder.addLabel(gridPane, "Status:", "", ++row);
ConfidenceProgressIndicator progressIndicator = new ConfidenceProgressIndicator();
@NotNull ConfidenceProgressIndicator progressIndicator = new ConfidenceProgressIndicator();
progressIndicator.setPrefSize(20, 20);
progressIndicator.setLayoutY(2);
Pane progressIndicatorHolder = new Pane();
@NotNull Pane progressIndicatorHolder = new Pane();
progressIndicatorHolder.getChildren().addAll(progressIndicator);
gridPane.add(progressIndicatorHolder, 1, row);
takerPaymentProtocol = trading.addTakerPaymentProtocol(trade, new TakerPaymentProtocolListener()
TakerPaymentProtocol takerPaymentProtocol = trading.addTakerPaymentProtocol(trade, new TakerPaymentProtocolListener()
{
@Override
public void onProgress(double progress)
@ -311,7 +316,7 @@ public class TakerTradeController implements Initializable, ChildController
}
@Override
public void onBankTransferInited(TradeMessage tradeMessage)
public void onBankTransferInited(@NotNull TradeMessage tradeMessage)
{
buildBankTransferInitedScreen(tradeMessage);
}
@ -326,6 +331,7 @@ public class TakerTradeController implements Initializable, ChildController
takerPaymentProtocol.takeOffer();
}
@SuppressWarnings("EmptyMethod")
private void updateTx(Trade trade)
{
@ -344,7 +350,7 @@ public class TakerTradeController implements Initializable, ChildController
// confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator);
}
private void buildBankTransferInitedScreen(TradeMessage tradeMessage)
private void buildBankTransferInitedScreen(@NotNull TradeMessage tradeMessage)
{
processStepBar.next();
@ -355,7 +361,7 @@ public class TakerTradeController implements Initializable, ChildController
nextButton.setOnAction(e -> releaseBTC(tradeMessage));
}
private void releaseBTC(TradeMessage tradeMessage)
private void releaseBTC(@NotNull TradeMessage tradeMessage)
{
processStepBar.next();
trading.releaseBTC(trade.getId(), tradeMessage);
@ -379,9 +385,9 @@ public class TakerTradeController implements Initializable, ChildController
else
{
//TODO
FormBuilder.addTextField(gridPane, "You got returned collateral (BTC):", BtcFormatter.formatSatoshis(getCollateralInSatoshis(), false), ++row);
FormBuilder.addTextField(gridPane, "You got returned collateral (BTC):", BtcFormatter.satoshiToString(getCollateralInSatoshis()), ++row);
FormBuilder.addTextField(gridPane, "You have received (" + offer.getCurrency() + "):", BitSquareFormatter.formatVolume(getVolume()), ++row);
FormBuilder.addTextField(gridPane, "You have received (BTC):", BtcFormatter.formatSatoshis(offer.getAmount(), false), ++row);
FormBuilder.addTextField(gridPane, "You have received (BTC):", BtcFormatter.satoshiToString(offer.getAmount()), ++row);
}
gridPane.add(nextButton, 1, ++row);
@ -395,7 +401,7 @@ public class TakerTradeController implements Initializable, ChildController
private void close()
{
TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
@NotNull TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigationController.navigateToView(NavigationItem.ORDER_BOOK);
@ -421,7 +427,8 @@ public class TakerTradeController implements Initializable, ChildController
checkOnlineStatusTimer = null;
}
offererIsOnline = isOnline;
//noinspection UnnecessaryLocalVariable
boolean offererIsOnline = isOnline;
isOnlineTextField.setText(offererIsOnline ? "Online" : "Offline");
gridPane.getChildren().remove(isOnlineCheckerHolder);
@ -443,11 +450,11 @@ public class TakerTradeController implements Initializable, ChildController
{
if (takerIsSelling())
{
return BtcFormatter.formatSatoshis(getTotalToPay(), false);
return BtcFormatter.satoshiToString(getTotalToPay());
}
else
{
return BtcFormatter.formatSatoshis(getTotalToPay(), false) + "\n" +
return BtcFormatter.satoshiToString(getTotalToPay()) + "\n" +
BitSquareFormatter.formatVolume(getVolume(), offer.getCurrency());
}
}
@ -466,7 +473,7 @@ public class TakerTradeController implements Initializable, ChildController
private void applyCollateral()
{
collateralTextField.setText(BtcFormatter.formatSatoshis(getCollateralInSatoshis(), false));
collateralTextField.setText(BtcFormatter.satoshiToString(getCollateralInSatoshis()));
}
private BigInteger getCollateralInSatoshis()

View File

@ -6,6 +6,7 @@ import io.bitsquare.gui.NavigationController;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,7 +20,7 @@ public class MsgController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public MsgController()
private MsgController()
{
}
@ -39,7 +40,7 @@ public class MsgController implements Initializable, ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}

View File

@ -10,6 +10,7 @@ import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,7 +28,7 @@ public class OrdersController implements Initializable, ChildController, Navigat
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public OrdersController(Storage storage)
private OrdersController(Storage storage)
{
this.storage = storage;
}
@ -49,7 +50,7 @@ public class OrdersController implements Initializable, ChildController, Navigat
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
}
@ -64,7 +65,7 @@ public class OrdersController implements Initializable, ChildController, Navigat
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
return tabPane.navigateToView(navigationItem.getFxmlUrl());
}

View File

@ -7,6 +7,7 @@ import io.bitsquare.gui.NavigationController;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,7 +21,7 @@ public class ClosedTradeController implements Initializable, ChildController, Hi
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ClosedTradeController()
private ClosedTradeController()
{
}
@ -40,7 +41,7 @@ public class ClosedTradeController implements Initializable, ChildController, Hi
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
log.debug("setNavigationController" + this);
}

View File

@ -7,6 +7,7 @@ import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.trade.Offer;
import io.bitsquare.trade.Trading;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@ -21,14 +22,17 @@ import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.util.Callback;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("EmptyMethod")
public class OfferController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(OfferController.class);
private final Trading trading;
protected ObservableList<OfferListItem> offerListItems;
private ObservableList<OfferListItem> offerListItems;
@FXML
private TableColumn<String, OfferListItem> offerIdColumn, dateColumn, amountColumn, priceColumn, volumeColumn, removeColumn;
@FXML
@ -40,7 +44,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public OfferController(Trading trading)
private OfferController(Trading trading)
{
this.trading = trading;
}
@ -64,7 +68,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
// Interface implementation: ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
log.debug("setNavigationController" + this);
}
@ -91,7 +95,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
{
offerListItems = FXCollections.observableArrayList();
Map<String, Offer> offerMap = trading.getOffers();
List<Offer> offerList = new ArrayList<>(offerMap.values());
@NotNull List<Offer> offerList = new ArrayList<>(offerMap.values());
offerListItems.addAll(offerList.stream().map(OfferListItem::new).collect(Collectors.toList()));
offerTable.setItems(offerListItems);
}
@ -107,12 +111,19 @@ public class OfferController implements Initializable, ChildController, Hibernat
///////////////////////////////////////////////////////////////////////////////////////////
private void removeOffer(OfferListItem offerListItem)
private void removeOffer(@NotNull OfferListItem offerListItem)
{
trading.removeOffer(offerListItem.getOffer());
try
{
trading.removeOffer(offerListItem.getOffer());
} catch (IOException e)
{
e.printStackTrace();
}
offerListItems.remove(offerListItem);
}
@SuppressWarnings("UnusedParameters")
private void openOfferDetails(OfferListItem offerListItem)
{
@ -127,6 +138,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
offerIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
offerIdColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>()
{
@Nullable
@Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> column)
{
@ -135,7 +147,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
Hyperlink hyperlink;
@Override
public void updateItem(final OfferListItem item, boolean empty)
public void updateItem(@Nullable final OfferListItem item, boolean empty)
{
super.updateItem(item, empty);
@ -143,12 +155,9 @@ public class OfferController implements Initializable, ChildController, Hibernat
{
hyperlink = new Hyperlink(item.getOfferId());
//hyperlink.getStyleClass().setAll("aaa");
if (item != null && !empty)
{
Tooltip tooltip = new Tooltip(item.getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> openOfferDetails(item));
}
@NotNull Tooltip tooltip = new Tooltip(item.getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> openOfferDetails(item));
setGraphic(hyperlink);
}
else
@ -167,6 +176,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
removeColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
removeColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>()
{
@Nullable
@Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> directionColumn)
{
@ -182,7 +192,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
}
@Override
public void updateItem(final OfferListItem offerListItem, boolean empty)
public void updateItem(@Nullable final OfferListItem offerListItem, boolean empty)
{
super.updateItem(offerListItem, empty);

View File

@ -5,17 +5,19 @@ import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.trade.Offer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.jetbrains.annotations.NotNull;
public class OfferListItem
{
protected final StringProperty price = new SimpleStringProperty();
protected final StringProperty amount = new SimpleStringProperty();
protected final StringProperty date = new SimpleStringProperty();
protected final StringProperty volume = new SimpleStringProperty();
protected final Offer offer;
private final StringProperty price = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
private final StringProperty date = new SimpleStringProperty();
private final StringProperty volume = new SimpleStringProperty();
@NotNull
private final Offer offer;
private final String offerId;
public OfferListItem(Offer offer)
public OfferListItem(@NotNull Offer offer)
{
this.offer = offer;
@ -30,6 +32,7 @@ public class OfferListItem
this.offerId = offer.getId();
}
@NotNull
public Offer getOffer()
{
return offer;
@ -37,21 +40,25 @@ public class OfferListItem
// called form table columns
@NotNull
public final StringProperty dateProperty()
{
return this.date;
}
@NotNull
public final StringProperty priceProperty()
{
return this.price;
}
@NotNull
public final StringProperty amountProperty()
{
return this.amount;
}
@NotNull
public final StringProperty volumeProperty()
{
return this.volume;

View File

@ -7,6 +7,7 @@ import io.bitsquare.gui.NavigationController;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,7 +21,7 @@ public class PendingTradeController implements Initializable, ChildController, H
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public PendingTradeController()
private PendingTradeController()
{
}
@ -40,7 +41,7 @@ public class PendingTradeController implements Initializable, ChildController, H
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
log.debug("setNavigationController" + this);
}

View File

@ -2,22 +2,25 @@ package io.bitsquare.gui.orders.pending;
import io.bitsquare.gui.market.orderbook.OrderBookListItem;
import io.bitsquare.trade.Trade;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradesTableItem extends OrderBookListItem
class TradesTableItem extends OrderBookListItem
{
private static final Logger log = LoggerFactory.getLogger(TradesTableItem.class);
@NotNull
private final Trade trade;
public TradesTableItem(Trade trade)
private TradesTableItem(@NotNull Trade trade)
{
super(trade.getOffer());
this.trade = trade;
}
@NotNull
public Trade getTrade()
{
return trade;

View File

@ -9,7 +9,9 @@ import javafx.application.Platform;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
public class Popups
{
@ -37,7 +39,7 @@ public class Popups
public static Action openConfirmPopup(String title, String message, String masthead)
{
List<Action> actions = new ArrayList<>();
@NotNull List<Action> actions = new ArrayList<>();
actions.add(Dialog.Actions.OK);
actions.add(Dialog.Actions.CANCEL);
return Dialogs.create()
@ -113,12 +115,13 @@ public class Popups
}
// Support handling of uncaught exception from any thread (also non gui thread)
public static void handleUncaughtExceptions(Throwable throwable)
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public static void handleUncaughtExceptions(@NotNull Throwable throwable)
{
// while dev
throwable.printStackTrace();
Runnable runnable = () ->
@NotNull Runnable runnable = () ->
{
if (Throwables.getRootCause(throwable) instanceof BlockStoreException)
{
@ -148,7 +151,7 @@ public class Popups
openWarningPopup("Not enough money available", "There is not enough money available. Please pay in first to your wallet.", null);
}
public static Action openRegistrationMissingPopup(String title, String message, String masthead, List<Dialogs.CommandLink> commandLinks, int selectedIndex)
public static Action openRegistrationMissingPopup(String title, String message, String masthead, @NotNull List<Dialogs.CommandLink> commandLinks, int selectedIndex)
{
return Dialogs.create()
.owner(BitSquare.getStage())

View File

@ -5,8 +5,7 @@ import com.google.bitcoin.core.Utils;
import com.google.inject.Inject;
import io.bitsquare.BitSquare;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountTypeInfo;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
@ -26,7 +25,6 @@ import java.net.URL;
import java.util.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
@ -40,22 +38,23 @@ import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
// TODO separate in 2 view/controllers
public class SettingsController implements Initializable, ChildController, NavigationController
{
private final User user;
@NotNull
private final Settings settings;
@NotNull
private final Storage storage;
private final WalletFacade walletFacade;
private final MessageFacade messageFacade;
private final ObservableList<Locale> languageList;
private final ObservableList<Country> countryList;
private NavigationController navigationController;
private ChildController childController;
private List<String> regionList;
private ObservableList<Arbitrator> arbitratorList;
private Region selectedRegion, selectedBankAccountRegion;
@FXML
private ListView<Locale> languagesListView;
@ -76,7 +75,7 @@ public class SettingsController implements Initializable, ChildController, Navig
@FXML
private ComboBox<BankAccount> bankAccountComboBox;
@FXML
private ComboBox<BankAccountTypeInfo> bankAccountTypesComboBox;
private ComboBox<BankAccountType> bankAccountTypesComboBox;
@FXML
private ComboBox<Currency> bankAccountCurrencyComboBox;
@ -86,12 +85,11 @@ public class SettingsController implements Initializable, ChildController, Navig
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public SettingsController(User user, Settings settings, Storage storage, WalletFacade walletFacade, MessageFacade messageFacade)
public SettingsController(User user, @NotNull Settings settings, @NotNull Storage storage, MessageFacade messageFacade)
{
this.user = user;
this.settings = settings;
this.storage = storage;
this.walletFacade = walletFacade;
this.messageFacade = messageFacade;
Settings savedSettings = (Settings) storage.read(settings.getClass().getName());
@ -118,7 +116,7 @@ public class SettingsController implements Initializable, ChildController, Navig
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void updateArbitrators()
void updateArbitrators()
{
arbitratorList = FXCollections.observableArrayList(settings.getAcceptedArbitrators());
initArbitrators();
@ -137,21 +135,22 @@ public class SettingsController implements Initializable, ChildController, Navig
addMockArbitrator();
}
@SuppressWarnings("ConstantConditions")
private void addMockArbitrator()
{
if (settings.getAcceptedArbitrators() == null || settings.getAcceptedArbitrators().size() == 0)
if (settings.getAcceptedArbitrators().isEmpty())
{
String pubKeyAsHex = Utils.bytesToHexString(new ECKey().getPubKey());
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(messageFacade.getPubKey());
List<Locale> languages = new ArrayList<>();
@NotNull List<Locale> languages = new ArrayList<>();
languages.add(LanguageUtil.getDefaultLanguageLocale());
List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
@NotNull List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
arbitrationMethods.add(Arbitrator.METHOD.TLS_NOTARY);
List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
@NotNull List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
idVerifications.add(Arbitrator.ID_VERIFICATION.PASSPORT);
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
Arbitrator arbitrator = new Arbitrator(pubKeyAsHex,
@NotNull Arbitrator arbitrator = new Arbitrator(pubKeyAsHex,
messagePubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
@ -188,9 +187,9 @@ public class SettingsController implements Initializable, ChildController, Navig
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
public void setNavigationController(@NotNull NavigationController navigationController)
{
this.navigationController = navigationController;
}
@Override
@ -204,14 +203,15 @@ public class SettingsController implements Initializable, ChildController, Navig
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
@Override
public ChildController navigateToView(NavigationItem navigationItem)
public ChildController navigateToView(@NotNull NavigationItem navigationItem)
{
if (childController != null)
childController.cleanup();
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
@NotNull final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), Localisation.getResourceBundle());
try
{
final Node view = loader.load();
@ -219,7 +219,7 @@ public class SettingsController implements Initializable, ChildController, Navig
childController.setNavigationController(this);
final Stage rootStage = BitSquare.getStage();
final Stage stage = new Stage();
@NotNull final Stage stage = new Stage();
stage.setTitle("Arbitrator selection");
stage.setMinWidth(800);
stage.setMinHeight(500);
@ -229,7 +229,7 @@ public class SettingsController implements Initializable, ChildController, Navig
stage.setY(rootStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(rootStage);
Scene scene = new Scene((Parent) view, 800, 600);
@NotNull Scene scene = new Scene((Parent) view, 800, 600);
stage.setScene(scene);
stage.setOnHidden(windowEvent -> {
if (navigationItem == NavigationItem.ARBITRATOR_OVERVIEW)
@ -253,29 +253,29 @@ public class SettingsController implements Initializable, ChildController, Navig
// General Settings
@FXML
public void onAddLanguage(ActionEvent actionEvent)
public void onAddLanguage()
{
addLanguage(languageComboBox.getSelectionModel().getSelectedItem());
languageComboBox.getSelectionModel().clearSelection();
}
@FXML
public void onSelectRegion(ActionEvent actionEvent)
public void onSelectRegion()
{
countryComboBox.setVisible(true);
selectedRegion = regionComboBox.getSelectionModel().getSelectedItem();
Region selectedRegion = regionComboBox.getSelectionModel().getSelectedItem();
countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion)));
}
@FXML
public void onAddCountry(ActionEvent actionEvent)
public void onAddCountry()
{
addCountry(countryComboBox.getSelectionModel().getSelectedItem());
countryComboBox.getSelectionModel().clearSelection();
}
@FXML
public void onAddArbitrator(ActionEvent actionEvent)
public void onAddArbitrator()
{
navigateToView(NavigationItem.ARBITRATOR_OVERVIEW);
}
@ -283,7 +283,7 @@ public class SettingsController implements Initializable, ChildController, Navig
// Bank Account Settings
@FXML
public void selectBankAccount(ActionEvent actionEvent)
public void selectBankAccount()
{
BankAccount bankAccount = bankAccountComboBox.getSelectionModel().getSelectedItem();
if (bankAccount != null && bankAccount != user.getCurrentBankAccount())
@ -295,41 +295,41 @@ public class SettingsController implements Initializable, ChildController, Navig
}
@FXML
public void selectBankAccountType(ActionEvent actionEvent)
public void selectBankAccountType()
{
BankAccountTypeInfo bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
if (bankAccountTypeInfo != null)
BankAccountType bankAccountType = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
if (bankAccountType != null)
{
bankAccountTitleTextField.setText("");
bankAccountPrimaryIDTextField.setText("");
bankAccountPrimaryIDTextField.setPromptText(bankAccountTypeInfo.getPrimaryIDName());
bankAccountPrimaryIDTextField.setPromptText(bankAccountType.getPrimaryId());
bankAccountSecondaryIDTextField.setText("");
bankAccountSecondaryIDTextField.setPromptText(bankAccountTypeInfo.getSecondaryIDName());
bankAccountSecondaryIDTextField.setPromptText(bankAccountType.getSecondaryId());
}
}
@FXML
public void onSelectBankAccountRegion(ActionEvent actionEvent)
public void onSelectBankAccountRegion()
{
bankAccountCountryComboBox.setVisible(true);
selectedBankAccountRegion = bankAccountRegionComboBox.getSelectionModel().getSelectedItem();
Region selectedBankAccountRegion = bankAccountRegionComboBox.getSelectionModel().getSelectedItem();
bankAccountCountryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedBankAccountRegion)));
}
@FXML
public void onAddBankAccount(ActionEvent actionEvent)
public void onAddBankAccount()
{
resetBankAccountInput();
}
@FXML
public void onRemoveBankAccount(ActionEvent actionEvent)
public void onRemoveBankAccount()
{
removeBankAccount();
}
@FXML
public void onSaveBankAccount(ActionEvent actionEvent)
void onSaveBankAccount()
{
saveBankAccount();
@ -354,6 +354,7 @@ public class SettingsController implements Initializable, ChildController, Navig
{
languagesListView.setCellFactory(new Callback<ListView<Locale>, ListCell<Locale>>()
{
@Nullable
@Override
public ListCell<Locale> call(ListView<Locale> list)
{
@ -378,7 +379,7 @@ public class SettingsController implements Initializable, ChildController, Navig
}
@Override
public void updateItem(final Locale item, boolean empty)
public void updateItem(@Nullable final Locale item, boolean empty)
{
super.updateItem(item, empty);
if (item != null && !empty)
@ -404,11 +405,12 @@ public class SettingsController implements Initializable, ChildController, Navig
languageComboBox.setConverter(new StringConverter<Locale>()
{
@Override
public String toString(Locale locale)
public String toString(@NotNull Locale locale)
{
return locale.getDisplayLanguage();
}
@Nullable
@Override
public Locale fromString(String s)
{
@ -423,11 +425,12 @@ public class SettingsController implements Initializable, ChildController, Navig
regionComboBox.setConverter(new StringConverter<Region>()
{
@Override
public String toString(Region region)
public String toString(@NotNull Region region)
{
return region.getName();
}
@Nullable
@Override
public Region fromString(String s)
{
@ -437,6 +440,7 @@ public class SettingsController implements Initializable, ChildController, Navig
countriesListView.setCellFactory(new Callback<ListView<Country>, ListCell<Country>>()
{
@Nullable
@Override
public ListCell<Country> call(ListView<Country> list)
{
@ -462,7 +466,7 @@ public class SettingsController implements Initializable, ChildController, Navig
@Override
public void updateItem(final Country item, boolean empty)
public void updateItem(@Nullable final Country item, boolean empty)
{
super.updateItem(item, empty);
if (item != null && !empty)
@ -486,12 +490,14 @@ public class SettingsController implements Initializable, ChildController, Navig
countryComboBox.setConverter(new StringConverter<Country>()
{
@NotNull
@Override
public String toString(Country country)
public String toString(@NotNull Country country)
{
return country.getName();
}
@Nullable
@Override
public Country fromString(String s)
{
@ -505,6 +511,7 @@ public class SettingsController implements Initializable, ChildController, Navig
{
arbitratorsListView.setCellFactory(new Callback<ListView<Arbitrator>, ListCell<Arbitrator>>()
{
@Nullable
@Override
public ListCell<Arbitrator> call(ListView<Arbitrator> list)
{
@ -530,7 +537,7 @@ public class SettingsController implements Initializable, ChildController, Navig
@Override
public void updateItem(final Arbitrator item, boolean empty)
public void updateItem(@Nullable final Arbitrator item, boolean empty)
{
super.updateItem(item, empty);
if (item != null && !empty)
@ -553,47 +560,56 @@ public class SettingsController implements Initializable, ChildController, Navig
arbitratorsListView.setItems(arbitratorList);
}
private void addLanguage(Locale item)
private void addLanguage(@Nullable Locale item)
{
if (!languageList.contains(item) && item != null)
{
languageList.add(item);
settings.addAcceptedLanguageLocale(item);
storage.write(settings.getClass().getName(), settings);
}
}
private void removeLanguage(Locale item)
private void removeLanguage(@NotNull Locale item)
{
languageList.remove(item);
settings.removeAcceptedLanguageLocale(item);
storage.write(settings.getClass().getName(), settings);
saveSettings();
}
private void addCountry(Country item)
private void addCountry(@Nullable Country item)
{
if (!countryList.contains(item) && item != null)
{
countryList.add(item);
settings.addAcceptedCountry(item);
storage.write(settings.getClass().getName(), settings);
saveSettings();
}
}
private void removeCountry(Country item)
private void removeCountry(@NotNull Country item)
{
countryList.remove(item);
settings.removeAcceptedCountry(item);
storage.write(settings.getClass().getName(), settings);
saveSettings();
}
private void removeArbitrator(Arbitrator item)
private void removeArbitrator(@NotNull Arbitrator item)
{
arbitratorList.remove(item);
settings.removeAcceptedArbitrator(item);
saveSettings();
}
private void saveSettings()
{
storage.write(settings.getClass().getName(), settings);
}
private void saveUser()
{
storage.write(user.getClass().getName(), user);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Bank Account Settings
@ -612,9 +628,9 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountTitleTextField.setText(currentBankAccount.getAccountTitle());
bankAccountHolderNameTextField.setText(currentBankAccount.getAccountHolderName());
bankAccountPrimaryIDTextField.setText(currentBankAccount.getAccountPrimaryID());
bankAccountPrimaryIDTextField.setPromptText(currentBankAccount.getBankAccountTypeInfo().getPrimaryIDName());
bankAccountPrimaryIDTextField.setPromptText(currentBankAccount.getBankAccountType().getPrimaryId());
bankAccountSecondaryIDTextField.setText(currentBankAccount.getAccountSecondaryID());
bankAccountSecondaryIDTextField.setPromptText(currentBankAccount.getBankAccountTypeInfo().getSecondaryIDName());
bankAccountSecondaryIDTextField.setPromptText(currentBankAccount.getBankAccountType().getSecondaryId());
}
else
{
@ -631,7 +647,7 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountPrimaryIDTextField.setText("dummy");
bankAccountSecondaryIDTextField.setText("dummy");
if (user.getCurrentBankAccount() == null)
onSaveBankAccount(null);
onSaveBankAccount();
}
private void resetBankAccountInput()
@ -649,19 +665,26 @@ public class SettingsController implements Initializable, ChildController, Navig
private void initBankAccountComboBox()
{
if (user.getBankAccounts().size() > 0)
if (user.getBankAccounts().isEmpty())
{
bankAccountComboBox.setPromptText("No bank account available");
bankAccountComboBox.setDisable(true);
}
else
{
bankAccountComboBox.setPromptText("Select bank account");
bankAccountComboBox.setDisable(false);
bankAccountComboBox.setItems(FXCollections.observableArrayList(user.getBankAccounts()));
bankAccountComboBox.setConverter(new StringConverter<BankAccount>()
{
@NotNull
@Override
public String toString(BankAccount bankAccount)
public String toString(@NotNull BankAccount bankAccount)
{
return bankAccount.getAccountTitle();
}
@Nullable
@Override
public BankAccount fromString(String s)
{
@ -675,26 +698,23 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountComboBox.getSelectionModel().select(index);
}
}
else
{
bankAccountComboBox.setPromptText("No bank account available");
bankAccountComboBox.setDisable(true);
}
}
private void initBankAccountTypesComboBox()
{
bankAccountTypesComboBox.setItems(FXCollections.observableArrayList(BankAccountTypeInfo.getAllBankAccountTypeInfoObjects()));
bankAccountTypesComboBox.setConverter(new StringConverter<BankAccountTypeInfo>()
bankAccountTypesComboBox.setItems(FXCollections.observableArrayList(BankAccountType.getAllBankAccountTypes()));
bankAccountTypesComboBox.setConverter(new StringConverter<BankAccountType>()
{
@NotNull
@Override
public String toString(BankAccountTypeInfo bankAccountTypeInfo)
public String toString(@NotNull BankAccountType bankAccountTypeInfo)
{
return Localisation.get(bankAccountTypeInfo.getType().toString());
return Localisation.get(bankAccountTypeInfo.toString());
}
@Nullable
@Override
public BankAccountTypeInfo fromString(String s)
public BankAccountType fromString(String s)
{
return null;
}
@ -703,7 +723,7 @@ public class SettingsController implements Initializable, ChildController, Navig
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
int index = bankAccountTypesComboBox.getItems().indexOf(currentBankAccount.getBankAccountTypeInfo());
int index = bankAccountTypesComboBox.getItems().indexOf(currentBankAccount.getBankAccountType());
bankAccountTypesComboBox.getSelectionModel().select(index);
}
}
@ -713,12 +733,14 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountCurrencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllCurrencies()));
bankAccountCurrencyComboBox.setConverter(new StringConverter<Currency>()
{
@NotNull
@Override
public String toString(Currency currency)
public String toString(@NotNull Currency currency)
{
return currency.getCurrencyCode() + " (" + currency.getDisplayName() + ")";
}
@Nullable
@Override
public Currency fromString(String s)
{
@ -741,11 +763,12 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountRegionComboBox.setConverter(new StringConverter<Region>()
{
@Override
public String toString(Region region)
public String toString(@NotNull Region region)
{
return region.getName();
}
@Nullable
@Override
public Region fromString(String s)
{
@ -755,12 +778,14 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountCountryComboBox.setConverter(new StringConverter<Country>()
{
@NotNull
@Override
public String toString(Country country)
public String toString(@NotNull Country country)
{
return country.getName();
}
@Nullable
@Override
public Country fromString(String s)
{
@ -786,7 +811,7 @@ public class SettingsController implements Initializable, ChildController, Navig
{
if (verifyBankAccountData())
{
BankAccount bankAccount = new BankAccount(
@NotNull BankAccount bankAccount = new BankAccount(
bankAccountTypesComboBox.getSelectionModel().getSelectedItem(),
bankAccountCurrencyComboBox.getSelectionModel().getSelectedItem(),
bankAccountCountryComboBox.getSelectionModel().getSelectedItem(),
@ -796,7 +821,7 @@ public class SettingsController implements Initializable, ChildController, Navig
bankAccountSecondaryIDTextField.getText());
user.addBankAccount(bankAccount);
storage.write(user.getClass().getName(), user);
saveUser();
initBankAccountScreen();
}
@ -806,8 +831,8 @@ public class SettingsController implements Initializable, ChildController, Navig
{
user.removeCurrentBankAccount();
storage.write(user.getClass().getName(), user);
saveUser();
saveSettings();
initBankAccountScreen();
}
@ -817,7 +842,7 @@ public class SettingsController implements Initializable, ChildController, Navig
{
BitSquareValidator.textFieldsNotEmptyWithReset(bankAccountTitleTextField, bankAccountHolderNameTextField, bankAccountPrimaryIDTextField, bankAccountSecondaryIDTextField);
BankAccountTypeInfo bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
BankAccountType bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
BitSquareValidator.textFieldBankAccountPrimaryIDIsValid(bankAccountPrimaryIDTextField, bankAccountTypeInfo);
BitSquareValidator.textFieldBankAccountSecondaryIDIsValid(bankAccountSecondaryIDTextField, bankAccountTypeInfo);

View File

@ -49,42 +49,6 @@
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<children>
<Label text="Bank account:"/>
<ComboBox fx:id="bankAccountComboBox" onAction="#selectBankAccount" GridPane.columnIndex="1"/>
<Label text="Bank account type:" GridPane.rowIndex="1"/>
<ComboBox fx:id="bankAccountTypesComboBox" promptText="Select bank account type" onAction="#selectBankAccountType" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
<Label text="Bank account title:" GridPane.rowIndex="2"/>
<TextField fx:id="bankAccountTitleTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Label text="Bank account holder name" GridPane.rowIndex="3"/>
<TextField fx:id="bankAccountHolderNameTextField" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<Label text="Bank account primary ID" GridPane.rowIndex="4"/>
<TextField fx:id="bankAccountPrimaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<Label text="Bank account secondary ID" GridPane.rowIndex="5"/>
<TextField fx:id="bankAccountSecondaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
<Label text="Currency used for bank account:" GridPane.rowIndex="6"/>
<ComboBox fx:id="bankAccountCurrencyComboBox" promptText="Select currency" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
<Label text="Country of bank account" GridPane.rowIndex="7"/>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="7">
<ComboBox fx:id="bankAccountRegionComboBox" onAction="#onSelectBankAccountRegion" prefWidth="150.0" promptText="Select region"/>
<ComboBox fx:id="bankAccountCountryComboBox" visible="false" prefWidth="150.0" promptText="Select country"/>
</HBox>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
<Button fx:id="saveBankAccountButton" defaultButton="true" onAction="#onSaveBankAccount" text="Save bank account"/>
<Button fx:id="addBankAccountButton" onAction="#onAddBankAccount" text="Add new bank account"/>
<Button onAction="#onRemoveBankAccount" text="Remove bank account"/>
</HBox>
</children>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES"/>
@ -100,6 +64,40 @@
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
</rowConstraints>
<Label text="Bank account:"/>
<ComboBox fx:id="bankAccountComboBox" onAction="#selectBankAccount" GridPane.columnIndex="1"/>
<Label text="Bank account type:" GridPane.rowIndex="1"/>
<ComboBox fx:id="bankAccountTypesComboBox" promptText="Select bank account type" onAction="#selectBankAccountType" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
<Label text="Bank account title:" GridPane.rowIndex="2"/>
<TextField fx:id="bankAccountTitleTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Label text="Bank account holder name" GridPane.rowIndex="3"/>
<TextField fx:id="bankAccountHolderNameTextField" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<Label text="Bank account primary ID" GridPane.rowIndex="4"/>
<TextField fx:id="bankAccountPrimaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<Label text="Bank account secondary ID" GridPane.rowIndex="5"/>
<TextField fx:id="bankAccountSecondaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
<Label text="Currency used for bank account:" GridPane.rowIndex="6"/>
<ComboBox fx:id="bankAccountCurrencyComboBox" promptText="Select currency" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
<Label text="Country of bank account" GridPane.rowIndex="7"/>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="7">
<ComboBox fx:id="bankAccountRegionComboBox" onAction="#onSelectBankAccountRegion" prefWidth="150.0" promptText="Select region"/>
<ComboBox fx:id="bankAccountCountryComboBox" visible="false" prefWidth="150.0" promptText="Select country"/>
</HBox>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
<Button fx:id="saveBankAccountButton" defaultButton="true" onAction="#onSaveBankAccount" text="Save bank account"/>
<Button fx:id="addBankAccountButton" onAction="#onAddBankAccount" text="Add new bank account"/>
<Button onAction="#onRemoveBankAccount" text="Remove bank account"/>
</HBox>
</GridPane>
</Tab>

View File

@ -1,5 +1,6 @@
package io.bitsquare.gui.util;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -16,7 +17,7 @@ public class BitSquareConverter
try
{
return stringToDouble2(input);
} catch (NumberFormatException | NullPointerException e)
} catch (@NotNull NumberFormatException | NullPointerException e)
{
return Double.NEGATIVE_INFINITY;
}

View File

@ -10,7 +10,9 @@ import java.util.Currency;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("WeakerAccess")
public class BitSquareFormatter
{
public static String formatPrice(double price)
@ -18,26 +20,34 @@ public class BitSquareFormatter
return formatDouble(price);
}
public static String formatPriceWithCurrencyPair(double price, Currency currency)
@NotNull
public static String formatPriceWithCurrencyPair(double price, @NotNull Currency currency)
{
return formatDouble(price) + " " + currency.toString() + "/BTC";
return formatDouble(price) + " " + currency + "/BTC";
}
@SuppressWarnings("SameParameterValue")
@NotNull
public static String formatAmount(double amount, boolean useBTC, boolean exact)
{
return formatDouble(amount, (exact ? 4 : 2)) + (useBTC ? " BTC" : "");
}
@SuppressWarnings("SameParameterValue")
@NotNull
public static String formatAmount(double amount, boolean useBTC)
{
return formatAmount(amount, useBTC, false);
}
@NotNull
public static String formatAmount(double amount)
{
return formatAmount(amount, false);
}
@SuppressWarnings("SameParameterValue")
@NotNull
public static String formatAmountWithMinAmount(double amount, double minAmount, boolean useBTC)
{
if (useBTC)
@ -46,6 +56,7 @@ public class BitSquareFormatter
return formatDouble(amount) + " (" + formatDouble(minAmount) + ")";
}
@NotNull
public static String formatAmountWithMinAmount(double amount, double minAmount)
{
return formatAmountWithMinAmount(amount, minAmount, false);
@ -56,35 +67,41 @@ public class BitSquareFormatter
return formatDouble(volume);
}
public static String formatVolume(double volume, Currency currency)
@NotNull
public static String formatVolume(double volume, @NotNull Currency currency)
{
return formatDouble(volume) + " " + currency.toString();
return formatDouble(volume) + " " + currency;
}
public static String formatVolumeWithMinVolume(double volume, double minVolume, Currency currency)
@NotNull
public static String formatVolumeWithMinVolume(double volume, double minVolume, @NotNull Currency currency)
{
return formatDouble(volume) + " " + currency.toString() + " (" + formatDouble(minVolume) + " " + currency.toString() + ")";
return formatDouble(volume) + " " + currency + " (" + formatDouble(minVolume) + " " + currency + ")";
}
@NotNull
public static String formatVolumeWithMinVolume(double volume, double minVolume)
{
return formatDouble(volume) + " (" + formatDouble(minVolume) + ")";
}
@NotNull
public static String formatCollateral(double collateral, double amount)
{
return formatPercent(collateral) + " (" + formatDouble(collateral * amount, 4) + " BTC)";
}
@NotNull
public static String formatDirection(Direction direction, boolean allUpperCase)
{
String result = (direction == Direction.BUY) ? "Buy" : "Sell";
@NotNull String result = (direction == Direction.BUY) ? "Buy" : "Sell";
if (allUpperCase)
result = result.toUpperCase();
return result;
}
public static String formatList(List<String> list)
@NotNull
public static String formatList(@NotNull List<String> list)
{
String s = list.toString();
return s.substring(1, s.length() - 1);
@ -97,29 +114,32 @@ public class BitSquareFormatter
public static String formatDouble(double value, int fractionDigits)
{
DecimalFormat decimalFormat = getDecimalFormat(fractionDigits);
@NotNull DecimalFormat decimalFormat = getDecimalFormat(fractionDigits);
return decimalFormat.format(value);
}
@NotNull
public static DecimalFormat getDecimalFormat(int fractionDigits)
{
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
@NotNull DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
decimalFormat.setMinimumFractionDigits(fractionDigits);
decimalFormat.setMaximumFractionDigits(fractionDigits);
decimalFormat.setGroupingUsed(false);
return decimalFormat;
}
@NotNull
private static String formatPercent(double value)
{
return value * 100 + "%";
}
public static String countryLocalesToString(List<Country> countries)
@NotNull
public static String countryLocalesToString(@NotNull List<Country> countries)
{
String result = "";
int i = 0;
for (Country country : countries)
for (@NotNull Country country : countries)
{
result += country.getName();
i++;
@ -129,11 +149,11 @@ public class BitSquareFormatter
return result;
}
public static String languageLocalesToString(List<Locale> languageLocales)
public static String languageLocalesToString(@NotNull List<Locale> languageLocales)
{
String result = "";
int i = 0;
for (Locale locale : languageLocales)
for (@NotNull Locale locale : languageLocales)
{
result += locale.getDisplayLanguage();
i++;
@ -143,11 +163,12 @@ public class BitSquareFormatter
return result;
}
public static String arbitrationMethodsToString(List<Arbitrator.METHOD> items)
@NotNull
public static String arbitrationMethodsToString(@NotNull List<Arbitrator.METHOD> items)
{
String result = "";
int i = 0;
for (Arbitrator.METHOD item : items)
for (@NotNull Arbitrator.METHOD item : items)
{
result += Localisation.get(item.toString());
i++;
@ -157,11 +178,12 @@ public class BitSquareFormatter
return result;
}
public static String arbitrationIDVerificationsToString(List<Arbitrator.ID_VERIFICATION> items)
@NotNull
public static String arbitrationIDVerificationsToString(@NotNull List<Arbitrator.ID_VERIFICATION> items)
{
String result = "";
int i = 0;
for (Arbitrator.ID_VERIFICATION item : items)
for (@NotNull Arbitrator.ID_VERIFICATION item : items)
{
result += Localisation.get(item.toString());
i++;
@ -171,6 +193,7 @@ public class BitSquareFormatter
return result;
}
@NotNull
public static String formatDateTime(Date date)
{
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.getDefault());

View File

@ -1,12 +1,15 @@
package io.bitsquare.gui.util;
import io.bitsquare.bank.BankAccountTypeInfo;
import io.bitsquare.bank.BankAccountType;
import javafx.scene.control.TextField;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.paint.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("WeakerAccess")
public class BitSquareValidator
{
private static final Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
@ -18,24 +21,24 @@ public class BitSquareValidator
textFieldsNotEmpty(textFields);
}
public static void resetTextFields(TextField... textFields)
public static void resetTextFields(@NotNull TextField... textFields)
{
for (TextField textField : textFields)
for (@NotNull TextField textField : textFields)
{
textField.setStyle("-fx-border-color: null");
textField.setEffect(null);
}
}
public static void textFieldsNotEmpty(TextField... textFields) throws ValidationException
public static void textFieldsNotEmpty(@NotNull TextField... textFields) throws ValidationException
{
for (TextField textField : textFields)
for (@NotNull TextField textField : textFields)
{
textFieldNotEmpty(textField);
}
}
public static void textFieldNotEmpty(TextField textField) throws ValidationException
public static void textFieldNotEmpty(@NotNull TextField textField) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
@ -51,15 +54,15 @@ public class BitSquareValidator
textFieldsHasDoubleValue(textFields);
}
public static void textFieldsHasDoubleValue(TextField... textFields) throws ValidationException
public static void textFieldsHasDoubleValue(@NotNull TextField... textFields) throws ValidationException
{
for (TextField textField : textFields)
for (@NotNull TextField textField : textFields)
{
textFieldHasDoubleValue(textField);
}
}
public static void textFieldHasDoubleValue(TextField textField) throws ValidationException
public static void textFieldHasDoubleValue(@NotNull TextField textField) throws ValidationException
{
if (!validateStringAsDouble(textField.getText()))
{
@ -70,7 +73,8 @@ public class BitSquareValidator
}
//TODO
public static void textFieldBankAccountPrimaryIDIsValid(TextField textField, BankAccountTypeInfo bankAccountTypeInfo) throws ValidationException
@SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountPrimaryIDIsValid(@NotNull TextField textField, BankAccountType bankAccountType) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
@ -81,7 +85,8 @@ public class BitSquareValidator
}
//TODO
public static void textFieldBankAccountSecondaryIDIsValid(TextField textField, BankAccountTypeInfo bankAccountTypeInfo) throws ValidationException
@SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountSecondaryIDIsValid(@NotNull TextField textField, BankAccountType bankAccountType) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
@ -91,7 +96,7 @@ public class BitSquareValidator
}
}
public static boolean validateStringsAsDouble(String... inputs)
public static boolean validateStringsAsDouble(@NotNull String... inputs)
{
boolean result = true;
for (String input : inputs)
@ -106,15 +111,16 @@ public class BitSquareValidator
try
{
input = input.replace(",", ".");
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(input);
return true;
} catch (NumberFormatException | NullPointerException e)
} catch (@NotNull NumberFormatException | NullPointerException e)
{
return false;
}
}
public static boolean validateStringsNotEmpty(String... inputs)
public static boolean validateStringsNotEmpty(@NotNull String... inputs)
{
boolean result = true;
for (String input : inputs)
@ -124,13 +130,14 @@ public class BitSquareValidator
return result;
}
public static boolean validateStringNotEmpty(String input)
public static boolean validateStringNotEmpty(@Nullable String input)
{
return input != null && input.length() > 0 && !input.equals(" ");
return input != null && !input.isEmpty() && !" ".equals(input);
}
public static class ValidationException extends Exception
{
private static final long serialVersionUID = -5583980308504568844L;
}
}

View File

@ -9,29 +9,29 @@ import java.util.List;
import java.util.Set;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("CanBeFinal")
public class ConfidenceDisplay
{
private static final Logger log = LoggerFactory.getLogger(ConfidenceDisplay.class);
@Nullable
private WalletEventListener walletEventListener;
@NotNull
private Wallet wallet;
@NotNull
private Label confirmationLabel;
@Nullable
private TextField balanceTextField;
private Transaction transaction;
@NotNull
private ConfidenceProgressIndicator progressIndicator;
/**
* We got the confidence for the actual updating tx.
*
* @param wallet
* @param confirmationLabel
* @param balanceTextField
* @param progressIndicator
*/
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField, ConfidenceProgressIndicator progressIndicator)
public ConfidenceDisplay(@NotNull Wallet wallet, @NotNull Label confirmationLabel, @NotNull TextField balanceTextField, @NotNull ConfidenceProgressIndicator progressIndicator)
{
this.wallet = wallet;
this.confirmationLabel = confirmationLabel;
@ -47,21 +47,21 @@ public class ConfidenceDisplay
walletEventListener = new WalletEventListener()
{
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, @NotNull BigInteger newBalance)
{
updateBalance(newBalance);
// log.debug("onCoinsReceived " + newBalance);
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
public void onTransactionConfidenceChanged(Wallet wallet, @NotNull Transaction tx)
{
updateConfidence(tx);
// log.debug("onTransactionConfidenceChanged tx " + tx.getHashAsString());
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, @NotNull BigInteger newBalance)
{
updateBalance(newBalance);
}
@ -89,21 +89,13 @@ public class ConfidenceDisplay
wallet.addEventListener(walletEventListener);
}
/**
* @param wallet
* @param confirmationLabel
* @param transaction We want the confidence for only that tx, not the lasted changed in the wallet
* @param progressIndicator
*/
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, final Transaction transaction, ConfidenceProgressIndicator progressIndicator)
public ConfidenceDisplay(@NotNull Wallet wallet, @NotNull Label confirmationLabel, @NotNull final Transaction transaction, @NotNull ConfidenceProgressIndicator progressIndicator)
{
this.wallet = wallet;
this.confirmationLabel = confirmationLabel;
this.transaction = transaction;
this.progressIndicator = progressIndicator;
if (balanceTextField != null)
balanceTextField.setText("");
confirmationLabel.setVisible(false);
progressIndicator.setVisible(false);
progressIndicator.setProgress(0);
@ -114,7 +106,7 @@ public class ConfidenceDisplay
walletEventListener = new WalletEventListener()
{
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
public void onCoinsReceived(Wallet wallet, @NotNull Transaction tx, BigInteger prevBalance, @NotNull BigInteger newBalance)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
updateBalance(newBalance);
@ -122,7 +114,7 @@ public class ConfidenceDisplay
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
public void onTransactionConfidenceChanged(Wallet wallet, @NotNull Transaction tx)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
updateConfidence(transaction);
@ -130,7 +122,7 @@ public class ConfidenceDisplay
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
public void onCoinsSent(Wallet wallet, @NotNull Transaction tx, BigInteger prevBalance, @NotNull BigInteger newBalance)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
updateBalance(newBalance);
@ -166,15 +158,9 @@ public class ConfidenceDisplay
confirmationLabel.setText("");
if (balanceTextField != null)
balanceTextField.setText("");
walletEventListener = null;
wallet = null;
confirmationLabel = null;
progressIndicator = null;
balanceTextField = null;
}
private void updateBalance(BigInteger balance)
private void updateBalance(@NotNull BigInteger balance)
{
if (balance.compareTo(BigInteger.ZERO) > 0)
{
@ -183,8 +169,8 @@ public class ConfidenceDisplay
progressIndicator.setProgress(-1);
Set<Transaction> transactions = wallet.getTransactions(false);
Transaction latestTransaction = null;
for (Transaction transaction : transactions)
@Nullable Transaction latestTransaction = null;
for (@NotNull Transaction transaction : transactions)
{
if (latestTransaction != null)
{
@ -206,7 +192,7 @@ public class ConfidenceDisplay
balanceTextField.setText(BtcFormatter.satoshiToString(balance));
}
private void updateConfidence(Transaction tx)
private void updateConfidence(@NotNull Transaction tx)
{
TransactionConfidence confidence = tx.getConfidence();
double progressIndicatorSize = 50;

View File

@ -1,56 +1,53 @@
package io.bitsquare.gui.util;
import io.bitsquare.bank.BankAccountTypeInfo;
import io.bitsquare.gui.components.VSpacer;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import javafx.collections.FXCollections;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import org.jetbrains.annotations.NotNull;
//TODO to be removed
@SuppressWarnings({"SameParameterValue", "UnusedReturnValue"})
public class FormBuilder
{
public static Label addLabel(GridPane gridPane, String title, String value, int row)
@NotNull
public static Label addLabel(@NotNull GridPane gridPane, String title, String value, int row)
{
gridPane.add(new Label(title), 0, row);
Label valueLabel = new Label(value);
@NotNull Label valueLabel = new Label(value);
gridPane.add(valueLabel, 1, row);
return valueLabel;
}
public static Label addHeaderLabel(GridPane gridPane, String title, int row, int column)
@NotNull
public static Label addHeaderLabel(@NotNull GridPane gridPane, String title, int row, int column)
{
Label headerLabel = new Label(title);
@NotNull Label headerLabel = new Label(title);
headerLabel.setId("form-header-text");
gridPane.add(headerLabel, column, row);
return headerLabel;
}
public static Label addHeaderLabel(GridPane gridPane, String title, int row)
@NotNull
public static Label addHeaderLabel(@NotNull GridPane gridPane, String title, int row)
{
return addHeaderLabel(gridPane, title, row, 0);
}
public static TextField addInputField(GridPane gridPane, String title, String value, int row)
{
return addTextField(gridPane, title, value, row, true, true);
}
public static TextField addTextField(GridPane gridPane, String title, String value, int row)
@NotNull
public static TextField addTextField(@NotNull GridPane gridPane, String title, String value, int row)
{
return addTextField(gridPane, title, value, row, false, false);
}
public static TextField addTextField(GridPane gridPane, String title, String value, int row, boolean editable, boolean selectable)
@NotNull
public static TextField addTextField(@NotNull GridPane gridPane, String title, String value, int row, boolean editable, boolean selectable)
{
gridPane.add(new Label(title), 0, row);
TextField textField = new TextField(value);
@NotNull TextField textField = new TextField(value);
gridPane.add(textField, 1, row);
textField.setMouseTransparent(!selectable && !editable);
textField.setEditable(editable);
@ -58,92 +55,18 @@ public class FormBuilder
return textField;
}
public static void addVSpacer(GridPane gridPane, int row)
public static void addVSpacer(@NotNull GridPane gridPane, int row)
{
gridPane.add(new VSpacer(10), 0, row);
}
public static Button addButton(GridPane gridPane, String title, int row)
@NotNull
public static Button addButton(@NotNull GridPane gridPane, String title, int row)
{
Button button = new Button(title);
@NotNull Button button = new Button(title);
gridPane.add(button, 1, row);
return button;
}
public static ComboBox<Locale> addLocalesComboBox(GridPane gridPane, String title, List<Locale> list, int row)
{
gridPane.add(new Label(title), 0, row);
ComboBox<Locale> comboBox = new ComboBox<>(FXCollections.observableArrayList(list));
gridPane.add(comboBox, 1, row);
return comboBox;
}
public static ComboBox<Currency> addCurrencyComboBox(GridPane gridPane, String title, List<Currency> list, int row)
{
gridPane.add(new Label(title), 0, row);
ComboBox<Currency> comboBox = new ComboBox<>(FXCollections.observableArrayList(list));
gridPane.add(comboBox, 1, row);
return comboBox;
}
public static ComboBox<BankAccountTypeInfo> addBankAccountComboBox(GridPane gridPane, String title, List<BankAccountTypeInfo> list, int row)
{
gridPane.add(new Label(title), 0, row);
ComboBox<BankAccountTypeInfo> comboBox = new ComboBox<>(FXCollections.observableArrayList(list));
gridPane.add(comboBox, 1, row);
return comboBox;
}
/* public static ComboBox addLocalesComboBox(GridPane gridPane, String title, List<?> list, int row)
{
gridPane.add(new Label(title), 0, row);
ComboBox<?> comboBox = new ComboBox<>(FXCollections.observableArrayList(list));
gridPane.add(comboBox, 1, row);
return comboBox;
} */
/* public static TextField addConfirmationsLabel(GridPane gridPane, WalletFacade walletFacade, int row)
{
return FormBuilder.addTextField(gridPane, "Confirmations:", getConfirmationText(walletFacade), row);
} */
/* public static ProgressIndicator addConfirmationsSpinner(GridPane gridPane, WalletFacade walletFacade, int row)
{
ProgressIndicator progressIndicator = new ProgressIndicator();
gridPane.add(progressIndicator, 3, row);
progressIndicator.setPrefSize(18, 18);
if (walletFacade.getRegConfDepthInBlocks() == 0 && walletFacade.getRegConfNumBroadcastPeers() > 0)
progressIndicator.setProgress(-1);
else
progressIndicator.setOpacity(0);
return progressIndicator;
}
public static ImageView addConfirmationsIcon(GridPane gridPane, WalletFacade walletFacade, int row)
{
int depthInBlocks = walletFacade.getRegConfNumBroadcastPeers();
int numBroadcastPeers = walletFacade.getRegConfDepthInBlocks();
Image confirmIconImage;
if (depthInBlocks > 0)
confirmIconImage = Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks));
else
confirmIconImage = Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers));
ImageView confirmIconImageView = new ImageView(confirmIconImage);
gridPane.add(confirmIconImageView, 2, row);
return confirmIconImageView;
}
public static String getConfirmationText(WalletFacade walletFacade)
{
int numBroadcastPeers = walletFacade.getRegConfNumBroadcastPeers();
int depthInBlocks = walletFacade.getRegConfDepthInBlocks();
return depthInBlocks + " confirmation(s) / " + "Seen by " + numBroadcastPeers + " peer(s)";
} */
}

View File

@ -2,6 +2,7 @@ package io.bitsquare.gui.util;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.jetbrains.annotations.NotNull;
public class Icons
{
@ -26,11 +27,13 @@ public class Icons
public static final String SELL = "/images/sell.png";
public static final String REMOVE = "/images/removeOffer.png";
@NotNull
public static Image getIconImage(String iconName)
{
return new Image(Icons.class.getResourceAsStream(iconName));
}
@NotNull
public static ImageView getIconImageView(String iconName)
{
return new ImageView(new Image(Icons.class.getResourceAsStream(iconName)));

View File

@ -6,65 +6,72 @@ import javafx.scene.Node;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
import org.jetbrains.annotations.NotNull;
import static com.google.common.base.Preconditions.checkState;
@SuppressWarnings("WeakerAccess")
public class Transitions
{
public static final int UI_ANIMATION_TIME = 350;
public static final int UI_ANIMATION_TIME = 800;
public static void fadeIn(Node ui)
{
fadeIn(ui, UI_ANIMATION_TIME);
}
@SuppressWarnings("SameParameterValue")
public static void fadeIn(Node ui, int time)
{
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME), ui);
@NotNull FadeTransition ft = new FadeTransition(Duration.millis(time), ui);
ft.setFromValue(0.0);
ft.setToValue(1.0);
ft.play();
}
public static Animation fadeOut(Node ui)
@NotNull
public static Animation fadeOut(@NotNull Node ui)
{
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME), ui);
@NotNull FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME), ui);
ft.setFromValue(ui.getOpacity());
ft.setToValue(0.0);
ft.play();
return ft;
}
public static Animation fadeOutAndRemove(Node ui, Pane parentPane)
@SuppressWarnings("UnusedReturnValue")
@NotNull
public static Animation fadeOutAndRemove(@NotNull Node ui)
{
Animation animation = fadeOut(ui);
animation.setOnFinished(actionEvent -> parentPane.getChildren().remove(ui));
@NotNull Animation animation = fadeOut(ui);
animation.setOnFinished(actionEvent -> ((Pane) (ui.getParent())).getChildren().remove(ui));
return animation;
}
public static void blurOut(Node node)
public static void blurOut(@NotNull Node node)
{
blurOut(node, UI_ANIMATION_TIME);
}
public static void blurOut(Node node, int time)
@SuppressWarnings("SameParameterValue")
public static void blurOut(@NotNull Node node, int time)
{
GaussianBlur blur = new GaussianBlur(0.0);
@NotNull GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
KeyFrame kf = new KeyFrame(Duration.millis(time), kv);
@NotNull Timeline timeline = new Timeline();
@NotNull KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
@NotNull KeyFrame kf = new KeyFrame(Duration.millis(time), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
}
public static void blurIn(Node node)
public static void blurIn(@NotNull Node node)
{
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME), kv);
@NotNull GaussianBlur blur = (GaussianBlur) node.getEffect();
@NotNull Timeline timeline = new Timeline();
@NotNull KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
@NotNull KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME), kv);
timeline.getKeyFrames().add(kf);
timeline.setOnFinished(actionEvent -> node.setEffect(null));
timeline.play();

View File

@ -2,16 +2,21 @@ package io.bitsquare.locale;
import java.io.Serializable;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Country implements Serializable
{
private static final long serialVersionUID = -5930294199097793187L;
@NotNull
private final String code;
@NotNull
private final String name;
@NotNull
private final Region region;
public Country(String code, String name, Region region)
public Country(@NotNull String code, @NotNull String name, @NotNull Region region)
{
this.code = code;
this.name = name;
@ -23,33 +28,37 @@ public class Country implements Serializable
return Objects.hashCode(code);
}
public boolean equals(Object obj)
public boolean equals(@Nullable Object obj)
{
if (!(obj instanceof Country))
return false;
if (obj == this)
return true;
Country other = (Country) obj;
return other.getCode().equals(code);
final Country other = (Country) obj;
return code.equals(other.getCode());
}
@NotNull
public String getCode()
{
return code;
}
@NotNull
public String getName()
{
return name;
}
@NotNull
public Region getRegion()
{
return region;
}
@NotNull
@Override
public String toString()
{

View File

@ -4,6 +4,8 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import java.util.*;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CountryUtil
{
@ -104,7 +106,7 @@ public class CountryUtil
"YE",
"ZA"
};
private static final List<String> regionCodeList = Arrays.asList(countryCodes);
private static final List<String> countryCodeList = Arrays.asList(countryCodes);
private static final String[] regionCodes = new String[]{
"AS",
"EU",
@ -203,7 +205,7 @@ public class CountryUtil
"AS",
"AF"
};
private static final List<String> countryCodeList = Arrays.asList(regionCodes);
private static final List<String> regionCodeList = Arrays.asList(regionCodes);
private static final String[][] regionCodeToName = new String[][]{
{"NA", "North America"},
{"SA", "South America"},
@ -213,12 +215,13 @@ public class CountryUtil
{"OC", "Oceania"}
};
@NotNull
public static List<Region> getAllRegions()
{
List<Region> allRegions = new ArrayList<>();
final List<Region> allRegions = new ArrayList<>();
String regionCode = "NA";
Region region = new Region(regionCode, getRegionName(regionCode));
@NotNull String regionCode = "NA";
@NotNull Region region = new Region(regionCode, getRegionName(regionCode));
allRegions.add(region);
regionCode = "SA";
@ -244,52 +247,50 @@ public class CountryUtil
return allRegions;
}
public static List<Country> getAllCountriesFor(Region selectedRegion)
public static List<Country> getAllCountriesFor(@Nullable Region selectedRegion)
{
List<Country> allCountries = getAllCountries();
return Lists.newArrayList(Collections2.filter(allCountries, country -> selectedRegion != null && country != null && country.getRegion().equals(selectedRegion)));
return Lists.newArrayList(Collections2.filter(getAllCountries(), country -> selectedRegion != null && country != null && selectedRegion.equals(country.getRegion())));
}
public static List<Country> getAllCountries()
@NotNull
private static List<Country> getAllCountries()
{
List<Locale> allCountryLocales = getAllCountryLocales();
List<Country> allCountries = new ArrayList<>();
for (Locale locale : allCountryLocales)
final List<Country> allCountries = new ArrayList<>();
for (final Locale locale : getAllCountryLocales())
{
String regionCode = getRegionCode(locale.getCountry());
Region region = new Region(regionCode, getRegionName(regionCode));
Country country = new Country(locale.getCountry(), locale.getDisplayCountry(), region);
final Region region = new Region(regionCode, getRegionName(regionCode));
final Country country = new Country(locale.getCountry(), locale.getDisplayCountry(), region);
allCountries.add(country);
}
return allCountries;
}
@NotNull
public static Country getDefaultCountry()
{
Locale locale = new Locale("", Locale.getDefault().getCountry());
final Locale locale = new Locale("", Locale.getDefault().getCountry());
String regionCode = getRegionCode(locale.getCountry());
Region region = new Region(regionCode, getRegionName(regionCode));
final Region region = new Region(regionCode, getRegionName(regionCode));
return new Country(locale.getCountry(), locale.getDisplayCountry(), region);
}
public static String getRegionName(String regionCode)
@NotNull
private static String getRegionName(@NotNull final String regionCode)
{
for (String[] regionName : regionCodeToName)
for (final String[] regionName : regionCodeToName)
{
if (regionName[0].equals(regionCode))
{
return regionName[1];
}
}
return regionCode;
}
@NotNull
private static List<Locale> getAllCountryLocales()
{
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !locale.getCountry().equals("")).map(locale -> new Locale("", locale.getCountry(), "")).collect(Collectors.toSet());
@NotNull List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getCountry())).map(locale -> new Locale("", locale.getCountry(), "")).collect(Collectors.toSet());
/*
same as:
Set<Locale> allLocalesAsSet = new HashSet<>();
@ -307,17 +308,13 @@ public class CountryUtil
return allLocales;
}
private static String getRegionCode(String countryCode)
@NotNull
private static String getRegionCode(@NotNull String countryCode)
{
if (countryCode.length() > 0 && countryCodeList.contains(countryCode))
{
int index = countryCodeList.indexOf(countryCode);
return regionCodeList.get(index);
}
if (!countryCode.isEmpty() && countryCodeList.contains(countryCode))
return regionCodeList.get(countryCodeList.indexOf(countryCode));
else
{
return "Undefined";
}
}
}

View File

@ -2,12 +2,14 @@ package io.bitsquare.locale;
import java.text.NumberFormat;
import java.util.*;
import org.jetbrains.annotations.NotNull;
public class CurrencyUtil
{
@NotNull
public static List<Currency> getAllCurrencies()
{
ArrayList<Currency> mainCurrencies = new ArrayList<>();
final ArrayList<Currency> mainCurrencies = new ArrayList<>();
mainCurrencies.add(Currency.getInstance("USD"));
mainCurrencies.add(Currency.getInstance("EUR"));
mainCurrencies.add(Currency.getInstance("CNY"));
@ -22,10 +24,10 @@ public class CurrencyUtil
Set<Currency> allCurrenciesSet = Currency.getAvailableCurrencies();
allCurrenciesSet.removeAll(mainCurrencies);
List<Currency> allCurrenciesList = new ArrayList<>(allCurrenciesSet);
final List<Currency> allCurrenciesList = new ArrayList<>(allCurrenciesSet);
allCurrenciesList.sort((a, b) -> a.getCurrencyCode().compareTo(b.getCurrencyCode()));
List<Currency> resultList = new ArrayList<>(mainCurrencies);
final List<Currency> resultList = new ArrayList<>(mainCurrencies);
resultList.addAll(allCurrenciesList);
Currency defaultCurrency = Currency.getInstance(Locale.getDefault());
@ -35,6 +37,7 @@ public class CurrencyUtil
return resultList;
}
@NotNull
public static Currency getDefaultCurrency()
{
return NumberFormat.getNumberInstance(Locale.getDefault()).getCurrency();

View File

@ -2,6 +2,7 @@ package io.bitsquare.locale;
import java.util.*;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
public class LanguageUtil
{
@ -22,17 +23,18 @@ public class LanguageUtil
return list;
} */
@NotNull
public static List<Locale> getAllLanguageLocales()
{
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !locale.getLanguage().equals("")).map(locale -> new Locale(locale.getLanguage(), "")).collect(Collectors.toSet());
@NotNull List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
final Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getLanguage())).map(locale -> new Locale(locale.getLanguage(), "")).collect(Collectors.toSet());
allLocales = new ArrayList<>();
allLocales.addAll(allLocalesAsSet);
allLocales.sort((locale1, locale2) -> locale1.getDisplayLanguage().compareTo(locale2.getDisplayLanguage()));
return allLocales;
}
@NotNull
public static Locale getDefaultLanguageLocale()
{
return new Locale(Locale.getDefault().getLanguage(), "");

View File

@ -10,6 +10,8 @@ import java.util.Locale;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -17,25 +19,27 @@ public class Localisation
{
private static final Logger log = LoggerFactory.getLogger(Localisation.class);
@NotNull
public static ResourceBundle getResourceBundle()
{
return ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control());
}
public static String get(String key)
@NotNull
public static String get(@NotNull String key)
{
try
{
return Localisation.getResourceBundle().getString(key);
} catch (MissingResourceException e)
{
log.error("MissingResourceException for key: " + key);
log.error("MissingResourceException for key: " + key);
return key + " is missing";
}
}
public static String get(String key, String... arguments)
@NotNull
public static String get(@NotNull String key, String... arguments)
{
return MessageFormat.format(Localisation.get(key), arguments);
}
@ -43,22 +47,20 @@ public class Localisation
class UTF8Control extends ResourceBundle.Control
{
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
@Nullable
public ResourceBundle newBundle(@NotNull String baseName, @NotNull Locale locale, @NotNull String format, @NotNull ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException
{
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
final String bundleName = toBundleName(baseName, locale);
final String resourceName = toResourceName(bundleName, "properties");
@Nullable ResourceBundle bundle = null;
@Nullable InputStream stream = null;
if (reload)
{
URL url = loader.getResource(resourceName);
final URL url = loader.getResource(resourceName);
if (url != null)
{
URLConnection connection = url.openConnection();
final URLConnection connection = url.openConnection();
if (connection != null)
{
connection.setUseCaches(false);

View File

@ -2,15 +2,19 @@ package io.bitsquare.locale;
import java.io.Serializable;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Region implements Serializable
{
private static final long serialVersionUID = -5930294199097793187L;
@NotNull
private final String code;
@NotNull
private final String name;
public Region(String code, String name)
public Region(@NotNull String code, @NotNull String name)
{
this.code = code;
this.name = name;
@ -21,27 +25,30 @@ public class Region implements Serializable
return Objects.hashCode(code);
}
public boolean equals(Object obj)
public boolean equals(@Nullable Object obj)
{
if (!(obj instanceof Region))
return false;
if (obj == this)
return true;
Region other = (Region) obj;
return other.getCode().equals(code);
@NotNull Region other = (Region) obj;
return code.equals(other.getCode());
}
public String getCode()
@NotNull
String getCode()
{
return code;
}
@NotNull
public String getName()
{
return name;
}
@NotNull
@Override
public String toString()
{

View File

@ -8,8 +8,7 @@ import io.bitsquare.trade.payment.offerer.OffererPaymentProtocol;
import io.bitsquare.trade.payment.taker.TakerPaymentProtocol;
import io.bitsquare.user.Arbitrator;
import io.bitsquare.util.DSAKeyUtil;
import io.bitsquare.util.Utilities;
import java.io.File;
import io.bitsquare.util.FileUtil;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PublicKey;
@ -24,9 +23,12 @@ import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerMaker;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.rpc.ObjectDataReply;
import net.tomp2p.storage.Data;
import net.tomp2p.storage.StorageDisk;
import net.tomp2p.utils.Utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -35,12 +37,14 @@ import org.slf4j.LoggerFactory;
* The TomP2P library codebase shall not be used outside that facade.
* That way a change of the library will only affect that class.
*/
@SuppressWarnings({"EmptyMethod", "ConstantConditions"})
public class MessageFacade
{
public static final String PING = "ping";
public static final String PONG = "pong";
private static final String PING = "ping";
private static final String PONG = "pong";
private static final Logger log = LoggerFactory.getLogger(MessageFacade.class);
private static final int MASTER_PEER_PORT = 5000;
@NotNull
private static String MASTER_PEER_IP = "192.168.1.33";
private final List<OrderBookListener> orderBookListeners = new ArrayList<>();
private final List<TakeOfferRequestListener> takeOfferRequestListeners = new ArrayList<>();
@ -51,7 +55,7 @@ public class MessageFacade
private final List<PingPeerListener> pingPeerListeners = new ArrayList<>();
private final BooleanProperty isDirty = new SimpleBooleanProperty(false);
private Peer myPeer;
private int port;
@Nullable
private KeyPair keyPair;
private Peer masterPeer;
private Long lastTimeStamp = -3L;
@ -81,17 +85,16 @@ public class MessageFacade
public void init()
{
String keyName = BitSquare.ID;
port = Bindings.MAX_PORT - Math.abs(new Random().nextInt()) % (Bindings.MAX_PORT - Bindings.MIN_DYN_PORT);
if (BitSquare.ID.equals("taker"))
int port = Bindings.MAX_PORT - Math.abs(new Random().nextInt()) % (Bindings.MAX_PORT - Bindings.MIN_DYN_PORT);
if ("taker".equals(BitSquare.ID))
port = 4501;
else if (BitSquare.ID.equals("offerer"))
else if ("offerer".equals(BitSquare.ID))
port = 4500;
try
{
createMyPeerInstance(keyName, port);
//setupStorage();
createMyPeerInstance(port);
// setupStorage();
//TODO save periodically or get informed if network address changes
saveMyAddressToDHT();
setupReplyHandler();
@ -136,6 +139,7 @@ public class MessageFacade
// That way he can prove with the signature that he is the payer of the offer fee.
// It does not assure that the trade was really executed, but we can protect the traders privacy that way.
// If we use the trade, we would link all trades together and would reveal the whole trading history.
@SuppressWarnings("UnusedParameters")
public void addOfferFeePaymentToReputation(String txId, String pubKeyOfFeePayment) throws IOException
{
String pubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(getPubKey()); // out message ID
@ -149,29 +153,31 @@ public class MessageFacade
// Arbitrators
///////////////////////////////////////////////////////////////////////////////////////////
public void addArbitrator(Arbitrator arbitrator) throws IOException
public void addArbitrator(@NotNull Arbitrator arbitrator) throws IOException
{
Number160 locationKey = Number160.createHash("Arbitrators");
final Number160 contentKey = Number160.createHash(arbitrator.getUID());
final Data arbitratorData = new Data(arbitrator);
final Number160 contentKey = Number160.createHash(arbitrator.getId());
@NotNull final Data arbitratorData = new Data(arbitrator);
//offerData.setTTLSeconds(5);
final FutureDHT addFuture = myPeer.put(locationKey).setData(contentKey, arbitratorData).start();
//final FutureDHT addFuture = myPeer.add(locationKey).setData(offerData).start();
addFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture future) throws Exception
public void operationComplete(@NotNull BaseFuture future) throws Exception
{
Platform.runLater(() -> onArbitratorAdded(arbitratorData, future.isSuccess(), locationKey));
}
});
}
@SuppressWarnings("UnusedParameters")
private void onArbitratorAdded(Data arbitratorData, boolean success, Number160 locationKey)
{
}
@SuppressWarnings("UnusedParameters")
public void getArbitrators(Locale languageLocale)
{
final Number160 locationKey = Number160.createHash("Arbitrators");
@ -179,7 +185,7 @@ public class MessageFacade
getArbitratorsFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture future) throws Exception
public void operationComplete(@NotNull BaseFuture future) throws Exception
{
final Map<Number160, Data> dataMap = getArbitratorsFuture.getDataMap();
Platform.runLater(() -> onArbitratorsReceived(dataMap, future.isSuccess()));
@ -189,7 +195,7 @@ public class MessageFacade
private void onArbitratorsReceived(Map<Number160, Data> dataMap, boolean success)
{
for (ArbitratorListener arbitratorListener : arbitratorListeners)
for (@NotNull ArbitratorListener arbitratorListener : arbitratorListeners)
arbitratorListener.onArbitratorsReceived(dataMap, success);
}
@ -199,29 +205,29 @@ public class MessageFacade
///////////////////////////////////////////////////////////////////////////////////////////
//TODO use Offer and do proper serialisation here
public void addOffer(Offer offer) throws IOException
public void addOffer(@NotNull Offer offer) throws IOException
{
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
final Number160 contentKey = Number160.createHash(offer.getId());
final Data offerData = new Data(offer);
@NotNull final Data offerData = new Data(offer);
//offerData.setTTLSeconds(5);
final FutureDHT addFuture = myPeer.put(locationKey).setData(contentKey, offerData).start();
//final FutureDHT addFuture = myPeer.add(locationKey).setData(offerData).start();
addFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture future) throws Exception
public void operationComplete(@NotNull BaseFuture future) throws Exception
{
Platform.runLater(() -> onOfferAdded(offerData, future.isSuccess(), locationKey));
}
});
}
private void onOfferAdded(Data offerData, boolean success, Number160 locationKey)
private void onOfferAdded(Data offerData, boolean success, @NotNull Number160 locationKey)
{
setDirty(locationKey);
for (OrderBookListener orderBookListener : orderBookListeners)
for (@NotNull OrderBookListener orderBookListener : orderBookListeners)
orderBookListener.onOfferAdded(offerData, success);
}
@ -237,7 +243,7 @@ public class MessageFacade
getOffersFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture future) throws Exception
public void operationComplete(@NotNull BaseFuture future) throws Exception
{
final Map<Number160, Data> dataMap = getOffersFuture.getDataMap();
Platform.runLater(() -> onOffersReceived(dataMap, future.isSuccess()));
@ -247,7 +253,7 @@ public class MessageFacade
private void onOffersReceived(Map<Number160, Data> dataMap, boolean success)
{
for (OrderBookListener orderBookListener : orderBookListeners)
for (@NotNull OrderBookListener orderBookListener : orderBookListeners)
orderBookListener.onOffersReceived(dataMap, success);
}
@ -255,7 +261,7 @@ public class MessageFacade
// Remove offer
///////////////////////////////////////////////////////////////////////////////////////////
public void removeOffer(Offer offer)
public void removeOffer(@NotNull Offer offer)
{
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
Number160 contentKey = Number160.createHash(offer.getId());
@ -264,7 +270,7 @@ public class MessageFacade
removeFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture future) throws Exception
public void operationComplete(@NotNull BaseFuture future) throws Exception
{
Data data = removeFuture.getData();
Platform.runLater(() -> onOfferRemoved(data, future.isSuccess(), locationKey));
@ -272,12 +278,12 @@ public class MessageFacade
});
}
private void onOfferRemoved(Data data, boolean success, Number160 locationKey)
private void onOfferRemoved(Data data, boolean success, @NotNull Number160 locationKey)
{
log.debug("onOfferRemoved");
setDirty(locationKey);
for (OrderBookListener orderBookListener : orderBookListeners)
for (@NotNull OrderBookListener orderBookListener : orderBookListeners)
orderBookListener.onOfferRemoved(data, success);
}
@ -286,12 +292,13 @@ public class MessageFacade
// Check dirty flag for a location key
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public BooleanProperty getIsDirtyProperty()
{
return isDirty;
}
public void getDirtyFlag(Currency currency)
public void getDirtyFlag(@NotNull Currency currency)
{
Number160 locationKey = Number160.createHash(currency.getCurrencyCode());
FutureDHT getFuture = myPeer.get(getDirtyLocationKey(locationKey)).start();
@ -334,12 +341,12 @@ public class MessageFacade
lastTimeStamp++;
}
private Number160 getDirtyLocationKey(Number160 locationKey)
private Number160 getDirtyLocationKey(@NotNull Number160 locationKey)
{
return Number160.createHash(locationKey.toString() + "Dirty");
return Number160.createHash(locationKey + "Dirty");
}
private void setDirty(Number160 locationKey)
private void setDirty(@NotNull Number160 locationKey)
{
// we don't want to get an update from dirty for own changes, so update the lastTimeStamp to omit a change trigger
lastTimeStamp = System.currentTimeMillis();
@ -423,18 +430,18 @@ public class MessageFacade
// Find peer address
///////////////////////////////////////////////////////////////////////////////////////////
public void getPeerAddress(final String pubKeyAsHex, AddressLookupListener listener)
public void getPeerAddress(final String pubKeyAsHex, @NotNull AddressLookupListener listener)
{
final Number160 location = Number160.createHash(pubKeyAsHex);
final FutureDHT getPeerAddressFuture = myPeer.get(location).start();
getPeerAddressFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
@Override
public void operationComplete(BaseFuture baseFuture) throws Exception
public void operationComplete(@NotNull BaseFuture baseFuture) throws Exception
{
if (baseFuture.isSuccess() && getPeerAddressFuture.getData() != null)
{
final PeerAddress peerAddress = (PeerAddress) getPeerAddressFuture.getData().getObject();
@NotNull final PeerAddress peerAddress = (PeerAddress) getPeerAddressFuture.getData().getObject();
Platform.runLater(() -> onAddressFound(peerAddress, listener));
}
else
@ -445,12 +452,12 @@ public class MessageFacade
});
}
private void onAddressFound(final PeerAddress peerAddress, AddressLookupListener listener)
private void onAddressFound(final PeerAddress peerAddress, @NotNull AddressLookupListener listener)
{
listener.onResult(peerAddress);
}
private void onGetPeerAddressFailed(AddressLookupListener listener)
private void onGetPeerAddressFailed(@NotNull AddressLookupListener listener)
{
listener.onFailed();
}
@ -460,7 +467,7 @@ public class MessageFacade
// Trade process
///////////////////////////////////////////////////////////////////////////////////////////
public void sendTradeMessage(final PeerAddress peerAddress, final TradeMessage tradeMessage, TradeMessageListener listener)
public void sendTradeMessage(final PeerAddress peerAddress, final TradeMessage tradeMessage, @NotNull TradeMessageListener listener)
{
final PeerConnection peerConnection = myPeer.createPeerConnection(peerAddress, 10);
final FutureResponse sendFuture = myPeer.sendDirect(peerConnection).setObject(tradeMessage).start();
@ -482,12 +489,12 @@ public class MessageFacade
);
}
private void onSendTradingMessageResult(TradeMessageListener listener)
private void onSendTradingMessageResult(@NotNull TradeMessageListener listener)
{
listener.onResult();
}
private void onSendTradingMessageFailed(TradeMessageListener listener)
private void onSendTradingMessageFailed(@NotNull TradeMessageListener listener)
{
listener.onFailed();
}
@ -497,47 +504,47 @@ public class MessageFacade
// Process incoming tradingMessage
///////////////////////////////////////////////////////////////////////////////////////////
private void processTradingMessage(TradeMessage tradeMessage, PeerAddress sender)
private void processTradingMessage(@NotNull TradeMessage tradeMessage, PeerAddress sender)
{
//TODO change to map (key: offerID) instead of list (offererPaymentProtocols, takerPaymentProtocols)
log.info("processTradingMessage " + tradeMessage.getType().toString());
log.info("processTradingMessage " + tradeMessage.getType());
switch (tradeMessage.getType())
{
case REQUEST_TAKE_OFFER:
// That is used to initiate the OffererPaymentProtocol and to show incoming requests in the view
for (TakeOfferRequestListener takeOfferRequestListener : takeOfferRequestListeners)
for (@NotNull TakeOfferRequestListener takeOfferRequestListener : takeOfferRequestListeners)
takeOfferRequestListener.onTakeOfferRequested(tradeMessage, sender);
break;
case ACCEPT_TAKE_OFFER_REQUEST:
for (TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
for (@NotNull TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
takeOfferTradeListener.onTakeOfferRequestAccepted();
break;
case REJECT_TAKE_OFFER_REQUEST:
for (TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
for (@NotNull TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
takeOfferTradeListener.onTakeOfferRequestRejected();
break;
case TAKE_OFFER_FEE_PAYED:
for (OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
for (@NotNull OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
offererPaymentProtocol.onTakeOfferFeePayed(tradeMessage);
break;
case REQUEST_TAKER_DEPOSIT_PAYMENT:
for (TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
for (@NotNull TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
takeOfferTradeListener.onTakerDepositPaymentRequested(tradeMessage);
break;
case REQUEST_OFFERER_DEPOSIT_PUBLICATION:
for (OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
for (@NotNull OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
offererPaymentProtocol.onDepositTxReadyForPublication(tradeMessage);
break;
case DEPOSIT_TX_PUBLISHED:
for (TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
for (@NotNull TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
takeOfferTradeListener.onDepositTxPublished(tradeMessage);
break;
case BANK_TX_INITED:
for (TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
for (@NotNull TakerPaymentProtocol takeOfferTradeListener : takerPaymentProtocols)
takeOfferTradeListener.onBankTransferInited(tradeMessage);
break;
case PAYOUT_TX_PUBLISHED:
for (OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
for (@NotNull OffererPaymentProtocol offererPaymentProtocol : offererPaymentProtocols)
offererPaymentProtocol.onPayoutTxPublished(tradeMessage);
break;
@ -564,7 +571,7 @@ public class MessageFacade
final Data data = getPeerAddressFuture.getData();
if (data != null && data.getObject() instanceof PeerAddress)
{
final PeerAddress peerAddress = (PeerAddress) data.getObject();
@NotNull final PeerAddress peerAddress = (PeerAddress) data.getObject();
Platform.runLater(() -> onAddressFoundPingPeer(peerAddress));
}
}
@ -587,9 +594,8 @@ public class MessageFacade
{
if (sendFuture.isSuccess())
{
final String pong = (String) sendFuture.getObject();
if (pong != null)
Platform.runLater(() -> onResponseFromPing(pong.equals(PONG)));
@NotNull final String pong = (String) sendFuture.getObject();
Platform.runLater(() -> onResponseFromPing(pong.equals(PONG)));
}
else
{
@ -608,7 +614,7 @@ public class MessageFacade
private void onResponseFromPing(boolean success)
{
for (PingPeerListener pingPeerListener : pingPeerListeners)
for (@NotNull PingPeerListener pingPeerListener : pingPeerListeners)
pingPeerListener.onPingPeerResult(success);
}
@ -618,6 +624,7 @@ public class MessageFacade
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
public PublicKey getPubKey()
{
return keyPair.getPublic();
@ -691,9 +698,9 @@ public class MessageFacade
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
private void createMyPeerInstance(String keyName, int port) throws IOException
private void createMyPeerInstance(int port) throws IOException
{
keyPair = DSAKeyUtil.getKeyPair(keyName);
keyPair = DSAKeyUtil.getKeyPair();
myPeer = new PeerMaker(keyPair).setPorts(port).makeAndListen();
final FutureBootstrap futureBootstrap = myPeer.bootstrap().setBroadcast().setPorts(MASTER_PEER_PORT).start();
// futureBootstrap.awaitUninterruptibly();
@ -728,17 +735,7 @@ public class MessageFacade
private void setupStorage()
{
//TODO BitSquare.ID just temp...
String dirPath = Utilities.getRootDir() + BitSquare.ID + "_tomP2P";
File dirFile = new File(dirPath);
boolean success = true;
if (!dirFile.exists())
success = dirFile.mkdir();
if (success)
myPeer.getPeerBean().setStorage(new StorageDisk(dirPath));
else
log.warn("Unable to create directory " + dirPath);
myPeer.getPeerBean().setStorage(new StorageDisk(FileUtil.getDirectory(BitSquare.ID + "_tomP2P").getAbsolutePath()));
}
private void saveMyAddressToDHT() throws IOException
@ -760,8 +757,20 @@ public class MessageFacade
{
Platform.runLater(() -> onMessage(request, sender));
}
//noinspection ReturnOfNull
return null;
});
//noinspection Convert2Lambda
myPeer.setObjectDataReply(new ObjectDataReply()
{
@Nullable
@Override
public Object reply(PeerAddress peerAddress, Object o) throws Exception
{
return null;
}
});
}
private void onMessage(Object request, PeerAddress sender)

View File

@ -6,6 +6,7 @@ import java.math.BigInteger;
import java.util.UUID;
//TODO refactor
@SuppressWarnings("SameParameterValue")
public class TradeMessage implements Serializable
{
private static final long serialVersionUID = 7916445031849763995L;

View File

@ -4,6 +4,7 @@ import java.util.Map;
import net.tomp2p.peers.Number160;
import net.tomp2p.storage.Data;
@SuppressWarnings({"EmptyMethod", "UnusedParameters"})
public interface ArbitratorListener
{
void onArbitratorAdded(Data offerData, boolean success);

View File

@ -6,6 +6,7 @@ import net.tomp2p.storage.Data;
public interface OrderBookListener
{
@SuppressWarnings("UnusedParameters")
void onOfferAdded(Data offerData, boolean success);
void onOffersReceived(Map<Number160, Data> dataMap, boolean success);

View File

@ -8,13 +8,18 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Settings implements Serializable
{
private static final long serialVersionUID = 7995048077355006861L;
@NotNull
private List<Locale> acceptedLanguageLocales = new ArrayList<>();
@NotNull
private List<Country> acceptedCountryLocales = new ArrayList<>();
@NotNull
private List<Arbitrator> acceptedArbitrators = new ArrayList<>();
private int maxCollateral;
private int minCollateral;
@ -33,7 +38,7 @@ public class Settings implements Serializable
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void updateFromStorage(Settings savedSettings)
public void updateFromStorage(@Nullable Settings savedSettings)
{
if (savedSettings != null)
{
@ -45,35 +50,35 @@ public class Settings implements Serializable
}
}
public void addAcceptedLanguageLocale(Locale locale)
public void addAcceptedLanguageLocale(@NotNull Locale locale)
{
if (!acceptedLanguageLocales.contains(locale))
acceptedLanguageLocales.add(locale);
}
public void removeAcceptedLanguageLocale(Locale item)
public void removeAcceptedLanguageLocale(@NotNull Locale item)
{
acceptedLanguageLocales.remove(item);
}
public void addAcceptedCountry(Country locale)
public void addAcceptedCountry(@NotNull Country locale)
{
if (!acceptedCountryLocales.contains(locale))
acceptedCountryLocales.add(locale);
}
public void removeAcceptedCountry(Country item)
public void removeAcceptedCountry(@NotNull Country item)
{
acceptedCountryLocales.remove(item);
}
public void addAcceptedArbitrator(Arbitrator arbitrator)
public void addAcceptedArbitrator(@NotNull Arbitrator arbitrator)
{
if (!acceptedArbitrators.contains(arbitrator))
acceptedArbitrators.add(arbitrator);
}
public void removeAcceptedArbitrator(Arbitrator item)
public void removeAcceptedArbitrator(@NotNull Arbitrator item)
{
acceptedArbitrators.remove(item);
}
@ -83,25 +88,31 @@ public class Settings implements Serializable
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public List<Arbitrator> getAcceptedArbitrators()
{
return acceptedArbitrators;
}
@NotNull
public List<Locale> getAcceptedLanguageLocales()
{
return acceptedLanguageLocales;
}
@NotNull
public List<Country> getAcceptedCountries()
{
return acceptedCountryLocales;
}
//TODO
public Arbitrator getRandomArbitrator(int collateral, BigInteger amount)
@SuppressWarnings("UnusedParameters")
@Nullable
public Arbitrator getRandomArbitrator(@SuppressWarnings("UnusedParameters") @NotNull Integer collateral, @SuppressWarnings("UnusedParameters") @NotNull BigInteger amount)
{
List<Arbitrator> candidates = new ArrayList<>();
@NotNull List<Arbitrator> candidates = new ArrayList<>();
//noinspection Convert2streamapi
for (Arbitrator arbitrator : acceptedArbitrators)
{
/*if (arbitrator.getArbitrationFeePercent() >= collateral &&
@ -110,10 +121,10 @@ public class Settings implements Serializable
candidates.add(arbitrator);
// }
}
return candidates.size() > 0 ? candidates.get((int) (Math.random() * candidates.size())) : null;
return !candidates.isEmpty() ? candidates.get((int) (Math.random() * candidates.size())) : null;
}
public int getMaxCollateral()
int getMaxCollateral()
{
return maxCollateral;
}

View File

@ -1,10 +1,18 @@
package io.bitsquare.storage;
import com.google.bitcoin.core.Utils;
import com.google.bitcoin.utils.Threading;
import com.google.inject.Inject;
import io.bitsquare.BitSquare;
import io.bitsquare.util.Utilities;
import io.bitsquare.util.FileUtil;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.concurrent.GuardedBy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -14,45 +22,157 @@ import org.slf4j.LoggerFactory;
public class Storage
{
private static final Logger log = LoggerFactory.getLogger(Storage.class);
private static final ReentrantLock lock = Threading.lock("Storage");
//TODO save in users preferences location
private final String preferencesFileName = BitSquare.ID + "_pref" + ".ser";
private final String storageFile;
private Map<String, Object> dict;
private final String prefix = BitSquare.ID + "_pref";
private final File storageFile = FileUtil.getFile(prefix, "ser");
@NotNull
@GuardedBy("lock")
private Map<String, Serializable> rootMap = new HashMap<>();
private boolean dirty;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public Storage()
{
storageFile = Utilities.getRootDir() + preferencesFileName;
dict = readDataVO();
if (dict == null)
{
dict = new HashMap<>();
writeDataVO(dict);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void write(String key, Object value)
public void init()
{
//log.info("Write object with key = " + key + " / value = " + value);
dict.put(key, value);
writeDataVO(dict);
try
{
lock.lock();
final Map<String, Serializable> map = readRootMap();
if (map == null)
{
lock.lock();
try
{
saveObjectToFile((Serializable) rootMap);
} finally
{
lock.unlock();
}
}
else
{
rootMap = map;
}
} finally
{
lock.unlock();
}
}
public Object read(String key)
// Map
public void write(@NotNull String key, @NotNull Map<String, ? extends Serializable> value)
{
dict = readDataVO();
return dict.get(key);
write(key, (Serializable) value);
}
public void write(@NotNull Object classInstance, @NotNull String propertyKey, @NotNull Map<String, ? extends Serializable> value)
{
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(@NotNull Object classInstance, @NotNull Map<String, ? extends Serializable> value)
{
write(classInstance.getClass().getName(), value);
}
// List
public void write(@NotNull String key, @NotNull List<? extends Serializable> value)
{
write(key, (Serializable) value);
}
public void write(@NotNull Object classInstance, @NotNull String propertyKey, @NotNull List<? extends Serializable> value)
{
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(@NotNull Object classInstance, @NotNull List<? extends Serializable> value)
{
write(classInstance.getClass().getName(), value);
}
// Serializable
public void write(@NotNull Object classInstance, @NotNull String propertyKey, @NotNull Serializable value)
{
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(@NotNull Object classInstance, @NotNull Serializable value)
{
write(classInstance.getClass().getName(), value);
}
public void write(@NotNull String key, @NotNull Serializable value)
{
// log.trace("Write object with key = " + key + " / value = " + value);
try
{
lock.lock();
dirty = true;
rootMap.put(key, value);
saveObjectToFile((Serializable) rootMap);
} finally
{
lock.unlock();
}
}
@Nullable
public Serializable read(@NotNull Object classInstance)
{
return read(classInstance.getClass().getName());
}
@Nullable
public Serializable read(@NotNull Object classInstance, @NotNull String propertyKey)
{
return read(classInstance.getClass().getName() + "." + propertyKey);
}
@Nullable
public Serializable read(@NotNull String key)
{
try
{
lock.lock();
if (dirty)
{
final Map<String, Serializable> map = readRootMap();
if (map != null)
{
rootMap = map;
dirty = false;
}
}
if (rootMap.containsKey(key))
{
// log.trace("Read object with key = " + key + " / value = " + rootMap.get(key));
return rootMap.get(key);
}
else
{
log.warn("Object with key = " + key + " not found.");
return null;
}
} finally
{
lock.unlock();
}
}
@ -60,41 +180,103 @@ public class Storage
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void writeDataVO(Map<String, Object> dict)
@Nullable
private Map<String, Serializable> readRootMap()
{
try
{
FileOutputStream fileOut = new FileOutputStream(storageFile);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(dict);
out.close();
fileOut.close();
} catch (IOException i)
final Object object = readObjectFromFile(storageFile);
if (object == null)
{
log.error("readRootMap returned null object.");
return null;
}
else
{
if (object instanceof Map)
{
//noinspection unchecked
return (Map<String, Serializable>) object;
}
else
{
log.error("Object is not type of Map<String, Serializable>");
return null;
}
}
} catch (@NotNull FileNotFoundException e)
{
i.printStackTrace();
log.trace("File not found is ok for the first run.");
return null;
} catch (@NotNull ClassNotFoundException | IOException e2)
{
e2.printStackTrace();
log.error("Could not read rootMap. " + e2);
return null;
}
}
private Map<String, Object> readDataVO()
private void saveObjectToFile(@NotNull Serializable serializable)
{
Map<String, Object> dict = null;
File file = new File(storageFile);
if (file.exists())
try
{
try
final File tempFile = FileUtil.getTempFile("temp_" + prefix);
try (final FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream))
{
FileInputStream fileIn = new FileInputStream(file);
ObjectInputStream in = new ObjectInputStream(fileIn);
Object object = in.readObject();
if (object instanceof Map)
dict = (Map<String, Object>) object;
in.close();
fileIn.close();
} catch (IOException | ClassNotFoundException i)
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
// to not write through to physical media for at least a few seconds, but this is the best we can do.
fileOutputStream.flush();
fileOutputStream.getFD().sync();
if (Utils.isWindows())
{
// Work around an issue on Windows whereby you can't rename over existing files.
final File canonical = storageFile.getCanonicalFile();
if (canonical.exists() && !canonical.delete())
throw new IOException("Failed to delete canonical file for replacement with save");
if (!tempFile.renameTo(canonical))
throw new IOException("Failed to rename " + tempFile + " to " + canonical);
}
else if (!tempFile.renameTo(storageFile))
{
throw new IOException("Failed to rename " + tempFile + " to " + storageFile);
}
} catch (IOException e)
{
i.printStackTrace();
e.printStackTrace();
log.error("saveObjectToFile failed." + e);
if (tempFile.exists())
{
log.warn("Temp file still exists after failed save.");
if (!tempFile.delete())
log.warn("Cannot delete temp file.");
}
}
} catch (IOException e)
{
e.printStackTrace();
log.error("getTempFile failed." + e);
}
}
@Nullable
private Object readObjectFromFile(@NotNull File file) throws IOException, ClassNotFoundException
{
lock.lock();
try (final FileInputStream fileInputStream = new FileInputStream(file);
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream))
{
return objectInputStream.readObject();
} finally
{
lock.unlock();
}
return dict;
}
}

View File

@ -3,6 +3,7 @@ package io.bitsquare.trade;
import io.bitsquare.bank.BankAccount;
import java.io.Serializable;
import java.math.BigInteger;
import org.jetbrains.annotations.NotNull;
public class Contract implements Serializable
{
@ -89,6 +90,7 @@ public class Contract implements Serializable
return offererMessagePubKeyAsHex;
}
@NotNull
@Override
public String toString()
{

View File

@ -1,12 +1,13 @@
package io.bitsquare.trade;
import io.bitsquare.bank.BankAccountTypeInfo;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.locale.Country;
import io.bitsquare.user.Arbitrator;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
import org.jetbrains.annotations.NotNull;
public class Offer implements Serializable
{
@ -17,13 +18,14 @@ public class Offer implements Serializable
private final Currency currency;
private final String id;
@NotNull
private final Date creationDate;
private final double price;
private final BigInteger amount;
private final BigInteger minAmount;
private final String messagePubKeyAsHex;
private final BankAccountTypeInfo.BankAccountType bankAccountType;
private final BankAccountType bankAccountType;
private final Country bankAccountCountry;
private final int collateral;
@ -43,7 +45,7 @@ public class Offer implements Serializable
double price,
BigInteger amount,
BigInteger minAmount,
BankAccountTypeInfo.BankAccountType bankAccountType,
BankAccountType bankAccountType,
Currency currency,
Country bankAccountCountry,
String bankAccountUID,
@ -111,7 +113,7 @@ public class Offer implements Serializable
return direction;
}
public BankAccountTypeInfo.BankAccountType getBankAccountType()
public BankAccountType getBankAccountType()
{
return bankAccountType;
}
@ -171,6 +173,7 @@ public class Offer implements Serializable
return bankAccountUID;
}
@NotNull
@Override
public String toString()
{
@ -193,6 +196,7 @@ public class Offer implements Serializable
'}';
}
@NotNull
public Date getCreationDate()
{
return creationDate;

View File

@ -5,7 +5,9 @@ import java.io.Serializable;
import java.math.BigInteger;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("SameParameterValue")
public class Trade implements Serializable
{
private static final long serialVersionUID = -8275323072940974077L;
@ -21,6 +23,7 @@ public class Trade implements Serializable
private String takerSignature;
private Transaction depositTransaction;
private Transaction payoutTransaction;
@NotNull
private State state = State.NONE;
public Trade(Offer offer)
@ -120,32 +123,37 @@ public class Trade implements Serializable
payoutTxChangedProperty.set(!payoutTxChangedProperty.get());
}
@NotNull
public State getState()
{
return state;
}
public void setState(State state)
public void setState(@NotNull State state)
{
this.state = state;
stateChangedProperty.set(state.toString());
}
@NotNull
public SimpleBooleanProperty getDepositTxChangedProperty()
{
return depositTxChangedProperty;
}
@NotNull
public SimpleBooleanProperty getContractChangedProperty()
{
return contractChangedProperty;
}
@NotNull
public SimpleBooleanProperty getPayoutTxChangedProperty()
{
return payoutTxChangedProperty;
}
@NotNull
public SimpleStringProperty getStateChangedProperty()
{
return stateChangedProperty;
@ -156,6 +164,7 @@ public class Trade implements Serializable
return getTradeAmount().multiply(BigInteger.valueOf(getOffer().getCollateral())).divide(BigInteger.valueOf(100));
}
@NotNull
@Override
public String toString()
{

View File

@ -9,7 +9,6 @@ import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.msg.TradeMessage;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.payment.offerer.OffererPaymentProtocol;
import io.bitsquare.trade.payment.offerer.OffererPaymentProtocolListener;
@ -22,12 +21,14 @@ import java.util.Map;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import net.tomp2p.peers.PeerAddress;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represents trade domain. Keeps complexity of process apart from view controller
*/
@SuppressWarnings("EmptyMethod")
public class Trading
{
private static final Logger log = LoggerFactory.getLogger(Trading.class);
@ -35,14 +36,16 @@ public class Trading
private final Map<String, OffererPaymentProtocol> offererPaymentProtocols = new HashMap<>();
private final String storageKey;
private final User user;
@NotNull
private final Storage storage;
private final MessageFacade messageFacade;
private final BlockChainFacade blockChainFacade;
private final WalletFacade walletFacade;
private final CryptoFacade cryptoFacade;
private final Settings settings;
private final StringProperty newTradeProperty = new SimpleStringProperty();
@NotNull
private Map<String, Offer> myOffers = new HashMap<>();
@NotNull
private Map<String, Trade> trades = new HashMap<>();
@ -50,17 +53,16 @@ public class Trading
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("unchecked")
@Inject
public Trading(User user,
Settings settings,
Storage storage,
@NotNull Storage storage,
MessageFacade messageFacade,
BlockChainFacade blockChainFacade,
WalletFacade walletFacade,
CryptoFacade cryptoFacade)
{
this.user = user;
this.settings = settings;
this.storage = storage;
this.messageFacade = messageFacade;
this.blockChainFacade = blockChainFacade;
@ -70,12 +72,13 @@ public class Trading
storageKey = this.getClass().getName();
Object offersObject = storage.read(storageKey + ".offers");
if (offersObject != null && offersObject instanceof HashMap)
if (offersObject instanceof HashMap)
myOffers = (Map<String, Offer>) offersObject;
Object tradesObject = storage.read(storageKey + ".trades");
if (tradesObject != null && tradesObject instanceof HashMap)
if (tradesObject instanceof HashMap)
trades = (Map<String, Trade>) tradesObject;
}
@ -92,7 +95,7 @@ public class Trading
storage.write(storageKey + ".offers", myOffers);
}
public void addOffer(Offer offer) throws IOException
public void addOffer(@NotNull Offer offer) throws IOException
{
if (myOffers.containsKey(offer.getId()))
throw new IllegalStateException("offers contains already a offer with the ID " + offer.getId());
@ -103,7 +106,7 @@ public class Trading
messageFacade.addOffer(offer);
}
public void removeOffer(Offer offer)
public void removeOffer(@NotNull Offer offer) throws IOException
{
myOffers.remove(offer.getId());
saveOffers();
@ -111,12 +114,13 @@ public class Trading
messageFacade.removeOffer(offer);
}
public Trade createTrade(Offer offer)
@NotNull
public Trade createTrade(@NotNull Offer offer)
{
if (trades.containsKey(offer.getId()))
throw new IllegalStateException("trades contains already a trade with the ID " + offer.getId());
Trade trade = new Trade(offer);
@NotNull Trade trade = new Trade(offer);
trades.put(offer.getId(), trade);
//TODO for testing
//storage.write(storageKey + ".trades", trades);
@ -126,36 +130,39 @@ public class Trading
return trade;
}
public void removeTrade(Trade trade)
public void removeTrade(@NotNull Trade trade)
{
trades.remove(trade.getId());
storage.write(storageKey + ".trades", trades);
}
@NotNull
public final StringProperty getNewTradeProperty()
{
return this.newTradeProperty;
}
public TakerPaymentProtocol addTakerPaymentProtocol(Trade trade, TakerPaymentProtocolListener listener)
@NotNull
public TakerPaymentProtocol addTakerPaymentProtocol(@NotNull Trade trade, TakerPaymentProtocolListener listener)
{
TakerPaymentProtocol takerPaymentProtocol = new TakerPaymentProtocol(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
@NotNull TakerPaymentProtocol takerPaymentProtocol = new TakerPaymentProtocol(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
takerPaymentProtocols.put(trade.getId(), takerPaymentProtocol);
return takerPaymentProtocol;
}
public OffererPaymentProtocol addOffererPaymentProtocol(Trade trade, OffererPaymentProtocolListener listener)
@NotNull
OffererPaymentProtocol addOffererPaymentProtocol(@NotNull Trade trade, OffererPaymentProtocolListener listener)
{
OffererPaymentProtocol offererPaymentProtocol = new OffererPaymentProtocol(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
@NotNull OffererPaymentProtocol offererPaymentProtocol = new OffererPaymentProtocol(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
offererPaymentProtocols.put(trade.getId(), offererPaymentProtocol);
return offererPaymentProtocol;
}
public void createOffererPaymentProtocol(TradeMessage tradeMessage, PeerAddress sender)
public void createOffererPaymentProtocol(@NotNull TradeMessage tradeMessage, PeerAddress sender)
{
Offer offer = myOffers.get(tradeMessage.getOfferUID());
Trade trade = createTrade(offer);
OffererPaymentProtocol offererPaymentProtocol = addOffererPaymentProtocol(trade, new OffererPaymentProtocolListener()
@NotNull Trade trade = createTrade(offer);
@NotNull OffererPaymentProtocol offererPaymentProtocol = addOffererPaymentProtocol(trade, new OffererPaymentProtocolListener()
{
@Override
public void onProgress(double progress)
@ -184,7 +191,7 @@ public class Trading
@Override
public void onPayoutTxPublished(String payoutTxAsHex)
{
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(), Utils.parseAsHexOrBase58(payoutTxAsHex));
@NotNull Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(), Utils.parseAsHexOrBase58(payoutTxAsHex));
trade.setPayoutTransaction(payoutTx);
trade.setState(Trade.State.COMPLETED);
log.debug("trading onPayoutTxPublished");
@ -216,7 +223,7 @@ public class Trading
// 6
public void releaseBTC(String tradeUID, TradeMessage tradeMessage)
public void releaseBTC(String tradeUID, @NotNull TradeMessage tradeMessage)
{
takerPaymentProtocols.get(tradeUID).releaseBTC(tradeMessage);
}
@ -225,11 +232,13 @@ public class Trading
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public Map<String, Trade> getTrades()
{
return trades;
}
@NotNull
public Map<String, Offer> getOffers()
{
return myOffers;

View File

@ -23,13 +23,15 @@ import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import net.tomp2p.peers.Number160;
import net.tomp2p.storage.Data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderBook implements OrderBookListener
{
private static final Logger log = LoggerFactory.getLogger(OrderBook.class);
protected final ObservableList<OrderBookListItem> allOffers = FXCollections.observableArrayList();
private final ObservableList<OrderBookListItem> allOffers = FXCollections.observableArrayList();
private final FilteredList<OrderBookListItem> filteredList = new FilteredList<>(allOffers);
// FilteredList does not support sorting, so we need to wrap it to a SortedList
private final SortedList<OrderBookListItem> offerList = new SortedList<>(filteredList);
@ -75,20 +77,25 @@ public class OrderBook implements OrderBookListener
messageFacade.getOffers(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
}
public void removeOffer(Offer offer)
public void removeOffer(@NotNull Offer offer)
{
trading.removeOffer(offer);
try
{
trading.removeOffer(offer);
} catch (IOException e)
{
e.printStackTrace();
}
messageFacade.removeOffer(offer);
}
public void applyFilter(OrderBookFilter orderBookFilter)
public void applyFilter(@Nullable OrderBookFilter orderBookFilter)
{
filteredList.setPredicate(orderBookListItem -> {
Offer offer = orderBookListItem.getOffer();
BankAccount currentBankAccount = user.getCurrentBankAccount();
@NotNull Offer offer = orderBookListItem.getOffer();
@Nullable BankAccount currentBankAccount = user.getCurrentBankAccount();
if (orderBookFilter == null
|| offer == null
|| currentBankAccount == null
|| orderBookFilter.getDirection() == null)
return false;
@ -125,6 +132,7 @@ public class OrderBook implements OrderBookListener
boolean arbitratorResult = arbitratorInList(offer.getArbitrator(), settings.getAcceptedArbitrators());
//noinspection UnnecessaryLocalVariable
boolean result = currencyResult
&& countryResult
&& languageResult
@ -170,41 +178,41 @@ public class OrderBook implements OrderBookListener
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onOfferAdded(Data offerData, boolean success)
public void onOfferAdded(@NotNull Data offerData, boolean success)
{
try
{
Object offerDataObject = offerData.getObject();
if (offerDataObject instanceof Offer)
{
Offer offer = (Offer) offerDataObject;
@NotNull Offer offer = (Offer) offerDataObject;
allOffers.add(new OrderBookListItem(offer));
}
} catch (ClassNotFoundException | IOException e)
} catch (@NotNull ClassNotFoundException | IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
@Override
public void onOffersReceived(Map<Number160, Data> dataMap, boolean success)
public void onOffersReceived(@Nullable Map<Number160, Data> dataMap, boolean success)
{
if (success && dataMap != null)
{
allOffers.clear();
for (Data offerData : dataMap.values())
for (@NotNull Data offerData : dataMap.values())
{
try
{
Object offerDataObject = offerData.getObject();
if (offerDataObject instanceof Offer)
{
Offer offer = (Offer) offerDataObject;
OrderBookListItem orderBookListItem = new OrderBookListItem(offer);
@NotNull Offer offer = (Offer) offerDataObject;
@NotNull OrderBookListItem orderBookListItem = new OrderBookListItem(offer);
allOffers.add(orderBookListItem);
}
} catch (ClassNotFoundException | IOException e)
} catch (@NotNull ClassNotFoundException | IOException e)
{
e.printStackTrace();
}
@ -217,7 +225,7 @@ public class OrderBook implements OrderBookListener
}
@Override
public void onOfferRemoved(Data offerData, boolean success)
public void onOfferRemoved(@NotNull Data offerData, boolean success)
{
if (success)
{
@ -226,10 +234,10 @@ public class OrderBook implements OrderBookListener
Object offerDataObject = offerData.getObject();
if (offerDataObject instanceof Offer)
{
Offer offer = (Offer) offerDataObject;
@NotNull Offer offer = (Offer) offerDataObject;
allOffers.removeIf(orderBookListItem -> orderBookListItem.getOffer().getId().equals(offer.getId()));
}
} catch (ClassNotFoundException | IOException e)
} catch (@NotNull ClassNotFoundException | IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
@ -245,6 +253,7 @@ public class OrderBook implements OrderBookListener
// Getter
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public SortedList<OrderBookListItem> getOfferList()
{
return offerList;
@ -255,9 +264,9 @@ public class OrderBook implements OrderBookListener
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
private boolean countryInList(Country countryToMatch, List<Country> list)
private boolean countryInList(@NotNull Country countryToMatch, @NotNull List<Country> list)
{
for (Country country : list)
for (@NotNull Country country : list)
{
if (country.getCode().equals(countryToMatch.getCode()))
return true;
@ -265,11 +274,11 @@ public class OrderBook implements OrderBookListener
return false;
}
private boolean languagesInList(List<Locale> list1, List<Locale> list2)
private boolean languagesInList(@NotNull List<Locale> list1, @NotNull List<Locale> list2)
{
for (Locale locale1 : list2)
for (@NotNull Locale locale1 : list2)
{
for (Locale locale2 : list1)
for (@NotNull Locale locale2 : list1)
{
if (locale1.getLanguage().equals(locale2.getLanguage()))
return true;
@ -278,15 +287,15 @@ public class OrderBook implements OrderBookListener
return false;
}
private boolean arbitratorInList(Arbitrator arbitratorToMatch, List<Arbitrator> list)
private boolean arbitratorInList(@Nullable Arbitrator arbitratorToMatch, @NotNull List<Arbitrator> list)
{
if (arbitratorToMatch != null)
{
for (Arbitrator arbitrator : list)
for (@NotNull Arbitrator arbitrator : list)
{
try
{
if (arbitrator.getUID().equals(arbitratorToMatch.getUID()))
if (arbitrator.getId().equals(arbitratorToMatch.getId()))
return true;
} catch (Exception e)
{

View File

@ -2,10 +2,11 @@ package io.bitsquare.trade.orderbook;
import io.bitsquare.trade.Direction;
import javafx.beans.property.SimpleBooleanProperty;
import org.jetbrains.annotations.NotNull;
public class OrderBookFilter
{
transient private final SimpleBooleanProperty directionChangedProperty = new SimpleBooleanProperty();
private final SimpleBooleanProperty directionChangedProperty = new SimpleBooleanProperty();
private double price;
private double amount;
@ -52,6 +53,7 @@ public class OrderBookFilter
this.price = price;
}
@NotNull
public SimpleBooleanProperty getDirectionChangedProperty()
{
return directionChangedProperty;

View File

@ -19,6 +19,8 @@ import io.bitsquare.util.Utilities;
import java.math.BigInteger;
import javafx.util.Pair;
import net.tomp2p.peers.PeerAddress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -30,16 +32,20 @@ public class OffererPaymentProtocol
private static final Logger log = LoggerFactory.getLogger(OffererPaymentProtocol.class);
@NotNull
private final Trade trade;
private final Offer offer;
private final OffererPaymentProtocolListener offererPaymentProtocolListener;
@NotNull
private final MessageFacade messageFacade;
@NotNull
private final WalletFacade walletFacade;
@NotNull
private final BlockChainFacade blockChainFacade;
@NotNull
private final CryptoFacade cryptoFacade;
@NotNull
private final User user;
private final int numberOfSteps = 10;//TODO
private Contract contract;
private PeerAddress peerAddress;
private boolean isTakeOfferRequested;
private int currentStep = 0;
@ -51,13 +57,13 @@ public class OffererPaymentProtocol
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public OffererPaymentProtocol(Trade trade,
public OffererPaymentProtocol(@NotNull Trade trade,
OffererPaymentProtocolListener offererPaymentProtocolListener,
MessageFacade messageFacade,
WalletFacade walletFacade,
BlockChainFacade blockChainFacade,
CryptoFacade cryptoFacade,
User user)
@NotNull MessageFacade messageFacade,
@NotNull WalletFacade walletFacade,
@NotNull BlockChainFacade blockChainFacade,
@NotNull CryptoFacade cryptoFacade,
@NotNull User user)
{
checkNotNull(trade);
checkNotNull(messageFacade);
@ -101,10 +107,34 @@ public class OffererPaymentProtocol
peerAddress = sender;
// The offer must be still available.
// TODO check also if offer is still in our offer list, if we canceled recently there might be inconsistency
if (!isTakeOfferRequested)
if (isTakeOfferRequested)
{
log.debug("1.3 offer already requested REJECT_TAKE_OFFER_REQUEST");
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REJECT_TAKE_OFFER_REQUEST, trade.getId());
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
{
log.debug("1.3 isTakeOfferRequested REJECT_TAKE_OFFER_REQUEST onResult");
// no more steps are needed, as we are not interested in that trade
}
@Override
public void onFailed()
{
log.warn("1.3 isTakeOfferRequested REJECT_TAKE_OFFER_REQUEST onFailed");
// we can ignore that as we are not interested in that trade
}
};
// Offerer reject take offer because it's not available anymore
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
}
else
{
log.debug("1.3 offer not yet requested");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -132,31 +162,7 @@ public class OffererPaymentProtocol
offererPaymentProtocolListener.onProgress(getProgress());
// 1.3a Send accept take offer message
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.ACCEPT_TAKE_OFFER_REQUEST, trade.getId());
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
}
else
{
log.debug("1.3 offer already requested REJECT_TAKE_OFFER_REQUEST");
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REJECT_TAKE_OFFER_REQUEST, trade.getId());
TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
{
log.debug("1.3 isTakeOfferRequested REJECT_TAKE_OFFER_REQUEST onResult");
// no more steps are needed, as we are not interested in that trade
}
@Override
public void onFailed()
{
log.warn("1.3 isTakeOfferRequested REJECT_TAKE_OFFER_REQUEST onFailed");
// we can ignore that as we are not interested in that trade
}
};
// Offerer reject take offer because it's not available anymore
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.ACCEPT_TAKE_OFFER_REQUEST, trade.getId());
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
}
}
@ -171,7 +177,7 @@ public class OffererPaymentProtocol
// Step 2.3
///////////////////////////////////////////////////////////////////////////////////////////
public void onTakeOfferFeePayed(TradeMessage requestTradeMessage)
public void onTakeOfferFeePayed(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.3 onTakeOfferFeePayed");
trade.setTakeOfferFeeTxID(requestTradeMessage.getTakeOfferFeeTxID());
@ -184,7 +190,7 @@ public class OffererPaymentProtocol
// Step 2.4
///////////////////////////////////////////////////////////////////////////////////////////
private void verifyTakeOfferFeePayment(TradeMessage requestTradeMessage)
private void verifyTakeOfferFeePayment(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.4 verifyTakeOfferFeePayment");
//TODO just dummy now, will be async
@ -200,7 +206,8 @@ public class OffererPaymentProtocol
// Step 2.5
///////////////////////////////////////////////////////////////////////////////////////////
private void createDepositTx(TradeMessage requestTradeMessage)
@SuppressWarnings("ConstantConditions")
private void createDepositTx(@NotNull TradeMessage requestTradeMessage)
{
checkNotNull(requestTradeMessage);
@ -223,7 +230,7 @@ public class OffererPaymentProtocol
log.debug("arbitrator pubkey " + arbitratorPubKey);
try
{
Transaction tx = walletFacade.offererCreatesMSTxAndAddPayment(offererInputAmount, offererPubKey, takerPubKey, arbitratorPubKey, trade.getId());
@NotNull Transaction tx = walletFacade.offererCreatesMSTxAndAddPayment(offererInputAmount, offererPubKey, takerPubKey, arbitratorPubKey, trade.getId());
preparedOffererDepositTxAsHex = Utils.bytesToHexString(tx.bitcoinSerialize());
long offererTxOutIndex = tx.getInput(0).getOutpoint().getIndex();
log.debug("2.5 deposit tx created: " + tx);
@ -243,12 +250,12 @@ public class OffererPaymentProtocol
// Step 2.6
///////////////////////////////////////////////////////////////////////////////////////////
private void sendDepositTxAndDataForContract(String preparedOffererDepositTxAsHex, String offererPubKey, long offererTxOutIndex)
private void sendDepositTxAndDataForContract(@NotNull String preparedOffererDepositTxAsHex, String offererPubKey, long offererTxOutIndex)
{
log.debug("2.6 sendDepositTxAndDataForContract");
// Send all the requested data
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -270,15 +277,10 @@ public class OffererPaymentProtocol
offererPaymentProtocolListener.onProgress(getProgress());
BankAccount bankAccount = user.getBankAccount(offer.getBankAccountUID());
@Nullable BankAccount bankAccount = user.getBankAccount(offer.getBankAccountUID());
String accountID = user.getAccountID();
checkNotNull(trade.getId());
checkNotNull(bankAccount);
checkNotNull(accountID);
checkNotNull(preparedOffererDepositTxAsHex);
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_TAKER_DEPOSIT_PAYMENT, trade.getId(), bankAccount, accountID, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_TAKER_DEPOSIT_PAYMENT, trade.getId(), bankAccount, accountID, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
log.debug("2.6 sendTradingMessage");
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
}
@ -292,7 +294,7 @@ public class OffererPaymentProtocol
// Step 3.1 Incoming msg from taker
///////////////////////////////////////////////////////////////////////////////////////////
public void onDepositTxReadyForPublication(TradeMessage requestTradeMessage)
public void onDepositTxReadyForPublication(@NotNull TradeMessage requestTradeMessage)
{
log.debug("3.1 onDepositTxReadyForPublication");
takerPayoutAddress = requestTradeMessage.getTakerPayoutAddress();
@ -304,20 +306,20 @@ public class OffererPaymentProtocol
// Step 3.2 Verify offerers account registration and against the blacklist
///////////////////////////////////////////////////////////////////////////////////////////
private void verifyTaker(TradeMessage requestTradeMessage)
private void verifyTaker(@NotNull TradeMessage requestTradeMessage)
{
log.debug("3.2 verifyTaker");
log.debug("3.2.1 verifyAccountRegistration");
if (blockChainFacade.verifyAccountRegistration())
{
log.debug("3.2.2 isAccountBlackListed");
if (!blockChainFacade.isAccountBlackListed(requestTradeMessage.getAccountID(), requestTradeMessage.getBankAccount()))
if (blockChainFacade.isAccountBlackListed(requestTradeMessage.getAccountID(), requestTradeMessage.getBankAccount()))
{
verifyAndSignContract(requestTradeMessage);
offererPaymentProtocolListener.onFailure("Taker is blacklisted.");
}
else
{
offererPaymentProtocolListener.onFailure("Taker is blacklisted.");
verifyAndSignContract(requestTradeMessage);
}
}
else
@ -330,9 +332,10 @@ public class OffererPaymentProtocol
// Step 3.3 Verify and sign the contract
///////////////////////////////////////////////////////////////////////////////////////////
private void verifyAndSignContract(TradeMessage requestTradeMessage)
@SuppressWarnings("ConstantConditions")
private void verifyAndSignContract(@NotNull TradeMessage requestTradeMessage)
{
contract = new Contract(offer,
Contract contract = new Contract(offer,
trade.getTradeAmount(),
trade.getTakeOfferFeeTxID(),
user.getAccountID(),
@ -342,7 +345,7 @@ public class OffererPaymentProtocol
offer.getMessagePubKeyAsHex(),
requestTradeMessage.getTakerMessagePubKey());
log.debug("3.3 offerer contract created: " + contract.toString());
log.debug("3.3 offerer contract created: " + contract);
String contractAsJson = Utilities.objectToJson(contract);
// log.debug("3.3 contractAsJson: " + contractAsJson);
@ -369,7 +372,7 @@ public class OffererPaymentProtocol
// Step 3.4 Sign and publish the deposit tx
///////////////////////////////////////////////////////////////////////////////////////////
private void signAndPublishDepositTx(TradeMessage requestTradeMessage)
private void signAndPublishDepositTx(@NotNull TradeMessage requestTradeMessage)
{
log.debug("3.4 signAndPublishDepositTx");
@ -377,12 +380,13 @@ public class OffererPaymentProtocol
String txConnOutAsHex = requestTradeMessage.getTxConnOutAsHex();
String txScriptSigAsHex = requestTradeMessage.getTxScriptSigAsHex();
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
@SuppressWarnings("ConstantConditions")
@Override
public void onSuccess(Transaction transaction)
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
log.info("3.4 signAndPublishDepositTx offererSignAndSendTx onSuccess:" + transaction.toString());
log.info("3.4 signAndPublishDepositTx offererSignAndSendTx onSuccess:" + transaction);
String txID = transaction.getHashAsString();
trade.setDepositTransaction(transaction);
@ -392,7 +396,7 @@ public class OffererPaymentProtocol
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
log.error("3.4 signAndPublishDepositTx offererSignAndSendTx onFailure:" + t.getMessage());
}
@ -414,11 +418,11 @@ public class OffererPaymentProtocol
// Step 3.5 Send tx id of published deposit tx to taker
///////////////////////////////////////////////////////////////////////////////////////////
private void sendDepositTxIdToTaker(Transaction transaction)
private void sendDepositTxIdToTaker(@NotNull Transaction transaction)
{
log.debug("3.5 sendDepositTxIdToTaker");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -434,7 +438,7 @@ public class OffererPaymentProtocol
offererPaymentProtocolListener.onFailure("sendDepositTxAndDataForContract onSendTradingMessageFailed");
}
};
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.DEPOSIT_TX_PUBLISHED, trade.getId(), Utils.bytesToHexString(transaction.bitcoinSerialize()));
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.DEPOSIT_TX_PUBLISHED, trade.getId(), Utils.bytesToHexString(transaction.bitcoinSerialize()));
log.debug("3.5 sendTradingMessage");
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
@ -452,7 +456,7 @@ public class OffererPaymentProtocol
// Step 3.7 We setup a listener for block chain confirmation
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListenerForBlockChainConfirmation(Transaction transaction)
private void setupListenerForBlockChainConfirmation(@NotNull Transaction transaction)
{
log.debug("3.7 setupListenerForBlockChainConfirmation");
@ -463,7 +467,7 @@ public class OffererPaymentProtocol
transaction.getConfidence().addEventListener(new TransactionConfidence.Listener()
{
@Override
public void onConfidenceChanged(Transaction tx, ChangeReason reason)
public void onConfidenceChanged(@NotNull Transaction tx, ChangeReason reason)
{
if (reason == ChangeReason.SEEN_PEERS)
{
@ -491,9 +495,9 @@ public class OffererPaymentProtocol
// Step 3.8 We check if the block chain confirmation is >= 1
///////////////////////////////////////////////////////////////////////////////////////////
private void updateConfirmation(TransactionConfidence confidence)
private void updateConfirmation(@NotNull TransactionConfidence confidence)
{
log.debug("3.8 updateConfirmation " + confidence.toString());
log.debug("3.8 updateConfirmation " + confidence);
offererPaymentProtocolListener.onDepositTxConfirmedUpdate(confidence);
}
@ -516,11 +520,12 @@ public class OffererPaymentProtocol
// Step 3.10 User clicked the "bank transfer inited" button, so we tell the peer that we started the bank tx
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("ConstantConditions")
public void bankTransferInited()
{
log.debug("3.10 bankTransferInited");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -542,21 +547,22 @@ public class OffererPaymentProtocol
{
BigInteger collateral = trade.getCollateralAmount();
BigInteger offererPaybackAmount = trade.getTradeAmount().add(collateral);
//noinspection UnnecessaryLocalVariable
BigInteger takerPaybackAmount = collateral;
log.debug("offererPaybackAmount " + offererPaybackAmount.toString());
log.debug("takerPaybackAmount " + takerPaybackAmount.toString());
log.debug("offererPaybackAmount " + offererPaybackAmount);
log.debug("takerPaybackAmount " + takerPaybackAmount);
log.debug("depositTransaction.getHashAsString() " + depositTransaction.getHashAsString());
log.debug("takerPayoutAddress " + takerPayoutAddress);
log.debug("walletFacade.offererCreatesAndSignsPayoutTx");
Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(), offererPaybackAmount, takerPaybackAmount, takerPayoutAddress, trade.getId());
@NotNull Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(), offererPaybackAmount, takerPaybackAmount, takerPayoutAddress, trade.getId());
ECKey.ECDSASignature offererSignature = result.getKey();
String offererSignatureR = offererSignature.r.toString();
String offererSignatureS = offererSignature.s.toString();
String depositTxAsHex = result.getValue();
String offererPayoutAddress = walletFacade.getAddressInfoByTradeID(trade.getId()).getAddressString();
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.BANK_TX_INITED, trade.getId(),
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.BANK_TX_INITED, trade.getId(),
depositTxAsHex,
offererSignatureR,
offererSignatureS,
@ -567,8 +573,8 @@ public class OffererPaymentProtocol
log.debug("depositTxAsHex " + depositTxAsHex);
log.debug("offererSignatureR " + offererSignatureR);
log.debug("offererSignatureS " + offererSignatureS);
log.debug("offererPaybackAmount " + offererPaybackAmount.toString());
log.debug("takerPaybackAmount " + takerPaybackAmount.toString());
log.debug("offererPaybackAmount " + offererPaybackAmount);
log.debug("takerPaybackAmount " + takerPaybackAmount);
log.debug("offererPayoutAddress " + offererPayoutAddress);
log.debug("3.10 sendTradingMessage BANK_TX_INITED");
@ -590,7 +596,7 @@ public class OffererPaymentProtocol
// Step 3.14 We received the payout tx. Trade is completed
///////////////////////////////////////////////////////////////////////////////////////////
public void onPayoutTxPublished(TradeMessage tradeMessage)
public void onPayoutTxPublished(@NotNull TradeMessage tradeMessage)
{
log.debug("3.14 onPayoutTxPublished");
log.debug("3.14 TRADE COMPLETE!!!!!!!!!!!");
@ -606,6 +612,7 @@ public class OffererPaymentProtocol
private double getProgress()
{
currentStep++;
int numberOfSteps = 10;
return (double) currentStep / (double) numberOfSteps;
}

View File

@ -2,8 +2,10 @@ package io.bitsquare.trade.payment.offerer;
import com.google.bitcoin.core.TransactionConfidence;
@SuppressWarnings("EmptyMethod")
public interface OffererPaymentProtocolListener
{
@SuppressWarnings("UnusedParameters")
void onProgress(double progress);
void onFailure(String failureMessage);
@ -12,6 +14,7 @@ public interface OffererPaymentProtocolListener
void onDepositTxConfirmedInBlockchain();
@SuppressWarnings("UnusedParameters")
void onDepositTxConfirmedUpdate(TransactionConfidence confidence);
void onPayoutTxPublished(String payoutTxID);

View File

@ -1,7 +1,7 @@
package io.bitsquare.trade.payment.process;
//TODO not used but let it for reference until all use cases are impl.
public class BuyOffererPaymentProcess extends PaymentProcess
class BuyOffererPaymentProcess extends PaymentProcess
{
public BuyOffererPaymentProcess()
{

View File

@ -8,6 +8,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//TODO not used but let it for reference until all use cases are impl.
@SuppressWarnings({"WeakerAccess", "EmptyMethod"})
public class PaymentProcess
{
private static final Logger log = LoggerFactory.getLogger(PaymentProcess.class);
@ -22,9 +23,6 @@ public class PaymentProcess
protected String takerTotalInputPayment;
protected String takerOutputPayment;
protected String multiSigAddress;
private MessageFacade messageService;
private BlockChainFacade bitcoinServices;
private WalletFacade wallet;
public PaymentProcess()
{
@ -33,19 +31,16 @@ public class PaymentProcess
@Inject
public void setMessageService(MessageFacade messageService)
{
this.messageService = messageService;
}
@Inject
public void setWallet(WalletFacade wallet)
{
this.wallet = wallet;
}
@Inject
public void setBtcServices(BlockChainFacade bitcoinServices)
{
this.bitcoinServices = bitcoinServices;
}

View File

@ -1,7 +1,7 @@
package io.bitsquare.trade.payment.process;
//TODO not used but let it for reference until all use cases are impl.
public class SellOffererPaymentProcess extends PaymentProcess
class SellOffererPaymentProcess extends PaymentProcess
{
public SellOffererPaymentProcess()
{

View File

@ -1,7 +1,7 @@
package io.bitsquare.trade.payment.process;
//TODO not used but let it for reference until all use cases are impl.
public class SellTakerPaymentProcess extends PaymentProcess
class SellTakerPaymentProcess extends PaymentProcess
{
public SellTakerPaymentProcess()
{

View File

@ -22,26 +22,29 @@ import io.bitsquare.user.User;
import io.bitsquare.util.Utilities;
import java.math.BigInteger;
import net.tomp2p.peers.PeerAddress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkNotNull;
//TODO use states
@SuppressWarnings("ConstantConditions")
public class TakerPaymentProtocol
{
private static final Logger log = LoggerFactory.getLogger(TakerPaymentProtocol.class);
@NotNull
private final Trade trade;
private final Offer offer;
private final TakerPaymentProtocolListener takerPaymentProtocolListener;
@NotNull
private final MessageFacade messageFacade;
private final WalletFacade walletFacade;
private final BlockChainFacade blockChainFacade;
private final CryptoFacade cryptoFacade;
private final User user;
private final int numberOfSteps = 10;//TODO
private Contract contract;
private PeerAddress peerAddress;
private int currentStep = 0;
@ -50,9 +53,9 @@ public class TakerPaymentProtocol
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public TakerPaymentProtocol(Trade trade,
public TakerPaymentProtocol(@NotNull Trade trade,
TakerPaymentProtocolListener takerPaymentProtocolListener,
MessageFacade messageFacade,
@NotNull MessageFacade messageFacade,
WalletFacade walletFacade,
BlockChainFacade blockChainFacade,
CryptoFacade cryptoFacade,
@ -87,7 +90,7 @@ public class TakerPaymentProtocol
private void findPeerAddress()
{
log.debug("1.1 findPeerAddress");
AddressLookupListener addressLookupListener = new AddressLookupListener()
@NotNull AddressLookupListener addressLookupListener = new AddressLookupListener()
{
@Override
public void onResult(PeerAddress address)
@ -124,7 +127,7 @@ public class TakerPaymentProtocol
private void requestTakeOffer()
{
log.debug("1.2 requestTakeOffer");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -150,7 +153,7 @@ public class TakerPaymentProtocol
takerPaymentProtocolListener.onProgress(getProgress());
// Send the take offer request
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_TAKE_OFFER, trade.getId());
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_TAKE_OFFER, trade.getId());
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
}
@ -186,13 +189,13 @@ public class TakerPaymentProtocol
// Step 2.1
///////////////////////////////////////////////////////////////////////////////////////////
private void payOfferFee(Trade trade)
private void payOfferFee(@NotNull Trade trade)
{
log.debug("2.1 payTakeOfferFee");
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
@Override
public void onSuccess(Transaction transaction)
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
log.debug("2.1 payTakeOfferFee onSuccess");
log.info("sendResult onSuccess txid:" + transaction.getHashAsString());
@ -207,7 +210,7 @@ public class TakerPaymentProtocol
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
log.debug("2.1 payTakeOfferFee onFailure");
takerPaymentProtocolListener.onFailure("payTakeOfferFee onFailure " + t.getMessage());
@ -237,7 +240,7 @@ public class TakerPaymentProtocol
private void sendTakerOfferFeeTxID(String takeOfferFeeTxID)
{
log.debug("2.2 sendTakerOfferFeeTxID");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -260,7 +263,7 @@ public class TakerPaymentProtocol
takerPaymentProtocolListener.onProgress(getProgress());
// 2.3. send request for the account details and send fee tx id so offerer can verify that the fee has been paid.
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.TAKE_OFFER_FEE_PAYED,
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.TAKE_OFFER_FEE_PAYED,
trade.getId(),
trade.getTradeAmount(),
takeOfferFeeTxID,
@ -278,7 +281,7 @@ public class TakerPaymentProtocol
// Step 2.7 Incoming msg from offerer
///////////////////////////////////////////////////////////////////////////////////////////
public void onTakerDepositPaymentRequested(TradeMessage requestTradeMessage)
public void onTakerDepositPaymentRequested(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.7 onTakerDepositPaymentRequested");
verifyOfferer(requestTradeMessage);
@ -289,20 +292,20 @@ public class TakerPaymentProtocol
// Step 2.8 Verify offerers account registration and against the blacklist
///////////////////////////////////////////////////////////////////////////////////////////
private void verifyOfferer(TradeMessage requestTradeMessage)
private void verifyOfferer(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.8 verifyOfferer");
log.debug("2.8.1 verifyAccountRegistration");
if (blockChainFacade.verifyAccountRegistration())
{
log.debug("2.8.2 isAccountBlackListed");
if (!blockChainFacade.isAccountBlackListed(requestTradeMessage.getAccountID(), requestTradeMessage.getBankAccount()))
if (blockChainFacade.isAccountBlackListed(requestTradeMessage.getAccountID(), requestTradeMessage.getBankAccount()))
{
createAndSignContract(requestTradeMessage);
takerPaymentProtocolListener.onFailure("Offerer is blacklisted.");
}
else
{
takerPaymentProtocolListener.onFailure("Offerer is blacklisted.");
createAndSignContract(requestTradeMessage);
}
}
else
@ -316,7 +319,7 @@ public class TakerPaymentProtocol
// Step 2.9 Create and sign the contract
///////////////////////////////////////////////////////////////////////////////////////////
private void createAndSignContract(TradeMessage requestTradeMessage)
private void createAndSignContract(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.9 createAndSignContract");
checkNotNull(offer);
@ -328,7 +331,7 @@ public class TakerPaymentProtocol
checkNotNull(user.getCurrentBankAccount());
checkNotNull(user.getMessagePubKeyAsHex());
contract = new Contract(offer,
Contract contract = new Contract(offer,
trade.getTradeAmount(),
trade.getTakeOfferFeeTxID(),
requestTradeMessage.getAccountID(),
@ -339,7 +342,7 @@ public class TakerPaymentProtocol
user.getMessagePubKeyAsHex()
);
log.debug("2.9 contract created: " + contract.toString());
log.debug("2.9 contract created: " + contract);
String contractAsJson = Utilities.objectToJson(contract);
String signature = cryptoFacade.signContract(walletFacade.getRegistrationAddressInfo().getKey(), contractAsJson);
@ -358,7 +361,7 @@ public class TakerPaymentProtocol
// Step 2.10 Pay in the funds to the deposit tx and sign it
///////////////////////////////////////////////////////////////////////////////////////////
private void payDeposit(TradeMessage requestTradeMessage)
private void payDeposit(@NotNull TradeMessage requestTradeMessage)
{
log.debug("2.10 payDeposit");
@ -387,7 +390,7 @@ public class TakerPaymentProtocol
log.debug("preparedOffererDepositTxAsHex " + preparedOffererDepositTxAsHex);
try
{
Transaction signedTakerDepositTx = walletFacade.takerAddPaymentAndSignTx(takerInputAmount, msOutputAmount, offererPubKey, takerPubKey, arbitratorPubKey, preparedOffererDepositTxAsHex, trade.getId());
@NotNull Transaction signedTakerDepositTx = walletFacade.takerAddPaymentAndSignTx(takerInputAmount, msOutputAmount, offererPubKey, takerPubKey, arbitratorPubKey, preparedOffererDepositTxAsHex, trade.getId());
log.debug("2.10 deposit tx created: " + signedTakerDepositTx);
long takerTxOutIndex = signedTakerDepositTx.getInput(1).getOutpoint().getIndex();
sendSignedTakerDepositTxAsHex(signedTakerDepositTx, takerTxOutIndex, requestTradeMessage.getOffererTxOutIndex());
@ -402,11 +405,11 @@ public class TakerPaymentProtocol
// Step 2.11 Send the tx to the offerer
///////////////////////////////////////////////////////////////////////////////////////////
private void sendSignedTakerDepositTxAsHex(Transaction signedTakerDepositTx, long takerTxOutIndex, long offererTxOutIndex)
private void sendSignedTakerDepositTxAsHex(@NotNull Transaction signedTakerDepositTx, long takerTxOutIndex, long offererTxOutIndex)
{
log.debug("2.11 sendSignedTakerDepositTxAsHex");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -426,7 +429,7 @@ public class TakerPaymentProtocol
takerPaymentProtocolListener.onProgress(getProgress());
BankAccount bankAccount = user.getCurrentBankAccount();
@Nullable BankAccount bankAccount = user.getCurrentBankAccount();
String accountID = user.getAccountID();
String messagePubKey = user.getMessagePubKeyAsHex();
String contractAsJson = trade.getContractAsJson();
@ -442,7 +445,7 @@ public class TakerPaymentProtocol
log.debug("2.10 txConnOutAsHex: " + txConnOutAsHex);
log.debug("2.10 payoutAddress: " + payoutAddress);
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_OFFERER_DEPOSIT_PUBLICATION,
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.REQUEST_OFFERER_DEPOSIT_PUBLICATION,
trade.getId(),
bankAccount,
accountID,
@ -471,7 +474,7 @@ public class TakerPaymentProtocol
// Step 3.6 Incoming msg from offerer
///////////////////////////////////////////////////////////////////////////////////////////
public void onDepositTxPublished(TradeMessage tradeMessage)
public void onDepositTxPublished(@NotNull TradeMessage tradeMessage)
{
log.debug("3.6 DepositTxID received: " + tradeMessage.getDepositTxAsHex());
@ -505,23 +508,23 @@ public class TakerPaymentProtocol
// Step 3.12 User clicked the "bank transfer received" button, so we release the funds for pay out
///////////////////////////////////////////////////////////////////////////////////////////
public void releaseBTC(TradeMessage tradeMessage)
public void releaseBTC(@NotNull TradeMessage tradeMessage)
{
log.debug("3.12 releaseBTC");
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
@NotNull FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
@Override
public void onSuccess(Transaction transaction)
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
System.out.println("######### 3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction.toString());
log.debug("3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction.toString());
System.out.println("######### 3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction);
log.debug("3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction);
takerPaymentProtocolListener.onTradeCompleted(transaction.getHashAsString());
sendPayoutTxToOfferer(Utils.bytesToHexString(transaction.bitcoinSerialize()));
}
@Override
public void onFailure(Throwable t)
public void onFailure(@NotNull Throwable t)
{
log.error("######### 3.12 onFailure walletFacade.takerSignsAndSendsTx");
System.err.println("3.12 onFailure walletFacade.takerSignsAndSendsTx");
@ -556,10 +559,10 @@ public class TakerPaymentProtocol
// Step 3.13 Send payout txID to offerer
///////////////////////////////////////////////////////////////////////////////////////////
public void sendPayoutTxToOfferer(String payoutTxAsHex)
void sendPayoutTxToOfferer(String payoutTxAsHex)
{
log.debug("3.13 sendPayoutTxToOfferer ");
TradeMessageListener listener = new TradeMessageListener()
@NotNull TradeMessageListener listener = new TradeMessageListener()
{
@Override
public void onResult()
@ -577,7 +580,7 @@ public class TakerPaymentProtocol
}
};
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.PAYOUT_TX_PUBLISHED, trade.getId());
@NotNull TradeMessage tradeMessage = new TradeMessage(TradeMessageType.PAYOUT_TX_PUBLISHED, trade.getId());
tradeMessage.setPayoutTxAsHex(payoutTxAsHex);
log.debug("3.13 sendTradeMessage PAYOUT_TX_PUBLISHED");
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
@ -586,6 +589,7 @@ public class TakerPaymentProtocol
private double getProgress()
{
currentStep++;
int numberOfSteps = 10;
return (double) currentStep / (double) numberOfSteps;
}
}

View File

@ -4,11 +4,14 @@ import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Arbitrator implements Serializable
{
private static final long serialVersionUID = -2625059604136756635L;
private String UID;
private String id;
private String pubKeyAsHex;
private String messagePubKeyAsHex;
private String name;
@ -22,28 +25,30 @@ public class Arbitrator implements Serializable
private double minArbitrationFee;
private List<METHOD> arbitrationMethods;
private List<ID_VERIFICATION> idVerifications;
@Nullable
private String webUrl;
@Nullable
private String description;
public Arbitrator()
{
}
public Arbitrator(String pubKeyAsHex,
String messagePubKeyAsHex,
String name,
ID_TYPE idType,
List<Locale> languages,
Reputation reputation,
public Arbitrator(@NotNull String pubKeyAsHex,
@NotNull String messagePubKeyAsHex,
@NotNull String name,
@NotNull ID_TYPE idType,
@NotNull List<Locale> languages,
@NotNull Reputation reputation,
double maxTradeVolume,
double passiveServiceFee,
double minPassiveServiceFee,
double arbitrationFee,
double minArbitrationFee,
List<METHOD> arbitrationMethods,
List<ID_VERIFICATION> idVerifications,
String webUrl,
String description)
@NotNull List<METHOD> arbitrationMethods,
@NotNull List<ID_VERIFICATION> idVerifications,
@Nullable String webUrl,
@Nullable String description)
{
this.pubKeyAsHex = pubKeyAsHex;
this.messagePubKeyAsHex = messagePubKeyAsHex;
@ -62,10 +67,10 @@ public class Arbitrator implements Serializable
this.description = description;
//TODO for mock arbitrator
UID = name;
id = name;
}
public void updateFromStorage(Arbitrator savedArbitrator)
public void updateFromStorage(@NotNull Arbitrator savedArbitrator)
{
this.pubKeyAsHex = savedArbitrator.getPubKeyAsHex();
this.messagePubKeyAsHex = savedArbitrator.getPubKeyAsHex();
@ -83,15 +88,21 @@ public class Arbitrator implements Serializable
this.webUrl = savedArbitrator.getWebUrl();
this.description = savedArbitrator.getDescription();
UID = pubKeyAsHex;
//TODO for mock arbitrator
id = name;
}
@SuppressWarnings("NonFinalFieldReferencedInHashCode")
public int hashCode()
{
return Objects.hashCode(UID);
if (id != null)
return Objects.hashCode(id);
else
return 0;
}
public boolean equals(Object obj)
@SuppressWarnings("NonFinalFieldReferenceInEquals")
public boolean equals(@Nullable Object obj)
{
if (!(obj instanceof Arbitrator))
return false;
@ -99,43 +110,51 @@ public class Arbitrator implements Serializable
return true;
Arbitrator other = (Arbitrator) obj;
return other.getUID().equals(UID);
return id != null && id.equals(other.getId());
}
public String getUID()
@NotNull
public String getId()
{
return UID;
return id;
}
@NotNull
public String getPubKeyAsHex()
{
return pubKeyAsHex;
}
@NotNull
public String getMessagePubKeyAsHex()
{
return messagePubKeyAsHex;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public String getName()
{
return name;
}
@NotNull
public ID_TYPE getIdType()
{
return idType;
}
@NotNull
public List<Locale> getLanguages()
{
return languages;
}
@NotNull
public Reputation getReputation()
{
return reputation;
@ -166,26 +185,35 @@ public class Arbitrator implements Serializable
return minArbitrationFee;
}
@NotNull
public List<METHOD> getArbitrationMethods()
{
return arbitrationMethods;
}
@NotNull
public List<ID_VERIFICATION> getIdVerifications()
{
return idVerifications;
}
@Nullable
public String getWebUrl()
{
return webUrl;
}
@Nullable
public String getDescription()
{
return description;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Enums
///////////////////////////////////////////////////////////////////////////////////////////
public enum ID_TYPE
{
REAL_LIFE_ID,

View File

@ -1,6 +1,7 @@
package io.bitsquare.user;
import java.io.Serializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -13,9 +14,9 @@ public class Reputation implements Serializable
//TODO
public Reputation()
{
}
@NotNull
@Override
public String toString()
{

View File

@ -5,6 +5,8 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.SimpleBooleanProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class User implements Serializable
{
@ -12,10 +14,14 @@ public class User implements Serializable
transient private final SimpleBooleanProperty bankAccountChangedProperty = new SimpleBooleanProperty();
@Nullable
private String accountID;
@Nullable
private String messagePubKeyAsHex;
private boolean isOnline;
@NotNull
private List<BankAccount> bankAccounts = new ArrayList<>();
@Nullable
private BankAccount currentBankAccount = null;
public User()
@ -27,7 +33,7 @@ public class User implements Serializable
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void updateFromStorage(User savedUser)
public void updateFromStorage(@Nullable User savedUser)
{
if (savedUser != null)
{
@ -39,7 +45,7 @@ public class User implements Serializable
}
}
public void addBankAccount(BankAccount bankAccount)
public void addBankAccount(@NotNull BankAccount bankAccount)
{
if (!bankAccounts.contains(bankAccount))
bankAccounts.add(bankAccount);
@ -49,13 +55,10 @@ public class User implements Serializable
public void removeCurrentBankAccount()
{
if (currentBankAccount != null)
bankAccounts.remove(currentBankAccount);
if (currentBankAccount != null) bankAccounts.remove(currentBankAccount);
if (bankAccounts.size() > 0)
currentBankAccount = bankAccounts.get(0);
else
currentBankAccount = null;
if (bankAccounts.isEmpty()) currentBankAccount = null;
else currentBankAccount = bankAccounts.get(0);
}
@ -63,9 +66,10 @@ public class User implements Serializable
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public String getStringifiedBankAccounts()
{
String bankAccountUIDs = "";
@NotNull String bankAccountUIDs = "";
for (int i = 0; i < bankAccounts.size(); i++)
{
BankAccount bankAccount = bankAccounts.get(i);
@ -78,22 +82,24 @@ public class User implements Serializable
return bankAccountUIDs;
}
@Nullable
public String getMessagePubKeyAsHex()
{
return messagePubKeyAsHex;
}
public void setMessagePubKeyAsHex(String messageID)
public void setMessagePubKeyAsHex(@Nullable String messageID)
{
this.messagePubKeyAsHex = messageID;
}
@Nullable
public String getAccountID()
{
return accountID;
}
public void setAccountID(String accountID)
public void setAccountID(@Nullable String accountID)
{
this.accountID = accountID;
}
@ -103,38 +109,41 @@ public class User implements Serializable
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public List<BankAccount> getBankAccounts()
{
return bankAccounts;
}
public void setBankAccounts(List<BankAccount> bankAccounts)
public void setBankAccounts(@NotNull List<BankAccount> bankAccounts)
{
this.bankAccounts = bankAccounts;
}
@Nullable
public BankAccount getCurrentBankAccount()
{
return currentBankAccount;
}
public void setCurrentBankAccount(BankAccount currentBankAccount)
public void setCurrentBankAccount(@NotNull BankAccount bankAccount)
{
this.currentBankAccount = currentBankAccount;
this.currentBankAccount = bankAccount;
bankAccountChangedProperty.set(!bankAccountChangedProperty.get());
}
public BankAccount getBankAccount(String bankAccountUID)
@Nullable
public BankAccount getBankAccount(@NotNull String bankAccountId)
{
for (BankAccount bankAccount : bankAccounts)
for (final BankAccount bankAccount : bankAccounts)
{
if (bankAccount.getUid().equals(bankAccountUID))
if (bankAccount.getUid().equals(bankAccountId))
return bankAccount;
}
return null;
}
public boolean getIsOnline()
boolean getIsOnline()
{
return isOnline;
}
@ -144,11 +153,13 @@ public class User implements Serializable
this.isOnline = isOnline;
}
@NotNull
public SimpleBooleanProperty getBankAccountChangedProperty()
{
return bankAccountChangedProperty;
}
@NotNull
@Override
public String toString()
{

View File

@ -1,146 +1,184 @@
package io.bitsquare.util;
import com.google.bitcoin.core.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.google.bitcoin.utils.Threading;
import io.bitsquare.BitSquare;
import java.io.*;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.concurrent.locks.ReentrantLock;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DSAKeyUtil
{
private static final Logger log = LoggerFactory.getLogger(DSAKeyUtil.class);
private static final String baseDir = Utilities.getRootDir();
private static final String prefix = BitSquare.ID + "_";
private static final ReentrantLock lock = Threading.lock("DSAKeyUtil");
public static KeyPair getKeyPair()
///////////////////////////////////////////////////////////////////////////////////////////
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public static String getHexStringFromPublicKey(@NotNull PublicKey publicKey)
{
return getKeyPair("public.key", "private.key");
}
public static KeyPair getKeyPair(String keyName)
{
return getKeyPair(keyName + "_public" + ".key", keyName + "_private" + ".key");
}
public static String getHexStringFromPublicKey(PublicKey publicKey)
{
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
return Utils.bytesToHexString(x509EncodedKeySpec.getEncoded());
}
public static PublicKey getPublicKeyFromHexString(String publicKeyAsHex)
// not used yet
/*
@Nullable
public static PublicKey getPublicKeyFromHexString(String publicKeyAsHex) throws NoSuchAlgorithmException, InvalidKeySpecException
{
byte[] bytes = Utils.parseAsHexOrBase58(publicKeyAsHex);
try
{
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
return keyFactory.generatePublic(new X509EncodedKeySpec(bytes));
} catch (NoSuchAlgorithmException | InvalidKeySpecException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return null;
final byte[] bytes = Utils.parseAsHexOrBase58(publicKeyAsHex);
final KeyFactory keyFactory = KeyFactory.INSTANCE("DSA");
return keyFactory.generatePublic(new X509EncodedKeySpec(bytes));
} */
@Nullable
public static KeyPair getKeyPair()
{
return getKeyPair(FileUtil.getFile(prefix + "public", "key"), FileUtil.getFile(prefix + "private", "key"));
}
public static KeyPair getKeyPair(String pubKeyPath, String privKeyPath)
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
private static KeyPair getKeyPair(@NotNull File pubKeyFile, @NotNull File privKeyFile)
{
try
{
return loadKeyPair(pubKeyPath, privKeyPath, "DSA");
} catch (Exception e)
return readKeyPairFromFiles(pubKeyFile, privKeyFile);
} catch (Throwable throwable)
{
if (throwable instanceof FileNotFoundException)
log.debug("Files not found. That is ok for the first run.");
else
log.error("Could not read key files. " + throwable);
try
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024);
KeyPair generatedKeyPair = keyGen.genKeyPair();
// System.out.println("Generated Key Pair");
dumpKeyPair(generatedKeyPair);
saveKeyPair(pubKeyPath, privKeyPath, generatedKeyPair);
try
{
saveKeyPairToFiles(pubKeyFile, privKeyFile, generatedKeyPair);
} catch (Throwable t2)
{
t2.printStackTrace();
log.error("Saving key pair failed. " + t2);
}
return generatedKeyPair;
} catch (Exception e2)
} catch (Throwable t3)
{
e2.printStackTrace();
t3.printStackTrace();
log.error("Generating key pair failed. " + t3);
return null;
}
}
}
private static void dumpKeyPair(KeyPair keyPair)
{
PublicKey pub = keyPair.getPublic();
// System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
// System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private static String getHexString(byte[] b)
private static void saveKeyPairToFiles(@NotNull File pubKeyFile, @NotNull File privKeyFile, @NotNull KeyPair keyPair) throws IOException
{
String result = "";
for (byte aB : b)
lock.lock();
final File pubKeyTempFile = FileUtil.getTempFile("pubKey_temp_" + prefix);
final File privKeyTempFile = FileUtil.getTempFile("privKey_temp_" + prefix);
try (final FileOutputStream pubKeyFileOutputStream = new FileOutputStream(pubKeyTempFile);
final FileOutputStream privKeyFileOutputStream = new FileOutputStream(privKeyTempFile))
{
result += Integer.toString((aB & 0xff) + 0x100, 16).substring(1);
final PublicKey publicKey = keyPair.getPublic();
final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
pubKeyFileOutputStream.write(x509EncodedKeySpec.getEncoded());
pubKeyFileOutputStream.flush();
pubKeyFileOutputStream.getFD().sync();
final PrivateKey privateKey = keyPair.getPrivate();
final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
privKeyFileOutputStream.write(pkcs8EncodedKeySpec.getEncoded());
privKeyFileOutputStream.flush();
privKeyFileOutputStream.getFD().sync();
if (Utils.isWindows())
{
// Work around an issue on Windows whereby you can't rename over existing files.
final File pubKeyCanonicalFile = pubKeyFile.getCanonicalFile();
if (pubKeyCanonicalFile.exists() && !pubKeyCanonicalFile.delete())
throw new IOException("Failed to delete pubKeyCanonicalFile for replacement with save");
if (!pubKeyTempFile.renameTo(pubKeyCanonicalFile))
throw new IOException("Failed to rename " + pubKeyTempFile + " to " + pubKeyCanonicalFile);
final File privKeyCanonicalFile = privKeyFile.getCanonicalFile();
if (privKeyCanonicalFile.exists() && !privKeyCanonicalFile.delete())
throw new IOException("Failed to delete privKeyCanonicalFile for replacement with save");
if (!privKeyTempFile.renameTo(privKeyCanonicalFile))
throw new IOException("Failed to rename " + privKeyTempFile + " to " + privKeyCanonicalFile);
}
else
{
if (!pubKeyTempFile.renameTo(pubKeyFile))
{
throw new IOException("Failed to rename " + pubKeyTempFile + " to " + pubKeyFile);
}
if (!privKeyTempFile.renameTo(privKeyFile))
{
throw new IOException("Failed to rename " + privKeyTempFile + " to " + privKeyFile);
}
}
} finally
{
if (pubKeyTempFile.exists())
{
log.warn("PubKeyTempFile still exists after failed save.");
if (!pubKeyTempFile.delete())
log.warn("Cannot delete pubKeyTempFile.");
}
if (privKeyTempFile.exists())
{
log.warn("PrivKeyTempFile still exists after failed save.");
if (!privKeyTempFile.delete())
log.warn("Cannot delete privKeyTempFile.");
}
lock.unlock();
}
return result;
}
public static void saveKeyPair(String pubKeyPath, String privKeyPath, KeyPair keyPair) throws IOException
@Nullable
private static KeyPair readKeyPairFromFiles(@NotNull File pubKeyFile, @NotNull File privKeyFile) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException
{
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
lock.lock();
try (final FileInputStream pubKeyFileInputStream = new FileInputStream(pubKeyFile);
final FileInputStream privKeyFileInputStream = new FileInputStream(privKeyFile))
{
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(baseDir + pubKeyPath);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
final byte[] encodedPubKey = new byte[(int) pubKeyFile.length()];
//noinspection ResultOfMethodCallIgnored
pubKeyFileInputStream.read(encodedPubKey);
final PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedPubKey));
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream(baseDir + privKeyPath);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
final byte[] encodedPrivKey = new byte[(int) privKeyFile.length()];
//noinspection ResultOfMethodCallIgnored
privKeyFileInputStream.read(encodedPrivKey);
final PrivateKey privKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedPrivKey));
return new KeyPair(pubKey, privKey);
} finally
{
lock.unlock();
}
}
public static KeyPair loadKeyPair(String pubKeyPath, String privKeyPath, String algorithm)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException
{
// Read Public Key.
File filePublicKey = new File(baseDir + pubKeyPath);
FileInputStream fis = new FileInputStream(baseDir + pubKeyPath);
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(baseDir + privKeyPath);
fis = new FileInputStream(baseDir + privKeyPath);
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new KeyPair(publicKey, privateKey);
}
}

View File

@ -0,0 +1,55 @@
package io.bitsquare.util;
import java.io.File;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtil
{
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
private final static File rootDirectory = new File(FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getFile()).getParentFile();
public static File getRootDirectory()
{
return rootDirectory;
}
// not used yet
/* public static void setRootDirectory(@NotNull File rootDirectory)
{
FileUtil.rootDirectory = rootDirectory;
if (!rootDirectory.exists())
{
if (!rootDirectory.mkdir())
log.error("Could not create directory. " + rootDirectory.getAbsolutePath());
}
} */
@NotNull
public static File getDirectory(@NotNull String name)
{
final File dir = new File(rootDirectory, name);
if (!dir.exists())
{
if (!dir.mkdir())
log.error("Could not create directory. " + dir.getAbsolutePath());
}
return dir;
}
@NotNull
public static File getFile(@NotNull String name, @NotNull String suffix)
{
return new File(rootDirectory, name + "." + suffix);
}
@NotNull
public static File getTempFile(@NotNull String prefix) throws IOException
{
return File.createTempFile("temp_" + prefix, null, rootDirectory);
}
}

View File

@ -9,6 +9,8 @@ import java.io.*;
import java.net.URI;
import java.util.function.Function;
import javafx.animation.AnimationTimer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -17,11 +19,6 @@ public class Utilities
private static final Logger log = LoggerFactory.getLogger(Utilities.class);
private static long lastTimeStamp = System.currentTimeMillis();
public static String getRootDir()
{
return Utilities.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/../";
}
public static String objectToJson(Object object)
{
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting().create();
@ -34,15 +31,16 @@ public class Utilities
return gson.fromJson(jsonString, classOfT);
}
@Nullable
public static Object deserializeHexStringToObject(String serializedHexString)
{
Object result = null;
@Nullable Object result = null;
try
{
ByteInputStream byteInputStream = new ByteInputStream();
@NotNull ByteInputStream byteInputStream = new ByteInputStream();
byteInputStream.setBuf(com.google.bitcoin.core.Utils.parseAsHexOrBase58(serializedHexString));
try (ObjectInputStream objectInputStream = new ObjectInputStream(byteInputStream))
try (@NotNull ObjectInputStream objectInputStream = new ObjectInputStream(byteInputStream))
{
result = objectInputStream.readObject();
} catch (ClassNotFoundException e)
@ -61,13 +59,14 @@ public class Utilities
return result;
}
public static String serializeObjectToHexString(Object serializable)
@Nullable
public static String serializeObjectToHexString(Serializable serializable)
{
String result = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
@Nullable String result = null;
@NotNull ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try
{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
@NotNull ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(serializable);
result = com.google.bitcoin.core.Utils.bytesToHexString(byteArrayOutputStream.toByteArray());
@ -81,9 +80,10 @@ public class Utilities
return result;
}
public static void printElapsedTime(String msg)
@SuppressWarnings("SameParameterValue")
private static void printElapsedTime(@NotNull String msg)
{
if (msg.length() > 0)
if (!msg.isEmpty())
msg += " / ";
long timeStamp = System.currentTimeMillis();
log.debug(msg + "Elapsed: " + String.valueOf(timeStamp - lastTimeStamp));
@ -96,38 +96,41 @@ public class Utilities
}
public static void openURL(String url) throws Exception
public static void openURL(@NotNull String url) throws Exception
{
Desktop.getDesktop().browse(new URI(url));
}
public static Object copy(Object orig)
@Nullable
public static Object copy(Serializable orig)
{
Object obj = null;
@Nullable Object obj = null;
try
{
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
@NotNull ByteArrayOutputStream bos = new ByteArrayOutputStream();
@NotNull ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
@NotNull ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
} catch (IOException | ClassNotFoundException e)
} catch (@NotNull IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
return obj;
}
public static AnimationTimer setTimeout(int delay, Function<AnimationTimer, Void> callback)
@SuppressWarnings("SameParameterValue")
@NotNull
public static AnimationTimer setTimeout(int delay, @NotNull Function<AnimationTimer, Void> callback)
{
AnimationTimer animationTimer = new AnimationTimer()
@NotNull AnimationTimer animationTimer = new AnimationTimer()
{
final long lastTimeStamp = System.currentTimeMillis();
@ -145,9 +148,11 @@ public class Utilities
return animationTimer;
}
public static AnimationTimer setInterval(int delay, Function<AnimationTimer, Void> callback)
@SuppressWarnings("SameParameterValue")
@NotNull
public static AnimationTimer setInterval(int delay, @NotNull Function<AnimationTimer, Void> callback)
{
AnimationTimer animationTimer = new AnimationTimer()
@NotNull AnimationTimer animationTimer = new AnimationTimer()
{
long lastTimeStamp = System.currentTimeMillis();

Some files were not shown because too many files have changed in this diff Show More