diff --git a/pom.xml b/pom.xml
index ec25577..e670832 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
com.github.informatik-ag-ngl
envoy-common
- develop-SNAPSHOT
+ v0.2-alpha
diff --git a/src/main/java/envoy/client/Settings.java b/src/main/java/envoy/client/data/Settings.java
similarity index 99%
rename from src/main/java/envoy/client/Settings.java
rename to src/main/java/envoy/client/data/Settings.java
index c921605..8cf0283 100644
--- a/src/main/java/envoy/client/Settings.java
+++ b/src/main/java/envoy/client/data/Settings.java
@@ -1,4 +1,4 @@
-package envoy.client;
+package envoy.client.data;
import java.io.File;
import java.io.IOException;
@@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.prefs.Preferences;
-import envoy.client.data.Config;
import envoy.client.ui.Color;
import envoy.client.ui.Theme;
import envoy.util.SerializationUtils;
diff --git a/src/main/java/envoy/client/SettingsItem.java b/src/main/java/envoy/client/data/SettingsItem.java
similarity index 99%
rename from src/main/java/envoy/client/SettingsItem.java
rename to src/main/java/envoy/client/data/SettingsItem.java
index 4de2a47..57ba600 100644
--- a/src/main/java/envoy/client/SettingsItem.java
+++ b/src/main/java/envoy/client/data/SettingsItem.java
@@ -1,4 +1,4 @@
-package envoy.client;
+package envoy.client.data;
import java.io.Serializable;
import java.util.HashMap;
diff --git a/src/main/java/envoy/client/event/HandshakeSuccessfulEvent.java b/src/main/java/envoy/client/event/HandshakeSuccessfulEvent.java
new file mode 100644
index 0000000..9cafa48
--- /dev/null
+++ b/src/main/java/envoy/client/event/HandshakeSuccessfulEvent.java
@@ -0,0 +1,18 @@
+package envoy.client.event;
+
+import envoy.event.Event;
+
+/**
+ * This {@link Event} indicates that a handshake was completed successfully.
+ *
+ * Project: envoy-client
+ * File: HandshakeSuccessfulEvent.java
+ * Created: 8 Feb 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy v0.3-alpha
+ */
+public class HandshakeSuccessfulEvent extends Event.Valueless {
+
+ private static final long serialVersionUID = -157972384126278855L;
+}
diff --git a/src/main/java/envoy/client/net/Client.java b/src/main/java/envoy/client/net/Client.java
index 8a62925..b404807 100644
--- a/src/main/java/envoy/client/net/Client.java
+++ b/src/main/java/envoy/client/net/Client.java
@@ -42,6 +42,7 @@ public class Client implements Closeable {
// Asynchronously initialized during handshake
private volatile User sender;
private volatile Contacts contacts;
+ private volatile boolean rejected;
// Configuration and logging
private static final Config config = Config.getInstance();
@@ -54,16 +55,19 @@ public class Client implements Closeable {
* an exception is thrown.
*
* @param credentials the login credentials of the user
- * @param localDb the local database used to persist the current
- * {@link IdGenerator}
* @param receivedMessageCache a message cache containing all unread messages
* from the server that can be relayed after
* initialization
- * @throws Exception if the online mode could not be entered or the request
- * failed for some other reason
- * @since Envoy v0.2-alpha
+ * @throws TimeLimitExceededException if the server could not be reached
+ * @throws IOException if the login credentials could not be
+ * written
+ * @throws InterruptedException if the current thread is interrupted while
+ * waiting for the handshake response
*/
- public void onlineInit(LoginCredentials credentials, LocalDb localDb, Cache receivedMessageCache) throws Exception {
+ public void performHandshake(LoginCredentials credentials, Cache receivedMessageCache)
+ throws TimeLimitExceededException, IOException, InterruptedException {
+ if (online) throw new IllegalStateException("Handshake has already been performed successfully");
+
// Establish TCP connection
logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
socket = new Socket(config.getServer(), config.getPort());
@@ -76,6 +80,9 @@ public class Client implements Closeable {
receiver.registerProcessor(User.class, sender -> { logger.info("Acquired user object " + sender); this.sender = sender; });
receiver.registerProcessor(Contacts.class, contacts -> { logger.info("Acquired contacts object " + contacts); this.contacts = contacts; });
receiver.registerProcessor(Message.class, receivedMessageCache);
+ receiver.registerProcessor(HandshakeRejectionEvent.class, evt -> { rejected = true; EventBus.getInstance().dispatch(evt); });
+
+ rejected = false;
// Start receiver
new Thread(receiver).start();
@@ -87,6 +94,15 @@ public class Client implements Closeable {
// Wait for a maximum of five seconds to acquire the sender object
long start = System.currentTimeMillis();
while (sender == null || contacts == null) {
+
+ // Quit immediately after handshake rejection
+ // This method can then be called again
+ if (rejected) {
+ socket.close();
+ receiver.removeAllProcessors();
+ return;
+ }
+
if (System.currentTimeMillis() - start > 5000) throw new TimeLimitExceededException("Did not log in after 5 seconds");
Thread.sleep(500);
}
@@ -96,8 +112,23 @@ public class Client implements Closeable {
// Remove user creation processor
receiver.removeAllProcessors();
+ }
- // Register processors for message and status handling
+ /**
+ * Initializes the {@link Receiver} used to process data sent from the server to
+ * this client.
+ *
+ * @param localDb the local database used to persist the current
+ * {@link IdGenerator}
+ * @param receivedMessageCache a message cache containing all unread messages
+ * from the server that can be relayed after
+ * initialization
+ * @throws IOException if no {@link IdGenerator} is present and none could be
+ * requested from the server
+ * @since Envoy v0.2-alpha
+ */
+ public void initReceiver(LocalDb localDb, Cache receivedMessageCache) throws IOException {
+ checkOnline();
// Process incoming messages
final ReceivedMessageProcessor receivedMessageProcessor = new ReceivedMessageProcessor();
diff --git a/src/main/java/envoy/client/net/Receiver.java b/src/main/java/envoy/client/net/Receiver.java
index 25e7153..d8a0d45 100644
--- a/src/main/java/envoy/client/net/Receiver.java
+++ b/src/main/java/envoy/client/net/Receiver.java
@@ -51,7 +51,7 @@ public class Receiver implements Runnable {
try (ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(objBytes))) {
Object obj = oin.readObject();
- logger.finest("Received object " + obj);
+ logger.info("Received object " + obj);
// Get appropriate processor
@SuppressWarnings("rawtypes")
diff --git a/src/main/java/envoy/client/ui/ChatWindow.java b/src/main/java/envoy/client/ui/ChatWindow.java
index 5aa18c5..045bf9c 100644
--- a/src/main/java/envoy/client/ui/ChatWindow.java
+++ b/src/main/java/envoy/client/ui/ChatWindow.java
@@ -12,9 +12,9 @@ import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
-import envoy.client.Settings;
import envoy.client.data.Chat;
import envoy.client.data.LocalDb;
+import envoy.client.data.Settings;
import envoy.client.event.MessageCreationEvent;
import envoy.client.event.ThemeChangeEvent;
import envoy.client.net.Client;
diff --git a/src/main/java/envoy/client/ui/ContactsSearchRenderer.java b/src/main/java/envoy/client/ui/ContactsSearchRenderer.java
index f206c54..92f5204 100644
--- a/src/main/java/envoy/client/ui/ContactsSearchRenderer.java
+++ b/src/main/java/envoy/client/ui/ContactsSearchRenderer.java
@@ -6,7 +6,7 @@ import java.awt.Font;
import javax.swing.*;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.client.event.SendEvent;
import envoy.client.ui.list.ComponentList;
import envoy.client.ui.list.ComponentListCellRenderer;
diff --git a/src/main/java/envoy/client/ui/LoginDialog.java b/src/main/java/envoy/client/ui/LoginDialog.java
index d8cd4ff..09fd551 100644
--- a/src/main/java/envoy/client/ui/LoginDialog.java
+++ b/src/main/java/envoy/client/ui/LoginDialog.java
@@ -2,40 +2,52 @@ package envoy.client.ui;
import java.awt.*;
import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
+import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
+import java.util.logging.Logger;
+import javax.naming.TimeLimitExceededException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
-import envoy.client.Settings;
+import envoy.client.data.*;
+import envoy.client.event.HandshakeSuccessfulEvent;
+import envoy.client.net.Client;
+import envoy.client.util.EnvoyLog;
import envoy.data.LoginCredentials;
+import envoy.data.Message;
+import envoy.data.User;
+import envoy.event.EventBus;
+import envoy.event.HandshakeRejectionEvent;
+import envoy.exception.EnvoyException;
/**
* Project: envoy-client
* File: LoginDialog.java
* Created: 01.01.2020
- *
+ *
* @author Kai S. K. Engelbart
* @author Maximilian Käfer
* @since Envoy v0.3-alpha
*/
public class LoginDialog extends JDialog {
- private final JPanel contentPanel;
- private JTextField textField;
- private JPasswordField passwordField;
- private JPasswordField repeatPasswordField;
+ private JPanel contentPanel;
+ private JTextField textField;
+ private JPasswordField passwordField;
+ private JPasswordField repeatPasswordField;
private JLabel lblUserName;
private JLabel lblPassword;
private JLabel lblRepeatPassword;
+ private JLabel errorMessage;
private GridBagConstraints gbc_lblRepeatPassword;
private GridBagConstraints gbc_repeatPasswordField;
+ private GridBagConstraints gbc_errorMessage;
- private JPanel buttonPane;
+ private JPanel buttonPane;
private JTextPane registerText;
private JCheckBox registerCheckBox;
private PrimaryButton okButton;
@@ -43,15 +55,101 @@ public class LoginDialog extends JDialog {
private LoginCredentials credentials;
- private static final long serialVersionUID = 352021600833907468L;
+ private final Client client;
+ private final LocalDb localDb;
+ private final Cache receivedMessageCache;
+
+ private static final Config config = Config.getInstance();
+ private static final Logger logger = EnvoyLog.getLogger(LoginDialog.class.getSimpleName());
+ private static final long serialVersionUID = 352021600833907468L;
+
/**
* Displays a dialog enabling the user to enter their user name and password.
- *
+ *
+ * @param client the client used to perform the handshake
+ * @param localDb the local database in which data is persisted
+ * @param receivedMessageCache the cache that stored messages received during
+ * the handshake
* @since Envoy v0.3-alpha
*/
- public LoginDialog() {
+ public LoginDialog(Client client, LocalDb localDb, Cache receivedMessageCache) {
+ this.client = client;
+ this.localDb = localDb;
+ this.receivedMessageCache = receivedMessageCache;
+
+ // Prepare handshake
+ localDb.loadIdGenerator();
+
+ initUi();
+
+ okButton.addActionListener((evt) -> {
+ try {
+ if (registerCheckBox.isSelected()) {
+ // Check password equality
+ if (Arrays.equals(passwordField.getPassword(), repeatPasswordField.getPassword()))
+ credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), true);
+ else {
+ JOptionPane.showMessageDialog(this, "The repeated password is not the origional password!");
+ clearPasswordFields();
+ }
+ } else credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), false);
+ performHandshake();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ });
+
+ // Listen to handshake rejections
+ EventBus.getInstance()
+ .register(HandshakeRejectionEvent.class,
+ evt -> { clearPasswordFields(); errorMessage.setVisible(true); errorMessage.setText(evt.get()); });
+
+ // Exit the application when the dialog is cancelled
+ cancelButton.addActionListener(evt -> { logger.info("The login process has been cancelled. Exiting..."); System.exit(0); });
+
+ // Log in directly if configured
+ if (config.hasLoginCredentials()) {
+ credentials = config.getLoginCredentials();
+ performHandshake();
+ return;
+ }
+
+ setVisible(true);
+ }
+
+ private void performHandshake() {
+ try {
+ client.performHandshake(credentials, receivedMessageCache);
+ if (client.isOnline()) {
+ client.initReceiver(localDb, receivedMessageCache);
+ dispose();
+ }
+ } catch (IOException | InterruptedException | TimeLimitExceededException e) {
+ logger.warning("Could not connect to server. Trying offline mode...");
+ e.printStackTrace();
+ try {
+ // Try entering offline mode
+ localDb.loadUsers();
+ User clientUser = localDb.getUsers().get(credentials.getIdentifier());
+ if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
+ client.setSender(clientUser);
+ JOptionPane.showMessageDialog(null,
+ "A connection to the server could not be established. Starting in offline mode.\n" + e,
+ "Connection error",
+ JOptionPane.WARNING_MESSAGE);
+ dispose();
+ } catch (Exception e1) {
+ JOptionPane.showMessageDialog(null, e1, "Client error", JOptionPane.ERROR_MESSAGE);
+ System.exit(1);
+ return;
+ }
+ }
+ }
+
+ private void initUi() {
setSize(338, 123);
setLocationRelativeTo(null);
+ setResizable(false);
getContentPane().setLayout(new BorderLayout());
contentPanel = new JPanel();
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
@@ -62,137 +160,121 @@ public class LoginDialog extends JDialog {
gbl_contentPanel.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
gbl_contentPanel.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
contentPanel.setLayout(gbl_contentPanel);
- {
- lblUserName = new JLabel("Username:");
- GridBagConstraints gbc_lblUserName = new GridBagConstraints();
- gbc_lblUserName.anchor = GridBagConstraints.EAST;
- gbc_lblUserName.insets = new Insets(0, 0, 5, 5);
- gbc_lblUserName.gridx = 0;
- gbc_lblUserName.gridy = 0;
- contentPanel.add(lblUserName, gbc_lblUserName);
- }
- {
- textField = new JTextField();
- textField.setBorder(null);
- GridBagConstraints gbc_textField = new GridBagConstraints();
- gbc_textField.insets = new Insets(0, 0, 5, 0);
- gbc_textField.fill = GridBagConstraints.HORIZONTAL;
- gbc_textField.gridx = 1;
- gbc_textField.gridy = 0;
- contentPanel.add(textField, gbc_textField);
- textField.setColumns(10);
- }
- {
- lblPassword = new JLabel("Password:");
- GridBagConstraints gbc_lblPassword = new GridBagConstraints();
- gbc_lblPassword.anchor = GridBagConstraints.EAST;
- gbc_lblPassword.insets = new Insets(0, 0, 0, 5);
- gbc_lblPassword.gridx = 0;
- gbc_lblPassword.gridy = 1;
- contentPanel.add(lblPassword, gbc_lblPassword);
- }
- {
- passwordField = new JPasswordField();
- passwordField.setBorder(null);
- GridBagConstraints gbc_passwordField = new GridBagConstraints();
- gbc_passwordField.fill = GridBagConstraints.HORIZONTAL;
- gbc_passwordField.gridx = 1;
- gbc_passwordField.gridy = 1;
- contentPanel.add(passwordField, gbc_passwordField);
- }
- {
- lblRepeatPassword = new JLabel("Repeat Password:");
- gbc_lblRepeatPassword = new GridBagConstraints();
- gbc_lblRepeatPassword.anchor = GridBagConstraints.EAST;
- gbc_lblRepeatPassword.insets = new Insets(0, 0, 0, 5);
- gbc_lblRepeatPassword.gridx = 0;
- gbc_lblRepeatPassword.gridy = 2;
- }
- {
- repeatPasswordField = new JPasswordField();
- repeatPasswordField.setBorder(null);
- gbc_repeatPasswordField = new GridBagConstraints();
- gbc_repeatPasswordField.fill = GridBagConstraints.HORIZONTAL;
- gbc_repeatPasswordField.gridx = 1;
- gbc_repeatPasswordField.gridy = 2;
- }
- {
- buttonPane = new JPanel();
- registerText = new JTextPane();
- registerText.setEditable(false);
- registerText.setText("Register?");
- registerText.setFont(new Font("Arial", Font.BOLD, 12));
- registerText.setAlignmentX(LEFT_ALIGNMENT);
- buttonPane.add(registerText);
+ lblUserName = new JLabel("Username:");
+ GridBagConstraints gbc_lblUserName = new GridBagConstraints();
+ gbc_lblUserName.anchor = GridBagConstraints.EAST;
+ gbc_lblUserName.insets = new Insets(0, 0, 5, 5);
+ gbc_lblUserName.gridx = 0;
+ gbc_lblUserName.gridy = 0;
+ contentPanel.add(lblUserName, gbc_lblUserName);
- registerCheckBox = new JCheckBox();
- registerCheckBox.setAlignmentX(LEFT_ALIGNMENT);
- registerCheckBox.addItemListener(new ItemListener() {
+ textField = new JTextField();
+ textField.setBorder(null);
+ GridBagConstraints gbc_textField = new GridBagConstraints();
+ gbc_textField.insets = new Insets(0, 0, 5, 0);
+ gbc_textField.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textField.gridx = 1;
+ gbc_textField.gridy = 0;
+ contentPanel.add(textField, gbc_textField);
+ textField.setColumns(10);
- @Override
- public void itemStateChanged(ItemEvent e) {
- switch (e.getStateChange()) {
- case ItemEvent.SELECTED:
- contentPanel.add(lblRepeatPassword, gbc_lblRepeatPassword);
- contentPanel.add(repeatPasswordField, gbc_repeatPasswordField);
- setSize(338, 148);
- contentPanel.revalidate();
- contentPanel.repaint();
- break;
+ lblPassword = new JLabel("Password:");
+ GridBagConstraints gbc_lblPassword = new GridBagConstraints();
+ gbc_lblPassword.anchor = GridBagConstraints.EAST;
+ gbc_lblPassword.insets = new Insets(0, 0, 0, 5);
+ gbc_lblPassword.gridx = 0;
+ gbc_lblPassword.gridy = 1;
+ contentPanel.add(lblPassword, gbc_lblPassword);
- case ItemEvent.DESELECTED:
- if (repeatPasswordField.getParent() == contentPanel) {
- contentPanel.remove(lblRepeatPassword);
- contentPanel.remove(repeatPasswordField);
- setSize(338, 123);
- contentPanel.revalidate();
- contentPanel.repaint();
- }
- break;
+ passwordField = new JPasswordField();
+ passwordField.setBorder(null);
+ GridBagConstraints gbc_passwordField = new GridBagConstraints();
+ gbc_passwordField.fill = GridBagConstraints.HORIZONTAL;
+ gbc_passwordField.gridx = 1;
+ gbc_passwordField.gridy = 1;
+ contentPanel.add(passwordField, gbc_passwordField);
+
+ lblRepeatPassword = new JLabel("Repeat Password:");
+ gbc_lblRepeatPassword = new GridBagConstraints();
+ gbc_lblRepeatPassword.anchor = GridBagConstraints.EAST;
+ gbc_lblRepeatPassword.insets = new Insets(0, 0, 0, 5);
+ gbc_lblRepeatPassword.gridx = 0;
+ gbc_lblRepeatPassword.gridy = 2;
+
+ repeatPasswordField = new JPasswordField();
+ gbc_repeatPasswordField = new GridBagConstraints();
+ gbc_repeatPasswordField.fill = GridBagConstraints.HORIZONTAL;
+ gbc_repeatPasswordField.gridx = 1;
+ gbc_repeatPasswordField.gridy = 2;
+
+ errorMessage = new JLabel();
+ gbc_errorMessage = new GridBagConstraints();
+ gbc_errorMessage.gridx = 1;
+ gbc_errorMessage.gridy = 3;
+ gbc_errorMessage.fill = GridBagConstraints.HORIZONTAL;
+ gbc_errorMessage.insets = new Insets(5, 5, 5, 5);
+ errorMessage.setForeground(Color.RED);
+ errorMessage.setVisible(false);
+ contentPanel.add(errorMessage, gbc_errorMessage);
+
+ buttonPane = new JPanel();
+
+ registerText = new JTextPane();
+ registerText.setEditable(false);
+ registerText.setText("Register?");
+ registerText.setFont(new Font("Arial", Font.BOLD, 12));
+ registerText.setAlignmentX(LEFT_ALIGNMENT);
+ buttonPane.add(registerText);
+
+ registerCheckBox = new JCheckBox();
+ registerCheckBox.setAlignmentX(LEFT_ALIGNMENT);
+ registerCheckBox.addItemListener(e -> {
+ switch (e.getStateChange()) {
+ case ItemEvent.SELECTED:
+ contentPanel.add(lblRepeatPassword, gbc_lblRepeatPassword);
+ contentPanel.add(repeatPasswordField, gbc_repeatPasswordField);
+ setSize(338, 173);
+ break;
+
+ case ItemEvent.DESELECTED:
+ if (repeatPasswordField.getParent() == contentPanel) {
+ contentPanel.remove(lblRepeatPassword);
+ contentPanel.remove(repeatPasswordField);
+ setSize(338, 148);
}
- }
- });
- buttonPane.add(registerCheckBox);
+ break;
+ }
+ contentPanel.revalidate();
+ contentPanel.repaint();
+ });
+ buttonPane.add(registerCheckBox);
- buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
- getContentPane().add(buttonPane, BorderLayout.SOUTH);
- {
- okButton = new PrimaryButton("OK");
- okButton.addActionListener((evt) -> {
- try {
- if (registerCheckBox.isSelected()) {
- if (Arrays.equals(passwordField.getPassword(), repeatPasswordField.getPassword())) {
- credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), true);
- dispose();
- } else {
- JOptionPane.showMessageDialog(this, "The repeated password is unequal to the origional password!");
- passwordField.setText(null);
- repeatPasswordField.setText(null);
- }
- } else {
- credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), false);
- dispose();
- }
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- });
- okButton.setActionCommand("OK");
- buttonPane.add(okButton);
- getRootPane().setDefaultButton(okButton);
- }
- {
- cancelButton = new PrimaryButton("Cancel");
- cancelButton.addActionListener((evt) -> dispose());
- cancelButton.setActionCommand("Cancel");
- buttonPane.add(cancelButton);
- }
- }
+ buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ getContentPane().add(buttonPane, BorderLayout.SOUTH);
+ okButton = new PrimaryButton("OK");
+ okButton.setActionCommand("OK");
+ buttonPane.add(okButton);
+ getRootPane().setDefaultButton(okButton);
+
+ cancelButton = new PrimaryButton("Cancel");
+ cancelButton.setActionCommand("Cancel");
+ buttonPane.add(cancelButton);
setTheme();
- setModal(true);
- setVisible(true);
+ setModalityType(Dialog.DEFAULT_MODALITY_TYPE);
+
+ EventBus.getInstance().register(HandshakeSuccessfulEvent.class, evt -> dispose());
+ }
+
+ /**
+ * Resets the text stored in the password fields.
+ *
+ * @since Envoy v0.3-alpha
+ */
+ private void clearPasswordFields() {
+ passwordField.setText(null);
+ repeatPasswordField.setText(null);
}
private void setTheme() {
@@ -238,11 +320,4 @@ public class LoginDialog extends JDialog {
cancelButton.setBackground(theme.getInteractableBackgroundColor());
cancelButton.setForeground(theme.getInteractableForegroundColor());
}
-
- /**
- * @return the {@link LoginCredentials} entered by the user, or {@code null} if
- * the dialog has been cancelled
- * @since Envoy v0.3-alpha
- */
- public LoginCredentials getCredentials() { return credentials; }
}
\ No newline at end of file
diff --git a/src/main/java/envoy/client/ui/MessageListRenderer.java b/src/main/java/envoy/client/ui/MessageListRenderer.java
index 65ee63a..a069721 100644
--- a/src/main/java/envoy/client/ui/MessageListRenderer.java
+++ b/src/main/java/envoy/client/ui/MessageListRenderer.java
@@ -5,7 +5,7 @@ import java.text.SimpleDateFormat;
import javax.swing.*;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.client.ui.list.ComponentList;
import envoy.client.ui.list.ComponentListCellRenderer;
import envoy.data.Message;
diff --git a/src/main/java/envoy/client/ui/PrimaryScrollBar.java b/src/main/java/envoy/client/ui/PrimaryScrollBar.java
index a7cb8fc..8e8131c 100644
--- a/src/main/java/envoy/client/ui/PrimaryScrollBar.java
+++ b/src/main/java/envoy/client/ui/PrimaryScrollBar.java
@@ -12,7 +12,7 @@ import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.plaf.basic.BasicScrollBarUI;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
/**
* Project: envoy-client
diff --git a/src/main/java/envoy/client/ui/PrimaryToggleSwitch.java b/src/main/java/envoy/client/ui/PrimaryToggleSwitch.java
index 2882a05..3f58e2e 100644
--- a/src/main/java/envoy/client/ui/PrimaryToggleSwitch.java
+++ b/src/main/java/envoy/client/ui/PrimaryToggleSwitch.java
@@ -5,8 +5,8 @@ import java.awt.Graphics;
import javax.swing.JButton;
-import envoy.client.Settings;
-import envoy.client.SettingsItem;
+import envoy.client.data.Settings;
+import envoy.client.data.SettingsItem;
/**
* This component can be used to toggle between two options. This will change
diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java
index 706e030..5427fe1 100644
--- a/src/main/java/envoy/client/ui/Startup.java
+++ b/src/main/java/envoy/client/ui/Startup.java
@@ -11,14 +11,11 @@ import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
-import envoy.client.Settings;
import envoy.client.data.*;
import envoy.client.net.Client;
import envoy.client.net.WriteProxy;
import envoy.client.util.EnvoyLog;
-import envoy.data.LoginCredentials;
import envoy.data.Message;
-import envoy.data.User;
import envoy.exception.EnvoyException;
/**
@@ -63,7 +60,7 @@ public class Startup {
if (args.length > 0) config.load(args);
// Check if all mandatory configuration values have been initialized
- if (!config.isInitialized()) throw new EnvoyException("Server or port are not defined");
+ if (!config.isInitialized()) throw new EnvoyException("Configuration is not fully initialized");
} catch (Exception e) {
JOptionPane
.showMessageDialog(null, "Error loading configuration values:\n" + e.toString(), "Configuration error", JOptionPane.ERROR_MESSAGE);
@@ -75,14 +72,6 @@ public class Startup {
EnvoyLog.setFileLevelBarrier(config.getFileLevelBarrier());
EnvoyLog.setConsoleLevelBarrier(config.getConsoleLevelBarrier());
- // Acquire login credentials
- LoginCredentials credentials = config.hasLoginCredentials() ? config.getLoginCredentials() : new LoginDialog().getCredentials();
-
- if (credentials == null) {
- logger.info("The login process has been aborted by the user. Exiting...");
- System.exit(0);
- }
-
// Initialize the local database
LocalDb localDb;
if (config.isIgnoreLocalDB()) {
@@ -96,40 +85,18 @@ public class Startup {
} catch (IOException e3) {
logger.log(Level.SEVERE, "Could not initialize local database", e3);
JOptionPane
- .showMessageDialog(null, "Could not initialize local database!\n" + e3.toString(), "Local database error", JOptionPane.ERROR_MESSAGE);
+ .showMessageDialog(null, "Could not initialize local database!\n" + e3, "Local database error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
return;
}
- SwingUtilities.invokeLater(() -> chatWindow.setVisible(true));
-
- // Acquire the client user (with ID) either from the server or from the local
- // database, which triggers offline mode
+ // Initialize client and unread message cache
Client client = new Client();
Cache cache = new Cache<>();
- try {
- // Try entering online mode first
- localDb.loadIdGenerator();
- client.onlineInit(credentials, localDb, cache);
- } catch (Exception e1) {
- logger.warning("Could not connect to server. Trying offline mode...");
- e1.printStackTrace();
- try {
- // Try entering offline mode
- localDb.loadUsers();
- User clientUser = localDb.getUsers().get(credentials.getName());
- if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
- client.setSender(clientUser);
- JOptionPane.showMessageDialog(null,
- "A connection to the server could not be established. Starting in offline mode.\n" + e1,
- "Connection error",
- JOptionPane.WARNING_MESSAGE);
- } catch (Exception e2) {
- JOptionPane.showMessageDialog(null, e2.toString(), "Client error", JOptionPane.ERROR_MESSAGE);
- System.exit(1);
- return;
- }
- }
+
+ // Try to connect to the server
+ new LoginDialog(client, localDb, cache);
+ SwingUtilities.invokeLater(() -> chatWindow.setVisible(true));
// Set client user in local database
localDb.setUser(client.getSender());
diff --git a/src/main/java/envoy/client/ui/UserListRenderer.java b/src/main/java/envoy/client/ui/UserListRenderer.java
index 8c63ad7..c43eeb6 100644
--- a/src/main/java/envoy/client/ui/UserListRenderer.java
+++ b/src/main/java/envoy/client/ui/UserListRenderer.java
@@ -7,7 +7,7 @@ import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.data.User;
import envoy.data.User.UserStatus;
diff --git a/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java b/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java
index adafc2e..a1b5966 100644
--- a/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java
+++ b/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java
@@ -10,8 +10,8 @@ import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JTextPane;
-import envoy.client.Settings;
-import envoy.client.SettingsItem;
+import envoy.client.data.Settings;
+import envoy.client.data.SettingsItem;
import envoy.client.ui.Theme;
import envoy.client.util.EnvoyLog;
diff --git a/src/main/java/envoy/client/ui/settings/NewThemeScreen.java b/src/main/java/envoy/client/ui/settings/NewThemeScreen.java
index 3e259e4..02dd42a 100644
--- a/src/main/java/envoy/client/ui/settings/NewThemeScreen.java
+++ b/src/main/java/envoy/client/ui/settings/NewThemeScreen.java
@@ -7,7 +7,7 @@ import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextPane;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.client.ui.PrimaryButton;
import envoy.client.ui.PrimaryTextArea;
import envoy.client.ui.Theme;
diff --git a/src/main/java/envoy/client/ui/settings/SettingsScreen.java b/src/main/java/envoy/client/ui/settings/SettingsScreen.java
index af68e8e..df2fa2c 100644
--- a/src/main/java/envoy/client/ui/settings/SettingsScreen.java
+++ b/src/main/java/envoy/client/ui/settings/SettingsScreen.java
@@ -9,7 +9,7 @@ import java.util.logging.Logger;
import javax.swing.*;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.client.event.ThemeChangeEvent;
import envoy.client.ui.PrimaryButton;
import envoy.client.ui.Theme;
diff --git a/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java b/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java
index 8df3491..ed4be4f 100644
--- a/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java
+++ b/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java
@@ -9,7 +9,7 @@ import java.util.logging.Logger;
import javax.swing.*;
-import envoy.client.Settings;
+import envoy.client.data.Settings;
import envoy.client.event.ThemeChangeEvent;
import envoy.client.ui.Color;
import envoy.client.ui.Theme;