diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 4d4f1ec..48ac98f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -1,5 +1,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameHandler; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameParser; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameRequest; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingHandler; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingParser; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingRequest; @@ -64,7 +67,7 @@ public class ServerApp { ResponseDispatcher responseDispatcher = new ResponseDispatcher(sessionManager); - registerCommands(dispatcher, router, responseDispatcher); + registerCommands(dispatcher, router, responseDispatcher, userRegistry); networkManager.start(); } @@ -79,8 +82,14 @@ public class ServerApp { private static void registerCommands( CommandParserDispatcher parserDispatcher, CommandRouter commandRouter, - ResponseDispatcher responseDispatcher) { + ResponseDispatcher responseDispatcher, + UserRegistry userRegistry) { parserDispatcher.register("PING", new PingParser()); commandRouter.register(PingRequest.class, new PingHandler(responseDispatcher)); + + parserDispatcher.register("CHECK_USERNAME", new CheckUsernameParser()); + commandRouter.register( + CheckUsernameRequest.class, + new CheckUsernameHandler(responseDispatcher, userRegistry)); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameHandler.java new file mode 100644 index 0000000..c238ba1 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameHandler.java @@ -0,0 +1,44 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick; + +import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.User; +import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher; +import java.util.Optional; + +/** Handles {@link CheckUsernameRequest}s to check whether a username is available. */ +public class CheckUsernameHandler implements CommandHandler { + private final ResponseDispatcher responseDispatcher; + private final UserRegistry userRegistry; + + /** + * Creates a new handler for checking username availability. + * + * @param responseDispatcher the dispatcher used to send the response + * @param userRegistry the registry used to look up existing users + */ + public CheckUsernameHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) { + this.responseDispatcher = responseDispatcher; + this.userRegistry = userRegistry; + } + + /** + * Executes the username availability check for the given request. + * + *

If no user exists for the requested username, the username is reported as {@link + * UsernameAvailability#FREE}; otherwise, it is reported as {@link UsernameAvailability#TAKEN}. + * + * @param request the request to execute + */ + @Override + public void execute(CheckUsernameRequest request) { + Optional user = userRegistry.getByUsername(request.getUsername()); + UsernameAvailability availability; + if (user.isEmpty()) { + availability = UsernameAvailability.FREE; + } else { + availability = UsernameAvailability.TAKEN; + } + responseDispatcher.dispatch(new CheckUsernameResponse(request.getContext(), availability)); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameParser.java new file mode 100644 index 0000000..20624c0 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameParser.java @@ -0,0 +1,21 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.RequestParameterAccessor; + +/** Parses a primitive request into a {@link CheckUsernameRequest}. */ +public class CheckUsernameParser implements CommandParser { + /** + * Extracts the required {@code USERNAME} parameter from the incoming request. + * + * @param primitiveRequest the request to parse + * @return {@link CheckUsernameRequest} containing the username + */ + @Override + public CheckUsernameRequest parse(PrimitiveRequest primitiveRequest) { + RequestParameterAccessor accessor = + new RequestParameterAccessor(primitiveRequest.parameters()); + return new CheckUsernameRequest(primitiveRequest.context(), accessor.require("USERNAME")); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameRequest.java new file mode 100644 index 0000000..7247b0e --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameRequest.java @@ -0,0 +1,30 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; + +/** Request implementation used to check whether a username is available or already taken */ +public class CheckUsernameRequest extends Request { + private final String username; + + /** + * Constructs a new CheckUsernameRequest with the given context and username to check + * + * @param context the {@link RequestContext} containing information for responding to the + * request + * @param username the username to check for availability + */ + public CheckUsernameRequest(RequestContext context, String username) { + super(context); + this.username = username; + } + + /** + * Returns the provided username in the request + * + * @return username to check + */ + public String getUsername() { + return username; + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameResponse.java new file mode 100644 index 0000000..5018323 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/CheckUsernameResponse.java @@ -0,0 +1,18 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.SuccessResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBodyBuilder; + +/** Response indicating the availability status of a username check. */ +public class CheckUsernameResponse extends SuccessResponse { + /** + * Creates a new response to respond to the username availability check to + * + * @param context the {@link RequestContext} associated with the request + * @param availability the availability status of the requested username + */ + public CheckUsernameResponse(RequestContext context, UsernameAvailability availability) { + super(context, new ResponseBodyBuilder().param("STATUS", availability).build()); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/UsernameAvailability.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/UsernameAvailability.java new file mode 100644 index 0000000..df3d358 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/check_nick/UsernameAvailability.java @@ -0,0 +1,10 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick; + +/** Represents the availability status of a username */ +enum UsernameAvailability { + /** Username is available */ + FREE, + + /** Username is already in use */ + TAKEN +}