diff --git a/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java index e79cc9f..91b5db1 100644 --- a/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java @@ -73,7 +73,15 @@ public class ActionHandler { private void send(JSONObject request) { try { + if (!request.has("action") || request.isNull("action")) { + System.err.println("Error: Request does not contain 'action'."); + return; + } + + String action = request.getString("action"); + this.out.println(request.toString()); + String responseText = this.in.readLine(); if (responseText != null) { @@ -81,55 +89,63 @@ public class ActionHandler { System.out.println("Server response: " + response.getString("message")); String status = response.getString("status"); - String action = request.getString("action"); - if (status.equals("success") && response.has("data") && !response.isNull("data")) { - if (action.equals("login") || action.equals("register")) { + switch (action) { + case "login": + case "register": + Session.currentUser = response.getJSONObject("data"); + JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list"); + List chatList = new ArrayList<>(); - Session.currentUser = response.getJSONObject("data"); + for (Object obj : chatListJson) { + JSONObject chat = (JSONObject) obj; + ChatEntry entry = new ChatEntry( + chat.getString("id"), + chat.getString("name"), + chat.getString("image_url"), + chat.getString("type"), + chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time")) + ); + chatList.add(entry); + } - JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list"); - List chatList = new ArrayList<>(); + Session.chatList = chatList; + break; - for (Object obj : chatListJson) { - JSONObject chat = (JSONObject) obj; + case "search": + JSONArray results = response.getJSONObject("data").getJSONArray("results"); - ChatEntry entry = new ChatEntry( - chat.getString("id"), - chat.getString("name"), - chat.getString("image_url"), - chat.getString("type"), - chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time")) - ); + if (results.isEmpty()) { + System.out.println("No results found."); + } else { + System.out.println("\nSearch Results:"); + for (Object obj : results) { + JSONObject item = (JSONObject) obj; + System.out.println("- [" + item.getString("type") + "] " + item.getString("name") + " (ID: " + item.getString("id") + ")"); + } + } + break; - chatList.add(entry); - } - - Session.chatList = chatList; - } - - else if (action.equals("search")) { - - JSONArray results = response.getJSONObject("data").getJSONArray("results"); - - System.out.println("\nSearch Results:"); - for (Object obj : results) { - JSONObject item = (JSONObject) obj; - System.out.println("- [" + item.getString("type") + "] " + item.getString("name") + " (ID: " + item.getString("id") + ")"); - } + case "get_messages": + break; } } + } else { System.out.println("No response from server."); } } catch (IOException e) { - System.err.println("Error: " + e.getMessage()); + System.err.println("Error while communicating with server: " + e.getMessage()); + } catch (Exception e) { + System.err.println("Client error: " + e.getMessage()); + e.printStackTrace(); } } + public void userMenu() { while (true) { System.out.println("\nUser Menu:"); diff --git a/src/main/java/org/to/telegramfinalproject/Database/ChannelDatabase.java b/src/main/java/org/to/telegramfinalproject/Database/ChannelDatabase.java index e2b0754..8f8de92 100644 --- a/src/main/java/org/to/telegramfinalproject/Database/ChannelDatabase.java +++ b/src/main/java/org/to/telegramfinalproject/Database/ChannelDatabase.java @@ -55,6 +55,8 @@ public class ChannelDatabase { try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, "%" + keyword + "%"); + stmt.setString(2, keyword); + ResultSet rs = stmt.executeQuery(); while (rs.next()) { Channel channel = new Channel( diff --git a/src/main/java/org/to/telegramfinalproject/Database/GroupDatabase.java b/src/main/java/org/to/telegramfinalproject/Database/GroupDatabase.java index 722f266..79fa09b 100644 --- a/src/main/java/org/to/telegramfinalproject/Database/GroupDatabase.java +++ b/src/main/java/org/to/telegramfinalproject/Database/GroupDatabase.java @@ -55,6 +55,8 @@ public class GroupDatabase { try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, "%" + keyword + "%"); + stmt.setString(2, keyword); + ResultSet rs = stmt.executeQuery(); while (rs.next()) { Group group = new Group( diff --git a/src/main/java/org/to/telegramfinalproject/Models/SearchRequestModel.java b/src/main/java/org/to/telegramfinalproject/Models/SearchRequestModel.java new file mode 100644 index 0000000..db63e19 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Models/SearchRequestModel.java @@ -0,0 +1,19 @@ +package org.to.telegramfinalproject.Models; + +public class SearchRequestModel { + private String action; + private String keyword; + + public SearchRequestModel(String action, String keyword) { + this.action = action; + this.keyword = keyword; + } + + public String getAction() { + return action; + } + + public String getKeyword() { + return keyword; + } +} diff --git a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java index cda3323..1058e3e 100644 --- a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java @@ -8,9 +8,7 @@ import org.to.telegramfinalproject.Models.*; import java.io.*; import java.net.Socket; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.util.*; public class ClientHandler implements Runnable { private final Socket socket; @@ -29,44 +27,51 @@ public class ClientHandler implements Runnable { String inputLine; while ((inputLine = in.readLine()) != null) { JSONObject requestJson = new JSONObject(inputLine); - - RequestModel request = new RequestModel( - requestJson.optString("action"), - requestJson.optString("user_id"), - requestJson.optString("username"), - requestJson.optString("password"), - requestJson.optString("profile_name") - ); - + String action = requestJson.getString("action"); ResponseModel response = null; - - String action = requestJson.optString("action"); + System.out.println("Received action: '" + action + "'"); + System.out.println("Full request: " + requestJson.toString()); + if (!requestJson.has("action") || requestJson.isNull("action")) { + ResponseModel errorResponse = new ResponseModel("error", "Missing 'action' in request."); + JSONObject responseJson = new JSONObject(); + responseJson.put("status", errorResponse.getStatus()); + responseJson.put("message", errorResponse.getMessage()); + responseJson.put("data", JSONObject.NULL); + out.println(responseJson.toString()); + continue; + } switch (action) { case "register": - boolean registered = authService.register( - request.getUser_id(), - request.getUsername(), - request.getPassword(), - request.getProfile_name() + case "login": { + RequestModel request = new RequestModel( + action, + requestJson.optString("user_id"), + requestJson.optString("username"), + requestJson.optString("password"), + requestJson.optString("profile_name") ); - response = registered - ? new ResponseModel("success", "Registration successful.") - : new ResponseModel("error", "Registration failed."); - break; - case "login": - User user = authService.login(request.getUsername(), request.getPassword()); - if (user == null) { - response = new ResponseModel("error", "Login failed."); - } - else { + if (action.equals("register")) { + boolean registered = authService.register( + request.getUser_id(), + request.getUsername(), + request.getPassword(), + request.getProfile_name() + ); + response = registered + ? new ResponseModel("success", "Registration successful.") + : new ResponseModel("error", "Registration failed."); + } else { + User user = authService.login(request.getUsername(), request.getPassword()); + if (user == null) { + response = new ResponseModel("error", "Login failed."); + break; + } SessionManager.addUser(user.getInternal_uuid(), this.socket); userDatabase.updateUserStatus(user.getInternal_uuid(), "online"); - - List contacts = ContactDatabase.getContacts(user.getInternal_uuid()); List groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid()); List channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid()); @@ -77,44 +82,20 @@ public class ClientHandler implements Runnable { user.setChannelList(channels); user.setUnreadMessages(unreadMessages); - List chatList = new ArrayList<>(); - for (Contact contact : contacts) { User target = userDatabase.findByInternalUUID(contact.getContact_id()); if (target == null) continue; - LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private"); - - chatList.add(new ChatEntry( - target.getUser_id(), - target.getProfile_name(), - target.getImage_url(), - "private", - last - )); + chatList.add(new ChatEntry(target.getUser_id(), target.getProfile_name(), target.getImage_url(), "private", last)); } - for (Group group : groups) { LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group"); - chatList.add(new ChatEntry( - group.getGroup_id(), - group.getGroup_name(), - group.getImage_url(), - "group", - last - )); + chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last)); } - for (Channel channel : channels) { LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel"); - chatList.add(new ChatEntry( - channel.getChannel_id(), - channel.getChannel_name(), - channel.getImage_url(), - "channel", - last - )); + chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last)); } chatList.sort((a, b) -> { @@ -123,36 +104,32 @@ public class ClientHandler implements Runnable { return b.getLastMessageTime().compareTo(a.getLastMessageTime()); }); - - JSONObject userData = JsonUtil.userToJson(user); - JSONArray chatListJson = JsonUtil.chatListToJson(chatList); - userData.put("chat_list", chatListJson); - - - response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData); + userData.put("chat_list", JsonUtil.chatListToJson(chatList)); + response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData); } - break; + } - case "logout": + case "logout": { + String userId = requestJson.optString("user_id"); + if (userId != null && !userId.isEmpty()) { + UUID uuid = UUID.fromString(userId); + userDatabase.updateUserStatus(uuid, "offline"); + userDatabase.updateLastSeen(uuid); + SessionManager.removeUser(uuid); + response = new ResponseModel("success", "Logged out."); + } else { + response = new ResponseModel("error", "Invalid user_id for logout."); + } + break; + } - UUID uuid = UUID.fromString(request.getUser_id()); - userDatabase.updateUserStatus(uuid, "offline"); - userDatabase.updateLastSeen(uuid); - SessionManager.removeUser(uuid); - - response = new ResponseModel("success", "Logged out."); - break; - - case "search": + case "search": { String keyword = requestJson.optString("keyword"); - List results = new ArrayList<>(); - // User search - List users = new userDatabase().searchUsers(keyword); - for (User u : users) { + for (User u : new userDatabase().searchUsers(keyword)) { JSONObject obj = new JSONObject(); obj.put("type", "user"); obj.put("id", u.getUser_id()); @@ -160,9 +137,7 @@ public class ClientHandler implements Runnable { results.add(obj); } - // Group search - List groups = GroupDatabase.searchGroups(keyword); - for (Group g : groups) { + for (Group g : GroupDatabase.searchGroups(keyword)) { JSONObject obj = new JSONObject(); obj.put("type", "group"); obj.put("id", g.getGroup_id()); @@ -170,9 +145,7 @@ public class ClientHandler implements Runnable { results.add(obj); } - // Channel search - List channels = ChannelDatabase.searchChannels(keyword); - for (Channel c : channels) { + for (Channel c : ChannelDatabase.searchChannels(keyword)) { JSONObject obj = new JSONObject(); obj.put("type", "channel"); obj.put("id", c.getChannel_id()); @@ -180,36 +153,30 @@ public class ClientHandler implements Runnable { results.add(obj); } - JSONArray dataArray = new JSONArray(results); JSONObject data = new JSONObject(); - data.put("results", dataArray); + data.put("results", new JSONArray(results)); response = new ResponseModel("success", "Search results found", data); break; + } default: response = new ResponseModel("error", "Unknown action: " + action); - } - - JSONObject responseJson = new JSONObject(); - responseJson.put("status", response.getStatus()); - responseJson.put("message", response.getMessage()); - responseJson.put("data",response.getData() != null ?response.getData() :JSONObject.NULL); - out.println(responseJson.toString()); } - } catch(IOException e){ - System.out.println("Connection with client lost."); - + JSONObject responseJson = new JSONObject(); + responseJson.put("status", response.getStatus()); + responseJson.put("message", response.getMessage()); + responseJson.put("data", response.getData() != null ? response.getData() : JSONObject.NULL); + out.println(responseJson.toString()); + } + } catch (IOException e) { + System.out.println("Connection with client lost."); UUID userId = SessionManager.getUserIdBySocket(this.socket); if (userId != null) { userDatabase.updateUserStatus(userId, "offline"); userDatabase.updateLastSeen(userId); SessionManager.removeUser(userId); } - } } - - - + } } -