mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
adding new/moved files
This commit is contained in:
parent
daa5557385
commit
104914a4de
7 changed files with 1420 additions and 0 deletions
117
common/src/main/java/io/bitsquare/messages/app/Log.java
Normal file
117
common/src/main/java/io/bitsquare/messages/app/Log.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.app;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
|
||||
import io.bitsquare.common.util.Profiler;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class Log {
|
||||
private static SizeBasedTriggeringPolicy triggeringPolicy;
|
||||
private static Logger logbackLogger;
|
||||
|
||||
public static void setLevel(Level logLevel) {
|
||||
//logbackLogger.setLevel(logLevel);
|
||||
}
|
||||
|
||||
public static void setup(String fileName) {
|
||||
/*
|
||||
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
|
||||
RollingFileAppender appender = new RollingFileAppender();
|
||||
appender.setContext(loggerContext);
|
||||
appender.setFile(fileName + ".log");
|
||||
|
||||
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
|
||||
rollingPolicy.setContext(loggerContext);
|
||||
rollingPolicy.setParent(appender);
|
||||
rollingPolicy.setFileNamePattern(fileName + "_%i.log");
|
||||
rollingPolicy.setMinIndex(1);
|
||||
rollingPolicy.setMaxIndex(10);
|
||||
rollingPolicy.start();
|
||||
|
||||
triggeringPolicy = new SizeBasedTriggeringPolicy();
|
||||
triggeringPolicy.setMaxFileSize("10MB");
|
||||
triggeringPolicy.start();
|
||||
|
||||
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
||||
encoder.setContext(loggerContext);
|
||||
encoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg %xEx%n");
|
||||
encoder.start();
|
||||
|
||||
appender.setEncoder(encoder);
|
||||
appender.setRollingPolicy(rollingPolicy);
|
||||
appender.setTriggeringPolicy(triggeringPolicy);
|
||||
appender.start();
|
||||
|
||||
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
||||
logbackLogger.addAppender(appender);
|
||||
logbackLogger.setLevel(Level.INFO);
|
||||
*/
|
||||
|
||||
// log errors in separate file
|
||||
// not working as expected still.... damn logback...
|
||||
/* FileAppender errorAppender = new FileAppender();
|
||||
errorAppender.setEncoder(encoder);
|
||||
errorAppender.setName("Error");
|
||||
errorAppender.setContext(loggerContext);
|
||||
errorAppender.setFile(fileName + "_error.log");
|
||||
LevelFilter levelFilter = new LevelFilter();
|
||||
levelFilter.setLevel(Level.ERROR);
|
||||
levelFilter.setOnMatch(FilterReply.ACCEPT);
|
||||
levelFilter.setOnMismatch(FilterReply.DENY);
|
||||
levelFilter.start();
|
||||
errorAppender.addFilter(levelFilter);
|
||||
errorAppender.start();
|
||||
logbackLogger.addAppender(errorAppender);*/
|
||||
}
|
||||
|
||||
public static void traceCall() {
|
||||
if (LoggerFactory.getLogger(Log.class).isTraceEnabled()) {
|
||||
StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1];
|
||||
String methodName = stackTraceElement.getMethodName();
|
||||
if (methodName.equals("<init>"))
|
||||
methodName = "Constructor ";
|
||||
String className = stackTraceElement.getClassName();
|
||||
LoggerFactory.getLogger(className).trace("Called: {}", methodName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void traceCall(String message) {
|
||||
if (LoggerFactory.getLogger(Log.class).isTraceEnabled()) {
|
||||
StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1];
|
||||
String methodName = stackTraceElement.getMethodName();
|
||||
if (methodName.equals("<init>"))
|
||||
methodName = "Constructor ";
|
||||
String className = stackTraceElement.getClassName();
|
||||
LoggerFactory.getLogger(className).trace("Called: {} [{}]", methodName, message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logIfStressTests(String msg) {
|
||||
if (DevFlags.STRESS_TEST_MODE)
|
||||
System.err.println(new SimpleDateFormat("HH:mm:ss.SSS").format(new Date()) +
|
||||
" - " + msg +
|
||||
" / Memory(MB): " + Profiler.getUsedMemoryInMB());
|
||||
}
|
||||
}
|
429
gui/src/main/java/io/bitsquare/messages/app/BitsquareApp.java
Normal file
429
gui/src/main/java/io/bitsquare/messages/app/BitsquareApp.java
Normal file
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.app;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import io.bitsquare.alert.AlertManager;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.wallet.*;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.common.util.LimitedKeyStrengthException;
|
||||
import io.bitsquare.common.util.Profiler;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.filter.FilterManager;
|
||||
import io.bitsquare.gui.SystemTray;
|
||||
import io.bitsquare.gui.common.UITimer;
|
||||
import io.bitsquare.gui.common.view.CachingViewLoader;
|
||||
import io.bitsquare.gui.common.view.View;
|
||||
import io.bitsquare.gui.common.view.ViewLoader;
|
||||
import io.bitsquare.gui.common.view.guice.InjectorViewFactory;
|
||||
import io.bitsquare.gui.main.MainView;
|
||||
import io.bitsquare.gui.main.MainViewModel;
|
||||
import io.bitsquare.gui.main.debug.DebugView;
|
||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||
import io.bitsquare.gui.main.overlays.windows.*;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.bitcoinj.store.BlockStoreException;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.controlsfx.dialog.Dialogs;
|
||||
import org.reactfx.EventStreams;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.bitsquare.messages.app.AppOptionKeys.APP_NAME_KEY;
|
||||
|
||||
public class BitsquareApp extends Application {
|
||||
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
||||
|
||||
private static final long LOG_MEMORY_PERIOD_MIN = 10;
|
||||
|
||||
private static Environment env;
|
||||
|
||||
private BitsquareAppModule bitsquareAppModule;
|
||||
private Injector injector;
|
||||
private boolean popupOpened;
|
||||
|
||||
private static Stage primaryStage;
|
||||
private Scene scene;
|
||||
private final List<String> corruptedDatabaseFiles = new ArrayList<>();
|
||||
private MainView mainView;
|
||||
|
||||
public static Runnable shutDownHandler;
|
||||
private boolean shutDownRequested;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
BitsquareApp.env = env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException {
|
||||
BitsquareApp.primaryStage = stage;
|
||||
|
||||
String logPath = Paths.get(env.getProperty(AppOptionKeys.APP_DATA_DIR_KEY), "bitsquare").toString();
|
||||
Log.setup(logPath);
|
||||
log.info("Log files under: " + logPath);
|
||||
Version.printVersion();
|
||||
Utilities.printSysInfo();
|
||||
Log.setLevel(Level.toLevel(env.getRequiredProperty(CommonOptionKeys.LOG_LEVEL_KEY)));
|
||||
|
||||
UserThread.setExecutor(Platform::runLater);
|
||||
UserThread.setTimerClass(UITimer.class);
|
||||
|
||||
shutDownHandler = this::stop;
|
||||
|
||||
// setup UncaughtExceptionHandler
|
||||
Thread.UncaughtExceptionHandler handler = (thread, throwable) -> {
|
||||
// Might come from another thread
|
||||
if (throwable.getCause() != null && throwable.getCause().getCause() != null &&
|
||||
throwable.getCause().getCause() instanceof BlockStoreException) {
|
||||
log.error(throwable.getMessage());
|
||||
} else {
|
||||
log.error("Uncaught Exception from thread " + Thread.currentThread().getName());
|
||||
log.error("throwableMessage= " + throwable.getMessage());
|
||||
log.error("throwableClass= " + throwable.getClass());
|
||||
log.error("Stack trace:\n" + ExceptionUtils.getStackTrace(throwable));
|
||||
throwable.printStackTrace();
|
||||
UserThread.execute(() -> showErrorPopup(throwable, false));
|
||||
}
|
||||
};
|
||||
Thread.setDefaultUncaughtExceptionHandler(handler);
|
||||
Thread.currentThread().setUncaughtExceptionHandler(handler);
|
||||
|
||||
try {
|
||||
Utilities.checkCryptoPolicySetup();
|
||||
} catch (NoSuchAlgorithmException | LimitedKeyStrengthException e) {
|
||||
e.printStackTrace();
|
||||
UserThread.execute(() -> showErrorPopup(e, true));
|
||||
}
|
||||
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
try {
|
||||
// Guice
|
||||
bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
|
||||
injector = Guice.createInjector(bitsquareAppModule);
|
||||
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
|
||||
|
||||
Version.setBtcNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
|
||||
|
||||
if (Utilities.isLinux())
|
||||
System.setProperty("prism.lcdtext", "false");
|
||||
|
||||
Storage.setDatabaseCorruptionHandler((String fileName) -> {
|
||||
corruptedDatabaseFiles.add(fileName);
|
||||
if (mainView != null)
|
||||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
});
|
||||
|
||||
// load the main view and create the main scene
|
||||
CachingViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
|
||||
mainView = (MainView) viewLoader.load(MainView.class);
|
||||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
|
||||
/* Storage.setDatabaseCorruptionHandler((String fileName) -> {
|
||||
corruptedDatabaseFiles.add(fileName);
|
||||
if (mainView != null)
|
||||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
});*/
|
||||
|
||||
scene = new Scene(mainView.getRoot(), 1200, 700); //740
|
||||
|
||||
Font.loadFont(getClass().getResource("/fonts/Verdana.ttf").toExternalForm(), 13);
|
||||
Font.loadFont(getClass().getResource("/fonts/VerdanaBold.ttf").toExternalForm(), 13);
|
||||
Font.loadFont(getClass().getResource("/fonts/VerdanaItalic.ttf").toExternalForm(), 13);
|
||||
Font.loadFont(getClass().getResource("/fonts/VerdanaBoldItalic.ttf").toExternalForm(), 13);
|
||||
scene.getStylesheets().setAll(
|
||||
"/io/bitsquare/gui/bitsquare.css",
|
||||
"/io/bitsquare/gui/images.css",
|
||||
"/io/bitsquare/gui/CandleStickChart.css");
|
||||
|
||||
// configure the system tray
|
||||
SystemTray.create(primaryStage, shutDownHandler);
|
||||
|
||||
primaryStage.setOnCloseRequest(event -> {
|
||||
event.consume();
|
||||
stop();
|
||||
});
|
||||
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> {
|
||||
if (new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || new KeyCodeCombination(KeyCode.W, KeyCombination.CONTROL_DOWN).match(keyEvent)) {
|
||||
stop();
|
||||
} else if (new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || new KeyCodeCombination(KeyCode.Q, KeyCombination.CONTROL_DOWN).match(keyEvent)) {
|
||||
stop();
|
||||
} else if (new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || new KeyCodeCombination(KeyCode.E, KeyCombination.CONTROL_DOWN).match(keyEvent)) {
|
||||
showEmptyWalletPopup(injector.getInstance(BtcWalletService.class));
|
||||
} else if (DevFlags.DEV_MODE && new KeyCodeCombination(KeyCode.B, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || new KeyCodeCombination(KeyCode.E, KeyCombination.CONTROL_DOWN).match(keyEvent)) {
|
||||
showEmptyWalletPopup(injector.getInstance(SquWalletService.class));
|
||||
} else if (new KeyCodeCombination(KeyCode.M, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
showSendAlertMessagePopup();
|
||||
} else if (new KeyCodeCombination(KeyCode.F, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
showFilterPopup();
|
||||
} else if (new KeyCodeCombination(KeyCode.F, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
showFPSWindow();
|
||||
} else if (new KeyCodeCombination(KeyCode.J, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
WalletsManager walletsManager = injector.getInstance(WalletsManager.class);
|
||||
if (walletsManager.areWalletsAvailable())
|
||||
new ShowWalletDataWindow(walletsManager).information("Wallet raw data").show();
|
||||
else
|
||||
new Popup<>().warning("The wallet is not initialized yet").show();
|
||||
} else if (DevFlags.DEV_MODE && new KeyCodeCombination(KeyCode.G, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
TradeWalletService tradeWalletService = injector.getInstance(TradeWalletService.class);
|
||||
BtcWalletService walletService = injector.getInstance(BtcWalletService.class);
|
||||
if (walletService.isWalletReady())
|
||||
new SpendFromDepositTxWindow(tradeWalletService).information("Emergency wallet tool").show();
|
||||
else
|
||||
new Popup<>().warning("The wallet is not initialized yet").show();
|
||||
} else if (DevFlags.DEV_MODE && new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) {
|
||||
showDebugWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// configure the primary stage
|
||||
primaryStage.setTitle(env.getRequiredProperty(APP_NAME_KEY));
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.setMinWidth(1020);
|
||||
primaryStage.setMinHeight(620);
|
||||
|
||||
// on windows the title icon is also used as task bar icon in a larger size
|
||||
// on Linux no title icon is supported but also a large task bar icon is derived from that title icon
|
||||
String iconPath;
|
||||
if (Utilities.isOSX())
|
||||
iconPath = ImageUtil.isRetina() ? "/images/window_icon@2x.png" : "/images/window_icon.png";
|
||||
else if (Utilities.isWindows())
|
||||
iconPath = "/images/task_bar_icon_windows.png";
|
||||
else
|
||||
iconPath = "/images/task_bar_icon_linux.png";
|
||||
|
||||
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream(iconPath)));
|
||||
|
||||
// make the UI visible
|
||||
primaryStage.show();
|
||||
|
||||
|
||||
if (!Utilities.isCorrectOSArchitecture()) {
|
||||
String osArchitecture = Utilities.getOSArchitecture();
|
||||
// We don't force a shutdown as the osArchitecture might in strange cases return a wrong value.
|
||||
// Needs at least more testing on different machines...
|
||||
new Popup<>().warning("You probably have the wrong Bitsquare version for this computer.\n" +
|
||||
"Your computer's architecture is: " + osArchitecture + ".\n" +
|
||||
"The Bitsquare binary you installed is: " + Utilities.getJVMArchitecture() + ".\n" +
|
||||
"Please shut down and re-install the correct version (" + osArchitecture + ").")
|
||||
.show();
|
||||
}
|
||||
|
||||
UserThread.runPeriodically(() -> Profiler.printSystemLoad(log), LOG_MEMORY_PERIOD_MIN, TimeUnit.MINUTES);
|
||||
|
||||
} catch (
|
||||
Throwable throwable
|
||||
)
|
||||
|
||||
{
|
||||
showErrorPopup(throwable, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void showSendAlertMessagePopup() {
|
||||
AlertManager alertManager = injector.getInstance(AlertManager.class);
|
||||
new SendAlertMessageWindow()
|
||||
.onAddAlertMessage(alertManager::addAlertMessageIfKeyIsValid)
|
||||
.onRemoveAlertMessage(alertManager::removeAlertMessageIfKeyIsValid)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showFilterPopup() {
|
||||
FilterManager filterManager = injector.getInstance(FilterManager.class);
|
||||
new FilterWindow(filterManager)
|
||||
.onAddFilter(filterManager::addFilterMessageIfKeyIsValid)
|
||||
.onRemoveFilter(filterManager::removeFilterMessageIfKeyIsValid)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showEmptyWalletPopup(WalletService walletService) {
|
||||
EmptyWalletWindow emptyWalletWindow = injector.getInstance(EmptyWalletWindow.class);
|
||||
emptyWalletWindow.setwalletService(walletService);
|
||||
emptyWalletWindow.show();
|
||||
}
|
||||
|
||||
private void showErrorPopup(Throwable throwable, boolean doShutDown) {
|
||||
if (!shutDownRequested) {
|
||||
if (scene == null) {
|
||||
log.warn("Scene not available yet, we create a new scene. The bug might be caused by an exception in a constructor or by a circular dependency in guice.");
|
||||
scene = new Scene(new StackPane(), 1000, 650);
|
||||
scene.getStylesheets().setAll(
|
||||
"/io/bitsquare/gui/bitsquare.css",
|
||||
"/io/bitsquare/gui/images.css");
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
try {
|
||||
try {
|
||||
if (!popupOpened) {
|
||||
String message = throwable.getMessage();
|
||||
popupOpened = true;
|
||||
if (message != null)
|
||||
new Popup().error(message).onClose(() -> popupOpened = false).show();
|
||||
else
|
||||
new Popup().error(throwable.toString()).onClose(() -> popupOpened = false).show();
|
||||
}
|
||||
} catch (Throwable throwable3) {
|
||||
log.error("Error at displaying Throwable.");
|
||||
throwable3.printStackTrace();
|
||||
}
|
||||
if (doShutDown)
|
||||
stop();
|
||||
} catch (Throwable throwable2) {
|
||||
// If printStackTrace cause a further exception we don't pass the throwable to the Popup.
|
||||
Dialogs.create()
|
||||
.owner(primaryStage)
|
||||
.title("Error")
|
||||
.message(throwable.toString())
|
||||
.masthead("A fatal exception occurred at startup.")
|
||||
.showError();
|
||||
if (doShutDown)
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used for debugging trade process
|
||||
private void showDebugWindow() {
|
||||
ViewLoader viewLoader = injector.getInstance(ViewLoader.class);
|
||||
View debugView = viewLoader.load(DebugView.class);
|
||||
Parent parent = (Parent) debugView.getRoot();
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(parent));
|
||||
stage.setTitle("Debug window");
|
||||
stage.initModality(Modality.NONE);
|
||||
stage.initStyle(StageStyle.UTILITY);
|
||||
stage.initOwner(scene.getWindow());
|
||||
stage.setX(primaryStage.getX() + primaryStage.getWidth() + 10);
|
||||
stage.setY(primaryStage.getY());
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
||||
private void showFPSWindow() {
|
||||
Label label = new Label();
|
||||
EventStreams.animationTicks()
|
||||
.latestN(100)
|
||||
.map(ticks -> {
|
||||
int n = ticks.size() - 1;
|
||||
return n * 1_000_000_000.0 / (ticks.get(n) - ticks.get(0));
|
||||
})
|
||||
.map(d -> String.format("FPS: %.3f", d))
|
||||
.feedTo(label.textProperty());
|
||||
|
||||
Pane root = new StackPane();
|
||||
root.getChildren().add(label);
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(root));
|
||||
stage.setTitle("FPS");
|
||||
stage.initModality(Modality.NONE);
|
||||
stage.initStyle(StageStyle.UTILITY);
|
||||
stage.initOwner(scene.getWindow());
|
||||
stage.setX(primaryStage.getX() + primaryStage.getWidth() + 10);
|
||||
stage.setY(primaryStage.getY());
|
||||
stage.setWidth(200);
|
||||
stage.setHeight(100);
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (!shutDownRequested) {
|
||||
new Popup().headLine("Shut down in progress")
|
||||
.backgroundInfo("Shutting down application can take a few seconds.\n" +
|
||||
"Please don't interrupt this process.")
|
||||
.hideCloseButton()
|
||||
.useAnimation(false)
|
||||
.show();
|
||||
UserThread.runAfter(() -> {
|
||||
gracefulShutDown(() -> {
|
||||
log.debug("App shutdown complete");
|
||||
System.exit(0);
|
||||
});
|
||||
}, 200, TimeUnit.MILLISECONDS);
|
||||
shutDownRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void gracefulShutDown(ResultHandler resultHandler) {
|
||||
log.debug("gracefulShutDown");
|
||||
try {
|
||||
if (injector != null) {
|
||||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(MainViewModel.class).shutDown();
|
||||
injector.getInstance(TradeManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
bitsquareAppModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
});
|
||||
// we wait max 20 sec.
|
||||
UserThread.runAfter(resultHandler::handleResult, 20);
|
||||
} else {
|
||||
UserThread.runAfter(resultHandler::handleResult, 1);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
log.debug("App shutdown failed with exception");
|
||||
t.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.app;
|
||||
|
||||
import joptsimple.OptionException;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.messages.app.BitsquareEnvironment.DEFAULT_APP_NAME;
|
||||
import static io.bitsquare.messages.app.BitsquareEnvironment.DEFAULT_USER_DATA_DIR;
|
||||
|
||||
public class BitsquareAppMain extends BitsquareExecutable {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitsquareAppMain.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// We don't want to do the full argument parsing here as that might easily change in update versions
|
||||
// So we only handle the absolute minimum which is APP_NAME, APP_DATA_DIR_KEY and USER_DATA_DIR
|
||||
OptionParser parser = new OptionParser();
|
||||
parser.allowsUnrecognizedOptions();
|
||||
parser.accepts(AppOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR))
|
||||
.withRequiredArg();
|
||||
parser.accepts(AppOptionKeys.APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME))
|
||||
.withRequiredArg();
|
||||
|
||||
OptionSet options;
|
||||
try {
|
||||
options = parser.parse(args);
|
||||
} catch (OptionException ex) {
|
||||
System.out.println("error: " + ex.getMessage());
|
||||
System.out.println();
|
||||
parser.printHelpOn(System.out);
|
||||
System.exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
BitsquareEnvironment bitsquareEnvironment = getBitsquareEnvironment(options);
|
||||
|
||||
// need to call that before BitsquareAppMain().execute(args)
|
||||
BitsquareExecutable.initAppDir(bitsquareEnvironment.getProperty(AppOptionKeys.APP_DATA_DIR_KEY));
|
||||
|
||||
// For some reason the JavaFX launch process results in us losing the thread context class loader: reset it.
|
||||
// In order to work around a bug in JavaFX 8u25 and below, you must include the following code as the first line of your realMain method:
|
||||
Thread.currentThread().setContextClassLoader(BitsquareAppMain.class.getClassLoader());
|
||||
|
||||
new BitsquareAppMain().execute(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(OptionSet options) {
|
||||
BitsquareApp.setEnvironment(getBitsquareEnvironment(options));
|
||||
javafx.application.Application.launch(BitsquareApp.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.app;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import io.bitsquare.alert.AlertModule;
|
||||
import io.bitsquare.arbitration.ArbitratorModule;
|
||||
import io.bitsquare.btc.BitcoinModule;
|
||||
import io.bitsquare.common.Clock;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.crypto.KeyStorage;
|
||||
import io.bitsquare.crypto.EncryptionServiceModule;
|
||||
import io.bitsquare.dao.DaoModule;
|
||||
import io.bitsquare.filter.FilterModule;
|
||||
import io.bitsquare.gui.GuiModule;
|
||||
import io.bitsquare.gui.common.view.CachingViewLoader;
|
||||
import io.bitsquare.gui.main.overlays.notifications.NotificationCenter;
|
||||
import io.bitsquare.p2p.P2PModule;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.TradeModule;
|
||||
import io.bitsquare.trade.offer.OfferModule;
|
||||
import io.bitsquare.messages.user.Preferences;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static com.google.inject.name.Names.named;
|
||||
|
||||
class BitsquareAppModule extends AppModule {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitsquareAppModule.class);
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public BitsquareAppModule(Environment env, Stage primaryStage) {
|
||||
super(env);
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(CachingViewLoader.class).in(Singleton.class);
|
||||
bind(KeyStorage.class).in(Singleton.class);
|
||||
bind(KeyRing.class).in(Singleton.class);
|
||||
bind(User.class).in(Singleton.class);
|
||||
bind(Preferences.class).in(Singleton.class);
|
||||
bind(NotificationCenter.class).in(Singleton.class);
|
||||
bind(Clock.class).in(Singleton.class);
|
||||
|
||||
File storageDir = new File(env.getRequiredProperty(Storage.DIR_KEY));
|
||||
bind(File.class).annotatedWith(named(Storage.DIR_KEY)).toInstance(storageDir);
|
||||
|
||||
File keyStorageDir = new File(env.getRequiredProperty(KeyStorage.DIR_KEY));
|
||||
bind(File.class).annotatedWith(named(KeyStorage.DIR_KEY)).toInstance(keyStorageDir);
|
||||
|
||||
bind(BitsquareEnvironment.class).toInstance((BitsquareEnvironment) env);
|
||||
|
||||
// ordering is used for shut down sequence
|
||||
install(tradeModule());
|
||||
install(encryptionServiceModule());
|
||||
install(arbitratorModule());
|
||||
install(offerModule());
|
||||
install(torModule());
|
||||
install(bitcoinModule());
|
||||
install(daoModule());
|
||||
install(guiModule());
|
||||
install(alertModule());
|
||||
install(filterModule());
|
||||
}
|
||||
|
||||
private TradeModule tradeModule() {
|
||||
return new TradeModule(env);
|
||||
}
|
||||
|
||||
private EncryptionServiceModule encryptionServiceModule() {
|
||||
return new EncryptionServiceModule(env);
|
||||
}
|
||||
|
||||
private ArbitratorModule arbitratorModule() {
|
||||
return new ArbitratorModule(env);
|
||||
}
|
||||
|
||||
private AlertModule alertModule() {
|
||||
return new AlertModule(env);
|
||||
}
|
||||
|
||||
private FilterModule filterModule() {
|
||||
return new FilterModule(env);
|
||||
}
|
||||
|
||||
private OfferModule offerModule() {
|
||||
return new OfferModule(env);
|
||||
}
|
||||
|
||||
private P2PModule torModule() {
|
||||
return new P2PModule(env);
|
||||
}
|
||||
|
||||
private BitcoinModule bitcoinModule() {
|
||||
return new BitcoinModule(env);
|
||||
}
|
||||
|
||||
private DaoModule daoModule() {
|
||||
return new DaoModule(env);
|
||||
}
|
||||
|
||||
private GuiModule guiModule() {
|
||||
return new GuiModule(env, primaryStage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.arbitration;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.bitsquare.messages.app.Version;
|
||||
import io.bitsquare.common.crypto.PubKeyRing;
|
||||
import io.bitsquare.common.wire.Payload;
|
||||
import io.bitsquare.common.wire.proto.Messages;
|
||||
import io.bitsquare.messages.trade.payload.Contract;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@EqualsAndHashCode
|
||||
public final class Dispute implements Payload {
|
||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Fields
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private final String tradeId;
|
||||
private final String id;
|
||||
private final int traderId;
|
||||
private final boolean disputeOpenerIsBuyer;
|
||||
private final boolean disputeOpenerIsOfferer;
|
||||
private final long openingDate;
|
||||
private final PubKeyRing traderPubKeyRing;
|
||||
private final long tradeDate;
|
||||
private final Contract contract;
|
||||
private final byte[] contractHash;
|
||||
@Nullable
|
||||
private final byte[] depositTxSerialized;
|
||||
@Nullable
|
||||
private final byte[] payoutTxSerialized;
|
||||
@Nullable
|
||||
private final String depositTxId;
|
||||
@Nullable
|
||||
private final String payoutTxId;
|
||||
private final String contractAsJson;
|
||||
private final String offererContractSignature;
|
||||
private final String takerContractSignature;
|
||||
private final PubKeyRing arbitratorPubKeyRing;
|
||||
private final boolean isSupportTicket;
|
||||
|
||||
private final ArrayList<DisputeCommunicationMessage> disputeCommunicationMessages = new ArrayList<>();
|
||||
|
||||
private boolean isClosed;
|
||||
private DisputeResult disputeResult;
|
||||
@Nullable
|
||||
private String disputePayoutTxId;
|
||||
|
||||
transient private Storage<DisputeList<Dispute>> storage;
|
||||
transient private ObservableList<DisputeCommunicationMessage> disputeCommunicationMessagesAsObservableList = FXCollections.observableArrayList(disputeCommunicationMessages);
|
||||
transient private BooleanProperty isClosedProperty = new SimpleBooleanProperty(isClosed);
|
||||
transient private ObjectProperty<DisputeResult> disputeResultProperty = new SimpleObjectProperty<>(disputeResult);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Dispute(Storage<DisputeList<Dispute>> storage,
|
||||
String tradeId,
|
||||
int traderId,
|
||||
boolean disputeOpenerIsBuyer,
|
||||
boolean disputeOpenerIsOfferer,
|
||||
PubKeyRing traderPubKeyRing,
|
||||
Date tradeDate,
|
||||
Contract contract,
|
||||
byte[] contractHash,
|
||||
@Nullable byte[] depositTxSerialized,
|
||||
@Nullable byte[] payoutTxSerialized,
|
||||
@Nullable String depositTxId,
|
||||
@Nullable String payoutTxId,
|
||||
String contractAsJson,
|
||||
String offererContractSignature,
|
||||
String takerContractSignature,
|
||||
PubKeyRing arbitratorPubKeyRing,
|
||||
boolean isSupportTicket) {
|
||||
this.storage = storage;
|
||||
this.tradeId = tradeId;
|
||||
this.traderId = traderId;
|
||||
this.disputeOpenerIsBuyer = disputeOpenerIsBuyer;
|
||||
this.disputeOpenerIsOfferer = disputeOpenerIsOfferer;
|
||||
this.traderPubKeyRing = traderPubKeyRing;
|
||||
this.tradeDate = tradeDate.getTime();
|
||||
this.contract = contract;
|
||||
this.contractHash = contractHash;
|
||||
this.depositTxSerialized = depositTxSerialized;
|
||||
this.payoutTxSerialized = payoutTxSerialized;
|
||||
this.depositTxId = depositTxId;
|
||||
this.payoutTxId = payoutTxId;
|
||||
this.contractAsJson = contractAsJson;
|
||||
this.offererContractSignature = offererContractSignature;
|
||||
this.takerContractSignature = takerContractSignature;
|
||||
this.arbitratorPubKeyRing = arbitratorPubKeyRing;
|
||||
this.isSupportTicket = isSupportTicket;
|
||||
this.openingDate = new Date().getTime();
|
||||
|
||||
id = tradeId + "_" + traderId;
|
||||
fillInTransients();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
in.defaultReadObject();
|
||||
fillInTransients();
|
||||
} catch (Throwable t) {
|
||||
log.warn("Cannot be deserialized." + t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void fillInTransients() {
|
||||
disputeCommunicationMessagesAsObservableList = FXCollections.observableArrayList(disputeCommunicationMessages);
|
||||
disputeResultProperty = new SimpleObjectProperty<>(disputeResult);
|
||||
isClosedProperty = new SimpleBooleanProperty(isClosed);
|
||||
}
|
||||
|
||||
public void addDisputeMessage(DisputeCommunicationMessage disputeCommunicationMessage) {
|
||||
if (!disputeCommunicationMessages.contains(disputeCommunicationMessage)) {
|
||||
disputeCommunicationMessages.add(disputeCommunicationMessage);
|
||||
disputeCommunicationMessagesAsObservableList.add(disputeCommunicationMessage);
|
||||
storage.queueUpForSave();
|
||||
} else {
|
||||
log.error("disputeDirectMessage already exists");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// In case we get the object via the network storage is not set as its transient, so we need to set it.
|
||||
public void setStorage(Storage<DisputeList<Dispute>> storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
public void setIsClosed(boolean isClosed) {
|
||||
boolean changed = this.isClosed != isClosed;
|
||||
this.isClosed = isClosed;
|
||||
isClosedProperty.set(isClosed);
|
||||
if (changed)
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
public void setDisputeResult(DisputeResult disputeResult) {
|
||||
boolean changed = this.disputeResult == null || !this.disputeResult.equals(disputeResult);
|
||||
this.disputeResult = disputeResult;
|
||||
disputeResultProperty.set(disputeResult);
|
||||
if (changed)
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
public void setDisputePayoutTxId(String disputePayoutTxId) {
|
||||
boolean changed = this.disputePayoutTxId == null || !this.disputePayoutTxId.equals(disputePayoutTxId);
|
||||
this.disputePayoutTxId = disputePayoutTxId;
|
||||
if (changed)
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTradeId() {
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
public String getShortTradeId() {
|
||||
return tradeId.substring(0, 8);
|
||||
}
|
||||
|
||||
public int getTraderId() {
|
||||
return traderId;
|
||||
}
|
||||
|
||||
public boolean isDisputeOpenerIsBuyer() {
|
||||
return disputeOpenerIsBuyer;
|
||||
}
|
||||
|
||||
public boolean isDisputeOpenerIsOfferer() {
|
||||
return disputeOpenerIsOfferer;
|
||||
}
|
||||
|
||||
public Date getOpeningDate() {
|
||||
return new Date(openingDate);
|
||||
}
|
||||
|
||||
public PubKeyRing getTraderPubKeyRing() {
|
||||
return traderPubKeyRing;
|
||||
}
|
||||
|
||||
public Contract getContract() {
|
||||
return contract;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getDepositTxSerialized() {
|
||||
return depositTxSerialized;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getPayoutTxSerialized() {
|
||||
return payoutTxSerialized;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDepositTxId() {
|
||||
return depositTxId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPayoutTxId() {
|
||||
return payoutTxId;
|
||||
}
|
||||
|
||||
public String getContractAsJson() {
|
||||
return contractAsJson;
|
||||
}
|
||||
|
||||
public String getOffererContractSignature() {
|
||||
return offererContractSignature;
|
||||
}
|
||||
|
||||
public String getTakerContractSignature() {
|
||||
return takerContractSignature;
|
||||
}
|
||||
|
||||
public ObservableList<DisputeCommunicationMessage> getDisputeCommunicationMessagesAsObservableList() {
|
||||
return disputeCommunicationMessagesAsObservableList;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return isClosedProperty.get();
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty isClosedProperty() {
|
||||
return isClosedProperty;
|
||||
}
|
||||
|
||||
public PubKeyRing getArbitratorPubKeyRing() {
|
||||
return arbitratorPubKeyRing;
|
||||
}
|
||||
|
||||
public ObjectProperty<DisputeResult> disputeResultProperty() {
|
||||
return disputeResultProperty;
|
||||
}
|
||||
|
||||
public boolean isSupportTicket() {
|
||||
return isSupportTicket;
|
||||
}
|
||||
|
||||
public byte[] getContractHash() {
|
||||
return contractHash;
|
||||
}
|
||||
|
||||
public Date getTradeDate() {
|
||||
return new Date(tradeDate);
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
public String getDisputePayoutTxId() {
|
||||
return disputePayoutTxId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Dispute{" +
|
||||
"tradeId='" + tradeId + '\'' +
|
||||
", id='" + id + '\'' +
|
||||
", traderId=" + traderId +
|
||||
", disputeOpenerIsBuyer=" + disputeOpenerIsBuyer +
|
||||
", disputeOpenerIsOfferer=" + disputeOpenerIsOfferer +
|
||||
", openingDate=" + openingDate +
|
||||
", traderPubKeyRing=" + traderPubKeyRing +
|
||||
", tradeDate=" + tradeDate +
|
||||
", contract=" + contract +
|
||||
", contractHash=" + Arrays.toString(contractHash) +
|
||||
", depositTxSerialized=" + Arrays.toString(depositTxSerialized) +
|
||||
", payoutTxSerialized=" + Arrays.toString(payoutTxSerialized) +
|
||||
", depositTxId='" + depositTxId + '\'' +
|
||||
", payoutTxId='" + payoutTxId + '\'' +
|
||||
", contractAsJson='" + contractAsJson + '\'' +
|
||||
", offererContractSignature='" + offererContractSignature + '\'' +
|
||||
", takerContractSignature='" + takerContractSignature + '\'' +
|
||||
", arbitratorPubKeyRing=" + arbitratorPubKeyRing +
|
||||
", isSupportTicket=" + isSupportTicket +
|
||||
", disputeCommunicationMessages=" + disputeCommunicationMessages +
|
||||
", isClosed=" + isClosed +
|
||||
", disputeResult=" + disputeResult +
|
||||
", disputePayoutTxId='" + disputePayoutTxId + '\'' +
|
||||
", disputeCommunicationMessagesAsObservableList=" + disputeCommunicationMessagesAsObservableList +
|
||||
", isClosedProperty=" + isClosedProperty +
|
||||
", disputeResultProperty=" + disputeResultProperty +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public Messages.ProtectedMailboxStorageEntry toProtoBuf() {
|
||||
return Messages.Dispute.newBuilder().setTradeId(tradeId)
|
||||
.setId(id)
|
||||
.setTraderId(traderId)
|
||||
.setDisputeOpenerIsBuyer(disputeOpenerIsBuyer)
|
||||
.setDisputeOpenerIsOfferer(disputeOpenerIsOfferer)
|
||||
.setOpeningDate(openingDate)
|
||||
.setTraderPubKeyRing(traderPubKeyRing.toProtoBuf())
|
||||
.setTradeDate(tradeDate)
|
||||
.setContract(contract.toProtoBuf())
|
||||
.setContractHash(ByteString.copyFrom(contractHash))
|
||||
.setDepositTxSerialized(ByteString.copyFrom(depositTxSerialized))
|
||||
.setPayoutTxId(payoutTxId)
|
||||
.setDepositTxId(depositTxId)
|
||||
.setPayoutTxId(payoutTxId)
|
||||
.setContractAsJson(contractAsJson)
|
||||
.setOffererContractSignature(offererContractSignature)
|
||||
.setTakerContractSignature(takerContractSignature)
|
||||
.setArbitratorPubKeyRing(arbitratorPubKeyRing.toProtoBuf())
|
||||
.setIsSupportTicket(isSupportTicket)
|
||||
.addAllDisputeCommunicationMessages(disputeCommunicationMessages.stream().map(disputeCommunicationMessage -> disputeCommunicationMessage.toProtoBuf().getDisputeCommunicationMessage()).collect(Collectors.toList()))
|
||||
.setIsClosed(isClosed)
|
||||
.setDisputeResult((Messages.DisputeResult) disputeResult.toProtoBuf())
|
||||
.setDisputePayoutTxId(disputePayoutTxId).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.arbitration;
|
||||
|
||||
import io.bitsquare.messages.app.Version;
|
||||
import io.bitsquare.messages.arbitration.payload.Attachment;
|
||||
import io.bitsquare.common.util.ProtoBufferUtils;
|
||||
import io.bitsquare.common.wire.proto.Messages;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class DisputeCommunicationMessage extends DisputeMessage {
|
||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
|
||||
private static final Logger log = LoggerFactory.getLogger(DisputeCommunicationMessage.class);
|
||||
|
||||
private final long date;
|
||||
private final String tradeId;
|
||||
|
||||
private final int traderId;
|
||||
private final boolean senderIsTrader;
|
||||
private final String message;
|
||||
private final ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
private boolean arrived;
|
||||
private boolean storedInMailbox;
|
||||
private boolean isSystemMessage;
|
||||
private final NodeAddress myNodeAddress;
|
||||
|
||||
transient private BooleanProperty arrivedProperty = new SimpleBooleanProperty();
|
||||
transient private BooleanProperty storedInMailboxProperty = new SimpleBooleanProperty();
|
||||
|
||||
public DisputeCommunicationMessage(String tradeId, int traderId, boolean senderIsTrader, String message,
|
||||
NodeAddress myNodeAddress, long date, boolean arrived, boolean storedInMailbox) {
|
||||
this.tradeId = tradeId;
|
||||
this.traderId = traderId;
|
||||
this.senderIsTrader = senderIsTrader;
|
||||
this.message = message;
|
||||
this.myNodeAddress = myNodeAddress;
|
||||
this.date = date;
|
||||
this.arrived = arrived;
|
||||
this.storedInMailbox = storedInMailbox;
|
||||
updateBooleanProperties();
|
||||
}
|
||||
|
||||
public DisputeCommunicationMessage(String tradeId, int traderId, boolean senderIsTrader, String message,
|
||||
NodeAddress myNodeAddress) {
|
||||
this(tradeId, traderId, senderIsTrader, message, myNodeAddress, new Date().getTime(), false, false);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
in.defaultReadObject();
|
||||
updateBooleanProperties();
|
||||
} catch (Throwable t) {
|
||||
log.warn("Cannot be deserialized." + t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBooleanProperties() {
|
||||
arrivedProperty = new SimpleBooleanProperty(arrived);
|
||||
storedInMailboxProperty = new SimpleBooleanProperty(storedInMailbox);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NodeAddress getSenderNodeAddress() {
|
||||
return myNodeAddress;
|
||||
}
|
||||
|
||||
public void addAttachment(Attachment attachment) {
|
||||
attachments.add(attachment);
|
||||
}
|
||||
|
||||
public void addAllAttachments(List<Attachment> attachments) {
|
||||
this.attachments.addAll(attachments);
|
||||
}
|
||||
|
||||
public void setArrived(boolean arrived) {
|
||||
this.arrived = arrived;
|
||||
this.arrivedProperty.set(arrived);
|
||||
}
|
||||
|
||||
public void setStoredInMailbox(boolean storedInMailbox) {
|
||||
this.storedInMailbox = storedInMailbox;
|
||||
this.storedInMailboxProperty.set(storedInMailbox);
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return new Date(date);
|
||||
}
|
||||
|
||||
public boolean isSenderIsTrader() {
|
||||
return senderIsTrader;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getTraderId() {
|
||||
return traderId;
|
||||
}
|
||||
|
||||
public BooleanProperty arrivedProperty() {
|
||||
return arrivedProperty;
|
||||
}
|
||||
|
||||
public BooleanProperty storedInMailboxProperty() {
|
||||
return storedInMailboxProperty;
|
||||
}
|
||||
|
||||
public List<Attachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
public String getTradeId() {
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
public boolean isSystemMessage() {
|
||||
return isSystemMessage;
|
||||
}
|
||||
|
||||
public void setIsSystemMessage(boolean isSystemMessage) {
|
||||
this.isSystemMessage = isSystemMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof DisputeCommunicationMessage)) return false;
|
||||
|
||||
DisputeCommunicationMessage that = (DisputeCommunicationMessage) o;
|
||||
|
||||
if (date != that.date) return false;
|
||||
if (traderId != that.traderId) return false;
|
||||
if (senderIsTrader != that.senderIsTrader) return false;
|
||||
if (arrived != that.arrived) return false;
|
||||
if (storedInMailbox != that.storedInMailbox) return false;
|
||||
if (isSystemMessage != that.isSystemMessage) return false;
|
||||
if (tradeId != null ? !tradeId.equals(that.tradeId) : that.tradeId != null) return false;
|
||||
if (message != null ? !message.equals(that.message) : that.message != null) return false;
|
||||
if (attachments != null ? !attachments.equals(that.attachments) : that.attachments != null) return false;
|
||||
return !(myNodeAddress != null ? !myNodeAddress.equals(that.myNodeAddress) : that.myNodeAddress != null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (date ^ (date >>> 32));
|
||||
result = 31 * result + (tradeId != null ? tradeId.hashCode() : 0);
|
||||
result = 31 * result + traderId;
|
||||
result = 31 * result + (senderIsTrader ? 1 : 0);
|
||||
result = 31 * result + (message != null ? message.hashCode() : 0);
|
||||
result = 31 * result + (attachments != null ? attachments.hashCode() : 0);
|
||||
result = 31 * result + (arrived ? 1 : 0);
|
||||
result = 31 * result + (storedInMailbox ? 1 : 0);
|
||||
result = 31 * result + (isSystemMessage ? 1 : 0);
|
||||
result = 31 * result + (myNodeAddress != null ? myNodeAddress.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DisputeDirectMessage{" +
|
||||
"date=" + date +
|
||||
", tradeId='" + tradeId + '\'' +
|
||||
", traderId='" + traderId + '\'' +
|
||||
", senderIsTrader=" + senderIsTrader +
|
||||
", message='" + message + '\'' +
|
||||
", attachments=" + attachments +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public Messages.Envelope toProtoBuf() {
|
||||
Messages.Envelope.Builder baseEnvelope = ProtoBufferUtils.getBaseEnvelope();
|
||||
return baseEnvelope.setDisputeCommunicationMessage(Messages.DisputeCommunicationMessage.newBuilder()
|
||||
.setDate(date)
|
||||
.setTradeId(tradeId)
|
||||
.setTraderId(traderId)
|
||||
.setSenderIsTrader(senderIsTrader)
|
||||
.setMessage(message)
|
||||
.addAllAttachments(attachments.stream().map(attachment -> attachment.toProtoBuf()).collect(Collectors.toList()))
|
||||
.setArrived(arrived)
|
||||
.setStoredInMailbox(storedInMailbox)
|
||||
.setIsSystemMessage(isSystemMessage)
|
||||
.setMyNodeAddress(myNodeAddress.toProtoBuf())).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.messages.locale;
|
||||
|
||||
import io.bitsquare.messages.app.Version;
|
||||
import io.bitsquare.common.persistance.Persistable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class TradeCurrency implements Persistable, Comparable<TradeCurrency> {
|
||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
|
||||
|
||||
protected final String code;
|
||||
protected final String name;
|
||||
protected String symbol;
|
||||
|
||||
|
||||
public TradeCurrency(String code) {
|
||||
this.code = code;
|
||||
this.name = CurrencyUtil.getNameByCode(code);
|
||||
}
|
||||
|
||||
protected TradeCurrency(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TradeCurrency(String code, String name, String symbol) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public String getDisplayPrefix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getNameAndCode() {
|
||||
return name + " (" + code + ")";
|
||||
}
|
||||
|
||||
public String getCodeAndName() {
|
||||
return code + " (" + name + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull TradeCurrency other) {
|
||||
return this.getName().compareTo(other.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof TradeCurrency)) return false;
|
||||
|
||||
TradeCurrency that = (TradeCurrency) o;
|
||||
|
||||
return !(getCode() != null ? !getCode().equals(that.getCode()) : that.getCode() != null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getCode() != null ? getCode().hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TradeCurrency{" +
|
||||
"code='" + code + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", symbol='" + symbol + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue