From 0f64ce0a016e137320a4c3e274d9258524eb9ec9 Mon Sep 17 00:00:00 2001 From: kske Date: Wed, 11 Dec 2019 18:52:30 +0100 Subject: [PATCH] Added offline mode to Client + Saving the user ID in Settings + Loading the user ID from Settings in Client if the server can't be reached --- src/main/java/envoy/client/Client.java | 63 ++++++++++++---------- src/main/java/envoy/client/Settings.java | 25 ++++++--- src/main/java/envoy/client/ui/Startup.java | 21 ++++++-- 3 files changed, 73 insertions(+), 36 deletions(-) diff --git a/src/main/java/envoy/client/Client.java b/src/main/java/envoy/client/Client.java index 8f96739..a6a7f36 100644 --- a/src/main/java/envoy/client/Client.java +++ b/src/main/java/envoy/client/Client.java @@ -10,6 +10,7 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; +import envoy.exception.EnvoyException; import envoy.schema.ObjectFactory; import envoy.schema.Sync; import envoy.schema.User; @@ -29,14 +30,18 @@ public class Client { private ObjectFactory objectFactory = new ObjectFactory(); private Config config; private User sender, recipient; + private boolean online = false; private static final Logger logger = Logger.getLogger(Client.class.getSimpleName()); - public Client(Config config, String username) { + public Client(Config config, String userName) throws EnvoyException { this.config = config; - sender = getUser(username); - - logger.info("ID: " + sender.getID()); + sender = getUser(userName); + + // Update the user ID in the cache + Settings.getInstance().setUserID(sender.getID()); + + logger.info("Client user ID: " + sender.getID()); } private R post(String uri, T body, Class responseBodyClass) { @@ -48,7 +53,6 @@ public class Client { client.close(); return responseBody; - } /** @@ -63,9 +67,7 @@ public class Client { user.setID(-1); sendSync.getUsers().add(user); - Sync returnSendSync = post( - String - .format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), + Sync returnSendSync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), sendSync, Sync.class); return returnSendSync; @@ -77,29 +79,33 @@ public class Client { * * @param name - the name of the {@link User} * @return a {@link User} with the specified name + * @throws EnvoyException if the server does not return the requested ID * @since Envoy v0.1-alpha */ - private User getUser(String name) { + private User getUser(String name) throws EnvoyException { + // Create a sync with only a user with the requested name Sync senderSync = objectFactory.createSync(); User user = objectFactory.createUser(); user.setName(name); senderSync.getUsers().add(user); - Sync returnSenderSync = post( - String - .format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), - senderSync, - Sync.class); + try { + Sync sync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), + senderSync, + Sync.class); - User returnSender = objectFactory.createUser(); - - if (returnSenderSync.getUsers().size() == 1) { - returnSender = returnSenderSync.getUsers().get(0); - } else { - logger.warning("ERROR exiting..."); + // Expecting a single user with an ID + if (sync.getUsers().size() == 1) { + online = true; + return sync.getUsers().get(0); + } else throw new EnvoyException("Unexpected response from Envoy Server"); + } catch (Exception e) { + logger.warning("Could not connect to server, trying offline mode."); + if (Settings.getInstance().getUserID() != -1) { + user.setID(Settings.getInstance().getUserID()); + return user; + } else throw new EnvoyException("Could not enter offline mode."); } - - return returnSender; } /** @@ -134,7 +140,8 @@ public class Client { * their updated UserStatus to the client.)
* * @param userId the id of the {@link Client} who sends the {@link Sync} - * @param sync the sync object (yet to be converted from java class to sync.xml) + * @param sync the sync object (yet to be converted from java class to + * sync.xml) * @return a returnSync.xml file * @since Envoy v0.1-alpha */ @@ -151,10 +158,7 @@ public class Client { } // Send sync - return post(String - .format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), userId), - sync, - Sync.class); + return post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), userId), sync, Sync.class); } /** @@ -182,4 +186,9 @@ public class Client { * @since Envoy v0.1-alpha */ public boolean hasRecipient() { return recipient != null; } + + /** + * @return {@code true} if a connection to the server could be established + */ + public boolean isOnline() { return online; } } diff --git a/src/main/java/envoy/client/Settings.java b/src/main/java/envoy/client/Settings.java index 91f696f..851c936 100644 --- a/src/main/java/envoy/client/Settings.java +++ b/src/main/java/envoy/client/Settings.java @@ -27,6 +27,7 @@ public class Settings { // Actual settings accessible by the rest of the application private String username; + private long userID; private String email; private boolean enterToSend = true; private Map themes; @@ -66,6 +67,7 @@ public class Settings { @SuppressWarnings("unchecked") private void load() { setUsername(prefs.get("username", "")); + setUserID(prefs.getLong("userID", -1)); setEmail(prefs.get("email", "")); setEnterToSend(prefs.getBoolean("enterToSend", true)); setCurrentTheme(prefs.get("theme", "dark")); @@ -73,9 +75,9 @@ public class Settings { // Load themes from theme file try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(themeFile))) { Object obj = in.readObject(); - if(obj instanceof HashMap) themes = (Map) obj; + if (obj instanceof HashMap) themes = (Map) obj; } catch (IOException | ClassNotFoundException e) { - themes = new HashMap<>(); + themes = new HashMap<>(); currentTheme = "dark"; e.printStackTrace(); } @@ -90,20 +92,21 @@ public class Settings { } /** - * updates prefs when save button is clicked + * Updates the preferences when the save button is clicked. * * @throws IOException * @since Envoy v0.2-alpha */ - public void save() throws IOException{ + public void save() throws IOException { prefs.put("username", getUsername()); + prefs.putLong("userID", getUserID()); prefs.put("email", getEmail()); prefs.put("theme", currentTheme); prefs.putBoolean("enterToSend", isEnterToSend()); - + // Save themes to theme file themeFile.createNewFile(); - try(ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(themeFile))) { + try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(themeFile))) { out.writeObject(themes); } } @@ -145,6 +148,16 @@ public class Settings { */ public void setUsername(String username) { this.username = username; } + /** + * @return the userID + */ + public long getUserID() { return userID; } + + /** + * @param userID the userID to set + */ + public void setUserID(long userID) { this.userID = userID; } + /** * @return the email associated with that user. * @since Envoy v0.2-alpha diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java index edd5aa2..c8373ed 100644 --- a/src/main/java/envoy/client/ui/Startup.java +++ b/src/main/java/envoy/client/ui/Startup.java @@ -16,7 +16,7 @@ import envoy.exception.EnvoyException; /** * Starts the Envoy client and prompts the user to enter their name. - * + *
* Project: envoy-client
* File: Startup.java
* Created: 12 Oct 2019
@@ -48,19 +48,34 @@ public class Startup { // Override configuration values with command line arguments if (args.length > 0) config.load(args); + // Check if all configuration values have been initialized if (!config.isInitialized()) { logger.severe("Server or port are not defined. Exiting..."); JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", JOptionPane.ERROR_MESSAGE); System.exit(1); } + // Ask the user for their user name String userName = JOptionPane.showInputDialog("Please enter your username"); if (userName == null || userName.isEmpty()) { logger.severe("User name is not set or empty. Exiting..."); System.exit(1); } - Client client = new Client(config, userName); - LocalDB localDB = new LocalDB(client.getSender()); + + // Acquire the client user (with ID) either from the server or from the local + // cache (Preferences), which triggers offline mode + Client client; + try { + client = new Client(config, userName); + } catch (Exception e1) { + logger.log(Level.SEVERE, "Failed to acquire client user ID", e1); + JOptionPane.showMessageDialog(null, e1.toString(), "Client error", JOptionPane.ERROR_MESSAGE); + System.exit(1); + return; + } + + // Load the local database + LocalDB localDB = new LocalDB(client.getSender()); try { localDB.initializeDBFile(config.getLocalDB()); } catch (EnvoyException e) {