-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMessageDatabase.java
More file actions
184 lines (178 loc) · 7.39 KB
/
Copy pathMessageDatabase.java
File metadata and controls
184 lines (178 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import java.util.*;
import java.io.*;
/**
* Team Project -- MessageDatabase
*
* This file handles the message data for each user.
* For more in depth documentation see Docs/MessageDataStorage.md
*
* @author William Boulton, 7
*
* @version November 1, 2024
*
*/
public class MessageDatabase extends Thread implements MData {
protected ArrayList<Message> recievedMessages;
protected ArrayList<Message> sentMessages;
private User user; // this will be the user who has sent or recieved the messages stored in said database object
private String filePath;
public static final Object LOCK = new Object();
//this creates a message database for the specified user, which is a csv file with name "username.txt"
public MessageDatabase(User user) {
this.user = user;
filePath = String.format("resources/%s.txt", user.getUsername());
//if a file does not exist for this user, create it
try {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
e.printStackTrace();
}
recievedMessages = new ArrayList<>();
sentMessages = new ArrayList<>();
}
public ArrayList<Message> getSentMessages() {
recoverMessages();
return sentMessages;
}
public ArrayList<Message> getRecievedMessages() {
recoverMessages();
return recievedMessages;
}
//this reads all of the messages in a user's file and adds them to the correct sent/recieved arraylist
public void recoverMessages() {
//clear the arraylists to avoid duplicates
recievedMessages.clear();
sentMessages.clear();
try (BufferedReader bfr = new BufferedReader(new FileReader(this.filePath))) {
String line;
synchronized (LOCK) {
while ((line = bfr.readLine()) != null) {
Message newMessage = new Message(line);
if (newMessage.getSender().equals(user.getUsername())) {
//if the message isnt already in the sent messages arraylist, add it
if (!sentMessages.contains(newMessage)) {
sentMessages.add(newMessage);
}
} else if (newMessage.getReciever().equals(user.getUsername())) {
//if the message isnt already in the recieved messages arraylist, add it
if (!recievedMessages.contains(newMessage)) {
recievedMessages.add(newMessage);
}
} else {
System.out.println("This message shouldn't be here");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//this handles sending messages by adding it immediately to the arraylist and the file for this user, it also adds it
// to the file for the recieving user. I do this immediately so that if the program crashes later the messages are
// not lost.
public void sendMessage(Message m) throws BadDataException {
//Here I simply check if they are blocked before sending the message
//Carefull, before this function can be called the database must be loaded and running
User rUser = UserDatabase.getUser(m.getReciever());
User sUser = UserDatabase.getUser(m.getSender());
if (rUser == null || sUser == null) {
throw new BadDataException("One of the users did not exist");
}
if (rUser.getBlockedUsers().contains(m.getSender())) {
throw new BadDataException("This user is blocked");
}
if (!rUser.isAllowAll()) {
if (!rUser.getFriends().contains(m.getSender())) {
throw new BadDataException("This user only allows messages from friends");
}
}
//this system allows illegal messages to be created but never sent, that is subject to change.
synchronized (LOCK) {
sentMessages.add(m);
String senderFile = String.format("resources/%s.txt", m.getSender());
String recieverFile = String.format("resources/%s.txt", m.getReciever());
try (PrintWriter out = new PrintWriter(new FileWriter(senderFile, true))) {
out.println(m);
} catch (Exception e) {
e.printStackTrace();
}
try (PrintWriter out = new PrintWriter(new FileWriter(recieverFile, true))) {
out.println(m);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// this removes a specified message from both the sender and reciever's files
@Override
public void deleteMessage(Message m) throws BadDataException {
synchronized (LOCK) {
recoverMessages();
int id = m.getMessageID();
try {
if (!sentMessages.remove(m)) {
throw new BadDataException("This message did not exist");
}
System.out.println("removed");
} catch (Exception e) {
throw new BadDataException("This message did not exist");
}
//here I use the arraylist to generate the new list of messages after the delete, this means
//the array list must be up to date before deleting.
ArrayList<Message> messages = sentMessages;
messages.addAll(recievedMessages);
messages.sort(Comparator.comparingInt(Message::getMessageID));
try (BufferedWriter sender = new BufferedWriter(new FileWriter(filePath))) {
for (Message message : messages) {
sender.write(message.toString());
sender.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}
String receiver = m.getReciever();
String receiveFile = String.format("resources/%s.txt", receiver);
ArrayList<Message> messagesToWrite = new ArrayList<>();
try (BufferedReader get = new BufferedReader(new FileReader(receiveFile))) {
String line;
while ((line = get.readLine()) != null) {
messagesToWrite.add(new Message(line));
}
} catch (Exception e) {
e.printStackTrace();
}
try (BufferedWriter put = new BufferedWriter(new FileWriter(receiveFile))) {
for (Message message : messagesToWrite) {
if (message.getMessageID() == id) {
continue;
}
put.write(message.toString());
put.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public User getUser() {
return user;
}
@Override
public String getFilePath() {
return filePath;
}
//edits the message by creating a new one witht the same messageID and resending it.
@Override
public void editMessage(Message m, Message n) throws BadDataException {
synchronized (LOCK) {
System.out.println("EDITING MESSAGE");
n.setMessageID(m.getMessageID());
deleteMessage(m);
sendMessage(n);
}
}
}