-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUserDatabase.java
More file actions
296 lines (285 loc) · 9.76 KB
/
Copy pathUserDatabase.java
File metadata and controls
296 lines (285 loc) · 9.76 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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Scanner;
import java.nio.file.Files;
/**
* Team Project -- UserDatabase
*
* This file handles the user data for each user.
* For more in depth documentation see Docs/UserDataStorage.md
*
* @author William Boulton, Mukund Venkatesh
*
* @version November 1, 2024
*
*/
public class UserDatabase implements UserDBInt {
/*
* User profiles.
New user account creation.
Password protected login.
User search.
User viewer.
Add, block, and remove friend features.
Extra credit opportunity – Add support to upload and display profile pictures.
*/
private static ArrayList<User> users;
private static final String OUTPUT_FILE = "resources/users.txt";
private static final Object LOCK = new Object();
public UserDatabase() {
// This is a constructor
//if the files do not exist, create them
try {
File file = new File(OUTPUT_FILE);
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
e.printStackTrace();
}
users = new ArrayList<User>();
//if users file is not empty, load the database
load();
}
public static String byteArrayToString(byte[] picture) {
// This method converts a byte array to a string
StringBuilder sb = new StringBuilder();
for (byte b : picture) {
sb.append(b);
sb.append(",");
}
return sb.toString();
}
public static BufferedImage getProfilePicture(String viewingUsername) {
// This method gets the profile picture of a user
synchronized (LOCK) {
User user = getUser(viewingUsername);
if (user == null) {
return null;
}
byte[] picture = user.getProfilePicture();
if (picture == null) {
return null;
}
try {
return ImageIO.read(new ByteArrayInputStream(picture));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public User createUser(String username, String password, String firstName, String lastName, byte[] profilePicture)
throws BadDataException {
// This method creates a new user
//if the username is not taken, create a new user
//if user already exists, throw exception
if (getUser(username) != null) {
throw new BadDataException("Username already exists");
}
//if the username is not valid, throw exception
if (!validateUser(username)) {
throw new BadDataException("Username is not valid. It cannot contain a comma");
}
//if password is not legal, throw exception
if (!legalPassword(password)) {
throw new BadDataException("Password is not legal. It must be at least 8 characters, contain at least one"
+ " number, at least one Capital letter and at least one lowercase letter. '|' and ',' not allowed");
}
//if the profile picture is not found, throw exception
//split the profile pic string by comma, and check if the file exists
User user = new User(username, password, firstName, lastName, profilePicture);
writeDB(user);
//create a new user
return user;
}
//add to database
public void writeDB(User user) {
// append user to database
synchronized (LOCK) {
try {
FileWriter writer = new FileWriter(OUTPUT_FILE, true);
writer.write(user.toString() + "\n");
//if the user is not already in the database, add it
if (!users.contains(user)) {
users.add(user);
}
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//get users list
public ArrayList<User> getUsers() {
// This method gets the list of users
return users;
}
//re-write entire DB
public static void updateDB() {
synchronized (LOCK) {
try (BufferedWriter bwr = new BufferedWriter(new FileWriter(OUTPUT_FILE))) {
for (User user : users) {
bwr.write(user.toString());
bwr.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static boolean addFriend(User user, User friend) {
// This method adds a friend to a user
synchronized (LOCK) {
//if the user is not already a friend, add the friend
if (!user.getFriends().contains(friend.getUsername())) {
user.addFriend(friend.getUsername());
} else {
return false;
}
updateDB();
//if the friend is added, return true, else return false
return user.getFriends().contains(friend.getUsername());
}
}
public static boolean removeFriend(User user, User friend) {
//if the user is a friend, remove the friend
synchronized (LOCK) {
if (user.getFriends().contains(friend.getUsername())) {
user.removeFriend(friend.getUsername());
updateDB();
return true;
}
return false;
}
}
public static void blockUser(User user, User blockedUser) {
// This method blocks a user
synchronized (LOCK) {
if (!user.getBlockedUsers().contains(blockedUser.getUsername())) {
user.blockUser(blockedUser.getUsername());
updateDB();
}
updateDB();
}
}
public static boolean unblockUser(User user, User blockedUser) {
// This method unblocks a user
synchronized (LOCK) {
if (user.getBlockedUsers().contains(blockedUser.getUsername())) {
user.unblockUser(blockedUser.getUsername());
updateDB();
return true;
}
return false;
}
}
public static User getUser(String username) {
// This method gets a user by their username
for (User user : users) {
if (user.getUsername().equals(username)) {
return user;
}
}
return null;
}
public boolean verifyLogin(String username, String password) {
// This method verifies a user's login
synchronized (LOCK) {
User user = getUser(username);
if (user == null) {
return false;
}
return user.verifyLogin(password);
}
}
//change username
public boolean changeUsername(User user, String newUsername) {
//if the username is not taken, change the username
synchronized (LOCK) {
if (getUser(newUsername) == null) {
user.changeUsername(newUsername);
updateDB();
return true;
}
updateDB();
}
return false;
}
//change password
public boolean changePassword(User user, String newPassword) {
//if the password is legal, change the password
synchronized (LOCK) {
if (legalPassword(newPassword)) {
user.changePassword(newPassword);
return true;
}
return false;
}
}
//legal password
public static boolean legalPassword(String password) {
// This method checks if a password is legal - at least 8 characters,
//at least one number, at least one Capital letter and at least one lowercase letter
//if password contains comma return false
if (password.contains("|")) {
return false;
}
return password.length() >= 8 && password.matches(".*[0-9].*")
&& password.matches(".*[A-Z].*") && password.matches(".*[a-z].*");
}
//load function for when the program starts
public void load() {
// This method loads the database
synchronized (LOCK) {
users.clear();
try {
Scanner scanner = new Scanner(new File(OUTPUT_FILE));
while (scanner.hasNextLine()) {
User user = new User(scanner.nextLine());
//if the user isnt already in the database, add it
if (!users.contains(user)) {
users.add(user);
}
}
scanner.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public boolean validateUser(String username) {
// This method validates a user
//if username contains comma return false
return !username.contains("|");
}
//add user
public void addUser(User user) {
// This method adds a user
synchronized (LOCK) {
if (!users.contains(user)) {
users.add(user);
updateDB();
}
}
}
private byte[] stringToByteArray(String string) {
String[] stringArray = string.split(",");
byte[] byteArray = new byte[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
byteArray[i] = Byte.parseByte(stringArray[i]);
}
return byteArray;
}
public static void changePicture(User user, byte[] picture) {
synchronized (LOCK) {
user.setProfilePicture(picture);
updateDB();
}
}
}