Searching system
This commit is contained in:
@@ -73,7 +73,15 @@ public class ActionHandler {
|
|||||||
|
|
||||||
private void send(JSONObject request) {
|
private void send(JSONObject request) {
|
||||||
try {
|
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());
|
this.out.println(request.toString());
|
||||||
|
|
||||||
String responseText = this.in.readLine();
|
String responseText = this.in.readLine();
|
||||||
|
|
||||||
if (responseText != null) {
|
if (responseText != null) {
|
||||||
@@ -81,55 +89,63 @@ public class ActionHandler {
|
|||||||
System.out.println("Server response: " + response.getString("message"));
|
System.out.println("Server response: " + response.getString("message"));
|
||||||
String status = response.getString("status");
|
String status = response.getString("status");
|
||||||
|
|
||||||
String action = request.getString("action");
|
|
||||||
|
|
||||||
if (status.equals("success") && response.has("data") && !response.isNull("data")) {
|
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<ChatEntry> 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");
|
Session.chatList = chatList;
|
||||||
List<ChatEntry> chatList = new ArrayList<>();
|
break;
|
||||||
|
|
||||||
for (Object obj : chatListJson) {
|
case "search":
|
||||||
JSONObject chat = (JSONObject) obj;
|
JSONArray results = response.getJSONObject("data").getJSONArray("results");
|
||||||
|
|
||||||
ChatEntry entry = new ChatEntry(
|
if (results.isEmpty()) {
|
||||||
chat.getString("id"),
|
System.out.println("No results found.");
|
||||||
chat.getString("name"),
|
} else {
|
||||||
chat.getString("image_url"),
|
System.out.println("\nSearch Results:");
|
||||||
chat.getString("type"),
|
for (Object obj : results) {
|
||||||
chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time"))
|
JSONObject item = (JSONObject) obj;
|
||||||
);
|
System.out.println("- [" + item.getString("type") + "] " + item.getString("name") + " (ID: " + item.getString("id") + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
chatList.add(entry);
|
case "get_messages":
|
||||||
}
|
break;
|
||||||
|
|
||||||
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") + ")");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("No response from server.");
|
System.out.println("No response from server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} 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() {
|
public void userMenu() {
|
||||||
while (true) {
|
while (true) {
|
||||||
System.out.println("\nUser Menu:");
|
System.out.println("\nUser Menu:");
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class ChannelDatabase {
|
|||||||
try (Connection conn = ConnectionDb.connect();
|
try (Connection conn = ConnectionDb.connect();
|
||||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
stmt.setString(1, "%" + keyword + "%");
|
stmt.setString(1, "%" + keyword + "%");
|
||||||
|
stmt.setString(2, keyword);
|
||||||
|
|
||||||
ResultSet rs = stmt.executeQuery();
|
ResultSet rs = stmt.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
Channel channel = new Channel(
|
Channel channel = new Channel(
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class GroupDatabase {
|
|||||||
try (Connection conn = ConnectionDb.connect();
|
try (Connection conn = ConnectionDb.connect();
|
||||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
stmt.setString(1, "%" + keyword + "%");
|
stmt.setString(1, "%" + keyword + "%");
|
||||||
|
stmt.setString(2, keyword);
|
||||||
|
|
||||||
ResultSet rs = stmt.executeQuery();
|
ResultSet rs = stmt.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
Group group = new Group(
|
Group group = new Group(
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,7 @@ import org.to.telegramfinalproject.Models.*;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ClientHandler implements Runnable {
|
public class ClientHandler implements Runnable {
|
||||||
private final Socket socket;
|
private final Socket socket;
|
||||||
@@ -29,44 +27,51 @@ public class ClientHandler implements Runnable {
|
|||||||
String inputLine;
|
String inputLine;
|
||||||
while ((inputLine = in.readLine()) != null) {
|
while ((inputLine = in.readLine()) != null) {
|
||||||
JSONObject requestJson = new JSONObject(inputLine);
|
JSONObject requestJson = new JSONObject(inputLine);
|
||||||
|
String action = requestJson.getString("action");
|
||||||
RequestModel request = new RequestModel(
|
|
||||||
requestJson.optString("action"),
|
|
||||||
requestJson.optString("user_id"),
|
|
||||||
requestJson.optString("username"),
|
|
||||||
requestJson.optString("password"),
|
|
||||||
requestJson.optString("profile_name")
|
|
||||||
);
|
|
||||||
|
|
||||||
ResponseModel response = null;
|
ResponseModel response = null;
|
||||||
|
System.out.println("Received action: '" + action + "'");
|
||||||
String action = requestJson.optString("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) {
|
switch (action) {
|
||||||
case "register":
|
case "register":
|
||||||
boolean registered = authService.register(
|
case "login": {
|
||||||
request.getUser_id(),
|
RequestModel request = new RequestModel(
|
||||||
request.getUsername(),
|
action,
|
||||||
request.getPassword(),
|
requestJson.optString("user_id"),
|
||||||
request.getProfile_name()
|
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":
|
if (action.equals("register")) {
|
||||||
User user = authService.login(request.getUsername(), request.getPassword());
|
boolean registered = authService.register(
|
||||||
if (user == null) {
|
request.getUser_id(),
|
||||||
response = new ResponseModel("error", "Login failed.");
|
request.getUsername(),
|
||||||
}
|
request.getPassword(),
|
||||||
else {
|
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);
|
SessionManager.addUser(user.getInternal_uuid(), this.socket);
|
||||||
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
||||||
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
|
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
|
||||||
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
||||||
@@ -77,44 +82,20 @@ public class ClientHandler implements Runnable {
|
|||||||
user.setChannelList(channels);
|
user.setChannelList(channels);
|
||||||
user.setUnreadMessages(unreadMessages);
|
user.setUnreadMessages(unreadMessages);
|
||||||
|
|
||||||
|
|
||||||
List<ChatEntry> chatList = new ArrayList<>();
|
List<ChatEntry> chatList = new ArrayList<>();
|
||||||
|
|
||||||
for (Contact contact : contacts) {
|
for (Contact contact : contacts) {
|
||||||
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||||
if (target == null) continue;
|
if (target == null) continue;
|
||||||
|
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
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) {
|
for (Group group : groups) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||||
chatList.add(new ChatEntry(
|
chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last));
|
||||||
group.getGroup_id(),
|
|
||||||
group.getGroup_name(),
|
|
||||||
group.getImage_url(),
|
|
||||||
"group",
|
|
||||||
last
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel channel : channels) {
|
for (Channel channel : channels) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
||||||
chatList.add(new ChatEntry(
|
chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last));
|
||||||
channel.getChannel_id(),
|
|
||||||
channel.getChannel_name(),
|
|
||||||
channel.getImage_url(),
|
|
||||||
"channel",
|
|
||||||
last
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chatList.sort((a, b) -> {
|
chatList.sort((a, b) -> {
|
||||||
@@ -123,36 +104,32 @@ public class ClientHandler implements Runnable {
|
|||||||
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JSONObject userData = JsonUtil.userToJson(user);
|
JSONObject userData = JsonUtil.userToJson(user);
|
||||||
JSONArray chatListJson = JsonUtil.chatListToJson(chatList);
|
userData.put("chat_list", JsonUtil.chatListToJson(chatList));
|
||||||
userData.put("chat_list", chatListJson);
|
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
|
||||||
|
|
||||||
|
|
||||||
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
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());
|
case "search": {
|
||||||
userDatabase.updateUserStatus(uuid, "offline");
|
|
||||||
userDatabase.updateLastSeen(uuid);
|
|
||||||
SessionManager.removeUser(uuid);
|
|
||||||
|
|
||||||
response = new ResponseModel("success", "Logged out.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "search":
|
|
||||||
String keyword = requestJson.optString("keyword");
|
String keyword = requestJson.optString("keyword");
|
||||||
|
|
||||||
List<JSONObject> results = new ArrayList<>();
|
List<JSONObject> results = new ArrayList<>();
|
||||||
|
|
||||||
// User search
|
for (User u : new userDatabase().searchUsers(keyword)) {
|
||||||
List<User> users = new userDatabase().searchUsers(keyword);
|
|
||||||
for (User u : users) {
|
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("type", "user");
|
obj.put("type", "user");
|
||||||
obj.put("id", u.getUser_id());
|
obj.put("id", u.getUser_id());
|
||||||
@@ -160,9 +137,7 @@ public class ClientHandler implements Runnable {
|
|||||||
results.add(obj);
|
results.add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group search
|
for (Group g : GroupDatabase.searchGroups(keyword)) {
|
||||||
List<Group> groups = GroupDatabase.searchGroups(keyword);
|
|
||||||
for (Group g : groups) {
|
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("type", "group");
|
obj.put("type", "group");
|
||||||
obj.put("id", g.getGroup_id());
|
obj.put("id", g.getGroup_id());
|
||||||
@@ -170,9 +145,7 @@ public class ClientHandler implements Runnable {
|
|||||||
results.add(obj);
|
results.add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channel search
|
for (Channel c : ChannelDatabase.searchChannels(keyword)) {
|
||||||
List<Channel> channels = ChannelDatabase.searchChannels(keyword);
|
|
||||||
for (Channel c : channels) {
|
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("type", "channel");
|
obj.put("type", "channel");
|
||||||
obj.put("id", c.getChannel_id());
|
obj.put("id", c.getChannel_id());
|
||||||
@@ -180,36 +153,30 @@ public class ClientHandler implements Runnable {
|
|||||||
results.add(obj);
|
results.add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray dataArray = new JSONArray(results);
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("results", dataArray);
|
data.put("results", new JSONArray(results));
|
||||||
response = new ResponseModel("success", "Search results found", data);
|
response = new ResponseModel("success", "Search results found", data);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
response = new ResponseModel("error", "Unknown action: " + action);
|
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){
|
JSONObject responseJson = new JSONObject();
|
||||||
System.out.println("Connection with client lost.");
|
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);
|
UUID userId = SessionManager.getUserIdBySocket(this.socket);
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
userDatabase.updateUserStatus(userId, "offline");
|
userDatabase.updateUserStatus(userId, "offline");
|
||||||
userDatabase.updateLastSeen(userId);
|
userDatabase.updateLastSeen(userId);
|
||||||
SessionManager.removeUser(userId);
|
SessionManager.removeUser(userId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user