Add presence server skeleton
This commit is contained in:
parent
1cf3f738cb
commit
20e341c190
10 changed files with 298 additions and 56 deletions
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"serveur" :"test"
|
||||
"serveur": {
|
||||
"actif": 1,
|
||||
"uri": "test",
|
||||
"type": "INSA"
|
||||
}
|
||||
}
|
|
@ -28,8 +28,7 @@ public class MainApp extends Application {
|
|||
final Parent content = mainLoader.load();
|
||||
MainController mainController = mainLoader.getController();
|
||||
|
||||
userList = new UserList();
|
||||
mainController.setUserList(userList);
|
||||
userList = mainController.getUserList();
|
||||
|
||||
Scene scene = new Scene(content);
|
||||
|
||||
|
@ -44,7 +43,9 @@ public class MainApp extends Application {
|
|||
@Override
|
||||
public void stop() throws Exception {
|
||||
// Stop all threads and active connections before exiting
|
||||
userList.destroy();
|
||||
if (userList != null) {
|
||||
userList.destroy();
|
||||
}
|
||||
super.stop();
|
||||
}
|
||||
}
|
124
src/main/java/fr/insa/clavardator/config/Config.java
Normal file
124
src/main/java/fr/insa/clavardator/config/Config.java
Normal file
|
@ -0,0 +1,124 @@
|
|||
package fr.insa.clavardator.config;
|
||||
|
||||
import fr.insa.clavardator.server.PresenceType;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
public class Config {
|
||||
|
||||
private ServerConfig serverConfig;
|
||||
private final String SERVER_KEY = "serveur";
|
||||
|
||||
public Config() {
|
||||
serverConfig = new ServerConfig();
|
||||
}
|
||||
|
||||
public Config(JSONObject obj) {
|
||||
this();
|
||||
if (obj.has(SERVER_KEY)) {
|
||||
this.serverConfig = new ServerConfig(obj.getJSONObject(SERVER_KEY));
|
||||
}
|
||||
}
|
||||
|
||||
public ServerConfig getServerConfig() {
|
||||
return serverConfig;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
public static class ServerConfig {
|
||||
|
||||
private JSONObject obj;
|
||||
|
||||
private boolean enabled;
|
||||
private String uri;
|
||||
private PresenceType type;
|
||||
|
||||
private final String ENABLED_KEY = "actif";
|
||||
private final String URI_KEY = "uri";
|
||||
private final String TYPE_KEY = "type";
|
||||
|
||||
/**
|
||||
* Basic constructor setting the default server configuration
|
||||
*/
|
||||
public ServerConfig() {
|
||||
enabled = false;
|
||||
uri = "";
|
||||
type = PresenceType.INSA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to read the given JSON object to extract custom user configuration
|
||||
*
|
||||
* @param obj THe JSON object to read config from
|
||||
*/
|
||||
public ServerConfig(JSONObject obj) {
|
||||
this();
|
||||
this.obj = obj;
|
||||
readServerEnabled();
|
||||
if (enabled) {
|
||||
readServerUri();
|
||||
if (uri.isBlank()) {
|
||||
enabled = false;
|
||||
} else {
|
||||
readServerType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads if the server is enabled.
|
||||
* Uses false by default.
|
||||
*/
|
||||
private void readServerEnabled() {
|
||||
try {
|
||||
enabled = obj.getInt(ENABLED_KEY) == 1;
|
||||
} catch (JSONException e) {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the server URI.
|
||||
* Uses the empty string as default
|
||||
*/
|
||||
private void readServerUri() {
|
||||
try {
|
||||
uri = obj.getString(URI_KEY);
|
||||
} catch (JSONException e) {
|
||||
uri = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the server type.
|
||||
* Uses INSA as default.
|
||||
*/
|
||||
private void readServerType() {
|
||||
try {
|
||||
type = obj.getEnum(PresenceType.class, TYPE_KEY);
|
||||
} catch (JSONException e) {
|
||||
type = PresenceType.INSA;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the presence server is enabled.
|
||||
* If this returns false, all other data returned by this object can be ignored.
|
||||
*
|
||||
* @return True if enabled, false otherwise.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public PresenceType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package fr.insa.clavardator.util;
|
||||
package fr.insa.clavardator.config;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import fr.insa.clavardator.util.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
@ -34,25 +34,4 @@ public class ConfigLoader {
|
|||
void onLoaded(Config config);
|
||||
}
|
||||
|
||||
public static class Config {
|
||||
@Nullable
|
||||
private String serverUri;
|
||||
private final String SERVER_URI_KEY = "serveur";
|
||||
|
||||
public Config() {
|
||||
serverUri = null;
|
||||
}
|
||||
|
||||
public Config(JSONObject obj) {
|
||||
this();
|
||||
if (obj.has(SERVER_URI_KEY)) {
|
||||
serverUri = obj.getString(SERVER_URI_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable String getServerUri() {
|
||||
return serverUri;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
38
src/main/java/fr/insa/clavardator/server/InsaPresence.java
Normal file
38
src/main/java/fr/insa/clavardator/server/InsaPresence.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package fr.insa.clavardator.server;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class InsaPresence implements Presence {
|
||||
|
||||
private final String path;
|
||||
|
||||
public InsaPresence(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<String> subscribe() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publish(boolean connected) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptNotifications() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopNotifications() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getInetAddress() {
|
||||
return null;
|
||||
}
|
||||
}
|
41
src/main/java/fr/insa/clavardator/server/Presence.java
Normal file
41
src/main/java/fr/insa/clavardator/server/Presence.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package fr.insa.clavardator.server;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface Presence {
|
||||
|
||||
/**
|
||||
* Subscribes to this presence server notifications.
|
||||
* A list of Ids representing the current active users is returned.
|
||||
*
|
||||
* @return The list of connected user's Ids
|
||||
*/
|
||||
ArrayList<String> subscribe();
|
||||
|
||||
/**
|
||||
* Updates the current user state on the server.
|
||||
* This function must be called on app exit,
|
||||
* or the server won't know this user is inactive.
|
||||
*
|
||||
* @param connected The new user state
|
||||
*/
|
||||
void publish(boolean connected);
|
||||
|
||||
/**
|
||||
* Starts listening to presence server update notifications.
|
||||
*/
|
||||
void acceptNotifications();
|
||||
|
||||
/**
|
||||
* Stops listening to presence server update notifications.
|
||||
*/
|
||||
void stopNotifications();
|
||||
|
||||
/**
|
||||
* Gets the presence server InetAddress
|
||||
*
|
||||
* @return The server address
|
||||
*/
|
||||
InetAddress getInetAddress();
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package fr.insa.clavardator.server;
|
||||
|
||||
public class PresenceFactory {
|
||||
public static Presence create(PresenceType type, String uri) throws UnknownPresenceException {
|
||||
switch (type) {
|
||||
case INSA:
|
||||
return new InsaPresence(uri);
|
||||
default:
|
||||
throw new UnknownPresenceException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package fr.insa.clavardator.server;
|
||||
|
||||
public enum PresenceType {
|
||||
INSA,
|
||||
TEST,
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package fr.insa.clavardator.server;
|
||||
|
||||
public class UnknownPresenceException extends Exception {
|
||||
public UnknownPresenceException() {
|
||||
super("Unknown presence server sepcified");
|
||||
}
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
package fr.insa.clavardator.ui;
|
||||
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import fr.insa.clavardator.config.Config;
|
||||
import fr.insa.clavardator.db.DatabaseController;
|
||||
import fr.insa.clavardator.server.Presence;
|
||||
import fr.insa.clavardator.server.PresenceFactory;
|
||||
import fr.insa.clavardator.server.PresenceType;
|
||||
import fr.insa.clavardator.server.UnknownPresenceException;
|
||||
import fr.insa.clavardator.ui.chat.ChatController;
|
||||
import fr.insa.clavardator.ui.dialogs.AboutDialogController;
|
||||
import fr.insa.clavardator.ui.dialogs.EditUsernameDialogController;
|
||||
|
@ -9,7 +14,7 @@ import fr.insa.clavardator.ui.dialogs.SnackbarController;
|
|||
import fr.insa.clavardator.ui.users.UserListController;
|
||||
import fr.insa.clavardator.users.CurrentUser;
|
||||
import fr.insa.clavardator.users.UserList;
|
||||
import fr.insa.clavardator.util.ConfigLoader;
|
||||
import fr.insa.clavardator.config.ConfigLoader;
|
||||
import fr.insa.clavardator.util.Log;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -47,6 +52,7 @@ public class MainController implements Initializable {
|
|||
|
||||
private JFXSnackbar snackbar;
|
||||
private UserList userList;
|
||||
private Presence presenceServer;
|
||||
private boolean online;
|
||||
|
||||
public MainController() {
|
||||
|
@ -92,7 +98,7 @@ public class MainController implements Initializable {
|
|||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param mode
|
||||
* @param mode The dialog mode
|
||||
*/
|
||||
private void openEditUsernameDialog(EditUsernameDialogController.Mode mode) {
|
||||
final boolean initialMode = mode == EditUsernameDialogController.Mode.INITIAL;
|
||||
|
@ -233,36 +239,19 @@ public class MainController implements Initializable {
|
|||
errorController.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
loadingController.show("Initialisation de Clavardator...");
|
||||
snackbar = new JFXSnackbar(root);
|
||||
|
||||
listController.setUserSelectedListener((user) -> chatController.setRemoteUser(user));
|
||||
// chatController.setAttachmentListener(() -> System.out.println("attach event"));
|
||||
chatController.setSendErrorListener((e) -> showSnackbarEvent("Erreur: Message non envoyé", SnackbarController.Mode.ERROR));
|
||||
toolbarController.setEditListener(() -> openEditUsernameDialog(EditUsernameDialogController.Mode.EDIT));
|
||||
toolbarController.setAboutListener(this::openAboutDialog);
|
||||
}
|
||||
|
||||
private void onInitError(Exception e) {
|
||||
Log.e("INIT", "Error during initialization", e);
|
||||
showError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates database if needed, then init current user, and finally load user list
|
||||
* Reads user config, then creates database if needed,
|
||||
* then init current user, and finally load user list.
|
||||
*/
|
||||
private void initBackend() {
|
||||
ConfigLoader.load((ConfigLoader.Config config) -> {
|
||||
final String serverUri = config.getServerUri();
|
||||
if (serverUri != null) {
|
||||
Log.v("INIT", "Found server URI: " + serverUri);
|
||||
} else {
|
||||
Log.v("INIT", "Server URI not found. Proceeding without");
|
||||
}
|
||||
final DatabaseController db = new DatabaseController();
|
||||
db.initTables(
|
||||
ConfigLoader.load((Config config) -> {
|
||||
initPresenceServer(config);
|
||||
new DatabaseController().initTables(
|
||||
() -> userList.retrievedPreviousUsers(
|
||||
() -> currentUser.init(this::onInitError),
|
||||
this::onInitError
|
||||
|
@ -271,16 +260,57 @@ public class MainController implements Initializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the user list to use.
|
||||
* We must set it from the MainApp to allow destroying it on exit.
|
||||
* Initializes the presence server based on user config
|
||||
*
|
||||
* @param userList The user list to use
|
||||
* @param config The user config
|
||||
*/
|
||||
public void setUserList(UserList userList) {
|
||||
this.userList = userList;
|
||||
private void initPresenceServer(Config config) {
|
||||
final Config.ServerConfig serverConfig = config.getServerConfig();
|
||||
if (serverConfig.isEnabled()) {
|
||||
try {
|
||||
final PresenceType type = serverConfig.getType();
|
||||
final String uri = serverConfig.getUri();
|
||||
presenceServer = PresenceFactory.create(type, uri);
|
||||
Log.v("INIT", "Presence server support enabled: " + type + " @ " + uri);
|
||||
} catch (UnknownPresenceException e) {
|
||||
Log.e("INIT", "Presence server type not found", e);
|
||||
presenceServer = null;
|
||||
}
|
||||
} else {
|
||||
Log.v("INIT", "Presence server support disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current user list.
|
||||
*
|
||||
* @implNote BE SURE TO CALL .destroy() BEFORE EXITING THE APP.
|
||||
*
|
||||
* @return The current user list
|
||||
*/
|
||||
public UserList getUserList() {
|
||||
return userList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
loadingController.show("Initialisation de Clavardator...");
|
||||
snackbar = new JFXSnackbar(root);
|
||||
userList = new UserList();
|
||||
|
||||
|
||||
listController.setUserList(userList);
|
||||
listController.setRefreshUserListener(this::discoverActiveUsers);
|
||||
listController.setUserSelectedListener((user) -> chatController.setRemoteUser(user));
|
||||
|
||||
chatController.setSendErrorListener((e) -> showSnackbarEvent("Erreur: Message non envoyé", SnackbarController.Mode.ERROR));
|
||||
|
||||
toolbarController.setEditListener(() -> openEditUsernameDialog(EditUsernameDialogController.Mode.EDIT));
|
||||
toolbarController.setAboutListener(this::openAboutDialog);
|
||||
|
||||
editUserDialogController.setUserList(userList);
|
||||
|
||||
initBackend();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue