From c7ac2db02a39cf349f9434186996c93eebc17a3c Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Sun, 23 Feb 2025 15:51:28 -0500 Subject: Created UserDAO and file as well as user class --- .../java/com/ufund/api/ufundapi/model/User.java | 20 +++ .../ufund/api/ufundapi/persistence/UserDAO.java | 84 ++++++++++++ .../api/ufundapi/persistence/UserFileDAO.java | 146 +++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java create mode 100644 ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java create mode 100644 ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java new file mode 100644 index 0000000..12bbddc --- /dev/null +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -0,0 +1,20 @@ +package com.ufund.api.ufundapi.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class User { + + @JsonProperty("name") private String name; + + /** + * Create a new user + * + * @param name The name of the user + */ + public User(String name) { + this.name = name; + } + + + +} diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java new file mode 100644 index 0000000..df797b9 --- /dev/null +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java @@ -0,0 +1,84 @@ +package com.ufund.api.ufundapi.persistence; + +import java.io.IOException; + +import com.ufund.api.ufundapi.model.Need; + +/** + * Defines the interface for Need object persistence + * + * @author Team 2B Jelly Solutions + */ +public interface UserDAO { + /** + * Retrieves all {@linkplain Need needs} + * + * @return An array of {@link Need need} objects, may be empty + * + * @throws IOException if an issue with underlying storage + */ + Need[] getUsers() throws IOException; + + /** + * Finds all {@linkplain Need needs} whose name contains the given text + * + * @param targetName The text to match against + * + * @return An array of {@link Need needs} whose names contains the given text, + * may be empty + * + * @throws IOException if an issue with underlying storage + */ + Need[] findUsers(String targetName) throws IOException; + + /** + * Retrieves a {@linkplain Need need} with the given name + * + * @param id The ID of the {@link Need need} to get + * + * @return a {@link Need need} object with the matching name + *
+ * null if no {@link Need need} with a matching name is found + * + * @throws IOException if an issue with underlying storage + */ + Need getUser(int id) throws IOException; + + /** + * Creates and saves a {@linkplain Need need} + * + * @param need {@linkplain Need need} object to be created and saved + *
+ * The id of the need object is automatically incremented. + * + * @return new {@link Need need} if successful, null otherwise + * + * @throws IOException if an issue with underlying storage + */ + Need createNeed(Need need) throws IOException; + + /** + * Updates and saves a {@linkplain Need need} + * + * @param need {@link Need need} object to be updated and saved + * + * @return updated {@link Need need} if successful, null if + * {@link Need need} could not be found + * + * @throws IOException if underlying storage cannot be accessed + */ + Need updateNeed(Need need) throws IOException; + + /** + * Deletes a {@linkplain Need need} with the given id + * + * @param id The id of the {@link Need need} + * + * @return true if the {@link Need need} was deleted + *
+ * false if the need with the given id does not exist + * + * @throws IOException if underlying storage cannot be accessed + */ + boolean deleteNeed(int id) throws IOException; +} diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java new file mode 100644 index 0000000..87b8103 --- /dev/null +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -0,0 +1,146 @@ +package com.ufund.api.ufundapi.persistence; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ufund.api.ufundapi.model.Need; + +@Component +public class UserFileDAO implements UserDAO { + + private final Map needs; // cache + private final ObjectMapper objectMapper; + private static int nextId; + private final String filename; + + public UserFileDAO(@Value("${users.file}") String filename, ObjectMapper objectMapper) throws IOException { + this.filename = filename; + this.objectMapper = objectMapper; + needs = new TreeMap<>(); + load(); // load the heroes from the file + } + + private synchronized static int nextId() { + int id = nextId; + nextId++; + return id; + } + + /** + * Load changes from the json file + * + * @throws IOException Any IO issue with the file + */ + private void load() throws IOException { + needs.clear(); + nextId = 0; + + Need[] needsArray = objectMapper.readValue(new File(filename), Need[].class); + + for (Need need : needsArray) { + needs.put(need.getId(), need); + if (need.getId() > nextId()) { + nextId = need.getId(); + } + } + nextId++; + } + + /** + * Return an array of the needs + * + * @return An array of all the needs + */ + private Need[] getNeedsArray() { + return needs.values().toArray(Need[]::new); + } + + /** + * Returns an array of needs filtered by a search + * + * @param search The search substring + * @return The requested array + */ + private Need[] getNeedsArray(String search) { + return needs.values().stream() + .filter(i -> i.getName().toLowerCase().contains(search.toLowerCase())) + .toArray(Need[]::new); + } + + /** + * Saves the needs to json + * + * @return True if the save was successful, false otherwise + * @throws IOException If there was an IO issue saving the file + */ + private boolean save() throws IOException { + Need[] needArray = getNeedsArray(); + + objectMapper.writeValue(new File(filename), needArray); + return true; + } + + @Override + public Need[] getNeeds() { + synchronized (needs) { + return getNeedsArray(); + } + } + + @Override + public Need[] findNeeds(String targetName) { + synchronized (needs) { + return getNeedsArray(targetName); + } + } + + @Override + public Need getNeed(int id) { + synchronized (needs) { + return needs.getOrDefault(id, null); + } + } + + @Override + public Need createNeed(Need need) throws IOException { + synchronized (needs) { + Need newNeed = new Need(need); + newNeed.setID(nextId()); + needs.put(newNeed.getId(), newNeed); + save(); + return newNeed; + } + } + + @Override + public Need updateNeed(Need need) throws IOException { + synchronized (needs) { + if (needs.containsKey(need.getId())) { + needs.put(need.getId(), need); + save(); + return need; + } else { + return null; + } + + } + } + + @Override + public boolean deleteNeed(int id) throws IOException { + synchronized (needs) { + if (needs.containsKey(id)) { + needs.remove(id); + return save(); + } else { + return false; + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From a9fed97547a698c7641aae53758deec6102f3360 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 12:36:23 -0500 Subject: Created user class with fields name and password --- .../java/com/ufund/api/ufundapi/model/User.java | 26 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 12bbddc..ed34817 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -4,17 +4,35 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class User { - @JsonProperty("name") private String name; + @JsonProperty("name") private final String name; + @JsonProperty("password") private String password; /** * Create a new user - * - * @param name The name of the user + * + * @param name The name of the user + * @param password The password of the user + * @param id The unique ID of the user */ public User(String name) { this.name = name; } - + /** + * Create a deep copy of another user + * + * @param other The user to copy from + */ + public User(User other) { + this.name = other.name; + } + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } } -- cgit v1.2.3 From d775671c878a15a138d16efd70138e3a4fbec7d7 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 12:36:51 -0500 Subject: Modified UserDAO to have correct methods and paramters for the userFileDAO --- .../ufund/api/ufundapi/persistence/UserDAO.java | 63 +++++++++------------- 1 file changed, 26 insertions(+), 37 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java index df797b9..5926214 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java @@ -2,83 +2,72 @@ package com.ufund.api.ufundapi.persistence; import java.io.IOException; -import com.ufund.api.ufundapi.model.Need; +import com.ufund.api.ufundapi.model.User; + /** - * Defines the interface for Need object persistence + * Defines the interface for User object persistence * * @author Team 2B Jelly Solutions */ public interface UserDAO { /** - * Retrieves all {@linkplain Need needs} - * - * @return An array of {@link Need need} objects, may be empty - * - * @throws IOException if an issue with underlying storage - */ - Need[] getUsers() throws IOException; - - /** - * Finds all {@linkplain Need needs} whose name contains the given text - * - * @param targetName The text to match against + * Retrieves all {@linkplain User users} * - * @return An array of {@link Need needs} whose names contains the given text, - * may be empty + * @return An array of {@link User user} objects, may be empty * * @throws IOException if an issue with underlying storage */ - Need[] findUsers(String targetName) throws IOException; + User[] getUsers() throws IOException; /** - * Retrieves a {@linkplain Need need} with the given name + * Retrieves a {@linkplain User user} with the given name * - * @param id The ID of the {@link Need need} to get + * @param id The ID of the {@link User user} to get * - * @return a {@link Need need} object with the matching name + * @return a {@link User user} object with the matching name *
- * null if no {@link Need need} with a matching name is found + * null if no {@link User user} with a matching name is found * * @throws IOException if an issue with underlying storage */ - Need getUser(int id) throws IOException; + User getUser(String name) throws IOException; /** - * Creates and saves a {@linkplain Need need} + * Creates and saves a {@linkplain User user} * - * @param need {@linkplain Need need} object to be created and saved + * @param user {@linkplain User user} object to be created and saved *
- * The id of the need object is automatically incremented. + * The id of the user object is automatically incremented. * - * @return new {@link Need need} if successful, null otherwise + * @return new {@link User user} if successful, null otherwise * * @throws IOException if an issue with underlying storage */ - Need createNeed(Need need) throws IOException; + User createUser(User user) throws IOException; /** - * Updates and saves a {@linkplain Need need} + * Updates and saves a {@linkplain User user} * - * @param need {@link Need need} object to be updated and saved + * @param user {@link User user} object to be updated and saved * - * @return updated {@link Need need} if successful, null if - * {@link Need need} could not be found + * @return updated {@link User user} if successful, null if + * {@link User user} could not be found * * @throws IOException if underlying storage cannot be accessed */ - Need updateNeed(Need need) throws IOException; + User updateUser(User user) throws IOException; /** - * Deletes a {@linkplain Need need} with the given id + * Deletes a {@linkplain User user} with the given id * - * @param id The id of the {@link Need need} + * @param id The id of the {@link User user} * - * @return true if the {@link Need need} was deleted + * @return true if the {@link User user} was deleted *
- * false if the need with the given id does not exist + * false if the user with the given id does not exist * * @throws IOException if underlying storage cannot be accessed */ - boolean deleteNeed(int id) throws IOException; + boolean deleteUser(String name) throws IOException; } -- cgit v1.2.3 From a52c511db3743a9be027672b353a16651b37a2bb Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 12:37:07 -0500 Subject: Implemented CRUD operations and helper methods --- .../api/ufundapi/persistence/UserFileDAO.java | 126 +++++++++------------ 1 file changed, 56 insertions(+), 70 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java index 87b8103..c42d211 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -9,27 +9,20 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; -import com.ufund.api.ufundapi.model.Need; +import com.ufund.api.ufundapi.model.User; @Component public class UserFileDAO implements UserDAO { - private final Map needs; // cache + private final Map users; // cache private final ObjectMapper objectMapper; - private static int nextId; private final String filename; public UserFileDAO(@Value("${users.file}") String filename, ObjectMapper objectMapper) throws IOException { this.filename = filename; this.objectMapper = objectMapper; - needs = new TreeMap<>(); - load(); // load the heroes from the file - } - - private synchronized static int nextId() { - int id = nextId; - nextId++; - return id; + users = new TreeMap<>(); + load(); // load the users from the file } /** @@ -38,39 +31,13 @@ public class UserFileDAO implements UserDAO { * @throws IOException Any IO issue with the file */ private void load() throws IOException { - needs.clear(); - nextId = 0; + users.clear(); - Need[] needsArray = objectMapper.readValue(new File(filename), Need[].class); + User[] usersArray = objectMapper.readValue(new File(filename), User[].class); - for (Need need : needsArray) { - needs.put(need.getId(), need); - if (need.getId() > nextId()) { - nextId = need.getId(); - } + for (User user : usersArray) { + users.put(user.getName(), user); } - nextId++; - } - - /** - * Return an array of the needs - * - * @return An array of all the needs - */ - private Need[] getNeedsArray() { - return needs.values().toArray(Need[]::new); - } - - /** - * Returns an array of needs filtered by a search - * - * @param search The search substring - * @return The requested array - */ - private Need[] getNeedsArray(String search) { - return needs.values().stream() - .filter(i -> i.getName().toLowerCase().contains(search.toLowerCase())) - .toArray(Need[]::new); } /** @@ -80,67 +47,86 @@ public class UserFileDAO implements UserDAO { * @throws IOException If there was an IO issue saving the file */ private boolean save() throws IOException { - Need[] needArray = getNeedsArray(); + User[] userArray = getUserArray(); - objectMapper.writeValue(new File(filename), needArray); + objectMapper.writeValue(new File(filename), userArray); return true; } - @Override - public Need[] getNeeds() { - synchronized (needs) { - return getNeedsArray(); - } + /** + * Return an array of the needs + * + * @return An array of all the needs + */ + private User[] getUserArray() { + return users.values().toArray(User[]::new); } + @Override - public Need[] findNeeds(String targetName) { - synchronized (needs) { - return getNeedsArray(targetName); + public User[] getUsers() throws IOException { + synchronized (users) { + return getUserArray(); } } + /** + * Return the user with the String name name or null otherwise + * + * @param name Name of desired user + * + * @return Desired user, null otherwise + * @throws IOException If there was an IO issue saving the file + */ @Override - public Need getNeed(int id) { - synchronized (needs) { - return needs.getOrDefault(id, null); + public User getUser(String name) throws IOException { + synchronized (users) { + return users.getOrDefault(name, null); } } + /** + * Return the user with the String name name or null otherwise + * + * @param name Name of desired user + * + * @return Desired user, null otherwise + * @throws IOException If there was an IO issue saving the file + */ @Override - public Need createNeed(Need need) throws IOException { - synchronized (needs) { - Need newNeed = new Need(need); - newNeed.setID(nextId()); - needs.put(newNeed.getId(), newNeed); + public User createUser(User user) throws IOException { + synchronized (users) { + User newUser = new User(user); + users.put(newUser.getName(), newUser); save(); - return newNeed; + return newUser; } } @Override - public Need updateNeed(Need need) throws IOException { - synchronized (needs) { - if (needs.containsKey(need.getId())) { - needs.put(need.getId(), need); + public User updateUser(User user) throws IOException { + synchronized (users) { + if (users.containsKey(user.getName())) { + users.put(user.getName(), user); save(); - return need; + return user; } else { return null; } - } } @Override - public boolean deleteNeed(int id) throws IOException { - synchronized (needs) { - if (needs.containsKey(id)) { - needs.remove(id); + public boolean deleteUser(String name) throws IOException { + synchronized (users) { + if (users.containsKey(name)) { + users.remove(name); return save(); } else { return false; } } } + + } \ No newline at end of file -- cgit v1.2.3 From cbcd49f2b96dffe359b99b8791ccfb62cbd4717f Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 13:18:18 -0500 Subject: Updated and added more javadocs. Also modified updateUser method to take a string name to use to find desired user to update. --- .../ufund/api/ufundapi/persistence/UserDAO.java | 5 ++-- .../api/ufundapi/persistence/UserFileDAO.java | 33 ++++++++++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java index 5926214..d456abc 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserDAO.java @@ -49,14 +49,15 @@ public interface UserDAO { /** * Updates and saves a {@linkplain User user} * - * @param user {@link User user} object to be updated and saved + * @param newUser {@link User user} object to be updated and saved + * @param name {@link String name} name of object to be updated * * @return updated {@link User user} if successful, null if * {@link User user} could not be found * * @throws IOException if underlying storage cannot be accessed */ - User updateUser(User user) throws IOException; + User updateUser(User newUser, String name) throws IOException; /** * Deletes a {@linkplain User user} with the given id diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java index c42d211..ebfa9f2 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -62,7 +62,6 @@ public class UserFileDAO implements UserDAO { return users.values().toArray(User[]::new); } - @Override public User[] getUsers() throws IOException { synchronized (users) { @@ -86,11 +85,11 @@ public class UserFileDAO implements UserDAO { } /** - * Return the user with the String name name or null otherwise + * Create a User user * - * @param name Name of desired user + * @param user User to create * - * @return Desired user, null otherwise + * @return Desired created user * @throws IOException If there was an IO issue saving the file */ @Override @@ -103,19 +102,36 @@ public class UserFileDAO implements UserDAO { } } + /** + * Update a user that matches the supplied name + * + * @param name The name of the user + * @param newUser New user data + * + * @return Desired user, null otherwise + * @throws IOException If there was an IO issue saving the file + */ @Override - public User updateUser(User user) throws IOException { + public User updateUser(User newUser, String name) throws IOException { synchronized (users) { - if (users.containsKey(user.getName())) { - users.put(user.getName(), user); + if (users.containsKey(name)) { + users.put(name, newUser); save(); - return user; + return newUser; } else { return null; } } } + /** + * Delete a user matching the name + * + * @param name The name of the user + * + * @return True if deleted, false otherwise + * @throws IOException If there was an IO issue saving the file + */ @Override public boolean deleteUser(String name) throws IOException { synchronized (users) { @@ -128,5 +144,4 @@ public class UserFileDAO implements UserDAO { } } - } \ No newline at end of file -- cgit v1.2.3 From 380b0ca3f3ebd1564d2e961a67e0fc8a8dac80f2 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 13:22:33 -0500 Subject: Created UserController class to handle http requests --- .../api/ufundapi/controller/UserController.java | 170 +++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java new file mode 100644 index 0000000..223963d --- /dev/null +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -0,0 +1,170 @@ +package com.ufund.api.ufundapi.controller; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.ufund.api.ufundapi.model.Need; +import com.ufund.api.ufundapi.persistence.UserDAO; + +@RestController +@RequestMapping("cupboard") +public class UserController { + private static final Logger LOG = Logger.getLogger(CupboardController.class.getName()); + private final UserDAO UserDAO; + + /** + * Create a cupboard controller to receive REST signals + * + * @param UserDAO The Data Access Object + */ + public UserController(UserDAO userDAO) { + this.UserDAO = userDAO; + } + + /** + * Creates a Need with the provided object + * + * @param need The need to create + * @return OK response and the need if it was successful, INTERNAL_SERVER_ERROR otherwise + */ + @PostMapping("") + public ResponseEntity createUser(@RequestBody Need need) { + try { + if (need.getMaxGoal() <= 0) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + if (need.getMaxGoal() < need.getCurrent()) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + UserDAO.createNeed(need); + return new ResponseEntity<>(need, HttpStatus.OK); + } catch (IOException ex) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** + * Responds to the GET request for all {@linkplain Need needs} + * + * @return ResponseEntity with array of {@link Need needs} objects (may be empty) + * and + * HTTP status of OK
+ * ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise + */ + @GetMapping("") + public ResponseEntity getNeeds() { + LOG.info("GET /needs"); + + try { + Need[] needs = UserDAO.getNeeds(); + return new ResponseEntity<>(needs, HttpStatus.OK); + } catch (IOException e) { + LOG.log(Level.SEVERE, e.getLocalizedMessage()); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** + * Responds to the GET request for all {@linkplain Need need} whose name contains + * the text in name + * + * @param name The name parameter which contains the text used to find the {@link Need need} + * + * @return ResponseEntity with array of {@link Need need} objects (may be empty) and + * HTTP status of OK
+ * ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise + *

+ */ + @GetMapping("/") + public ResponseEntity searchNeeds(@RequestParam String name) { + LOG.info("GET /need/?name="+name); + + try { + Need[] needArray = UserDAO.findNeeds(name); + return new ResponseEntity<>(needArray, HttpStatus.OK); + } catch (IOException e) { + LOG.log(Level.SEVERE,e.getLocalizedMessage()); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** + * Responds to the GET request for a {@linkplain Need need} for the given id + * + * @param id The id used to locate the {@link Need need} + * + * @return ResponseEntity with {@link Need need} object and HTTP status of OK if + * found
+ * ResponseEntity with HTTP status of NOT_FOUND if not found
+ * ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise + */ + @GetMapping("/{id}") + public ResponseEntity getNeed(@PathVariable int id) { + LOG.log(Level.INFO, "GET /need/{0}", id); + + try { + Need need = UserDAO.getNeed(id); + if (need != null) { + return new ResponseEntity<>(need, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + } catch (IOException e) { + LOG.log(Level.SEVERE, e.getLocalizedMessage()); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + /** + * Updates a Need with the provided one + * + * @param need The need to update + * @return OK response and the need if it was successful, or INTERNAL_SERVER_ERROR if there was an issue + */ + + @PutMapping("") + public ResponseEntity updateNeed(@RequestBody Need need) { + try { + need = UserDAO.updateNeed(need); + return new ResponseEntity<>(need, HttpStatus.OK); + } catch (IOException e) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** + * Deletes a single need from the cupboard using the Need's id + * + * @param id The need's ID + * @return OK if the need was deleted, NOT_FOUND if the need was not found, or INTERNAL_SERVER_ERROR if an error occurred + */ + @DeleteMapping("/{id}") + public ResponseEntity deleteNeed(@PathVariable int id) { + try { + if (UserDAO.getNeed(id) != null) { + UserDAO.deleteNeed(id); + return new ResponseEntity<>(HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } catch (IOException e) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + +} -- cgit v1.2.3 From 0d1c11aa2738a622fc2ee6ecb23aef214c9520db Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 13:33:03 -0500 Subject: Implemented createUser in the controller and modified logic in the UserFileDAO to check for conflict --- .../ufund/api/ufundapi/controller/UserController.java | 16 +++++++--------- .../com/ufund/api/ufundapi/persistence/UserFileDAO.java | 12 ++++++++---- 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java index 223963d..bf3f7a1 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.ufund.api.ufundapi.model.Need; +import com.ufund.api.ufundapi.model.User; import com.ufund.api.ufundapi.persistence.UserDAO; @RestController @@ -41,16 +41,14 @@ public class UserController { * @return OK response and the need if it was successful, INTERNAL_SERVER_ERROR otherwise */ @PostMapping("") - public ResponseEntity createUser(@RequestBody Need need) { + public ResponseEntity createUser(@RequestBody User user) { try { - if (need.getMaxGoal() <= 0) { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - if (need.getMaxGoal() < need.getCurrent()) { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + if (UserDAO.createUser(user) != null) { + return new ResponseEntity<>(user, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.CONFLICT); } - UserDAO.createNeed(need); - return new ResponseEntity<>(need, HttpStatus.OK); + } catch (IOException ex) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java index ebfa9f2..0f30824 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -95,10 +95,14 @@ public class UserFileDAO implements UserDAO { @Override public User createUser(User user) throws IOException { synchronized (users) { - User newUser = new User(user); - users.put(newUser.getName(), newUser); - save(); - return newUser; + if (getUser(user.getName()) != null) { + User newUser = new User(user); + users.put(newUser.getName(), newUser); + save(); + return newUser; + } else { + return null; + } } } -- cgit v1.2.3 From 03799f252ad2fb207e256fe7eff7ad0600131b7d Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 15:30:04 -0500 Subject: Updated javadocs and implemented additional CRUD operations --- .../api/ufundapi/controller/UserController.java | 94 +++++++++------------- 1 file changed, 36 insertions(+), 58 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java index bf3f7a1..ae75179 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -13,7 +13,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.ufund.api.ufundapi.model.User; @@ -35,10 +34,10 @@ public class UserController { } /** - * Creates a Need with the provided object + * Creates a User with the provided object * - * @param need The need to create - * @return OK response and the need if it was successful, INTERNAL_SERVER_ERROR otherwise + * @param user The user to create + * @return OK response and the user if it was successful, INTERNAL_SERVER_ERROR otherwise */ @PostMapping("") public ResponseEntity createUser(@RequestBody User user) { @@ -55,68 +54,44 @@ public class UserController { } /** - * Responds to the GET request for all {@linkplain Need needs} + * Responds to the GET request for all {@linkplain User user} * - * @return ResponseEntity with array of {@link Need needs} objects (may be empty) + * @return ResponseEntity with array of {@link User user} objects (may be empty) * and * HTTP status of OK
* ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise */ @GetMapping("") - public ResponseEntity getNeeds() { - LOG.info("GET /needs"); + public ResponseEntity getUseers() { + LOG.info("GET /users"); try { - Need[] needs = UserDAO.getNeeds(); - return new ResponseEntity<>(needs, HttpStatus.OK); + User[] users = UserDAO.getUsers(); + return new ResponseEntity<>(users, HttpStatus.OK); } catch (IOException e) { LOG.log(Level.SEVERE, e.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } - /** - * Responds to the GET request for all {@linkplain Need need} whose name contains - * the text in name - * - * @param name The name parameter which contains the text used to find the {@link Need need} - * - * @return ResponseEntity with array of {@link Need need} objects (may be empty) and - * HTTP status of OK
- * ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise - *

- */ - @GetMapping("/") - public ResponseEntity searchNeeds(@RequestParam String name) { - LOG.info("GET /need/?name="+name); - - try { - Need[] needArray = UserDAO.findNeeds(name); - return new ResponseEntity<>(needArray, HttpStatus.OK); - } catch (IOException e) { - LOG.log(Level.SEVERE,e.getLocalizedMessage()); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } - /** - * Responds to the GET request for a {@linkplain Need need} for the given id + * Responds to the GET request for a {@linkplain User user} for the given id * - * @param id The id used to locate the {@link Need need} + * @param id The id used to locate the {@link User user} * - * @return ResponseEntity with {@link Need need} object and HTTP status of OK if + * @return ResponseEntity with {@link User user} object and HTTP status of OK if * found
* ResponseEntity with HTTP status of NOT_FOUND if not found
* ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise */ - @GetMapping("/{id}") - public ResponseEntity getNeed(@PathVariable int id) { - LOG.log(Level.INFO, "GET /need/{0}", id); + @GetMapping("/{name}") + public ResponseEntity getUser(@PathVariable String name) { + LOG.log(Level.INFO, "GET /user/{0}", name); try { - Need need = UserDAO.getNeed(id); - if (need != null) { - return new ResponseEntity<>(need, HttpStatus.OK); + User user = UserDAO.getUser(name); + if (user != null) { + return new ResponseEntity<>(user, HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } @@ -129,33 +104,36 @@ public class UserController { } /** - * Updates a Need with the provided one - * - * @param need The need to update - * @return OK response and the need if it was successful, or INTERNAL_SERVER_ERROR if there was an issue + * Updates a User with the provided one + * + * @param user The user to update + * @return OK response and the user if it was successful, or INTERNAL_SERVER_ERROR if there was an issue */ - @PutMapping("") - public ResponseEntity updateNeed(@RequestBody Need need) { + public ResponseEntity updateUser(@RequestBody User user, String string) { try { - need = UserDAO.updateNeed(need); - return new ResponseEntity<>(need, HttpStatus.OK); + user = UserDAO.updateUser(user, string); + if (user != null) { + return new ResponseEntity<>(user, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } catch (IOException e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } /** - * Deletes a single need from the cupboard using the Need's id + * Deletes a user with the desired name * - * @param id The need's ID - * @return OK if the need was deleted, NOT_FOUND if the need was not found, or INTERNAL_SERVER_ERROR if an error occurred + * @param name The name of the user + * @return OK if the user was deleted, NOT_FOUND if the user was not found, or INTERNAL_SERVER_ERROR if an error occurred */ - @DeleteMapping("/{id}") - public ResponseEntity deleteNeed(@PathVariable int id) { + @DeleteMapping("/{name}") + public ResponseEntity deleteUser(@PathVariable String name) { try { - if (UserDAO.getNeed(id) != null) { - UserDAO.deleteNeed(id); + if (UserDAO.deleteUser(name)) { return new ResponseEntity<>(HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); -- cgit v1.2.3 From 72d614074a3cd578322931af647c6f0a65a23dfd Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 16:00:35 -0500 Subject: Tested user http calls and fixed update user --- .../api/ufundapi/controller/UserController.java | 27 ++++++++++++---------- .../java/com/ufund/api/ufundapi/model/User.java | 3 +-- .../api/ufundapi/persistence/UserFileDAO.java | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java index ae75179..1af865d 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -19,13 +19,13 @@ import com.ufund.api.ufundapi.model.User; import com.ufund.api.ufundapi.persistence.UserDAO; @RestController -@RequestMapping("cupboard") +@RequestMapping("users") public class UserController { private static final Logger LOG = Logger.getLogger(CupboardController.class.getName()); private final UserDAO UserDAO; /** - * Create a cupboard controller to receive REST signals + * Create a user controller to receive REST signals * * @param UserDAO The Data Access Object */ @@ -37,7 +37,8 @@ public class UserController { * Creates a User with the provided object * * @param user The user to create - * @return OK response and the user if it was successful, INTERNAL_SERVER_ERROR otherwise + * @return OK response and the user if it was successful, INTERNAL_SERVER_ERROR + * otherwise */ @PostMapping("") public ResponseEntity createUser(@RequestBody User user) { @@ -47,7 +48,7 @@ public class UserController { } else { return new ResponseEntity<>(HttpStatus.CONFLICT); } - + } catch (IOException ex) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } @@ -107,18 +108,19 @@ public class UserController { * Updates a User with the provided one * * @param user The user to update - * @return OK response and the user if it was successful, or INTERNAL_SERVER_ERROR if there was an issue + * @return OK response and the user if it was successful, or + * INTERNAL_SERVER_ERROR if there was an issue */ - @PutMapping("") - public ResponseEntity updateUser(@RequestBody User user, String string) { + @PutMapping("/{name}") + public ResponseEntity updateUser(@RequestBody User user, @PathVariable String name) { try { - user = UserDAO.updateUser(user, string); + user = UserDAO.updateUser(user, name); if (user != null) { return new ResponseEntity<>(user, HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - + } catch (IOException e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } @@ -128,8 +130,9 @@ public class UserController { * Deletes a user with the desired name * * @param name The name of the user - * @return OK if the user was deleted, NOT_FOUND if the user was not found, or INTERNAL_SERVER_ERROR if an error occurred - */ + * @return OK if the user was deleted, NOT_FOUND if the user was not found, or + * INTERNAL_SERVER_ERROR if an error occurred + */ @DeleteMapping("/{name}") public ResponseEntity deleteUser(@PathVariable String name) { try { @@ -137,7 +140,7 @@ public class UserController { return new ResponseEntity<>(HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } + } } catch (IOException e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index ed34817..2086d45 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -12,9 +12,8 @@ public class User { * * @param name The name of the user * @param password The password of the user - * @param id The unique ID of the user */ - public User(String name) { + public User(@JsonProperty("name") String name) { this.name = name; } diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java index 0f30824..18eec18 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/persistence/UserFileDAO.java @@ -95,7 +95,7 @@ public class UserFileDAO implements UserDAO { @Override public User createUser(User user) throws IOException { synchronized (users) { - if (getUser(user.getName()) != null) { + if (getUser(user.getName()) == null) { User newUser = new User(user); users.put(newUser.getName(), newUser); save(); @@ -131,7 +131,7 @@ public class UserFileDAO implements UserDAO { /** * Delete a user matching the name * - * @param name The name of the user + * @param name The name of the user * * @return True if deleted, false otherwise * @throws IOException If there was an IO issue saving the file -- cgit v1.2.3 From 173ebb5f2efb328f96cbd17d8bbe4acc07e74b84 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 16:23:03 -0500 Subject: Added basket field to User --- ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 2086d45..011aeef 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -1,11 +1,14 @@ package com.ufund.api.ufundapi.model; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; public class User { @JsonProperty("name") private final String name; @JsonProperty("password") private String password; + @JsonProperty("basket") private final List basket; /** * Create a new user @@ -13,8 +16,9 @@ public class User { * @param name The name of the user * @param password The password of the user */ - public User(@JsonProperty("name") String name) { + public User(@JsonProperty("name") String name, @JsonProperty("basket") List basket) { this.name = name; + this.basket = basket; } /** @@ -24,6 +28,7 @@ public class User { */ public User(User other) { this.name = other.name; + this.basket = other.basket; } public String getName() { -- cgit v1.2.3 From 98b66c0ccc3e555879f8d68bd61ea573184e4b3c Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 17:00:54 -0500 Subject: Removed getUsers method --- .../api/ufundapi/controller/UserController.java | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java index 1af865d..a40c46f 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/controller/UserController.java @@ -54,27 +54,6 @@ public class UserController { } } - /** - * Responds to the GET request for all {@linkplain User user} - * - * @return ResponseEntity with array of {@link User user} objects (may be empty) - * and - * HTTP status of OK
- * ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise - */ - @GetMapping("") - public ResponseEntity getUseers() { - LOG.info("GET /users"); - - try { - User[] users = UserDAO.getUsers(); - return new ResponseEntity<>(users, HttpStatus.OK); - } catch (IOException e) { - LOG.log(Level.SEVERE, e.getLocalizedMessage()); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } - /** * Responds to the GET request for a {@linkplain User user} for the given id * -- cgit v1.2.3 From 12f3e55bb7385e84c8296a8dd008584990429ae7 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 17:02:03 -0500 Subject: Added another constructor, verify password method, and basket methods --- .../java/com/ufund/api/ufundapi/model/User.java | 35 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 011aeef..1136481 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -1,5 +1,6 @@ package com.ufund.api.ufundapi.model; +import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; @@ -7,14 +8,24 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class User { @JsonProperty("name") private final String name; - @JsonProperty("password") private String password; + @JsonProperty("passwordHash") private String passwordHash; @JsonProperty("basket") private final List basket; /** * Create a new user * - * @param name The name of the user - * @param password The password of the user + * @param name The name of the user + */ + public User(@JsonProperty("name") String name) { + this.name = name; + basket = new ArrayList<>(); + } + + /** + * Create a new user + * + * @param name The name of the user + * @param basket A basket to copy from */ public User(@JsonProperty("name") String name, @JsonProperty("basket") List basket) { this.name = name; @@ -35,8 +46,20 @@ public class User { return name; } - public String getPassword() { - return password; + public boolean verifyPassword(String password) { + return password.equals(passwordHash); } - + + public void addToBasket(Need need) { + basket.add(need); + } + + public Need[] getBasketNeeds() { + return basket.toArray(Need[]::new); + } + + public void removeBasketNeed(Need need) { + basket.remove(need); + } + } -- cgit v1.2.3 From da74d5c7e67b873dc8fdbfc672891eb63c0b8ea2 Mon Sep 17 00:00:00 2001 From: Gunther6070 Date: Wed, 26 Feb 2025 17:10:27 -0500 Subject: Made verifyPassword actually hash the input password --- .../src/main/java/com/ufund/api/ufundapi/model/User.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'ufund-api/src/main/java') diff --git a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java index 1136481..0a61714 100644 --- a/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java +++ b/ufund-api/src/main/java/com/ufund/api/ufundapi/model/User.java @@ -7,9 +7,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class User { - @JsonProperty("name") private final String name; - @JsonProperty("passwordHash") private String passwordHash; - @JsonProperty("basket") private final List basket; + @JsonProperty("name") + private final String name; + @JsonProperty("passwordHash") + private int passwordHash; + @JsonProperty("basket") + private final List basket; /** * Create a new user @@ -47,7 +50,7 @@ public class User { } public boolean verifyPassword(String password) { - return password.equals(passwordHash); + return password.hashCode() == passwordHash; } public void addToBasket(Need need) { -- cgit v1.2.3