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;