From 03aef8f4b5486729869a5c117326b576f6c7d990 Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Mon, 4 Nov 2024 11:29:50 -0500 Subject: [PATCH 001/113] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e1d8b77c..7e5c9867f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ -# Note Application +# Spotify Soundsmiths + +## Team Members + +- Teddy Yang (teddyyang8) + +## Starter Readme Below This is a minimal example demonstrating usage of the password-protected user part of the API used in lab 5. From e6fde91cd365da738cf8477a0ffc0df80f8e3afc Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:30:46 -0500 Subject: [PATCH 002/113] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e5c9867f..4bb8614c8 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ## Team Members - Teddy Yang (teddyyang8) +- Shirley Zhang (shirleyyzhang) ## Starter Readme Below From 6a3b9a5ba3ccf50ed001750f585bf096bf7f21bd Mon Sep 17 00:00:00 2001 From: yasmatopia <163909616+yasmatopia@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:30:59 -0500 Subject: [PATCH 003/113] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e5c9867f..213fddfcd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Team Members - Teddy Yang (teddyyang8) - +- Yasmina Mimassi (yasmatopia) ## Starter Readme Below This is a minimal example demonstrating usage of the From 742c7a8f252009348f3a8264f425374dc563dbe4 Mon Sep 17 00:00:00 2001 From: Ray Fang <155117488+rayf5372@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:38:07 -0500 Subject: [PATCH 004/113] Update README.md Added username - Ray --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4ac8bb25..d4c233281 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - Teddy Yang (teddyyang8) - Yasmina Mimassi (yasmatopia) - Shirley Zhang (shirleyyzhang) -- +- Ray Fang (rayf5372) ## Starter Readme Below This is a minimal example demonstrating usage of the From 307f9a30bccd5fe23b1afb9bc9e6bde109bc77c6 Mon Sep 17 00:00:00 2001 From: seanwoo12 <160199751+seanwoo12@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:39:09 -0500 Subject: [PATCH 005/113] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d4c233281..2b4f88b7e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ - Yasmina Mimassi (yasmatopia) - Shirley Zhang (shirleyyzhang) - Ray Fang (rayf5372) +- Sean Woo (seanwoo12) ## Starter Readme Below This is a minimal example demonstrating usage of the From 1f48f5cdc7fb3c810ac07141293b2d2a08b286e5 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:27:58 -0500 Subject: [PATCH 006/113] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b4f88b7e..7fa7754db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Spotify Soundsmiths +# Travel Advisors ## Team Members From c9057b9ea03ba7bed72a4c60ff4a662886027705 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:27:05 -0500 Subject: [PATCH 007/113] Created place entity and cleaned use case folder --- .idea/vcs.xml | 2 +- src/main/java/app/MainNoteApplication.java | 2 +- src/main/java/app/NoteAppBuilder.java | 6 ++--- .../data_access/DBNoteDataAccessObject.java | 4 ++-- src/main/java/entity/Place.java | 24 +++++++++++++++++++ .../note/NoteController.java | 2 +- .../interface_adapter/note/NotePresenter.java | 2 +- .../{note => }/DataAccessException.java | 2 +- .../{note => }/NoteDataAccessInterface.java | 2 +- .../{note => }/NoteInputBoundary.java | 2 +- .../use_case/{note => }/NoteInteractor.java | 2 +- .../{note => }/NoteOutputBoundary.java | 2 +- .../java/app/MainNoteApplicationTest.java | 2 +- .../{note => }/NoteInteractorTest.java | 2 +- 14 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 src/main/java/entity/Place.java rename src/main/java/use_case/{note => }/DataAccessException.java (89%) rename src/main/java/use_case/{note => }/NoteDataAccessInterface.java (97%) rename src/main/java/use_case/{note => }/NoteInputBoundary.java (94%) rename src/main/java/use_case/{note => }/NoteInteractor.java (98%) rename src/main/java/use_case/{note => }/NoteOutputBoundary.java (95%) rename src/test/java/use_case/{note => }/NoteInteractorTest.java (97%) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f4..35eb1ddfb 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java index c37860156..6a34b4576 100644 --- a/src/main/java/app/MainNoteApplication.java +++ b/src/main/java/app/MainNoteApplication.java @@ -1,7 +1,7 @@ package app; import data_access.DBNoteDataAccessObject; -import use_case.note.NoteDataAccessInterface; +import use_case.NoteDataAccessInterface; /** * An application where we can view and add to a note stored by a user. diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java index a68cb9ad6..10c2e072b 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/NoteAppBuilder.java @@ -6,9 +6,9 @@ import interface_adapter.note.NoteController; import interface_adapter.note.NotePresenter; import interface_adapter.note.NoteViewModel; -import use_case.note.NoteDataAccessInterface; -import use_case.note.NoteInteractor; -import use_case.note.NoteOutputBoundary; +import use_case.NoteDataAccessInterface; +import use_case.NoteInteractor; +import use_case.NoteOutputBoundary; import view.NoteView; /** diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java index dadb0cab0..1306b9e1c 100644 --- a/src/main/java/data_access/DBNoteDataAccessObject.java +++ b/src/main/java/data_access/DBNoteDataAccessObject.java @@ -11,8 +11,8 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import use_case.note.DataAccessException; -import use_case.note.NoteDataAccessInterface; +import use_case.DataAccessException; +import use_case.NoteDataAccessInterface; /** * The DAO for accessing notes stored in the database. diff --git a/src/main/java/entity/Place.java b/src/main/java/entity/Place.java new file mode 100644 index 000000000..8d3d122a2 --- /dev/null +++ b/src/main/java/entity/Place.java @@ -0,0 +1,24 @@ +package entity; + +/** + * The representation of a place/destination for our program. + */ +public class Place { + + private final String name; + private final String address; + + public Place(String name, String address) { + this.name = name; + this.address = address; + } + + public String getName() { + return name; + } + + public String getAddress() { + return address; + } + +} diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java index e3e5dfb32..fbd2d3a41 100644 --- a/src/main/java/interface_adapter/note/NoteController.java +++ b/src/main/java/interface_adapter/note/NoteController.java @@ -1,6 +1,6 @@ package interface_adapter.note; -import use_case.note.NoteInputBoundary; +import use_case.NoteInputBoundary; /** * Controller for our Note related Use Cases. diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java index d4e416165..0d1b784c7 100644 --- a/src/main/java/interface_adapter/note/NotePresenter.java +++ b/src/main/java/interface_adapter/note/NotePresenter.java @@ -1,6 +1,6 @@ package interface_adapter.note; -import use_case.note.NoteOutputBoundary; +import use_case.NoteOutputBoundary; /** * The presenter for our Note viewing and editing program. diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/DataAccessException.java similarity index 89% rename from src/main/java/use_case/note/DataAccessException.java rename to src/main/java/use_case/DataAccessException.java index b8c17920d..59cf779b3 100644 --- a/src/main/java/use_case/note/DataAccessException.java +++ b/src/main/java/use_case/DataAccessException.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; /** * Exception thrown when there is an error with accessing data. diff --git a/src/main/java/use_case/note/NoteDataAccessInterface.java b/src/main/java/use_case/NoteDataAccessInterface.java similarity index 97% rename from src/main/java/use_case/note/NoteDataAccessInterface.java rename to src/main/java/use_case/NoteDataAccessInterface.java index b71597828..c5259f1e6 100644 --- a/src/main/java/use_case/note/NoteDataAccessInterface.java +++ b/src/main/java/use_case/NoteDataAccessInterface.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; import entity.User; diff --git a/src/main/java/use_case/note/NoteInputBoundary.java b/src/main/java/use_case/NoteInputBoundary.java similarity index 94% rename from src/main/java/use_case/note/NoteInputBoundary.java rename to src/main/java/use_case/NoteInputBoundary.java index b41da9bf5..161695d48 100644 --- a/src/main/java/use_case/note/NoteInputBoundary.java +++ b/src/main/java/use_case/NoteInputBoundary.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; /** * The Input Boundary for our note-related use cases. Since they are closely related, diff --git a/src/main/java/use_case/note/NoteInteractor.java b/src/main/java/use_case/NoteInteractor.java similarity index 98% rename from src/main/java/use_case/note/NoteInteractor.java rename to src/main/java/use_case/NoteInteractor.java index 369e9309a..9ce666e96 100644 --- a/src/main/java/use_case/note/NoteInteractor.java +++ b/src/main/java/use_case/NoteInteractor.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; import entity.User; diff --git a/src/main/java/use_case/note/NoteOutputBoundary.java b/src/main/java/use_case/NoteOutputBoundary.java similarity index 95% rename from src/main/java/use_case/note/NoteOutputBoundary.java rename to src/main/java/use_case/NoteOutputBoundary.java index c0c2bb1d0..deea3046a 100644 --- a/src/main/java/use_case/note/NoteOutputBoundary.java +++ b/src/main/java/use_case/NoteOutputBoundary.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; /** * The output boundary for the Login Use Case. diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainNoteApplicationTest.java index 025d970e2..d62e389c1 100644 --- a/src/test/java/app/MainNoteApplicationTest.java +++ b/src/test/java/app/MainNoteApplicationTest.java @@ -3,7 +3,7 @@ import entity.User; import org.junit.Before; import org.junit.Test; -import use_case.note.NoteDataAccessInterface; +import use_case.NoteDataAccessInterface; import javax.swing.*; import java.awt.*; diff --git a/src/test/java/use_case/note/NoteInteractorTest.java b/src/test/java/use_case/NoteInteractorTest.java similarity index 97% rename from src/test/java/use_case/note/NoteInteractorTest.java rename to src/test/java/use_case/NoteInteractorTest.java index a3ed466b6..4b3933e4c 100644 --- a/src/test/java/use_case/note/NoteInteractorTest.java +++ b/src/test/java/use_case/NoteInteractorTest.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case; import entity.User; import org.junit.Test; From a10c90227928c1552ec51bf0f909221cf7a4e212 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 16:48:09 -0500 Subject: [PATCH 008/113] added location dao --- .gitignore | 4 +- src/main/java/app/MainNoteApplication.java | 4 +- .../DBLocationDataAccessObject.java | 70 ++++++++++++ .../data_access/DBNoteDataAccessObject.java | 107 ------------------ .../note/LocationDataAccessInterface.java | 18 +++ .../note/NoteDataAccessInterface.java | 30 ----- 6 files changed, 93 insertions(+), 140 deletions(-) create mode 100644 src/main/java/data_access/DBLocationDataAccessObject.java delete mode 100644 src/main/java/data_access/DBNoteDataAccessObject.java create mode 100644 src/main/java/use_case/note/LocationDataAccessInterface.java delete mode 100644 src/main/java/use_case/note/NoteDataAccessInterface.java diff --git a/.gitignore b/.gitignore index 650c91720..a87051d46 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,6 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store + +api_key.txt \ No newline at end of file diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java index c37860156..a51dc8edc 100644 --- a/src/main/java/app/MainNoteApplication.java +++ b/src/main/java/app/MainNoteApplication.java @@ -1,6 +1,6 @@ package app; -import data_access.DBNoteDataAccessObject; +import data_access.DBLocationDataAccessObject; import use_case.note.NoteDataAccessInterface; /** @@ -46,7 +46,7 @@ public class MainNoteApplication { public static void main(String[] args) { // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject(); + final NoteDataAccessInterface noteDataAccess = new DBLocationDataAccessObject(); final NoteAppBuilder builder = new NoteAppBuilder(); builder.addNoteDAO(noteDataAccess) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java new file mode 100644 index 000000000..6a5d86448 --- /dev/null +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -0,0 +1,70 @@ +package data_access; + +import java.io.IOException; + +import org.json.JSONException; +import org.json.JSONObject; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import use_case.note.DataAccessException; +import use_case.note.LocationDataAccessInterface; + +/** + * The DAO for accessing places using Google Places API. + */ +public class DBLocationDataAccessObject implements LocationDataAccessInterface { + private static final int SUCCESS_CODE = 200; + private static final int CREDENTIAL_ERROR = 403; + private static final String API_HEADER = "X-Goog-Api-Key"; + private static final String API_FIELD = "X-Goog-FieldMask"; + private static final String FIELDS = "places.displayName,places.formattedAddress"; + private static final String CONTENT_TYPE_LABEL = "Content-Type"; + private static final String CONTENT_TYPE_JSON = "application/json"; + private static final String STATUS_CODE_LABEL = "status_code"; + private static final String MESSAGE = "message"; + + public static String getKey() { + return System.getenv("api_key"); + } + + @Override + public String searchLocation(String address, String locationType) throws DataAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + + // POST METHOD + final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON); + final JSONObject requestBody = new JSONObject(); + requestBody.put("textQuery", locationType + " near " + address); + final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); + final Request request = new Request.Builder() + .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") + .method("POST", body) + .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) + .addHeader(API_HEADER, getKey()) + .addHeader(API_FIELD, FIELDS) + .build(); + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { + return responseBody.toString(); + } + else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { + throw new DataAccessException("Needs API Key"); + } + else { + throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); + } + } + catch (IOException | JSONException ex) { + throw new DataAccessException(ex.getMessage()); + } + } +} diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java deleted file mode 100644 index dadb0cab0..000000000 --- a/src/main/java/data_access/DBNoteDataAccessObject.java +++ /dev/null @@ -1,107 +0,0 @@ -package data_access; - -import java.io.IOException; - -import org.json.JSONException; -import org.json.JSONObject; - -import entity.User; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import use_case.note.DataAccessException; -import use_case.note.NoteDataAccessInterface; - -/** - * The DAO for accessing notes stored in the database. - *

This class demonstrates how your group can use the password-protected user - * endpoints of the API used in lab 5 to store persistent data in your program. - *

- *

You can also refer to the lab 5 code for signing up a new user and other use cases. - *

- * See - * - * the documentation - * of the API for more details. - */ -public class DBNoteDataAccessObject implements NoteDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final int CREDENTIAL_ERROR = 401; - private static final String CONTENT_TYPE_LABEL = "Content-Type"; - private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String STATUS_CODE_LABEL = "status_code"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - private static final String MESSAGE = "message"; - - @Override - public String saveNote(User user, String note) throws DataAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder() - .build(); - - // POST METHOD - final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON); - final JSONObject requestBody = new JSONObject(); - requestBody.put(USERNAME, user.getName()); - requestBody.put(PASSWORD, user.getPassword()); - final JSONObject extra = new JSONObject(); - extra.put("note", note); - requestBody.put("info", extra); - final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); - final Request request = new Request.Builder() - .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") - .method("PUT", body) - .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - return loadNote(user); - } - else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { - throw new DataAccessException("message could not be found or password was incorrect"); - } - else { - throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new DataAccessException(ex.getMessage()); - } - } - - @Override - public String loadNote(User user) throws DataAccessException { - // Make an API call to get the user object. - final String username = user.getName(); - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder() - .url(String.format("http://vm003.teach.cs.toronto.edu:20112/user?username=%s", username)) - .addHeader("Content-Type", CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - final JSONObject userJSONObject = responseBody.getJSONObject("user"); - final JSONObject data = userJSONObject.getJSONObject("info"); - return data.getString("note"); - } - else { - throw new DataAccessException(responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/use_case/note/LocationDataAccessInterface.java b/src/main/java/use_case/note/LocationDataAccessInterface.java new file mode 100644 index 000000000..c465a6cbf --- /dev/null +++ b/src/main/java/use_case/note/LocationDataAccessInterface.java @@ -0,0 +1,18 @@ +package use_case.note; + +/** + * Interface for the LocationDAO. It consists of methods for + * searching locations + */ +public interface LocationDataAccessInterface { + + /** + * Gets a list of locations based on address given. + * @param address address the user gives + * @param locationType the type of location + * @return a list of locations + * @throws DataAccessException if the location can not be loaded for any reason + */ + String searchLocation(String address, String locationType) throws DataAccessException; + +} diff --git a/src/main/java/use_case/note/NoteDataAccessInterface.java b/src/main/java/use_case/note/NoteDataAccessInterface.java deleted file mode 100644 index b71597828..000000000 --- a/src/main/java/use_case/note/NoteDataAccessInterface.java +++ /dev/null @@ -1,30 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * Interface for the NoteDAO. It consists of methods for - * both loading and saving a note. - */ -public interface NoteDataAccessInterface { - - /** - * Saves a note for a given user. This will replace any existing note. - *

The password of the user must match that of the user saved in the system.

- * @param user the user information associated with the note - * @param note the note to be saved - * @return the contents of the note - * @throws DataAccessException if the user's note can not be saved for any reason - */ - String saveNote(User user, String note) throws DataAccessException; - - /** - * Returns the note associated with the user. The password - * is not checked, so anyone can read the information. - * @param user the user information associated with the note - * @return the contents of the note - * @throws DataAccessException if the user's note can not be loaded for any reason - */ - String loadNote(User user) throws DataAccessException; - -} From 616fb94bfccaa2726a545027a60df6e1ba6d15ab Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Sun, 10 Nov 2024 16:55:58 -0500 Subject: [PATCH 009/113] Updated NoteView and NoteState --- .../interface_adapter/note/NoteState.java | 82 +++++++++- src/main/java/view/NoteView.java | 147 +++++++++++++----- 2 files changed, 185 insertions(+), 44 deletions(-) diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java index c5b2234d6..3bf0c74d2 100644 --- a/src/main/java/interface_adapter/note/NoteState.java +++ b/src/main/java/interface_adapter/note/NoteState.java @@ -1,26 +1,96 @@ package interface_adapter.note; +import java.util.ArrayList; +import java.util.List; + /** * The State for a note. - *

For this example, a note is simplay a string.

*/ public class NoteState { - private String note = ""; private String error; + private String city; + private String address; + private String keyword1; + private String keyword2; + private String keyword3; + private String keyword4; + private String keyword5; + private List suggestedLocations; + + public NoteState() { + this.suggestedLocations = new ArrayList<>(); + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getKeyword1() { + return keyword1; + } + + public void setKeyword1(String keyword1) { + this.keyword1 = keyword1; + } + + public String getKeyword2() { + return keyword2; + } + + public void setKeyword2(String keyword2) { + this.keyword2 = keyword2; + } + + public String getKeyword3() { + return keyword3; + } + + public void setKeyword3(String keyword3) { + this.keyword3 = keyword3; + } + + public String getKeyword4() { + return keyword4; + } + + public void setKeyword4(String keyword4) { + this.keyword4 = keyword4; + } - public String getNote() { - return note; + public String getKeyword5() { + return keyword5; } - public void setNote(String note) { - this.note = note; + public void setKeyword5(String keyword5) { + this.keyword5 = keyword5; } public void setError(String errorMessage) { + this.error = errorMessage; } public String getError() { return error; } + + public List getSuggestedLocations() { + return suggestedLocations; + } + + public void setSuggestedLocations(List suggestedLocations) { + this.suggestedLocations = suggestedLocations; + } } diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index 331d76493..cdefcf298 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -5,13 +5,10 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextArea; +import javax.swing.*; import interface_adapter.note.NoteController; import interface_adapter.note.NoteState; @@ -22,48 +19,99 @@ */ public class NoteView extends JPanel implements ActionListener, PropertyChangeListener { + private static final int TEXT_FIELD_WIDTH = 30; + private static final int KEYWORD_FIELD_WIDTH = 10; private final NoteViewModel noteViewModel; - - private final JLabel noteName = new JLabel("note for jonathan_calver2"); - private final JTextArea noteInputField = new JTextArea(); - - private final JButton saveButton = new JButton("Save"); - private final JButton refreshButton = new JButton("Refresh"); + private final JLabel noteName = new JLabel("Home Screen"); + private final JTextField cityField; + private final JTextField addressField; + private final JTextField keyword1Field; + private final JTextField keyword2Field; + private final JTextField keyword3Field; + private final JTextField keyword4Field; + private final JTextField keyword5Field; + private JPanel suggestedLocations; + private final JButton suggestButton = new JButton("Suggest Locations"); private NoteController noteController; public NoteView(NoteViewModel noteViewModel) { - + cityField = new JTextField(TEXT_FIELD_WIDTH); + addressField = new JTextField(TEXT_FIELD_WIDTH); + keyword1Field = new JTextField(KEYWORD_FIELD_WIDTH); + keyword2Field = new JTextField(KEYWORD_FIELD_WIDTH); + keyword3Field = new JTextField(KEYWORD_FIELD_WIDTH); + keyword4Field = new JTextField(KEYWORD_FIELD_WIDTH); + keyword5Field = new JTextField(KEYWORD_FIELD_WIDTH); noteName.setAlignmentX(Component.CENTER_ALIGNMENT); this.noteViewModel = noteViewModel; this.noteViewModel.addPropertyChangeListener(this); - final JPanel buttons = new JPanel(); - buttons.add(saveButton); - buttons.add(refreshButton); + final JPanel panel = new JPanel(); + panel.add(new JLabel("Choose City:")); + panel.add(cityField); + panel.add(new JLabel("Enter Address:")); + panel.add(addressField); + panel.add(new JLabel("Choose Interests:")); + panel.add(keyword1Field); + panel.add(keyword2Field); + panel.add(keyword3Field); + panel.add(keyword4Field); + panel.add(keyword5Field); + panel.add(suggestButton); + + suggestButton.addActionListener(evt -> { + if (evt.getSource().equals(suggestButton)) { + final String city = cityField.getText().trim(); + final String address = addressField.getText().trim(); + final List keywords = getKeywords(); + final String joinedKeywords = String.join(";", keywords); + final String inputText = String.join(";", city, address, joinedKeywords); + noteController.execute(inputText); + } + }); - saveButton.addActionListener( - evt -> { - if (evt.getSource().equals(saveButton)) { - noteController.execute(noteInputField.getText()); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(noteName); + this.add(panel); + this.setVisible(true); + } - } - } - ); + public void setNoteController(NoteController controller) { + this.noteController = controller; + } - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - noteController.execute(null); + public String getCity() { + return cityField.getText(); + } - } - } - ); + public String getAddress() { + return addressField.getText(); + } - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + public List getKeywords() { + final List keywords = new ArrayList<>(); - this.add(noteName); - this.add(noteInputField); - this.add(buttons); + final String keyword1 = keyword1Field.getText().trim(); + if (!keyword1.isEmpty()) { + keywords.add(keyword1); + } + final String keyword2 = keyword2Field.getText().trim(); + if (!keyword2.isEmpty()) { + keywords.add(keyword2); + } + final String keyword3 = keyword3Field.getText().trim(); + if (!keyword3.isEmpty()) { + keywords.add(keyword3); + } + final String keyword4 = keyword4Field.getText().trim(); + if (!keyword4.isEmpty()) { + keywords.add(keyword4); + } + final String keyword5 = keyword5Field.getText().trim(); + if (!keyword5.isEmpty()) { + keywords.add(keyword5); + } + return keywords; } /** @@ -82,14 +130,37 @@ public void propertyChange(PropertyChangeEvent evt) { JOptionPane.showMessageDialog(this, state.getError(), "Error", JOptionPane.ERROR_MESSAGE); } + if (state.getSuggestedLocations() != null) { + showSuggestedLocations(state.getSuggestedLocations()); + } } - private void setFields(NoteState state) { - noteInputField.setText(state.getNote()); + private void showSuggestedLocations(List locations) { + if (suggestedLocations != null) { + this.remove(suggestedLocations); + } + + suggestedLocations = new JPanel(); + suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); + suggestedLocations.add(new JLabel("List of Suggested Locations:")); + for (String location : locations) { + suggestedLocations.add(new JLabel(location)); + } + this.add(suggestedLocations); } - public void setNoteController(NoteController controller) { - this.noteController = controller; + private void setFields(NoteState state) { + cityField.setText(state.getCity()); + addressField.setText(state.getAddress()); + keyword1Field.setText(state.getKeyword1()); + keyword2Field.setText(state.getKeyword2()); + keyword3Field.setText(state.getKeyword3()); + keyword4Field.setText(state.getKeyword4()); + keyword5Field.setText(state.getKeyword5()); + if (state.getError() != null) { + JOptionPane.showMessageDialog(this, state.getError(), + "Error", JOptionPane.ERROR_MESSAGE); + } } } From b69fec02767307c4ecdeb5835fd89308cade8608 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 17:02:50 -0500 Subject: [PATCH 010/113] changed api key access --- .gitignore | 2 -- src/main/java/data_access/DBLocationDataAccessObject.java | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index a87051d46..26559eb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,5 +30,3 @@ bin/ ### Mac OS ### .DS_Store - -api_key.txt \ No newline at end of file diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 6a5d86448..c804b57fa 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -26,10 +26,7 @@ public class DBLocationDataAccessObject implements LocationDataAccessInterface { private static final String CONTENT_TYPE_JSON = "application/json"; private static final String STATUS_CODE_LABEL = "status_code"; private static final String MESSAGE = "message"; - - public static String getKey() { - return System.getenv("api_key"); - } + private static final String API_KEY = ""; @Override public String searchLocation(String address, String locationType) throws DataAccessException { @@ -45,7 +42,7 @@ public String searchLocation(String address, String locationType) throws DataAcc .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") .method("POST", body) .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) - .addHeader(API_HEADER, getKey()) + .addHeader(API_HEADER, API_KEY) .addHeader(API_FIELD, FIELDS) .build(); try { From 5e943624f5754e446b4cdb3e6233b5665c375d01 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 17:13:59 -0500 Subject: [PATCH 011/113] changed return to use "places" key --- src/main/java/data_access/DBLocationDataAccessObject.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index c804b57fa..d4d8d2fd9 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -51,7 +51,8 @@ public String searchLocation(String address, String locationType) throws DataAcc final JSONObject responseBody = new JSONObject(response.body().string()); if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - return responseBody.toString(); + final JSONObject result = responseBody.getJSONObject("places"); + return result.toString(); } else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { throw new DataAccessException("Needs API Key"); From 4c26f9efa5e1863950dd220d1d7be6dc32654496 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 10 Nov 2024 17:14:29 -0500 Subject: [PATCH 012/113] Created place entity, created suggest locations use case (interactor not done yet, need other code) --- src/main/java/app/MainNoteApplication.java | 2 +- src/main/java/app/NoteAppBuilder.java | 6 ++-- .../data_access/DBNoteDataAccessObject.java | 4 +-- src/main/java/entity/Place.java | 30 ++++++++----------- src/main/java/entity/PlaceFactory.java | 14 +++++++++ src/main/java/entity/SuggestedPlace.java | 25 ++++++++++++++++ .../java/entity/SuggestedPlaceFactory.java | 12 ++++++++ .../note/NoteController.java | 2 +- .../interface_adapter/note/NotePresenter.java | 2 +- .../{ => note}/DataAccessException.java | 2 +- .../{ => note}/NoteDataAccessInterface.java | 2 +- .../{ => note}/NoteInputBoundary.java | 2 +- .../use_case/{ => note}/NoteInteractor.java | 2 +- .../{ => note}/NoteOutputBoundary.java | 2 +- .../SuggestLocationsInputBoundary.java | 13 ++++++++ .../SuggestLocationsInputData.java | 24 +++++++++++++++ .../SuggestLocationsInteractor.java | 25 ++++++++++++++++ .../SuggestLocationsOutputBoundary.java | 18 +++++++++++ .../SuggestLocationsOutputData.java | 23 ++++++++++++++ .../java/app/MainNoteApplicationTest.java | 2 +- .../java/use_case/NoteInteractorTest.java | 3 ++ 21 files changed, 183 insertions(+), 32 deletions(-) create mode 100644 src/main/java/entity/PlaceFactory.java create mode 100644 src/main/java/entity/SuggestedPlace.java create mode 100644 src/main/java/entity/SuggestedPlaceFactory.java rename src/main/java/use_case/{ => note}/DataAccessException.java (89%) rename src/main/java/use_case/{ => note}/NoteDataAccessInterface.java (97%) rename src/main/java/use_case/{ => note}/NoteInputBoundary.java (94%) rename src/main/java/use_case/{ => note}/NoteInteractor.java (98%) rename src/main/java/use_case/{ => note}/NoteOutputBoundary.java (95%) create mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java create mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java create mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java create mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java create mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java index 6a34b4576..c37860156 100644 --- a/src/main/java/app/MainNoteApplication.java +++ b/src/main/java/app/MainNoteApplication.java @@ -1,7 +1,7 @@ package app; import data_access.DBNoteDataAccessObject; -import use_case.NoteDataAccessInterface; +import use_case.note.NoteDataAccessInterface; /** * An application where we can view and add to a note stored by a user. diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java index 10c2e072b..a68cb9ad6 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/NoteAppBuilder.java @@ -6,9 +6,9 @@ import interface_adapter.note.NoteController; import interface_adapter.note.NotePresenter; import interface_adapter.note.NoteViewModel; -import use_case.NoteDataAccessInterface; -import use_case.NoteInteractor; -import use_case.NoteOutputBoundary; +import use_case.note.NoteDataAccessInterface; +import use_case.note.NoteInteractor; +import use_case.note.NoteOutputBoundary; import view.NoteView; /** diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java index 1306b9e1c..dadb0cab0 100644 --- a/src/main/java/data_access/DBNoteDataAccessObject.java +++ b/src/main/java/data_access/DBNoteDataAccessObject.java @@ -11,8 +11,8 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import use_case.DataAccessException; -import use_case.NoteDataAccessInterface; +import use_case.note.DataAccessException; +import use_case.note.NoteDataAccessInterface; /** * The DAO for accessing notes stored in the database. diff --git a/src/main/java/entity/Place.java b/src/main/java/entity/Place.java index 8d3d122a2..2695234db 100644 --- a/src/main/java/entity/Place.java +++ b/src/main/java/entity/Place.java @@ -1,24 +1,18 @@ package entity; /** - * The representation of a place/destination for our program. + * The representation of a place in our program. */ -public class Place { - - private final String name; - private final String address; - - public Place(String name, String address) { - this.name = name; - this.address = address; - } - - public String getName() { - return name; - } - - public String getAddress() { - return address; - } +public interface Place { + /** + * Returns the name of the place. + * @return the name of the place. + */ + String getName(); + /** + * Returns the address of the place. + * @return the address of the place. + */ + String getAddress(); } diff --git a/src/main/java/entity/PlaceFactory.java b/src/main/java/entity/PlaceFactory.java new file mode 100644 index 000000000..135c32c1c --- /dev/null +++ b/src/main/java/entity/PlaceFactory.java @@ -0,0 +1,14 @@ +package entity; + +/** + * Factory for creating places. + */ +public interface PlaceFactory { + /** + * Creates a new Place. + * @param name the name of the new place + * @param address the address of the new place + * @return the new place + */ + Place create(String name, String address); +} diff --git a/src/main/java/entity/SuggestedPlace.java b/src/main/java/entity/SuggestedPlace.java new file mode 100644 index 000000000..6bcc77d41 --- /dev/null +++ b/src/main/java/entity/SuggestedPlace.java @@ -0,0 +1,25 @@ +package entity; + +/** + * An implementation of the Place interface. + */ +public class SuggestedPlace implements Place { + + private final String name; + private final String address; + + public SuggestedPlace(String name, String address) { + this.name = name; + this.address = address; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getAddress() { + return address; + } +} diff --git a/src/main/java/entity/SuggestedPlaceFactory.java b/src/main/java/entity/SuggestedPlaceFactory.java new file mode 100644 index 000000000..83b81bb6c --- /dev/null +++ b/src/main/java/entity/SuggestedPlaceFactory.java @@ -0,0 +1,12 @@ +package entity; + +/** + * Factory for creating SuggestedPlace objects. + */ +public class SuggestedPlaceFactory implements PlaceFactory { + + @Override + public Place create(String name, String address) { + return new SuggestedPlace(name, address); + } +} diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java index fbd2d3a41..e3e5dfb32 100644 --- a/src/main/java/interface_adapter/note/NoteController.java +++ b/src/main/java/interface_adapter/note/NoteController.java @@ -1,6 +1,6 @@ package interface_adapter.note; -import use_case.NoteInputBoundary; +import use_case.note.NoteInputBoundary; /** * Controller for our Note related Use Cases. diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java index 0d1b784c7..d4e416165 100644 --- a/src/main/java/interface_adapter/note/NotePresenter.java +++ b/src/main/java/interface_adapter/note/NotePresenter.java @@ -1,6 +1,6 @@ package interface_adapter.note; -import use_case.NoteOutputBoundary; +import use_case.note.NoteOutputBoundary; /** * The presenter for our Note viewing and editing program. diff --git a/src/main/java/use_case/DataAccessException.java b/src/main/java/use_case/note/DataAccessException.java similarity index 89% rename from src/main/java/use_case/DataAccessException.java rename to src/main/java/use_case/note/DataAccessException.java index 59cf779b3..b8c17920d 100644 --- a/src/main/java/use_case/DataAccessException.java +++ b/src/main/java/use_case/note/DataAccessException.java @@ -1,4 +1,4 @@ -package use_case; +package use_case.note; /** * Exception thrown when there is an error with accessing data. diff --git a/src/main/java/use_case/NoteDataAccessInterface.java b/src/main/java/use_case/note/NoteDataAccessInterface.java similarity index 97% rename from src/main/java/use_case/NoteDataAccessInterface.java rename to src/main/java/use_case/note/NoteDataAccessInterface.java index c5259f1e6..b71597828 100644 --- a/src/main/java/use_case/NoteDataAccessInterface.java +++ b/src/main/java/use_case/note/NoteDataAccessInterface.java @@ -1,4 +1,4 @@ -package use_case; +package use_case.note; import entity.User; diff --git a/src/main/java/use_case/NoteInputBoundary.java b/src/main/java/use_case/note/NoteInputBoundary.java similarity index 94% rename from src/main/java/use_case/NoteInputBoundary.java rename to src/main/java/use_case/note/NoteInputBoundary.java index 161695d48..b41da9bf5 100644 --- a/src/main/java/use_case/NoteInputBoundary.java +++ b/src/main/java/use_case/note/NoteInputBoundary.java @@ -1,4 +1,4 @@ -package use_case; +package use_case.note; /** * The Input Boundary for our note-related use cases. Since they are closely related, diff --git a/src/main/java/use_case/NoteInteractor.java b/src/main/java/use_case/note/NoteInteractor.java similarity index 98% rename from src/main/java/use_case/NoteInteractor.java rename to src/main/java/use_case/note/NoteInteractor.java index 9ce666e96..369e9309a 100644 --- a/src/main/java/use_case/NoteInteractor.java +++ b/src/main/java/use_case/note/NoteInteractor.java @@ -1,4 +1,4 @@ -package use_case; +package use_case.note; import entity.User; diff --git a/src/main/java/use_case/NoteOutputBoundary.java b/src/main/java/use_case/note/NoteOutputBoundary.java similarity index 95% rename from src/main/java/use_case/NoteOutputBoundary.java rename to src/main/java/use_case/note/NoteOutputBoundary.java index deea3046a..c0c2bb1d0 100644 --- a/src/main/java/use_case/NoteOutputBoundary.java +++ b/src/main/java/use_case/note/NoteOutputBoundary.java @@ -1,4 +1,4 @@ -package use_case; +package use_case.note; /** * The output boundary for the Login Use Case. diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java new file mode 100644 index 000000000..e4418102b --- /dev/null +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java @@ -0,0 +1,13 @@ +package use_case.suggest_locations; + +/** + * The Suggest Locations Use Case. + */ +public interface SuggestLocationsInputBoundary { + + /** + * Execute the Suggest Locations Use Case. + * @param suggestLocationsInputData the input data for this use case + */ + void execute(SuggestLocationsInputData suggestLocationsInputData); +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java new file mode 100644 index 000000000..9f470de8c --- /dev/null +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java @@ -0,0 +1,24 @@ +package use_case.suggest_locations; + +/** + * The input data for the Suggest Locations Use Case. + */ +public class SuggestLocationsInputData { + + private final String address; + private final String locationType; + + public SuggestLocationsInputData(String address, String locationType) { + this.address = address; + this.locationType = locationType; + } + + public String getAddress() { + return address; + } + + public String getLocationType() { + return locationType; + } + +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java new file mode 100644 index 000000000..e7efddf76 --- /dev/null +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -0,0 +1,25 @@ +package use_case.suggest_locations; + +/** + * The Suggest Locations Interactor. + */ +public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { + private final LocationDataAccessInterface placeDataAccessObject; + private final SuggestLocationsOutputBoundary placePresenter; + + public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, + SuggestLocationsOutputBoundary suggestLocationsOutputBoundary) { + this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; + this.placePresenter = suggestLocationsOutputBoundary; + } + + @Override + public void execute(SuggestLocationsInputData suggestLocationsInputData) { + final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), + suggestLocationsInputData.getLocationType()); + + final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedLocations, + false); + placePresenter.prepareSuccessView(suggestLocationsOutputData); + } +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java new file mode 100644 index 000000000..086aa1e8b --- /dev/null +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java @@ -0,0 +1,18 @@ +package use_case.suggest_locations; + +/** + * The output boundary for the Suggest Locations Use Case. + */ +public interface SuggestLocationsOutputBoundary { + /** + * Prepares the success view for the Suggest Locations Use Case. + * @param outputData the output data + */ + void prepareSuccessView(SuggestLocationsOutputData outputData); + + /** + * Prepares the failure view for the SuggestLocations Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java new file mode 100644 index 000000000..ec30afca3 --- /dev/null +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java @@ -0,0 +1,23 @@ +package use_case.suggest_locations; + +/** + * Output Data for the Suggest Locations Use Case. + */ +public class SuggestLocationsOutputData { + + private final String locations; + private final boolean useCaseFailed; + + public SuggestLocationsOutputData(String locations, boolean useCaseFailed) { + this.locations = locations; + this.useCaseFailed = useCaseFailed; + } + + public String getLocations() { + return locations; + } + + public boolean isUseCaseFailed() { + return useCaseFailed; + } +} diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainNoteApplicationTest.java index d62e389c1..025d970e2 100644 --- a/src/test/java/app/MainNoteApplicationTest.java +++ b/src/test/java/app/MainNoteApplicationTest.java @@ -3,7 +3,7 @@ import entity.User; import org.junit.Before; import org.junit.Test; -import use_case.NoteDataAccessInterface; +import use_case.note.NoteDataAccessInterface; import javax.swing.*; import java.awt.*; diff --git a/src/test/java/use_case/NoteInteractorTest.java b/src/test/java/use_case/NoteInteractorTest.java index 4b3933e4c..9cabc0429 100644 --- a/src/test/java/use_case/NoteInteractorTest.java +++ b/src/test/java/use_case/NoteInteractorTest.java @@ -2,6 +2,9 @@ import entity.User; import org.junit.Test; +import use_case.note.NoteDataAccessInterface; +import use_case.note.NoteInteractor; +import use_case.note.NoteOutputBoundary; import static org.junit.Assert.*; From 95905160c626b9a2a455b2ea4ba72d82b922efa7 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 17:19:38 -0500 Subject: [PATCH 013/113] fixed url --- src/main/java/data_access/DBLocationDataAccessObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index d4d8d2fd9..ada174e3f 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -39,7 +39,7 @@ public String searchLocation(String address, String locationType) throws DataAcc requestBody.put("textQuery", locationType + " near " + address); final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); final Request request = new Request.Builder() - .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") + .url("https://places.googleapis.com/v1/places:searchText") .method("POST", body) .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) .addHeader(API_HEADER, API_KEY) From 796a8703e7ce3b0b3fe36e6b2d917b393cb2db48 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 17:31:40 -0500 Subject: [PATCH 014/113] fixed url --- src/main/java/data_access/DBLocationDataAccessObject.java | 2 +- .../LocationDataAccessInterface.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/main/java/use_case/{note => suggest_locations}/LocationDataAccessInterface.java (86%) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index ada174e3f..d107c6257 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -11,7 +11,7 @@ import okhttp3.RequestBody; import okhttp3.Response; import use_case.note.DataAccessException; -import use_case.note.LocationDataAccessInterface; +import use_case.suggest_locations.LocationDataAccessInterface; /** * The DAO for accessing places using Google Places API. diff --git a/src/main/java/use_case/note/LocationDataAccessInterface.java b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java similarity index 86% rename from src/main/java/use_case/note/LocationDataAccessInterface.java rename to src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java index c465a6cbf..4cb8131d0 100644 --- a/src/main/java/use_case/note/LocationDataAccessInterface.java +++ b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java @@ -1,4 +1,6 @@ -package use_case.note; +package use_case.suggest_locations; + +import use_case.note.DataAccessException; /** * Interface for the LocationDAO. It consists of methods for From 52a2f470f3689b617b8008c311761780cdf5e4f6 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:10:53 -0500 Subject: [PATCH 015/113] finished suggest locations use case --- .../DBLocationDataAccessObject.java | 11 +++++++++-- .../LocationDataAccessInterface.java | 14 ++++++++++++++ .../SuggestLocationsInteractor.java | 19 +++++++++++++++++-- .../SuggestLocationsOutputData.java | 10 +++++++--- 4 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index ada174e3f..5fd44ffd8 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -2,6 +2,7 @@ import java.io.IOException; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -51,8 +52,14 @@ public String searchLocation(String address, String locationType) throws DataAcc final JSONObject responseBody = new JSONObject(response.body().string()); if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - final JSONObject result = responseBody.getJSONObject("places"); - return result.toString(); + final StringBuilder places = new StringBuilder(); + final JSONArray jsonArray = responseBody.getJSONArray("places"); + for (int i = 0; i < jsonArray.length(); i++) { + final JSONObject jsonObject = jsonArray.getJSONObject(i); + places.append(jsonObject.getString("formattedAddress")).append(">").append(jsonObject + .getJSONObject("displayName").getString("text")).append("<"); + } + return places.toString(); } else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { throw new DataAccessException("Needs API Key"); diff --git a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java new file mode 100644 index 000000000..c1cad4e1a --- /dev/null +++ b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java @@ -0,0 +1,14 @@ +package use_case.suggest_locations; + +/** + * The interface of the DAO for the Suggest Locations Use Case. + */ +public interface LocationDataAccessInterface { + /** + * Display suggested locations and info. + * @param address the starting address. + * @param locationType the location type to search for. + * @return String of the suggested locations. + */ + String searchLocation(String address, String locationType); +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index e7efddf76..8128b8864 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -1,24 +1,39 @@ package use_case.suggest_locations; +import java.util.ArrayList; +import java.util.List; + +import entity.Place; +import entity.PlaceFactory; + /** * The Suggest Locations Interactor. */ public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { private final LocationDataAccessInterface placeDataAccessObject; private final SuggestLocationsOutputBoundary placePresenter; + private final PlaceFactory placeFactory; public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, - SuggestLocationsOutputBoundary suggestLocationsOutputBoundary) { + SuggestLocationsOutputBoundary suggestLocationsOutputBoundary, + PlaceFactory placeFactory) { this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; this.placePresenter = suggestLocationsOutputBoundary; + this.placeFactory = placeFactory; } @Override public void execute(SuggestLocationsInputData suggestLocationsInputData) { final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), suggestLocationsInputData.getLocationType()); + final String[] locationsList = suggestedLocations.split("<:>"); + + final List suggestedPlaces = new ArrayList<>(); + for (String location : locationsList) { + suggestedPlaces.add(placeFactory.create(location.split(">")[1], location.split(">")[0])); + } - final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedLocations, + final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedPlaces, false); placePresenter.prepareSuccessView(suggestLocationsOutputData); } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java index ec30afca3..a30c1cc9b 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java @@ -1,19 +1,23 @@ package use_case.suggest_locations; +import java.util.List; + +import entity.Place; + /** * Output Data for the Suggest Locations Use Case. */ public class SuggestLocationsOutputData { - private final String locations; + private final List locations; private final boolean useCaseFailed; - public SuggestLocationsOutputData(String locations, boolean useCaseFailed) { + public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { this.locations = locations; this.useCaseFailed = useCaseFailed; } - public String getLocations() { + public List getLocations() { return locations; } From f1577cbb854605eb2522fa695f6978a4428c242e Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 10 Nov 2024 19:02:04 -0500 Subject: [PATCH 016/113] Added LoginView --- .../interface_adapter/note/NoteState.java | 2 +- src/main/java/view/LoginView.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/view/LoginView.java diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java index c5b2234d6..900b924e6 100644 --- a/src/main/java/interface_adapter/note/NoteState.java +++ b/src/main/java/interface_adapter/note/NoteState.java @@ -2,7 +2,7 @@ /** * The State for a note. - *

For this example, a note is simplay a string.

+ *

For this example, a note is simply a string.

*/ public class NoteState { private String note = ""; diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java new file mode 100644 index 000000000..d5946d933 --- /dev/null +++ b/src/main/java/view/LoginView.java @@ -0,0 +1,55 @@ +package view; + +import java.awt.GridLayout; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.WindowConstants; + +public class LoginView extends JFrame { + private JTextField usernameField; + private JPasswordField passwordField; + private JButton loginButton; + private JButton createProfileButton; + + public LoginView() { + setTitle("Login"); + setSize(300, 200); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setLayout(new GridLayout(3, 2)); + + add(new JLabel("Username:")); + usernameField = new JTextField(); + add(usernameField); + + add(new JLabel("Password:")); + passwordField = new JPasswordField(); + add(passwordField); + + loginButton = new JButton("Login"); + add(loginButton); + + createProfileButton = new JButton("Create Profile"); + add(createProfileButton); + } + + public String getUsername() { + return usernameField.getText(); + } + + public String getPassword() { + return new String(passwordField.getPassword()); + } + + public void addLoginListener(ActionListener listener) { + loginButton.addActionListener(listener); + } + + public void addCreateProfileListener(ActionListener listener) { + createProfileButton.addActionListener(listener); + } +} From 9fad7ce5de540cb1c07cd6164b3694cfddcf0fad Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 10 Nov 2024 19:02:04 -0500 Subject: [PATCH 017/113] Added LoginView --- src/main/java/view/LoginView.java | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/main/java/view/LoginView.java diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java new file mode 100644 index 000000000..d5946d933 --- /dev/null +++ b/src/main/java/view/LoginView.java @@ -0,0 +1,55 @@ +package view; + +import java.awt.GridLayout; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.WindowConstants; + +public class LoginView extends JFrame { + private JTextField usernameField; + private JPasswordField passwordField; + private JButton loginButton; + private JButton createProfileButton; + + public LoginView() { + setTitle("Login"); + setSize(300, 200); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setLayout(new GridLayout(3, 2)); + + add(new JLabel("Username:")); + usernameField = new JTextField(); + add(usernameField); + + add(new JLabel("Password:")); + passwordField = new JPasswordField(); + add(passwordField); + + loginButton = new JButton("Login"); + add(loginButton); + + createProfileButton = new JButton("Create Profile"); + add(createProfileButton); + } + + public String getUsername() { + return usernameField.getText(); + } + + public String getPassword() { + return new String(passwordField.getPassword()); + } + + public void addLoginListener(ActionListener listener) { + loginButton.addActionListener(listener); + } + + public void addCreateProfileListener(ActionListener listener) { + createProfileButton.addActionListener(listener); + } +} From 1cd61bfe2921563a6fd895e78ab22caac65373ea Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 10 Nov 2024 19:33:33 -0500 Subject: [PATCH 018/113] Updated Interface Adapter to working with locations --- src/main/java/app/NoteAppBuilder.java | 16 ++++---- .../LocationController.java} | 6 +-- .../location/LocationPresenter.java | 38 +++++++++++++++++++ .../LocationState.java} | 4 +- .../location/LocationViewModel.java | 13 +++++++ .../interface_adapter/note/NotePresenter.java | 38 ------------------- .../interface_adapter/note/NoteViewModel.java | 13 ------- src/main/java/view/NoteView.java | 26 ++++++------- 8 files changed, 77 insertions(+), 77 deletions(-) rename src/main/java/interface_adapter/{note/NoteController.java => location/LocationController.java} (78%) create mode 100644 src/main/java/interface_adapter/location/LocationPresenter.java rename src/main/java/interface_adapter/{note/NoteState.java => location/LocationState.java} (86%) create mode 100644 src/main/java/interface_adapter/location/LocationViewModel.java delete mode 100644 src/main/java/interface_adapter/note/NotePresenter.java delete mode 100644 src/main/java/interface_adapter/note/NoteViewModel.java diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java index a68cb9ad6..6e8e216f8 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/NoteAppBuilder.java @@ -3,9 +3,9 @@ import javax.swing.JFrame; import javax.swing.WindowConstants; -import interface_adapter.note.NoteController; -import interface_adapter.note.NotePresenter; -import interface_adapter.note.NoteViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationPresenter; +import interface_adapter.location.LocationViewModel; import use_case.note.NoteDataAccessInterface; import use_case.note.NoteInteractor; import use_case.note.NoteOutputBoundary; @@ -18,7 +18,7 @@ public class NoteAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; private NoteDataAccessInterface noteDAO; - private NoteViewModel noteViewModel = new NoteViewModel(); + private LocationViewModel locationViewModel = new LocationViewModel(); private NoteView noteView; private NoteInteractor noteInteractor; @@ -40,11 +40,11 @@ public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { * @throws RuntimeException if this method is called before addNoteView */ public NoteAppBuilder addNoteUseCase() { - final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); + final NoteOutputBoundary noteOutputBoundary = new LocationPresenter(locationViewModel); noteInteractor = new NoteInteractor( noteDAO, noteOutputBoundary); - final NoteController controller = new NoteController(noteInteractor); + final LocationController controller = new LocationController(noteInteractor); if (noteView == null) { throw new RuntimeException("addNoteView must be called before addNoteUseCase"); } @@ -57,8 +57,8 @@ public NoteAppBuilder addNoteUseCase() { * @return this builder */ public NoteAppBuilder addNoteView() { - noteViewModel = new NoteViewModel(); - noteView = new NoteView(noteViewModel); + locationViewModel = new LocationViewModel(); + noteView = new NoteView(locationViewModel); return this; } diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/location/LocationController.java similarity index 78% rename from src/main/java/interface_adapter/note/NoteController.java rename to src/main/java/interface_adapter/location/LocationController.java index e3e5dfb32..3b5f5504e 100644 --- a/src/main/java/interface_adapter/note/NoteController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,15 +1,15 @@ -package interface_adapter.note; +package interface_adapter.location; import use_case.note.NoteInputBoundary; /** * Controller for our Note related Use Cases. */ -public class NoteController { +public class LocationController { private final NoteInputBoundary noteInteractor; - public NoteController(NoteInputBoundary noteInteractor) { + public LocationController(NoteInputBoundary noteInteractor) { this.noteInteractor = noteInteractor; } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java new file mode 100644 index 000000000..4052b5e54 --- /dev/null +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -0,0 +1,38 @@ +package interface_adapter.location; + +import use_case.note.NoteOutputBoundary; + +/** + * The presenter for our Note viewing and editing program. + */ +public class LocationPresenter implements NoteOutputBoundary { + + private final LocationViewModel locationViewModel; + + public LocationPresenter(LocationViewModel locationViewModel) { + this.locationViewModel = locationViewModel; + } + + /** + * Prepares the success view for the Note related Use Cases. + * + * @param note the output data + */ + @Override + public void prepareSuccessView(String note) { + locationViewModel.getState().setNote(note); + locationViewModel.getState().setError(null); + locationViewModel.firePropertyChanged(); + } + + /** + * Prepares the failure view for the Note related Use Cases. + * + * @param errorMessage the explanation of the failure + */ + @Override + public void prepareFailView(String errorMessage) { + locationViewModel.getState().setError(errorMessage); + locationViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/location/LocationState.java similarity index 86% rename from src/main/java/interface_adapter/note/NoteState.java rename to src/main/java/interface_adapter/location/LocationState.java index c5b2234d6..40ffe2f98 100644 --- a/src/main/java/interface_adapter/note/NoteState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -1,10 +1,10 @@ -package interface_adapter.note; +package interface_adapter.location; /** * The State for a note. *

For this example, a note is simplay a string.

*/ -public class NoteState { +public class LocationState { private String note = ""; private String error; diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java new file mode 100644 index 000000000..63adebd46 --- /dev/null +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -0,0 +1,13 @@ +package interface_adapter.location; + +import interface_adapter.ViewModel; + +/** + * The ViewModel for the NoteView. + */ +public class LocationViewModel extends ViewModel { + public LocationViewModel() { + super("note"); + setState(new LocationState()); + } +} diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java deleted file mode 100644 index d4e416165..000000000 --- a/src/main/java/interface_adapter/note/NotePresenter.java +++ /dev/null @@ -1,38 +0,0 @@ -package interface_adapter.note; - -import use_case.note.NoteOutputBoundary; - -/** - * The presenter for our Note viewing and editing program. - */ -public class NotePresenter implements NoteOutputBoundary { - - private final NoteViewModel noteViewModel; - - public NotePresenter(NoteViewModel noteViewModel) { - this.noteViewModel = noteViewModel; - } - - /** - * Prepares the success view for the Note related Use Cases. - * - * @param note the output data - */ - @Override - public void prepareSuccessView(String note) { - noteViewModel.getState().setNote(note); - noteViewModel.getState().setError(null); - noteViewModel.firePropertyChanged(); - } - - /** - * Prepares the failure view for the Note related Use Cases. - * - * @param errorMessage the explanation of the failure - */ - @Override - public void prepareFailView(String errorMessage) { - noteViewModel.getState().setError(errorMessage); - noteViewModel.firePropertyChanged(); - } -} diff --git a/src/main/java/interface_adapter/note/NoteViewModel.java b/src/main/java/interface_adapter/note/NoteViewModel.java deleted file mode 100644 index 6e185d0fa..000000000 --- a/src/main/java/interface_adapter/note/NoteViewModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package interface_adapter.note; - -import interface_adapter.ViewModel; - -/** - * The ViewModel for the NoteView. - */ -public class NoteViewModel extends ViewModel { - public NoteViewModel() { - super("note"); - setState(new NoteState()); - } -} diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index cdefcf298..f1d101ee1 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -10,9 +10,9 @@ import javax.swing.*; -import interface_adapter.note.NoteController; -import interface_adapter.note.NoteState; -import interface_adapter.note.NoteViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationState; +import interface_adapter.location.LocationViewModel; /** * The View for when the user is viewing a note in the program. @@ -21,7 +21,7 @@ public class NoteView extends JPanel implements ActionListener, PropertyChangeLi private static final int TEXT_FIELD_WIDTH = 30; private static final int KEYWORD_FIELD_WIDTH = 10; - private final NoteViewModel noteViewModel; + private final LocationViewModel locationViewModel; private final JLabel noteName = new JLabel("Home Screen"); private final JTextField cityField; private final JTextField addressField; @@ -32,9 +32,9 @@ public class NoteView extends JPanel implements ActionListener, PropertyChangeLi private final JTextField keyword5Field; private JPanel suggestedLocations; private final JButton suggestButton = new JButton("Suggest Locations"); - private NoteController noteController; + private LocationController locationController; - public NoteView(NoteViewModel noteViewModel) { + public NoteView(LocationViewModel locationViewModel) { cityField = new JTextField(TEXT_FIELD_WIDTH); addressField = new JTextField(TEXT_FIELD_WIDTH); keyword1Field = new JTextField(KEYWORD_FIELD_WIDTH); @@ -43,8 +43,8 @@ public NoteView(NoteViewModel noteViewModel) { keyword4Field = new JTextField(KEYWORD_FIELD_WIDTH); keyword5Field = new JTextField(KEYWORD_FIELD_WIDTH); noteName.setAlignmentX(Component.CENTER_ALIGNMENT); - this.noteViewModel = noteViewModel; - this.noteViewModel.addPropertyChangeListener(this); + this.locationViewModel = locationViewModel; + this.locationViewModel.addPropertyChangeListener(this); final JPanel panel = new JPanel(); panel.add(new JLabel("Choose City:")); @@ -66,7 +66,7 @@ public NoteView(NoteViewModel noteViewModel) { final List keywords = getKeywords(); final String joinedKeywords = String.join(";", keywords); final String inputText = String.join(";", city, address, joinedKeywords); - noteController.execute(inputText); + locationController.execute(inputText); } }); @@ -76,8 +76,8 @@ public NoteView(NoteViewModel noteViewModel) { this.setVisible(true); } - public void setNoteController(NoteController controller) { - this.noteController = controller; + public void setNoteController(LocationController controller) { + this.locationController = controller; } public String getCity() { @@ -124,7 +124,7 @@ public void actionPerformed(ActionEvent evt) { @Override public void propertyChange(PropertyChangeEvent evt) { - final NoteState state = (NoteState) evt.getNewValue(); + final LocationState state = (LocationState) evt.getNewValue(); setFields(state); if (state.getError() != null) { JOptionPane.showMessageDialog(this, state.getError(), @@ -149,7 +149,7 @@ private void showSuggestedLocations(List locations) { this.add(suggestedLocations); } - private void setFields(NoteState state) { + private void setFields(LocationState state) { cityField.setText(state.getCity()); addressField.setText(state.getAddress()); keyword1Field.setText(state.getKeyword1()); From 56bd41e659447f1c70524ab912902e2198af01ff Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 10 Nov 2024 19:38:46 -0500 Subject: [PATCH 019/113] Updated Interface Adapter to working with locations --- src/main/java/view/LoginView.java | 55 ------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 src/main/java/view/LoginView.java diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java deleted file mode 100644 index d5946d933..000000000 --- a/src/main/java/view/LoginView.java +++ /dev/null @@ -1,55 +0,0 @@ -package view; - -import java.awt.GridLayout; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.WindowConstants; - -public class LoginView extends JFrame { - private JTextField usernameField; - private JPasswordField passwordField; - private JButton loginButton; - private JButton createProfileButton; - - public LoginView() { - setTitle("Login"); - setSize(300, 200); - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - setLayout(new GridLayout(3, 2)); - - add(new JLabel("Username:")); - usernameField = new JTextField(); - add(usernameField); - - add(new JLabel("Password:")); - passwordField = new JPasswordField(); - add(passwordField); - - loginButton = new JButton("Login"); - add(loginButton); - - createProfileButton = new JButton("Create Profile"); - add(createProfileButton); - } - - public String getUsername() { - return usernameField.getText(); - } - - public String getPassword() { - return new String(passwordField.getPassword()); - } - - public void addLoginListener(ActionListener listener) { - loginButton.addActionListener(listener); - } - - public void addCreateProfileListener(ActionListener listener) { - createProfileButton.addActionListener(listener); - } -} From e4fd4dbef4e0097aca64626518d8e193cab47553 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 10 Nov 2024 20:06:38 -0500 Subject: [PATCH 020/113] Updated Interface Adapter to working with locations: handle city selection, address input, interest selection. --- .../location/LocationController.java | 49 ++++++++--- .../location/LocationPresenter.java | 4 +- .../location/LocationState.java | 82 +++++++++++++++++-- .../DataAccessException.java | 2 +- .../LocationInputBoundary.java} | 10 ++- .../LocationInteractor.java} | 6 +- .../LocationOutputBoundary.java} | 4 +- .../LocationDataAccessInterface.java | 2 +- 8 files changed, 130 insertions(+), 29 deletions(-) rename src/main/java/use_case/{note => location}/DataAccessException.java (88%) rename src/main/java/use_case/{note/NoteInputBoundary.java => location/LocationInputBoundary.java} (68%) rename src/main/java/use_case/{note/NoteInteractor.java => location/LocationInteractor.java} (89%) rename src/main/java/use_case/{note/NoteOutputBoundary.java => location/LocationOutputBoundary.java} (85%) diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 3b5f5504e..4a9537b72 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,28 +1,55 @@ package interface_adapter.location; -import use_case.note.NoteInputBoundary; +import use_case.location.LocationInputBoundary; /** - * Controller for our Note related Use Cases. + * The LocationController class handles user input related to locations. + * It interacts with the LocationInputBoundary to process the input and + * perform actions such as setting the city, address, and interests, + * as well as executing save or refresh operations. */ public class LocationController { - private final NoteInputBoundary noteInteractor; + private final LocationInputBoundary locationInteractor; - public LocationController(NoteInputBoundary noteInteractor) { - this.noteInteractor = noteInteractor; + public LocationController(LocationInputBoundary locationInteractor) { + this.locationInteractor = locationInteractor; } /** - * Executes the Note related Use Cases. - * @param note the note to be recorded + * Handles the selection of a city. + * @param city the selected city */ - public void execute(String note) { - if (note != null) { - noteInteractor.executeSave(note); + public void handleCitySelection(String city) { + locationInteractor.setCity(city); + } + + /** + * Handles the input of an address. + * @param address the input address + */ + public void handleAddressInput(String address) { + locationInteractor.setAddress(address); + } + + /** + * Handles the selection of an interest. + * @param interest the selected interest + */ + public void handleInterestSelection(String interest) { + locationInteractor.setInterest(interest); + } + + /** + * Executes the save or refresh operation based on the location. + * @param location the location to save or refresh + */ + public void execute(String location) { + if (location != null) { + locationInteractor.executeSave(location); } else { - noteInteractor.executeRefresh(); + locationInteractor.executeRefresh(); } } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 4052b5e54..74bfdc8b6 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -1,11 +1,9 @@ package interface_adapter.location; -import use_case.note.NoteOutputBoundary; - /** * The presenter for our Note viewing and editing program. */ -public class LocationPresenter implements NoteOutputBoundary { +public class LocationPresenter implements use_case.note.LocationOutputBoundary { private final LocationViewModel locationViewModel; diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index 40ffe2f98..6732d6af7 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -1,26 +1,96 @@ package interface_adapter.location; +import java.util.ArrayList; +import java.util.List; + /** * The State for a note. - *

For this example, a note is simplay a string.

*/ public class LocationState { - private String note = ""; private String error; + private String city; + private String address; + private String keyword1; + private String keyword2; + private String keyword3; + private String keyword4; + private String keyword5; + private List suggestedLocations; + + public LocationState() { + this.suggestedLocations = new ArrayList<>(); + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getKeyword1() { + return keyword1; + } + + public void setKeyword1(String keyword1) { + this.keyword1 = keyword1; + } + + public String getKeyword2() { + return keyword2; + } + + public void setKeyword2(String keyword2) { + this.keyword2 = keyword2; + } + + public String getKeyword3() { + return keyword3; + } + + public void setKeyword3(String keyword3) { + this.keyword3 = keyword3; + } + + public String getKeyword4() { + return keyword4; + } + + public void setKeyword4(String keyword4) { + this.keyword4 = keyword4; + } - public String getNote() { - return note; + public String getKeyword5() { + return keyword5; } - public void setNote(String note) { - this.note = note; + public void setKeyword5(String keyword5) { + this.keyword5 = keyword5; } public void setError(String errorMessage) { + this.error = errorMessage; } public String getError() { return error; } + + public List getSuggestedLocations() { + return suggestedLocations; + } + + public void setSuggestedLocations(List suggestedLocations) { + this.suggestedLocations = suggestedLocations; + } } diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/location/DataAccessException.java similarity index 88% rename from src/main/java/use_case/note/DataAccessException.java rename to src/main/java/use_case/location/DataAccessException.java index b8c17920d..6483b8b51 100644 --- a/src/main/java/use_case/note/DataAccessException.java +++ b/src/main/java/use_case/location/DataAccessException.java @@ -1,4 +1,4 @@ -package use_case.note; +package use_case.location; /** * Exception thrown when there is an error with accessing data. diff --git a/src/main/java/use_case/note/NoteInputBoundary.java b/src/main/java/use_case/location/LocationInputBoundary.java similarity index 68% rename from src/main/java/use_case/note/NoteInputBoundary.java rename to src/main/java/use_case/location/LocationInputBoundary.java index b41da9bf5..c3266ebb8 100644 --- a/src/main/java/use_case/note/NoteInputBoundary.java +++ b/src/main/java/use_case/location/LocationInputBoundary.java @@ -1,10 +1,16 @@ -package use_case.note; +package use_case.location; /** * The Input Boundary for our note-related use cases. Since they are closely related, * we have included them both in the same interface for simplicity. */ -public interface NoteInputBoundary { +public interface LocationInputBoundary { + + void setCity(String city); + + void setAddress(String address); + + void setInterest(String interest); /** * Executes the refresh note use case. diff --git a/src/main/java/use_case/note/NoteInteractor.java b/src/main/java/use_case/location/LocationInteractor.java similarity index 89% rename from src/main/java/use_case/note/NoteInteractor.java rename to src/main/java/use_case/location/LocationInteractor.java index 369e9309a..874a14b27 100644 --- a/src/main/java/use_case/note/NoteInteractor.java +++ b/src/main/java/use_case/location/LocationInteractor.java @@ -7,7 +7,7 @@ * the contents of the note and saving the contents of the note. Since they * are closely related, we have combined them here for simplicity. */ -public class NoteInteractor implements NoteInputBoundary { +public class LocationInteractor implements NoteInputBoundary { private final NoteDataAccessInterface noteDataAccessInterface; private final NoteOutputBoundary noteOutputBoundary; @@ -18,8 +18,8 @@ public class NoteInteractor implements NoteInputBoundary { // in a JSON object stored in one common "user" stored through the API. private final User user = new User("jonathan_calver2", "abc123"); - public NoteInteractor(NoteDataAccessInterface noteDataAccessInterface, - NoteOutputBoundary noteOutputBoundary) { + public LocationInteractor(NoteDataAccessInterface noteDataAccessInterface, + NoteOutputBoundary noteOutputBoundary) { this.noteDataAccessInterface = noteDataAccessInterface; this.noteOutputBoundary = noteOutputBoundary; } diff --git a/src/main/java/use_case/note/NoteOutputBoundary.java b/src/main/java/use_case/location/LocationOutputBoundary.java similarity index 85% rename from src/main/java/use_case/note/NoteOutputBoundary.java rename to src/main/java/use_case/location/LocationOutputBoundary.java index c0c2bb1d0..e7e04a58b 100644 --- a/src/main/java/use_case/note/NoteOutputBoundary.java +++ b/src/main/java/use_case/location/LocationOutputBoundary.java @@ -1,9 +1,9 @@ -package use_case.note; +package use_case.location; /** * The output boundary for the Login Use Case. */ -public interface NoteOutputBoundary { +public interface LocationOutputBoundary { /** * Prepares the success view for the Note related Use Cases. * @param message the output data diff --git a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java index 4cb8131d0..b91bb2c6e 100644 --- a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java +++ b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java @@ -1,6 +1,6 @@ package use_case.suggest_locations; -import use_case.note.DataAccessException; +import use_case.location.DataAccessException; /** * Interface for the LocationDAO. It consists of methods for From 11df8412afae89fcb1d3e3e6db01b50c69f94298 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 10 Nov 2024 20:21:58 -0500 Subject: [PATCH 021/113] fixed suggest locations use case --- .../suggest_locations/SuggestLocationsInputBoundary.java | 4 +++- .../suggest_locations/SuggestLocationsInteractor.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java index e4418102b..c19c1c8eb 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java @@ -1,5 +1,7 @@ package use_case.suggest_locations; +import use_case.note.DataAccessException; + /** * The Suggest Locations Use Case. */ @@ -9,5 +11,5 @@ public interface SuggestLocationsInputBoundary { * Execute the Suggest Locations Use Case. * @param suggestLocationsInputData the input data for this use case */ - void execute(SuggestLocationsInputData suggestLocationsInputData); + void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException; } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 8128b8864..c81567435 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -5,6 +5,7 @@ import entity.Place; import entity.PlaceFactory; +import use_case.note.DataAccessException; /** * The Suggest Locations Interactor. @@ -23,7 +24,7 @@ public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPl } @Override - public void execute(SuggestLocationsInputData suggestLocationsInputData) { + public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), suggestLocationsInputData.getLocationType()); final String[] locationsList = suggestedLocations.split("<:>"); From 17579077fa1a92ee95d48b801b6be9aecec7fb79 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 20:27:26 -0500 Subject: [PATCH 022/113] updated existing file names to location; created new application builders for our app --- src/main/java/app/HomeScreenApplication.java | 30 ++++++++++++++++++ ...ppBuilder.java => LocationAppBuilder.java} | 8 ++--- ...tion.java => MainLocationApplication.java} | 4 +-- .../app/SuggestedLocationsApplication.java | 31 +++++++++++++++++++ ....java => MainLocationApplicationTest.java} | 4 +-- 5 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/main/java/app/HomeScreenApplication.java rename src/main/java/app/{NoteAppBuilder.java => LocationAppBuilder.java} (91%) rename src/main/java/app/{MainNoteApplication.java => MainLocationApplication.java} (95%) create mode 100644 src/main/java/app/SuggestedLocationsApplication.java rename src/test/java/app/{MainNoteApplicationTest.java => MainLocationApplicationTest.java} (96%) diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java new file mode 100644 index 000000000..876ac1daf --- /dev/null +++ b/src/main/java/app/HomeScreenApplication.java @@ -0,0 +1,30 @@ +package app; + +import javax.swing.JFrame; +import javax.swing.WindowConstants; + +/** + * Builder for the Home Screen Application. + */ +public class HomeScreenApplication { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + + public JFrame build() { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Home Screen Application"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(noteView); + + // refresh so that the note will be visible when we start the program + noteInteractor.executeRefresh(); + + return frame; + + } +} + + diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/LocationAppBuilder.java similarity index 91% rename from src/main/java/app/NoteAppBuilder.java rename to src/main/java/app/LocationAppBuilder.java index a68cb9ad6..cc2f425c9 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -14,7 +14,7 @@ /** * Builder for the Note Application. */ -public class NoteAppBuilder { +public class LocationAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; private NoteDataAccessInterface noteDAO; @@ -27,7 +27,7 @@ public class NoteAppBuilder { * @param noteDataAccess the DAO to use * @return this builder */ - public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { + public LocationAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { noteDAO = noteDataAccess; return this; } @@ -39,7 +39,7 @@ public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { * @return this builder * @throws RuntimeException if this method is called before addNoteView */ - public NoteAppBuilder addNoteUseCase() { + public LocationAppBuilder addNoteUseCase() { final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); noteInteractor = new NoteInteractor( noteDAO, noteOutputBoundary); @@ -56,7 +56,7 @@ public NoteAppBuilder addNoteUseCase() { * Creates the NoteView and underlying NoteViewModel. * @return this builder */ - public NoteAppBuilder addNoteView() { + public LocationAppBuilder addNoteView() { noteViewModel = new NoteViewModel(); noteView = new NoteView(noteViewModel); return this; diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainLocationApplication.java similarity index 95% rename from src/main/java/app/MainNoteApplication.java rename to src/main/java/app/MainLocationApplication.java index c37860156..78759055c 100644 --- a/src/main/java/app/MainNoteApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -19,7 +19,7 @@ * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting * switching between views depending on your project. */ -public class MainNoteApplication { +public class MainLocationApplication { /** * The main entry point of the application. @@ -48,7 +48,7 @@ public static void main(String[] args) { // create the data access and inject it into our builder! final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject(); - final NoteAppBuilder builder = new NoteAppBuilder(); + final LocationAppBuilder builder = new LocationAppBuilder(); builder.addNoteDAO(noteDataAccess) .addNoteView() .addNoteUseCase().build().setVisible(true); diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java new file mode 100644 index 000000000..112c410d7 --- /dev/null +++ b/src/main/java/app/SuggestedLocationsApplication.java @@ -0,0 +1,31 @@ +package app; + +import javax.swing.JFrame; +import javax.swing.WindowConstants; + + +/** + * Builder for the Suggested Locations Application. + */ +public class SuggestedLocationsApplication { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + + public JFrame build() { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Suggested Locations Application"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(noteView); + + // refresh so that the note will be visible when we start the program + noteInteractor.executeRefresh(); + + return frame; + + } +} + + diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainLocationApplicationTest.java similarity index 96% rename from src/test/java/app/MainNoteApplicationTest.java rename to src/test/java/app/MainLocationApplicationTest.java index 025d970e2..94546ef3f 100644 --- a/src/test/java/app/MainNoteApplicationTest.java +++ b/src/test/java/app/MainLocationApplicationTest.java @@ -11,7 +11,7 @@ import static java.lang.Thread.sleep; import static org.junit.Assert.*; -public class MainNoteApplicationTest { +public class MainLocationApplicationTest { private JFrame app; @@ -35,7 +35,7 @@ public String loadNote(User user) { } }; - final NoteAppBuilder builder = new NoteAppBuilder(); + final LocationAppBuilder builder = new LocationAppBuilder(); app = builder.addNoteDAO(noteDataAccess) .addNoteView() .addNoteUseCase().build(); From 8bffb8c34a2d7189d16a2b2ac3f654a4adc55de2 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 20:53:53 -0500 Subject: [PATCH 023/113] Added home screen application --- src/main/java/app/HomeScreenApplication.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java index 876ac1daf..8c26e504f 100644 --- a/src/main/java/app/HomeScreenApplication.java +++ b/src/main/java/app/HomeScreenApplication.java @@ -1,15 +1,10 @@ -package app; - import javax.swing.JFrame; import javax.swing.WindowConstants; -/** - * Builder for the Home Screen Application. - */ public class HomeScreenApplication { public static final int HEIGHT = 300; public static final int WIDTH = 400; - +// private LocationViewModel locationViewModel = new LocationViewModel(); public JFrame build() { final JFrame frame = new JFrame(); @@ -17,14 +12,12 @@ public JFrame build() { frame.setTitle("Home Screen Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(noteView); +// frame.add(noteView); - // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); +// noteInteractor.executeRefresh(); return frame; } -} - +} \ No newline at end of file From 594fbe38ae4d50b778724de05f3dad85405c9075 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 20:27:26 -0500 Subject: [PATCH 024/113] fixed merge conflicts --- src/main/java/app/HomeScreenApplication.java | 30 ++++++++++++++++++ ...ppBuilder.java => LocationAppBuilder.java} | 11 ++++--- ...tion.java => MainLocationApplication.java} | 4 +-- .../app/SuggestedLocationsApplication.java | 31 +++++++++++++++++++ ....java => MainLocationApplicationTest.java} | 4 +-- 5 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/main/java/app/HomeScreenApplication.java rename src/main/java/app/{NoteAppBuilder.java => LocationAppBuilder.java} (85%) rename src/main/java/app/{MainNoteApplication.java => MainLocationApplication.java} (95%) create mode 100644 src/main/java/app/SuggestedLocationsApplication.java rename src/test/java/app/{MainNoteApplicationTest.java => MainLocationApplicationTest.java} (96%) diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java new file mode 100644 index 000000000..876ac1daf --- /dev/null +++ b/src/main/java/app/HomeScreenApplication.java @@ -0,0 +1,30 @@ +package app; + +import javax.swing.JFrame; +import javax.swing.WindowConstants; + +/** + * Builder for the Home Screen Application. + */ +public class HomeScreenApplication { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + + public JFrame build() { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Home Screen Application"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(noteView); + + // refresh so that the note will be visible when we start the program + noteInteractor.executeRefresh(); + + return frame; + + } +} + + diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/LocationAppBuilder.java similarity index 85% rename from src/main/java/app/NoteAppBuilder.java rename to src/main/java/app/LocationAppBuilder.java index 6e8e216f8..aca730fd5 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -14,7 +14,7 @@ /** * Builder for the Note Application. */ -public class NoteAppBuilder { +public class LocationAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; private NoteDataAccessInterface noteDAO; @@ -27,7 +27,7 @@ public class NoteAppBuilder { * @param noteDataAccess the DAO to use * @return this builder */ - public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { + public LocationAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { noteDAO = noteDataAccess; return this; } @@ -39,8 +39,8 @@ public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { * @return this builder * @throws RuntimeException if this method is called before addNoteView */ - public NoteAppBuilder addNoteUseCase() { - final NoteOutputBoundary noteOutputBoundary = new LocationPresenter(locationViewModel); + public LocationAppBuilder addNoteUseCase() { + final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); noteInteractor = new NoteInteractor( noteDAO, noteOutputBoundary); @@ -56,6 +56,9 @@ public NoteAppBuilder addNoteUseCase() { * Creates the NoteView and underlying NoteViewModel. * @return this builder */ + public LocationAppBuilder addNoteView() { + noteViewModel = new NoteViewModel(); + noteView = new NoteView(noteViewModel); public NoteAppBuilder addNoteView() { locationViewModel = new LocationViewModel(); noteView = new NoteView(locationViewModel); diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainLocationApplication.java similarity index 95% rename from src/main/java/app/MainNoteApplication.java rename to src/main/java/app/MainLocationApplication.java index a51dc8edc..dc7e1c87c 100644 --- a/src/main/java/app/MainNoteApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -19,7 +19,7 @@ * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting * switching between views depending on your project. */ -public class MainNoteApplication { +public class MainLocationApplication { /** * The main entry point of the application. @@ -48,7 +48,7 @@ public static void main(String[] args) { // create the data access and inject it into our builder! final NoteDataAccessInterface noteDataAccess = new DBLocationDataAccessObject(); - final NoteAppBuilder builder = new NoteAppBuilder(); + final LocationAppBuilder builder = new LocationAppBuilder(); builder.addNoteDAO(noteDataAccess) .addNoteView() .addNoteUseCase().build().setVisible(true); diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java new file mode 100644 index 000000000..112c410d7 --- /dev/null +++ b/src/main/java/app/SuggestedLocationsApplication.java @@ -0,0 +1,31 @@ +package app; + +import javax.swing.JFrame; +import javax.swing.WindowConstants; + + +/** + * Builder for the Suggested Locations Application. + */ +public class SuggestedLocationsApplication { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + + public JFrame build() { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Suggested Locations Application"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(noteView); + + // refresh so that the note will be visible when we start the program + noteInteractor.executeRefresh(); + + return frame; + + } +} + + diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainLocationApplicationTest.java similarity index 96% rename from src/test/java/app/MainNoteApplicationTest.java rename to src/test/java/app/MainLocationApplicationTest.java index 025d970e2..94546ef3f 100644 --- a/src/test/java/app/MainNoteApplicationTest.java +++ b/src/test/java/app/MainLocationApplicationTest.java @@ -11,7 +11,7 @@ import static java.lang.Thread.sleep; import static org.junit.Assert.*; -public class MainNoteApplicationTest { +public class MainLocationApplicationTest { private JFrame app; @@ -35,7 +35,7 @@ public String loadNote(User user) { } }; - final NoteAppBuilder builder = new NoteAppBuilder(); + final LocationAppBuilder builder = new LocationAppBuilder(); app = builder.addNoteDAO(noteDataAccess) .addNoteView() .addNoteUseCase().build(); From 08db0c1cf4258624ac0f693dc22faa68d932a802 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 20:53:53 -0500 Subject: [PATCH 025/113] Added home screen application --- src/main/java/app/HomeScreenApplication.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java index 876ac1daf..8c26e504f 100644 --- a/src/main/java/app/HomeScreenApplication.java +++ b/src/main/java/app/HomeScreenApplication.java @@ -1,15 +1,10 @@ -package app; - import javax.swing.JFrame; import javax.swing.WindowConstants; -/** - * Builder for the Home Screen Application. - */ public class HomeScreenApplication { public static final int HEIGHT = 300; public static final int WIDTH = 400; - +// private LocationViewModel locationViewModel = new LocationViewModel(); public JFrame build() { final JFrame frame = new JFrame(); @@ -17,14 +12,12 @@ public JFrame build() { frame.setTitle("Home Screen Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(noteView); +// frame.add(noteView); - // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); +// noteInteractor.executeRefresh(); return frame; } -} - +} \ No newline at end of file From 557970291ea0ada703c294e85e6dbd5677208c65 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 23:14:59 -0500 Subject: [PATCH 026/113] renamed noteview etc. --- src/main/java/app/NoteAppBuilder.java | 6 +- .../DBLocationDataAccessObject.java | 2 +- .../location/LocationPresenter.java | 11 ++-- .../location/LocationViewModel.java | 2 +- .../location/LocationInputBoundary.java | 25 -------- .../use_case/location/LocationInteractor.java | 59 ------------------- .../location/LocationOutputBoundary.java | 18 ------ .../DataAccessException.java | 2 +- .../LocationDataAccessInterface.java | 2 - .../SuggestLocationsInputBoundary.java | 6 +- .../SuggestLocationsInteractor.java | 1 - .../view/{NoteView.java => LocationView.java} | 14 ++--- 12 files changed, 24 insertions(+), 124 deletions(-) delete mode 100644 src/main/java/use_case/location/LocationInputBoundary.java delete mode 100644 src/main/java/use_case/location/LocationInteractor.java delete mode 100644 src/main/java/use_case/location/LocationOutputBoundary.java rename src/main/java/use_case/{location => suggest_locations}/DataAccessException.java (85%) rename src/main/java/view/{NoteView.java => LocationView.java} (92%) diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java index 6e8e216f8..62c6ff6c5 100644 --- a/src/main/java/app/NoteAppBuilder.java +++ b/src/main/java/app/NoteAppBuilder.java @@ -9,7 +9,7 @@ import use_case.note.NoteDataAccessInterface; import use_case.note.NoteInteractor; import use_case.note.NoteOutputBoundary; -import view.NoteView; +import view.LocationView; /** * Builder for the Note Application. @@ -19,7 +19,7 @@ public class NoteAppBuilder { public static final int WIDTH = 400; private NoteDataAccessInterface noteDAO; private LocationViewModel locationViewModel = new LocationViewModel(); - private NoteView noteView; + private LocationView noteView; private NoteInteractor noteInteractor; /** @@ -58,7 +58,7 @@ public NoteAppBuilder addNoteUseCase() { */ public NoteAppBuilder addNoteView() { locationViewModel = new LocationViewModel(); - noteView = new NoteView(locationViewModel); + noteView = new LocationView(locationViewModel); return this; } diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 95d345597..63afa1a59 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -11,7 +11,7 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import use_case.note.DataAccessException; +import use_case.suggest_locations.DataAccessException; import use_case.suggest_locations.LocationDataAccessInterface; /** diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 74bfdc8b6..934431e4a 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -1,9 +1,12 @@ package interface_adapter.location; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggest_locations.SuggestLocationsOutputData; + /** * The presenter for our Note viewing and editing program. */ -public class LocationPresenter implements use_case.note.LocationOutputBoundary { +public class LocationPresenter implements SuggestLocationsOutputBoundary { private final LocationViewModel locationViewModel; @@ -14,11 +17,11 @@ public LocationPresenter(LocationViewModel locationViewModel) { /** * Prepares the success view for the Note related Use Cases. * - * @param note the output data + * @param outputData the output data */ @Override - public void prepareSuccessView(String note) { - locationViewModel.getState().setNote(note); + public void prepareSuccessView(SuggestLocationsOutputData outputData) { + locationViewModel.getState().setLocation(outputData.getLocation()); locationViewModel.getState().setError(null); locationViewModel.firePropertyChanged(); } diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index 63adebd46..6ad6f76c9 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -7,7 +7,7 @@ */ public class LocationViewModel extends ViewModel { public LocationViewModel() { - super("note"); + super("location"); setState(new LocationState()); } } diff --git a/src/main/java/use_case/location/LocationInputBoundary.java b/src/main/java/use_case/location/LocationInputBoundary.java deleted file mode 100644 index c3266ebb8..000000000 --- a/src/main/java/use_case/location/LocationInputBoundary.java +++ /dev/null @@ -1,25 +0,0 @@ -package use_case.location; - -/** - * The Input Boundary for our note-related use cases. Since they are closely related, - * we have included them both in the same interface for simplicity. - */ -public interface LocationInputBoundary { - - void setCity(String city); - - void setAddress(String address); - - void setInterest(String interest); - - /** - * Executes the refresh note use case. - */ - void executeRefresh(); - - /** - * Executes the save note use case. - * @param message the input data - */ - void executeSave(String message); -} diff --git a/src/main/java/use_case/location/LocationInteractor.java b/src/main/java/use_case/location/LocationInteractor.java deleted file mode 100644 index 874a14b27..000000000 --- a/src/main/java/use_case/location/LocationInteractor.java +++ /dev/null @@ -1,59 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * The "Use Case Interactor" for our two note-related use cases of refreshing - * the contents of the note and saving the contents of the note. Since they - * are closely related, we have combined them here for simplicity. - */ -public class LocationInteractor implements NoteInputBoundary { - - private final NoteDataAccessInterface noteDataAccessInterface; - private final NoteOutputBoundary noteOutputBoundary; - // Note: this program has it hardcoded which user object it is getting data for; - // you could change this if you wanted to generalize the code. For example, - // you might allow a user of the program to create a new note, which you - // could store as a "user" through the API OR you might maintain all notes - // in a JSON object stored in one common "user" stored through the API. - private final User user = new User("jonathan_calver2", "abc123"); - - public LocationInteractor(NoteDataAccessInterface noteDataAccessInterface, - NoteOutputBoundary noteOutputBoundary) { - this.noteDataAccessInterface = noteDataAccessInterface; - this.noteOutputBoundary = noteOutputBoundary; - } - - /** - * Executes the refresh note use case. - * - */ - @Override - public void executeRefresh() { - try { - - final String note = noteDataAccessInterface.loadNote(user); - noteOutputBoundary.prepareSuccessView(note); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } - - /** - * Executes the save note use case. - * - * @param note the input data - */ - @Override - public void executeSave(String note) { - try { - - final String updatedNote = noteDataAccessInterface.saveNote(user, note); - noteOutputBoundary.prepareSuccessView(updatedNote); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } -} diff --git a/src/main/java/use_case/location/LocationOutputBoundary.java b/src/main/java/use_case/location/LocationOutputBoundary.java deleted file mode 100644 index e7e04a58b..000000000 --- a/src/main/java/use_case/location/LocationOutputBoundary.java +++ /dev/null @@ -1,18 +0,0 @@ -package use_case.location; - -/** - * The output boundary for the Login Use Case. - */ -public interface LocationOutputBoundary { - /** - * Prepares the success view for the Note related Use Cases. - * @param message the output data - */ - void prepareSuccessView(String message); - - /** - * Prepares the failure view for the Note related Use Cases. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); -} diff --git a/src/main/java/use_case/location/DataAccessException.java b/src/main/java/use_case/suggest_locations/DataAccessException.java similarity index 85% rename from src/main/java/use_case/location/DataAccessException.java rename to src/main/java/use_case/suggest_locations/DataAccessException.java index 6483b8b51..911c948eb 100644 --- a/src/main/java/use_case/location/DataAccessException.java +++ b/src/main/java/use_case/suggest_locations/DataAccessException.java @@ -1,4 +1,4 @@ -package use_case.location; +package use_case.suggest_locations; /** * Exception thrown when there is an error with accessing data. diff --git a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java index f955e0ac4..042be973f 100644 --- a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java +++ b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java @@ -1,7 +1,5 @@ package use_case.suggest_locations; -import use_case.location.DataAccessException; - /** * Interface for the LocationDAO. It consists of methods for * searching locations diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java index c19c1c8eb..fda953ee8 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java @@ -1,12 +1,14 @@ package use_case.suggest_locations; -import use_case.note.DataAccessException; - /** * The Suggest Locations Use Case. */ public interface SuggestLocationsInputBoundary { + void setAddress(String address); + + void setInterest(String interest); + /** * Execute the Suggest Locations Use Case. * @param suggestLocationsInputData the input data for this use case diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index c81567435..66f3e4f78 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -5,7 +5,6 @@ import entity.Place; import entity.PlaceFactory; -import use_case.note.DataAccessException; /** * The Suggest Locations Interactor. diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/LocationView.java similarity index 92% rename from src/main/java/view/NoteView.java rename to src/main/java/view/LocationView.java index f1d101ee1..8177bb717 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/LocationView.java @@ -15,14 +15,14 @@ import interface_adapter.location.LocationViewModel; /** - * The View for when the user is viewing a note in the program. + * The View for when the user is viewing a in the program. */ -public class NoteView extends JPanel implements ActionListener, PropertyChangeListener { +public class LocationView extends JPanel implements ActionListener, PropertyChangeListener { private static final int TEXT_FIELD_WIDTH = 30; private static final int KEYWORD_FIELD_WIDTH = 10; private final LocationViewModel locationViewModel; - private final JLabel noteName = new JLabel("Home Screen"); + private final JLabel locationName = new JLabel("Home Screen"); private final JTextField cityField; private final JTextField addressField; private final JTextField keyword1Field; @@ -34,7 +34,7 @@ public class NoteView extends JPanel implements ActionListener, PropertyChangeLi private final JButton suggestButton = new JButton("Suggest Locations"); private LocationController locationController; - public NoteView(LocationViewModel locationViewModel) { + public LocationView(LocationViewModel locationViewModel) { cityField = new JTextField(TEXT_FIELD_WIDTH); addressField = new JTextField(TEXT_FIELD_WIDTH); keyword1Field = new JTextField(KEYWORD_FIELD_WIDTH); @@ -42,7 +42,7 @@ public NoteView(LocationViewModel locationViewModel) { keyword3Field = new JTextField(KEYWORD_FIELD_WIDTH); keyword4Field = new JTextField(KEYWORD_FIELD_WIDTH); keyword5Field = new JTextField(KEYWORD_FIELD_WIDTH); - noteName.setAlignmentX(Component.CENTER_ALIGNMENT); + locationName.setAlignmentX(Component.CENTER_ALIGNMENT); this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); @@ -71,12 +71,12 @@ public NoteView(LocationViewModel locationViewModel) { }); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(noteName); + this.add(locationName); this.add(panel); this.setVisible(true); } - public void setNoteController(LocationController controller) { + public void setLocationController(LocationController controller) { this.locationController = controller; } From 44535f8f490cc53d5bce589f3c4f82444e63b04a Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 23:15:52 -0500 Subject: [PATCH 027/113] updated some variable names --- src/main/java/app/LocationAppBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index aca730fd5..f321a2cee 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -6,9 +6,9 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import use_case.note.NoteDataAccessInterface; -import use_case.note.NoteInteractor; -import use_case.note.NoteOutputBoundary; +import use_case.location.locationDataAccessInterface; +import use_case.location.ocationInteractor; +import use_case.location.ocationOutputBoundary; import view.NoteView; /** From 4c8754a737d284013c8935e8d353e9d2f73e3430 Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Sun, 10 Nov 2024 23:20:05 -0500 Subject: [PATCH 028/113] Update LocationAppBuilder.java --- src/main/java/app/LocationAppBuilder.java | 44 +++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index f321a2cee..cb122ad1e 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -6,10 +6,10 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import use_case.location.locationDataAccessInterface; -import use_case.location.ocationInteractor; -import use_case.location.ocationOutputBoundary; -import view.NoteView; +import use_case.suggest_location.locationDataAccessInterface; +import use_case.suggest_location.locationInteractor; +import use_case.suggest_location.ocationOutputBoundary; +import view.LocationView; /** * Builder for the Note Application. @@ -17,9 +17,9 @@ public class LocationAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; - private NoteDataAccessInterface noteDAO; + private LocationDataAccessInterface locationDAO; private LocationViewModel locationViewModel = new LocationViewModel(); - private NoteView noteView; + private LocationView locationView; private NoteInteractor noteInteractor; /** @@ -27,8 +27,8 @@ public class LocationAppBuilder { * @param noteDataAccess the DAO to use * @return this builder */ - public LocationAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { - noteDAO = noteDataAccess; + public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { + locationDAO = locationDataAccess; return this; } @@ -39,16 +39,16 @@ public LocationAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { * @return this builder * @throws RuntimeException if this method is called before addNoteView */ - public LocationAppBuilder addNoteUseCase() { - final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); - noteInteractor = new NoteInteractor( - noteDAO, noteOutputBoundary); + public LocationAppBuilder addLocationUseCase() { + final LocationOutputBoundary locationOutputBoundary = new LocationPresenter(locationViewModel); + locationInteractor = new LocationInteractor( + locationDAO, locationOutputBoundary); - final LocationController controller = new LocationController(noteInteractor); - if (noteView == null) { + final LocationController controller = new LocationController(locationInteractor); + if (locationView == null) { throw new RuntimeException("addNoteView must be called before addNoteUseCase"); } - noteView.setNoteController(controller); + locationView.setLocationController(controller); return this; } @@ -56,12 +56,12 @@ public LocationAppBuilder addNoteUseCase() { * Creates the NoteView and underlying NoteViewModel. * @return this builder */ - public LocationAppBuilder addNoteView() { - noteViewModel = new NoteViewModel(); - noteView = new NoteView(noteViewModel); - public NoteAppBuilder addNoteView() { + public LocationAppBuilder addLocationView() { locationViewModel = new LocationViewModel(); - noteView = new NoteView(locationViewModel); + locationView = new LocationView(locationViewModel); + public LocationAppBuilder addLocationView() { + locationViewModel = new LocationViewModel(); + locationView = new LocationView(locationViewModel); return this; } @@ -72,10 +72,10 @@ public NoteAppBuilder addNoteView() { public JFrame build() { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Note Application"); + frame.setTitle("Location Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(noteView); + frame.add(locationView); // refresh so that the note will be visible when we start the program noteInteractor.executeRefresh(); From 73e555d7df5a98669d8290d44bf7e1102af7c6ab Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Sun, 10 Nov 2024 23:21:26 -0500 Subject: [PATCH 029/113] Update MainLocationApplication.java --- src/main/java/app/MainLocationApplication.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java index dc7e1c87c..9c9bb8835 100644 --- a/src/main/java/app/MainLocationApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -1,7 +1,7 @@ package app; import data_access.DBLocationDataAccessObject; -import use_case.note.NoteDataAccessInterface; +import use_case.suggest_locations.LocationDataAccessInterface; /** * An application where we can view and add to a note stored by a user. @@ -46,11 +46,11 @@ public class MainLocationApplication { public static void main(String[] args) { // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new DBLocationDataAccessObject(); + final LocationDataAccessInterface locationDataAccess = new DBLocationDataAccessObject(); final LocationAppBuilder builder = new LocationAppBuilder(); - builder.addNoteDAO(noteDataAccess) - .addNoteView() - .addNoteUseCase().build().setVisible(true); + builder.addLocationDAO(locationDataAccess) + .addLocationView() + .addLocationUseCase().build().setVisible(true); } } From 0c714145a33e8fca2374a9801f90bc03d6c9a9da Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Sun, 10 Nov 2024 23:21:51 -0500 Subject: [PATCH 030/113] Update SuggestedLocationsApplication.java --- src/main/java/app/SuggestedLocationsApplication.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java index 112c410d7..0f946b501 100644 --- a/src/main/java/app/SuggestedLocationsApplication.java +++ b/src/main/java/app/SuggestedLocationsApplication.java @@ -18,10 +18,10 @@ public JFrame build() { frame.setTitle("Suggested Locations Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(noteView); + frame.add(locationView); // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); + locationInteractor.executeRefresh(); return frame; From ffa2d379faaa8c2527009b1c4e774370fc30b385 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 10 Nov 2024 23:49:21 -0500 Subject: [PATCH 031/113] added text field --- src/main/java/app/LocationAppBuilder.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index cb122ad1e..589374bcf 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -1,16 +1,17 @@ package app; -import javax.swing.JFrame; -import javax.swing.WindowConstants; +import javax.swing.*; import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; import use_case.suggest_location.locationDataAccessInterface; import use_case.suggest_location.locationInteractor; -import use_case.suggest_location.ocationOutputBoundary; +import use_case.suggest_location.locationOutputBoundary; import view.LocationView; +import java.awt.*; + /** * Builder for the Note Application. */ @@ -75,7 +76,10 @@ public JFrame build() { frame.setTitle("Location Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(locationView); + JTextField userInputField = new JTextField(); + frame.add(userInputField, BorderLayout.NORTH); + + frame.add(locationView, BorderLayout.CENTER); // refresh so that the note will be visible when we start the program noteInteractor.executeRefresh(); From f72c26deebc9e8f6c77ef2a95796bbf20dd33800 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 10 Nov 2024 23:54:46 -0500 Subject: [PATCH 032/113] fixed locationview, and usecases --- src/main/java/app/LocationAppBuilder.java | 24 ++++++++--------- .../app/SuggestedLocationsApplication.java | 2 +- .../location/LocationController.java | 26 +++++++------------ .../SuggestLocationsInteractor.java | 10 +++++++ src/main/java/view/LocationView.java | 12 ++++++--- 5 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index cb122ad1e..b110f8fb2 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -3,12 +3,13 @@ import javax.swing.JFrame; import javax.swing.WindowConstants; +import entity.PlaceFactory; import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import use_case.suggest_location.locationDataAccessInterface; -import use_case.suggest_location.locationInteractor; -import use_case.suggest_location.ocationOutputBoundary; +import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInteractor; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; import view.LocationView; /** @@ -20,11 +21,12 @@ public class LocationAppBuilder { private LocationDataAccessInterface locationDAO; private LocationViewModel locationViewModel = new LocationViewModel(); private LocationView locationView; - private NoteInteractor noteInteractor; + private SuggestLocationsInteractor locationInteractor; + private PlaceFactory placeFactory; /** * Sets the NoteDAO to be used in this application. - * @param noteDataAccess the DAO to use + * @param locationDataAccess the DAO to use * @return this builder */ public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { @@ -40,9 +42,9 @@ public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDat * @throws RuntimeException if this method is called before addNoteView */ public LocationAppBuilder addLocationUseCase() { - final LocationOutputBoundary locationOutputBoundary = new LocationPresenter(locationViewModel); - locationInteractor = new LocationInteractor( - locationDAO, locationOutputBoundary); + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); + locationInteractor = new SuggestLocationsInteractor( + locationDAO, suggestLocationsOutputBoundary, placeFactory); final LocationController controller = new LocationController(locationInteractor); if (locationView == null) { @@ -56,9 +58,7 @@ public LocationAppBuilder addLocationUseCase() { * Creates the NoteView and underlying NoteViewModel. * @return this builder */ - public LocationAppBuilder addLocationView() { - locationViewModel = new LocationViewModel(); - locationView = new LocationView(locationViewModel); + public LocationAppBuilder addLocationView() { locationViewModel = new LocationViewModel(); locationView = new LocationView(locationViewModel); @@ -78,7 +78,7 @@ public JFrame build() { frame.add(locationView); // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); + locationInteractor.execute(); return frame; diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java index 0f946b501..007f19b57 100644 --- a/src/main/java/app/SuggestedLocationsApplication.java +++ b/src/main/java/app/SuggestedLocationsApplication.java @@ -18,7 +18,7 @@ public JFrame build() { frame.setTitle("Suggested Locations Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(locationView); + frame.add(LocationView); // refresh so that the note will be visible when we start the program locationInteractor.executeRefresh(); diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 4a9537b72..6072e812e 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,6 +1,8 @@ package interface_adapter.location; -import use_case.location.LocationInputBoundary; +import use_case.suggest_locations.DataAccessException; +import use_case.suggest_locations.SuggestLocationsInputBoundary; +import use_case.suggest_locations.SuggestLocationsInputData; /** * The LocationController class handles user input related to locations. @@ -10,20 +12,12 @@ */ public class LocationController { - private final LocationInputBoundary locationInteractor; + private final SuggestLocationsInputBoundary locationInteractor; - public LocationController(LocationInputBoundary locationInteractor) { + public LocationController(SuggestLocationsInputBoundary locationInteractor) { this.locationInteractor = locationInteractor; } - /** - * Handles the selection of a city. - * @param city the selected city - */ - public void handleCitySelection(String city) { - locationInteractor.setCity(city); - } - /** * Handles the input of an address. * @param address the input address @@ -44,12 +38,10 @@ public void handleInterestSelection(String interest) { * Executes the save or refresh operation based on the location. * @param location the location to save or refresh */ - public void execute(String location) { - if (location != null) { - locationInteractor.executeSave(location); - } - else { - locationInteractor.executeRefresh(); + public void execute(SuggestLocationsInputData location) throws DataAccessException { + if (location == null) { + throw new DataAccessException("Location is null"); } + locationInteractor.execute(location); } } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 66f3e4f78..1becb42e8 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -22,6 +22,16 @@ public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPl this.placeFactory = placeFactory; } + @Override + public void setAddress(String address) { + + } + + @Override + public void setInterest(String interest) { + + } + @Override public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 8177bb717..2a4208ae8 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -13,6 +13,8 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; +import use_case.suggest_locations.DataAccessException; +import use_case.suggest_locations.SuggestLocationsInputData; /** * The View for when the user is viewing a in the program. @@ -61,12 +63,16 @@ public LocationView(LocationViewModel locationViewModel) { suggestButton.addActionListener(evt -> { if (evt.getSource().equals(suggestButton)) { - final String city = cityField.getText().trim(); final String address = addressField.getText().trim(); final List keywords = getKeywords(); final String joinedKeywords = String.join(";", keywords); - final String inputText = String.join(";", city, address, joinedKeywords); - locationController.execute(inputText); + final SuggestLocationsInputData inputText = new SuggestLocationsInputData(address, joinedKeywords); + try { + locationController.execute(inputText); + } + catch (DataAccessException dataAccessException) { + JOptionPane.showMessageDialog(this, "Error accessing data: " + dataAccessException.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } } }); From 278ed43e2fe206dcd59195d943761ed643e9200c Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 00:08:21 -0500 Subject: [PATCH 033/113] Small updates in location state --- src/main/java/interface_adapter/location/LocationState.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index 6732d6af7..5022513b7 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -4,7 +4,8 @@ import java.util.List; /** - * The State for a note. + * The state representing location-related data, including city, address, keywords, + * suggested locations, and any error messages. */ public class LocationState { private String error; From 150f20b2b05fe295a246dd68d19c84998b4d5649 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 00:09:10 -0500 Subject: [PATCH 034/113] Small updates in location state --- .../java/interface_adapter/location/LocationState.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index 5022513b7..f50441dd0 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -22,14 +22,6 @@ public LocationState() { this.suggestedLocations = new ArrayList<>(); } - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - public String getAddress() { return address; } From b54ab0815d393e137e5eb02a990f3964fba5ad2a Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 00:10:16 -0500 Subject: [PATCH 035/113] Small updates in location state --- src/main/java/interface_adapter/location/LocationState.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index f50441dd0..d1277a6fa 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -9,7 +9,6 @@ */ public class LocationState { private String error; - private String city; private String address; private String keyword1; private String keyword2; From 0ed5dbf6dd09f88a7d8ff09c6deb29806da4878f Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Mon, 11 Nov 2024 00:55:17 -0500 Subject: [PATCH 036/113] LocationAppBuilder should be functional, modified location view --- src/main/java/app/LocationAppBuilder.java | 27 +++++++++---------- .../app/SuggestedLocationsApplication.java | 20 ++++++++++++-- src/main/java/view/LocationView.java | 8 +++--- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index b110f8fb2..f1f2b5927 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -7,13 +7,11 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInteractor; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggest_locations.*; import view.LocationView; /** - * Builder for the Note Application. + * Builder for the Location Application. */ public class LocationAppBuilder { public static final int HEIGHT = 300; @@ -25,7 +23,7 @@ public class LocationAppBuilder { private PlaceFactory placeFactory; /** - * Sets the NoteDAO to be used in this application. + * Sets the LocationDAO to be used in this application. * @param locationDataAccess the DAO to use * @return this builder */ @@ -35,11 +33,12 @@ public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDat } /** - * Creates the objects for the Note Use Case and connects the NoteView to its + * Creates the objects for the Location Use Case and connects the + * LocationView to its * controller. - *

This method must be called after addNoteView!

+ *

This method must be called after addLocationView!

* @return this builder - * @throws RuntimeException if this method is called before addNoteView + * @throws RuntimeException if this method is called before addLocationView */ public LocationAppBuilder addLocationUseCase() { final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); @@ -48,17 +47,16 @@ public LocationAppBuilder addLocationUseCase() { final LocationController controller = new LocationController(locationInteractor); if (locationView == null) { - throw new RuntimeException("addNoteView must be called before addNoteUseCase"); + throw new RuntimeException("addLocationView must be called before" + " addLocationUseCase"); } locationView.setLocationController(controller); return this; } /** - * Creates the NoteView and underlying NoteViewModel. + * Creates the LocationView and underlying LocationViewModel. * @return this builder */ - public LocationAppBuilder addLocationView() { locationViewModel = new LocationViewModel(); locationView = new LocationView(locationViewModel); @@ -69,7 +67,7 @@ public LocationAppBuilder addLocationView() { * Builds the application. * @return the JFrame for the application */ - public JFrame build() { + public JFrame build() throws DataAccessException { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setTitle("Location Application"); @@ -77,8 +75,9 @@ public JFrame build() { frame.add(locationView); - // refresh so that the note will be visible when we start the program - locationInteractor.execute(); + final SuggestLocationsInputData inputData = locationView.getInputData(); + + locationInteractor.execute(inputData); return frame; diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java index 007f19b57..1a3ab2879 100644 --- a/src/main/java/app/SuggestedLocationsApplication.java +++ b/src/main/java/app/SuggestedLocationsApplication.java @@ -1,5 +1,11 @@ package app; +import entity.PlaceFactory; +import interface_adapter.location.LocationViewModel; +import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInteractor; +import view.LocationView; + import javax.swing.JFrame; import javax.swing.WindowConstants; @@ -10,17 +16,27 @@ public class SuggestedLocationsApplication { public static final int HEIGHT = 300; public static final int WIDTH = 400; + private LocationDataAccessInterface locationDAO; + private LocationViewModel locationViewModel = new LocationViewModel(); + private LocationView locationView; + private SuggestLocationsInteractor locationInteractor; + private PlaceFactory placeFactory; + + + /** + * Builds the application. + * @return the JFrame for the application + */ public JFrame build() { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setTitle("Suggested Locations Application"); frame.setSize(WIDTH, HEIGHT); - frame.add(LocationView); + frame.add(); - // refresh so that the note will be visible when we start the program locationInteractor.executeRefresh(); return frame; diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 2a4208ae8..e34cedee5 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -86,10 +86,6 @@ public void setLocationController(LocationController controller) { this.locationController = controller; } - public String getCity() { - return cityField.getText(); - } - public String getAddress() { return addressField.getText(); } @@ -120,6 +116,10 @@ public List getKeywords() { return keywords; } + public SuggestLocationsInputData getInputData() { + return new SuggestLocationsInputData(getAddress(), String.join(";", getKeywords())); + } + /** * React to a button click that results in evt. * @param evt the ActionEvent to react to From b186db96e75d97d3e30dc370af700bb8c6b6066e Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Mon, 11 Nov 2024 01:14:09 -0500 Subject: [PATCH 037/113] updated LocationAppBuilder --- src/main/java/app/LocationAppBuilder.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index d2ab6d67e..7ac76790f 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -6,9 +6,9 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.locationDataAccessInterface; -import use_case.suggest_location.locationInteractor; -import use_case.suggest_location.locationOutputBoundary; +import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInteractor; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.*; import view.LocationView; @@ -61,9 +61,6 @@ public LocationAppBuilder addLocationUseCase() { * Creates the LocationView and underlying LocationViewModel. * @return this builder */ - public LocationAppBuilder addLocationView() { - locationViewModel = new LocationViewModel(); - locationView = new LocationView(locationViewModel); public LocationAppBuilder addLocationView() { locationViewModel = new LocationViewModel(); locationView = new LocationView(locationViewModel); @@ -80,7 +77,7 @@ public JFrame build() throws DataAccessException { frame.setTitle("Location Application"); frame.setSize(WIDTH, HEIGHT); - JTextField userInputField = new JTextField(); + final JTextField userInputField = new JTextField(); frame.add(userInputField, BorderLayout.NORTH); frame.add(locationView, BorderLayout.CENTER); From 380250a070fe0d388dfda352e82d7ad781627667 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Mon, 11 Nov 2024 01:44:36 -0500 Subject: [PATCH 038/113] updated template for SuggestedLocationsAppBuilder.java --- .../app/SuggestedLocationsAppBuilder.java | 92 +++++++++++++++++++ .../app/SuggestedLocationsApplication.java | 47 ---------- 2 files changed, 92 insertions(+), 47 deletions(-) create mode 100644 src/main/java/app/SuggestedLocationsAppBuilder.java delete mode 100644 src/main/java/app/SuggestedLocationsApplication.java diff --git a/src/main/java/app/SuggestedLocationsAppBuilder.java b/src/main/java/app/SuggestedLocationsAppBuilder.java new file mode 100644 index 000000000..34e91b497 --- /dev/null +++ b/src/main/java/app/SuggestedLocationsAppBuilder.java @@ -0,0 +1,92 @@ +package app; + +import javax.swing.*; + +import entity.PlaceFactory; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationPresenter; +import interface_adapter.location.LocationViewModel; +import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInteractor; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggest_locations.*; +import view.LocationView; + +import java.awt.*; + +/** + * Builder for the Suggested Locations Application. + */ +public class SuggestedLocationsAppBuilder { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + private LocationDataAccessInterface locationDAO; + private LocationViewModel locationViewModel = new LocationViewModel(); + private LocationView locationView; + private SuggestLocationsInteractor locationInteractor; + private PlaceFactory placeFactory; + + /** + * Sets the LocationDAO to be used in this application. + * @param locationDataAccess the DAO to use + * @return this builder + */ + public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { + locationDAO = locationDataAccess; + return this; + } + + /** + * Creates the objects for the Location Use Case and connects the + * LocationView to its + * controller. + *

This method must be called after addLocationView!

+ * @return this builder + * @throws RuntimeException if this method is called before addLocationView + */ + public LocationAppBuilder addLocationUseCase() { + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); + locationInteractor = new SuggestLocationsInteractor( + locationDAO, suggestLocationsOutputBoundary, placeFactory); + + final LocationController controller = new LocationController(locationInteractor); + if (locationView == null) { + throw new RuntimeException("addLocationView must be called before" + " addLocationUseCase"); + } + locationView.setLocationController(controller); + return this; + } + + /** + * Creates the LocationView and underlying LocationViewModel. + * @return this builder + */ + public LocationAppBuilder addLocationView() { + locationViewModel = new LocationViewModel(); + locationView = new LocationView(locationViewModel); + return this; + } + + /** + * Builds the application. + * @return the JFrame for the application + */ + public JFrame build() throws DataAccessException { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Suggested Locations Application"); + frame.setSize(WIDTH, HEIGHT); + + final JTextField userInputField = new JTextField(); + frame.add(userInputField, BorderLayout.NORTH); + + frame.add(locationView, BorderLayout.CENTER); + + final SuggestLocationsInputData inputData = locationView.getInputData(); + + locationInteractor.execute(inputData); + + return frame; + + } +} diff --git a/src/main/java/app/SuggestedLocationsApplication.java b/src/main/java/app/SuggestedLocationsApplication.java deleted file mode 100644 index 1a3ab2879..000000000 --- a/src/main/java/app/SuggestedLocationsApplication.java +++ /dev/null @@ -1,47 +0,0 @@ -package app; - -import entity.PlaceFactory; -import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInteractor; -import view.LocationView; - -import javax.swing.JFrame; -import javax.swing.WindowConstants; - - -/** - * Builder for the Suggested Locations Application. - */ -public class SuggestedLocationsApplication { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - private LocationDataAccessInterface locationDAO; - private LocationViewModel locationViewModel = new LocationViewModel(); - private LocationView locationView; - private SuggestLocationsInteractor locationInteractor; - private PlaceFactory placeFactory; - - - - - /** - * Builds the application. - * @return the JFrame for the application - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Suggested Locations Application"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(); - - locationInteractor.executeRefresh(); - - return frame; - - } -} - - From 3663ed62a21bf8edf506935b14e1a856f90abae0 Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Mon, 11 Nov 2024 12:14:02 -0500 Subject: [PATCH 039/113] view pt 2 --- src/main/java/view/LocationView.java | 8 ----- .../java/view/SuggestedLocationsView.java | 36 +++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 src/main/java/view/SuggestedLocationsView.java diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 2a4208ae8..ea35862cc 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -25,7 +25,6 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private static final int KEYWORD_FIELD_WIDTH = 10; private final LocationViewModel locationViewModel; private final JLabel locationName = new JLabel("Home Screen"); - private final JTextField cityField; private final JTextField addressField; private final JTextField keyword1Field; private final JTextField keyword2Field; @@ -37,7 +36,6 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private LocationController locationController; public LocationView(LocationViewModel locationViewModel) { - cityField = new JTextField(TEXT_FIELD_WIDTH); addressField = new JTextField(TEXT_FIELD_WIDTH); keyword1Field = new JTextField(KEYWORD_FIELD_WIDTH); keyword2Field = new JTextField(KEYWORD_FIELD_WIDTH); @@ -50,7 +48,6 @@ public LocationView(LocationViewModel locationViewModel) { final JPanel panel = new JPanel(); panel.add(new JLabel("Choose City:")); - panel.add(cityField); panel.add(new JLabel("Enter Address:")); panel.add(addressField); panel.add(new JLabel("Choose Interests:")); @@ -86,10 +83,6 @@ public void setLocationController(LocationController controller) { this.locationController = controller; } - public String getCity() { - return cityField.getText(); - } - public String getAddress() { return addressField.getText(); } @@ -156,7 +149,6 @@ private void showSuggestedLocations(List locations) { } private void setFields(LocationState state) { - cityField.setText(state.getCity()); addressField.setText(state.getAddress()); keyword1Field.setText(state.getKeyword1()); keyword2Field.setText(state.getKeyword2()); diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java new file mode 100644 index 000000000..7c1bad6f8 --- /dev/null +++ b/src/main/java/view/SuggestedLocationsView.java @@ -0,0 +1,36 @@ +package view; + +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationState; +import interface_adapter.location.LocationViewModel; +import use_case.suggest_locations.DataAccessException; +import use_case.suggest_locations.SuggestLocationsInputData; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +public class SuggestedLocationsView extends JPanel { + + private JPanel suggestedLocations; + + public SuggestedLocationsView(List locations) { + if (suggestedLocations != null) { + this.remove(suggestedLocations); + } + + suggestedLocations = new JPanel(); + suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); + suggestedLocations.add(new JLabel("List of Suggested Locations:")); + for (String location : locations) { + suggestedLocations.add(new JLabel(location)); + } + this.add(suggestedLocations); + this.setVisible(true); + } +} From d8827bf5acbb63af4baeb0c3a2212e3fbb86bd8d Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 12:17:42 -0500 Subject: [PATCH 040/113] Small updates interface adapter files --- src/main/java/app/HomeScreenApplication.java | 4 +++- src/main/java/interface_adapter/ViewModel.java | 1 + .../java/interface_adapter/location/LocationController.java | 1 + .../java/interface_adapter/location/LocationViewModel.java | 2 +- src/main/java/view/LocationView.java | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java index 8c26e504f..57099c79f 100644 --- a/src/main/java/app/HomeScreenApplication.java +++ b/src/main/java/app/HomeScreenApplication.java @@ -1,3 +1,5 @@ +package app; + import javax.swing.JFrame; import javax.swing.WindowConstants; @@ -20,4 +22,4 @@ public JFrame build() { } -} \ No newline at end of file +} diff --git a/src/main/java/interface_adapter/ViewModel.java b/src/main/java/interface_adapter/ViewModel.java index 130d797a1..f4ceddcf5 100644 --- a/src/main/java/interface_adapter/ViewModel.java +++ b/src/main/java/interface_adapter/ViewModel.java @@ -45,6 +45,7 @@ public void firePropertyChanged() { * Fires a property changed event for the state of this ViewModel, which * allows the user to specify a different propertyName. This can be useful * when a class is listening for multiple kinds of property changes. + * *

For example, the LoggedInView listens for two kinds of property changes; * it can use the property name to distinguish which property has changed.

* @param propertyName the label for the property that was changed diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 6072e812e..275aed883 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -37,6 +37,7 @@ public void handleInterestSelection(String interest) { /** * Executes the save or refresh operation based on the location. * @param location the location to save or refresh + * @throws DataAccessException if the location is null */ public void execute(SuggestLocationsInputData location) throws DataAccessException { if (location == null) { diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index 6ad6f76c9..ef089e6fb 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -3,7 +3,7 @@ import interface_adapter.ViewModel; /** - * The ViewModel for the NoteView. + * The ViewModel for the LocationView. */ public class LocationViewModel extends ViewModel { public LocationViewModel() { diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 2a4208ae8..d089bf8c3 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -17,7 +17,7 @@ import use_case.suggest_locations.SuggestLocationsInputData; /** - * The View for when the user is viewing a in the program. + * The View for when the user is viewing a location in the program. */ public class LocationView extends JPanel implements ActionListener, PropertyChangeListener { From 2b0ff294aef99804cdde7deefbe93ec7d9c5d518 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Mon, 11 Nov 2024 12:26:22 -0500 Subject: [PATCH 041/113] fixed api key to be stored in .env --- .gitignore | 3 +++ src/main/java/data_access/DBLocationDataAccessObject.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 26559eb1d..1a73a2c8e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ bin/ ### Mac OS ### .DS_Store + +### API KEY ### +.env \ No newline at end of file diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 63afa1a59..c07bfc1e8 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -27,7 +27,7 @@ public class DBLocationDataAccessObject implements LocationDataAccessInterface { private static final String CONTENT_TYPE_JSON = "application/json"; private static final String STATUS_CODE_LABEL = "status_code"; private static final String MESSAGE = "message"; - private static final String API_KEY = ""; + private static final String API_KEY = System.getenv("API_KEY"); @Override public String searchLocation(String address, String locationType) throws DataAccessException { From 9a4cecadd2308432e6830ecea7b809b802b961c5 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 12:33:43 -0500 Subject: [PATCH 042/113] Small updates interface adapter files, updated LocationViewModel to use suggestedlocationsview --- .../location/LocationViewModel.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index ef089e6fb..f6e771b13 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -1,5 +1,7 @@ package interface_adapter.location; +import java.util.List; + import interface_adapter.ViewModel; /** @@ -10,4 +12,14 @@ public LocationViewModel() { super("location"); setState(new LocationState()); } + + /** + * Updates the suggested locations. + * @param suggestedLocations the list of suggested locations + */ + public void updateSuggestedLocations(List suggestedLocations) { + getState().setSuggestedLocations(suggestedLocations); + firePropertyChanged("suggestLocations"); + } + } From f7e90e7340508d8b2bacab44b68e3193aaf46b61 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 16:21:49 -0500 Subject: [PATCH 043/113] Updated Place to be a class, added features in LocationPresenter and LocationController to prepare data to be displayed in view when the location suggestion is called. --- src/main/java/entity/Place.java | 31 ++++++++++-- src/main/java/entity/SuggestedPlace.java | 2 +- .../location/LocationPresenter.java | 12 +++-- .../SuggestLocationsInteractor.java | 48 ++++++++----------- 4 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/main/java/entity/Place.java b/src/main/java/entity/Place.java index 2695234db..f7ba47898 100644 --- a/src/main/java/entity/Place.java +++ b/src/main/java/entity/Place.java @@ -3,16 +3,37 @@ /** * The representation of a place in our program. */ -public interface Place { +public class Place { + private final String name; + private final String address; + /** - * Returns the name of the place. - * @return the name of the place. + * The representation of a place. + * + * @param name the name of the place + * @param address the address of the place */ - String getName(); + public Place(String name, String address) { + this.name = name; + this.address = address; + } /** * Returns the address of the place. + * * @return the address of the place. */ - String getAddress(); + public String getName() { + return name; + } + + /** + * Returns the address of the place. + * + * @return the address of the place. + */ + public String getAddress() { + return address; + + } } diff --git a/src/main/java/entity/SuggestedPlace.java b/src/main/java/entity/SuggestedPlace.java index 6bcc77d41..83cf69b52 100644 --- a/src/main/java/entity/SuggestedPlace.java +++ b/src/main/java/entity/SuggestedPlace.java @@ -22,4 +22,4 @@ public String getName() { public String getAddress() { return address; } -} +} \ No newline at end of file diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 934431e4a..ca73364e8 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -1,5 +1,9 @@ package interface_adapter.location; +import java.util.List; +import java.util.stream.Collectors; + +import entity.Place; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; @@ -21,9 +25,10 @@ public LocationPresenter(LocationViewModel locationViewModel) { */ @Override public void prepareSuccessView(SuggestLocationsOutputData outputData) { - locationViewModel.getState().setLocation(outputData.getLocation()); - locationViewModel.getState().setError(null); - locationViewModel.firePropertyChanged(); + final List locationNames = outputData.getLocations().stream() + .map(Place::getName) + .collect(Collectors.toList()); + locationViewModel.updateSuggestedLocations(locationNames); } /** @@ -31,7 +36,6 @@ public void prepareSuccessView(SuggestLocationsOutputData outputData) { * * @param errorMessage the explanation of the failure */ - @Override public void prepareFailView(String errorMessage) { locationViewModel.getState().setError(errorMessage); locationViewModel.firePropertyChanged(); diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 1becb42e8..1c4934914 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -1,25 +1,15 @@ package use_case.suggest_locations; -import java.util.ArrayList; import java.util.List; -import entity.Place; -import entity.PlaceFactory; - -/** - * The Suggest Locations Interactor. - */ public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { - private final LocationDataAccessInterface placeDataAccessObject; - private final SuggestLocationsOutputBoundary placePresenter; - private final PlaceFactory placeFactory; - - public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, - SuggestLocationsOutputBoundary suggestLocationsOutputBoundary, - PlaceFactory placeFactory) { - this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; - this.placePresenter = suggestLocationsOutputBoundary; - this.placeFactory = placeFactory; + + private final LocationDataAccessInterface locationDataAccess; + private final SuggestLocationsOutputBoundary outputBoundary; + + public SuggestLocationsInteractor(LocationDataAccessInterface locationDataAccess, SuggestLocationsOutputBoundary outputBoundary) { + this.locationDataAccess = locationDataAccess; + this.outputBoundary = outputBoundary; } @Override @@ -33,18 +23,18 @@ public void setInterest(String interest) { } @Override - public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { - final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), - suggestLocationsInputData.getLocationType()); - final String[] locationsList = suggestedLocations.split("<:>"); - - final List suggestedPlaces = new ArrayList<>(); - for (String location : locationsList) { - suggestedPlaces.add(placeFactory.create(location.split(">")[1], location.split(">")[0])); + public void execute(SuggestLocationsInputData inputData) { + try { + String response = locationDataAccess.searchLocation(inputData.getAddress(), inputData.getInterest()); + List locations = parseResponse(response); + SuggestLocationsOutputData outputData = new SuggestLocationsOutputData(locations); + outputBoundary.prepareSuccessView(outputData); + } catch (DataAccessException e) { + outputBoundary.prepareFailView(e.getMessage()); } + } + + private List parseResponse(String response) { - final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedPlaces, - false); - placePresenter.prepareSuccessView(suggestLocationsOutputData); } -} +} \ No newline at end of file From 1979289ea7e345fc26894a5d12f037dd576daae3 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:41:27 -0500 Subject: [PATCH 044/113] Fixed minor issues in interface adapter --- .../interface_adapter/location/LocationPresenter.java | 2 +- .../java/interface_adapter/location/LocationState.java | 8 +++++--- .../interface_adapter/location/LocationViewModel.java | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 934431e4a..f63e591cc 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -21,7 +21,7 @@ public LocationPresenter(LocationViewModel locationViewModel) { */ @Override public void prepareSuccessView(SuggestLocationsOutputData outputData) { - locationViewModel.getState().setLocation(outputData.getLocation()); + locationViewModel.getState().setSuggestedLocations(outputData.getLocations()); locationViewModel.getState().setError(null); locationViewModel.firePropertyChanged(); } diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index d1277a6fa..e589b67ee 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import entity.Place; + /** * The state representing location-related data, including city, address, keywords, * suggested locations, and any error messages. @@ -15,7 +17,7 @@ public class LocationState { private String keyword3; private String keyword4; private String keyword5; - private List suggestedLocations; + private List suggestedLocations; public LocationState() { this.suggestedLocations = new ArrayList<>(); @@ -78,11 +80,11 @@ public String getError() { return error; } - public List getSuggestedLocations() { + public List getSuggestedLocations() { return suggestedLocations; } - public void setSuggestedLocations(List suggestedLocations) { + public void setSuggestedLocations(List suggestedLocations) { this.suggestedLocations = suggestedLocations; } } diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index f6e771b13..f91424629 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -2,6 +2,7 @@ import java.util.List; +import entity.Place; import interface_adapter.ViewModel; /** @@ -17,7 +18,7 @@ public LocationViewModel() { * Updates the suggested locations. * @param suggestedLocations the list of suggested locations */ - public void updateSuggestedLocations(List suggestedLocations) { + public void updateSuggestedLocations(List suggestedLocations) { getState().setSuggestedLocations(suggestedLocations); firePropertyChanged("suggestLocations"); } From fb75d60f526f1075af21bfcc3dd8ff8077c76544 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 11 Nov 2024 20:05:04 -0500 Subject: [PATCH 045/113] Updated getState --- .../java/interface_adapter/location/LocationViewModel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index f6e771b13..9fad66d5f 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -13,6 +13,10 @@ public LocationViewModel() { setState(new LocationState()); } + public LocationState getState() { + return super.getState(); + } + /** * Updates the suggested locations. * @param suggestedLocations the list of suggested locations From 69dfabb4504d420eef329a85cc309d84e77e1e9b Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Mon, 11 Nov 2024 21:07:44 -0500 Subject: [PATCH 046/113] Used input and output data to change views --- .../location/LocationState.java | 33 +++++++++ src/main/java/view/LocationView.java | 67 ++++++------------- .../java/view/SuggestedLocationsView.java | 36 +++++----- 3 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index e589b67ee..8268933ee 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -4,6 +4,7 @@ import java.util.List; import entity.Place; +import use_case.suggest_locations.SuggestLocationsInputData; /** * The state representing location-related data, including city, address, keywords, @@ -87,4 +88,36 @@ public List getSuggestedLocations() { public void setSuggestedLocations(List suggestedLocations) { this.suggestedLocations = suggestedLocations; } + + /** + * Returns current InputData. + * @return current input data. + */ + public SuggestLocationsInputData getInputData() { + final List keywords = getKeywords(); + final String joinedKeywords = String.join(";", keywords); + return new SuggestLocationsInputData(address, joinedKeywords); + } + + private List getKeywords() { + final List keywords = new ArrayList<>(); + + if (!keyword1.isEmpty()) { + keywords.add(keyword1); + } + if (!keyword2.isEmpty()) { + keywords.add(keyword2); + } + if (!keyword3.isEmpty()) { + keywords.add(keyword3); + } + if (!keyword4.isEmpty()) { + keywords.add(keyword4); + } + if (!keyword5.isEmpty()) { + keywords.add(keyword5); + } + return keywords; + } } + diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 14f13fcb3..c45d59403 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -10,11 +10,11 @@ import javax.swing.*; +import entity.Place; import interface_adapter.location.LocationController; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.SuggestLocationsInputData; /** * The View for when the user is viewing a location in the program. @@ -60,12 +60,9 @@ public LocationView(LocationViewModel locationViewModel) { suggestButton.addActionListener(evt -> { if (evt.getSource().equals(suggestButton)) { - final String address = addressField.getText().trim(); - final List keywords = getKeywords(); - final String joinedKeywords = String.join(";", keywords); - final SuggestLocationsInputData inputText = new SuggestLocationsInputData(address, joinedKeywords); + final LocationState currentState = locationViewModel.getState(); try { - locationController.execute(inputText); + locationController.execute(currentState.getInputData()); } catch (DataAccessException dataAccessException) { JOptionPane.showMessageDialog(this, "Error accessing data: " + dataAccessException.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); @@ -87,32 +84,6 @@ public String getAddress() { return addressField.getText(); } - public List getKeywords() { - final List keywords = new ArrayList<>(); - - final String keyword1 = keyword1Field.getText().trim(); - if (!keyword1.isEmpty()) { - keywords.add(keyword1); - } - final String keyword2 = keyword2Field.getText().trim(); - if (!keyword2.isEmpty()) { - keywords.add(keyword2); - } - final String keyword3 = keyword3Field.getText().trim(); - if (!keyword3.isEmpty()) { - keywords.add(keyword3); - } - final String keyword4 = keyword4Field.getText().trim(); - if (!keyword4.isEmpty()) { - keywords.add(keyword4); - } - final String keyword5 = keyword5Field.getText().trim(); - if (!keyword5.isEmpty()) { - keywords.add(keyword5); - } - return keywords; - } - /** * React to a button click that results in evt. * @param evt the ActionEvent to react to @@ -129,24 +100,24 @@ public void propertyChange(PropertyChangeEvent evt) { JOptionPane.showMessageDialog(this, state.getError(), "Error", JOptionPane.ERROR_MESSAGE); } - if (state.getSuggestedLocations() != null) { - showSuggestedLocations(state.getSuggestedLocations()); - } +// if (state.getSuggestedLocations() != null) { +// showSuggestedLocations(state.getSuggestedLocations()); +// } } - private void showSuggestedLocations(List locations) { - if (suggestedLocations != null) { - this.remove(suggestedLocations); - } - - suggestedLocations = new JPanel(); - suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); - suggestedLocations.add(new JLabel("List of Suggested Locations:")); - for (String location : locations) { - suggestedLocations.add(new JLabel(location)); - } - this.add(suggestedLocations); - } +// private void showSuggestedLocations(List locations) { +// if (suggestedLocations != null) { +// this.remove(suggestedLocations); +// } +// +// suggestedLocations = new JPanel(); +// suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); +// suggestedLocations.add(new JLabel("List of Suggested Locations:")); +// for (Place location : locations) { +// suggestedLocations.add(new JLabel(location)); +// } +// this.add(suggestedLocations); +// } private void setFields(LocationState state) { addressField.setText(state.getAddress()); diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 7c1bad6f8..2a933a47b 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -1,36 +1,32 @@ package view; -import interface_adapter.location.LocationController; +import entity.Place; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.SuggestLocationsInputData; import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.List; +/** + * Suggested Locations View Panel + */ public class SuggestedLocationsView extends JPanel { - private JPanel suggestedLocations; + private JPanel suggestedLocationsPanel; - public SuggestedLocationsView(List locations) { - if (suggestedLocations != null) { - this.remove(suggestedLocations); + public SuggestedLocationsView(LocationViewModel locationViewModel) { + + if (suggestedLocationsPanel != null) { + this.remove(suggestedLocationsPanel); } + final LocationState locationState = locationViewModel.getState(); - suggestedLocations = new JPanel(); - suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); - suggestedLocations.add(new JLabel("List of Suggested Locations:")); - for (String location : locations) { - suggestedLocations.add(new JLabel(location)); + suggestedLocationsPanel.setLayout(new BoxLayout(suggestedLocationsPanel, BoxLayout.Y_AXIS)); + suggestedLocationsPanel.add(new JLabel("List of Suggested Locations:")); + for (Place location : locationState.getSuggestedLocations()) { + suggestedLocationsPanel.add(new JLabel(location.getName())); + suggestedLocationsPanel.add(new JLabel(location.getAddress())); } - this.add(suggestedLocations); + this.add(suggestedLocationsPanel); this.setVisible(true); } } From 5ee75e93ef35cbd2d98928ca552e02f3990f6085 Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Mon, 11 Nov 2024 22:06:25 -0500 Subject: [PATCH 047/113] Added View Manager and View Manager Model. --- .../location/LocationViewManagerModel.java | 11 ++++++++ src/main/java/view/ViewManager.java | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/interface_adapter/location/LocationViewManagerModel.java create mode 100644 src/main/java/view/ViewManager.java diff --git a/src/main/java/interface_adapter/location/LocationViewManagerModel.java b/src/main/java/interface_adapter/location/LocationViewManagerModel.java new file mode 100644 index 000000000..a913db31d --- /dev/null +++ b/src/main/java/interface_adapter/location/LocationViewManagerModel.java @@ -0,0 +1,11 @@ +package interface_adapter.location; + +import interface_adapter.ViewModel; + +public class LocationViewManagerModel extends ViewModel { + public LocationViewManagerModel() { + super("view manager"); + this.setState(""); + } + +} diff --git a/src/main/java/view/ViewManager.java b/src/main/java/view/ViewManager.java new file mode 100644 index 000000000..e3fdb2048 --- /dev/null +++ b/src/main/java/view/ViewManager.java @@ -0,0 +1,27 @@ +package view; + +import interface_adapter.location.LocationViewManagerModel; +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ViewManager implements PropertyChangeListener { + private final CardLayout cardLayout; + private final JPanel views; + private final LocationViewManagerModel viewManagerModel; + + public ViewManager(JPanel views, CardLayout cardLayout, LocationViewManagerModel viewManagerModel) { + this.cardLayout = cardLayout; + this.views = views; + this.viewManagerModel = viewManagerModel; + this.viewManagerModel.addPropertyChangeListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("state")) { + cardLayout.show(views, (String) evt.getNewValue()); + } + } +} From daf13ff6b4bf50e2a657476a0bb6ed1a12993a8a Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:18:31 -0500 Subject: [PATCH 048/113] reverted SuggestLocationsInteractor back. --- src/main/java/entity/Place.java | 25 ++-------- .../location/LocationController.java | 16 ------- .../SuggestLocationsInteractor.java | 46 +++++++++++-------- 3 files changed, 31 insertions(+), 56 deletions(-) diff --git a/src/main/java/entity/Place.java b/src/main/java/entity/Place.java index f7ba47898..e916838d0 100644 --- a/src/main/java/entity/Place.java +++ b/src/main/java/entity/Place.java @@ -3,37 +3,18 @@ /** * The representation of a place in our program. */ -public class Place { - private final String name; - private final String address; - - /** - * The representation of a place. - * - * @param name the name of the place - * @param address the address of the place - */ - public Place(String name, String address) { - this.name = name; - this.address = address; - } - +public interface Place { /** * Returns the address of the place. * * @return the address of the place. */ - public String getName() { - return name; - } + String getName(); /** * Returns the address of the place. * * @return the address of the place. */ - public String getAddress() { - return address; - - } + String getAddress(); } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 275aed883..c471191c1 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -18,22 +18,6 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { this.locationInteractor = locationInteractor; } - /** - * Handles the input of an address. - * @param address the input address - */ - public void handleAddressInput(String address) { - locationInteractor.setAddress(address); - } - - /** - * Handles the selection of an interest. - * @param interest the selected interest - */ - public void handleInterestSelection(String interest) { - locationInteractor.setInterest(interest); - } - /** * Executes the save or refresh operation based on the location. * @param location the location to save or refresh diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 1c4934914..9ebba874e 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -1,15 +1,25 @@ package use_case.suggest_locations; +import java.util.ArrayList; import java.util.List; -public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { - - private final LocationDataAccessInterface locationDataAccess; - private final SuggestLocationsOutputBoundary outputBoundary; +import entity.Place; +import entity.PlaceFactory; - public SuggestLocationsInteractor(LocationDataAccessInterface locationDataAccess, SuggestLocationsOutputBoundary outputBoundary) { - this.locationDataAccess = locationDataAccess; - this.outputBoundary = outputBoundary; +/** + * The Suggest Locations Interactor. + */ +public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { + private final LocationDataAccessInterface placeDataAccessObject; + private final SuggestLocationsOutputBoundary placePresenter; + private final PlaceFactory placeFactory; + + public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, + SuggestLocationsOutputBoundary suggestLocationsOutputBoundary, + PlaceFactory placeFactory) { + this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; + this.placePresenter = suggestLocationsOutputBoundary; + this.placeFactory = placeFactory; } @Override @@ -23,18 +33,18 @@ public void setInterest(String interest) { } @Override - public void execute(SuggestLocationsInputData inputData) { - try { - String response = locationDataAccess.searchLocation(inputData.getAddress(), inputData.getInterest()); - List locations = parseResponse(response); - SuggestLocationsOutputData outputData = new SuggestLocationsOutputData(locations); - outputBoundary.prepareSuccessView(outputData); - } catch (DataAccessException e) { - outputBoundary.prepareFailView(e.getMessage()); + public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { + final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), + suggestLocationsInputData.getLocationType()); + final String[] locationsList = suggestedLocations.split("<:>"); + + final List suggestedPlaces = new ArrayList<>(); + for (String location : locationsList) { + suggestedPlaces.add(placeFactory.create(location.split(">")[1], location.split(">")[0])); } - } - - private List parseResponse(String response) { + final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedPlaces, + false); + placePresenter.prepareSuccessView(suggestLocationsOutputData); } } \ No newline at end of file From 5e6c950dd1d71335967bbf19d630f4f7bc314a20 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Mon, 11 Nov 2024 23:23:48 -0500 Subject: [PATCH 049/113] fixed main location application, runs now --- src/main/java/app/LocationAppBuilder.java | 20 ++-- .../java/app/MainLocationApplication.java | 95 ++++++++++--------- .../app/SuggestedLocationsAppBuilder.java | 41 ++++---- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index 7ac76790f..6ffa5e8a4 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -2,15 +2,19 @@ import javax.swing.*; +import data_access.DBLocationDataAccessObject; import entity.PlaceFactory; +import entity.SuggestedPlaceFactory; import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; +import interface_adapter.location.LocationViewManagerModel; import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.LocationDataAccessInterface; import use_case.suggest_locations.SuggestLocationsInteractor; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.*; import view.LocationView; +import view.ViewManager; import java.awt.*; @@ -20,11 +24,11 @@ public class LocationAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; - private LocationDataAccessInterface locationDAO; - private LocationViewModel locationViewModel = new LocationViewModel(); - private LocationView locationView; - private SuggestLocationsInteractor locationInteractor; - private PlaceFactory placeFactory; + public LocationDataAccessInterface locationDAO; + public static LocationViewModel locationViewModel = new LocationViewModel(); + public LocationView locationView; + public SuggestLocationsInteractor locationInteractor; + public PlaceFactory placeFactory; /** * Sets the LocationDAO to be used in this application. @@ -82,11 +86,9 @@ public JFrame build() throws DataAccessException { frame.add(locationView, BorderLayout.CENTER); - final SuggestLocationsInputData inputData = locationView.getInputData(); - - locationInteractor.execute(inputData); - return frame; + } + } diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java index 9c9bb8835..5ff5ec33e 100644 --- a/src/main/java/app/MainLocationApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -1,56 +1,61 @@ package app; import data_access.DBLocationDataAccessObject; +import entity.PlaceFactory; +import entity.SuggestedPlaceFactory; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationPresenter; +import interface_adapter.location.LocationViewManagerModel; +import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInputBoundary; +import use_case.suggest_locations.SuggestLocationsInteractor; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import view.LocationView; +import view.ViewManager; + +import javax.swing.*; +import java.awt.*; + +import static app.LocationAppBuilder.locationViewModel; -/** - * An application where we can view and add to a note stored by a user. - *

- * This is a minimal example of using the password-protected user API from lab 5, - * but demonstrating the endpoint allowing you to store an arbitrary JSON object. - * This functionality could be used in any project where your team wants to persist - * data which is then accessible across devices.

- *

The code is intentionally somewhat incomplete to leave work to be done if your - * team were to choose to work on a project which would require similar functionality. - * For example, we have intentionally not created a full "Note" entity here, but - * rather just represented a note as a string. - *

- * The ViewManager code has also been removed, since this minimal program only requires a single - * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting - * switching between views depending on your project. - */ public class MainLocationApplication { - /** - * The main entry point of the application. - *

- * The program will show you the note currently saved in the system. - * You are able to edit it and then save it to the system. You can refresh - * to update the note to reflect what was saved most recently. This - * uses the API from lab, so there is one database storing the note, - * which means that if anyone updates the note, that is what you will - * see when you refresh. - *

- * You can generalize the code to allow you to - * specify which "user" to save the note for, which will allow your team - * to store information specific to your team which is password-protected. - * The username and password used in this application are currently for - * user jonathan_calver2, but you can change that. As you did in lab 3, - * you will likely want to store password information locally rather than - * in your repo. Or you can require the user to enter their credentials - * in your application; it just depends on what your program's main - * functionality. - *

- * @param args commandline arguments are ignored - */ public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + final JFrame application = new JFrame("Location Application"); + final CardLayout cardLayout = new CardLayout(); + final JPanel views = new JPanel(cardLayout); + final LocationViewModel locationViewModel = new LocationViewModel(); + final LocationView locationView = new LocationView(locationViewModel); + views.add(locationView, "Location"); + application.add(views); + final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); + + new ViewManager(locationView, cardLayout, viewManagerModel); + final LocationController locationController = createLocationUseCase(); + + createViewsAndAddToPanel(locationViewModel, views, locationController); - // create the data access and inject it into our builder! - final LocationDataAccessInterface locationDataAccess = new DBLocationDataAccessObject(); + cardLayout.show(views, "Location"); + + application.pack(); + application.setVisible(true); + }); + } + + private static void createViewsAndAddToPanel(LocationViewModel locationViewModel, + JPanel views, + LocationController locationController) { + final LocationView locationView = new LocationView(locationViewModel); + views.add(locationView, "Location"); + } - final LocationAppBuilder builder = new LocationAppBuilder(); - builder.addLocationDAO(locationDataAccess) - .addLocationView() - .addLocationUseCase().build().setVisible(true); + private static LocationController createLocationUseCase() { + final LocationDataAccessInterface location = new DBLocationDataAccessObject(); + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); + final PlaceFactory placeFactory = new SuggestedPlaceFactory(); + final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); + return new LocationController(locationInteractor); } -} +} \ No newline at end of file diff --git a/src/main/java/app/SuggestedLocationsAppBuilder.java b/src/main/java/app/SuggestedLocationsAppBuilder.java index 34e91b497..1122191bb 100644 --- a/src/main/java/app/SuggestedLocationsAppBuilder.java +++ b/src/main/java/app/SuggestedLocationsAppBuilder.java @@ -2,6 +2,7 @@ import javax.swing.*; +import entity.Place; import entity.PlaceFactory; import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; @@ -10,9 +11,10 @@ import use_case.suggest_locations.SuggestLocationsInteractor; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.*; -import view.LocationView; +import view.SuggestedLocationsView; import java.awt.*; +import java.util.List; /** * Builder for the Suggested Locations Application. @@ -22,7 +24,7 @@ public class SuggestedLocationsAppBuilder { public static final int WIDTH = 400; private LocationDataAccessInterface locationDAO; private LocationViewModel locationViewModel = new LocationViewModel(); - private LocationView locationView; + private SuggestedLocationsView suggestedLocationsView; private SuggestLocationsInteractor locationInteractor; private PlaceFactory placeFactory; @@ -31,39 +33,38 @@ public class SuggestedLocationsAppBuilder { * @param locationDataAccess the DAO to use * @return this builder */ - public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { + public SuggestedLocationsAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { locationDAO = locationDataAccess; return this; } /** * Creates the objects for the Location Use Case and connects the - * LocationView to its + * SuggestedLocationsView to its * controller. - *

This method must be called after addLocationView!

+ *

This method must be called after addSuggestedLocationsView!

* @return this builder - * @throws RuntimeException if this method is called before addLocationView + * @throws RuntimeException if this method is called before + * addSuggestedLocationsView */ - public LocationAppBuilder addLocationUseCase() { + public SuggestedLocationsAppBuilder addLocationUseCase() { final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); locationInteractor = new SuggestLocationsInteractor( locationDAO, suggestLocationsOutputBoundary, placeFactory); - final LocationController controller = new LocationController(locationInteractor); - if (locationView == null) { - throw new RuntimeException("addLocationView must be called before" + " addLocationUseCase"); + if (suggestedLocationsView == null) { + throw new RuntimeException("addSuggestedLocationsView must be " + "called before" + " addLocationUseCase"); } - locationView.setLocationController(controller); return this; } /** - * Creates the LocationView and underlying LocationViewModel. + * Creates the SuggestedLocationView and underlying LocationViewModel. * @return this builder */ - public LocationAppBuilder addLocationView() { + public SuggestedLocationsAppBuilder addSuggestedLocationsView(List locations) { locationViewModel = new LocationViewModel(); - locationView = new LocationView(locationViewModel); + suggestedLocationsView = new SuggestedLocationsView(locationViewModel); return this; } @@ -77,16 +78,8 @@ public JFrame build() throws DataAccessException { frame.setTitle("Suggested Locations Application"); frame.setSize(WIDTH, HEIGHT); - final JTextField userInputField = new JTextField(); - frame.add(userInputField, BorderLayout.NORTH); - - frame.add(locationView, BorderLayout.CENTER); - - final SuggestLocationsInputData inputData = locationView.getInputData(); - - locationInteractor.execute(inputData); + frame.add(suggestedLocationsView, BorderLayout.CENTER); return frame; - } -} +} \ No newline at end of file From 88486db173535b7da9f62637993faa40a53c9e5c Mon Sep 17 00:00:00 2001 From: teddyyang Date: Tue, 12 Nov 2024 16:44:16 -0500 Subject: [PATCH 050/113] doesnt work plz fix --- .../java/app/MainLocationApplication.java | 12 ++++++++++++ .../app/SuggestedLocationsAppBuilder.java | 19 +++++++++---------- .../java/view/SuggestedLocationsView.java | 8 +++++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java index 5ff5ec33e..5e9c06f41 100644 --- a/src/main/java/app/MainLocationApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -7,6 +7,9 @@ import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewManagerModel; import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestedLocation.SuggestedLocationController; +import interface_adapter.suggestedLocation.SuggestedLocationPresenter; +import interface_adapter.suggestedLocation.SuggestedLocationViewModel; import use_case.suggest_locations.LocationDataAccessInterface; import use_case.suggest_locations.SuggestLocationsInputBoundary; import use_case.suggest_locations.SuggestLocationsInteractor; @@ -28,6 +31,7 @@ public static void main(String[] args) { final JPanel views = new JPanel(cardLayout); final LocationViewModel locationViewModel = new LocationViewModel(); final LocationView locationView = new LocationView(locationViewModel); + final SuggestedLocationViewModel suggestedLocationViewModel = new SuggestedLocationViewModel(); views.add(locationView, "Location"); application.add(views); final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); @@ -58,4 +62,12 @@ private static LocationController createLocationUseCase() { final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); return new LocationController(locationInteractor); } + + private static SuggestedLocationController createSuggestedLocationUseCase() { + final LocationDataAccessInterface location = new DBLocationDataAccessObject(); + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationPresenter(suggestedLocationViewModel); + final PlaceFactory placeFactory = new SuggestedPlaceFactory(); + final SuggestLocationsOutputBoundary suggestLocationsInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); + return new SuggestedLocationController(suggestLocationsInteractor); + } } \ No newline at end of file diff --git a/src/main/java/app/SuggestedLocationsAppBuilder.java b/src/main/java/app/SuggestedLocationsAppBuilder.java index 1122191bb..5e587fba8 100644 --- a/src/main/java/app/SuggestedLocationsAppBuilder.java +++ b/src/main/java/app/SuggestedLocationsAppBuilder.java @@ -4,9 +4,8 @@ import entity.Place; import entity.PlaceFactory; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationPresenter; -import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestedLocation.SuggestedLocationPresenter; +import interface_adapter.suggestedLocation.SuggestedLocationViewModel; import use_case.suggest_locations.LocationDataAccessInterface; import use_case.suggest_locations.SuggestLocationsInteractor; import use_case.suggest_locations.SuggestLocationsOutputBoundary; @@ -23,9 +22,9 @@ public class SuggestedLocationsAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; private LocationDataAccessInterface locationDAO; - private LocationViewModel locationViewModel = new LocationViewModel(); + private SuggestedLocationViewModel suggestedLocationViewModel = new SuggestedLocationViewModel(); private SuggestedLocationsView suggestedLocationsView; - private SuggestLocationsInteractor locationInteractor; + private SuggestLocationsInteractor suggestLocationsInteractor; private PlaceFactory placeFactory; /** @@ -47,9 +46,9 @@ public SuggestedLocationsAppBuilder addLocationDAO(LocationDataAccessInterface l * @throws RuntimeException if this method is called before * addSuggestedLocationsView */ - public SuggestedLocationsAppBuilder addLocationUseCase() { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); - locationInteractor = new SuggestLocationsInteractor( + public SuggestedLocationsAppBuilder addSuggestedLocationUseCase() { + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationPresenter(suggestedLocationViewModel); + suggestLocationsInteractor = new SuggestLocationsInteractor( locationDAO, suggestLocationsOutputBoundary, placeFactory); if (suggestedLocationsView == null) { @@ -63,8 +62,8 @@ public SuggestedLocationsAppBuilder addLocationUseCase() { * @return this builder */ public SuggestedLocationsAppBuilder addSuggestedLocationsView(List locations) { - locationViewModel = new LocationViewModel(); - suggestedLocationsView = new SuggestedLocationsView(locationViewModel); + suggestedLocationViewModel = new SuggestedLocationViewModel(); + suggestedLocationsView = new SuggestedLocationsView(suggestedLocationViewModel); return this; } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 2a933a47b..9722d08fa 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -3,6 +3,8 @@ import entity.Place; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestedLocation.SuggestedLocationState; +import interface_adapter.suggestedLocation.SuggestedLocationViewModel; import javax.swing.*; @@ -13,16 +15,16 @@ public class SuggestedLocationsView extends JPanel { private JPanel suggestedLocationsPanel; - public SuggestedLocationsView(LocationViewModel locationViewModel) { + public SuggestedLocationsView(SuggestedLocationViewModel suggestedLocationViewModel) { if (suggestedLocationsPanel != null) { this.remove(suggestedLocationsPanel); } - final LocationState locationState = locationViewModel.getState(); + final SuggestedLocationState suggestedLocationState = suggestedLocationViewModel.getState(); suggestedLocationsPanel.setLayout(new BoxLayout(suggestedLocationsPanel, BoxLayout.Y_AXIS)); suggestedLocationsPanel.add(new JLabel("List of Suggested Locations:")); - for (Place location : locationState.getSuggestedLocations()) { + for (Place location : suggestedLocationState.getSuggestedLocations()) { suggestedLocationsPanel.add(new JLabel(location.getName())); suggestedLocationsPanel.add(new JLabel(location.getAddress())); } From dabe77130e1628fe7388a61bbc703a450adce7f1 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:26:44 -0500 Subject: [PATCH 051/113] common starting point --- src/main/java/app/LocationAppBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index b110f8fb2..38d03bdd4 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -81,6 +81,5 @@ public JFrame build() { locationInteractor.execute(); return frame; - } } From fd155f89a2aeff4eabfdadd8367ec3f026df6ac7 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Tue, 12 Nov 2024 22:54:31 -0500 Subject: [PATCH 052/113] remade interface adaptors and modified usecases to use SuggestedPlace instead of Place --- .../java/app/MainLocationApplication.java | 1 - .../location/LocationController.java | 18 ++-- .../location/LocationPresenter.java | 33 +++---- .../location/LocationSearchFailed.java | 7 ++ .../location/LocationState.java | 97 ++----------------- .../location/LocationViewManagerModel.java | 11 --- .../location/LocationViewModel.java | 17 ---- .../SuggestLocationsInputBoundary.java | 5 - .../SuggestLocationsOutputData.java | 11 +-- 9 files changed, 43 insertions(+), 157 deletions(-) create mode 100644 src/main/java/interface_adapter/location/LocationSearchFailed.java delete mode 100644 src/main/java/interface_adapter/location/LocationViewManagerModel.java diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java index 5e9c06f41..370639e41 100644 --- a/src/main/java/app/MainLocationApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -34,7 +34,6 @@ public static void main(String[] args) { final SuggestedLocationViewModel suggestedLocationViewModel = new SuggestedLocationViewModel(); views.add(locationView, "Location"); application.add(views); - final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); new ViewManager(locationView, cardLayout, viewManagerModel); final LocationController locationController = createLocationUseCase(); diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index c471191c1..1c8c041e5 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -12,21 +12,25 @@ */ public class LocationController { - private final SuggestLocationsInputBoundary locationInteractor; + private final SuggestLocationsInputBoundary locationInput; public LocationController(SuggestLocationsInputBoundary locationInteractor) { - this.locationInteractor = locationInteractor; + this.locationInput = locationInteractor; } /** * Executes the save or refresh operation based on the location. - * @param location the location to save or refresh + * @param address the location to save or refresh + * @param locationType the type of location to save or refresh * @throws DataAccessException if the location is null */ - public void execute(SuggestLocationsInputData location) throws DataAccessException { - if (location == null) { - throw new DataAccessException("Location is null"); + public void execute(String address, String locationType) throws DataAccessException { + if (address == null) { + throw new DataAccessException("Address is null"); } - locationInteractor.execute(location); + final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( + address, locationType); + + locationInput.execute(suggestLocationInputData); } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index f63e591cc..bd85bbe35 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -2,38 +2,31 @@ import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; +import view.LocationView; /** * The presenter for our Note viewing and editing program. */ public class LocationPresenter implements SuggestLocationsOutputBoundary { - private final LocationViewModel locationViewModel; + private LocationView view; + private LocationViewModel viewModel; - public LocationPresenter(LocationViewModel locationViewModel) { - this.locationViewModel = locationViewModel; + public LocationPresenter(LocationViewModel viewModel) { + this.viewModel = viewModel; + } + + public void setView(LocationView view) { + this.view = view; } - /** - * Prepares the success view for the Note related Use Cases. - * - * @param outputData the output data - */ @Override - public void prepareSuccessView(SuggestLocationsOutputData outputData) { - locationViewModel.getState().setSuggestedLocations(outputData.getLocations()); - locationViewModel.getState().setError(null); - locationViewModel.firePropertyChanged(); + public void prepareSuccessView(SuggestLocationsOutputData response) { + } - /** - * Prepares the failure view for the Note related Use Cases. - * - * @param errorMessage the explanation of the failure - */ @Override - public void prepareFailView(String errorMessage) { - locationViewModel.getState().setError(errorMessage); - locationViewModel.firePropertyChanged(); + public void prepareFailView(String error) { + throw new LocationSearchFailed(error); } } diff --git a/src/main/java/interface_adapter/location/LocationSearchFailed.java b/src/main/java/interface_adapter/location/LocationSearchFailed.java new file mode 100644 index 000000000..e5abeaa8c --- /dev/null +++ b/src/main/java/interface_adapter/location/LocationSearchFailed.java @@ -0,0 +1,7 @@ +package interface_adapter.location; + +public class LocationSearchFailed extends RuntimeException { + public LocationSearchFailed(String error) { + super(error); + } +} diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index 8268933ee..dfee73239 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -11,18 +11,9 @@ * suggested locations, and any error messages. */ public class LocationState { + private String address = ""; + private String locationType = ""; private String error; - private String address; - private String keyword1; - private String keyword2; - private String keyword3; - private String keyword4; - private String keyword5; - private List suggestedLocations; - - public LocationState() { - this.suggestedLocations = new ArrayList<>(); - } public String getAddress() { return address; @@ -32,92 +23,20 @@ public void setAddress(String address) { this.address = address; } - public String getKeyword1() { - return keyword1; - } - - public void setKeyword1(String keyword1) { - this.keyword1 = keyword1; - } - - public String getKeyword2() { - return keyword2; - } - - public void setKeyword2(String keyword2) { - this.keyword2 = keyword2; - } - - public String getKeyword3() { - return keyword3; - } - - public void setKeyword3(String keyword3) { - this.keyword3 = keyword3; - } - - public String getKeyword4() { - return keyword4; + public String getLocationType() { + return locationType; } - public void setKeyword4(String keyword4) { - this.keyword4 = keyword4; - } - - public String getKeyword5() { - return keyword5; - } - - public void setKeyword5(String keyword5) { - this.keyword5 = keyword5; - } - - public void setError(String errorMessage) { - - this.error = errorMessage; + public void setLocationType(String locationType) { + this.locationType = locationType; } public String getError() { return error; } - public List getSuggestedLocations() { - return suggestedLocations; - } - - public void setSuggestedLocations(List suggestedLocations) { - this.suggestedLocations = suggestedLocations; - } - - /** - * Returns current InputData. - * @return current input data. - */ - public SuggestLocationsInputData getInputData() { - final List keywords = getKeywords(); - final String joinedKeywords = String.join(";", keywords); - return new SuggestLocationsInputData(address, joinedKeywords); - } - - private List getKeywords() { - final List keywords = new ArrayList<>(); - - if (!keyword1.isEmpty()) { - keywords.add(keyword1); - } - if (!keyword2.isEmpty()) { - keywords.add(keyword2); - } - if (!keyword3.isEmpty()) { - keywords.add(keyword3); - } - if (!keyword4.isEmpty()) { - keywords.add(keyword4); - } - if (!keyword5.isEmpty()) { - keywords.add(keyword5); - } - return keywords; + public void setError(String error) { + this.error = error; } } diff --git a/src/main/java/interface_adapter/location/LocationViewManagerModel.java b/src/main/java/interface_adapter/location/LocationViewManagerModel.java deleted file mode 100644 index a913db31d..000000000 --- a/src/main/java/interface_adapter/location/LocationViewManagerModel.java +++ /dev/null @@ -1,11 +0,0 @@ -package interface_adapter.location; - -import interface_adapter.ViewModel; - -public class LocationViewManagerModel extends ViewModel { - public LocationViewManagerModel() { - super("view manager"); - this.setState(""); - } - -} diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index e4754cb26..ef089e6fb 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -1,8 +1,5 @@ package interface_adapter.location; -import java.util.List; - -import entity.Place; import interface_adapter.ViewModel; /** @@ -13,18 +10,4 @@ public LocationViewModel() { super("location"); setState(new LocationState()); } - - public LocationState getState() { - return super.getState(); - } - - /** - * Updates the suggested locations. - * @param suggestedLocations the list of suggested locations - */ - public void updateSuggestedLocations(List suggestedLocations) { - getState().setSuggestedLocations(suggestedLocations); - firePropertyChanged("suggestLocations"); - } - } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java index fda953ee8..19c41adf8 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java @@ -4,11 +4,6 @@ * The Suggest Locations Use Case. */ public interface SuggestLocationsInputBoundary { - - void setAddress(String address); - - void setInterest(String interest); - /** * Execute the Suggest Locations Use Case. * @param suggestLocationsInputData the input data for this use case diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java index a30c1cc9b..29d2fd742 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java @@ -3,25 +3,22 @@ import java.util.List; import entity.Place; +import entity.SuggestedPlace; /** * Output Data for the Suggest Locations Use Case. */ public class SuggestLocationsOutputData { - private final List locations; + private final List locations; private final boolean useCaseFailed; - public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { + public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { this.locations = locations; this.useCaseFailed = useCaseFailed; } - public List getLocations() { + public List getLocations() { return locations; } - - public boolean isUseCaseFailed() { - return useCaseFailed; - } } From e40a422abcf8b937da93d6f832dc34db1c53b782 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Tue, 12 Nov 2024 23:10:20 -0500 Subject: [PATCH 053/113] changed interactor and outputdata --- .../SuggestLocationsInteractor.java | 15 ++++----------- .../SuggestLocationsOutputData.java | 6 +++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 9ebba874e..5cf0fa569 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -5,6 +5,8 @@ import entity.Place; import entity.PlaceFactory; +import entity.SuggestedPlace; +import entity.SuggestedPlaceFactory; /** * The Suggest Locations Interactor. @@ -22,16 +24,6 @@ public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPl this.placeFactory = placeFactory; } - @Override - public void setAddress(String address) { - - } - - @Override - public void setInterest(String interest) { - - } - @Override public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), @@ -40,7 +32,8 @@ public void execute(SuggestLocationsInputData suggestLocationsInputData) throws final List suggestedPlaces = new ArrayList<>(); for (String location : locationsList) { - suggestedPlaces.add(placeFactory.create(location.split(">")[1], location.split(">")[0])); + final Place place = placeFactory.create(location.split(">")[1], location.split(">")[0]); + suggestedPlaces.add(place); } final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedPlaces, diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java index 29d2fd742..7ec79cf5b 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java @@ -10,15 +10,15 @@ */ public class SuggestLocationsOutputData { - private final List locations; + private final List locations; private final boolean useCaseFailed; - public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { + public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { this.locations = locations; this.useCaseFailed = useCaseFailed; } - public List getLocations() { + public List getLocations() { return locations; } } From eeb7399d1cde9ba082b90c92032aec37b7ba1488 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:53:26 -0500 Subject: [PATCH 054/113] fixed app - changed the build function and all of MainLocationApplication --- src/main/java/app/HomeScreenApplication.java | 25 ----- src/main/java/app/LocationAppBuilder.java | 63 +++++++---- .../java/app/MainLocationApplication.java | 102 +++++++++--------- .../location/LocationController.java | 4 +- 4 files changed, 97 insertions(+), 97 deletions(-) delete mode 100644 src/main/java/app/HomeScreenApplication.java diff --git a/src/main/java/app/HomeScreenApplication.java b/src/main/java/app/HomeScreenApplication.java deleted file mode 100644 index 57099c79f..000000000 --- a/src/main/java/app/HomeScreenApplication.java +++ /dev/null @@ -1,25 +0,0 @@ -package app; - -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -public class HomeScreenApplication { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; -// private LocationViewModel locationViewModel = new LocationViewModel(); - - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Home Screen Application"); - frame.setSize(WIDTH, HEIGHT); - -// frame.add(noteView); - -// noteInteractor.executeRefresh(); - - return frame; - - } - -} diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java index bfd98be66..08c5ebe4d 100644 --- a/src/main/java/app/LocationAppBuilder.java +++ b/src/main/java/app/LocationAppBuilder.java @@ -18,22 +18,22 @@ import java.awt.*; + /** * Builder for the Location Application. */ public class LocationAppBuilder { public static final int HEIGHT = 300; public static final int WIDTH = 400; - public LocationDataAccessInterface locationDAO; - public static LocationViewModel locationViewModel = new LocationViewModel(); - public LocationView locationView; - public SuggestLocationsInteractor locationInteractor; - public PlaceFactory placeFactory; + private static LocationViewModel locationViewModel; + private static LocationDataAccessInterface locationDAO; + private static final PlaceFactory placeFactory = new SuggestedPlaceFactory(); + private static LocationView locationView; + private static SuggestLocationsInteractor suggestLocationsInteractor; /** - * Sets the LocationDAO to be used in this application. - * @param locationDataAccess the DAO to use - * @return this builder + * Adds the LocationDAO. + * @param locationDataAccess the Location Data Access Interface. */ public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { locationDAO = locationDataAccess; @@ -41,23 +41,22 @@ public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDat } /** - * Creates the objects for the Location Use Case and connects the - * LocationView to its + * Creates the objects for the Location Use Case and connects the LocationView to its * controller. *

This method must be called after addLocationView!

* @return this builder - * @throws RuntimeException if this method is called before addLocationView + * @throws RuntimeException if this method is called before addNoteView */ public LocationAppBuilder addLocationUseCase() { final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); - locationInteractor = new SuggestLocationsInteractor( - locationDAO, suggestLocationsOutputBoundary, placeFactory); + final SuggestLocationsInteractor locationInteractor = new SuggestLocationsInteractor(locationDAO, + suggestLocationsOutputBoundary, placeFactory); - final LocationController controller = new LocationController(locationInteractor); + final LocationController locationController = new LocationController(locationInteractor); if (locationView == null) { - throw new RuntimeException("addLocationView must be called before" + " addLocationUseCase"); + throw new RuntimeException("addNoteView must be called before addNoteUseCase"); } - locationView.setLocationController(controller); + locationView.setLocationController(locationController); return this; } @@ -75,18 +74,40 @@ public LocationAppBuilder addLocationView() { * Builds the application. * @return the JFrame for the application */ - public JFrame build() throws DataAccessException { + public JFrame build() { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Location Application"); + frame.setTitle("Suggest Locations Application"); frame.setSize(WIDTH, HEIGHT); - final JTextField userInputField = new JTextField(); - frame.add(userInputField, BorderLayout.NORTH); - frame.add(locationView, BorderLayout.CENTER); + // refresh so that the note will be visible when we start the program + // suggestLocationsInteractor.executeRefresh(); + return frame; } } + +// OLD BUILD - DON'T DELETE CUZ IDK IF WE NEED THOSE TEXT FIELDS AND STUFF. +// i don't think we need the input text fields since the view/viewmodel should take care of it but ill leave +// it here in case. +// /** +// * Builds the application. +// * @return the JFrame for the application +// */ +// public JFrame build() throws DataAccessException { +// final JFrame frame = new JFrame(); +// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); +// frame.setTitle("Location Application"); +// frame.setSize(WIDTH, HEIGHT); +// +// final JTextField userInputField = new JTextField(); +// frame.add(userInputField, BorderLayout.NORTH); +// +// frame.add(locationView, BorderLayout.CENTER); +// +// return frame; +// } +// } diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java index 5ff5ec33e..5b485bc24 100644 --- a/src/main/java/app/MainLocationApplication.java +++ b/src/main/java/app/MainLocationApplication.java @@ -1,61 +1,65 @@ package app; import data_access.DBLocationDataAccessObject; -import entity.PlaceFactory; -import entity.SuggestedPlaceFactory; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationPresenter; -import interface_adapter.location.LocationViewManagerModel; -import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInputBoundary; -import use_case.suggest_locations.SuggestLocationsInteractor; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import view.LocationView; -import view.ViewManager; - -import javax.swing.*; -import java.awt.*; - -import static app.LocationAppBuilder.locationViewModel; +/** + * An application that suggests locations for users based on their address and interests. + */ public class MainLocationApplication { + /** + * Main entry point. + * @param args commandline arguments are ignored. + */ public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - final JFrame application = new JFrame("Location Application"); - final CardLayout cardLayout = new CardLayout(); - final JPanel views = new JPanel(cardLayout); - final LocationViewModel locationViewModel = new LocationViewModel(); - final LocationView locationView = new LocationView(locationViewModel); - views.add(locationView, "Location"); - application.add(views); - final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); - - new ViewManager(locationView, cardLayout, viewManagerModel); - final LocationController locationController = createLocationUseCase(); - - createViewsAndAddToPanel(locationViewModel, views, locationController); - cardLayout.show(views, "Location"); + // create the data access and inject it into our builder! + final LocationDataAccessInterface locationDataAccess = new DBLocationDataAccessObject(); - application.pack(); - application.setVisible(true); - }); + final LocationAppBuilder builder = new LocationAppBuilder(); + builder.addLocationDAO(locationDataAccess) + .addLocationView() + .addLocationUseCase().build().setVisible(true); } +} - private static void createViewsAndAddToPanel(LocationViewModel locationViewModel, - JPanel views, - LocationController locationController) { - final LocationView locationView = new LocationView(locationViewModel); - views.add(locationView, "Location"); - } - - private static LocationController createLocationUseCase() { - final LocationDataAccessInterface location = new DBLocationDataAccessObject(); - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); - final PlaceFactory placeFactory = new SuggestedPlaceFactory(); - final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); - return new LocationController(locationInteractor); - } -} \ No newline at end of file +// public static void main(String[] args) { +// SwingUtilities.invokeLater(() -> { +// final JFrame application = new JFrame("Location Application"); +// final CardLayout cardLayout = new CardLayout(); +// final JPanel views = new JPanel(cardLayout); +// final LocationViewModel locationViewModel = new LocationViewModel(); +// final LocationView locationView = new LocationView(locationViewModel); +// views.add(locationView, "Location"); +// application.add(views); +// final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); +// +// new ViewManager(locationView, cardLayout, viewManagerModel); +// final LocationController locationController = createLocationUseCase(); +// +// createViewsAndAddToPanel(locationViewModel, views, locationController); +// +// cardLayout.show(views, "Location"); +// +// application.pack(); +// application.setVisible(true); +// }); +// } +// +// private static void createViewsAndAddToPanel(LocationViewModel locationViewModel, +// JPanel views, +// LocationController locationController) { +// final LocationView locationView = new LocationView(locationViewModel); +// views.add(locationView, "Location"); +// } +// +// private static LocationController createLocationUseCase() { +// final LocationDataAccessInterface location = new DBLocationDataAccessObject(); +// final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); +// final PlaceFactory placeFactory = new SuggestedPlaceFactory(); +// final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); +// return new LocationController(locationInteractor); +// } +// +// } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index c471191c1..29961c72e 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -19,8 +19,8 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { } /** - * Executes the save or refresh operation based on the location. - * @param location the location to save or refresh + * Executes the show location. + * @param location the location to show * @throws DataAccessException if the location is null */ public void execute(SuggestLocationsInputData location) throws DataAccessException { From 2edec3988b3494889884ae9d9fff61bd3638b754 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Mon, 18 Nov 2024 12:20:53 -0500 Subject: [PATCH 055/113] added locationView --- .../DBLocationDataAccessObject.java | 2 +- .../location/LocationController.java | 7 +- src/main/java/view/LabelTextPanel.java | 15 ++ src/main/java/view/LocationView.java | 182 ++++++++++-------- 4 files changed, 114 insertions(+), 92 deletions(-) create mode 100644 src/main/java/view/LabelTextPanel.java diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index c07bfc1e8..a51d6fc07 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -68,7 +68,7 @@ else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); } } - catch (IOException | JSONException ex) { + catch (IOException | JSONException | DataAccessException ex) { throw new DataAccessException(ex.getMessage()); } } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 1c8c041e5..9a8ccbeb4 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,6 +1,5 @@ package interface_adapter.location; -import use_case.suggest_locations.DataAccessException; import use_case.suggest_locations.SuggestLocationsInputBoundary; import use_case.suggest_locations.SuggestLocationsInputData; @@ -22,12 +21,8 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { * Executes the save or refresh operation based on the location. * @param address the location to save or refresh * @param locationType the type of location to save or refresh - * @throws DataAccessException if the location is null */ - public void execute(String address, String locationType) throws DataAccessException { - if (address == null) { - throw new DataAccessException("Address is null"); - } + public void execute(String address, String locationType){ final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( address, locationType); diff --git a/src/main/java/view/LabelTextPanel.java b/src/main/java/view/LabelTextPanel.java new file mode 100644 index 000000000..e7138555f --- /dev/null +++ b/src/main/java/view/LabelTextPanel.java @@ -0,0 +1,15 @@ +package view; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +/** + * A panel containing a label and a text field. + */ +class LabelTextPanel extends JPanel { + LabelTextPanel(JLabel label, JTextField textField) { + this.add(label); + this.add(textField); + } +} diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index c45d59403..4f8287eac 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -5,89 +5,126 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.List; import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; -import entity.Place; import interface_adapter.location.LocationController; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.DataAccessException; /** * The View for when the user is viewing a location in the program. */ public class LocationView extends JPanel implements ActionListener, PropertyChangeListener { - private static final int TEXT_FIELD_WIDTH = 30; - private static final int KEYWORD_FIELD_WIDTH = 10; private final LocationViewModel locationViewModel; - private final JLabel locationName = new JLabel("Home Screen"); - private final JTextField addressField; - private final JTextField keyword1Field; - private final JTextField keyword2Field; - private final JTextField keyword3Field; - private final JTextField keyword4Field; - private final JTextField keyword5Field; - private JPanel suggestedLocations; - private final JButton suggestButton = new JButton("Suggest Locations"); - private LocationController locationController; - - public LocationView(LocationViewModel locationViewModel) { - addressField = new JTextField(TEXT_FIELD_WIDTH); - keyword1Field = new JTextField(KEYWORD_FIELD_WIDTH); - keyword2Field = new JTextField(KEYWORD_FIELD_WIDTH); - keyword3Field = new JTextField(KEYWORD_FIELD_WIDTH); - keyword4Field = new JTextField(KEYWORD_FIELD_WIDTH); - keyword5Field = new JTextField(KEYWORD_FIELD_WIDTH); - locationName.setAlignmentX(Component.CENTER_ALIGNMENT); + private final LocationController locationController; + + private final JLabel addressLabel = new JLabel("Address"); + + private final JTextField addressField = new JTextField(20); + + private final JLabel locationTypeLabel = new JLabel("Location Type"); + + private final JTextField locationTypeField = new JTextField(20); + + private final JButton suggestLocationsButton; + + public LocationView(LocationViewModel locationViewModel, LocationController locationController) { this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); + this.locationController = locationController; + + final JLabel title = new JLabel("Suggest Locations"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel addressInfo = new LabelTextPanel( + new JLabel("Address"), addressField); + + final LabelTextPanel locationTypeInfo = new LabelTextPanel( + new JLabel("Location Type"), locationTypeField); + + final JPanel buttons = new JPanel(); + suggestLocationsButton = new JButton("Suggest Locations"); + buttons.add(suggestLocationsButton); + + suggestLocationsButton.addActionListener(this); - final JPanel panel = new JPanel(); - panel.add(new JLabel("Choose City:")); - panel.add(new JLabel("Enter Address:")); - panel.add(addressField); - panel.add(new JLabel("Choose Interests:")); - panel.add(keyword1Field); - panel.add(keyword2Field); - panel.add(keyword3Field); - panel.add(keyword4Field); - panel.add(keyword5Field); - panel.add(suggestButton); - - suggestButton.addActionListener(evt -> { - if (evt.getSource().equals(suggestButton)) { + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + addressField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getInputData()); - } - catch (DataAccessException dataAccessException) { - JOptionPane.showMessageDialog(this, "Error accessing data: " + dataAccessException.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); - } + currentState.setAddress(addressField.getText()); + locationViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); } }); - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(locationName); - this.add(panel); - this.setVisible(true); - } + locationTypeField.getDocument().addDocumentListener(new DocumentListener() { - public void setLocationController(LocationController controller) { - this.locationController = controller; - } + private void documentListenerHelper() { + final LocationState currentState = locationViewModel.getState(); + currentState.setLocationType(locationTypeField.getText()); + locationViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + + suggestLocationsButton.addActionListener( + // This creates an anonymous subclass of ActionListener and instantiates it. + evt -> { + if (evt.getSource().equals(suggestLocationsButton)) { + final LocationState currentState = locationViewModel.getState(); + + this.locationController.execute( + currentState.getAddress(), + currentState.getLocationType() + ); + } + } + ); + + this.add(title); + this.add(addressInfo); + this.add(addressLabel); + this.add(locationTypeInfo); + this.add(locationTypeLabel); + this.add(buttons); - public String getAddress() { - return addressField.getText(); } - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ public void actionPerformed(ActionEvent evt) { System.out.println("Click " + evt.getActionCommand()); } @@ -100,36 +137,11 @@ public void propertyChange(PropertyChangeEvent evt) { JOptionPane.showMessageDialog(this, state.getError(), "Error", JOptionPane.ERROR_MESSAGE); } -// if (state.getSuggestedLocations() != null) { -// showSuggestedLocations(state.getSuggestedLocations()); -// } } -// private void showSuggestedLocations(List locations) { -// if (suggestedLocations != null) { -// this.remove(suggestedLocations); -// } -// -// suggestedLocations = new JPanel(); -// suggestedLocations.setLayout(new BoxLayout(suggestedLocations, BoxLayout.Y_AXIS)); -// suggestedLocations.add(new JLabel("List of Suggested Locations:")); -// for (Place location : locations) { -// suggestedLocations.add(new JLabel(location)); -// } -// this.add(suggestedLocations); -// } - private void setFields(LocationState state) { addressField.setText(state.getAddress()); - keyword1Field.setText(state.getKeyword1()); - keyword2Field.setText(state.getKeyword2()); - keyword3Field.setText(state.getKeyword3()); - keyword4Field.setText(state.getKeyword4()); - keyword5Field.setText(state.getKeyword5()); - if (state.getError() != null) { - JOptionPane.showMessageDialog(this, state.getError(), - "Error", JOptionPane.ERROR_MESSAGE); - } + locationTypeField.setText(state.getLocationType()); } } From e5ea87e7f7119c9c335ed2e10c6c51031c6624af Mon Sep 17 00:00:00 2001 From: teddyyang Date: Mon, 18 Nov 2024 12:24:51 -0500 Subject: [PATCH 056/113] added viewmanager --- .../java/interface_adapter/ViewManagerModel.java | 14 ++++++++++++++ src/main/java/view/ViewManager.java | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/main/java/interface_adapter/ViewManagerModel.java diff --git a/src/main/java/interface_adapter/ViewManagerModel.java b/src/main/java/interface_adapter/ViewManagerModel.java new file mode 100644 index 000000000..99dc0ffe5 --- /dev/null +++ b/src/main/java/interface_adapter/ViewManagerModel.java @@ -0,0 +1,14 @@ +package interface_adapter; + +/** + * Model for the View Manager. Its state is the name of the View which + * is currently active. An initial state of "" is used. + */ +public class ViewManagerModel extends ViewModel { + + public ViewManagerModel() { + super("view manager"); + this.setState(""); + } + +} diff --git a/src/main/java/view/ViewManager.java b/src/main/java/view/ViewManager.java index e3fdb2048..d0f471d71 100644 --- a/src/main/java/view/ViewManager.java +++ b/src/main/java/view/ViewManager.java @@ -1,6 +1,6 @@ package view; -import interface_adapter.location.LocationViewManagerModel; +import interface_adapter.ViewManagerModel; import javax.swing.*; import java.awt.*; import java.beans.PropertyChangeEvent; @@ -9,9 +9,9 @@ public class ViewManager implements PropertyChangeListener { private final CardLayout cardLayout; private final JPanel views; - private final LocationViewManagerModel viewManagerModel; + private final ViewManagerModel viewManagerModel; - public ViewManager(JPanel views, CardLayout cardLayout, LocationViewManagerModel viewManagerModel) { + public ViewManager(JPanel views, CardLayout cardLayout, ViewManagerModel viewManagerModel) { this.cardLayout = cardLayout; this.views = views; this.viewManagerModel = viewManagerModel; From 22de57856024494a9b736932a28c8ff311301ba9 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 18 Nov 2024 20:45:06 -0500 Subject: [PATCH 057/113] Created suggestedlocations interface adapters --- .../SuggesedLocationsState.java | 29 +++++++ .../SuggestedLocaionsViewModel.java | 4 + .../SuggestedLocationsController.java | 4 + .../SuggestedLocationsPresenter.java | 4 + .../java/view/SuggestedLocationsView.java | 79 ++++++++++++++----- 5 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java create mode 100644 src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java create mode 100644 src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java create mode 100644 src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java diff --git a/src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java new file mode 100644 index 000000000..a9b951774 --- /dev/null +++ b/src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java @@ -0,0 +1,29 @@ +package interface_adapter.suggestlocation; + +import java.util.List; + +import entity.Place; + +/** + * The state representing suggested locations-related data. + */ +public class SuggestedLocationsSate { + private List suggestedLocations; + private String error; + + public List getSuggestedLocations() { + return suggestedLocations; + } + + public void setSuggestedLocations(List suggestedLocations) { + this.suggestedLocations = suggestedLocations; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } +} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java new file mode 100644 index 000000000..b929244db --- /dev/null +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.suggestlocation; + +public class SuggestedLocaionsViewModel { +} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java new file mode 100644 index 000000000..fed682a23 --- /dev/null +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -0,0 +1,4 @@ +package interface_adapter.suggestlocation; + +public class SuggestedLocationsController { +} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java new file mode 100644 index 000000000..a7ee083ab --- /dev/null +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.suggestlocation; + +public class SuggestedLocationsPresenter { +} diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 9722d08fa..96950afb0 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -1,34 +1,77 @@ package view; -import entity.Place; -import interface_adapter.location.LocationState; -import interface_adapter.location.LocationViewModel; -import interface_adapter.suggestedLocation.SuggestedLocationState; -import interface_adapter.suggestedLocation.SuggestedLocationViewModel; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; -import javax.swing.*; +import entity.Place; +import interface_adapter.suggest_locations.SuggestLocationsController; +import interface_adapter.suggest_locations.SuggestLocationsState; +import interface_adapter.suggest_locations.SuggestLocationsViewModel; /** - * Suggested Locations View Panel + * The View for when the user receives a list of suggested locations in the program. */ -public class SuggestedLocationsView extends JPanel { +public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { + + private final SuggestLocationsViewModel suggestLocationsViewModel; + private final SuggestLocationsController suggestLocationsController; + private final ViewManager viewManager; + + private final JPanel suggestedLocationsPanel; + private final JButton newSearchButton; + + public SuggestedLocationsView(SuggestLocationsViewModel suggestLocationsViewModel, + SuggestLocationsController suggestLocationsController, + ViewManager viewManager) { + this.suggestLocationsViewModel = suggestLocationsViewModel; + this.suggestLocationsViewModel.addPropertyChangeListener(this); + this.suggestLocationsController = suggestLocationsController; + this.viewManager = viewManager; + + final JLabel title = new JLabel("List of Suggested Locations:"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + this.suggestedLocationsPanel = new JPanel(); + this.suggestedLocationsPanel.setLayout(new BoxLayout(suggestedLocationsPanel, BoxLayout.Y_AXIS)); - private JPanel suggestedLocationsPanel; + this.newSearchButton = new JButton("New Search"); + newSearchButton.addActionListener(this); - public SuggestedLocationsView(SuggestedLocationViewModel suggestedLocationViewModel) { + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(title); + this.add(suggestedLocationsPanel); + this.add(newSearchButton); + + updateSuggestedLocations(suggestLocationsViewModel.getState()); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(newSearchButton)) { + viewManager.showLocationView(); + } + } - if (suggestedLocationsPanel != null) { - this.remove(suggestedLocationsPanel); + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("state".equals(evt.getPropertyName())) { + updateSuggestedLocations((SuggestLocationsState) evt.getNewValue()); } - final SuggestedLocationState suggestedLocationState = suggestedLocationViewModel.getState(); + } - suggestedLocationsPanel.setLayout(new BoxLayout(suggestedLocationsPanel, BoxLayout.Y_AXIS)); - suggestedLocationsPanel.add(new JLabel("List of Suggested Locations:")); - for (Place location : suggestedLocationState.getSuggestedLocations()) { + private void updateSuggestedLocations(SuggestLocationsState state) { + suggestedLocationsPanel.removeAll(); + for (Place location : state.getSuggestedLocations()) { suggestedLocationsPanel.add(new JLabel(location.getName())); suggestedLocationsPanel.add(new JLabel(location.getAddress())); } - this.add(suggestedLocationsPanel); - this.setVisible(true); } } From 8fa4221bf701876aa3860207a370fa302986740f Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 18 Nov 2024 21:27:59 -0500 Subject: [PATCH 058/113] Created suggestedlocations interface adapters --- .../SuggestedLocaionsViewModel.java | 4 ---- .../SuggestedLocationsController.java | 24 +++++++++++++++++++ .../SuggestedLocationsPresenter.java | 22 ++++++++++++++++- ...tate.java => SuggestedLocationsState.java} | 5 ++-- .../SuggestedLocationsViewModel.java | 20 ++++++++++++++++ 5 files changed, 68 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java rename src/main/java/interface_adapter/suggestlocation/{SuggesedLocationsState.java => SuggestedLocationsState.java} (79%) create mode 100644 src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java deleted file mode 100644 index b929244db..000000000 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocaionsViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.suggestlocation; - -public class SuggestedLocaionsViewModel { -} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index fed682a23..eb02dc87f 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,4 +1,28 @@ package interface_adapter.suggestlocation; +import use_case.suggest_locations.SuggestLocationsInputBoundary; +import use_case.suggest_locations.SuggestLocationsInputData; + +/** + * The SuggestedLocationsController class handles user input related to suggested locations. + */ public class SuggestedLocationsController { + + private final SuggestLocationsInputBoundary suggestLocationsInput; + + public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocationsInput) { + this.suggestLocationsInput = suggestLocationsInput; + } + + /** + * Executes the suggest locations operation. + * @param address the address to suggest locations for + * @param locationType the type of location to suggest + */ + public void execute(String address, String locationType) { + final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( + address, locationType); + + suggestLocationsInput.execute(suggestLocationInputData); + } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index a7ee083ab..e5cb74d9f 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,4 +1,24 @@ package interface_adapter.suggestlocation; -public class SuggestedLocationsPresenter { +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggest_locations.SuggestLocationsOutputData; +import view.SuggestedLocationsView; + +/** + * The presenter for the suggested locations use case. + */ +public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary { + + private SuggestedLocationsView view; + private SuggestedLocationsViewModel viewModel; + + public SuggestedLocationsPresenter(SuggestedLocationsViewModel viewModel) { + this.viewModel = viewModel; + } + + public void setView(SuggestedLocationsView view) { + this.view = view; + } + + } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java similarity index 79% rename from src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java rename to src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java index a9b951774..3e962d719 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggesedLocationsState.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java @@ -5,9 +5,10 @@ import entity.Place; /** - * The state representing suggested locations-related data. + * The state representing suggested location-related data, including a list of suggested locations. */ -public class SuggestedLocationsSate { + +public class SuggestedLocationsState { private List suggestedLocations; private String error; diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java new file mode 100644 index 000000000..91057b0fb --- /dev/null +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java @@ -0,0 +1,20 @@ +package interface_adapter.suggestlocation; + +/** + * The ViewModel for the SuggestedLocationsView. + */ +public class SuggestedLocationsViewModel { + private SuggestedLocationsState state; + + public SuggestedLocationsViewModel() { + this.state = new SuggestedLocationsState(); + } + + public SuggestedLocationsState getState() { + return state; + } + + public void setState(SuggestedLocationsState state) { + this.state = state; + } +} From 0ff411b197bdf99c830b1f15b282818db518b7da Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 18 Nov 2024 21:31:14 -0500 Subject: [PATCH 059/113] Created suggestedlocations interface adapters --- .../suggestlocation/SuggestedLocationsPresenter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index e5cb74d9f..227c25c19 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -20,5 +20,4 @@ public void setView(SuggestedLocationsView view) { this.view = view; } - } } From 236db7b2c0f9fc1b3d390012ff996258a6e91601 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Mon, 18 Nov 2024 22:20:58 -0500 Subject: [PATCH 060/113] Fixed SuggestedLocationsView --- .../java/view/SuggestedLocationsView.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 96950afb0..93f477683 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -12,29 +12,26 @@ import javax.swing.JPanel; import entity.Place; -import interface_adapter.suggest_locations.SuggestLocationsController; -import interface_adapter.suggest_locations.SuggestLocationsState; -import interface_adapter.suggest_locations.SuggestLocationsViewModel; +import interface_adapter.suggestlocation.SuggestedLocationsController; +import interface_adapter.suggestlocation.SuggestedLocationsState; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; /** * The View for when the user receives a list of suggested locations in the program. */ public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { - private final SuggestLocationsViewModel suggestLocationsViewModel; - private final SuggestLocationsController suggestLocationsController; - private final ViewManager viewManager; + private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final SuggestedLocationsController suggestedLocationsController; private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; - public SuggestedLocationsView(SuggestLocationsViewModel suggestLocationsViewModel, - SuggestLocationsController suggestLocationsController, - ViewManager viewManager) { - this.suggestLocationsViewModel = suggestLocationsViewModel; - this.suggestLocationsViewModel.addPropertyChangeListener(this); - this.suggestLocationsController = suggestLocationsController; - this.viewManager = viewManager; + public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, + SuggestedLocationsController suggestedLocationsController) { + this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.suggestedLocationsViewModel.addPropertyChangeListener(this); + this.suggestedLocationsController = suggestedLocationsController; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -50,28 +47,31 @@ public SuggestedLocationsView(SuggestLocationsViewModel suggestLocationsViewMode this.add(suggestedLocationsPanel); this.add(newSearchButton); - updateSuggestedLocations(suggestLocationsViewModel.getState()); + updateSuggestedLocations(suggestedLocationsViewModel.getState()); } @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { - viewManager.showLocationView(); + // Handle new search action + System.out.println("New Search button clicked"); } } @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equals(evt.getPropertyName())) { - updateSuggestedLocations((SuggestLocationsState) evt.getNewValue()); + updateSuggestedLocations((SuggestedLocationsState) evt.getNewValue()); } } - private void updateSuggestedLocations(SuggestLocationsState state) { + private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); for (Place location : state.getSuggestedLocations()) { suggestedLocationsPanel.add(new JLabel(location.getName())); suggestedLocationsPanel.add(new JLabel(location.getAddress())); } + suggestedLocationsPanel.revalidate(); + suggestedLocationsPanel.repaint(); } } From ee0449bce91a48659ff282dfd68e11a5fe384f48 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Thu, 21 Nov 2024 00:53:27 -0500 Subject: [PATCH 061/113] Implemented the new search button in SuggestedLocationsView with CardLayout, fixed error in implementing SuggestedLocationsViewModel --- .../SuggestedLocationsViewModel.java | 17 +++++------------ src/main/java/view/SuggestedLocationsView.java | 11 ++++++++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java index 91057b0fb..979ecfe99 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java @@ -1,20 +1,13 @@ package interface_adapter.suggestlocation; +import interface_adapter.ViewModel; + /** * The ViewModel for the SuggestedLocationsView. */ -public class SuggestedLocationsViewModel { - private SuggestedLocationsState state; - +public class SuggestedLocationsViewModel extends ViewModel { public SuggestedLocationsViewModel() { - this.state = new SuggestedLocationsState(); - } - - public SuggestedLocationsState getState() { - return state; - } - - public void setState(SuggestedLocationsState state) { - this.state = state; + super("suggestedLocations"); + setState(new SuggestedLocationsState()); } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 93f477683..8e55954dd 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -1,5 +1,6 @@ package view; +import java.awt.CardLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -23,15 +24,20 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; + private final CardLayout cardLayout; + private final JPanel parentPanel; private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, - SuggestedLocationsController suggestedLocationsController) { + SuggestedLocationsController suggestedLocationsController, + CardLayout cardLayout, JPanel parentPanel) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; + this.cardLayout = cardLayout; + this.parentPanel = parentPanel; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -53,8 +59,7 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { - // Handle new search action - System.out.println("New Search button clicked"); + cardLayout.show(parentPanel, "locationView"); } } From 04aad4c8f74326046ff5fa6579e958d48528aa4e Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:13:11 -0500 Subject: [PATCH 062/113] fixed app and relating files --- src/main/java/app/LocationAppBuilder.java | 113 ------------------ src/main/java/app/LocationUseCaseFactory.java | 60 ++++++++++ .../java/app/MainLocationApplication.java | 112 ----------------- src/main/java/app/MainWithDB.java | 62 ++++++++++ .../app/SuggestedLocationsAppBuilder.java | 84 ------------- .../DBLocationDataAccessObject.java | 22 +++- .../location/LocationController.java | 5 +- .../SuggestedLocationsController.java | 3 +- .../SuggestedLocationsPresenter.java | 37 ++++-- .../LocationDataAccessInterface.java | 6 +- .../SuggestLocationsInteractor.java | 27 +---- src/main/java/view/LocationView.java | 19 ++- 12 files changed, 201 insertions(+), 349 deletions(-) delete mode 100644 src/main/java/app/LocationAppBuilder.java create mode 100644 src/main/java/app/LocationUseCaseFactory.java delete mode 100644 src/main/java/app/MainLocationApplication.java create mode 100644 src/main/java/app/MainWithDB.java delete mode 100644 src/main/java/app/SuggestedLocationsAppBuilder.java diff --git a/src/main/java/app/LocationAppBuilder.java b/src/main/java/app/LocationAppBuilder.java deleted file mode 100644 index 08c5ebe4d..000000000 --- a/src/main/java/app/LocationAppBuilder.java +++ /dev/null @@ -1,113 +0,0 @@ -package app; - -import javax.swing.*; - -import data_access.DBLocationDataAccessObject; -import entity.PlaceFactory; -import entity.SuggestedPlaceFactory; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationPresenter; -import interface_adapter.location.LocationViewManagerModel; -import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInteractor; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import use_case.suggest_locations.*; -import view.LocationView; -import view.ViewManager; - -import java.awt.*; - - -/** - * Builder for the Location Application. - */ -public class LocationAppBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - private static LocationViewModel locationViewModel; - private static LocationDataAccessInterface locationDAO; - private static final PlaceFactory placeFactory = new SuggestedPlaceFactory(); - private static LocationView locationView; - private static SuggestLocationsInteractor suggestLocationsInteractor; - - /** - * Adds the LocationDAO. - * @param locationDataAccess the Location Data Access Interface. - */ - public LocationAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { - locationDAO = locationDataAccess; - return this; - } - - /** - * Creates the objects for the Location Use Case and connects the LocationView to its - * controller. - *

This method must be called after addLocationView!

- * @return this builder - * @throws RuntimeException if this method is called before addNoteView - */ - public LocationAppBuilder addLocationUseCase() { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); - final SuggestLocationsInteractor locationInteractor = new SuggestLocationsInteractor(locationDAO, - suggestLocationsOutputBoundary, placeFactory); - - final LocationController locationController = new LocationController(locationInteractor); - if (locationView == null) { - throw new RuntimeException("addNoteView must be called before addNoteUseCase"); - } - locationView.setLocationController(locationController); - return this; - } - - /** - * Creates the LocationView and underlying LocationViewModel. - * @return this builder - */ - public LocationAppBuilder addLocationView() { - locationViewModel = new LocationViewModel(); - locationView = new LocationView(locationViewModel); - return this; - } - - /** - * Builds the application. - * @return the JFrame for the application - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Suggest Locations Application"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(locationView, BorderLayout.CENTER); - - // refresh so that the note will be visible when we start the program - // suggestLocationsInteractor.executeRefresh(); - - return frame; - } - -} - -// OLD BUILD - DON'T DELETE CUZ IDK IF WE NEED THOSE TEXT FIELDS AND STUFF. -// i don't think we need the input text fields since the view/viewmodel should take care of it but ill leave -// it here in case. -// /** -// * Builds the application. -// * @return the JFrame for the application -// */ -// public JFrame build() throws DataAccessException { -// final JFrame frame = new JFrame(); -// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); -// frame.setTitle("Location Application"); -// frame.setSize(WIDTH, HEIGHT); -// -// final JTextField userInputField = new JTextField(); -// frame.add(userInputField, BorderLayout.NORTH); -// -// frame.add(locationView, BorderLayout.CENTER); -// -// return frame; -// } -// } diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java new file mode 100644 index 000000000..4821144e4 --- /dev/null +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -0,0 +1,60 @@ +package app; + +import entity.PlaceFactory; +import entity.SuggestedPlaceFactory; +import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestlocation.SuggestedLocationsPresenter; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.suggest_locations.SuggestLocationsInputBoundary; +import use_case.suggest_locations.SuggestLocationsInteractor; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import view.LocationView; + +/** + * This class contains the static factory function for creating the LocationView. + */ +public class LocationUseCaseFactory { + + /** Prevent instantiation. */ + private LocationUseCaseFactory() { + + } + + /** + * Factory function for creating the LocationView. + * @param viewManagerModel the ViewManagerModel to inject + * @param locationViewModel the LocationViewModel to inject + * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @param locationDataAccessObject the LocationDataAccessInterface to inject + * @return the LocationView created for the provided input classes. + */ + public static LocationView create( + ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel, + SuggestedLocationsViewModel suggestedLocationsViewModel, + LocationDataAccessInterface locationDataAccessObject) { + + final LocationController locationController = createLocationUseCase(viewManagerModel, locationViewModel, + suggestedLocationsViewModel, locationDataAccessObject); + + return new LocationView(locationViewModel, locationController); + } + + private static LocationController createLocationUseCase( + ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel, + SuggestedLocationsViewModel suggestedLocationsViewModel, + LocationDataAccessInterface userDataAccessObject) { + + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, + suggestedLocationsViewModel, locationViewModel); + final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(userDataAccessObject, + suggestLocationsOutputBoundary); + + return new LocationController(locationInteractor); + } + +} diff --git a/src/main/java/app/MainLocationApplication.java b/src/main/java/app/MainLocationApplication.java deleted file mode 100644 index 7f3e8472d..000000000 --- a/src/main/java/app/MainLocationApplication.java +++ /dev/null @@ -1,112 +0,0 @@ -package app; - -import data_access.DBLocationDataAccessObject; -import entity.PlaceFactory; -import entity.SuggestedPlaceFactory; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationPresenter; -import interface_adapter.location.LocationViewManagerModel; -import interface_adapter.location.LocationViewModel; -import interface_adapter.suggestedLocation.SuggestedLocationController; -import interface_adapter.suggestedLocation.SuggestedLocationPresenter; -import interface_adapter.suggestedLocation.SuggestedLocationViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; - -/** - * An application that suggests locations for users based on their address and interests. - */ -public class MainLocationApplication { - - /** - * Main entry point. - * @param args commandline arguments are ignored. - */ - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - final JFrame application = new JFrame("Location Application"); - final CardLayout cardLayout = new CardLayout(); - final JPanel views = new JPanel(cardLayout); - final LocationViewModel locationViewModel = new LocationViewModel(); - final LocationView locationView = new LocationView(locationViewModel); - final SuggestedLocationViewModel suggestedLocationViewModel = new SuggestedLocationViewModel(); - views.add(locationView, "Location"); - application.add(views); - - new ViewManager(locationView, cardLayout, viewManagerModel); - final LocationController locationController = createLocationUseCase(); - - createViewsAndAddToPanel(locationViewModel, views, locationController); - - // create the data access and inject it into our builder! - final LocationDataAccessInterface locationDataAccess = new DBLocationDataAccessObject(); - - final LocationAppBuilder builder = new LocationAppBuilder(); - builder.addLocationDAO(locationDataAccess) - .addLocationView() - .addLocationUseCase().build().setVisible(true); - } -} - -// public static void main(String[] args) { -// SwingUtilities.invokeLater(() -> { -// final JFrame application = new JFrame("Location Application"); -// final CardLayout cardLayout = new CardLayout(); -// final JPanel views = new JPanel(cardLayout); -// final LocationViewModel locationViewModel = new LocationViewModel(); -// final LocationView locationView = new LocationView(locationViewModel); -// views.add(locationView, "Location"); -// application.add(views); -// final LocationViewManagerModel viewManagerModel = new LocationViewManagerModel(); -// -// new ViewManager(locationView, cardLayout, viewManagerModel); -// final LocationController locationController = createLocationUseCase(); -// -// createViewsAndAddToPanel(locationViewModel, views, locationController); -// -// cardLayout.show(views, "Location"); -// -// application.pack(); -// application.setVisible(true); -// }); -// } -// -// private static void createViewsAndAddToPanel(LocationViewModel locationViewModel, -// JPanel views, -// LocationController locationController) { -// final LocationView locationView = new LocationView(locationViewModel); -// views.add(locationView, "Location"); -// } -// -// private static LocationController createLocationUseCase() { -// final LocationDataAccessInterface location = new DBLocationDataAccessObject(); -// final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); -// final PlaceFactory placeFactory = new SuggestedPlaceFactory(); -// final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); -// return new LocationController(locationInteractor); -// } -// -// } - - private static void createViewsAndAddToPanel(LocationViewModel locationViewModel, - JPanel views, - LocationController locationController) { - final LocationView locationView = new LocationView(locationViewModel); - views.add(locationView, "Location"); - } - - private static LocationController createLocationUseCase() { - final LocationDataAccessInterface location = new DBLocationDataAccessObject(); - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel); - final PlaceFactory placeFactory = new SuggestedPlaceFactory(); - final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); - return new LocationController(locationInteractor); - } - - private static SuggestedLocationController createSuggestedLocationUseCase() { - final LocationDataAccessInterface location = new DBLocationDataAccessObject(); - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationPresenter(suggestedLocationViewModel); - final PlaceFactory placeFactory = new SuggestedPlaceFactory(); - final SuggestLocationsOutputBoundary suggestLocationsInteractor = new SuggestLocationsInteractor(location, suggestLocationsOutputBoundary, placeFactory); - return new SuggestedLocationController(suggestLocationsInteractor); - } -} diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java new file mode 100644 index 000000000..5fa041aa3 --- /dev/null +++ b/src/main/java/app/MainWithDB.java @@ -0,0 +1,62 @@ +package app; + +import data_access.DBLocationDataAccessObject; +import entity.SuggestedPlaceFactory; +import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import view.LocationView; +import view.SuggestedLocationsView; +import view.ViewManager; + +import javax.swing.*; +import java.awt.*; + +/** + * The version of Main with an external database used to persist user data. + */ +public class MainWithDB { + + /** + * The main method for starting the program with an external database used to persist user data. + * @param args input to main + */ + public static void main(String[] args) { + // Build the main program window, the main panel containing the + // various cards, and the layout, and stitch them together. + + // The main application window. + final JFrame application = new JFrame("Location Suggester"); + application.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + final CardLayout cardLayout = new CardLayout(); + + final JPanel views = new JPanel(cardLayout); + application.add(views); + + final ViewManagerModel viewManagerModel = new ViewManagerModel(); + new ViewManager(views, cardLayout, viewManagerModel); + + final LocationViewModel locationViewModel = new LocationViewModel(); + final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); + // add any future view models here in the same way + + final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( + new SuggestedPlaceFactory()); + + final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, + suggestedLocationsViewModel, locationDataAccessObject); + views.add(locationView, locationView.getViewName()); + +// final SuggestedLocationsView suggestedLocationsView = Sugg.create(viewManagerModel, +// loggedInViewModel, userDataAccessObject); +// views.add(loggedInView, loggedInView.getViewName()); + + viewManagerModel.setState(locationView.getViewName()); + viewManagerModel.firePropertyChanged(); + + application.pack(); + application.setVisible(true); + } +} + diff --git a/src/main/java/app/SuggestedLocationsAppBuilder.java b/src/main/java/app/SuggestedLocationsAppBuilder.java deleted file mode 100644 index 5e587fba8..000000000 --- a/src/main/java/app/SuggestedLocationsAppBuilder.java +++ /dev/null @@ -1,84 +0,0 @@ -package app; - -import javax.swing.*; - -import entity.Place; -import entity.PlaceFactory; -import interface_adapter.suggestedLocation.SuggestedLocationPresenter; -import interface_adapter.suggestedLocation.SuggestedLocationViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInteractor; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import use_case.suggest_locations.*; -import view.SuggestedLocationsView; - -import java.awt.*; -import java.util.List; - -/** - * Builder for the Suggested Locations Application. - */ -public class SuggestedLocationsAppBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - private LocationDataAccessInterface locationDAO; - private SuggestedLocationViewModel suggestedLocationViewModel = new SuggestedLocationViewModel(); - private SuggestedLocationsView suggestedLocationsView; - private SuggestLocationsInteractor suggestLocationsInteractor; - private PlaceFactory placeFactory; - - /** - * Sets the LocationDAO to be used in this application. - * @param locationDataAccess the DAO to use - * @return this builder - */ - public SuggestedLocationsAppBuilder addLocationDAO(LocationDataAccessInterface locationDataAccess) { - locationDAO = locationDataAccess; - return this; - } - - /** - * Creates the objects for the Location Use Case and connects the - * SuggestedLocationsView to its - * controller. - *

This method must be called after addSuggestedLocationsView!

- * @return this builder - * @throws RuntimeException if this method is called before - * addSuggestedLocationsView - */ - public SuggestedLocationsAppBuilder addSuggestedLocationUseCase() { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationPresenter(suggestedLocationViewModel); - suggestLocationsInteractor = new SuggestLocationsInteractor( - locationDAO, suggestLocationsOutputBoundary, placeFactory); - - if (suggestedLocationsView == null) { - throw new RuntimeException("addSuggestedLocationsView must be " + "called before" + " addLocationUseCase"); - } - return this; - } - - /** - * Creates the SuggestedLocationView and underlying LocationViewModel. - * @return this builder - */ - public SuggestedLocationsAppBuilder addSuggestedLocationsView(List locations) { - suggestedLocationViewModel = new SuggestedLocationViewModel(); - suggestedLocationsView = new SuggestedLocationsView(suggestedLocationViewModel); - return this; - } - - /** - * Builds the application. - * @return the JFrame for the application - */ - public JFrame build() throws DataAccessException { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Suggested Locations Application"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(suggestedLocationsView, BorderLayout.CENTER); - - return frame; - } -} \ No newline at end of file diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index a51d6fc07..f4e413e96 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -1,7 +1,11 @@ package data_access; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import entity.Place; +import entity.PlaceFactory; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -28,9 +32,14 @@ public class DBLocationDataAccessObject implements LocationDataAccessInterface { private static final String STATUS_CODE_LABEL = "status_code"; private static final String MESSAGE = "message"; private static final String API_KEY = System.getenv("API_KEY"); + private final PlaceFactory placeFactory; + + public DBLocationDataAccessObject(PlaceFactory placeFactory) { + this.placeFactory = placeFactory; + } @Override - public String searchLocation(String address, String locationType) throws DataAccessException { + public List searchLocation(String address, String locationType) throws DataAccessException { final OkHttpClient client = new OkHttpClient().newBuilder() .build(); @@ -59,7 +68,16 @@ public String searchLocation(String address, String locationType) throws DataAcc places.append(jsonObject.getString("formattedAddress")).append(">").append(jsonObject .getJSONObject("displayName").getString("text")).append("<"); } - return places.toString(); + final String placesString = places.toString(); + + final String[] locationsList = placesString.split("<:>"); + final List suggestedPlaces = new ArrayList<>(); + for (String location : locationsList) { + final Place place = placeFactory.create(location.split(">")[1], location.split(">")[0]); + suggestedPlaces.add(place); + } + return suggestedPlaces; + } else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { throw new DataAccessException("Needs API Key"); diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 622eff811..a91cf1066 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,5 +1,6 @@ package interface_adapter.location; +import use_case.suggest_locations.DataAccessException; import use_case.suggest_locations.SuggestLocationsInputBoundary; import use_case.suggest_locations.SuggestLocationsInputData; @@ -19,12 +20,12 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { /** * Executes the show location. - * @param location the location to show * Executes the save or refresh operation based on the location. * @param address the location to save or refresh * @param locationType the type of location to save or refresh + * @throws DataAccessException if data cannot be accessed */ - public void execute(String address, String locationType){ + public void execute(String address, String locationType) throws DataAccessException { final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( address, locationType); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index eb02dc87f..66f7b7fa2 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,5 +1,6 @@ package interface_adapter.suggestlocation; +import use_case.suggest_locations.DataAccessException; import use_case.suggest_locations.SuggestLocationsInputBoundary; import use_case.suggest_locations.SuggestLocationsInputData; @@ -19,7 +20,7 @@ public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocatio * @param address the address to suggest locations for * @param locationType the type of location to suggest */ - public void execute(String address, String locationType) { + public void execute(String address, String locationType) throws DataAccessException { final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( address, locationType); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 227c25c19..7dfcf1a26 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,23 +1,46 @@ package interface_adapter.suggestlocation; +import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationState; +import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; -import view.SuggestedLocationsView; /** * The presenter for the suggested locations use case. */ public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary { - private SuggestedLocationsView view; - private SuggestedLocationsViewModel viewModel; + private final ViewManagerModel viewManagerModel; + private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final LocationViewModel locationViewModel; - public SuggestedLocationsPresenter(SuggestedLocationsViewModel viewModel) { - this.viewModel = viewModel; + public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, + SuggestedLocationsViewModel suggestedLocationsViewModel, + LocationViewModel locationsViewModel) { + this.viewManagerModel = viewManagerModel; + this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.locationViewModel = locationsViewModel; } - public void setView(SuggestedLocationsView view) { - this.view = view; + @Override + public void prepareSuccessView(SuggestLocationsOutputData response) { + // On success, switch to the logged in view. + + final SuggestedLocationsState loggedInState = suggestedLocationsViewModel.getState(); + loggedInState.setSuggestedLocations(response.getLocations()); + this.suggestedLocationsViewModel.setState(loggedInState); + this.suggestedLocationsViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + final LocationState loginState = locationViewModel.getState(); + loginState.setError(error); + locationViewModel.firePropertyChanged(); } } diff --git a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java index 042be973f..720f6ddb5 100644 --- a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java +++ b/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java @@ -1,5 +1,9 @@ package use_case.suggest_locations; +import java.util.List; + +import entity.Place; + /** * Interface for the LocationDAO. It consists of methods for * searching locations @@ -13,6 +17,6 @@ public interface LocationDataAccessInterface { * @return a list of locations * @throws DataAccessException if the location can not be loaded for any reason */ - String searchLocation(String address, String locationType) throws DataAccessException; + List searchLocation(String address, String locationType) throws DataAccessException; } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index 5cf0fa569..f136ab9de 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -1,12 +1,5 @@ package use_case.suggest_locations; -import java.util.ArrayList; -import java.util.List; - -import entity.Place; -import entity.PlaceFactory; -import entity.SuggestedPlace; -import entity.SuggestedPlaceFactory; /** * The Suggest Locations Interactor. @@ -14,30 +7,18 @@ public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { private final LocationDataAccessInterface placeDataAccessObject; private final SuggestLocationsOutputBoundary placePresenter; - private final PlaceFactory placeFactory; public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, - SuggestLocationsOutputBoundary suggestLocationsOutputBoundary, - PlaceFactory placeFactory) { + SuggestLocationsOutputBoundary suggestLocationsOutputBoundary) { this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; this.placePresenter = suggestLocationsOutputBoundary; - this.placeFactory = placeFactory; } @Override public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { - final String suggestedLocations = placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), - suggestLocationsInputData.getLocationType()); - final String[] locationsList = suggestedLocations.split("<:>"); - - final List suggestedPlaces = new ArrayList<>(); - for (String location : locationsList) { - final Place place = placeFactory.create(location.split(">")[1], location.split(">")[0]); - suggestedPlaces.add(place); - } - - final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(suggestedPlaces, + final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), + suggestLocationsInputData.getLocationType()), false); placePresenter.prepareSuccessView(suggestLocationsOutputData); } -} \ No newline at end of file +} diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 4f8287eac..4873fa5af 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -13,12 +13,14 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; +import use_case.suggest_locations.DataAccessException; /** * The View for when the user is viewing a location in the program. */ public class LocationView extends JPanel implements ActionListener, PropertyChangeListener { + private final String locationViewName = "Search Locations"; private final LocationViewModel locationViewModel; private final LocationController locationController; @@ -108,10 +110,15 @@ public void changedUpdate(DocumentEvent e) { if (evt.getSource().equals(suggestLocationsButton)) { final LocationState currentState = locationViewModel.getState(); - this.locationController.execute( - currentState.getAddress(), - currentState.getLocationType() - ); + try { + this.locationController.execute( + currentState.getAddress(), + currentState.getLocationType() + ); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } } } ); @@ -143,5 +150,9 @@ private void setFields(LocationState state) { addressField.setText(state.getAddress()); locationTypeField.setText(state.getLocationType()); } + + public String getViewName() { + return locationViewName; + } } From ac5fa51bccc6597f1967be868f2782bf5b7c7796 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Thu, 21 Nov 2024 22:42:40 -0500 Subject: [PATCH 063/113] concatenated 5 location types into one string in view --- src/main/java/view/LocationView.java | 74 ++++++++++++++++++---------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 4f8287eac..e0fc18db8 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -28,7 +28,7 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final JLabel locationTypeLabel = new JLabel("Location Type"); - private final JTextField locationTypeField = new JTextField(20); + private final JTextField[] locationTypeFields = new JTextField[5]; private final JButton suggestLocationsButton; @@ -43,8 +43,12 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca final LabelTextPanel addressInfo = new LabelTextPanel( new JLabel("Address"), addressField); - final LabelTextPanel locationTypeInfo = new LabelTextPanel( - new JLabel("Location Type"), locationTypeField); + final JPanel locationTypePanel = new JPanel(); + locationTypePanel.setLayout(new BoxLayout(locationTypePanel, BoxLayout.Y_AXIS)); + for (int i = 0; i < locationTypeFields.length; i++) { + locationTypeFields[i] = new JTextField(20); + locationTypePanel.add(new LabelTextPanel(new JLabel("Location Type " + (i + 1)), locationTypeFields[i])); + } final JPanel buttons = new JPanel(); suggestLocationsButton = new JButton("Suggest Locations"); @@ -78,29 +82,41 @@ public void changedUpdate(DocumentEvent e) { } }); - locationTypeField.getDocument().addDocumentListener(new DocumentListener() { - - private void documentListenerHelper() { - final LocationState currentState = locationViewModel.getState(); - currentState.setLocationType(locationTypeField.getText()); - locationViewModel.setState(currentState); - } + for (JTextField locationTypeField : locationTypeFields) { + locationTypeField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final LocationState currentState = locationViewModel.getState(); + // make into one string + final StringBuilder locationTypes = new StringBuilder(); + for (JTextField field : locationTypeFields) { + if (!field.getText().isEmpty()) { + if (locationTypes.length() > 0) { + locationTypes.append(", "); + } + locationTypes.append(field.getText()); + } + } + currentState.setLocationType(locationTypes.toString()); + locationViewModel.setState(currentState); + } - @Override - public void insertUpdate(DocumentEvent e) { - documentListenerHelper(); - } + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } - @Override - public void removeUpdate(DocumentEvent e) { - documentListenerHelper(); - } + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } - @Override - public void changedUpdate(DocumentEvent e) { - documentListenerHelper(); - } - }); + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } suggestLocationsButton.addActionListener( // This creates an anonymous subclass of ActionListener and instantiates it. @@ -119,7 +135,7 @@ public void changedUpdate(DocumentEvent e) { this.add(title); this.add(addressInfo); this.add(addressLabel); - this.add(locationTypeInfo); + this.add(locationTypePanel); this.add(locationTypeLabel); this.add(buttons); @@ -141,7 +157,15 @@ public void propertyChange(PropertyChangeEvent evt) { private void setFields(LocationState state) { addressField.setText(state.getAddress()); - locationTypeField.setText(state.getLocationType()); + final String[] locationTypes = state.getLocationType().split(", "); + for (int i = 0; i < locationTypeFields.length; i++) { + if (i < locationTypes.length) { + locationTypeFields[i].setText(locationTypes[i]); + } + else { + locationTypeFields[i].setText(""); + } + } } } From 1ee31b981b02d7e48568743bad186eced91ea0a3 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:48:16 -0500 Subject: [PATCH 064/113] fixed app and relating files, fixed variable names --- .../suggestlocation/SuggestedLocationsPresenter.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 7dfcf1a26..e0fac58e7 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -27,9 +27,9 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, public void prepareSuccessView(SuggestLocationsOutputData response) { // On success, switch to the logged in view. - final SuggestedLocationsState loggedInState = suggestedLocationsViewModel.getState(); - loggedInState.setSuggestedLocations(response.getLocations()); - this.suggestedLocationsViewModel.setState(loggedInState); + final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); + suggestedLocationsState.setSuggestedLocations(response.getLocations()); + this.suggestedLocationsViewModel.setState(suggestedLocationsState); this.suggestedLocationsViewModel.firePropertyChanged(); this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); @@ -38,8 +38,8 @@ public void prepareSuccessView(SuggestLocationsOutputData response) { @Override public void prepareFailView(String error) { - final LocationState loginState = locationViewModel.getState(); - loginState.setError(error); + final LocationState locationState = locationViewModel.getState(); + locationState.setError(error); locationViewModel.firePropertyChanged(); } From aab7289b7a910d5f3999985b8ea2dbd449bc02c6 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Thu, 21 Nov 2024 23:25:30 -0500 Subject: [PATCH 065/113] fixed API call using parameter instead of body --- .../data_access/DBLocationDataAccessObject.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index f4e413e96..57a641d70 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -6,15 +6,11 @@ import entity.Place; import entity.PlaceFactory; +import okhttp3.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; import use_case.suggest_locations.DataAccessException; import use_case.suggest_locations.LocationDataAccessInterface; @@ -43,14 +39,13 @@ public List searchLocation(String address, String locationType) throws Da final OkHttpClient client = new OkHttpClient().newBuilder() .build(); + final HttpUrl url = HttpUrl.parse("https://places.googleapis.com/v1/places:searchText").newBuilder() + .addQueryParameter("textQuery", locationType + " near " + address) + .build(); + // POST METHOD - final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON); - final JSONObject requestBody = new JSONObject(); - requestBody.put("textQuery", locationType + " near " + address); - final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); final Request request = new Request.Builder() - .url("https://places.googleapis.com/v1/places:searchText") - .method("POST", body) + .url(url) .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) .addHeader(API_HEADER, API_KEY) .addHeader(API_FIELD, FIELDS) From e9bf44d6a9f1d138299551a5a4d2b0a1f588574e Mon Sep 17 00:00:00 2001 From: teddyyang Date: Fri, 22 Nov 2024 00:25:25 -0500 Subject: [PATCH 066/113] fixed api call again undo changes basically --- .../DBLocationDataAccessObject.java | 25 +++++++++---------- src/main/java/view/LocationView.java | 6 ----- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 57a641d70..e14473485 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -25,8 +25,7 @@ public class DBLocationDataAccessObject implements LocationDataAccessInterface { private static final String FIELDS = "places.displayName,places.formattedAddress"; private static final String CONTENT_TYPE_LABEL = "Content-Type"; private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String STATUS_CODE_LABEL = "status_code"; - private static final String MESSAGE = "message"; + private static final String STATUS_CODE_LABEL = "code"; private static final String API_KEY = System.getenv("API_KEY"); private final PlaceFactory placeFactory; @@ -39,23 +38,23 @@ public List searchLocation(String address, String locationType) throws Da final OkHttpClient client = new OkHttpClient().newBuilder() .build(); - final HttpUrl url = HttpUrl.parse("https://places.googleapis.com/v1/places:searchText").newBuilder() - .addQueryParameter("textQuery", locationType + " near " + address) - .build(); - + final JSONObject requestBody = new JSONObject(); + requestBody.put("textQuery", locationType + " near " + address); + final RequestBody body = RequestBody.create( + requestBody.toString(), MediaType.parse(CONTENT_TYPE_JSON)); // POST METHOD final Request request = new Request.Builder() - .url(url) + .url("https://places.googleapis.com/v1/places:searchText") + .post(body) .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) .addHeader(API_HEADER, API_KEY) .addHeader(API_FIELD, FIELDS) .build(); - try { - final Response response = client.newCall(request).execute(); + try (Response response = client.newCall(request).execute()) { final JSONObject responseBody = new JSONObject(response.body().string()); - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { + if (responseBody.has("places")) { final StringBuilder places = new StringBuilder(); final JSONArray jsonArray = responseBody.getJSONArray("places"); for (int i = 0; i < jsonArray.length(); i++) { @@ -74,11 +73,11 @@ public List searchLocation(String address, String locationType) throws Da return suggestedPlaces; } - else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { - throw new DataAccessException("Needs API Key"); + else if (responseBody.has("error")) { + throw new DataAccessException("API Error: " + responseBody.getJSONObject("error").getString("message")); } else { - throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); + throw new DataAccessException("Unexpected API response format."); } } catch (IOException | JSONException | DataAccessException ex) { diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 9c35041c3..0d8e5f010 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -24,12 +24,8 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final LocationViewModel locationViewModel; private final LocationController locationController; - private final JLabel addressLabel = new JLabel("Address"); - private final JTextField addressField = new JTextField(20); - private final JLabel locationTypeLabel = new JLabel("Location Type"); - private final JTextField[] locationTypeFields = new JTextField[5]; private final JButton suggestLocationsButton; @@ -141,9 +137,7 @@ public void changedUpdate(DocumentEvent e) { this.add(title); this.add(addressInfo); - this.add(addressLabel); this.add(locationTypePanel); - this.add(locationTypeLabel); this.add(buttons); } From f2e01f2f2bc0a419c669b7a09edda5bda739442d Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 22 Nov 2024 00:50:18 -0500 Subject: [PATCH 067/113] fixed view --- src/main/java/app/MainWithDB.java | 6 +++--- src/main/java/view/LocationView.java | 14 +++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 5fa041aa3..7b463ebd4 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -48,9 +48,9 @@ public static void main(String[] args) { suggestedLocationsViewModel, locationDataAccessObject); views.add(locationView, locationView.getViewName()); -// final SuggestedLocationsView suggestedLocationsView = Sugg.create(viewManagerModel, -// loggedInViewModel, userDataAccessObject); -// views.add(loggedInView, loggedInView.getViewName()); +// final SuggestedLocationsView suggestedLocationsView = SuggestedLocationUseCaseFactory.create(viewManagerModel, +// suggestedLocationsViewModel, locationDataAccessObject); +// views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 0d8e5f010..663cd8bd2 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -143,7 +143,19 @@ public void changedUpdate(DocumentEvent e) { } public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); + if (evt.getSource().equals(suggestLocationsButton)) { + final LocationState currentState = locationViewModel.getState(); + + try { + this.locationController.execute( + currentState.getAddress(), + currentState.getLocationType() + ); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } + } } @Override From 5afdfbaa61a0582dc5a6ed4c9ae25aeb72a87c91 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Fri, 22 Nov 2024 02:39:38 -0500 Subject: [PATCH 068/113] update LocationView, create SuggestedLocationUseCaseFactory, created suggested_locations input boundary, input data, interactor, output boundary, output data --- src/main/java/app/LocationUseCaseFactory.java | 9 ++- .../app/SuggestedLocationUseCaseFactory.java | 57 +++++++++++++++++++ .../SuggestedLocationsController.java | 12 ++-- .../SuggestedLocationInputBoundary.java | 14 +++++ .../SuggestedLocationInputData.java | 23 ++++++++ .../SuggestedLocationInteractor.java | 21 +++++++ .../SuggestedLocationOutputBoundary.java | 18 ++++++ .../SuggestedLocationOutputData.java | 17 ++++++ src/main/java/view/LocationView.java | 13 ++++- 9 files changed, 172 insertions(+), 12 deletions(-) create mode 100644 src/main/java/app/SuggestedLocationUseCaseFactory.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index 4821144e4..c62159ca2 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -1,7 +1,5 @@ package app; -import entity.PlaceFactory; -import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationController; import interface_adapter.location.LocationViewModel; @@ -13,6 +11,9 @@ import use_case.suggest_locations.SuggestLocationsOutputBoundary; import view.LocationView; +import javax.swing.*; +import java.awt.*; + /** * This class contains the static factory function for creating the LocationView. */ @@ -37,10 +38,12 @@ public static LocationView create( SuggestedLocationsViewModel suggestedLocationsViewModel, LocationDataAccessInterface locationDataAccessObject) { + final CardLayout cardLayout = new CardLayout(); + final JPanel parentPanel = new JPanel(); final LocationController locationController = createLocationUseCase(viewManagerModel, locationViewModel, suggestedLocationsViewModel, locationDataAccessObject); - return new LocationView(locationViewModel, locationController); + return new LocationView(locationViewModel, locationController, cardLayout, parentPanel); } private static LocationController createLocationUseCase( diff --git a/src/main/java/app/SuggestedLocationUseCaseFactory.java b/src/main/java/app/SuggestedLocationUseCaseFactory.java new file mode 100644 index 000000000..3d896861c --- /dev/null +++ b/src/main/java/app/SuggestedLocationUseCaseFactory.java @@ -0,0 +1,57 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; +import interface_adapter.suggestlocation.SuggestedLocationsController; +import interface_adapter.suggestlocation.SuggestedLocationsPresenter; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggested_locations.SuggestedLocationInputBoundary; +import use_case.suggested_locations.SuggestedLocationInteractor; +import use_case.suggested_locations.SuggestedLocationOutputBoundary; +import use_case.suggested_locations.SuggestedLocationOutputData; +import view.SuggestedLocationsView; + +import javax.swing.*; +import java.awt.*; + +/** + * This class contains the static factory function for creating the SuggestedLocationView. + */ +public class SuggestedLocationUseCaseFactory { + /** Prevent instantiation. */ + private SuggestedLocationUseCaseFactory() { + + } + + /** + * Factory function for creating the SuggestedLocationView. + * @param viewManagerModel the ViewManagerModel to inject + * @param locationViewModel the LocationViewModel to inject + * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @return the SuggestedLocationView created for the provided input classes. + */ + public static SuggestedLocationsView create( + ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel, + SuggestedLocationsViewModel suggestedLocationsViewModel) { + final CardLayout cardLayout = new CardLayout(); + final JPanel parentPanel = new JPanel(); + final SuggestedLocationsController suggestedLocationController = createSuggestedLocationUseCase( + viewManagerModel, locationViewModel, + suggestedLocationsViewModel); + + return new SuggestedLocationsView(suggestedLocationsViewModel, + suggestedLocationController, cardLayout, parentPanel); +} + + private static SuggestedLocationsController createSuggestedLocationUseCase( + ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel, + SuggestedLocationsViewModel suggestedLocationsViewModel) { + final SuggestLocationsOutputBoundary suggestedLocationOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, + suggestedLocationsViewModel, locationViewModel); + final SuggestedLocationInputBoundary locationInteractor = new SuggestedLocationInteractor(suggestedLocationOutputBoundary); + return new SuggestedLocationsController(locationInteractor); + } + } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index 66f7b7fa2..d4b947a72 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,17 +1,17 @@ package interface_adapter.suggestlocation; import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.SuggestLocationsInputBoundary; -import use_case.suggest_locations.SuggestLocationsInputData; +import use_case.suggested_locations.SuggestedLocationInputBoundary; +import use_case.suggested_locations.SuggestedLocationInputData; /** * The SuggestedLocationsController class handles user input related to suggested locations. */ public class SuggestedLocationsController { - private final SuggestLocationsInputBoundary suggestLocationsInput; + private final SuggestedLocationInputBoundary suggestLocationsInput; - public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocationsInput) { + public SuggestedLocationsController(SuggestedLocationInputBoundary suggestLocationsInput) { this.suggestLocationsInput = suggestLocationsInput; } @@ -21,9 +21,7 @@ public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocatio * @param locationType the type of location to suggest */ public void execute(String address, String locationType) throws DataAccessException { - final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( - address, locationType); - + final SuggestedLocationInputData suggestLocationInputData = new SuggestedLocationInputData(address, locationType); suggestLocationsInput.execute(suggestLocationInputData); } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java new file mode 100644 index 000000000..5fb3d5806 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java @@ -0,0 +1,14 @@ +package use_case.suggested_locations; + +import use_case.suggest_locations.DataAccessException; + +/** + * The Suggested Locations Use Case. + */ +public interface SuggestedLocationInputBoundary { + /** + * Execute the Suggested Locations Use Case. + * @param suggestedLocationsInputData the input data for this use case + */ + void execute(SuggestedLocationInputData suggestedLocationsInputData) throws DataAccessException; +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java new file mode 100644 index 000000000..54b0325a2 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java @@ -0,0 +1,23 @@ +package use_case.suggested_locations; + +/** + * The input data for the Suggested Locations Use Case. + */ +public class SuggestedLocationInputData { + + private final String address; + private final String locationType; + + public SuggestedLocationInputData(String address, String locationType) { + this.address = address; + this.locationType = locationType; + } + + public String getAddress() { + return address; + } + + public String getLocationType() { + return locationType; + } +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java new file mode 100644 index 000000000..b3d652595 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java @@ -0,0 +1,21 @@ +package use_case.suggested_locations; + +/** + * The Suggested Locations Interactor. + */ +public class SuggestedLocationInteractor implements SuggestedLocationInputBoundary { + + private final SuggestedLocationOutputBoundary outputBoundary; + + public SuggestedLocationInteractor(SuggestedLocationOutputBoundary outputBoundary) { + this.outputBoundary = outputBoundary; + } + + @Override + public void execute(SuggestedLocationInputData suggestedLocationInputData) { + final SuggestedLocationOutputData suggestedLocationOutputData = new SuggestedLocationOutputData( + suggestedLocationInputData.getAddress() + ); + outputBoundary.prepareSuccessView(suggestedLocationOutputData); + } +} \ No newline at end of file diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java new file mode 100644 index 000000000..25957bd54 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java @@ -0,0 +1,18 @@ +package use_case.suggested_locations; + +/** + * The output boundary for the Suggested Location Use Case. + */ +public interface SuggestedLocationOutputBoundary { + /** + * Prepares the sucess view for the Suggested Location Use Case. + * @param outputData the explanation of the failure + */ + void prepareSuccessView(SuggestedLocationOutputData outputData); + + /** + * Prepares the failure view for the Suggested Location Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java new file mode 100644 index 000000000..3a1f62614 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java @@ -0,0 +1,17 @@ +package use_case.suggested_locations; + +/** + * The output data for the Suggested Location Use Case. + */ +public class SuggestedLocationOutputData { + + private final String suggestedLocation; + + public SuggestedLocationOutputData(String suggestedLocation) { + this.suggestedLocation = suggestedLocation; + } + + public String getSuggestedLocation() { + return suggestedLocation; + } +} diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 663cd8bd2..cb5622ac8 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -1,12 +1,14 @@ package view; -import java.awt.Component; +import java.awt.*; +import java.awt.CardLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; +import javax.swing.JPanel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -23,6 +25,8 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final String locationViewName = "Search Locations"; private final LocationViewModel locationViewModel; private final LocationController locationController; + private final CardLayout cardLayout; + private final JPanel parentPanel; private final JTextField addressField = new JTextField(20); @@ -30,10 +34,14 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final JButton suggestLocationsButton; - public LocationView(LocationViewModel locationViewModel, LocationController locationController) { + public LocationView(LocationViewModel locationViewModel, + LocationController locationController, + CardLayout cardLayout, JPanel parentPanel) { this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); this.locationController = locationController; + this.cardLayout = cardLayout; + this.parentPanel = parentPanel; final JLabel title = new JLabel("Suggest Locations"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -144,6 +152,7 @@ public void changedUpdate(DocumentEvent e) { public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { + cardLayout.show(parentPanel, "suggestedLocationsView"); final LocationState currentState = locationViewModel.getState(); try { From 1ce157deb2b499542d86b9698185d75a8045c7ce Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Fri, 22 Nov 2024 02:56:21 -0500 Subject: [PATCH 069/113] tried to fix SuggestedLocationUseCaseFactory --- src/main/java/app/SuggestedLocationUseCaseFactory.java | 2 +- .../suggestlocation/SuggestedLocationsPresenter.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/SuggestedLocationUseCaseFactory.java b/src/main/java/app/SuggestedLocationUseCaseFactory.java index 3d896861c..8647ed721 100644 --- a/src/main/java/app/SuggestedLocationUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationUseCaseFactory.java @@ -49,7 +49,7 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, SuggestedLocationsViewModel suggestedLocationsViewModel) { - final SuggestLocationsOutputBoundary suggestedLocationOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, + final SuggestedLocationsPresenter suggestedLocationOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, suggestedLocationsViewModel, locationViewModel); final SuggestedLocationInputBoundary locationInteractor = new SuggestedLocationInteractor(suggestedLocationOutputBoundary); return new SuggestedLocationsController(locationInteractor); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index e0fac58e7..6255aae7c 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -5,11 +5,13 @@ import interface_adapter.location.LocationViewModel; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; +import use_case.suggested_locations.SuggestedLocationOutputBoundary; +import use_case.suggested_locations.SuggestedLocationOutputData; /** * The presenter for the suggested locations use case. */ -public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary { +public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary, SuggestedLocationOutputBoundary { private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; @@ -36,6 +38,11 @@ public void prepareSuccessView(SuggestLocationsOutputData response) { this.viewManagerModel.firePropertyChanged(); } + @Override + public void prepareSuccessView(SuggestedLocationOutputData outputData) { + + } + @Override public void prepareFailView(String error) { final LocationState locationState = locationViewModel.getState(); From 940275d84731ac2232f9728e39350b885317e152 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 22 Nov 2024 14:23:08 -0500 Subject: [PATCH 070/113] fixed presenter --- .../location/LocationPresenter.java | 33 ++++++++++++++----- .../SuggestLocationsOutputBoundary.java | 5 +++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index bd85bbe35..2f3aa658d 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -1,5 +1,8 @@ package interface_adapter.location; +import interface_adapter.ViewManagerModel; +import interface_adapter.suggestlocation.SuggestedLocationsState; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; import view.LocationView; @@ -9,24 +12,36 @@ */ public class LocationPresenter implements SuggestLocationsOutputBoundary { - private LocationView view; - private LocationViewModel viewModel; + private final LocationViewModel locationViewModel; + private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final ViewManagerModel viewManagerModel; - public LocationPresenter(LocationViewModel viewModel) { - this.viewModel = viewModel; - } - - public void setView(LocationView view) { - this.view = view; + public LocationPresenter(LocationViewModel locationViewModel, SuggestedLocationsViewModel suggestedLocationsViewModel, ViewManagerModel viewManagerModel) { + this.locationViewModel = locationViewModel; + this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.viewManagerModel = viewManagerModel; } @Override public void prepareSuccessView(SuggestLocationsOutputData response) { - + // On success, switch to the suggested locations view. + final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); + suggestedLocationsState.setSuggestedLocations(response.getLocations()); + this.suggestedLocationsViewModel.setState(suggestedLocationsState); + suggestedLocationsViewModel.firePropertyChanged(); + + viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); } @Override public void prepareFailView(String error) { throw new LocationSearchFailed(error); } + + @Override + public void switchToSuggestedLocationsView() { + viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java index 086aa1e8b..8e267c1bb 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java @@ -15,4 +15,9 @@ public interface SuggestLocationsOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); + + /** + * Switches to the Suggested Locations View. + */ + void switchToSuggestedLocationsView(); } From 9c43c84f48a955f5dde639a9ba643a1e427861c2 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 22 Nov 2024 14:33:12 -0500 Subject: [PATCH 071/113] made changes to use case and interface adaptors --- .../interface_adapter/location/LocationController.java | 10 +++++++++- .../interface_adapter/location/LocationPresenter.java | 1 - .../SuggestLocationsInputBoundary.java | 5 +++++ .../suggest_locations/SuggestLocationsInteractor.java | 5 +++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index a91cf1066..64254d0e7 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -21,7 +21,8 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { /** * Executes the show location. * Executes the save or refresh operation based on the location. - * @param address the location to save or refresh + * + * @param address the location to save or refresh * @param locationType the type of location to save or refresh * @throws DataAccessException if data cannot be accessed */ @@ -31,4 +32,11 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(suggestLocationInputData); } + + /** + * Switches to the suggested locations view. + */ + public void switchToSuggestedLocationsView() { + locationInput.switchToSuggestedLocationsView(); + } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 2f3aa658d..e5f637bca 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -5,7 +5,6 @@ import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import use_case.suggest_locations.SuggestLocationsOutputBoundary; import use_case.suggest_locations.SuggestLocationsOutputData; -import view.LocationView; /** * The presenter for our Note viewing and editing program. diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java index 19c41adf8..aebae4f8e 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java @@ -9,4 +9,9 @@ public interface SuggestLocationsInputBoundary { * @param suggestLocationsInputData the input data for this use case */ void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException; + + /** + * Switch to the Suggested Locations View. + */ + void switchToSuggestedLocationsView(); } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java index f136ab9de..11506e0c0 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java @@ -21,4 +21,9 @@ public void execute(SuggestLocationsInputData suggestLocationsInputData) throws false); placePresenter.prepareSuccessView(suggestLocationsOutputData); } + + @Override + public void switchToSuggestedLocationsView() { + placePresenter.switchToSuggestedLocationsView(); + } } From 3f435679c59d7c0994ede420ff19d9edfada4204 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 22 Nov 2024 14:41:00 -0500 Subject: [PATCH 072/113] changed use case factory to work with presenter --- src/main/java/app/LocationUseCaseFactory.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index 4821144e4..63d06bd33 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -4,6 +4,7 @@ import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationController; +import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -49,8 +50,8 @@ private static LocationController createLocationUseCase( SuggestedLocationsViewModel suggestedLocationsViewModel, LocationDataAccessInterface userDataAccessObject) { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, - suggestedLocationsViewModel, locationViewModel); + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel, + suggestedLocationsViewModel, viewManagerModel); final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(userDataAccessObject, suggestLocationsOutputBoundary); From fcb3f73f6f03d2a72055d5f50f1f97b1fd43b455 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 22 Nov 2024 15:04:33 -0500 Subject: [PATCH 073/113] Changed name of use cases --- src/main/java/app/LocationUseCaseFactory.java | 15 ++++------ .../location/LocationController.java | 12 ++++---- .../location/LocationPresenter.java | 8 ++--- .../location/LocationState.java | 6 ---- .../SuggestedLocationsController.java | 10 +++---- .../SuggestedLocationsPresenter.java | 13 ++++++--- ...ndary.java => LocationsInputBoundary.java} | 6 ++-- ...InputData.java => LocationsInputData.java} | 4 +-- .../LocationsInteractor.java | 29 +++++++++++++++++++ ...dary.java => LocationsOutputBoundary.java} | 4 +-- ...tputData.java => LocationsOutputData.java} | 5 ++-- .../SuggestLocationsInteractor.java | 29 ------------------- src/main/java/view/LocationView.java | 20 +++++++++++++ 13 files changed, 88 insertions(+), 73 deletions(-) rename src/main/java/use_case/suggest_locations/{SuggestLocationsInputBoundary.java => LocationsInputBoundary.java} (53%) rename src/main/java/use_case/suggest_locations/{SuggestLocationsInputData.java => LocationsInputData.java} (77%) create mode 100644 src/main/java/use_case/suggest_locations/LocationsInteractor.java rename src/main/java/use_case/suggest_locations/{SuggestLocationsOutputBoundary.java => LocationsOutputBoundary.java} (81%) rename src/main/java/use_case/suggest_locations/{SuggestLocationsOutputData.java => LocationsOutputData.java} (71%) delete mode 100644 src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index 63d06bd33..03be01576 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -1,17 +1,14 @@ package app; -import entity.PlaceFactory; -import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationController; import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.SuggestLocationsInputBoundary; -import use_case.suggest_locations.SuggestLocationsInteractor; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; +import use_case.suggest_locations.LocationsInputBoundary; +import use_case.suggest_locations.LocationsInteractor; +import use_case.suggest_locations.LocationsOutputBoundary; import view.LocationView; /** @@ -50,10 +47,10 @@ private static LocationController createLocationUseCase( SuggestedLocationsViewModel suggestedLocationsViewModel, LocationDataAccessInterface userDataAccessObject) { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new LocationPresenter(locationViewModel, + final LocationsOutputBoundary locationsOutputBoundary = new LocationPresenter(locationViewModel, suggestedLocationsViewModel, viewManagerModel); - final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(userDataAccessObject, - suggestLocationsOutputBoundary); + final LocationsInputBoundary locationInteractor = new LocationsInteractor(userDataAccessObject, + locationsOutputBoundary); return new LocationController(locationInteractor); } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 64254d0e7..939e885e1 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,8 +1,8 @@ package interface_adapter.location; import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.SuggestLocationsInputBoundary; -import use_case.suggest_locations.SuggestLocationsInputData; +import use_case.suggest_locations.LocationsInputBoundary; +import use_case.suggest_locations.LocationsInputData; /** * The LocationController class handles user input related to locations. @@ -12,9 +12,9 @@ */ public class LocationController { - private final SuggestLocationsInputBoundary locationInput; + private final LocationsInputBoundary locationInput; - public LocationController(SuggestLocationsInputBoundary locationInteractor) { + public LocationController(LocationsInputBoundary locationInteractor) { this.locationInput = locationInteractor; } @@ -27,10 +27,10 @@ public LocationController(SuggestLocationsInputBoundary locationInteractor) { * @throws DataAccessException if data cannot be accessed */ public void execute(String address, String locationType) throws DataAccessException { - final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( + final LocationsInputData locationInputData = new LocationsInputData( address, locationType); - locationInput.execute(suggestLocationInputData); + locationInput.execute(locationInputData); } /** diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index e5f637bca..eaa69a0e1 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -3,13 +3,13 @@ import interface_adapter.ViewManagerModel; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import use_case.suggest_locations.SuggestLocationsOutputData; +import use_case.suggest_locations.LocationsOutputBoundary; +import use_case.suggest_locations.LocationsOutputData; /** * The presenter for our Note viewing and editing program. */ -public class LocationPresenter implements SuggestLocationsOutputBoundary { +public class LocationPresenter implements LocationsOutputBoundary { private final LocationViewModel locationViewModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; @@ -22,7 +22,7 @@ public LocationPresenter(LocationViewModel locationViewModel, SuggestedLocations } @Override - public void prepareSuccessView(SuggestLocationsOutputData response) { + public void prepareSuccessView(LocationsOutputData response) { // On success, switch to the suggested locations view. final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); suggestedLocationsState.setSuggestedLocations(response.getLocations()); diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index dfee73239..2e93d8b3a 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -1,11 +1,5 @@ package interface_adapter.location; -import java.util.ArrayList; -import java.util.List; - -import entity.Place; -import use_case.suggest_locations.SuggestLocationsInputData; - /** * The state representing location-related data, including city, address, keywords, * suggested locations, and any error messages. diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index 66f7b7fa2..23f4ba768 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,17 +1,17 @@ package interface_adapter.suggestlocation; import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.SuggestLocationsInputBoundary; -import use_case.suggest_locations.SuggestLocationsInputData; +import use_case.suggest_locations.LocationsInputBoundary; +import use_case.suggest_locations.LocationsInputData; /** * The SuggestedLocationsController class handles user input related to suggested locations. */ public class SuggestedLocationsController { - private final SuggestLocationsInputBoundary suggestLocationsInput; + private final LocationsInputBoundary suggestLocationsInput; - public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocationsInput) { + public SuggestedLocationsController(LocationsInputBoundary suggestLocationsInput) { this.suggestLocationsInput = suggestLocationsInput; } @@ -21,7 +21,7 @@ public SuggestedLocationsController(SuggestLocationsInputBoundary suggestLocatio * @param locationType the type of location to suggest */ public void execute(String address, String locationType) throws DataAccessException { - final SuggestLocationsInputData suggestLocationInputData = new SuggestLocationsInputData( + final LocationsInputData suggestLocationInputData = new LocationsInputData( address, locationType); suggestLocationsInput.execute(suggestLocationInputData); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index e0fac58e7..04a2b62ed 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -3,13 +3,13 @@ import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import use_case.suggest_locations.SuggestLocationsOutputData; +import use_case.suggest_locations.LocationsOutputBoundary; +import use_case.suggest_locations.LocationsOutputData; /** * The presenter for the suggested locations use case. */ -public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary { +public class SuggestedLocationsPresenter implements LocationsOutputBoundary { private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; @@ -24,7 +24,7 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, } @Override - public void prepareSuccessView(SuggestLocationsOutputData response) { + public void prepareSuccessView(LocationsOutputData response) { // On success, switch to the logged in view. final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); @@ -43,4 +43,9 @@ public void prepareFailView(String error) { locationViewModel.firePropertyChanged(); } + @Override + public void switchToSuggestedLocationsView() { + + } + } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java b/src/main/java/use_case/suggest_locations/LocationsInputBoundary.java similarity index 53% rename from src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java rename to src/main/java/use_case/suggest_locations/LocationsInputBoundary.java index aebae4f8e..ed291e634 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputBoundary.java +++ b/src/main/java/use_case/suggest_locations/LocationsInputBoundary.java @@ -3,12 +3,12 @@ /** * The Suggest Locations Use Case. */ -public interface SuggestLocationsInputBoundary { +public interface LocationsInputBoundary { /** * Execute the Suggest Locations Use Case. - * @param suggestLocationsInputData the input data for this use case + * @param locationsInputData the input data for this use case */ - void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException; + void execute(LocationsInputData locationsInputData) throws DataAccessException; /** * Switch to the Suggested Locations View. diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java b/src/main/java/use_case/suggest_locations/LocationsInputData.java similarity index 77% rename from src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java rename to src/main/java/use_case/suggest_locations/LocationsInputData.java index 9f470de8c..3317a6409 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInputData.java +++ b/src/main/java/use_case/suggest_locations/LocationsInputData.java @@ -3,12 +3,12 @@ /** * The input data for the Suggest Locations Use Case. */ -public class SuggestLocationsInputData { +public class LocationsInputData { private final String address; private final String locationType; - public SuggestLocationsInputData(String address, String locationType) { + public LocationsInputData(String address, String locationType) { this.address = address; this.locationType = locationType; } diff --git a/src/main/java/use_case/suggest_locations/LocationsInteractor.java b/src/main/java/use_case/suggest_locations/LocationsInteractor.java new file mode 100644 index 000000000..d3c03c5ed --- /dev/null +++ b/src/main/java/use_case/suggest_locations/LocationsInteractor.java @@ -0,0 +1,29 @@ +package use_case.suggest_locations; + + +/** + * The Suggest Locations Interactor. + */ +public class LocationsInteractor implements LocationsInputBoundary { + private final LocationDataAccessInterface placeDataAccessObject; + private final LocationsOutputBoundary placePresenter; + + public LocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, + LocationsOutputBoundary locationsOutputBoundary) { + this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; + this.placePresenter = locationsOutputBoundary; + } + + @Override + public void execute(LocationsInputData locationsInputData) throws DataAccessException { + final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject.searchLocation(locationsInputData.getAddress(), + locationsInputData.getLocationType()), + false); + placePresenter.prepareSuccessView(locationsOutputData); + } + + @Override + public void switchToSuggestedLocationsView() { + placePresenter.switchToSuggestedLocationsView(); + } +} diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java b/src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java similarity index 81% rename from src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java rename to src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java index 8e267c1bb..b08b1ff28 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputBoundary.java +++ b/src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java @@ -3,12 +3,12 @@ /** * The output boundary for the Suggest Locations Use Case. */ -public interface SuggestLocationsOutputBoundary { +public interface LocationsOutputBoundary { /** * Prepares the success view for the Suggest Locations Use Case. * @param outputData the output data */ - void prepareSuccessView(SuggestLocationsOutputData outputData); + void prepareSuccessView(LocationsOutputData outputData); /** * Prepares the failure view for the SuggestLocations Use Case. diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java b/src/main/java/use_case/suggest_locations/LocationsOutputData.java similarity index 71% rename from src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java rename to src/main/java/use_case/suggest_locations/LocationsOutputData.java index 7ec79cf5b..be93f75a7 100644 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsOutputData.java +++ b/src/main/java/use_case/suggest_locations/LocationsOutputData.java @@ -3,17 +3,16 @@ import java.util.List; import entity.Place; -import entity.SuggestedPlace; /** * Output Data for the Suggest Locations Use Case. */ -public class SuggestLocationsOutputData { +public class LocationsOutputData { private final List locations; private final boolean useCaseFailed; - public SuggestLocationsOutputData(List locations, boolean useCaseFailed) { + public LocationsOutputData(List locations, boolean useCaseFailed) { this.locations = locations; this.useCaseFailed = useCaseFailed; } diff --git a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java b/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java deleted file mode 100644 index 11506e0c0..000000000 --- a/src/main/java/use_case/suggest_locations/SuggestLocationsInteractor.java +++ /dev/null @@ -1,29 +0,0 @@ -package use_case.suggest_locations; - - -/** - * The Suggest Locations Interactor. - */ -public class SuggestLocationsInteractor implements SuggestLocationsInputBoundary { - private final LocationDataAccessInterface placeDataAccessObject; - private final SuggestLocationsOutputBoundary placePresenter; - - public SuggestLocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, - SuggestLocationsOutputBoundary suggestLocationsOutputBoundary) { - this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; - this.placePresenter = suggestLocationsOutputBoundary; - } - - @Override - public void execute(SuggestLocationsInputData suggestLocationsInputData) throws DataAccessException { - final SuggestLocationsOutputData suggestLocationsOutputData = new SuggestLocationsOutputData(placeDataAccessObject.searchLocation(suggestLocationsInputData.getAddress(), - suggestLocationsInputData.getLocationType()), - false); - placePresenter.prepareSuccessView(suggestLocationsOutputData); - } - - @Override - public void switchToSuggestedLocationsView() { - placePresenter.switchToSuggestedLocationsView(); - } -} diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 0d8e5f010..7bde8d732 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -135,6 +135,26 @@ public void changedUpdate(DocumentEvent e) { } ); + suggestLocationsButton.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute( + currentState.getAddress(), + currentState.getLocationType() + ); + locationController.switchToSuggestedLocationsView(); + } + catch (DataAccessException ex) { + throw new RuntimeException(ex); + } + + } + } + ); + this.add(title); this.add(addressInfo); this.add(locationTypePanel); From 56fb8f8074656ad5c0bba83c9745168c17982020 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Fri, 22 Nov 2024 20:30:49 -0500 Subject: [PATCH 074/113] fixed some comments, still need to fix views and any remaining bugs --- .../SuggestedLocationsController.java | 10 ++++++---- .../SuggestedLocationsPresenter.java | 2 +- .../SuggestedLocationInputData.java | 19 +++++++++---------- .../SuggestedLocationInteractor.java | 12 +++++++----- .../SuggestedLocationOutputData.java | 10 +++++++--- .../java/view/SuggestedLocationsView.java | 1 + 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index d4b947a72..976b9a90c 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,9 +1,12 @@ package interface_adapter.suggestlocation; +import entity.Place; import use_case.suggest_locations.DataAccessException; import use_case.suggested_locations.SuggestedLocationInputBoundary; import use_case.suggested_locations.SuggestedLocationInputData; +import java.util.List; + /** * The SuggestedLocationsController class handles user input related to suggested locations. */ @@ -17,11 +20,10 @@ public SuggestedLocationsController(SuggestedLocationInputBoundary suggestLocati /** * Executes the suggest locations operation. - * @param address the address to suggest locations for - * @param locationType the type of location to suggest + * @param places the suggested places found. */ - public void execute(String address, String locationType) throws DataAccessException { - final SuggestedLocationInputData suggestLocationInputData = new SuggestedLocationInputData(address, locationType); + public void execute(List places) throws DataAccessException { + final SuggestedLocationInputData suggestLocationInputData = new SuggestedLocationInputData(places); suggestLocationsInput.execute(suggestLocationInputData); } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 6255aae7c..30e39b617 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -11,7 +11,7 @@ /** * The presenter for the suggested locations use case. */ -public class SuggestedLocationsPresenter implements SuggestLocationsOutputBoundary, SuggestedLocationOutputBoundary { +public class SuggestedLocationsPresenter implements SuggestedLocationOutputBoundary { private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java index 54b0325a2..ddee5e126 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java @@ -1,23 +1,22 @@ package use_case.suggested_locations; +import entity.Place; + +import java.util.List; + /** * The input data for the Suggested Locations Use Case. */ public class SuggestedLocationInputData { - private final String address; - private final String locationType; + private final List places; - public SuggestedLocationInputData(String address, String locationType) { - this.address = address; - this.locationType = locationType; + public SuggestedLocationInputData(List places) { + this.places = places; } - public String getAddress() { - return address; + public List getPlaces() { + return places; } - public String getLocationType() { - return locationType; - } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java index b3d652595..d1408b896 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java @@ -1,21 +1,23 @@ package use_case.suggested_locations; +import interface_adapter.suggestlocation.SuggestedLocationsPresenter; + /** * The Suggested Locations Interactor. */ public class SuggestedLocationInteractor implements SuggestedLocationInputBoundary { - private final SuggestedLocationOutputBoundary outputBoundary; + private final SuggestedLocationOutputBoundary suggestedLocationsPresenter; - public SuggestedLocationInteractor(SuggestedLocationOutputBoundary outputBoundary) { - this.outputBoundary = outputBoundary; + public SuggestedLocationInteractor(SuggestedLocationOutputBoundary suggestedLocationOutputBoundary) { + this.suggestedLocationsPresenter = suggestedLocationOutputBoundary; } @Override public void execute(SuggestedLocationInputData suggestedLocationInputData) { final SuggestedLocationOutputData suggestedLocationOutputData = new SuggestedLocationOutputData( - suggestedLocationInputData.getAddress() + suggestedLocationInputData.getPlaces() ); - outputBoundary.prepareSuccessView(suggestedLocationOutputData); + suggestedLocationOutputBoundary.prepareSuccessView(suggestedLocationOutputData); } } \ No newline at end of file diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java index 3a1f62614..d4d2449bc 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java @@ -1,17 +1,21 @@ package use_case.suggested_locations; +import entity.Place; + +import java.util.List; + /** * The output data for the Suggested Location Use Case. */ public class SuggestedLocationOutputData { - private final String suggestedLocation; + private final List suggestedLocation; - public SuggestedLocationOutputData(String suggestedLocation) { + public SuggestedLocationOutputData(List suggestedLocation) { this.suggestedLocation = suggestedLocation; } - public String getSuggestedLocation() { + public List getSuggestedLocation() { return suggestedLocation; } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 8e55954dd..1c4cee281 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -56,6 +56,7 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView updateSuggestedLocations(suggestedLocationsViewModel.getState()); } +// how to change this @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { From ad3008c35c66a8d52a887cc345b007fc61c2a5a3 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Fri, 22 Nov 2024 21:12:39 -0500 Subject: [PATCH 075/113] fixed errors, jpanels and cardlayouts. review for errors. --- src/main/java/app/LocationUseCaseFactory.java | 20 ++++++++----------- src/main/java/app/MainWithDB.java | 11 +++++----- .../app/SuggestedLocationUseCaseFactory.java | 6 +++--- .../SuggestedLocationsPresenter.java | 1 - .../SuggestedLocationInteractor.java | 2 +- src/main/java/view/LocationView.java | 1 + .../java/view/SuggestedLocationsView.java | 6 +++++- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index c62159ca2..473e98fa9 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -2,8 +2,8 @@ import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationController; +import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; -import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import use_case.suggest_locations.LocationDataAccessInterface; import use_case.suggest_locations.SuggestLocationsInputBoundary; @@ -28,32 +28,28 @@ private LocationUseCaseFactory() { * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject * @param locationViewModel the LocationViewModel to inject - * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject * @param locationDataAccessObject the LocationDataAccessInterface to inject + * @param cardLayout the CardLayout to inject + * @param parentPanel the JPanel to inject * @return the LocationView created for the provided input classes. */ public static LocationView create( ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, - SuggestedLocationsViewModel suggestedLocationsViewModel, - LocationDataAccessInterface locationDataAccessObject) { + LocationDataAccessInterface locationDataAccessObject, CardLayout cardLayout, JPanel parentPanel) { - final CardLayout cardLayout = new CardLayout(); - final JPanel parentPanel = new JPanel(); - final LocationController locationController = createLocationUseCase(viewManagerModel, locationViewModel, - suggestedLocationsViewModel, locationDataAccessObject); + final LocationController locationController = createLocationUseCase( + locationViewModel, locationDataAccessObject); return new LocationView(locationViewModel, locationController, cardLayout, parentPanel); } private static LocationController createLocationUseCase( - ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, - SuggestedLocationsViewModel suggestedLocationsViewModel, LocationDataAccessInterface userDataAccessObject) { - final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, - suggestedLocationsViewModel, locationViewModel); + final SuggestLocationsOutputBoundary suggestLocationsOutputBoundary = + new LocationPresenter(locationViewModel); final SuggestLocationsInputBoundary locationInteractor = new SuggestLocationsInteractor(userDataAccessObject, suggestLocationsOutputBoundary); diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 7b463ebd4..fb3c5e6ed 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -44,13 +44,14 @@ public static void main(String[] args) { final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); - final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, - suggestedLocationsViewModel, locationDataAccessObject); + final LocationView locationView = + LocationUseCaseFactory.create(viewManagerModel, + locationViewModel, locationDataAccessObject, cardLayout, views); views.add(locationView, locationView.getViewName()); -// final SuggestedLocationsView suggestedLocationsView = SuggestedLocationUseCaseFactory.create(viewManagerModel, -// suggestedLocationsViewModel, locationDataAccessObject); -// views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final SuggestedLocationsView suggestedLocationsView = SuggestedLocationUseCaseFactory.create(viewManagerModel, + locationViewModel, suggestedLocationsViewModel, cardLayout, views); + views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/app/SuggestedLocationUseCaseFactory.java b/src/main/java/app/SuggestedLocationUseCaseFactory.java index 8647ed721..7ac35ac00 100644 --- a/src/main/java/app/SuggestedLocationUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationUseCaseFactory.java @@ -29,14 +29,14 @@ private SuggestedLocationUseCaseFactory() { * @param viewManagerModel the ViewManagerModel to inject * @param locationViewModel the LocationViewModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @param cardLayout the CardLayout to inject + * @param parentPanel the JPanel to inject * @return the SuggestedLocationView created for the provided input classes. */ public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { - final CardLayout cardLayout = new CardLayout(); - final JPanel parentPanel = new JPanel(); + SuggestedLocationsViewModel suggestedLocationsViewModel, CardLayout cardLayout, JPanel parentPanel) { final SuggestedLocationsController suggestedLocationController = createSuggestedLocationUseCase( viewManagerModel, locationViewModel, suggestedLocationsViewModel); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 30e39b617..1c98194d2 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -25,7 +25,6 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, this.locationViewModel = locationsViewModel; } - @Override public void prepareSuccessView(SuggestLocationsOutputData response) { // On success, switch to the logged in view. diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java index d1408b896..043d725e8 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java @@ -18,6 +18,6 @@ public void execute(SuggestedLocationInputData suggestedLocationInputData) { final SuggestedLocationOutputData suggestedLocationOutputData = new SuggestedLocationOutputData( suggestedLocationInputData.getPlaces() ); - suggestedLocationOutputBoundary.prepareSuccessView(suggestedLocationOutputData); + suggestedLocationsPresenter.prepareSuccessView(suggestedLocationOutputData); } } \ No newline at end of file diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index cb5622ac8..3f522b42a 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -150,6 +150,7 @@ public void changedUpdate(DocumentEvent e) { } + @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { cardLayout.show(parentPanel, "suggestedLocationsView"); diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 1c4cee281..0ee95cd58 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -22,6 +22,7 @@ */ public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { + private final String suggestLocationsViewName = "Found Locations"; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; private final CardLayout cardLayout; @@ -56,7 +57,6 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView updateSuggestedLocations(suggestedLocationsViewModel.getState()); } -// how to change this @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { @@ -80,4 +80,8 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); } + + public String getViewName() { + return suggestLocationsViewName; + } } From 89faac43781507696d4bb1f57e0bb0391c91ef94 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:20:58 -0500 Subject: [PATCH 076/113] added SuggestedLocations use case and corresponding files in app --- .../app/SuggestedLocationsUseCaseFactory.java | 53 +++++++++++++++++++ .../SuggestedLocationsInputBoundary.java | 22 ++++++++ .../SuggestedLocationsInputData.java | 22 ++++++++ .../SuggestedLocationsInteractor.java | 21 ++++++++ .../SuggestedLocationsOutputBoundary.java | 20 +++++++ .../SuggestedLocationsOutputData.java | 23 ++++++++ 6 files changed, 161 insertions(+) create mode 100644 src/main/java/app/SuggestedLocationsUseCaseFactory.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationsOutputBoundary.java create mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java new file mode 100644 index 000000000..70564c274 --- /dev/null +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -0,0 +1,53 @@ +package app; + + +import interface_adapter.ViewManagerModel; +import interface_adapter.suggestlocation.SuggestedLocationsController; +import interface_adapter.suggestlocation.SuggestedLocationsPresenter; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.suggested_locations.SuggestedLocationsInteractor; +import use_case.suggested_locations.SuggestedLocationsInputBoundary; +import use_case.suggested_locations.SuggestedLocationsOutputBoundary; +import view.SuggestedLocationsView; + +/** + * This class contains the static factory function for creating the SuggestedLocationView. + */ +public class SuggestedLocationsUseCaseFactory { + + /** Prevent instantiation. */ + private SuggestedLocationsUseCaseFactory() { + + } + + /** + * Factory function for creating the LocationView. + * @param viewManagerModel the ViewManagerModel to inject + * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @return the LocationView created for the provided input classes. + */ + public static SuggestedLocationsView create( + ViewManagerModel viewManagerModel, + SuggestedLocationsViewModel suggestedLocationsViewModel) { + + final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, + suggestedLocationsViewModel); + + // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) + return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); + } + + private static SuggestedLocationsController createSuggestedLocationUseCase( + ViewManagerModel viewManagerModel, + SuggestedLocationsViewModel suggestedLocationsViewModel) { + + final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( + viewManagerModel, suggestedLocationsViewModel); + final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( + suggestedLocationsOutputBoundary); + + return new SuggestedLocationsController(suggestedLocationsInteractor); + } +} + + diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java new file mode 100644 index 000000000..23592803d --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java @@ -0,0 +1,22 @@ +package use_case.suggested_locations; + +import use_case.DataAccessException; + +/** + * The Suggested Locations Use Case. + */ +public interface SuggestedLocationsInputBoundary { + /** + * Execute the Suggested Locations Use Case. + * + * @param suggestedLocationsInputData the input data for this use case + * @throws DataAccessException if data cannot be accessed at any time + */ + void execute(SuggestedLocationsInputData suggestedLocationsInputData) throws DataAccessException; +// +// /** +// * Switch to the TODO: next View. +// */ +// void switchToSuggestedLocationsView(); +//} +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java new file mode 100644 index 000000000..4c32334c1 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java @@ -0,0 +1,22 @@ +package use_case.suggested_locations; + +import java.util.List; + +import entity.Place; + +/** + * The input data for the Suggested Locations Use Case. + */ +public class SuggestedLocationsInputData { + + private final List suggestedLocations; + + public SuggestedLocationsInputData(List suggestedLocations) { + this.suggestedLocations = suggestedLocations; + } + + public List getSuggestedLocations() { + return suggestedLocations; + } + +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java new file mode 100644 index 000000000..34212cffc --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java @@ -0,0 +1,21 @@ +package use_case.suggested_locations; + +import use_case.DataAccessException; + +/** + * The Suggested Locations Interactor. + */ +public class SuggestedLocationsInteractor implements SuggestedLocationsInputBoundary { + private final SuggestedLocationsOutputBoundary placePresenter; + + public SuggestedLocationsInteractor(SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary) { + this.placePresenter = suggestedLocationsOutputBoundary; + } + + @Override + public void execute(SuggestedLocationsInputData suggestedLocationsInputData) throws DataAccessException { + final SuggestedLocationsOutputData suggestedLocationsOutputData = new SuggestedLocationsOutputData( + suggestedLocationsInputData.getSuggestedLocations(), false); + placePresenter.prepareSuccessView(suggestedLocationsOutputData); + } +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputBoundary.java new file mode 100644 index 000000000..e66cb9d0f --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputBoundary.java @@ -0,0 +1,20 @@ +package use_case.suggested_locations; + +/** + * The output boundary for the Suggested Locations Use Case. + */ +public interface SuggestedLocationsOutputBoundary { + /** + * Prepares the success view for the Suggest Locations Use Case. + * + * @param outputData the output data + */ + void prepareSuccessView(SuggestedLocationsOutputData outputData); + + /** + * Prepares the failure view for the SuggestLocations Use Case. + * + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java new file mode 100644 index 000000000..f9149d354 --- /dev/null +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -0,0 +1,23 @@ +package use_case.suggested_locations; + +import java.util.List; + +import entity.Place; + +/** + * Output Data for the Suggested Locations Use Case. + */ +public class SuggestedLocationsOutputData { + + private final List suggestedLocations; + private final boolean useCaseFailed; + + public SuggestedLocationsOutputData(List suggestedLocations, boolean useCaseFailed) { + this.suggestedLocations = suggestedLocations; + this.useCaseFailed = useCaseFailed; + } + + public List getSuggestedLocations() { + return suggestedLocations; + } +} From 03bc5a21bcfc3cdfa52ab16fd66eab02ed586c3e Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:22:17 -0500 Subject: [PATCH 077/113] Fixed SuggestedLocations presenter and controller. added case to main --- src/main/java/app/MainWithDB.java | 6 +-- .../SuggestedLocationsController.java | 29 ++++++++------- .../SuggestedLocationsPresenter.java | 37 +++++++++---------- .../java/view/SuggestedLocationsView.java | 12 +++--- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 7b463ebd4..a05cfae9e 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -48,9 +48,9 @@ public static void main(String[] args) { suggestedLocationsViewModel, locationDataAccessObject); views.add(locationView, locationView.getViewName()); -// final SuggestedLocationsView suggestedLocationsView = SuggestedLocationUseCaseFactory.create(viewManagerModel, -// suggestedLocationsViewModel, locationDataAccessObject); -// views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel, + suggestedLocationsViewModel); + views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index 23f4ba768..476a80164 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,29 +1,32 @@ package interface_adapter.suggestlocation; -import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.LocationsInputBoundary; -import use_case.suggest_locations.LocationsInputData; +import java.util.List; + +import entity.Place; +import use_case.DataAccessException; +import use_case.suggested_locations.SuggestedLocationsInputBoundary; +import use_case.suggested_locations.SuggestedLocationsInputData; /** * The SuggestedLocationsController class handles user input related to suggested locations. */ public class SuggestedLocationsController { - private final LocationsInputBoundary suggestLocationsInput; + private final SuggestedLocationsInputBoundary suggestedLocationsInteractor; - public SuggestedLocationsController(LocationsInputBoundary suggestLocationsInput) { - this.suggestLocationsInput = suggestLocationsInput; + public SuggestedLocationsController(SuggestedLocationsInputBoundary suggestedLocationsInteractor) { + this.suggestedLocationsInteractor = suggestedLocationsInteractor; } /** - * Executes the suggest locations operation. - * @param address the address to suggest locations for - * @param locationType the type of location to suggest + * Executes the suggested locations' operation. + * @param suggestedLocations the suggestedLocations produced. + * @throws DataAccessException if data cannot be accessed. */ - public void execute(String address, String locationType) throws DataAccessException { - final LocationsInputData suggestLocationInputData = new LocationsInputData( - address, locationType); + public void execute(List suggestedLocations) throws DataAccessException { + final SuggestedLocationsInputData suggestedLocationInputData = new SuggestedLocationsInputData( + suggestedLocations); - suggestLocationsInput.execute(suggestLocationInputData); + suggestedLocationsInteractor.execute(suggestedLocationInputData); } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 04a2b62ed..9670eaf5a 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,34 +1,30 @@ package interface_adapter.suggestlocation; import interface_adapter.ViewManagerModel; -import interface_adapter.location.LocationState; -import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.LocationsOutputBoundary; -import use_case.suggest_locations.LocationsOutputData; +import use_case.locations.LocationsOutputData; +import use_case.suggested_locations.SuggestedLocationsOutputBoundary; +import use_case.suggested_locations.SuggestedLocationsOutputData; /** * The presenter for the suggested locations use case. */ -public class SuggestedLocationsPresenter implements LocationsOutputBoundary { +public class SuggestedLocationsPresenter implements SuggestedLocationsOutputBoundary { private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; - private final LocationViewModel locationViewModel; public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel, - LocationViewModel locationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel) { this.viewManagerModel = viewManagerModel; this.suggestedLocationsViewModel = suggestedLocationsViewModel; - this.locationViewModel = locationsViewModel; } @Override - public void prepareSuccessView(LocationsOutputData response) { - // On success, switch to the logged in view. + public void prepareSuccessView(SuggestedLocationsOutputData response) { + // On success, switch to the TODO: next view. final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); - suggestedLocationsState.setSuggestedLocations(response.getLocations()); + suggestedLocationsState.setSuggestedLocations(response.getSuggestedLocations()); this.suggestedLocationsViewModel.setState(suggestedLocationsState); this.suggestedLocationsViewModel.firePropertyChanged(); @@ -38,14 +34,15 @@ public void prepareSuccessView(LocationsOutputData response) { @Override public void prepareFailView(String error) { - final LocationState locationState = locationViewModel.getState(); - locationState.setError(error); - locationViewModel.firePropertyChanged(); - } - - @Override - public void switchToSuggestedLocationsView() { - + final SuggestedLocationsState suggestedLocationState = suggestedLocationsViewModel.getState(); + suggestedLocationState.setError(error); + suggestedLocationsViewModel.firePropertyChanged(); } +// +// // change to switch to next view +// @Override +// public void switchToSuggestedLocationsView() { +// +// } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 8e55954dd..f3896bdab 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -22,22 +22,18 @@ */ public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { + private final String viewName = "Suggested Locations"; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; - private final CardLayout cardLayout; - private final JPanel parentPanel; private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, - SuggestedLocationsController suggestedLocationsController, - CardLayout cardLayout, JPanel parentPanel) { + SuggestedLocationsController suggestedLocationsController) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; - this.cardLayout = cardLayout; - this.parentPanel = parentPanel; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -79,4 +75,8 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); } + + public String getViewName() { + return viewName; + } } From 9707fdf0a80fdbe6f107e2f4274d4ad14cf769c7 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:23:24 -0500 Subject: [PATCH 078/113] Fixed some other files, got rid of switchToSuggestedView(), cuz that happens in execute already. --- src/main/java/app/LocationUseCaseFactory.java | 8 +++---- .../DBLocationDataAccessObject.java | 4 ++-- .../location/LocationController.java | 18 +++++++-------- .../location/LocationPresenter.java | 22 +++++++++++-------- .../DataAccessException.java | 2 +- .../LocationDataAccessInterface.java | 3 ++- .../LocationsInputBoundary.java | 13 +++++------ .../LocationsInputData.java | 2 +- .../LocationsInteractor.java | 12 +++++----- .../LocationsOutputBoundary.java | 10 ++++----- .../LocationsOutputData.java | 2 +- src/main/java/view/LocationView.java | 2 +- 12 files changed, 50 insertions(+), 48 deletions(-) rename src/main/java/use_case/{suggest_locations => }/DataAccessException.java (85%) rename src/main/java/use_case/{suggest_locations => locations}/LocationDataAccessInterface.java (89%) rename src/main/java/use_case/{suggest_locations => locations}/LocationsInputBoundary.java (67%) rename src/main/java/use_case/{suggest_locations => locations}/LocationsInputData.java (92%) rename src/main/java/use_case/{suggest_locations => locations}/LocationsInteractor.java (78%) rename src/main/java/use_case/{suggest_locations => locations}/LocationsOutputBoundary.java (77%) rename src/main/java/use_case/{suggest_locations => locations}/LocationsOutputData.java (92%) diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index 03be01576..899f8e188 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -5,10 +5,10 @@ import interface_adapter.location.LocationPresenter; import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; -import use_case.suggest_locations.LocationDataAccessInterface; -import use_case.suggest_locations.LocationsInputBoundary; -import use_case.suggest_locations.LocationsInteractor; -import use_case.suggest_locations.LocationsOutputBoundary; +import use_case.locations.LocationDataAccessInterface; +import use_case.locations.LocationsInputBoundary; +import use_case.locations.LocationsInteractor; +import use_case.locations.LocationsOutputBoundary; import view.LocationView; /** diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index e14473485..d4f65ffb7 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -11,8 +11,8 @@ import org.json.JSONException; import org.json.JSONObject; -import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.LocationDataAccessInterface; +import use_case.DataAccessException; +import use_case.locations.LocationDataAccessInterface; /** * The DAO for accessing places using Google Places API. diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 939e885e1..9d964dd80 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -1,8 +1,8 @@ package interface_adapter.location; -import use_case.suggest_locations.DataAccessException; -import use_case.suggest_locations.LocationsInputBoundary; -import use_case.suggest_locations.LocationsInputData; +import use_case.DataAccessException; +import use_case.locations.LocationsInputBoundary; +import use_case.locations.LocationsInputData; /** * The LocationController class handles user input related to locations. @@ -33,10 +33,10 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(locationInputData); } - /** - * Switches to the suggested locations view. - */ - public void switchToSuggestedLocationsView() { - locationInput.switchToSuggestedLocationsView(); - } +// /** +// * Switches to the suggested locations view. +// */ +// public void switchToSuggestedLocationsView() { +// locationInput.switchToSuggestedLocationsView(); +// } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index eaa69a0e1..2b9e2cd8f 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -3,8 +3,8 @@ import interface_adapter.ViewManagerModel; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; -import use_case.suggest_locations.LocationsOutputBoundary; -import use_case.suggest_locations.LocationsOutputData; +import use_case.locations.LocationsOutputBoundary; +import use_case.locations.LocationsOutputData; /** * The presenter for our Note viewing and editing program. @@ -35,12 +35,16 @@ public void prepareSuccessView(LocationsOutputData response) { @Override public void prepareFailView(String error) { - throw new LocationSearchFailed(error); - } - - @Override - public void switchToSuggestedLocationsView() { - viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); - viewManagerModel.firePropertyChanged(); + final LocationState locationState = locationViewModel.getState(); + locationState.setError(error); + locationViewModel.firePropertyChanged(); } } + + // commenting out bc i dont think we need it; view switches in execute (see CAUSerLogin) +// @Override +// public void switchToSuggestedLocationsView() { +// viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); +// viewManagerModel.firePropertyChanged(); +// } +// diff --git a/src/main/java/use_case/suggest_locations/DataAccessException.java b/src/main/java/use_case/DataAccessException.java similarity index 85% rename from src/main/java/use_case/suggest_locations/DataAccessException.java rename to src/main/java/use_case/DataAccessException.java index 911c948eb..59cf779b3 100644 --- a/src/main/java/use_case/suggest_locations/DataAccessException.java +++ b/src/main/java/use_case/DataAccessException.java @@ -1,4 +1,4 @@ -package use_case.suggest_locations; +package use_case; /** * Exception thrown when there is an error with accessing data. diff --git a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java b/src/main/java/use_case/locations/LocationDataAccessInterface.java similarity index 89% rename from src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java rename to src/main/java/use_case/locations/LocationDataAccessInterface.java index 720f6ddb5..b6a40331c 100644 --- a/src/main/java/use_case/suggest_locations/LocationDataAccessInterface.java +++ b/src/main/java/use_case/locations/LocationDataAccessInterface.java @@ -1,8 +1,9 @@ -package use_case.suggest_locations; +package use_case.locations; import java.util.List; import entity.Place; +import use_case.DataAccessException; /** * Interface for the LocationDAO. It consists of methods for diff --git a/src/main/java/use_case/suggest_locations/LocationsInputBoundary.java b/src/main/java/use_case/locations/LocationsInputBoundary.java similarity index 67% rename from src/main/java/use_case/suggest_locations/LocationsInputBoundary.java rename to src/main/java/use_case/locations/LocationsInputBoundary.java index ed291e634..96d2b9c63 100644 --- a/src/main/java/use_case/suggest_locations/LocationsInputBoundary.java +++ b/src/main/java/use_case/locations/LocationsInputBoundary.java @@ -1,4 +1,6 @@ -package use_case.suggest_locations; +package use_case.locations; + +import use_case.DataAccessException; /** * The Suggest Locations Use Case. @@ -6,12 +8,9 @@ public interface LocationsInputBoundary { /** * Execute the Suggest Locations Use Case. + * * @param locationsInputData the input data for this use case + * @throws DataAccessException if data cannot be accessed at any time */ void execute(LocationsInputData locationsInputData) throws DataAccessException; - - /** - * Switch to the Suggested Locations View. - */ - void switchToSuggestedLocationsView(); -} +} \ No newline at end of file diff --git a/src/main/java/use_case/suggest_locations/LocationsInputData.java b/src/main/java/use_case/locations/LocationsInputData.java similarity index 92% rename from src/main/java/use_case/suggest_locations/LocationsInputData.java rename to src/main/java/use_case/locations/LocationsInputData.java index 3317a6409..2bbd46878 100644 --- a/src/main/java/use_case/suggest_locations/LocationsInputData.java +++ b/src/main/java/use_case/locations/LocationsInputData.java @@ -1,4 +1,4 @@ -package use_case.suggest_locations; +package use_case.locations; /** * The input data for the Suggest Locations Use Case. diff --git a/src/main/java/use_case/suggest_locations/LocationsInteractor.java b/src/main/java/use_case/locations/LocationsInteractor.java similarity index 78% rename from src/main/java/use_case/suggest_locations/LocationsInteractor.java rename to src/main/java/use_case/locations/LocationsInteractor.java index d3c03c5ed..26e0e4ce5 100644 --- a/src/main/java/use_case/suggest_locations/LocationsInteractor.java +++ b/src/main/java/use_case/locations/LocationsInteractor.java @@ -1,6 +1,8 @@ -package use_case.suggest_locations; +package use_case.locations; +import use_case.DataAccessException; + /** * The Suggest Locations Interactor. */ @@ -16,14 +18,10 @@ public LocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceData @Override public void execute(LocationsInputData locationsInputData) throws DataAccessException { - final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject.searchLocation(locationsInputData.getAddress(), + final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject.searchLocation( + locationsInputData.getAddress(), locationsInputData.getLocationType()), false); placePresenter.prepareSuccessView(locationsOutputData); } - - @Override - public void switchToSuggestedLocationsView() { - placePresenter.switchToSuggestedLocationsView(); - } } diff --git a/src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java b/src/main/java/use_case/locations/LocationsOutputBoundary.java similarity index 77% rename from src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java rename to src/main/java/use_case/locations/LocationsOutputBoundary.java index b08b1ff28..2be723519 100644 --- a/src/main/java/use_case/suggest_locations/LocationsOutputBoundary.java +++ b/src/main/java/use_case/locations/LocationsOutputBoundary.java @@ -1,4 +1,4 @@ -package use_case.suggest_locations; +package use_case.locations; /** * The output boundary for the Suggest Locations Use Case. @@ -16,8 +16,8 @@ public interface LocationsOutputBoundary { */ void prepareFailView(String errorMessage); - /** - * Switches to the Suggested Locations View. - */ - void switchToSuggestedLocationsView(); +// /** +// * Switches to the Suggested Locations View. +// */ +// void switchToSuggestedLocationsView(); } diff --git a/src/main/java/use_case/suggest_locations/LocationsOutputData.java b/src/main/java/use_case/locations/LocationsOutputData.java similarity index 92% rename from src/main/java/use_case/suggest_locations/LocationsOutputData.java rename to src/main/java/use_case/locations/LocationsOutputData.java index be93f75a7..01d04795f 100644 --- a/src/main/java/use_case/suggest_locations/LocationsOutputData.java +++ b/src/main/java/use_case/locations/LocationsOutputData.java @@ -1,4 +1,4 @@ -package use_case.suggest_locations; +package use_case.locations; import java.util.List; diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 990d6dea0..13f565f1f 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -13,7 +13,7 @@ import interface_adapter.location.LocationController; import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; -import use_case.suggest_locations.DataAccessException; +import use_case.DataAccessException; /** * The View for when the user is viewing a location in the program. From d8ebe270fc5ba832b99493cef3cfd47e2dc060f3 Mon Sep 17 00:00:00 2001 From: teddy Date: Sun, 24 Nov 2024 19:54:43 -0500 Subject: [PATCH 079/113] changed view --- .../location/LocationPresenter.java | 12 ++-- .../SuggestedLocationsPresenter.java | 2 +- src/main/java/view/LocationView.java | 65 +++++-------------- .../java/view/SuggestedLocationsView.java | 18 +++-- 4 files changed, 37 insertions(+), 60 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 2b9e2cd8f..948d0eff6 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -7,7 +7,7 @@ import use_case.locations.LocationsOutputData; /** - * The presenter for our Note viewing and editing program. + * The Presenter for the Location Use Case. */ public class LocationPresenter implements LocationsOutputBoundary { @@ -15,7 +15,9 @@ public class LocationPresenter implements LocationsOutputBoundary { private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final ViewManagerModel viewManagerModel; - public LocationPresenter(LocationViewModel locationViewModel, SuggestedLocationsViewModel suggestedLocationsViewModel, ViewManagerModel viewManagerModel) { + public LocationPresenter(LocationViewModel locationViewModel, + SuggestedLocationsViewModel suggestedLocationsViewModel, + ViewManagerModel viewManagerModel) { this.locationViewModel = locationViewModel; this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.viewManagerModel = viewManagerModel; @@ -27,10 +29,10 @@ public void prepareSuccessView(LocationsOutputData response) { final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); suggestedLocationsState.setSuggestedLocations(response.getLocations()); this.suggestedLocationsViewModel.setState(suggestedLocationsState); - suggestedLocationsViewModel.firePropertyChanged(); + this.suggestedLocationsViewModel.firePropertyChanged(); - viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); - viewManagerModel.firePropertyChanged(); + this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); } @Override diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 9670eaf5a..8c9ad8eb6 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -21,7 +21,7 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { - // On success, switch to the TODO: next view. + // On success, switch to the suggested locations view. final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); suggestedLocationsState.setSuggestedLocations(response.getSuggestedLocations()); diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 13f565f1f..9823f2608 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -55,6 +55,10 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca suggestLocationsButton.addActionListener(this); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(title); + this.add(addressInfo); + this.add(locationTypePanel); + this.add(buttons); addressField.getDocument().addDocumentListener(new DocumentListener() { @@ -116,63 +120,26 @@ public void changedUpdate(DocumentEvent e) { }); } - suggestLocationsButton.addActionListener( - // This creates an anonymous subclass of ActionListener and instantiates it. - evt -> { - if (evt.getSource().equals(suggestLocationsButton)) { - final LocationState currentState = locationViewModel.getState(); - - try { - this.locationController.execute( - currentState.getAddress(), - currentState.getLocationType() - ); - } - catch (DataAccessException e) { - throw new RuntimeException(e); - } - } - } - ); - - suggestLocationsButton.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute( - currentState.getAddress(), - currentState.getLocationType() - ); - locationController.switchToSuggestedLocationsView(); - } - catch (DataAccessException ex) { - throw new RuntimeException(ex); - } - - } + suggestLocationsButton.addActionListener(evt -> { + if (evt.getSource().equals(suggestLocationsButton)) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } catch (DataAccessException e) { + throw new RuntimeException(e); } - ); - - this.add(title); - this.add(addressInfo); - this.add(locationTypePanel); - this.add(buttons); - + } + }); } + @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { final LocationState currentState = locationViewModel.getState(); try { - this.locationController.execute( - currentState.getAddress(), - currentState.getLocationType() - ); - } - catch (DataAccessException e) { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } catch (DataAccessException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index f3896bdab..03b262fde 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -1,18 +1,20 @@ package view; -import java.awt.CardLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.List; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import entity.Place; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -55,7 +57,7 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { - cardLayout.show(parentPanel, "locationView"); + // Handle new search button click } } @@ -68,9 +70,15 @@ public void propertyChange(PropertyChangeEvent evt) { private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); - for (Place location : state.getSuggestedLocations()) { - suggestedLocationsPanel.add(new JLabel(location.getName())); - suggestedLocationsPanel.add(new JLabel(location.getAddress())); + List suggestedLocations = state.getSuggestedLocations(); + if (suggestedLocations != null) { + for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { + final Place location = suggestedLocations.get(i); + suggestedLocationsPanel.add(new JLabel(location.getName())); + suggestedLocationsPanel.add(new JLabel(location.getAddress())); + } + } else { + JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); From 92217695731885cd2d90afc8655b03ccf4c7dede Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Mon, 25 Nov 2024 12:09:03 -0500 Subject: [PATCH 080/113] fixed api stuff --- src/main/java/data_access/DBLocationDataAccessObject.java | 2 +- .../suggestlocation/SuggestedLocationsState.java | 3 ++- src/main/java/view/SuggestedLocationsView.java | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index d4f65ffb7..95ab19e11 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -64,7 +64,7 @@ public List searchLocation(String address, String locationType) throws Da } final String placesString = places.toString(); - final String[] locationsList = placesString.split("<:>"); + final String[] locationsList = placesString.split("<"); final List suggestedPlaces = new ArrayList<>(); for (String location : locationsList) { final Place place = placeFactory.create(location.split(">")[1], location.split(">")[0]); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java index 3e962d719..0221540c9 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java @@ -1,5 +1,6 @@ package interface_adapter.suggestlocation; +import java.util.ArrayList; import java.util.List; import entity.Place; @@ -9,7 +10,7 @@ */ public class SuggestedLocationsState { - private List suggestedLocations; + private List suggestedLocations = new ArrayList<>(); private String error; public List getSuggestedLocations() { diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 03b262fde..6577c7f78 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -71,6 +71,7 @@ public void propertyChange(PropertyChangeEvent evt) { private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); List suggestedLocations = state.getSuggestedLocations(); + System.out.println(suggestedLocations.size()); if (suggestedLocations != null) { for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); From 53bfddc9f0dd40b2103c5ccec0d785753f0258f2 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:11:27 -0500 Subject: [PATCH 081/113] FINALLY FIXED TEAM USE CASE --- .../java/interface_adapter/location/LocationViewModel.java | 2 +- .../suggestlocation/SuggestedLocationsViewModel.java | 2 +- src/main/java/view/SuggestedLocationsView.java | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java index ef089e6fb..6af84c69b 100644 --- a/src/main/java/interface_adapter/location/LocationViewModel.java +++ b/src/main/java/interface_adapter/location/LocationViewModel.java @@ -7,7 +7,7 @@ */ public class LocationViewModel extends ViewModel { public LocationViewModel() { - super("location"); + super("Search Locations"); setState(new LocationState()); } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java index 979ecfe99..a17bb17fd 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java @@ -7,7 +7,7 @@ */ public class SuggestedLocationsViewModel extends ViewModel { public SuggestedLocationsViewModel() { - super("suggestedLocations"); + super("Suggested Locations"); setState(new SuggestedLocationsState()); } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 6577c7f78..9c2c08db8 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -14,7 +14,6 @@ import javax.swing.JPanel; import entity.Place; -import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -70,7 +69,7 @@ public void propertyChange(PropertyChangeEvent evt) { private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); - List suggestedLocations = state.getSuggestedLocations(); + final List suggestedLocations = state.getSuggestedLocations(); System.out.println(suggestedLocations.size()); if (suggestedLocations != null) { for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { From 1c492fdefc53a281e551a0fccc8dea945d0883ff Mon Sep 17 00:00:00 2001 From: teddy Date: Thu, 28 Nov 2024 18:08:48 -0500 Subject: [PATCH 082/113] modified view to have better layout and added checkbox implementation to use in next view --- .../java/view/SuggestedLocationsView.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 9c2c08db8..332e0b980 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -1,17 +1,14 @@ package view; -import java.awt.Component; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.ArrayList; import java.util.List; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; +import javax.swing.*; import entity.Place; import interface_adapter.suggestlocation.SuggestedLocationsController; @@ -29,6 +26,7 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; + private final List selectedLocations; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, SuggestedLocationsController suggestedLocationsController) { @@ -45,6 +43,8 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.newSearchButton = new JButton("New Search"); newSearchButton.addActionListener(this); + this.selectedLocations = new ArrayList<>(); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(suggestedLocationsPanel); @@ -70,21 +70,39 @@ public void propertyChange(PropertyChangeEvent evt) { private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); final List suggestedLocations = state.getSuggestedLocations(); - System.out.println(suggestedLocations.size()); if (suggestedLocations != null) { for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); - suggestedLocationsPanel.add(new JLabel(location.getName())); - suggestedLocationsPanel.add(new JLabel(location.getAddress())); + JPanel locationPanel = new JPanel(); + locationPanel.setLayout(new BoxLayout(locationPanel, BoxLayout.Y_AXIS)); + JCheckBox checkBox = new JCheckBox(); + checkBox.addActionListener(e -> { + if (checkBox.isSelected()) { + selectedLocations.add(location); + } else { + selectedLocations.remove(location); + } + }); + locationPanel.add(checkBox); + locationPanel.add(new JLabel(location.getName())); + locationPanel.add(new JLabel(location.getAddress())); + locationPanel.add(Box.createVerticalStrut(10)); + suggestedLocationsPanel.add(locationPanel); } } else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); + this.setPreferredSize(new Dimension(800, 1200)); + + } + + public List getSelectedLocations() { + return selectedLocations; } public String getViewName() { return viewName; } -} +} \ No newline at end of file From 75a726b5aa51bbcb2fee6d2608e742c99a815434 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sat, 30 Nov 2024 11:46:51 -0500 Subject: [PATCH 083/113] Individual use case - custom profile creation --- src/main/java/app/MainWithDB.java | 4 + src/main/java/app/UserUseCaseFactory.java | 39 ++++++++ .../data_access/DBUserDataAccessObject.java | 28 ++++++ src/main/java/entity/User.java | 10 ++ src/main/java/entity/UserFactory.java | 23 +++++ .../user/UserController.java | 31 ++++++ .../interface_adapter/user/UserPresenter.java | 43 +++++++++ .../interface_adapter/user/UserState.java | 37 ++++++++ .../interface_adapter/user/UserViewModel.java | 13 +++ .../user/UserDataAccessInterface.java | 13 +++ .../user/UserProfileInputBoundary.java | 16 ++++ .../use_case/user/UserProfileInputData.java | 30 ++++++ .../use_case/user/UserProfileInteractor.java | 33 +++++++ .../user/UserProfileOutputBoundary.java | 12 +++ src/main/java/view/UserProfileView.java | 95 +++++++++++++++++++ 15 files changed, 427 insertions(+) create mode 100644 src/main/java/app/UserUseCaseFactory.java create mode 100644 src/main/java/data_access/DBUserDataAccessObject.java create mode 100644 src/main/java/entity/UserFactory.java create mode 100644 src/main/java/interface_adapter/user/UserController.java create mode 100644 src/main/java/interface_adapter/user/UserPresenter.java create mode 100644 src/main/java/interface_adapter/user/UserState.java create mode 100644 src/main/java/interface_adapter/user/UserViewModel.java create mode 100644 src/main/java/use_case/user/UserDataAccessInterface.java create mode 100644 src/main/java/use_case/user/UserProfileInputBoundary.java create mode 100644 src/main/java/use_case/user/UserProfileInputData.java create mode 100644 src/main/java/use_case/user/UserProfileInteractor.java create mode 100644 src/main/java/use_case/user/UserProfileOutputBoundary.java create mode 100644 src/main/java/view/UserProfileView.java diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index a05cfae9e..1c336e0e6 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -7,6 +7,7 @@ import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import view.LocationView; import view.SuggestedLocationsView; +import view.UserProfileView; import view.ViewManager; import javax.swing.*; @@ -52,6 +53,9 @@ public static void main(String[] args) { suggestedLocationsViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final UserProfileView userProfileView = UserUseCaseFactory.create(viewManagerModel); + views.add(userProfileView, "User Profile"); + viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/app/UserUseCaseFactory.java b/src/main/java/app/UserUseCaseFactory.java new file mode 100644 index 000000000..1a8d36b29 --- /dev/null +++ b/src/main/java/app/UserUseCaseFactory.java @@ -0,0 +1,39 @@ +package app; + +import data_access.DBUserDataAccessObject; +import entity.UserFactory; +import interface_adapter.ViewManagerModel; +import interface_adapter.user.UserController; +import interface_adapter.user.UserPresenter; +import interface_adapter.user.UserViewModel; +import use_case.user.UserProfileInputBoundary; +import use_case.user.UserProfileInteractor; +import view.UserProfileView; + +/** + * This class contains the static factory function for creating a user use case. + */ +public class UserUseCaseFactory { + + private UserUseCaseFactory() { + // Prevent instantiation + } + + /** + * Factory function for creating the UserProfileView. + * + * @param viewManagerModel the ViewManagerModel to inject + * @return the UserProfileView created for the provided input classes. + */ + public static UserProfileView create(ViewManagerModel viewManagerModel) { + final DBUserDataAccessObject userDataAccess = new DBUserDataAccessObject(); + final UserViewModel userViewModel = new UserViewModel(); + final UserPresenter userPresenter = new UserPresenter(viewManagerModel, userViewModel); + final UserFactory userFactory = new UserFactory(); + final UserProfileInputBoundary interactor = new UserProfileInteractor( + userDataAccess, userPresenter, userFactory); + final UserController userController = new UserController(interactor); + + return new UserProfileView(userController, userViewModel); + } +} diff --git a/src/main/java/data_access/DBUserDataAccessObject.java b/src/main/java/data_access/DBUserDataAccessObject.java new file mode 100644 index 000000000..c69b125f6 --- /dev/null +++ b/src/main/java/data_access/DBUserDataAccessObject.java @@ -0,0 +1,28 @@ +package data_access; + +import java.util.HashMap; +import java.util.Map; + +import entity.User; +import use_case.DataAccessException; +import use_case.user.UserDataAccessInterface; + +/** + * The DAO for user data. + */ +public class DBUserDataAccessObject implements UserDataAccessInterface { + private final Map userStorage = new HashMap<>(); + + @Override + public User findUserByName(String name) throws DataAccessException { + if (!userStorage.containsKey(name)) { + throw new DataAccessException("User not found"); + } + return userStorage.get(name); + } + + @Override + public void saveUser(User user) { + userStorage.put(user.getName(), user); + } +} diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index e0c57e9a6..3a2463e0d 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -1,5 +1,7 @@ package entity; +import java.util.List; + /** * The representation of a password-protected user for our program. */ @@ -7,6 +9,7 @@ public class User { private final String name; private final String password; + private List interests; public User(String name, String password) { this.name = name; @@ -21,4 +24,11 @@ public String getPassword() { return password; } + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } } diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java new file mode 100644 index 000000000..592e3604a --- /dev/null +++ b/src/main/java/entity/UserFactory.java @@ -0,0 +1,23 @@ +package entity; + +import java.util.List; + +/** + * Factory for creating User objects. + */ +public class UserFactory { + + /** + * Creates a new User object. + * + * @param name the name of the user + * @param password the password of the user + * @param interests the interests of the user + * @return the new User object + */ + public User create(String name, String password, List interests) { + final User user = new User(name, password); + user.setInterests(interests); + return user; + } +} diff --git a/src/main/java/interface_adapter/user/UserController.java b/src/main/java/interface_adapter/user/UserController.java new file mode 100644 index 000000000..cdc6ddfe7 --- /dev/null +++ b/src/main/java/interface_adapter/user/UserController.java @@ -0,0 +1,31 @@ +package interface_adapter.user; + +import java.util.List; + +import use_case.DataAccessException; +import use_case.user.UserProfileInputBoundary; +import use_case.user.UserProfileInputData; + +/** + * Controller for creating a user profile. + */ +public class UserController { + private final UserProfileInputBoundary interactor; + + public UserController(UserProfileInputBoundary interactor) { + this.interactor = interactor; + } + + /** + * Creates a new user profile. + * + * @param username the username of the user + * @param password the password of the user + * @param interests the interests of the user + * @throws DataAccessException if the user profile can not be created for any reason + */ + public void createUser(String username, String password, List interests) throws DataAccessException { + final UserProfileInputData inputData = new UserProfileInputData(username, password, interests); + interactor.createUser(inputData); + } +} diff --git a/src/main/java/interface_adapter/user/UserPresenter.java b/src/main/java/interface_adapter/user/UserPresenter.java new file mode 100644 index 000000000..c7e5e5e3f --- /dev/null +++ b/src/main/java/interface_adapter/user/UserPresenter.java @@ -0,0 +1,43 @@ +package interface_adapter.user; + +import entity.User; +import interface_adapter.ViewManagerModel; +import use_case.user.UserProfileOutputBoundary; + +/** + * Presenter for user profile creation. + */ +public class UserPresenter implements UserProfileOutputBoundary { + private final ViewManagerModel viewManagerModel; + private final UserViewModel userViewModel; + + public UserPresenter(ViewManagerModel viewManagerModel, UserViewModel userViewModel) { + this.viewManagerModel = viewManagerModel; + this.userViewModel = userViewModel; + } + + @Override + public void prepareSuccessView(User user) { + final UserState userState = new UserState(); + userState.setUsername(user.getName()); + userState.setPassword(user.getPassword()); + userState.setInterests(user.getInterests()); + + userViewModel.setState(userState); + userViewModel.firePropertyChanged(); + + // Need to implement the login view + viewManagerModel.setState("Login"); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + UserState userState = userViewModel.getState(); + if (userState == null) { + userState = new UserState(); + } + userViewModel.setState(userState); + userViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/user/UserState.java b/src/main/java/interface_adapter/user/UserState.java new file mode 100644 index 000000000..4a72b6e1f --- /dev/null +++ b/src/main/java/interface_adapter/user/UserState.java @@ -0,0 +1,37 @@ +package interface_adapter.user; + +import java.util.List; + +/** + * The state representing user profile-related data. + */ +public class UserState { + + private String username = ""; + private String password = ""; + private List interests; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } +} diff --git a/src/main/java/interface_adapter/user/UserViewModel.java b/src/main/java/interface_adapter/user/UserViewModel.java new file mode 100644 index 000000000..3e6f810f4 --- /dev/null +++ b/src/main/java/interface_adapter/user/UserViewModel.java @@ -0,0 +1,13 @@ +package interface_adapter.user; + +import interface_adapter.ViewModel; + +/** + * View model for the user profile. + */ +public class UserViewModel extends ViewModel { + public UserViewModel() { + super("User Profile"); + setState(null); + } +} diff --git a/src/main/java/use_case/user/UserDataAccessInterface.java b/src/main/java/use_case/user/UserDataAccessInterface.java new file mode 100644 index 000000000..948a76d3a --- /dev/null +++ b/src/main/java/use_case/user/UserDataAccessInterface.java @@ -0,0 +1,13 @@ +package use_case.user; + +import entity.User; +import use_case.DataAccessException; + +/** + * Interface for accessing user data. + */ +public interface UserDataAccessInterface { + User findUserByName(String name) throws DataAccessException; + + void saveUser(User user) throws DataAccessException; +} diff --git a/src/main/java/use_case/user/UserProfileInputBoundary.java b/src/main/java/use_case/user/UserProfileInputBoundary.java new file mode 100644 index 000000000..cb3ae153d --- /dev/null +++ b/src/main/java/use_case/user/UserProfileInputBoundary.java @@ -0,0 +1,16 @@ +package use_case.user; + +import use_case.DataAccessException; + +/** + * Input boundary for creating a user profile. + */ +public interface UserProfileInputBoundary { + /** + * Creates a new user profile. + * + * @param inputData the input data for the user profile + * @throws DataAccessException if the user profile can not be created for any reason + */ + void createUser(UserProfileInputData inputData) throws DataAccessException; +} diff --git a/src/main/java/use_case/user/UserProfileInputData.java b/src/main/java/use_case/user/UserProfileInputData.java new file mode 100644 index 000000000..9492cd9b3 --- /dev/null +++ b/src/main/java/use_case/user/UserProfileInputData.java @@ -0,0 +1,30 @@ +package use_case.user; + +import java.util.List; + +/** + * The input data for creating a user profile. + */ +public class UserProfileInputData { + private final String username; + private final String password; + private final List interests; + + public UserProfileInputData(String username, String password, List interests) { + this.username = username; + this.password = password; + this.interests = interests; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public List getInterests() { + return interests; + } +} diff --git a/src/main/java/use_case/user/UserProfileInteractor.java b/src/main/java/use_case/user/UserProfileInteractor.java new file mode 100644 index 000000000..7f7f08935 --- /dev/null +++ b/src/main/java/use_case/user/UserProfileInteractor.java @@ -0,0 +1,33 @@ +package use_case.user; + +import entity.User; +import entity.UserFactory; +import use_case.DataAccessException; + +/** + * Interactor for creating a user profile. + */ +public class UserProfileInteractor implements UserProfileInputBoundary { + private final UserDataAccessInterface userDataAccess; + private final UserProfileOutputBoundary presenter; + private final UserFactory userFactory; + + public UserProfileInteractor(UserDataAccessInterface userDataAccess, UserProfileOutputBoundary presenter, + UserFactory userFactory) { + this.userDataAccess = userDataAccess; + this.presenter = presenter; + this.userFactory = userFactory; + } + + @Override + public void createUser(UserProfileInputData inputData) { + try { + User user = userFactory.create(inputData.getUsername(), inputData.getPassword(), inputData.getInterests()); + userDataAccess.saveUser(user); + presenter.prepareSuccessView(user); + } + catch (DataAccessException e) { + presenter.prepareFailView(e.getMessage()); + } + } +} diff --git a/src/main/java/use_case/user/UserProfileOutputBoundary.java b/src/main/java/use_case/user/UserProfileOutputBoundary.java new file mode 100644 index 000000000..424cf51cd --- /dev/null +++ b/src/main/java/use_case/user/UserProfileOutputBoundary.java @@ -0,0 +1,12 @@ +package use_case.user; + +import entity.User; + +/** + * Output boundary for the user profile use case. + */ +public interface UserProfileOutputBoundary { + void prepareSuccessView(User user); + + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/view/UserProfileView.java b/src/main/java/view/UserProfileView.java new file mode 100644 index 000000000..696f10775 --- /dev/null +++ b/src/main/java/view/UserProfileView.java @@ -0,0 +1,95 @@ +package view; + +import java.awt.Dimension; +import java.util.Arrays; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; + +import interface_adapter.user.UserController; +import interface_adapter.user.UserState; +import interface_adapter.user.UserViewModel; +import use_case.DataAccessException; + +/** + * User profile view for creating a user profile. + */ +public class UserProfileView extends JPanel { + + private final JTextField usernameField; + private final JPasswordField passwordField; + private final JComboBox interestsBox1; + private final JComboBox interestsBox2; + private final JComboBox interestsBox3; + private final JButton createProfileButton; + + public UserProfileView(UserController controller, UserViewModel userViewModel) { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setPreferredSize(new Dimension(400, 300)); + + usernameField = new JTextField(20); + passwordField = new JPasswordField(20); + interestsBox1 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); + interestsBox2 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); + interestsBox3 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); + createProfileButton = new JButton("Create Profile"); + + addComponents(); + + userViewModel.addPropertyChangeListener(evt -> handleStateChange(userViewModel.getState())); + + createProfileButton.addActionListener(evt -> handleCreateProfileAction(controller)); + } + + /** + * Adds UI components to the panel. + */ + private void addComponents() { + add(new JLabel("Username:")); + add(usernameField); + add(new JLabel("Password:")); + add(passwordField); + add(new JLabel("Select up to 3 Interests:")); + add(interestsBox1); + add(interestsBox2); + add(interestsBox3); + add(createProfileButton); + } + + /** + * Handles the action of creating a user profile. + * + * @param controller The controller to manage user creation. + */ + private void handleCreateProfileAction(UserController controller) { + final String username = usernameField.getText(); + final String password = new String(passwordField.getPassword()); + try { + controller.createUser(username, password, Arrays.asList( + interestsBox1.getSelectedItem().toString(), + interestsBox2.getSelectedItem().toString(), + interestsBox3.getSelectedItem().toString() + )); + } + catch (DataAccessException dataAccessException) { + System.err.println("Error creating user: " + dataAccessException.getMessage()); + } + } + + /** + * Handles changes in the user profile state. + * + * @param state The new user state. + */ + private void handleStateChange(UserState state) { + if (state != null) { + usernameField.setText(state.getUsername()); + passwordField.setText(""); + } + } +} From ff909c06417903b2d1f4db9fe48cb5d510bb88b3 Mon Sep 17 00:00:00 2001 From: teddy Date: Sat, 30 Nov 2024 17:05:38 -0500 Subject: [PATCH 084/113] added SavedPlace --- .../DBLocationDataAccessObject.java | 3 -- src/main/java/entity/SavedPlace.java | 38 +++++++++++++++++++ src/main/java/entity/SavedPlaceFactory.java | 12 ++++++ src/main/java/entity/SuggestedPlace.java | 1 + src/main/java/entity/User.java | 10 ++++- src/main/java/view/LocationView.java | 3 +- .../java/view/SuggestedLocationsView.java | 7 +--- 7 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 src/main/java/entity/SavedPlace.java create mode 100644 src/main/java/entity/SavedPlaceFactory.java diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 95ab19e11..6957731ed 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -18,14 +18,11 @@ * The DAO for accessing places using Google Places API. */ public class DBLocationDataAccessObject implements LocationDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final int CREDENTIAL_ERROR = 403; private static final String API_HEADER = "X-Goog-Api-Key"; private static final String API_FIELD = "X-Goog-FieldMask"; private static final String FIELDS = "places.displayName,places.formattedAddress"; private static final String CONTENT_TYPE_LABEL = "Content-Type"; private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String STATUS_CODE_LABEL = "code"; private static final String API_KEY = System.getenv("API_KEY"); private final PlaceFactory placeFactory; diff --git a/src/main/java/entity/SavedPlace.java b/src/main/java/entity/SavedPlace.java new file mode 100644 index 000000000..9b74e9cf0 --- /dev/null +++ b/src/main/java/entity/SavedPlace.java @@ -0,0 +1,38 @@ + +package entity; + +/** + * An implementation of the Place interface. + */ +public class SavedPlace implements Place { + + private final String name; + private final String address; + private final String review; + private final boolean rating; + + public SavedPlace(String name, String address, String review, boolean rating) { + this.name = name; + this.address = address; + this.review = review; + this.rating = rating; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getAddress() { + return address; + } + + public String getReview() { + return review; + } + + public boolean getRating() { + return rating; + } +} \ No newline at end of file diff --git a/src/main/java/entity/SavedPlaceFactory.java b/src/main/java/entity/SavedPlaceFactory.java new file mode 100644 index 000000000..722093cf8 --- /dev/null +++ b/src/main/java/entity/SavedPlaceFactory.java @@ -0,0 +1,12 @@ +package entity; + +/** + * Factory for creating SuggestedPlace objects. + */ +public class SavedPlaceFactory implements PlaceFactory { + + @Override + public Place create(String name, String address) { + return new SavedPlace(name, address, "", true); + } +} diff --git a/src/main/java/entity/SuggestedPlace.java b/src/main/java/entity/SuggestedPlace.java index 83cf69b52..e3b092b53 100644 --- a/src/main/java/entity/SuggestedPlace.java +++ b/src/main/java/entity/SuggestedPlace.java @@ -1,3 +1,4 @@ + package entity; /** diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index e0c57e9a6..f16678913 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -1,5 +1,8 @@ package entity; +import java.util.HashMap; +import java.util.List; + /** * The representation of a password-protected user for our program. */ @@ -7,10 +10,12 @@ public class User { private final String name; private final String password; + private final HashMap> savedPlaces; - public User(String name, String password) { + public User(String name, String password, HashMap> savedPlaces) { this.name = name; this.password = password; + this.savedPlaces = savedPlaces; } public String getName() { @@ -21,4 +26,7 @@ public String getPassword() { return password; } + public HashMap> getSavedPlaces() { + return savedPlaces; + } } diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 9823f2608..2ffabc063 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -1,6 +1,6 @@ package view; -import java.awt.Component; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; @@ -34,7 +34,6 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); this.locationController = locationController; - final JLabel title = new JLabel("Suggest Locations"); title.setAlignmentX(Component.CENTER_ALIGNMENT); diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 332e0b980..6f0641a1e 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -79,7 +79,8 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { checkBox.addActionListener(e -> { if (checkBox.isSelected()) { selectedLocations.add(location); - } else { + } + else { selectedLocations.remove(location); } }); @@ -98,10 +99,6 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { } - public List getSelectedLocations() { - return selectedLocations; - } - public String getViewName() { return viewName; } From 8283e558e41bb9035cdced78f02a2613660b8fe1 Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Sat, 30 Nov 2024 17:11:36 -0500 Subject: [PATCH 085/113] created filter and made action listener check which filter is selected before proceeding --- .../location/LocationController.java | 6 ++ src/main/java/view/LocationView.java | 60 +++++++++++++++---- .../java/view/SuggestedLocationsView.java | 12 ++-- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 9d964dd80..3742b54ed 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -26,6 +26,8 @@ public LocationController(LocationsInputBoundary locationInteractor) { * @param locationType the type of location to save or refresh * @throws DataAccessException if data cannot be accessed */ + + public void execute(String address, String locationType) throws DataAccessException { final LocationsInputData locationInputData = new LocationsInputData( address, locationType); @@ -33,6 +35,10 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(locationInputData); } + public void clearSaved() { + + } + // /** // * Switches to the suggested locations view. // */ diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 9823f2608..00896b1af 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -30,6 +30,9 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final JButton suggestLocationsButton; + private final JComboBox filtersDropDown; + private String currentFilter = ""; + public LocationView(LocationViewModel locationViewModel, LocationController locationController) { this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); @@ -51,9 +54,13 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca final JPanel buttons = new JPanel(); suggestLocationsButton = new JButton("Suggest Locations"); buttons.add(suggestLocationsButton); - + final JLabel filterLabel = new JLabel("Filters:"); + final String[] filters = {"None", "Remove Disliked Locations", "Removed Saved Locations"}; + filtersDropDown = new JComboBox<>(filters); + buttons.add(filterLabel); + buttons.add(filtersDropDown); suggestLocationsButton.addActionListener(this); - + filtersDropDown.addActionListener(this); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(addressInfo); @@ -122,12 +129,38 @@ public void changedUpdate(DocumentEvent e) { suggestLocationsButton.addActionListener(evt -> { if (evt.getSource().equals(suggestLocationsButton)) { - final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } catch (DataAccessException e) { - throw new RuntimeException(e); + + currentFilter = filtersDropDown.getSelectedItem().toString(); + + if ("None".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } } + + if ("Removed Saved Locations".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.clearSaved(); + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } + } +// if ("Remove Disliked Locations".equals(currentFilter)) { +// final LocationState currentState = locationViewModel.getState(); +// try { +// locationController.execute(currentState.getAddress(), currentState.getLocationType()); +// } +// catch (DataAccessException e) { +// throw new RuntimeException(e); +// } +// } } }); } @@ -135,12 +168,15 @@ public void changedUpdate(DocumentEvent e) { @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { - final LocationState currentState = locationViewModel.getState(); + if ("None".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } catch (DataAccessException e) { - throw new RuntimeException(e); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } } } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 332e0b980..a215f1781 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -73,13 +73,14 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { if (suggestedLocations != null) { for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); - JPanel locationPanel = new JPanel(); + final JPanel locationPanel = new JPanel(); locationPanel.setLayout(new BoxLayout(locationPanel, BoxLayout.Y_AXIS)); - JCheckBox checkBox = new JCheckBox(); + final JCheckBox checkBox = new JCheckBox(); checkBox.addActionListener(e -> { if (checkBox.isSelected()) { selectedLocations.add(location); - } else { + } + else { selectedLocations.remove(location); } }); @@ -89,7 +90,8 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { locationPanel.add(Box.createVerticalStrut(10)); suggestedLocationsPanel.add(locationPanel); } - } else { + } + else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); @@ -105,4 +107,4 @@ public List getSelectedLocations() { public String getViewName() { return viewName; } -} \ No newline at end of file +} From e10dca0922441d3ef01221bd8c34908897aad3c8 Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Sat, 30 Nov 2024 17:11:36 -0500 Subject: [PATCH 086/113] created filter and made action listener check which filter is selected before proceeding --- .../location/LocationController.java | 6 ++ src/main/java/view/LocationView.java | 60 +++++++++++++++---- .../java/view/SuggestedLocationsView.java | 9 +-- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 9d964dd80..3742b54ed 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -26,6 +26,8 @@ public LocationController(LocationsInputBoundary locationInteractor) { * @param locationType the type of location to save or refresh * @throws DataAccessException if data cannot be accessed */ + + public void execute(String address, String locationType) throws DataAccessException { final LocationsInputData locationInputData = new LocationsInputData( address, locationType); @@ -33,6 +35,10 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(locationInputData); } + public void clearSaved() { + + } + // /** // * Switches to the suggested locations view. // */ diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 2ffabc063..0d87fffb1 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -30,6 +30,9 @@ public class LocationView extends JPanel implements ActionListener, PropertyChan private final JButton suggestLocationsButton; + private final JComboBox filtersDropDown; + private String currentFilter = ""; + public LocationView(LocationViewModel locationViewModel, LocationController locationController) { this.locationViewModel = locationViewModel; this.locationViewModel.addPropertyChangeListener(this); @@ -50,9 +53,13 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca final JPanel buttons = new JPanel(); suggestLocationsButton = new JButton("Suggest Locations"); buttons.add(suggestLocationsButton); - + final JLabel filterLabel = new JLabel("Filters:"); + final String[] filters = {"None", "Remove Disliked Locations", "Removed Saved Locations"}; + filtersDropDown = new JComboBox<>(filters); + buttons.add(filterLabel); + buttons.add(filtersDropDown); suggestLocationsButton.addActionListener(this); - + filtersDropDown.addActionListener(this); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(addressInfo); @@ -121,12 +128,38 @@ public void changedUpdate(DocumentEvent e) { suggestLocationsButton.addActionListener(evt -> { if (evt.getSource().equals(suggestLocationsButton)) { - final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } catch (DataAccessException e) { - throw new RuntimeException(e); + + currentFilter = filtersDropDown.getSelectedItem().toString(); + + if ("None".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } } + + if ("Removed Saved Locations".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); + try { + locationController.clearSaved(); + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } + } +// if ("Remove Disliked Locations".equals(currentFilter)) { +// final LocationState currentState = locationViewModel.getState(); +// try { +// locationController.execute(currentState.getAddress(), currentState.getLocationType()); +// } +// catch (DataAccessException e) { +// throw new RuntimeException(e); +// } +// } } }); } @@ -134,12 +167,15 @@ public void changedUpdate(DocumentEvent e) { @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { - final LocationState currentState = locationViewModel.getState(); + if ("None".equals(currentFilter)) { + final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } catch (DataAccessException e) { - throw new RuntimeException(e); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } } } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 6f0641a1e..71bf2e049 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -73,9 +73,9 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { if (suggestedLocations != null) { for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); - JPanel locationPanel = new JPanel(); + final JPanel locationPanel = new JPanel(); locationPanel.setLayout(new BoxLayout(locationPanel, BoxLayout.Y_AXIS)); - JCheckBox checkBox = new JCheckBox(); + final JCheckBox checkBox = new JCheckBox(); checkBox.addActionListener(e -> { if (checkBox.isSelected()) { selectedLocations.add(location); @@ -90,7 +90,8 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { locationPanel.add(Box.createVerticalStrut(10)); suggestedLocationsPanel.add(locationPanel); } - } else { + } + else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); @@ -102,4 +103,4 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { public String getViewName() { return viewName; } -} \ No newline at end of file +} From 601987bb7e249f95cb32f98574182a026ae9333c Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sat, 30 Nov 2024 22:17:28 -0500 Subject: [PATCH 087/113] Individual use case - custom profile that contains saved lists in hasmap, allows for user to add description, and implemented sign up view --- src/main/java/app/MainWithDB.java | 2 +- src/main/java/app/SignupUseCaseFactory.java | 39 ++++++ .../java/app/UserProfileUseCaseFactory.java | 40 ++++++ src/main/java/app/UserUseCaseFactory.java | 39 ------ .../DBSignupUserDataAccessObject.java | 33 +++++ .../data_access/DBUserDataAccessObject.java | 21 ++-- src/main/java/entity/User.java | 24 +--- src/main/java/entity/UserFactory.java | 20 ++- .../signup/SignupController.java | 34 ++++++ .../signup/SignupPresenter.java | 37 ++++++ .../signup/SignupViewModel.java | 65 ++++++++++ .../user/UserController.java | 31 ----- .../interface_adapter/user/UserPresenter.java | 43 ------- .../user/UserProfileController.java | 30 +++++ .../user/UserProfilePresenter.java | 34 ++++++ .../interface_adapter/user/UserState.java | 31 ++++- .../interface_adapter/user/UserViewModel.java | 20 ++- .../use_case/signup/SignupInputBoundary.java | 20 +++ .../java/use_case/signup/SignupInputData.java | 28 +++++ .../use_case/signup/SignupInteractor.java | 53 ++++++++ .../use_case/signup/SignupOutputBoundary.java | 25 ++++ .../use_case/signup/SignupOutputData.java | 22 ++++ .../signup/SignupUserDataAccessInterface.java | 35 ++++++ .../user/UserDataAccessInterface.java | 13 -- .../user/UserProfileDataAccessInterface.java | 29 +++++ .../user/UserProfileInputBoundary.java | 17 ++- .../use_case/user/UserProfileInteractor.java | 36 +++--- .../user/UserProfileOutputBoundary.java | 17 ++- src/main/java/view/SignupView.java | 58 +++++++++ src/main/java/view/UserProfileView.java | 115 +++++++----------- .../java/app/MainLocationApplicationTest.java | 1 - .../java/use_case/NoteInteractorTest.java | 1 - 32 files changed, 741 insertions(+), 272 deletions(-) create mode 100644 src/main/java/app/SignupUseCaseFactory.java create mode 100644 src/main/java/app/UserProfileUseCaseFactory.java delete mode 100644 src/main/java/app/UserUseCaseFactory.java create mode 100644 src/main/java/data_access/DBSignupUserDataAccessObject.java create mode 100644 src/main/java/interface_adapter/signup/SignupController.java create mode 100644 src/main/java/interface_adapter/signup/SignupPresenter.java create mode 100644 src/main/java/interface_adapter/signup/SignupViewModel.java delete mode 100644 src/main/java/interface_adapter/user/UserController.java delete mode 100644 src/main/java/interface_adapter/user/UserPresenter.java create mode 100644 src/main/java/interface_adapter/user/UserProfileController.java create mode 100644 src/main/java/interface_adapter/user/UserProfilePresenter.java create mode 100644 src/main/java/use_case/signup/SignupInputBoundary.java create mode 100644 src/main/java/use_case/signup/SignupInputData.java create mode 100644 src/main/java/use_case/signup/SignupInteractor.java create mode 100644 src/main/java/use_case/signup/SignupOutputBoundary.java create mode 100644 src/main/java/use_case/signup/SignupOutputData.java create mode 100644 src/main/java/use_case/signup/SignupUserDataAccessInterface.java delete mode 100644 src/main/java/use_case/user/UserDataAccessInterface.java create mode 100644 src/main/java/use_case/user/UserProfileDataAccessInterface.java create mode 100644 src/main/java/view/SignupView.java diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 1c336e0e6..d39040354 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -53,7 +53,7 @@ public static void main(String[] args) { suggestedLocationsViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); - final UserProfileView userProfileView = UserUseCaseFactory.create(viewManagerModel); + final UserProfileView userProfileView = UserProfileUseCaseFactory.create(viewManagerModel); views.add(userProfileView, "User Profile"); viewManagerModel.setState(locationView.getViewName()); diff --git a/src/main/java/app/SignupUseCaseFactory.java b/src/main/java/app/SignupUseCaseFactory.java new file mode 100644 index 000000000..e83333894 --- /dev/null +++ b/src/main/java/app/SignupUseCaseFactory.java @@ -0,0 +1,39 @@ +package app; + +import data_access.DBSignupUserDataAccessObject; +import entity.UserFactory; +import interface_adapter.ViewManagerModel; +import interface_adapter.signup.SignupController; +import interface_adapter.signup.SignupPresenter; +import interface_adapter.signup.SignupViewModel; +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInteractor; +import use_case.signup.SignupOutputBoundary; +import view.SignupView; + +/** + * Factory for creating the Signup use case. + */ +public final class SignupUseCaseFactory { + + private SignupUseCaseFactory() { + + } + + /** + * Factory method for creating the SignupView. + * + * @param viewManagerModel the ViewManagerModel + * @param userFactory the UserFactory + * @return a SignupView instance + */ + public static SignupView create(ViewManagerModel viewManagerModel, UserFactory userFactory) { + final DBSignupUserDataAccessObject userDataAccess = new DBSignupUserDataAccessObject(); + final SignupViewModel signupViewModel = new SignupViewModel(); + final SignupOutputBoundary signupPresenter = new SignupPresenter(viewManagerModel, signupViewModel); + final SignupInputBoundary signupInteractor = new SignupInteractor(userDataAccess, signupPresenter, userFactory); + final SignupController signupController = new SignupController(signupInteractor); + + return new SignupView(signupController, signupViewModel); + } +} diff --git a/src/main/java/app/UserProfileUseCaseFactory.java b/src/main/java/app/UserProfileUseCaseFactory.java new file mode 100644 index 000000000..485ba788d --- /dev/null +++ b/src/main/java/app/UserProfileUseCaseFactory.java @@ -0,0 +1,40 @@ +package app; + +import data_access.DBUserDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.user.UserProfileController; +import interface_adapter.user.UserProfilePresenter; +import interface_adapter.user.UserViewModel; +import use_case.user.UserProfileInputBoundary; +import use_case.user.UserProfileInteractor; +import use_case.user.UserProfileOutputBoundary; +import view.UserProfileView; + +/** + * Factory for creating the User Profile use case. + */ +public final class UserProfileUseCaseFactory { + + /** Prevent instantiation. */ + private UserProfileUseCaseFactory() { + + } + + /** + * Factory method for creating the UserProfileView. + * + * @param viewManagerModel the ViewManagerModel + * @return a UserProfileView instance + */ + public static UserProfileView create(ViewManagerModel viewManagerModel) { + final DBUserDataAccessObject userDataAccess = new DBUserDataAccessObject(); + final UserViewModel userViewModel = new UserViewModel(); + final UserProfileOutputBoundary userProfilePresenter = + new UserProfilePresenter(viewManagerModel, userViewModel); + final UserProfileInputBoundary userProfileInteractor = + new UserProfileInteractor(userDataAccess, userProfilePresenter); + final UserProfileController userProfileController = new UserProfileController(userProfileInteractor); + + return new UserProfileView(userProfileController, userViewModel); + } +} diff --git a/src/main/java/app/UserUseCaseFactory.java b/src/main/java/app/UserUseCaseFactory.java deleted file mode 100644 index 1a8d36b29..000000000 --- a/src/main/java/app/UserUseCaseFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -package app; - -import data_access.DBUserDataAccessObject; -import entity.UserFactory; -import interface_adapter.ViewManagerModel; -import interface_adapter.user.UserController; -import interface_adapter.user.UserPresenter; -import interface_adapter.user.UserViewModel; -import use_case.user.UserProfileInputBoundary; -import use_case.user.UserProfileInteractor; -import view.UserProfileView; - -/** - * This class contains the static factory function for creating a user use case. - */ -public class UserUseCaseFactory { - - private UserUseCaseFactory() { - // Prevent instantiation - } - - /** - * Factory function for creating the UserProfileView. - * - * @param viewManagerModel the ViewManagerModel to inject - * @return the UserProfileView created for the provided input classes. - */ - public static UserProfileView create(ViewManagerModel viewManagerModel) { - final DBUserDataAccessObject userDataAccess = new DBUserDataAccessObject(); - final UserViewModel userViewModel = new UserViewModel(); - final UserPresenter userPresenter = new UserPresenter(viewManagerModel, userViewModel); - final UserFactory userFactory = new UserFactory(); - final UserProfileInputBoundary interactor = new UserProfileInteractor( - userDataAccess, userPresenter, userFactory); - final UserController userController = new UserController(interactor); - - return new UserProfileView(userController, userViewModel); - } -} diff --git a/src/main/java/data_access/DBSignupUserDataAccessObject.java b/src/main/java/data_access/DBSignupUserDataAccessObject.java new file mode 100644 index 000000000..f95bf3a3d --- /dev/null +++ b/src/main/java/data_access/DBSignupUserDataAccessObject.java @@ -0,0 +1,33 @@ +package data_access; + +import java.util.HashMap; +import java.util.Map; + +import entity.User; +import use_case.DataAccessException; +import use_case.signup.SignupUserDataAccessInterface; + +/** + * A DAO for signup user data. + */ +public class DBSignupUserDataAccessObject implements SignupUserDataAccessInterface { + private final Map users = new HashMap<>(); + + @Override + public User getSignupUser(String username) throws DataAccessException { + return users.get(username); + } + + @Override + public void save(User user) throws DataAccessException { + if (users.containsKey(user.getUsername())) { + throw new DataAccessException("User already exists."); + } + users.put(user.getUsername(), user); + } + + @Override + public boolean existsByName(String username) throws DataAccessException { + return users.containsKey(username); + } +} diff --git a/src/main/java/data_access/DBUserDataAccessObject.java b/src/main/java/data_access/DBUserDataAccessObject.java index c69b125f6..05cec63d7 100644 --- a/src/main/java/data_access/DBUserDataAccessObject.java +++ b/src/main/java/data_access/DBUserDataAccessObject.java @@ -3,26 +3,25 @@ import java.util.HashMap; import java.util.Map; -import entity.User; import use_case.DataAccessException; -import use_case.user.UserDataAccessInterface; +import use_case.user.UserProfileDataAccessInterface; /** - * The DAO for user data. + * A DAO for user profile data. */ -public class DBUserDataAccessObject implements UserDataAccessInterface { - private final Map userStorage = new HashMap<>(); +public class DBUserDataAccessObject implements UserProfileDataAccessInterface { + private final Map> userPlaces = new HashMap<>(); @Override - public User findUserByName(String name) throws DataAccessException { - if (!userStorage.containsKey(name)) { - throw new DataAccessException("User not found"); + public void savePlaces(String username, Map places) throws DataAccessException { + if (!userPlaces.containsKey(username)) { + userPlaces.put(username, new HashMap<>()); } - return userStorage.get(name); + userPlaces.get(username).putAll(places); } @Override - public void saveUser(User user) { - userStorage.put(user.getName(), user); + public Map getSavedPlaces(String username) throws DataAccessException { + return userPlaces.getOrDefault(username, new HashMap<>()); } } diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index 3a2463e0d..8c2d259af 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -1,34 +1,22 @@ package entity; -import java.util.List; - /** - * The representation of a password-protected user for our program. + * Represents a User entity with basic attributes. */ public class User { - - private final String name; + private final String username; private final String password; - private List interests; - public User(String name, String password) { - this.name = name; + public User(String username, String password) { + this.username = username; this.password = password; } - public String getName() { - return name; + public String getUsername() { + return username; } public String getPassword() { return password; } - - public List getInterests() { - return interests; - } - - public void setInterests(List interests) { - this.interests = interests; - } } diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java index 592e3604a..082a73418 100644 --- a/src/main/java/entity/UserFactory.java +++ b/src/main/java/entity/UserFactory.java @@ -1,23 +1,17 @@ package entity; -import java.util.List; - /** - * Factory for creating User objects. + * Represents a User entity. */ public class UserFactory { - /** - * Creates a new User object. + * Creates a new User instance. * - * @param name the name of the user - * @param password the password of the user - * @param interests the interests of the user - * @return the new User object + * @param username the username + * @param password the password + * @return a new User instance */ - public User create(String name, String password, List interests) { - final User user = new User(name, password); - user.setInterests(interests); - return user; + public User create(String username, String password) { + return new User(username, password); } } diff --git a/src/main/java/interface_adapter/signup/SignupController.java b/src/main/java/interface_adapter/signup/SignupController.java new file mode 100644 index 000000000..d6ed9c4a8 --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupController.java @@ -0,0 +1,34 @@ +package interface_adapter.signup; + +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInputData; + +/** + * Controller for the Signup use case. + */ +public class SignupController { + private final SignupInputBoundary signupInteractor; + + public SignupController(SignupInputBoundary signupInteractor) { + this.signupInteractor = signupInteractor; + } + + /** + * Executes the Signup use case with the provided information. + * + * @param username the username + * @param password the password + * @param repeatPassword the repeated password + */ + public void execute(String username, String password, String repeatPassword) { + final SignupInputData inputData = new SignupInputData(username, password, repeatPassword); + signupInteractor.execute(inputData); + } + + /** + * Switches to the login view. + */ + public void switchToLoginView() { + signupInteractor.switchToLoginView(); + } +} diff --git a/src/main/java/interface_adapter/signup/SignupPresenter.java b/src/main/java/interface_adapter/signup/SignupPresenter.java new file mode 100644 index 000000000..f5c04eaf8 --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupPresenter.java @@ -0,0 +1,37 @@ +package interface_adapter.signup; + +import interface_adapter.ViewManagerModel; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupOutputData; + +/** + * Presenter for the signup use case. + */ +public class SignupPresenter implements SignupOutputBoundary { + private final ViewManagerModel viewManagerModel; + private final SignupViewModel signupViewModel; + + public SignupPresenter(ViewManagerModel viewManagerModel, SignupViewModel signupViewModel) { + this.viewManagerModel = viewManagerModel; + this.signupViewModel = signupViewModel; + } + + @Override + public void prepareSuccessView(SignupOutputData outputData) { + signupViewModel.setUsername(outputData.getUsername()); + viewManagerModel.setState("LoggedIn"); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + signupViewModel.setErrorMessage(errorMessage); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareSwitchToLoginView() { + viewManagerModel.setState("Login"); + viewManagerModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/signup/SignupViewModel.java b/src/main/java/interface_adapter/signup/SignupViewModel.java new file mode 100644 index 000000000..247afcd01 --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupViewModel.java @@ -0,0 +1,65 @@ +package interface_adapter.signup; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * ViewModel for the signup process, holding state for the signup view. + */ +public class SignupViewModel { + private String username; + private String errorMessage; + private final PropertyChangeSupport support; + + public SignupViewModel() { + this.support = new PropertyChangeSupport(this); + } + + public String getUsername() { + return username; + } + + /** + * Sets the username and notifies listeners of the change. + * + * @param username the username + */ + public void setUsername(String username) { + final String oldUsername = this.username; + this.username = username; + support.firePropertyChange("username", oldUsername, username); + } + + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the error message and notifies listeners of the change. + * + * @param errorMessage the error message + */ + public void setErrorMessage(String errorMessage) { + final String oldErrorMessage = this.errorMessage; + this.errorMessage = errorMessage; + support.firePropertyChange("errorMessage", oldErrorMessage, errorMessage); + } + + /** + * Adds a property change listener. + * + * @param listener the listener + */ + public void addPropertyChangeListener(PropertyChangeListener listener) { + support.addPropertyChangeListener(listener); + } + + /** + * Removes a property change listener. + * + * @param listener the listener + */ + public void removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener(listener); + } +} diff --git a/src/main/java/interface_adapter/user/UserController.java b/src/main/java/interface_adapter/user/UserController.java deleted file mode 100644 index cdc6ddfe7..000000000 --- a/src/main/java/interface_adapter/user/UserController.java +++ /dev/null @@ -1,31 +0,0 @@ -package interface_adapter.user; - -import java.util.List; - -import use_case.DataAccessException; -import use_case.user.UserProfileInputBoundary; -import use_case.user.UserProfileInputData; - -/** - * Controller for creating a user profile. - */ -public class UserController { - private final UserProfileInputBoundary interactor; - - public UserController(UserProfileInputBoundary interactor) { - this.interactor = interactor; - } - - /** - * Creates a new user profile. - * - * @param username the username of the user - * @param password the password of the user - * @param interests the interests of the user - * @throws DataAccessException if the user profile can not be created for any reason - */ - public void createUser(String username, String password, List interests) throws DataAccessException { - final UserProfileInputData inputData = new UserProfileInputData(username, password, interests); - interactor.createUser(inputData); - } -} diff --git a/src/main/java/interface_adapter/user/UserPresenter.java b/src/main/java/interface_adapter/user/UserPresenter.java deleted file mode 100644 index c7e5e5e3f..000000000 --- a/src/main/java/interface_adapter/user/UserPresenter.java +++ /dev/null @@ -1,43 +0,0 @@ -package interface_adapter.user; - -import entity.User; -import interface_adapter.ViewManagerModel; -import use_case.user.UserProfileOutputBoundary; - -/** - * Presenter for user profile creation. - */ -public class UserPresenter implements UserProfileOutputBoundary { - private final ViewManagerModel viewManagerModel; - private final UserViewModel userViewModel; - - public UserPresenter(ViewManagerModel viewManagerModel, UserViewModel userViewModel) { - this.viewManagerModel = viewManagerModel; - this.userViewModel = userViewModel; - } - - @Override - public void prepareSuccessView(User user) { - final UserState userState = new UserState(); - userState.setUsername(user.getName()); - userState.setPassword(user.getPassword()); - userState.setInterests(user.getInterests()); - - userViewModel.setState(userState); - userViewModel.firePropertyChanged(); - - // Need to implement the login view - viewManagerModel.setState("Login"); - viewManagerModel.firePropertyChanged(); - } - - @Override - public void prepareFailView(String errorMessage) { - UserState userState = userViewModel.getState(); - if (userState == null) { - userState = new UserState(); - } - userViewModel.setState(userState); - userViewModel.firePropertyChanged(); - } -} diff --git a/src/main/java/interface_adapter/user/UserProfileController.java b/src/main/java/interface_adapter/user/UserProfileController.java new file mode 100644 index 000000000..77d7f5c97 --- /dev/null +++ b/src/main/java/interface_adapter/user/UserProfileController.java @@ -0,0 +1,30 @@ +package interface_adapter.user; + +import java.util.Map; + +import use_case.user.UserProfileInputBoundary; + +/** + * Controller for the User Profile use case. + */ +public class UserProfileController { + private final UserProfileInputBoundary userProfileInteractor; + + public UserProfileController(UserProfileInputBoundary userProfileInteractor) { + this.userProfileInteractor = userProfileInteractor; + } + + /** + * Retrieves the saved places for the given username. + * + * @param username the username + * @param places the places + */ + public void savePlaces(String username, Map places) { + userProfileInteractor.savePlaces(username, places); + } + + public void logOut() { + userProfileInteractor.logOut(); + } +} diff --git a/src/main/java/interface_adapter/user/UserProfilePresenter.java b/src/main/java/interface_adapter/user/UserProfilePresenter.java new file mode 100644 index 000000000..1ce04bbe6 --- /dev/null +++ b/src/main/java/interface_adapter/user/UserProfilePresenter.java @@ -0,0 +1,34 @@ +package interface_adapter.user; + +import interface_adapter.ViewManagerModel; +import use_case.user.UserProfileOutputBoundary; + +/** + * Presenter for user profile creation. + */ +public class UserProfilePresenter implements UserProfileOutputBoundary { + private final ViewManagerModel viewManagerModel; + private final UserViewModel userViewModel; + + public UserProfilePresenter(ViewManagerModel viewManagerModel, UserViewModel userViewModel) { + this.viewManagerModel = viewManagerModel; + this.userViewModel = userViewModel; + } + + @Override + public void prepareSuccessView(String message) { + userViewModel.setSuccessMessage(message); + + userViewModel.firePropertyChanged("Place save successfuly!"); + + viewManagerModel.setState("PlacesSaved"); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + userViewModel.setErrorMessage(errorMessage); + + userViewModel.firePropertyChanged("Error in saving place"); + } +} diff --git a/src/main/java/interface_adapter/user/UserState.java b/src/main/java/interface_adapter/user/UserState.java index 4a72b6e1f..d808fb465 100644 --- a/src/main/java/interface_adapter/user/UserState.java +++ b/src/main/java/interface_adapter/user/UserState.java @@ -1,15 +1,18 @@ package interface_adapter.user; import java.util.List; +import java.util.Map; /** - * The state representing user profile-related data. + * State for the user. */ public class UserState { - private String username = ""; private String password = ""; private List interests; + private Map savedPlaces; + private String errorMessage = ""; + private boolean loggedIn = false; public String getUsername() { return username; @@ -34,4 +37,28 @@ public List getInterests() { public void setInterests(List interests) { this.interests = interests; } + + public Map getSavedPlaces() { + return savedPlaces; + } + + public void setSavedPlaces(Map savedPlaces) { + this.savedPlaces = savedPlaces; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public boolean isLoggedIn() { + return loggedIn; + } + + public void setLoggedIn(boolean loggedIn) { + this.loggedIn = loggedIn; + } } diff --git a/src/main/java/interface_adapter/user/UserViewModel.java b/src/main/java/interface_adapter/user/UserViewModel.java index 3e6f810f4..c413fcbd6 100644 --- a/src/main/java/interface_adapter/user/UserViewModel.java +++ b/src/main/java/interface_adapter/user/UserViewModel.java @@ -6,8 +6,26 @@ * View model for the user profile. */ public class UserViewModel extends ViewModel { + private String successMessage; + private String errorMessage; + public UserViewModel() { super("User Profile"); - setState(null); + } + + public String getSuccessMessage() { + return successMessage; + } + + public void setSuccessMessage(String successMessage) { + this.successMessage = successMessage; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; } } diff --git a/src/main/java/use_case/signup/SignupInputBoundary.java b/src/main/java/use_case/signup/SignupInputBoundary.java new file mode 100644 index 000000000..00e88daed --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputBoundary.java @@ -0,0 +1,20 @@ +package use_case.signup; + +/** + * Input boundary for the Signup use case. + */ +public interface SignupInputBoundary { + /** + * Executes the Signup use case with the provided information. + * + * @param inputData the input data + */ + void execute(SignupInputData inputData); + + /** + * Switches to the login view. + */ + + void switchToLoginView(); +} + diff --git a/src/main/java/use_case/signup/SignupInputData.java b/src/main/java/use_case/signup/SignupInputData.java new file mode 100644 index 000000000..982423e70 --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputData.java @@ -0,0 +1,28 @@ +package use_case.signup; + +/** + * Data structure for holding signup input information. + */ +public class SignupInputData { + private final String username; + private final String password; + private final String repeatPassword; + + public SignupInputData(String username, String password, String repeatPassword) { + this.username = username; + this.password = password; + this.repeatPassword = repeatPassword; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getRepeatPassword() { + return repeatPassword; + } +} diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java new file mode 100644 index 000000000..732da4957 --- /dev/null +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -0,0 +1,53 @@ +package use_case.signup; + +import entity.User; +import entity.UserFactory; +import use_case.DataAccessException; + +/** + * The Signup Interactor handles the logic for user signup. + */ +public class SignupInteractor implements SignupInputBoundary { + private final SignupUserDataAccessInterface userDataAccessObject; + private final SignupOutputBoundary userPresenter; + private final UserFactory userFactory; + + public SignupInteractor(SignupUserDataAccessInterface userDataAccessObject, + SignupOutputBoundary userPresenter, + UserFactory userFactory) { + this.userDataAccessObject = userDataAccessObject; + this.userPresenter = userPresenter; + this.userFactory = userFactory; + } + + @Override + public void execute(SignupInputData signupInputData) { + final String username = signupInputData.getUsername(); + final String password = signupInputData.getPassword(); + final String repeatPassword = signupInputData.getRepeatPassword(); + + try { + if (userDataAccessObject.existsByName(username)) { + userPresenter.prepareFailView("User already exists."); + } + else if (!password.equals(repeatPassword)) { + userPresenter.prepareFailView("Passwords don't match."); + } + else { + final User newUser = userFactory.create(username, password); + userDataAccessObject.save(newUser); + + final SignupOutputData signupOutputData = new SignupOutputData(username, false); + userPresenter.prepareSuccessView(signupOutputData); + } + } + catch (DataAccessException err) { + userPresenter.prepareFailView("An error occurred while signing up: " + err.getMessage()); + } + } + + @Override + public void switchToLoginView() { + userPresenter.prepareSwitchToLoginView(); + } +} diff --git a/src/main/java/use_case/signup/SignupOutputBoundary.java b/src/main/java/use_case/signup/SignupOutputBoundary.java new file mode 100644 index 000000000..f3d71adcd --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -0,0 +1,25 @@ +package use_case.signup; + +/** + * Output boundary for the Signup use case. + */ +public interface SignupOutputBoundary { + /** + * Prepares the view with the output data. + * + * @param outputData the output data + */ + void prepareSuccessView(SignupOutputData outputData); + + /** + * Prepares the view with an error message. + * + * @param errorMessage the error message + */ + void prepareFailView(String errorMessage); + + /** + * Prepares the view to switch to the login view. + */ + void prepareSwitchToLoginView(); +} diff --git a/src/main/java/use_case/signup/SignupOutputData.java b/src/main/java/use_case/signup/SignupOutputData.java new file mode 100644 index 000000000..37f1c2a89 --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputData.java @@ -0,0 +1,22 @@ +package use_case.signup; + +/** + * Data structure for holding signup output information. + */ +public class SignupOutputData { + private final String username; + private final boolean newUser; + + public SignupOutputData(String username, boolean newUser) { + this.username = username; + this.newUser = newUser; + } + + public String getUsername() { + return username; + } + + public boolean isNewUser() { + return newUser; + } +} diff --git a/src/main/java/use_case/signup/SignupUserDataAccessInterface.java b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java new file mode 100644 index 000000000..294d445ba --- /dev/null +++ b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java @@ -0,0 +1,35 @@ +package use_case.signup; + +import entity.User; +import use_case.DataAccessException; + +/** + * Interface for accessing SignupUser data. + */ +public interface SignupUserDataAccessInterface { + /** + * Gets the SignupUser with the given username. + * + * @param username the username + * @return the SignupUser with the given username + * @throws DataAccessException if there is an issue accessing the data + */ + User getSignupUser(String username) throws DataAccessException; + + /** + * Saves the given SignupUser. + * + * @param user the SignupUser to save + * @throws DataAccessException if there is an issue accessing the data + */ + void save(User user) throws DataAccessException; + + /** + * Checks if a SignupUser with the given username exists. + * + * @param username the username + * @return true if a SignupUser with the given username exists, false otherwise + * @throws DataAccessException if there is an issue accessing the data + */ + boolean existsByName(String username) throws DataAccessException; +} diff --git a/src/main/java/use_case/user/UserDataAccessInterface.java b/src/main/java/use_case/user/UserDataAccessInterface.java deleted file mode 100644 index 948a76d3a..000000000 --- a/src/main/java/use_case/user/UserDataAccessInterface.java +++ /dev/null @@ -1,13 +0,0 @@ -package use_case.user; - -import entity.User; -import use_case.DataAccessException; - -/** - * Interface for accessing user data. - */ -public interface UserDataAccessInterface { - User findUserByName(String name) throws DataAccessException; - - void saveUser(User user) throws DataAccessException; -} diff --git a/src/main/java/use_case/user/UserProfileDataAccessInterface.java b/src/main/java/use_case/user/UserProfileDataAccessInterface.java new file mode 100644 index 000000000..e61bfe459 --- /dev/null +++ b/src/main/java/use_case/user/UserProfileDataAccessInterface.java @@ -0,0 +1,29 @@ +package use_case.user; + +import java.util.Map; + +import use_case.DataAccessException; + +/** + * Data access interface for user profile data. + */ +public interface UserProfileDataAccessInterface { + /** + * Saves the given places for the given username. + * + * @param username the username + * @param places the places + * @throws DataAccessException if there is an issue accessing the data + */ + void savePlaces(String username, Map places) throws DataAccessException; + + /** + * Gets the saved places for the given username. + * + * @param username the username + * @return the saved places for the given username + * @throws DataAccessException if there is an issue accessing the data + */ + + Map getSavedPlaces(String username) throws DataAccessException; +} diff --git a/src/main/java/use_case/user/UserProfileInputBoundary.java b/src/main/java/use_case/user/UserProfileInputBoundary.java index cb3ae153d..cf6638d26 100644 --- a/src/main/java/use_case/user/UserProfileInputBoundary.java +++ b/src/main/java/use_case/user/UserProfileInputBoundary.java @@ -1,16 +1,21 @@ package use_case.user; -import use_case.DataAccessException; +import java.util.Map; /** - * Input boundary for creating a user profile. + * Input boundary for the User Profile use case. */ public interface UserProfileInputBoundary { /** - * Creates a new user profile. + * Saves the given places for the given username. * - * @param inputData the input data for the user profile - * @throws DataAccessException if the user profile can not be created for any reason + * @param username the username + * @param places the places */ - void createUser(UserProfileInputData inputData) throws DataAccessException; + void savePlaces(String username, Map places); + + /** + * Logs out the user. + */ + void logOut(); } diff --git a/src/main/java/use_case/user/UserProfileInteractor.java b/src/main/java/use_case/user/UserProfileInteractor.java index 7f7f08935..ae2c9e135 100644 --- a/src/main/java/use_case/user/UserProfileInteractor.java +++ b/src/main/java/use_case/user/UserProfileInteractor.java @@ -1,33 +1,35 @@ package use_case.user; -import entity.User; -import entity.UserFactory; +import java.util.Map; + import use_case.DataAccessException; /** - * Interactor for creating a user profile. + * Interactor for the User Profile use case. */ public class UserProfileInteractor implements UserProfileInputBoundary { - private final UserDataAccessInterface userDataAccess; - private final UserProfileOutputBoundary presenter; - private final UserFactory userFactory; + private final UserProfileDataAccessInterface userProfileDataAccess; + private final UserProfileOutputBoundary userProfileOutputBoundary; - public UserProfileInteractor(UserDataAccessInterface userDataAccess, UserProfileOutputBoundary presenter, - UserFactory userFactory) { - this.userDataAccess = userDataAccess; - this.presenter = presenter; - this.userFactory = userFactory; + public UserProfileInteractor(UserProfileDataAccessInterface userProfileDataAccess, + UserProfileOutputBoundary userProfileOutputBoundary) { + this.userProfileDataAccess = userProfileDataAccess; + this.userProfileOutputBoundary = userProfileOutputBoundary; } @Override - public void createUser(UserProfileInputData inputData) { + public void savePlaces(String username, Map places) { try { - User user = userFactory.create(inputData.getUsername(), inputData.getPassword(), inputData.getInterests()); - userDataAccess.saveUser(user); - presenter.prepareSuccessView(user); + userProfileDataAccess.savePlaces(username, places); + userProfileOutputBoundary.prepareSuccessView("Places saved successfully!"); } - catch (DataAccessException e) { - presenter.prepareFailView(e.getMessage()); + catch (DataAccessException err) { + userProfileOutputBoundary.prepareFailView("Failed to save places."); } } + + @Override + public void logOut() { + userProfileOutputBoundary.prepareFailView("Logging out is currently not implemented."); + } } diff --git a/src/main/java/use_case/user/UserProfileOutputBoundary.java b/src/main/java/use_case/user/UserProfileOutputBoundary.java index 424cf51cd..97cc2840d 100644 --- a/src/main/java/use_case/user/UserProfileOutputBoundary.java +++ b/src/main/java/use_case/user/UserProfileOutputBoundary.java @@ -1,12 +1,21 @@ package use_case.user; -import entity.User; - /** - * Output boundary for the user profile use case. + * Output boundary for the User Profile use case. */ public interface UserProfileOutputBoundary { - void prepareSuccessView(User user); + /** + * Prepares the view with a success message. + * + * @param message the message + */ + void prepareSuccessView(String message); + + /** + * Prepares the view with an error message. + * + * @param errorMessage the error message + */ void prepareFailView(String errorMessage); } diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java new file mode 100644 index 000000000..297018203 --- /dev/null +++ b/src/main/java/view/SignupView.java @@ -0,0 +1,58 @@ +package view; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; + +import interface_adapter.signup.SignupController; +import interface_adapter.signup.SignupViewModel; + +/** + * View for the signup process. + */ +public class SignupView extends JPanel { + private final JTextField usernameInputField = new JTextField(15); + private final JPasswordField passwordInputField = new JPasswordField(15); + private final JPasswordField repeatPasswordInputField = new JPasswordField(15); + private final SignupController signupController; + + public SignupView(SignupController signupController, SignupViewModel signupViewModel) { + this.signupController = signupController; + signupViewModel.addPropertyChangeListener(evt -> { + final String errorMessage = (String) evt.getNewValue(); + if (errorMessage != null) { + JOptionPane.showMessageDialog(this, errorMessage); + } + }); + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + add(new JLabel("Username:")); + add(usernameInputField); + add(new JLabel("Password:")); + add(passwordInputField); + add(new JLabel("Repeat Password:")); + add(repeatPasswordInputField); + + final JButton signUpButton = new JButton("Sign Up"); + signUpButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + signupController.execute( + usernameInputField.getText(), + new String(passwordInputField.getPassword()), + new String(repeatPasswordInputField.getPassword()) + ); + } + }); + + add(signUpButton); + } +} diff --git a/src/main/java/view/UserProfileView.java b/src/main/java/view/UserProfileView.java index 696f10775..75765f888 100644 --- a/src/main/java/view/UserProfileView.java +++ b/src/main/java/view/UserProfileView.java @@ -1,95 +1,68 @@ package view; -import java.awt.Dimension; -import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import javax.swing.BoxLayout; import javax.swing.JButton; -import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JPasswordField; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.JTextField; -import interface_adapter.user.UserController; -import interface_adapter.user.UserState; +import interface_adapter.user.UserProfileController; import interface_adapter.user.UserViewModel; -import use_case.DataAccessException; /** - * User profile view for creating a user profile. + * View for the user profile. */ public class UserProfileView extends JPanel { + private final JTextField placeNameField = new JTextField(20); + private final JTextField placeDescriptionField = new JTextField(20); + private final JButton addPlaceButton = new JButton("Add Place"); + private final JTextArea placesListArea = new JTextArea(10, 30); + private final JButton logOutButton = new JButton("Log Out"); + private final UserProfileController userProfileController; - private final JTextField usernameField; - private final JPasswordField passwordField; - private final JComboBox interestsBox1; - private final JComboBox interestsBox2; - private final JComboBox interestsBox3; - private final JButton createProfileButton; + public UserProfileView(UserProfileController userProfileController, UserViewModel userViewModel) { + this.userProfileController = userProfileController; + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - public UserProfileView(UserController controller, UserViewModel userViewModel) { - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - setPreferredSize(new Dimension(400, 300)); + // Add UI elements for adding a place + add(new JLabel("Place Name:")); + add(placeNameField); + add(new JLabel("Place Description:")); + add(placeDescriptionField); + add(addPlaceButton); - usernameField = new JTextField(20); - passwordField = new JPasswordField(20); - interestsBox1 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); - interestsBox2 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); - interestsBox3 = new JComboBox<>(new String[]{"Books", "Museums", "Cafes", "Parks", "Fine Dining", "Street Food", "Music", "Theater", "Sports"}); - createProfileButton = new JButton("Create Profile"); + addPlaceButton.addActionListener(evt -> { + final String placeName = placeNameField.getText(); + final String placeDescription = placeDescriptionField.getText(); - addComponents(); + final Map newPlace = new HashMap<>(); + newPlace.put(placeName, placeDescription); - userViewModel.addPropertyChangeListener(evt -> handleStateChange(userViewModel.getState())); + userProfileController.savePlaces(userViewModel.getState().getUsername(), newPlace); + }); - createProfileButton.addActionListener(evt -> handleCreateProfileAction(controller)); - } - - /** - * Adds UI components to the panel. - */ - private void addComponents() { - add(new JLabel("Username:")); - add(usernameField); - add(new JLabel("Password:")); - add(passwordField); - add(new JLabel("Select up to 3 Interests:")); - add(interestsBox1); - add(interestsBox2); - add(interestsBox3); - add(createProfileButton); - } + // Display list of saved places + add(new JLabel("Saved Places:")); + add(new JScrollPane(placesListArea)); - /** - * Handles the action of creating a user profile. - * - * @param controller The controller to manage user creation. - */ - private void handleCreateProfileAction(UserController controller) { - final String username = usernameField.getText(); - final String password = new String(passwordField.getPassword()); - try { - controller.createUser(username, password, Arrays.asList( - interestsBox1.getSelectedItem().toString(), - interestsBox2.getSelectedItem().toString(), - interestsBox3.getSelectedItem().toString() - )); - } - catch (DataAccessException dataAccessException) { - System.err.println("Error creating user: " + dataAccessException.getMessage()); - } - } + userViewModel.addPropertyChangeListener(evt -> { + if ("savedPlaces".equals(evt.getPropertyName())) { + final Map savedPlaces = (Map) evt.getNewValue(); + final StringBuilder placesString = new StringBuilder(); + for (Map.Entry entry : savedPlaces.entrySet()) { + placesString.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); + } + placesListArea.setText(placesString.toString()); + } + }); - /** - * Handles changes in the user profile state. - * - * @param state The new user state. - */ - private void handleStateChange(UserState state) { - if (state != null) { - usernameField.setText(state.getUsername()); - passwordField.setText(""); - } + // Log out button + add(logOutButton); + logOutButton.addActionListener(evt -> userProfileController.logOut()); } } diff --git a/src/test/java/app/MainLocationApplicationTest.java b/src/test/java/app/MainLocationApplicationTest.java index 94546ef3f..a0ea6d0f8 100644 --- a/src/test/java/app/MainLocationApplicationTest.java +++ b/src/test/java/app/MainLocationApplicationTest.java @@ -1,6 +1,5 @@ package app; -import entity.User; import org.junit.Before; import org.junit.Test; import use_case.note.NoteDataAccessInterface; diff --git a/src/test/java/use_case/NoteInteractorTest.java b/src/test/java/use_case/NoteInteractorTest.java index 9cabc0429..51cde7287 100644 --- a/src/test/java/use_case/NoteInteractorTest.java +++ b/src/test/java/use_case/NoteInteractorTest.java @@ -1,6 +1,5 @@ package use_case; -import entity.User; import org.junit.Test; import use_case.note.NoteDataAccessInterface; import use_case.note.NoteInteractor; From 345fe948bfbe22f0644db30773b30bc320319c04 Mon Sep 17 00:00:00 2001 From: teddy Date: Sat, 30 Nov 2024 23:46:38 -0500 Subject: [PATCH 088/113] Added ReviewLocation use case and Coordinates DAO --- .../DBCoordinatesDataAccessObject.java | 63 +++++++++++++++++++ .../ReviewLocationController.java | 7 +++ .../ReviewLocationPresenter.java | 4 ++ .../reviewlocation/ReviewLocationState.java | 4 ++ .../ReviewLocationViewModel.java | 4 ++ .../SuggestedLocationsPresenter.java | 19 ++---- .../CoordinateDataAccessInterface.java | 23 +++++++ .../ReviewLocationsInputBoundary.java | 4 ++ .../ReviewLocationsInputData.java | 4 ++ .../ReviewLocationsInteractor.java | 4 ++ .../ReviewLocationsOutputBoundary.java | 4 ++ .../ReviewLocationsOutputData.java | 4 ++ .../SuggestedLocationsInputBoundary.java | 6 -- .../SuggestedLocationsInteractor.java | 2 +- .../SuggestedLocationsOutputData.java | 10 +-- src/main/java/view/ReviewLocationsView.java | 4 ++ 16 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 src/main/java/data_access/DBCoordinatesDataAccessObject.java create mode 100644 src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java create mode 100644 src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java create mode 100644 src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java create mode 100644 src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java create mode 100644 src/main/java/use_case/CoordinateDataAccessInterface.java create mode 100644 src/main/java/use_case/review_locations/ReviewLocationsInputBoundary.java create mode 100644 src/main/java/use_case/review_locations/ReviewLocationsInputData.java create mode 100644 src/main/java/use_case/review_locations/ReviewLocationsInteractor.java create mode 100644 src/main/java/use_case/review_locations/ReviewLocationsOutputBoundary.java create mode 100644 src/main/java/use_case/review_locations/ReviewLocationsOutputData.java create mode 100644 src/main/java/view/ReviewLocationsView.java diff --git a/src/main/java/data_access/DBCoordinatesDataAccessObject.java b/src/main/java/data_access/DBCoordinatesDataAccessObject.java new file mode 100644 index 000000000..9fbb5c2d5 --- /dev/null +++ b/src/main/java/data_access/DBCoordinatesDataAccessObject.java @@ -0,0 +1,63 @@ +package data_access; + +import java.io.IOException; + +import entity.Place; +import okhttp3.*; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import use_case.DataAccessException; +import use_case.locations.CoordinateDataAccessInterface; + +/** + * The DAO for accessing places using Google Places API. + */ +public class DBCoordinatesDataAccessObject implements CoordinateDataAccessInterface { + private static final String API_KEY = System.getenv("API_KEY"); + private static final String CONTENT_TYPE_JSON = "application/json"; + + @Override + public String searchCoordinates(Place place) throws DataAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + + final JSONObject requestBody = new JSONObject(); + requestBody.put("key", API_KEY); + requestBody.put("address", place.getAddress()); + final RequestBody body = RequestBody.create( + requestBody.toString(), MediaType.parse(CONTENT_TYPE_JSON)); + // POST METHOD + final Request request = new Request.Builder() + .url("https://maps.googleapis.com/maps/api/geocode/json") + .post(body) + .build(); + try (Response response = client.newCall(request).execute()) { + final JSONObject responseBody = new JSONObject(response.body().string()); + + if (responseBody.has("results")) { + final StringBuilder coordinates = new StringBuilder(); + final JSONArray jsonArray = responseBody.getJSONArray("results"); + final JSONObject firstResult = jsonArray.getJSONObject(0); + final JSONObject geometry = firstResult.getJSONObject("geometry"); + final JSONObject location = geometry.getJSONObject("location"); + + final double lat = location.getDouble("lat"); + final double lng = location.getDouble("lng"); + + coordinates.append(lat).append(",").append(lng); + return coordinates.toString(); + } + else if (responseBody.has("error_message")) { + throw new DataAccessException("API Error: " + responseBody.getJSONObject("error_message").getString("message")); + } + else { + throw new DataAccessException("Unexpected API response format."); + } + } + catch (IOException | JSONException | DataAccessException ex) { + throw new DataAccessException(ex.getMessage()); + } + } +} diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java new file mode 100644 index 000000000..29c270af8 --- /dev/null +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java @@ -0,0 +1,7 @@ +package interface_adapter.reviewlocation; + +public class ReviewLocationController { + + private final + +} diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java new file mode 100644 index 000000000..9f9f8673f --- /dev/null +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.reviewlocation; + +public class ReviewLocationPresenter { +} diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java new file mode 100644 index 000000000..82b4be804 --- /dev/null +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java @@ -0,0 +1,4 @@ +package interface_adapter.reviewlocation; + +public class ReviewLocationState { +} diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java new file mode 100644 index 000000000..ba8f46319 --- /dev/null +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.reviewlocation; + +public class ReviewLocationViewModel { +} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 8c9ad8eb6..8d124b60b 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -21,14 +21,14 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { - // On success, switch to the suggested locations view. + // On success, switch to the selected locations view. - final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); - suggestedLocationsState.setSuggestedLocations(response.getSuggestedLocations()); - this.suggestedLocationsViewModel.setState(suggestedLocationsState); - this.suggestedLocationsViewModel.firePropertyChanged(); + final SelectedLocationState selectedLocationState = selectedLocationViewModel.getState(); + selectedLocationState.setSelectedLocations(response.getSelectedLocations()); + this.selectedLocationViewModel.setState(selectedLocationState); + this.selectedLocationViewModel.firePropertyChanged(); - this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + this.viewManagerModel.setState(selectedLocationViewModel.getViewName()); this.viewManagerModel.firePropertyChanged(); } @@ -38,11 +38,4 @@ public void prepareFailView(String error) { suggestedLocationState.setError(error); suggestedLocationsViewModel.firePropertyChanged(); } -// -// // change to switch to next view -// @Override -// public void switchToSuggestedLocationsView() { -// -// } - } diff --git a/src/main/java/use_case/CoordinateDataAccessInterface.java b/src/main/java/use_case/CoordinateDataAccessInterface.java new file mode 100644 index 000000000..98e47acd7 --- /dev/null +++ b/src/main/java/use_case/CoordinateDataAccessInterface.java @@ -0,0 +1,23 @@ +package use_case.locations; + +import java.util.HashMap; +import java.util.List; + +import entity.Place; +import use_case.DataAccessException; + +/** + * Interface for the LocationDAO. It consists of methods for + * searching locations + */ +public interface CoordinateDataAccessInterface { + + /** + * Gets a list of locations based on address given. + * @param location the place the user gives + * @return a HashMap of locations and their coordinates + * @throws DataAccessException if the location can not be loaded for any reason + */ + String searchCoordinates(Place location) throws DataAccessException; + +} diff --git a/src/main/java/use_case/review_locations/ReviewLocationsInputBoundary.java b/src/main/java/use_case/review_locations/ReviewLocationsInputBoundary.java new file mode 100644 index 000000000..bbe04c4a6 --- /dev/null +++ b/src/main/java/use_case/review_locations/ReviewLocationsInputBoundary.java @@ -0,0 +1,4 @@ +package use_case.review_locations; + +public class ReviewLocationsInputBoundary { +} diff --git a/src/main/java/use_case/review_locations/ReviewLocationsInputData.java b/src/main/java/use_case/review_locations/ReviewLocationsInputData.java new file mode 100644 index 000000000..c487e8120 --- /dev/null +++ b/src/main/java/use_case/review_locations/ReviewLocationsInputData.java @@ -0,0 +1,4 @@ +package use_case.review_locations; + +public class ReviewLocationsInputData { +} diff --git a/src/main/java/use_case/review_locations/ReviewLocationsInteractor.java b/src/main/java/use_case/review_locations/ReviewLocationsInteractor.java new file mode 100644 index 000000000..cb8c08685 --- /dev/null +++ b/src/main/java/use_case/review_locations/ReviewLocationsInteractor.java @@ -0,0 +1,4 @@ +package use_case.review_locations; + +public class ReviewLocationsInteractor { +} diff --git a/src/main/java/use_case/review_locations/ReviewLocationsOutputBoundary.java b/src/main/java/use_case/review_locations/ReviewLocationsOutputBoundary.java new file mode 100644 index 000000000..92fd978be --- /dev/null +++ b/src/main/java/use_case/review_locations/ReviewLocationsOutputBoundary.java @@ -0,0 +1,4 @@ +package use_case.review_locations; + +public class ReviewLocationsOutputBoundary { +} diff --git a/src/main/java/use_case/review_locations/ReviewLocationsOutputData.java b/src/main/java/use_case/review_locations/ReviewLocationsOutputData.java new file mode 100644 index 000000000..b906eb33d --- /dev/null +++ b/src/main/java/use_case/review_locations/ReviewLocationsOutputData.java @@ -0,0 +1,4 @@ +package use_case.review_locations; + +public class ReviewLocationsOutputData { +} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java index 23592803d..6f21b7d7d 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java @@ -13,10 +13,4 @@ public interface SuggestedLocationsInputBoundary { * @throws DataAccessException if data cannot be accessed at any time */ void execute(SuggestedLocationsInputData suggestedLocationsInputData) throws DataAccessException; -// -// /** -// * Switch to the TODO: next View. -// */ -// void switchToSuggestedLocationsView(); -//} } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java index 34212cffc..fa5a4c01d 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java @@ -13,7 +13,7 @@ public SuggestedLocationsInteractor(SuggestedLocationsOutputBoundary suggestedLo } @Override - public void execute(SuggestedLocationsInputData suggestedLocationsInputData) throws DataAccessException { + public void execute(SuggestedLocationsInputData suggestedLocationsInputData) { final SuggestedLocationsOutputData suggestedLocationsOutputData = new SuggestedLocationsOutputData( suggestedLocationsInputData.getSuggestedLocations(), false); placePresenter.prepareSuccessView(suggestedLocationsOutputData); diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java index f9149d354..a615eafd1 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -9,15 +9,15 @@ */ public class SuggestedLocationsOutputData { - private final List suggestedLocations; + private final List selectedLocations; private final boolean useCaseFailed; - public SuggestedLocationsOutputData(List suggestedLocations, boolean useCaseFailed) { - this.suggestedLocations = suggestedLocations; + public SuggestedLocationsOutputData(List selectedLocations, boolean useCaseFailed) { + this.selectedLocations = selectedLocations; this.useCaseFailed = useCaseFailed; } - public List getSuggestedLocations() { - return suggestedLocations; + public List getSelectedLocations() { + return selectedLocations; } } diff --git a/src/main/java/view/ReviewLocationsView.java b/src/main/java/view/ReviewLocationsView.java new file mode 100644 index 000000000..655672fdb --- /dev/null +++ b/src/main/java/view/ReviewLocationsView.java @@ -0,0 +1,4 @@ +package view; + +public class ReviewLocationsView { +} From 844865b3f8824f81609d0dcc6c438779fe747cb4 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 1 Dec 2024 00:47:27 -0500 Subject: [PATCH 089/113] Individual use case - custom profile that contains saved lists in hasmap, allows for user to add description, and implemented sign up view --- src/main/java/view/UserProfileView.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/view/UserProfileView.java b/src/main/java/view/UserProfileView.java index 75765f888..0eccb3f5c 100644 --- a/src/main/java/view/UserProfileView.java +++ b/src/main/java/view/UserProfileView.java @@ -29,7 +29,6 @@ public UserProfileView(UserProfileController userProfileController, UserViewMode this.userProfileController = userProfileController; this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - // Add UI elements for adding a place add(new JLabel("Place Name:")); add(placeNameField); add(new JLabel("Place Description:")); @@ -61,7 +60,6 @@ public UserProfileView(UserProfileController userProfileController, UserViewMode } }); - // Log out button add(logOutButton); logOutButton.addActionListener(evt -> userProfileController.logOut()); } From ca297049faf4b1721c7d15d1a279401602f6915a Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 1 Dec 2024 00:48:15 -0500 Subject: [PATCH 090/113] Individual use case - custom profile that contains saved lists in hasmap, allows for user to add description, and implemented sign up view --- src/main/java/interface_adapter/user/UserState.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/interface_adapter/user/UserState.java b/src/main/java/interface_adapter/user/UserState.java index d808fb465..4376abb65 100644 --- a/src/main/java/interface_adapter/user/UserState.java +++ b/src/main/java/interface_adapter/user/UserState.java @@ -1,6 +1,5 @@ package interface_adapter.user; -import java.util.List; import java.util.Map; /** @@ -9,7 +8,6 @@ public class UserState { private String username = ""; private String password = ""; - private List interests; private Map savedPlaces; private String errorMessage = ""; private boolean loggedIn = false; @@ -30,14 +28,6 @@ public void setPassword(String password) { this.password = password; } - public List getInterests() { - return interests; - } - - public void setInterests(List interests) { - this.interests = interests; - } - public Map getSavedPlaces() { return savedPlaces; } From 3a8050031c5be84fb10bd251a3ceabad817affad Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 1 Dec 2024 00:56:34 -0500 Subject: [PATCH 091/113] added selectedlocations use case, modified some suggestedlocations files --- .../app/SelectedLocationsUseCaseFactory.java | 4 + .../SelectedLocationsController.java | 21 +++++ .../SelectedLocationsPresenter.java | 8 ++ .../SelectedLocationsState.java | 32 ++++++++ .../SelectedLocationsViewModel.java | 17 ++++ .../SuggestedLocationsPresenter.java | 14 ++-- .../SuggestedLocationsState.java | 1 - .../SelectedLocationsInputBoundary.java | 17 ++++ .../SelectedLocationsInputData.java | 18 +++++ .../SelectedLocationsInteractor.java | 25 ++++++ .../SelectedLocationsOutputBoundary.java | 19 +++++ .../SelectedLocationsOutputData.java | 11 +++ src/main/java/view/SelectedLocationView.java | 79 +++++++++++++++++++ .../java/view/SuggestedLocationsView.java | 4 + 14 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 src/main/java/app/SelectedLocationsUseCaseFactory.java create mode 100644 src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java create mode 100644 src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java create mode 100644 src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java create mode 100644 src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java create mode 100644 src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java create mode 100644 src/main/java/use_case/selected_locations/SelectedLocationsInputData.java create mode 100644 src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java create mode 100644 src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java create mode 100644 src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java create mode 100644 src/main/java/view/SelectedLocationView.java diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java new file mode 100644 index 000000000..8d40dfa2f --- /dev/null +++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java @@ -0,0 +1,4 @@ +package app; + +public class SelectedLocationsUseCaseFactory { +} diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java new file mode 100644 index 000000000..b00a9a8d3 --- /dev/null +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java @@ -0,0 +1,21 @@ +package interface_adapter.selectedlocation; + + +import use_case.DataAccessException; +import use_case.selected_locations.SelectedLocationsInputBoundary; + +public class SelectedLocationsController { + + private final SelectedLocationsInputBoundary selectedLocationsInteractor; + + public SelectedLocationsController(SelectedLocationsInputBoundary selectedLocationsInteractor) { + this.selectedLocationsInteractor = selectedLocationsInteractor; + } + + public void execute() throws DataAccessException { + final SelectedLocationsInputData selectedLocationsInputData = new SelectedLocationsInputData(); + } + + + +} diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java new file mode 100644 index 000000000..99707771b --- /dev/null +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java @@ -0,0 +1,8 @@ +package interface_adapter.selectedlocation; + + + +public class SelectedLocationsPresenter implements SelectedLocationsOutputBoundary { + + +} diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java new file mode 100644 index 000000000..e6214082c --- /dev/null +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java @@ -0,0 +1,32 @@ +package interface_adapter.selectedlocation; + +import entity.Place; + +import java.util.List; + +/** + * The state representing selected location-related data, including a list of + * selected locations. + */ +public class SelectedLocationsState { + + private List selectedLocations; + private String error; + + public List getSelectedLocations() { + return selectedLocations; + } + + public void setSelectedLocations(List selectedLocations) { + this.selectedLocations = selectedLocations; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + +} diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java new file mode 100644 index 000000000..6cd0c904e --- /dev/null +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java @@ -0,0 +1,17 @@ +package interface_adapter.selectedlocation; + +import interface_adapter.ViewModel; +import entity.Place; + +import java.util.List; + +/** + * The ViewModel for the SelectedLocationsView. + */ +public class SelectedLocationsViewModel extends ViewModel { + public SelectedLocationsViewModel() { + super("Selected Locations"); + setState(new SelectedLocationsState()); + } + +} diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 8c9ad8eb6..d7ec44943 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,7 +1,8 @@ package interface_adapter.suggestlocation; +import import interface_adapter.ViewManagerModel; -import use_case.locations.LocationsOutputData; +import interface_adapter.selectedlocation.SelectedLocationsState; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import use_case.suggested_locations.SuggestedLocationsOutputData; @@ -22,13 +23,12 @@ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { // On success, switch to the suggested locations view. + final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); + selectedLocationsState.setSelectedLocations(response.getLocations()); + this.selectedLocationsViewModel.setState(selectedLocationsState); + this.viewManagerModel.firePropertyChanged(); - final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); - suggestedLocationsState.setSuggestedLocations(response.getSuggestedLocations()); - this.suggestedLocationsViewModel.setState(suggestedLocationsState); - this.suggestedLocationsViewModel.firePropertyChanged(); - - this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + this.viewManagerModel.setState(selectedLocationsViewModel.getViewName()); this.viewManagerModel.firePropertyChanged(); } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java index 0221540c9..d81ec7280 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java @@ -8,7 +8,6 @@ /** * The state representing suggested location-related data, including a list of suggested locations. */ - public class SuggestedLocationsState { private List suggestedLocations = new ArrayList<>(); private String error; diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java b/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java new file mode 100644 index 000000000..e22bda0cc --- /dev/null +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java @@ -0,0 +1,17 @@ +package use_case.selected_locations; + +import use_case.DataAccessException; + +/** + * The input boundary for the Selected Locations Use Case. + */ +public interface SelectedLocationsInputBoundary { + /** + * Execute the Selected Locations Use Case. + * + * @param selectedLocationsInputData the input data for this use case + * @throws DataAccessException if data cannot be accessed at any time + */ + void execute(SelectedLocationsInputData selectedLocationsInputData) throws DataAccessException; + +} diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInputData.java b/src/main/java/use_case/selected_locations/SelectedLocationsInputData.java new file mode 100644 index 000000000..4d498bde1 --- /dev/null +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInputData.java @@ -0,0 +1,18 @@ +package use_case.selected_locations; + +import entity.Place; + +import java.util.List; + +public class SelectedLocationsInputData { + + private final List selectedLocations; + + public SelectedLocationsInputData(List selectedLocations) { + this.selectedLocations = selectedLocations; + } + + public List getSelectedLocations() { + return selectedLocations; + } +} diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java new file mode 100644 index 000000000..ca7adce45 --- /dev/null +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -0,0 +1,25 @@ +package use_case.selected_locations; + +import use_case.DataAccessException; + +public class SelectedLocationsInteractor implements SelectedLocationsInputBoundary { + private final CoordinateDataAccessInterface coordinateDataAccessInterface; + private final SelectedLocationsOutputBoundary selectedLocationsPresenter; + + public SelectedLocationsInteractor(SelectedLocationsOutputBoundary selectedLocationsOutputBoundary, + CoordinateDataAccessInterface coordinateDataAccessInterface) { + this.selectedLocationsPresenter = selectedLocationsOutputBoundary; + this.coordinateDataAccessInterface = coordinateDataAccessInterface; + } + + + @Override + public void execute(SelectedLocationsInputData selectedLocationsInputData) throws DataAccessException { + final SelectedLocationsOutputData selectedLocationsOutputData = + new SelectedLocationsOutputData(coordinateDataAccessInterface.getcoordinate(), + selectedLocationsInputData.getSelectedLocations(), + false); + selectedLocationsPresenter.prepareSuccessView(selectedLocationsOutputData); + } +} +} diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java b/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java new file mode 100644 index 000000000..6d074f364 --- /dev/null +++ b/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java @@ -0,0 +1,19 @@ +package use_case.selected_locations; + +/** + * The output boundary for the Selected Locations Use Case + */ +public interface SelectedLocationsOutputBoundary { + + /** + * Prepare the success view + * @param outputData The output data + */ + void prepareSuccessView(SelectedLocationsOutputData outputData); + + /** + * Prepare the failure view. + * @param errorMessage The explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java new file mode 100644 index 000000000..888ec1534 --- /dev/null +++ b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java @@ -0,0 +1,11 @@ +package use_case.selected_locations; + +public class SelectedLocationsOutputData { + + private boolean useCaseFailed; + + public void SuggestedLocationsOutputData(boolean useCaseFailed) { + this.useCaseFailed = useCaseFailed; + } + +} diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java new file mode 100644 index 000000000..f70ee3684 --- /dev/null +++ b/src/main/java/view/SelectedLocationView.java @@ -0,0 +1,79 @@ +package view; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; + +import entity.Place; +import interface_adapter.selectedlocation.SelectedLocationsController; +import interface_adapter.selectedlocation.SelectedLocationsState; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; +import interface_adapter.suggestlocation.SelectedLocationsState; + +/** + * The View for when the user has selected a location in the program. + */ +public class SelectedLocationView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "Selected Location"; + private final SelectedLocationsViewModel selectedLocationsViewModel; + private final SelectedLocationsController selectedLocationsController; + private final SelectedLocationsState selectedLocationsState; + + private final JPanel selectedLocationPanel; + + public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewModel, + SelectedLocationsController selectedLocationsController, + SelectedLocationsState selectedLocationsState) { + this.selectedLocationsViewModel = selectedLocationsViewModel; + this.selectedLocationsViewModel.addPropertyChangeListener(this); + this.selectedLocationsController = selectedLocationsController; + this.selectedLocationsState = selectedLocationsState; + + this.selectedLocationPanel = new JPanel(); + this.selectedLocationPanel.setLayout(new BoxLayout(selectedLocationPanel, BoxLayout.Y_AXIS)); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(selectedLocationPanel); + + updateSelectedLocations(selectedLocationsState.getSelectedLocations()); + } + + @Override + public void actionPerformed(ActionEvent e) { + + // TODO: Implement action for button click + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("selectedLocations".equals(evt.getPropertyName())) { + updateSelectedLocations((List) evt.getNewValue()); + } + } + + private void updateSelectedLocations(List selectedLocations) { + selectedLocationPanel.removeAll(); + for (Place location : selectedLocations) { + final JLabel nameLabel = new JLabel(location.getName()); + final JLabel addressLabel = new JLabel(location.getAddress()); + final JButton actionButton = + new JButton("Get Address for " + location.getName()); + actionButton.addActionListener(this); + + selectedLocationPanel.add(nameLabel); + selectedLocationPanel.add(addressLabel); + selectedLocationPanel.add(actionButton); + selectedLocationPanel.add(Box.createVerticalStrut(10)); + } + selectedLocationPanel.revalidate(); + selectedLocationPanel.repaint(); + } + + public String getViewName() { + return viewName; + } +} \ No newline at end of file diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 332e0b980..0a9dd86f6 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -11,6 +11,7 @@ import javax.swing.*; import entity.Place; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -51,6 +52,9 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.add(newSearchButton); updateSuggestedLocations(suggestedLocationsViewModel.getState()); + + SelectedLocationsViewModel.getState().setSelectedLocations(selectedLocations); + } @Override From cc30c3914f9475abc83f0520b7ceb7fbaffcf218 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 1 Dec 2024 01:56:14 -0500 Subject: [PATCH 092/113] added implementation of coordinatemap with selectedlocation --- src/main/java/app/MainWithDB.java | 9 ++- .../app/SelectedLocationsUseCaseFactory.java | 42 ++++++++++++++ .../app/SuggestedLocationUseCaseFactory.java | 57 ------------------- .../app/SuggestedLocationsUseCaseFactory.java | 13 +++-- .../SelectedLocationsController.java | 3 +- .../SelectedLocationsPresenter.java | 11 ++++ .../SuggestedLocationsPresenter.java | 10 +++- .../SelectedLocationsInteractor.java | 25 ++++++-- .../SelectedLocationsOutputData.java | 14 ++++- .../SuggestedLocationInputBoundary.java | 14 ----- .../SuggestedLocationInputData.java | 22 ------- .../SuggestedLocationInteractor.java | 23 -------- .../SuggestedLocationOutputBoundary.java | 18 ------ .../SuggestedLocationOutputData.java | 21 ------- src/main/java/view/SelectedLocationView.java | 25 +++++--- 15 files changed, 127 insertions(+), 180 deletions(-) delete mode 100644 src/main/java/app/SuggestedLocationUseCaseFactory.java delete mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java delete mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java delete mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java delete mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java delete mode 100644 src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index a05cfae9e..478e4e8c0 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -4,8 +4,10 @@ import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationViewModel; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import view.LocationView; +import view.SelectedLocationView; import view.SuggestedLocationsView; import view.ViewManager; @@ -39,6 +41,7 @@ public static void main(String[] args) { final LocationViewModel locationViewModel = new LocationViewModel(); final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); + final SelectedLocationsViewModel selectedLocationsViewModel = new SelectedLocationsViewModel(); // add any future view models here in the same way final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( @@ -49,9 +52,13 @@ public static void main(String[] args) { views.add(locationView, locationView.getViewName()); final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel, - suggestedLocationsViewModel); + suggestedLocationsViewModel, selectedLocationsViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel, + suggestedLocationsViewModel, selectedLocationsViewModel); + views.add(selectedLocationView, selectedLocationView.getViewName()); + viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java index 8d40dfa2f..31672b057 100644 --- a/src/main/java/app/SelectedLocationsUseCaseFactory.java +++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java @@ -1,4 +1,46 @@ package app; +import interface_adapter.ViewManagerModel; +import interface_adapter.selectedlocation.SelectedLocationsController; +import interface_adapter.selectedlocation.SelectedLocationsPresenter; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; +import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.selected_locations.SelectedLocationsOutputBoundary; +import view.SelectedLocationView; + +/** + * This class contains the static factory function for creating the SelectedLocationView. + */ public class SelectedLocationsUseCaseFactory { + + /** Prevent instantiation. */ + private SelectedLocationsUseCaseFactory() { + + } + + /** + * Factory function for creating the LocationView. + * @param viewManagerModel the ViewManagerModel to inject + * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to + * inject + * @param selectedLocationsViewModel the SelectedLocationsViewModel to + * inject + * @return the LocationView created for the provided input classes. + */ + public static SelectedLocationView create( + ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, + SelectedLocationsViewModel selectedLocationsViewModel) { + + final SelectedLocationsController selectedLocationsController = + createSelectedLocationUseCase(viewManagerModel, + suggestedLocationsViewModel, + selectedLocationsViewModel); + return new SelectedLocationView(selectedLocationsViewModel, + selectedLocationsController); +} + + private static SelectedLocationsController createSelectedLocationUseCase( + ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, + SelectedLocationsViewModel selectedLocationsViewModel) { + } } diff --git a/src/main/java/app/SuggestedLocationUseCaseFactory.java b/src/main/java/app/SuggestedLocationUseCaseFactory.java deleted file mode 100644 index 7ac35ac00..000000000 --- a/src/main/java/app/SuggestedLocationUseCaseFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -package app; - -import interface_adapter.ViewManagerModel; -import interface_adapter.location.LocationViewModel; -import interface_adapter.suggestlocation.SuggestedLocationsController; -import interface_adapter.suggestlocation.SuggestedLocationsPresenter; -import interface_adapter.suggestlocation.SuggestedLocationsViewModel; -import use_case.suggest_locations.SuggestLocationsOutputBoundary; -import use_case.suggested_locations.SuggestedLocationInputBoundary; -import use_case.suggested_locations.SuggestedLocationInteractor; -import use_case.suggested_locations.SuggestedLocationOutputBoundary; -import use_case.suggested_locations.SuggestedLocationOutputData; -import view.SuggestedLocationsView; - -import javax.swing.*; -import java.awt.*; - -/** - * This class contains the static factory function for creating the SuggestedLocationView. - */ -public class SuggestedLocationUseCaseFactory { - /** Prevent instantiation. */ - private SuggestedLocationUseCaseFactory() { - - } - - /** - * Factory function for creating the SuggestedLocationView. - * @param viewManagerModel the ViewManagerModel to inject - * @param locationViewModel the LocationViewModel to inject - * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject - * @param cardLayout the CardLayout to inject - * @param parentPanel the JPanel to inject - * @return the SuggestedLocationView created for the provided input classes. - */ - public static SuggestedLocationsView create( - ViewManagerModel viewManagerModel, - LocationViewModel locationViewModel, - SuggestedLocationsViewModel suggestedLocationsViewModel, CardLayout cardLayout, JPanel parentPanel) { - final SuggestedLocationsController suggestedLocationController = createSuggestedLocationUseCase( - viewManagerModel, locationViewModel, - suggestedLocationsViewModel); - - return new SuggestedLocationsView(suggestedLocationsViewModel, - suggestedLocationController, cardLayout, parentPanel); -} - - private static SuggestedLocationsController createSuggestedLocationUseCase( - ViewManagerModel viewManagerModel, - LocationViewModel locationViewModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { - final SuggestedLocationsPresenter suggestedLocationOutputBoundary = new SuggestedLocationsPresenter(viewManagerModel, - suggestedLocationsViewModel, locationViewModel); - final SuggestedLocationInputBoundary locationInteractor = new SuggestedLocationInteractor(suggestedLocationOutputBoundary); - return new SuggestedLocationsController(locationInteractor); - } - } diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 70564c274..1528e9a54 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -2,6 +2,7 @@ import interface_adapter.ViewManagerModel; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -24,14 +25,17 @@ private SuggestedLocationsUseCaseFactory() { * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @param selectedLocationsViewModel the SelectedLocationsViewModel to + * inject * @return the LocationView created for the provided input classes. */ public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + SelectedLocationsViewModel selectedLocationsViewModel) { final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, - suggestedLocationsViewModel); + suggestedLocationsViewModel, selectedLocationsViewModel); // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); @@ -39,10 +43,11 @@ public static SuggestedLocationsView create( private static SuggestedLocationsController createSuggestedLocationUseCase( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + SelectedLocationsViewModel selectedLocationsViewModel) { final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( - viewManagerModel, suggestedLocationsViewModel); + viewManagerModel, suggestedLocationsViewModel, selectedLocationsViewModel); final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( suggestedLocationsOutputBoundary); diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java index b00a9a8d3..239582c26 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java @@ -1,6 +1,7 @@ package interface_adapter.selectedlocation; +import entity.Place; import use_case.DataAccessException; import use_case.selected_locations.SelectedLocationsInputBoundary; @@ -16,6 +17,4 @@ public void execute() throws DataAccessException { final SelectedLocationsInputData selectedLocationsInputData = new SelectedLocationsInputData(); } - - } diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java index 99707771b..0943271ba 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java @@ -1,8 +1,19 @@ package interface_adapter.selectedlocation; +import use_case.selected_locations.SelectedLocationsOutputBoundary; +import use_case.selected_locations.SelectedLocationsOutputData; public class SelectedLocationsPresenter implements SelectedLocationsOutputBoundary { + @Override + public void prepareSuccessView(SelectedLocationsOutputData outputData) { + + } + + @Override + public void prepareFailView(String errorMessage) { + + } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 8d124b60b..89edb520b 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,9 +1,11 @@ package interface_adapter.suggestlocation; import interface_adapter.ViewManagerModel; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import use_case.locations.LocationsOutputData; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import use_case.suggested_locations.SuggestedLocationsOutputData; +import interface_adapter.selectedlocation.SelectedLocationsState; /** * The presenter for the suggested locations use case. @@ -12,18 +14,22 @@ public class SuggestedLocationsPresenter implements SuggestedLocationsOutputBoun private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final SelectedLocationsViewModel selectedLocationViewModel; public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + SelectedLocationsViewModel selectedLocationViewModel) { this.viewManagerModel = viewManagerModel; this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.selectedLocationViewModel = selectedLocationViewModel; } @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { // On success, switch to the selected locations view. - final SelectedLocationState selectedLocationState = selectedLocationViewModel.getState(); + final SelectedLocationsState selectedLocationState = + selectedLocationViewModel.getState(); selectedLocationState.setSelectedLocations(response.getSelectedLocations()); this.selectedLocationViewModel.setState(selectedLocationState); this.selectedLocationViewModel.firePropertyChanged(); diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java index ca7adce45..ae3f3adbe 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -1,6 +1,11 @@ package use_case.selected_locations; +import entity.Place; import use_case.DataAccessException; +import use_case.locations.CoordinateDataAccessInterface; + +import java.util.HashMap; +import java.util.List; public class SelectedLocationsInteractor implements SelectedLocationsInputBoundary { private final CoordinateDataAccessInterface coordinateDataAccessInterface; @@ -12,14 +17,24 @@ public SelectedLocationsInteractor(SelectedLocationsOutputBoundary selectedLocat this.coordinateDataAccessInterface = coordinateDataAccessInterface; } - @Override public void execute(SelectedLocationsInputData selectedLocationsInputData) throws DataAccessException { + final List selectedLocations = selectedLocationsInputData.getSelectedLocations(); + final HashMap locationCoordinatesMap = new HashMap<>(); + + for (Place location : selectedLocations) { + try { + String coordinates = coordinateDataAccessInterface.searchCoordinates(location); + locationCoordinatesMap.put(location, coordinates); + } + catch (DataAccessException e) { + selectedLocationsPresenter.prepareFailView("Failed to fetch coordinates for: " + place.getName()); + return; + } + } + final SelectedLocationsOutputData selectedLocationsOutputData = - new SelectedLocationsOutputData(coordinateDataAccessInterface.getcoordinate(), - selectedLocationsInputData.getSelectedLocations(), - false); + new SelectedLocationsOutputData(); selectedLocationsPresenter.prepareSuccessView(selectedLocationsOutputData); } } -} diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java index 888ec1534..6975b2563 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java @@ -1,11 +1,19 @@ package use_case.selected_locations; +import entity.Place; + +import java.util.HashMap; + public class SelectedLocationsOutputData { - private boolean useCaseFailed; + private final HashMap locationCoordinatesMap; + + public SelectedLocationsOutputData(HashMap locationCoordinatesMap) { + this.locationCoordinatesMap = locationCoordinatesMap; + } - public void SuggestedLocationsOutputData(boolean useCaseFailed) { - this.useCaseFailed = useCaseFailed; + public HashMap getLocationCoordinatesMap() { + return locationCoordinatesMap; } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java deleted file mode 100644 index 5fb3d5806..000000000 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInputBoundary.java +++ /dev/null @@ -1,14 +0,0 @@ -package use_case.suggested_locations; - -import use_case.suggest_locations.DataAccessException; - -/** - * The Suggested Locations Use Case. - */ -public interface SuggestedLocationInputBoundary { - /** - * Execute the Suggested Locations Use Case. - * @param suggestedLocationsInputData the input data for this use case - */ - void execute(SuggestedLocationInputData suggestedLocationsInputData) throws DataAccessException; -} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java deleted file mode 100644 index ddee5e126..000000000 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInputData.java +++ /dev/null @@ -1,22 +0,0 @@ -package use_case.suggested_locations; - -import entity.Place; - -import java.util.List; - -/** - * The input data for the Suggested Locations Use Case. - */ -public class SuggestedLocationInputData { - - private final List places; - - public SuggestedLocationInputData(List places) { - this.places = places; - } - - public List getPlaces() { - return places; - } - -} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java deleted file mode 100644 index 043d725e8..000000000 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationInteractor.java +++ /dev/null @@ -1,23 +0,0 @@ -package use_case.suggested_locations; - -import interface_adapter.suggestlocation.SuggestedLocationsPresenter; - -/** - * The Suggested Locations Interactor. - */ -public class SuggestedLocationInteractor implements SuggestedLocationInputBoundary { - - private final SuggestedLocationOutputBoundary suggestedLocationsPresenter; - - public SuggestedLocationInteractor(SuggestedLocationOutputBoundary suggestedLocationOutputBoundary) { - this.suggestedLocationsPresenter = suggestedLocationOutputBoundary; - } - - @Override - public void execute(SuggestedLocationInputData suggestedLocationInputData) { - final SuggestedLocationOutputData suggestedLocationOutputData = new SuggestedLocationOutputData( - suggestedLocationInputData.getPlaces() - ); - suggestedLocationsPresenter.prepareSuccessView(suggestedLocationOutputData); - } -} \ No newline at end of file diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java deleted file mode 100644 index 25957bd54..000000000 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputBoundary.java +++ /dev/null @@ -1,18 +0,0 @@ -package use_case.suggested_locations; - -/** - * The output boundary for the Suggested Location Use Case. - */ -public interface SuggestedLocationOutputBoundary { - /** - * Prepares the sucess view for the Suggested Location Use Case. - * @param outputData the explanation of the failure - */ - void prepareSuccessView(SuggestedLocationOutputData outputData); - - /** - * Prepares the failure view for the Suggested Location Use Case. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); -} diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java deleted file mode 100644 index d4d2449bc..000000000 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationOutputData.java +++ /dev/null @@ -1,21 +0,0 @@ -package use_case.suggested_locations; - -import entity.Place; - -import java.util.List; - -/** - * The output data for the Suggested Location Use Case. - */ -public class SuggestedLocationOutputData { - - private final List suggestedLocation; - - public SuggestedLocationOutputData(List suggestedLocation) { - this.suggestedLocation = suggestedLocation; - } - - public List getSuggestedLocation() { - return suggestedLocation; - } -} diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java index f70ee3684..2d234a0b8 100644 --- a/src/main/java/view/SelectedLocationView.java +++ b/src/main/java/view/SelectedLocationView.java @@ -9,9 +9,7 @@ import entity.Place; import interface_adapter.selectedlocation.SelectedLocationsController; -import interface_adapter.selectedlocation.SelectedLocationsState; import interface_adapter.selectedlocation.SelectedLocationsViewModel; -import interface_adapter.suggestlocation.SelectedLocationsState; /** * The View for when the user has selected a location in the program. @@ -21,17 +19,14 @@ public class SelectedLocationView extends JPanel implements ActionListener, Prop private final String viewName = "Selected Location"; private final SelectedLocationsViewModel selectedLocationsViewModel; private final SelectedLocationsController selectedLocationsController; - private final SelectedLocationsState selectedLocationsState; private final JPanel selectedLocationPanel; public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewModel, - SelectedLocationsController selectedLocationsController, - SelectedLocationsState selectedLocationsState) { + SelectedLocationsController selectedLocationsController) { this.selectedLocationsViewModel = selectedLocationsViewModel; this.selectedLocationsViewModel.addPropertyChangeListener(this); this.selectedLocationsController = selectedLocationsController; - this.selectedLocationsState = selectedLocationsState; this.selectedLocationPanel = new JPanel(); this.selectedLocationPanel.setLayout(new BoxLayout(selectedLocationPanel, BoxLayout.Y_AXIS)); @@ -39,13 +34,27 @@ public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewMode this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(selectedLocationPanel); - updateSelectedLocations(selectedLocationsState.getSelectedLocations()); + updateSelectedLocations(selectedLocationsViewModel.getState().getSelectedLocations()); } @Override public void actionPerformed(ActionEvent e) { + final JButton sourceButton = (JButton) e.getSource(); + final String locationName = sourceButton.getText().replace("Get " + "Address for ", ""); + final List selectedLocations = selectedLocationsViewModel.getState().getSelectedLocations(); - // TODO: Implement action for button click + for (Place location : selectedLocations) { + if (location.getName().equals(locationName)) { + try { + String coordinates = selectedLocationsController.getCoordinates(location); + JOptionPane.showMessageDialog(this, "Coordinates for " + locationName + ": " + coordinates); + } + catch (Exception ex) { + JOptionPane.showMessageDialog(this, "Failed to fetch coordinates for " + locationName, "Error", JOptionPane.ERROR_MESSAGE); + } + break; + } + } } @Override From 176c3e8dad1f0eea0b276d7fa7e78520686907d8 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 1 Dec 2024 02:05:32 -0500 Subject: [PATCH 093/113] added implementation of the button to the url --- .../selectedlocation/SelectedLocationsController.java | 1 + src/main/java/view/SelectedLocationView.java | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java index 239582c26..a62677988 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java @@ -4,6 +4,7 @@ import entity.Place; import use_case.DataAccessException; import use_case.selected_locations.SelectedLocationsInputBoundary; +import use_case.selected_locations.SelectedLocationsInputData; public class SelectedLocationsController { diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java index 2d234a0b8..103ebf2d8 100644 --- a/src/main/java/view/SelectedLocationView.java +++ b/src/main/java/view/SelectedLocationView.java @@ -10,6 +10,7 @@ import entity.Place; import interface_adapter.selectedlocation.SelectedLocationsController; import interface_adapter.selectedlocation.SelectedLocationsViewModel; +import use_case.selected_locations.SelectedLocationsOutputData; /** * The View for when the user has selected a location in the program. @@ -46,8 +47,10 @@ public void actionPerformed(ActionEvent e) { for (Place location : selectedLocations) { if (location.getName().equals(locationName)) { try { - String coordinates = selectedLocationsController.getCoordinates(location); - JOptionPane.showMessageDialog(this, "Coordinates for " + locationName + ": " + coordinates); + String coordinates = + SelectedLocationsOutputData.getLocationCoordinatesMap().get(location); + String message = + "https://maps.google.com/?q=" + coordinates[0] + "," + coordinates[1]; } catch (Exception ex) { JOptionPane.showMessageDialog(this, "Failed to fetch coordinates for " + locationName, "Error", JOptionPane.ERROR_MESSAGE); From 50fd96c6c9c0a762228c89d6bf797ec9f625a61a Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 1 Dec 2024 02:51:21 -0500 Subject: [PATCH 094/113] Calender user story working --- src/main/java/app/CalendarUseCaseFactory.java | 51 ++++++++ src/main/java/app/MainWithDB.java | 18 ++- .../app/SuggestedLocationsUseCaseFactory.java | 22 ++-- .../InMemoryCalendarDataAccessObject.java | 31 +++++ .../AddToCalendarController.java | 32 +++++ .../AddToCalendarPresenter.java | 38 ++++++ .../add_to_calendar/AddToCalendarState.java | 29 +++++ .../AddToCalendarViewModel.java | 14 +++ .../location/LocationController.java | 13 +-- .../location/LocationPresenter.java | 8 -- .../SuggestedLocationsController.java | 7 +- .../SuggestedLocationsPresenter.java | 26 ++--- .../SuggestedLocationsState.java | 11 ++ .../AddToCalendarDataAccessInterface.java | 32 +++++ .../AddToCalendarInputBoundary.java | 17 +++ .../AddToCalendarInputData.java | 21 ++++ .../AddToCalendarInteractor.java | 37 ++++++ .../AddToCalendarOutputBoundary.java | 19 +++ .../AddToCalendarOutputData.java | 21 ++++ .../locations/LocationsOutputBoundary.java | 5 - .../SuggestedLocationsInputBoundary.java | 6 - .../SuggestedLocationsInputData.java | 11 +- .../SuggestedLocationsOutputData.java | 11 +- src/main/java/view/CalendarView.java | 110 ++++++++++++++++++ .../java/view/SuggestedLocationsView.java | 103 +++++++++++++--- .../AddToCalendarInteractorTest.java | 87 ++++++++++++++ 26 files changed, 697 insertions(+), 83 deletions(-) create mode 100644 src/main/java/app/CalendarUseCaseFactory.java create mode 100644 src/main/java/data_access/InMemoryCalendarDataAccessObject.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java create mode 100644 src/main/java/view/CalendarView.java create mode 100644 src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java diff --git a/src/main/java/app/CalendarUseCaseFactory.java b/src/main/java/app/CalendarUseCaseFactory.java new file mode 100644 index 000000000..582cf5310 --- /dev/null +++ b/src/main/java/app/CalendarUseCaseFactory.java @@ -0,0 +1,51 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarPresenter; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import use_case.add_to_calendar.AddToCalendarDataAccessInterface; +import use_case.add_to_calendar.AddToCalendarInputBoundary; +import use_case.add_to_calendar.AddToCalendarInteractor; +import use_case.add_to_calendar.AddToCalendarOutputBoundary; +import view.CalendarView; + +/** + * This class contains the static factory function for creating the CalendarView. + */ +public class CalendarUseCaseFactory { + + /** Prevent instantiation. */ + private CalendarUseCaseFactory() { + + } + + /** + * Factory function for creating the CalendarView. + * @param viewManagerModel the ViewManagerModel to inject + * @param calendarViewModel the AddToCalendarViewModel to inject + * @param calendarDataAccessObject the AddToCalendarDataAccessObject to inject + * @return the LocationView created for the provided input classes. + */ + public static CalendarView create(ViewManagerModel viewManagerModel, + AddToCalendarViewModel calendarViewModel, + AddToCalendarDataAccessInterface calendarDataAccessObject) { + final AddToCalendarController calendarController = createCalendarUseCase(viewManagerModel, + calendarViewModel, calendarDataAccessObject); + + return new CalendarView(calendarViewModel, calendarController); + } + + private static AddToCalendarController createCalendarUseCase( + ViewManagerModel viewManagerModel, + AddToCalendarViewModel calendarViewModel, + AddToCalendarDataAccessInterface calendarDataAccessObject) { + final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel, + viewManagerModel); + final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject, + calendarOutputBoundary); + + return new AddToCalendarController(calendarInteractor); + } + +} diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index a05cfae9e..74e45a961 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -1,17 +1,21 @@ package app; +import java.awt.*; + +import javax.swing.*; + import data_access.DBLocationDataAccessObject; +import data_access.InMemoryCalendarDataAccessObject; import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import view.CalendarView; import view.LocationView; import view.SuggestedLocationsView; import view.ViewManager; -import javax.swing.*; -import java.awt.*; - /** * The version of Main with an external database used to persist user data. */ @@ -39,19 +43,25 @@ public static void main(String[] args) { final LocationViewModel locationViewModel = new LocationViewModel(); final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); + final AddToCalendarViewModel calendarViewModel = new AddToCalendarViewModel(); // add any future view models here in the same way final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); + final InMemoryCalendarDataAccessObject calendarDataAccessObject = new InMemoryCalendarDataAccessObject(); final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, suggestedLocationsViewModel, locationDataAccessObject); views.add(locationView, locationView.getViewName()); final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel, - suggestedLocationsViewModel); + suggestedLocationsViewModel, calendarViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel, + calendarDataAccessObject); + views.add(calendarView, calendarView.getViewName()); + viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 70564c274..e392351bc 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -2,6 +2,10 @@ import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -24,25 +28,29 @@ private SuggestedLocationsUseCaseFactory() { * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @param calendarViewModel the LocationViewModel to inject * @return the LocationView created for the provided input classes. */ public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel calendarViewModel) { - final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, - suggestedLocationsViewModel); + final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase( + viewManagerModel, + suggestedLocationsViewModel, + calendarViewModel); - // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) - return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); + return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel); } private static SuggestedLocationsController createSuggestedLocationUseCase( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel calendarViewModel) { final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( - viewManagerModel, suggestedLocationsViewModel); + viewManagerModel, suggestedLocationsViewModel, calendarViewModel); final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( suggestedLocationsOutputBoundary); diff --git a/src/main/java/data_access/InMemoryCalendarDataAccessObject.java b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java new file mode 100644 index 000000000..372312d8f --- /dev/null +++ b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java @@ -0,0 +1,31 @@ +package data_access; + +import java.util.HashMap; +import java.util.Map; + +import entity.Place; +import use_case.add_to_calendar.AddToCalendarDataAccessInterface; + +/** + * In-memory implementation of the DAO for storing calendar data. This implementation does + * NOT persist data between runs of the program. + */ +public class InMemoryCalendarDataAccessObject implements AddToCalendarDataAccessInterface { + + private final Map calendarItems = new HashMap<>(); + + @Override + public boolean hasLocation(Place location) { + return calendarItems.containsKey(location); + } + + @Override + public boolean hasTime(String time) { + return calendarItems.containsValue(time); + } + + @Override + public void save(Place location, String time) { + calendarItems.put(location, time); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java new file mode 100644 index 000000000..a25366c0c --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java @@ -0,0 +1,32 @@ +package interface_adapter.add_to_calendar; + +import java.util.Map; + +import entity.Place; +import use_case.DataAccessException; +import use_case.add_to_calendar.AddToCalendarInputBoundary; +import use_case.add_to_calendar.AddToCalendarInputData; + +/** + * The AddToCalendarController class handles user input related to adding locations to calendar. + * It interacts with the AddToCalendarInputBoundary to process the input and perform actions. + */ +public class AddToCalendarController { + + private final AddToCalendarInputBoundary addToCalendarInteractor; + + public AddToCalendarController(AddToCalendarInputBoundary calendarInteractor) { + this.addToCalendarInteractor = calendarInteractor; + } + + /** + * Executes the show calendar. + * @param addToCalendarData the locations and time map to add. + * @throws DataAccessException if data cannot be accessed + */ + public void execute(Map addToCalendarData) throws DataAccessException { + final AddToCalendarInputData calendarInputData = new AddToCalendarInputData(addToCalendarData); + + addToCalendarInteractor.execute(calendarInputData); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java new file mode 100644 index 000000000..dd4bea06b --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java @@ -0,0 +1,38 @@ +package interface_adapter.add_to_calendar; + +import interface_adapter.ViewManagerModel; +import use_case.add_to_calendar.AddToCalendarOutputBoundary; +import use_case.add_to_calendar.AddToCalendarOutputData; + +/** + * The Presenter for the Add to Calendar Use Case. + */ +public class AddToCalendarPresenter implements AddToCalendarOutputBoundary { + + private final AddToCalendarViewModel calendarViewModel; + private final ViewManagerModel viewManagerModel; + + public AddToCalendarPresenter(AddToCalendarViewModel calendarViewModel, ViewManagerModel viewManagerModel) { + this.calendarViewModel = calendarViewModel; + this.viewManagerModel = viewManagerModel; + } + + + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + final AddToCalendarState calendarState = calendarViewModel.getState(); + calendarState.setCalendarItems(outputData.getcalendarItems()); + this.calendarViewModel.setState(calendarState); + this.calendarViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(calendarViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + final AddToCalendarState calendarState = calendarViewModel.getState(); + calendarState.setAddError(errorMessage); + calendarViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java new file mode 100644 index 000000000..5f4aeb659 --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java @@ -0,0 +1,29 @@ +package interface_adapter.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The state representing calendar-related data, including locations, times, and any error messages. + */ +public class AddToCalendarState { + private Map calendarItems; + private String addError; + + public Map getCalendarItems() { + return calendarItems; + } + + public String getAddError() { + return addError; + } + + public void setCalendarItems(Map calendarItems) { + this.calendarItems = calendarItems; + } + + public void setAddError(String addError) { + this.addError = addError; + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java new file mode 100644 index 000000000..f4b9ee9f9 --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java @@ -0,0 +1,14 @@ +package interface_adapter.add_to_calendar; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Add to Calendar View. + */ +public class AddToCalendarViewModel extends ViewModel { + + public AddToCalendarViewModel() { + super("Calendar"); + setState(new AddToCalendarState()); + } +} diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 9d964dd80..9d5b3ae89 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -20,10 +20,8 @@ public LocationController(LocationsInputBoundary locationInteractor) { /** * Executes the show location. - * Executes the save or refresh operation based on the location. - * - * @param address the location to save or refresh - * @param locationType the type of location to save or refresh + * @param address the location to show. + * @param locationType the type of location to search. * @throws DataAccessException if data cannot be accessed */ public void execute(String address, String locationType) throws DataAccessException { @@ -32,11 +30,4 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(locationInputData); } - -// /** -// * Switches to the suggested locations view. -// */ -// public void switchToSuggestedLocationsView() { -// locationInput.switchToSuggestedLocationsView(); -// } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 948d0eff6..781ad81f7 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -42,11 +42,3 @@ public void prepareFailView(String error) { locationViewModel.firePropertyChanged(); } } - - // commenting out bc i dont think we need it; view switches in execute (see CAUSerLogin) -// @Override -// public void switchToSuggestedLocationsView() { -// viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); -// viewManagerModel.firePropertyChanged(); -// } -// diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index 476a80164..4e601078b 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,6 +1,7 @@ package interface_adapter.suggestlocation; import java.util.List; +import java.util.Map; import entity.Place; import use_case.DataAccessException; @@ -20,12 +21,12 @@ public SuggestedLocationsController(SuggestedLocationsInputBoundary suggestedLoc /** * Executes the suggested locations' operation. - * @param suggestedLocations the suggestedLocations produced. + * @param calendarItems the calendarItems produced. * @throws DataAccessException if data cannot be accessed. */ - public void execute(List suggestedLocations) throws DataAccessException { + public void execute(Map calendarItems) throws DataAccessException { final SuggestedLocationsInputData suggestedLocationInputData = new SuggestedLocationsInputData( - suggestedLocations); + calendarItems); suggestedLocationsInteractor.execute(suggestedLocationInputData); } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 8c9ad8eb6..a4386fcb4 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,6 +1,8 @@ package interface_adapter.suggestlocation; import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; import use_case.locations.LocationsOutputData; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import use_case.suggested_locations.SuggestedLocationsOutputData; @@ -12,23 +14,26 @@ public class SuggestedLocationsPresenter implements SuggestedLocationsOutputBoun private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final AddToCalendarViewModel addToCalendarViewModel; public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel addToCalendarViewModel) { this.viewManagerModel = viewManagerModel; this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.addToCalendarViewModel = addToCalendarViewModel; } @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { - // On success, switch to the suggested locations view. + // On success, switch to the Calendar view. - final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState(); - suggestedLocationsState.setSuggestedLocations(response.getSuggestedLocations()); - this.suggestedLocationsViewModel.setState(suggestedLocationsState); - this.suggestedLocationsViewModel.firePropertyChanged(); + final AddToCalendarState calendarState = addToCalendarViewModel.getState(); + calendarState.setCalendarItems(response.getCalendarItems()); + this.addToCalendarViewModel.setState(calendarState); + this.addToCalendarViewModel.firePropertyChanged(); - this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); + this.viewManagerModel.setState(addToCalendarViewModel.getViewName()); this.viewManagerModel.firePropertyChanged(); } @@ -38,11 +43,4 @@ public void prepareFailView(String error) { suggestedLocationState.setError(error); suggestedLocationsViewModel.firePropertyChanged(); } -// -// // change to switch to next view -// @Override -// public void switchToSuggestedLocationsView() { -// -// } - } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java index 0221540c9..68cc341cd 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java @@ -1,7 +1,9 @@ package interface_adapter.suggestlocation; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import entity.Place; @@ -11,6 +13,7 @@ public class SuggestedLocationsState { private List suggestedLocations = new ArrayList<>(); + private Map calendarItems = new HashMap<>(); private String error; public List getSuggestedLocations() { @@ -21,6 +24,14 @@ public void setSuggestedLocations(List suggestedLocations) { this.suggestedLocations = suggestedLocations; } + public Map getCalendarItems() { + return calendarItems; + } + + public void setCalendarItems(Map calendarItems) { + this.calendarItems = calendarItems; + } + public String getError() { return error; } diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java new file mode 100644 index 000000000..13f07fc05 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java @@ -0,0 +1,32 @@ +package use_case.add_to_calendar; + +import entity.Place; + +/** + * Interface for the AddToCalendar DAO. It consists of methods for adding locations to the calendar. + */ +public interface AddToCalendarDataAccessInterface { + + /** + * Checks if the given Place exists. + * @param location the name of the location to look for. + * @return true if a Place with the given name exists; false otherwise + */ + boolean hasLocation(Place location); + + /** + * Checks if the given time is available. + * @param time the time of the visit to look for + * @return true if the timeslot is already full; false otherwise + */ + boolean hasTime(String time); + + /** + * Saves the location and time to calendar. + * @param location the location to save + * @param time the time to save + */ + void save(Place location, String time); + + +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java new file mode 100644 index 000000000..f3bd6b104 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java @@ -0,0 +1,17 @@ +package use_case.add_to_calendar; + +import use_case.DataAccessException; + +/** +* The Add to Calendar Use Case. +*/ +public interface AddToCalendarInputBoundary { + + /** + * Execute the Add To Calendar Use Case. + * + * @param addToCalendarInputData the input data for this use case + * @throws DataAccessException if data cannot be accessed at any time + */ + void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException; +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java new file mode 100644 index 000000000..a81445c4e --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java @@ -0,0 +1,21 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The input data for the Add to Calendar Use Case. + */ +public class AddToCalendarInputData { + + private final Map addToCalendarPlace; + + public AddToCalendarInputData(Map addToCalendarPlace) { + this.addToCalendarPlace = addToCalendarPlace; + } + + public Map getAddToCalendarPlace() { + return addToCalendarPlace; + } +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java new file mode 100644 index 000000000..c41f02319 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java @@ -0,0 +1,37 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; +import use_case.DataAccessException; + +/** + * The Add to Calendar Interactor. + */ +public class AddToCalendarInteractor implements AddToCalendarInputBoundary { + private final AddToCalendarDataAccessInterface calendarDataAccessObject; + private final AddToCalendarOutputBoundary calendarPresenter; + + public AddToCalendarInteractor(AddToCalendarDataAccessInterface calendarDataAccessObject, + AddToCalendarOutputBoundary calendarPresenter) { + this.calendarDataAccessObject = calendarDataAccessObject; + this.calendarPresenter = calendarPresenter; + } + + @Override + public void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException { + final Map addToCalendarPlace = addToCalendarInputData.getAddToCalendarPlace(); + for (Map.Entry entry : addToCalendarPlace.entrySet()) { + final Place location = entry.getKey(); + final String time = entry.getValue(); + if (calendarDataAccessObject.hasTime(time)) { + calendarPresenter.prepareFailView(time + " is already full."); + } + else { + calendarDataAccessObject.save(location, time); + } + } + final AddToCalendarOutputData addToCalendarOutputData = new AddToCalendarOutputData(addToCalendarPlace); + calendarPresenter.prepareSuccessView(addToCalendarOutputData); + } +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java new file mode 100644 index 000000000..1c6f2e480 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java @@ -0,0 +1,19 @@ +package use_case.add_to_calendar; + +/** + * The output boundary for the Add to Calendar Use Case. + */ +public interface AddToCalendarOutputBoundary { + + /** + * Prepares the success view for the AddToCalendar Use Case. + * @param outputData the output data + */ + void prepareSuccessView(AddToCalendarOutputData outputData); + + /** + * Prepares the failure view for the AddToCalendar Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java new file mode 100644 index 000000000..153eb5aa5 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java @@ -0,0 +1,21 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The output data for the Add to Calendar Use Case. + */ +public class AddToCalendarOutputData { + + private final Map calendarItems; + + public AddToCalendarOutputData(Map addToCalendarPlace) { + this.calendarItems = addToCalendarPlace; + } + + public Map getcalendarItems() { + return calendarItems; + } +} diff --git a/src/main/java/use_case/locations/LocationsOutputBoundary.java b/src/main/java/use_case/locations/LocationsOutputBoundary.java index 2be723519..904014a0b 100644 --- a/src/main/java/use_case/locations/LocationsOutputBoundary.java +++ b/src/main/java/use_case/locations/LocationsOutputBoundary.java @@ -15,9 +15,4 @@ public interface LocationsOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); - -// /** -// * Switches to the Suggested Locations View. -// */ -// void switchToSuggestedLocationsView(); } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java index 23592803d..6f21b7d7d 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputBoundary.java @@ -13,10 +13,4 @@ public interface SuggestedLocationsInputBoundary { * @throws DataAccessException if data cannot be accessed at any time */ void execute(SuggestedLocationsInputData suggestedLocationsInputData) throws DataAccessException; -// -// /** -// * Switch to the TODO: next View. -// */ -// void switchToSuggestedLocationsView(); -//} } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java index 4c32334c1..585d7e52f 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java @@ -1,6 +1,7 @@ package use_case.suggested_locations; import java.util.List; +import java.util.Map; import entity.Place; @@ -9,14 +10,14 @@ */ public class SuggestedLocationsInputData { - private final List suggestedLocations; + private final Map calendarItems; - public SuggestedLocationsInputData(List suggestedLocations) { - this.suggestedLocations = suggestedLocations; + public SuggestedLocationsInputData(Map calendarItems) { + this.calendarItems = calendarItems; } - public List getSuggestedLocations() { - return suggestedLocations; + public Map getSuggestedLocations() { + return calendarItems; } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java index f9149d354..c459c8c6d 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -1,6 +1,7 @@ package use_case.suggested_locations; import java.util.List; +import java.util.Map; import entity.Place; @@ -9,15 +10,15 @@ */ public class SuggestedLocationsOutputData { - private final List suggestedLocations; + private final Map calendarItems; private final boolean useCaseFailed; - public SuggestedLocationsOutputData(List suggestedLocations, boolean useCaseFailed) { - this.suggestedLocations = suggestedLocations; + public SuggestedLocationsOutputData(Map calendarItems, boolean useCaseFailed) { + this.calendarItems = calendarItems; this.useCaseFailed = useCaseFailed; } - public List getSuggestedLocations() { - return suggestedLocations; + public Map getCalendarItems() { + return calendarItems; } } diff --git a/src/main/java/view/CalendarView.java b/src/main/java/view/CalendarView.java new file mode 100644 index 000000000..54599fbb0 --- /dev/null +++ b/src/main/java/view/CalendarView.java @@ -0,0 +1,110 @@ +package view; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; + +import entity.Place; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import use_case.DataAccessException; + +/** + * The View for when the user is viewing their calendar. + */ +public class CalendarView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "Calendar"; + private final AddToCalendarViewModel calendarViewModel; + private final AddToCalendarController addToCalendarController; + + private final JPanel calendarPanel; + private final JButton newSearchButton; + + private String[] calendarTimes = new String[]{"7:00AM", "8:00AM", "9:00AM", "10:00AM", "11:00AM", "12:00PM", + "1:00PM", "2:00PM", "3:00PM", "4:00PM", "5:00PM", "6:00PM", "7:00PM", "8:00PM", "9:00PM", "10:00PM"}; + + private final int viewWidth = 800; + private final int viewHeight = 1200; + + public CalendarView(AddToCalendarViewModel calendarViewModel, AddToCalendarController addToCalendarController) { + this.calendarViewModel = calendarViewModel; + this.calendarViewModel.addPropertyChangeListener(this); + this.addToCalendarController = addToCalendarController; + + this.setLayout(new BorderLayout()); + + final JLabel title = new JLabel("Calendar"); + title.setFont(new Font("Arial", Font.BOLD, 24)); + final JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + titlePanel.add(title); + this.add(titlePanel, BorderLayout.NORTH); + + this.calendarPanel = new JPanel(); + this.calendarPanel.setLayout(new BoxLayout(calendarPanel, BoxLayout.Y_AXIS)); + this.add(calendarPanel, BorderLayout.WEST); + + this.newSearchButton = new JButton("New Search"); + newSearchButton.addActionListener(this); + final JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(newSearchButton); + this.add(bottomPanel, BorderLayout.SOUTH); + + System.out.println(calendarViewModel.getState().getCalendarItems()); + updateCalendarView(calendarViewModel.getState()); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(newSearchButton)) { + final AddToCalendarState currentState = calendarViewModel.getState(); + try { + addToCalendarController.execute(currentState.getCalendarItems()); + } + catch (DataAccessException e) { + throw new RuntimeException(); + } + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("state".equals(evt.getPropertyName())) { + System.out.println("update (calendar view)"); + updateCalendarView((AddToCalendarState) evt.getNewValue()); + } + } + + private void updateCalendarView(AddToCalendarState state) { + final Map calendarItems = state.getCalendarItems(); + System.out.println("line 75"); + for (int i = 0; i < calendarTimes.length; i++) { + final JPanel timePanel = new JPanel(); + final JTextField timeField = new JTextField(calendarTimes[i]); + timePanel.add(timeField); + for (Map.Entry entry : calendarItems.entrySet()) { + if (entry.getValue().equals(calendarTimes[i])) { + final JTextField locationField = new JTextField(entry.getKey().getName()); + final JTextField addressField = new JTextField(entry.getKey().getAddress()); + timePanel.add(locationField); + timePanel.add(addressField); + } + } +// timePanel.add(Box.createVerticalStrut(calendarTimes.length)); +// timePanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + calendarPanel.add(timePanel); + } + calendarPanel.revalidate(); + calendarPanel.repaint(); + this.setPreferredSize(new Dimension(viewWidth, viewHeight)); + } + + public String getViewName() { + return viewName; + } +} diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 332e0b980..982c92acc 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -5,15 +5,25 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.time.LocalDate; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.swing.*; import entity.Place; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationState; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.DataAccessException; /** * The View for when the user receives a list of suggested locations in the program. @@ -21,18 +31,29 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { private final String viewName = "Suggested Locations"; +// private final LocationViewModel locationViewModel; +// private final LocationController locationController; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; + private final AddToCalendarViewModel calendarViewModel; private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; + private final JButton saveToCalendarButton; private final List selectedLocations; + private final Map calendarLocations; + + private final int numLocationsDisplayed = 5; + private final int viewWidth = 800; + private final int viewHeight = 1200; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, - SuggestedLocationsController suggestedLocationsController) { + SuggestedLocationsController suggestedLocationsController, + AddToCalendarViewModel calendarViewModel) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; + this.calendarViewModel = calendarViewModel; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -42,27 +63,27 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.newSearchButton = new JButton("New Search"); newSearchButton.addActionListener(this); + newSearchButton.setAlignmentX(Component.CENTER_ALIGNMENT); + + this.saveToCalendarButton = new JButton("Save to Calendar"); + saveToCalendarButton.addActionListener(this); this.selectedLocations = new ArrayList<>(); + this.calendarLocations = new HashMap<>(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(suggestedLocationsPanel); this.add(newSearchButton); + this.add(saveToCalendarButton); updateSuggestedLocations(suggestedLocationsViewModel.getState()); } - @Override - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(newSearchButton)) { - // Handle new search button click - } - } - @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equals(evt.getPropertyName())) { + System.out.println("update ( view)"); updateSuggestedLocations((SuggestedLocationsState) evt.getNewValue()); } } @@ -71,11 +92,11 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); final List suggestedLocations = state.getSuggestedLocations(); if (suggestedLocations != null) { - for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { + for (int i = 0; i < Math.min(numLocationsDisplayed, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); - JPanel locationPanel = new JPanel(); - locationPanel.setLayout(new BoxLayout(locationPanel, BoxLayout.Y_AXIS)); - JCheckBox checkBox = new JCheckBox(); + final JPanel locationPanel = new JPanel(); + locationPanel.setLayout(new FlowLayout()); + final JCheckBox checkBox = new JCheckBox(); checkBox.addActionListener(e -> { if (checkBox.isSelected()) { selectedLocations.add(location); @@ -83,21 +104,73 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { selectedLocations.remove(location); } }); + // array of string containing cities + final String[] times = new String[]{"None", "7:00AM", "8:00AM", "9:00AM", "10:00AM", "11:00AM", + "12:00PM", "1:00PM", "2:00PM", "3:00PM", "4:00PM", "5:00PM", "6:00PM", "7:00PM", "8:00PM", + "9:00PM", "10:00PM"}; + // create checkbox + final JComboBox timeSelection = new JComboBox<>(times); + // add ItemListener + timeSelection.addItemListener(e -> { + // if the state combobox is changed + if (e.getSource() == timeSelection) { + if (timeSelection.getSelectedItem().equals("None")) { + calendarLocations.remove(location); + } + else { + calendarLocations.put(location, timeSelection.getSelectedItem().toString()); + } + } + }); locationPanel.add(checkBox); locationPanel.add(new JLabel(location.getName())); locationPanel.add(new JLabel(location.getAddress())); - locationPanel.add(Box.createVerticalStrut(10)); + locationPanel.add(Box.createVerticalStrut(numLocationsDisplayed)); + locationPanel.add(timeSelection); + locationPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); suggestedLocationsPanel.add(locationPanel); } + final AddToCalendarState currentState = calendarViewModel.getState(); + currentState.setCalendarItems(calendarLocations); + calendarViewModel.setState(currentState); } else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); - this.setPreferredSize(new Dimension(800, 1200)); + this.setPreferredSize(new Dimension(viewWidth, viewHeight)); } + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(newSearchButton)) { +// final LocationState currentState = locationViewModel.getState(); +// try { +// locationController.execute(currentState.getAddress(), currentState.getLocationType()); +// } +// catch (DataAccessException e) { +// throw new RuntimeException(); +// } + } + if (evt.getSource().equals(saveToCalendarButton)) { + final AddToCalendarState currentState = calendarViewModel.getState(); + try { + suggestedLocationsController.execute(currentState.getCalendarItems()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } +// final AddToCalendarState currentState = calendarViewModel.getState(); +// try { +// calendarController.execute(currentState.getCalendarItems()); +// } +// catch (DataAccessException e) { +// throw new RuntimeException(e); +// } + } + } + public List getSelectedLocations() { return selectedLocations; } @@ -105,4 +178,4 @@ public List getSelectedLocations() { public String getViewName() { return viewName; } -} \ No newline at end of file +} diff --git a/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java new file mode 100644 index 000000000..88ed09b70 --- /dev/null +++ b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java @@ -0,0 +1,87 @@ +package use_case.add_to_calendar; + +import data_access.InMemoryCalendarDataAccessObject; +import entity.Place; +import entity.SuggestedPlace; +import entity.SuggestedPlaceFactory; +import org.junit.Test; +import use_case.DataAccessException; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class AddToCalendarInteractorTest { + + @Test + public void successTest() { + SuggestedPlaceFactory factory = new SuggestedPlaceFactory(); + Place inputPlace = factory.create("University of Toronto","27 King's College Cir, Toronto"); + Map inputData = new HashMap<>(); + String inputTime = "12:30"; + inputData.put(inputPlace, inputTime); + AddToCalendarInputData calendarInputData = new AddToCalendarInputData(inputData); + AddToCalendarDataAccessInterface calendarRepository = new InMemoryCalendarDataAccessObject(); + + // Add University of Toronto to the data access repository. + calendarRepository.save(inputPlace, inputTime); + + // Create a successPresenter to test the test case + AddToCalendarOutputBoundary successPresenter = new AddToCalendarOutputBoundary() { + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + assertEquals("University of Toronto", inputPlace.getName()); + } + + @Override + public void prepareFailView(String errorMessage) { + fail("Use case failure is unexpected."); + } + }; + + AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); + try{ + interactor.execute(calendarInputData); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } + } + + @Test + public void failureTimeslotBookedTest() { + SuggestedPlaceFactory factory = new SuggestedPlaceFactory(); + Place inputPlace = factory.create("University of Toronto","27 King's College Cir, Toronto"); + Map inputData = new HashMap<>(); + String inputTime = "12:30"; + inputData.put(inputPlace, inputTime); + String inputTime2 = "12:30"; + inputData.put(inputPlace, inputTime2); + AddToCalendarInputData calendarInputData = new AddToCalendarInputData(inputData); + AddToCalendarDataAccessInterface calendarRepository = new InMemoryCalendarDataAccessObject(); + + // Add University of Toronto to the data access repository. + calendarRepository.save(inputPlace, inputTime); + + // Create a successPresenter to test the test case + AddToCalendarOutputBoundary successPresenter = new AddToCalendarOutputBoundary() { + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + fail("Use case success is unexpected."); + } + + @Override + public void prepareFailView(String errorMessage) { + assertEquals("12:30 is already full.", errorMessage); + } + }; + + AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); + try{ + interactor.execute(calendarInputData); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } + } +} From 93f0f28ae60885f78cf86ffef71f2e8c0a84ce51 Mon Sep 17 00:00:00 2001 From: teddy Date: Sun, 1 Dec 2024 03:23:01 -0500 Subject: [PATCH 095/113] fixed SuggestedLocationsView --- src/main/java/app/MainWithDB.java | 2 +- .../app/SelectedLocationsUseCaseFactory.java | 18 +++++--- .../SelectedLocationsInteractor.java | 5 +-- .../java/view/SuggestedLocationsView.java | 43 ++++++++++++------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 478e4e8c0..17bfdda34 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -56,7 +56,7 @@ public static void main(String[] args) { views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel, - suggestedLocationsViewModel, selectedLocationsViewModel); + selectedLocationsViewModel); views.add(selectedLocationView, selectedLocationView.getViewName()); viewManagerModel.setState(locationView.getViewName()); diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java index 31672b057..bb3405638 100644 --- a/src/main/java/app/SelectedLocationsUseCaseFactory.java +++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java @@ -5,6 +5,8 @@ import interface_adapter.selectedlocation.SelectedLocationsPresenter; import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.selected_locations.SelectedLocationsInputBoundary; +import use_case.selected_locations.SelectedLocationsInteractor; import use_case.selected_locations.SelectedLocationsOutputBoundary; import view.SelectedLocationView; @@ -21,26 +23,32 @@ private SelectedLocationsUseCaseFactory() { /** * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject - * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to - * inject + * * @param selectedLocationsViewModel the SelectedLocationsViewModel to * inject * @return the LocationView created for the provided input classes. */ public static SelectedLocationView create( - ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, + ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel) { final SelectedLocationsController selectedLocationsController = createSelectedLocationUseCase(viewManagerModel, - suggestedLocationsViewModel, selectedLocationsViewModel); return new SelectedLocationView(selectedLocationsViewModel, selectedLocationsController); } private static SelectedLocationsController createSelectedLocationUseCase( - ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, + ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel) { +// final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( +// viewManagerModel, selectedLocationsViewModel); +// final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( +// selectedLocationsOutputBoundary); + +// return new SelectedLocationsController(selectedLocationsInteractor); + return null; + // TODO: Implement this method } } diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java index ae3f3adbe..c3b9aa5c5 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -28,13 +28,12 @@ public void execute(SelectedLocationsInputData selectedLocationsInputData) throw locationCoordinatesMap.put(location, coordinates); } catch (DataAccessException e) { - selectedLocationsPresenter.prepareFailView("Failed to fetch coordinates for: " + place.getName()); - return; + selectedLocationsPresenter.prepareFailView("Failed to fetch coordinates for: " + location.getName()); } } final SelectedLocationsOutputData selectedLocationsOutputData = - new SelectedLocationsOutputData(); + new SelectedLocationsOutputData(locationCoordinatesMap); selectedLocationsPresenter.prepareSuccessView(selectedLocationsOutputData); } } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index b7ca1d91d..3e9e905c9 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -11,10 +11,12 @@ import javax.swing.*; import entity.Place; +import interface_adapter.selectedlocation.SelectedLocationsState; import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.DataAccessException; /** * The View for when the user receives a list of suggested locations in the program. @@ -24,16 +26,19 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr private final String viewName = "Suggested Locations"; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; + private final SelectedLocationsViewModel selectedLocationsViewModel; private final JPanel suggestedLocationsPanel; - private final JButton newSearchButton; + private final JButton saveSelectionButton; private final List selectedLocations; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, - SuggestedLocationsController suggestedLocationsController) { + SuggestedLocationsController suggestedLocationsController, + SelectedLocationsViewModel selectedLocationsViewModel) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; + this.selectedLocationsViewModel = selectedLocationsViewModel; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -41,27 +46,19 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.suggestedLocationsPanel = new JPanel(); this.suggestedLocationsPanel.setLayout(new BoxLayout(suggestedLocationsPanel, BoxLayout.Y_AXIS)); - this.newSearchButton = new JButton("New Search"); - newSearchButton.addActionListener(this); + this.saveSelectionButton = new JButton("Save Selection"); + saveSelectionButton.addActionListener(this); + saveSelectionButton.setAlignmentX(Component.CENTER_ALIGNMENT); this.selectedLocations = new ArrayList<>(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(suggestedLocationsPanel); - this.add(newSearchButton); + this.add(saveSelectionButton); updateSuggestedLocations(suggestedLocationsViewModel.getState()); - SelectedLocationsViewModel.getState().setSelectedLocations(selectedLocations); - - } - - @Override - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(newSearchButton)) { - // Handle new search button click - } } @Override @@ -94,13 +91,29 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { locationPanel.add(Box.createVerticalStrut(10)); suggestedLocationsPanel.add(locationPanel); } - } else { + final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); + selectedLocationsState.setSelectedLocations(selectedLocations); + selectedLocationsViewModel.setState(selectedLocationsState); + } + else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); this.setPreferredSize(new Dimension(800, 1200)); + } + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() == saveSelectionButton) { + final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); + try { + suggestedLocationsController.execute(selectedLocationsState.getSelectedLocations()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } + } } public String getViewName() { From d28cb14d095843eac3f43bb745a157ae7d628389 Mon Sep 17 00:00:00 2001 From: "Ray.Fang" Date: Sun, 1 Dec 2024 03:24:13 -0500 Subject: [PATCH 096/113] Individual use case - custom profile that contains saved lists in hasmap, allows for user to add description, and implemented sign up view --- src/main/java/app/SignupUseCaseFactory.java | 10 +-- .../java/app/UserProfileUseCaseFactory.java | 9 +-- .../DBSignupUserDataAccessObject.java | 33 --------- .../data_access/DBUserDataAccessObject.java | 27 -------- .../data_access/InMemoryUserDataAccess.java | 69 +++++++++++++++++++ src/main/java/entity/UserFactory.java | 15 ++-- .../user/UserProfileController.java | 12 +++- .../interface_adapter/user/UserState.java | 48 ++----------- .../use_case/signup/SignupInteractor.java | 30 ++++---- .../signup/SignupUserDataAccessInterface.java | 28 ++++---- .../user/UserProfileDataAccessInterface.java | 33 ++++++--- .../user/UserProfileInputBoundary.java | 13 ++-- .../use_case/user/UserProfileInteractor.java | 8 ++- src/main/java/view/UserProfileView.java | 46 ++++++++++--- 14 files changed, 203 insertions(+), 178 deletions(-) delete mode 100644 src/main/java/data_access/DBSignupUserDataAccessObject.java delete mode 100644 src/main/java/data_access/DBUserDataAccessObject.java create mode 100644 src/main/java/data_access/InMemoryUserDataAccess.java diff --git a/src/main/java/app/SignupUseCaseFactory.java b/src/main/java/app/SignupUseCaseFactory.java index e83333894..0055b3e80 100644 --- a/src/main/java/app/SignupUseCaseFactory.java +++ b/src/main/java/app/SignupUseCaseFactory.java @@ -1,6 +1,6 @@ package app; -import data_access.DBSignupUserDataAccessObject; +import data_access.InMemoryUserDataAccess; import entity.UserFactory; import interface_adapter.ViewManagerModel; import interface_adapter.signup.SignupController; @@ -16,21 +16,21 @@ */ public final class SignupUseCaseFactory { + /** Prevent instantiation. */ private SignupUseCaseFactory() { - } /** * Factory method for creating the SignupView. * * @param viewManagerModel the ViewManagerModel - * @param userFactory the UserFactory * @return a SignupView instance */ - public static SignupView create(ViewManagerModel viewManagerModel, UserFactory userFactory) { - final DBSignupUserDataAccessObject userDataAccess = new DBSignupUserDataAccessObject(); + public static SignupView create(ViewManagerModel viewManagerModel) { + final InMemoryUserDataAccess userDataAccess = new InMemoryUserDataAccess(); final SignupViewModel signupViewModel = new SignupViewModel(); final SignupOutputBoundary signupPresenter = new SignupPresenter(viewManagerModel, signupViewModel); + final UserFactory userFactory = new UserFactory(); final SignupInputBoundary signupInteractor = new SignupInteractor(userDataAccess, signupPresenter, userFactory); final SignupController signupController = new SignupController(signupInteractor); diff --git a/src/main/java/app/UserProfileUseCaseFactory.java b/src/main/java/app/UserProfileUseCaseFactory.java index 485ba788d..413260acf 100644 --- a/src/main/java/app/UserProfileUseCaseFactory.java +++ b/src/main/java/app/UserProfileUseCaseFactory.java @@ -1,13 +1,12 @@ package app; -import data_access.DBUserDataAccessObject; +import data_access.InMemoryUserDataAccess; import interface_adapter.ViewManagerModel; import interface_adapter.user.UserProfileController; import interface_adapter.user.UserProfilePresenter; import interface_adapter.user.UserViewModel; import use_case.user.UserProfileInputBoundary; import use_case.user.UserProfileInteractor; -import use_case.user.UserProfileOutputBoundary; import view.UserProfileView; /** @@ -17,7 +16,6 @@ public final class UserProfileUseCaseFactory { /** Prevent instantiation. */ private UserProfileUseCaseFactory() { - } /** @@ -27,10 +25,9 @@ private UserProfileUseCaseFactory() { * @return a UserProfileView instance */ public static UserProfileView create(ViewManagerModel viewManagerModel) { - final DBUserDataAccessObject userDataAccess = new DBUserDataAccessObject(); + final InMemoryUserDataAccess userDataAccess = new InMemoryUserDataAccess(); final UserViewModel userViewModel = new UserViewModel(); - final UserProfileOutputBoundary userProfilePresenter = - new UserProfilePresenter(viewManagerModel, userViewModel); + final UserProfilePresenter userProfilePresenter = new UserProfilePresenter(viewManagerModel, userViewModel); final UserProfileInputBoundary userProfileInteractor = new UserProfileInteractor(userDataAccess, userProfilePresenter); final UserProfileController userProfileController = new UserProfileController(userProfileInteractor); diff --git a/src/main/java/data_access/DBSignupUserDataAccessObject.java b/src/main/java/data_access/DBSignupUserDataAccessObject.java deleted file mode 100644 index f95bf3a3d..000000000 --- a/src/main/java/data_access/DBSignupUserDataAccessObject.java +++ /dev/null @@ -1,33 +0,0 @@ -package data_access; - -import java.util.HashMap; -import java.util.Map; - -import entity.User; -import use_case.DataAccessException; -import use_case.signup.SignupUserDataAccessInterface; - -/** - * A DAO for signup user data. - */ -public class DBSignupUserDataAccessObject implements SignupUserDataAccessInterface { - private final Map users = new HashMap<>(); - - @Override - public User getSignupUser(String username) throws DataAccessException { - return users.get(username); - } - - @Override - public void save(User user) throws DataAccessException { - if (users.containsKey(user.getUsername())) { - throw new DataAccessException("User already exists."); - } - users.put(user.getUsername(), user); - } - - @Override - public boolean existsByName(String username) throws DataAccessException { - return users.containsKey(username); - } -} diff --git a/src/main/java/data_access/DBUserDataAccessObject.java b/src/main/java/data_access/DBUserDataAccessObject.java deleted file mode 100644 index 05cec63d7..000000000 --- a/src/main/java/data_access/DBUserDataAccessObject.java +++ /dev/null @@ -1,27 +0,0 @@ -package data_access; - -import java.util.HashMap; -import java.util.Map; - -import use_case.DataAccessException; -import use_case.user.UserProfileDataAccessInterface; - -/** - * A DAO for user profile data. - */ -public class DBUserDataAccessObject implements UserProfileDataAccessInterface { - private final Map> userPlaces = new HashMap<>(); - - @Override - public void savePlaces(String username, Map places) throws DataAccessException { - if (!userPlaces.containsKey(username)) { - userPlaces.put(username, new HashMap<>()); - } - userPlaces.get(username).putAll(places); - } - - @Override - public Map getSavedPlaces(String username) throws DataAccessException { - return userPlaces.getOrDefault(username, new HashMap<>()); - } -} diff --git a/src/main/java/data_access/InMemoryUserDataAccess.java b/src/main/java/data_access/InMemoryUserDataAccess.java new file mode 100644 index 000000000..06b542ec1 --- /dev/null +++ b/src/main/java/data_access/InMemoryUserDataAccess.java @@ -0,0 +1,69 @@ +package data_access; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import entity.Place; +import entity.User; +import use_case.DataAccessException; +import use_case.signup.SignupUserDataAccessInterface; +import use_case.user.UserProfileDataAccessInterface; + +/** + * In-memory implementation for storing user data for both sign-up and user profile. + */ +public class InMemoryUserDataAccess implements SignupUserDataAccessInterface, UserProfileDataAccessInterface { + + private final Map userDatabase = new HashMap<>(); + + @Override + public void save(User user) throws DataAccessException { + if (userDatabase.containsKey(user.getName())) { + throw new DataAccessException("User already exists."); + } + userDatabase.put(user.getName(), user); + } + + @Override + public User getUser(String username) throws DataAccessException { + final User user = userDatabase.get(username); + if (user == null) { + throw new DataAccessException("User not found."); + } + return user; + } + + @Override + public boolean existsByName(String username) { + return userDatabase.containsKey(username); + } + + @Override + public void savePlaces(String username, Map> places) throws DataAccessException { + final User user = getUser(username); + if (user != null) { + user.getSavedPlaces().putAll(places); + } + else { + throw new DataAccessException("User not found."); + } + } + + @Override + public Map> getSavedPlaces(String username) throws DataAccessException { + final User user = getUser(username); + if (user != null) { + return user.getSavedPlaces(); + } + else { + throw new DataAccessException("User not found."); + } + } + + // This method is added to fulfill the requirement of SignupUserDataAccessInterface + @Override + public User getSignupUser(String username) throws DataAccessException { + return getUser(username); + } +} diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java index 082a73418..500e11e8f 100644 --- a/src/main/java/entity/UserFactory.java +++ b/src/main/java/entity/UserFactory.java @@ -1,17 +1,20 @@ package entity; +import java.util.HashMap; +import java.util.List; + /** - * Represents a User entity. + * Factory for creating User entities. */ public class UserFactory { + /** - * Creates a new User instance. - * - * @param username the username - * @param password the password + * Create a new user with the given username and password. + * @param username the user's username + * @param password the user's password * @return a new User instance */ public User create(String username, String password) { - return new User(username, password); + return new User(username, password, new HashMap>()); } } diff --git a/src/main/java/interface_adapter/user/UserProfileController.java b/src/main/java/interface_adapter/user/UserProfileController.java index 77d7f5c97..63f2f3610 100644 --- a/src/main/java/interface_adapter/user/UserProfileController.java +++ b/src/main/java/interface_adapter/user/UserProfileController.java @@ -1,7 +1,9 @@ package interface_adapter.user; +import java.util.List; import java.util.Map; +import entity.Place; import use_case.user.UserProfileInputBoundary; /** @@ -15,15 +17,19 @@ public UserProfileController(UserProfileInputBoundary userProfileInteractor) { } /** - * Retrieves the saved places for the given username. + * Saves the places for the given username. * * @param username the username - * @param places the places + * @param places the places to be saved, represented as a map with the place name as the key + * and a list of place objects as the value */ - public void savePlaces(String username, Map places) { + public void savePlaces(String username, Map> places) { userProfileInteractor.savePlaces(username, places); } + /** + * Logs out the user. + */ public void logOut() { userProfileInteractor.logOut(); } diff --git a/src/main/java/interface_adapter/user/UserState.java b/src/main/java/interface_adapter/user/UserState.java index 4376abb65..bb78f6350 100644 --- a/src/main/java/interface_adapter/user/UserState.java +++ b/src/main/java/interface_adapter/user/UserState.java @@ -1,54 +1,20 @@ package interface_adapter.user; -import java.util.Map; - /** - * State for the user. + * Represents the state of a user. */ public class UserState { - private String username = ""; - private String password = ""; - private Map savedPlaces; - private String errorMessage = ""; - private boolean loggedIn = false; + private String username; - public String getUsername() { - return username; - } - - public void setUsername(String username) { + public UserState(String username) { this.username = username; } - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Map getSavedPlaces() { - return savedPlaces; - } - - public void setSavedPlaces(Map savedPlaces) { - this.savedPlaces = savedPlaces; - } - - public String getErrorMessage() { - return errorMessage; - } - - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - public boolean isLoggedIn() { - return loggedIn; + public String getName() { + return username; } - public void setLoggedIn(boolean loggedIn) { - this.loggedIn = loggedIn; + public void setName(String username) { + this.username = username; } } diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java index 732da4957..cfc9c7bf5 100644 --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -5,18 +5,18 @@ import use_case.DataAccessException; /** - * The Signup Interactor handles the logic for user signup. + * The interactor for signing up a new user. */ public class SignupInteractor implements SignupInputBoundary { - private final SignupUserDataAccessInterface userDataAccessObject; - private final SignupOutputBoundary userPresenter; + private final SignupUserDataAccessInterface userDataAccess; + private final SignupOutputBoundary signupOutputBoundary; private final UserFactory userFactory; - public SignupInteractor(SignupUserDataAccessInterface userDataAccessObject, - SignupOutputBoundary userPresenter, + public SignupInteractor(SignupUserDataAccessInterface userDataAccess, + SignupOutputBoundary signupOutputBoundary, UserFactory userFactory) { - this.userDataAccessObject = userDataAccessObject; - this.userPresenter = userPresenter; + this.userDataAccess = userDataAccess; + this.signupOutputBoundary = signupOutputBoundary; this.userFactory = userFactory; } @@ -27,27 +27,27 @@ public void execute(SignupInputData signupInputData) { final String repeatPassword = signupInputData.getRepeatPassword(); try { - if (userDataAccessObject.existsByName(username)) { - userPresenter.prepareFailView("User already exists."); + if (userDataAccess.existsByName(username)) { + signupOutputBoundary.prepareFailView("User already exists."); } else if (!password.equals(repeatPassword)) { - userPresenter.prepareFailView("Passwords don't match."); + signupOutputBoundary.prepareFailView("Passwords don't match."); } else { final User newUser = userFactory.create(username, password); - userDataAccessObject.save(newUser); + userDataAccess.save(newUser); final SignupOutputData signupOutputData = new SignupOutputData(username, false); - userPresenter.prepareSuccessView(signupOutputData); + signupOutputBoundary.prepareSuccessView(signupOutputData); } } - catch (DataAccessException err) { - userPresenter.prepareFailView("An error occurred while signing up: " + err.getMessage()); + catch (DataAccessException error) { + signupOutputBoundary.prepareFailView("An error occurred while signing up."); } } @Override public void switchToLoginView() { - userPresenter.prepareSwitchToLoginView(); + signupOutputBoundary.prepareSwitchToLoginView(); } } diff --git a/src/main/java/use_case/signup/SignupUserDataAccessInterface.java b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java index 294d445ba..59168c864 100644 --- a/src/main/java/use_case/signup/SignupUserDataAccessInterface.java +++ b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java @@ -4,32 +4,28 @@ import use_case.DataAccessException; /** - * Interface for accessing SignupUser data. + * Interface for accessing user data for sign-up. */ public interface SignupUserDataAccessInterface { /** - * Gets the SignupUser with the given username. - * - * @param username the username - * @return the SignupUser with the given username - * @throws DataAccessException if there is an issue accessing the data + * Get a user by username. + * @param username the username to get + * @return the user with the given username + * @throws DataAccessException if the user does not exist */ User getSignupUser(String username) throws DataAccessException; /** - * Saves the given SignupUser. - * - * @param user the SignupUser to save - * @throws DataAccessException if there is an issue accessing the data + * Save a user to the data store. + * @param user the user to save + * @throws DataAccessException if the user already exists */ void save(User user) throws DataAccessException; /** - * Checks if a SignupUser with the given username exists. - * - * @param username the username - * @return true if a SignupUser with the given username exists, false otherwise - * @throws DataAccessException if there is an issue accessing the data + * Check if a user with the given username exists. + * @param username the username to check + * @return true if a user with the given username exists, false otherwise */ - boolean existsByName(String username) throws DataAccessException; + boolean existsByName(String username); } diff --git a/src/main/java/use_case/user/UserProfileDataAccessInterface.java b/src/main/java/use_case/user/UserProfileDataAccessInterface.java index e61bfe459..eb83d4d0c 100644 --- a/src/main/java/use_case/user/UserProfileDataAccessInterface.java +++ b/src/main/java/use_case/user/UserProfileDataAccessInterface.java @@ -1,29 +1,44 @@ package use_case.user; +import java.util.List; import java.util.Map; +import entity.Place; +import entity.User; import use_case.DataAccessException; /** - * Data access interface for user profile data. + * Interface for accessing user profile data. */ public interface UserProfileDataAccessInterface { /** - * Saves the given places for the given username. + * Get the user with the given username. * * @param username the username - * @param places the places - * @throws DataAccessException if there is an issue accessing the data + * @return the user + * @throws DataAccessException if the user does not exist */ - void savePlaces(String username, Map places) throws DataAccessException; + User getUser(String username) throws DataAccessException; /** - * Gets the saved places for the given username. + * Save the places for the given username. * * @param username the username - * @return the saved places for the given username - * @throws DataAccessException if there is an issue accessing the data + * @param places the places to be saved, represented as a map with the place name as the key + * and a list of place objects as the value + * @throws DataAccessException if the user does not exist */ - Map getSavedPlaces(String username) throws DataAccessException; + void savePlaces(String username, Map> places) throws DataAccessException; + + /** + * Get the saved places for the given username. + * + * @param username the username + * @return the saved places, represented as a map with the place name as the key + * and a list of place objects as the value + * @throws DataAccessException if the user does not exist + */ + + Map> getSavedPlaces(String username) throws DataAccessException; } diff --git a/src/main/java/use_case/user/UserProfileInputBoundary.java b/src/main/java/use_case/user/UserProfileInputBoundary.java index cf6638d26..4240a8f8e 100644 --- a/src/main/java/use_case/user/UserProfileInputBoundary.java +++ b/src/main/java/use_case/user/UserProfileInputBoundary.java @@ -1,21 +1,26 @@ package use_case.user; +import java.util.List; import java.util.Map; +import entity.Place; + /** - * Input boundary for the User Profile use case. + * Input boundary for managing user profiles. */ public interface UserProfileInputBoundary { /** - * Saves the given places for the given username. + * Save the places for the given username. * * @param username the username - * @param places the places + * @param places the places to be saved, represented as a map with the place name as the key + * and a list of place objects as the value */ - void savePlaces(String username, Map places); + void savePlaces(String username, Map> places); /** * Logs out the user. */ + void logOut(); } diff --git a/src/main/java/use_case/user/UserProfileInteractor.java b/src/main/java/use_case/user/UserProfileInteractor.java index ae2c9e135..2390642dc 100644 --- a/src/main/java/use_case/user/UserProfileInteractor.java +++ b/src/main/java/use_case/user/UserProfileInteractor.java @@ -1,11 +1,13 @@ package use_case.user; +import java.util.List; import java.util.Map; +import entity.Place; import use_case.DataAccessException; /** - * Interactor for the User Profile use case. + * Interactor for managing user profiles. */ public class UserProfileInteractor implements UserProfileInputBoundary { private final UserProfileDataAccessInterface userProfileDataAccess; @@ -18,12 +20,12 @@ public UserProfileInteractor(UserProfileDataAccessInterface userProfileDataAcces } @Override - public void savePlaces(String username, Map places) { + public void savePlaces(String username, Map> places) { try { userProfileDataAccess.savePlaces(username, places); userProfileOutputBoundary.prepareSuccessView("Places saved successfully!"); } - catch (DataAccessException err) { + catch (DataAccessException error) { userProfileOutputBoundary.prepareFailView("Failed to save places."); } } diff --git a/src/main/java/view/UserProfileView.java b/src/main/java/view/UserProfileView.java index 0eccb3f5c..304a1c91f 100644 --- a/src/main/java/view/UserProfileView.java +++ b/src/main/java/view/UserProfileView.java @@ -1,16 +1,21 @@ package view; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; +import entity.Place; +import entity.SavedPlace; import interface_adapter.user.UserProfileController; import interface_adapter.user.UserViewModel; @@ -19,7 +24,9 @@ */ public class UserProfileView extends JPanel { private final JTextField placeNameField = new JTextField(20); - private final JTextField placeDescriptionField = new JTextField(20); + private final JTextField placeAddressField = new JTextField(20); + private final JTextField placeReviewField = new JTextField(20); + private final JCheckBox placeRatingCheckBox = new JCheckBox("Liked"); private final JButton addPlaceButton = new JButton("Add Place"); private final JTextArea placesListArea = new JTextArea(10, 30); private final JButton logOutButton = new JButton("Log Out"); @@ -29,20 +36,30 @@ public UserProfileView(UserProfileController userProfileController, UserViewMode this.userProfileController = userProfileController; this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + // Add UI elements for adding a place add(new JLabel("Place Name:")); add(placeNameField); - add(new JLabel("Place Description:")); - add(placeDescriptionField); + add(new JLabel("Place Address:")); + add(placeAddressField); + add(new JLabel("Place Review:")); + add(placeReviewField); + add(placeRatingCheckBox); add(addPlaceButton); addPlaceButton.addActionListener(evt -> { final String placeName = placeNameField.getText(); - final String placeDescription = placeDescriptionField.getText(); + final String placeAddress = placeAddressField.getText(); + final String placeReview = placeReviewField.getText(); + final boolean rating = placeRatingCheckBox.isSelected(); - final Map newPlace = new HashMap<>(); - newPlace.put(placeName, placeDescription); + final SavedPlace newPlace = new SavedPlace(placeName, placeAddress, placeReview, rating); + final List placeList = new ArrayList<>(); + placeList.add(newPlace); - userProfileController.savePlaces(userViewModel.getState().getUsername(), newPlace); + final Map> newPlaceMap = new HashMap<>(); + newPlaceMap.put(placeName, placeList); + + userProfileController.savePlaces(userViewModel.getState().getName(), newPlaceMap); }); // Display list of saved places @@ -51,15 +68,24 @@ public UserProfileView(UserProfileController userProfileController, UserViewMode userViewModel.addPropertyChangeListener(evt -> { if ("savedPlaces".equals(evt.getPropertyName())) { - final Map savedPlaces = (Map) evt.getNewValue(); + final Map> savedPlaces = (Map>) evt.getNewValue(); final StringBuilder placesString = new StringBuilder(); - for (Map.Entry entry : savedPlaces.entrySet()) { - placesString.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); + for (Map.Entry> entry : savedPlaces.entrySet()) { + placesString.append(entry.getKey()).append(":\n"); + for (Place place : entry.getValue()) { + if (place instanceof SavedPlace) { + final SavedPlace savedPlace = (SavedPlace) place; + placesString.append(" - Address: ").append(savedPlace.getAddress()).append("\n"); + placesString.append(" - Review: ").append(savedPlace.getReview()).append("\n"); + placesString.append(" - Liked: ").append(savedPlace.getRating() ? "Yes" : "No").append("\n"); + } + } } placesListArea.setText(placesString.toString()); } }); + // Log out button add(logOutButton); logOutButton.addActionListener(evt -> userProfileController.logOut()); } From d4a0e8004965760dab15107fec02dbe7b25a60b3 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 1 Dec 2024 02:51:21 -0500 Subject: [PATCH 097/113] Calender user story working --- src/main/java/app/CalendarUseCaseFactory.java | 51 ++++++++ src/main/java/app/MainWithDB.java | 18 ++- .../app/SuggestedLocationsUseCaseFactory.java | 22 ++-- .../InMemoryCalendarDataAccessObject.java | 31 +++++ .../AddToCalendarController.java | 32 +++++ .../AddToCalendarPresenter.java | 38 ++++++ .../add_to_calendar/AddToCalendarState.java | 29 +++++ .../AddToCalendarViewModel.java | 14 +++ .../location/LocationController.java | 13 +-- .../location/LocationPresenter.java | 8 -- .../SuggestedLocationsController.java | 7 +- .../SuggestedLocationsPresenter.java | 20 +++- .../SuggestedLocationsState.java | 11 ++ .../AddToCalendarDataAccessInterface.java | 32 +++++ .../AddToCalendarInputBoundary.java | 17 +++ .../AddToCalendarInputData.java | 21 ++++ .../AddToCalendarInteractor.java | 37 ++++++ .../AddToCalendarOutputBoundary.java | 19 +++ .../AddToCalendarOutputData.java | 21 ++++ .../locations/LocationsOutputBoundary.java | 5 - .../SuggestedLocationsInputData.java | 11 +- .../SuggestedLocationsOutputData.java | 9 +- src/main/java/view/CalendarView.java | 110 ++++++++++++++++++ .../java/view/SuggestedLocationsView.java | 95 ++++++++++++--- .../AddToCalendarInteractorTest.java | 87 ++++++++++++++ 25 files changed, 698 insertions(+), 60 deletions(-) create mode 100644 src/main/java/app/CalendarUseCaseFactory.java create mode 100644 src/main/java/data_access/InMemoryCalendarDataAccessObject.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java create mode 100644 src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java create mode 100644 src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java create mode 100644 src/main/java/view/CalendarView.java create mode 100644 src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java diff --git a/src/main/java/app/CalendarUseCaseFactory.java b/src/main/java/app/CalendarUseCaseFactory.java new file mode 100644 index 000000000..582cf5310 --- /dev/null +++ b/src/main/java/app/CalendarUseCaseFactory.java @@ -0,0 +1,51 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarPresenter; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import use_case.add_to_calendar.AddToCalendarDataAccessInterface; +import use_case.add_to_calendar.AddToCalendarInputBoundary; +import use_case.add_to_calendar.AddToCalendarInteractor; +import use_case.add_to_calendar.AddToCalendarOutputBoundary; +import view.CalendarView; + +/** + * This class contains the static factory function for creating the CalendarView. + */ +public class CalendarUseCaseFactory { + + /** Prevent instantiation. */ + private CalendarUseCaseFactory() { + + } + + /** + * Factory function for creating the CalendarView. + * @param viewManagerModel the ViewManagerModel to inject + * @param calendarViewModel the AddToCalendarViewModel to inject + * @param calendarDataAccessObject the AddToCalendarDataAccessObject to inject + * @return the LocationView created for the provided input classes. + */ + public static CalendarView create(ViewManagerModel viewManagerModel, + AddToCalendarViewModel calendarViewModel, + AddToCalendarDataAccessInterface calendarDataAccessObject) { + final AddToCalendarController calendarController = createCalendarUseCase(viewManagerModel, + calendarViewModel, calendarDataAccessObject); + + return new CalendarView(calendarViewModel, calendarController); + } + + private static AddToCalendarController createCalendarUseCase( + ViewManagerModel viewManagerModel, + AddToCalendarViewModel calendarViewModel, + AddToCalendarDataAccessInterface calendarDataAccessObject) { + final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel, + viewManagerModel); + final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject, + calendarOutputBoundary); + + return new AddToCalendarController(calendarInteractor); + } + +} diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index a05cfae9e..74e45a961 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -1,17 +1,21 @@ package app; +import java.awt.*; + +import javax.swing.*; + import data_access.DBLocationDataAccessObject; +import data_access.InMemoryCalendarDataAccessObject; import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import view.CalendarView; import view.LocationView; import view.SuggestedLocationsView; import view.ViewManager; -import javax.swing.*; -import java.awt.*; - /** * The version of Main with an external database used to persist user data. */ @@ -39,19 +43,25 @@ public static void main(String[] args) { final LocationViewModel locationViewModel = new LocationViewModel(); final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); + final AddToCalendarViewModel calendarViewModel = new AddToCalendarViewModel(); // add any future view models here in the same way final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); + final InMemoryCalendarDataAccessObject calendarDataAccessObject = new InMemoryCalendarDataAccessObject(); final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, suggestedLocationsViewModel, locationDataAccessObject); views.add(locationView, locationView.getViewName()); final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel, - suggestedLocationsViewModel); + suggestedLocationsViewModel, calendarViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); + final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel, + calendarDataAccessObject); + views.add(calendarView, calendarView.getViewName()); + viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 70564c274..e392351bc 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -2,6 +2,10 @@ import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; @@ -24,25 +28,29 @@ private SuggestedLocationsUseCaseFactory() { * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject + * @param calendarViewModel the LocationViewModel to inject * @return the LocationView created for the provided input classes. */ public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel calendarViewModel) { - final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, - suggestedLocationsViewModel); + final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase( + viewManagerModel, + suggestedLocationsViewModel, + calendarViewModel); - // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) - return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); + return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel); } private static SuggestedLocationsController createSuggestedLocationUseCase( ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel calendarViewModel) { final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( - viewManagerModel, suggestedLocationsViewModel); + viewManagerModel, suggestedLocationsViewModel, calendarViewModel); final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( suggestedLocationsOutputBoundary); diff --git a/src/main/java/data_access/InMemoryCalendarDataAccessObject.java b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java new file mode 100644 index 000000000..372312d8f --- /dev/null +++ b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java @@ -0,0 +1,31 @@ +package data_access; + +import java.util.HashMap; +import java.util.Map; + +import entity.Place; +import use_case.add_to_calendar.AddToCalendarDataAccessInterface; + +/** + * In-memory implementation of the DAO for storing calendar data. This implementation does + * NOT persist data between runs of the program. + */ +public class InMemoryCalendarDataAccessObject implements AddToCalendarDataAccessInterface { + + private final Map calendarItems = new HashMap<>(); + + @Override + public boolean hasLocation(Place location) { + return calendarItems.containsKey(location); + } + + @Override + public boolean hasTime(String time) { + return calendarItems.containsValue(time); + } + + @Override + public void save(Place location, String time) { + calendarItems.put(location, time); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java new file mode 100644 index 000000000..a25366c0c --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java @@ -0,0 +1,32 @@ +package interface_adapter.add_to_calendar; + +import java.util.Map; + +import entity.Place; +import use_case.DataAccessException; +import use_case.add_to_calendar.AddToCalendarInputBoundary; +import use_case.add_to_calendar.AddToCalendarInputData; + +/** + * The AddToCalendarController class handles user input related to adding locations to calendar. + * It interacts with the AddToCalendarInputBoundary to process the input and perform actions. + */ +public class AddToCalendarController { + + private final AddToCalendarInputBoundary addToCalendarInteractor; + + public AddToCalendarController(AddToCalendarInputBoundary calendarInteractor) { + this.addToCalendarInteractor = calendarInteractor; + } + + /** + * Executes the show calendar. + * @param addToCalendarData the locations and time map to add. + * @throws DataAccessException if data cannot be accessed + */ + public void execute(Map addToCalendarData) throws DataAccessException { + final AddToCalendarInputData calendarInputData = new AddToCalendarInputData(addToCalendarData); + + addToCalendarInteractor.execute(calendarInputData); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java new file mode 100644 index 000000000..dd4bea06b --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java @@ -0,0 +1,38 @@ +package interface_adapter.add_to_calendar; + +import interface_adapter.ViewManagerModel; +import use_case.add_to_calendar.AddToCalendarOutputBoundary; +import use_case.add_to_calendar.AddToCalendarOutputData; + +/** + * The Presenter for the Add to Calendar Use Case. + */ +public class AddToCalendarPresenter implements AddToCalendarOutputBoundary { + + private final AddToCalendarViewModel calendarViewModel; + private final ViewManagerModel viewManagerModel; + + public AddToCalendarPresenter(AddToCalendarViewModel calendarViewModel, ViewManagerModel viewManagerModel) { + this.calendarViewModel = calendarViewModel; + this.viewManagerModel = viewManagerModel; + } + + + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + final AddToCalendarState calendarState = calendarViewModel.getState(); + calendarState.setCalendarItems(outputData.getcalendarItems()); + this.calendarViewModel.setState(calendarState); + this.calendarViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(calendarViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + final AddToCalendarState calendarState = calendarViewModel.getState(); + calendarState.setAddError(errorMessage); + calendarViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java new file mode 100644 index 000000000..5f4aeb659 --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java @@ -0,0 +1,29 @@ +package interface_adapter.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The state representing calendar-related data, including locations, times, and any error messages. + */ +public class AddToCalendarState { + private Map calendarItems; + private String addError; + + public Map getCalendarItems() { + return calendarItems; + } + + public String getAddError() { + return addError; + } + + public void setCalendarItems(Map calendarItems) { + this.calendarItems = calendarItems; + } + + public void setAddError(String addError) { + this.addError = addError; + } +} diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java new file mode 100644 index 000000000..f4b9ee9f9 --- /dev/null +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java @@ -0,0 +1,14 @@ +package interface_adapter.add_to_calendar; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Add to Calendar View. + */ +public class AddToCalendarViewModel extends ViewModel { + + public AddToCalendarViewModel() { + super("Calendar"); + setState(new AddToCalendarState()); + } +} diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 9d964dd80..9d5b3ae89 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -20,10 +20,8 @@ public LocationController(LocationsInputBoundary locationInteractor) { /** * Executes the show location. - * Executes the save or refresh operation based on the location. - * - * @param address the location to save or refresh - * @param locationType the type of location to save or refresh + * @param address the location to show. + * @param locationType the type of location to search. * @throws DataAccessException if data cannot be accessed */ public void execute(String address, String locationType) throws DataAccessException { @@ -32,11 +30,4 @@ public void execute(String address, String locationType) throws DataAccessExcept locationInput.execute(locationInputData); } - -// /** -// * Switches to the suggested locations view. -// */ -// public void switchToSuggestedLocationsView() { -// locationInput.switchToSuggestedLocationsView(); -// } } diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java index 948d0eff6..781ad81f7 100644 --- a/src/main/java/interface_adapter/location/LocationPresenter.java +++ b/src/main/java/interface_adapter/location/LocationPresenter.java @@ -42,11 +42,3 @@ public void prepareFailView(String error) { locationViewModel.firePropertyChanged(); } } - - // commenting out bc i dont think we need it; view switches in execute (see CAUSerLogin) -// @Override -// public void switchToSuggestedLocationsView() { -// viewManagerModel.setState(suggestedLocationsViewModel.getViewName()); -// viewManagerModel.firePropertyChanged(); -// } -// diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java index 476a80164..4e601078b 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java @@ -1,6 +1,7 @@ package interface_adapter.suggestlocation; import java.util.List; +import java.util.Map; import entity.Place; import use_case.DataAccessException; @@ -20,12 +21,12 @@ public SuggestedLocationsController(SuggestedLocationsInputBoundary suggestedLoc /** * Executes the suggested locations' operation. - * @param suggestedLocations the suggestedLocations produced. + * @param calendarItems the calendarItems produced. * @throws DataAccessException if data cannot be accessed. */ - public void execute(List suggestedLocations) throws DataAccessException { + public void execute(Map calendarItems) throws DataAccessException { final SuggestedLocationsInputData suggestedLocationInputData = new SuggestedLocationsInputData( - suggestedLocations); + calendarItems); suggestedLocationsInteractor.execute(suggestedLocationInputData); } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 8d124b60b..3640628ce 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -1,6 +1,8 @@ package interface_adapter.suggestlocation; import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; import use_case.locations.LocationsOutputData; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import use_case.suggested_locations.SuggestedLocationsOutputData; @@ -12,15 +14,31 @@ public class SuggestedLocationsPresenter implements SuggestedLocationsOutputBoun private final ViewManagerModel viewManagerModel; private final SuggestedLocationsViewModel suggestedLocationsViewModel; + private final AddToCalendarViewModel addToCalendarViewModel; public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel, - SuggestedLocationsViewModel suggestedLocationsViewModel) { + SuggestedLocationsViewModel suggestedLocationsViewModel, + AddToCalendarViewModel addToCalendarViewModel) { this.viewManagerModel = viewManagerModel; this.suggestedLocationsViewModel = suggestedLocationsViewModel; + this.addToCalendarViewModel = addToCalendarViewModel; } @Override public void prepareSuccessView(SuggestedLocationsOutputData response) { + // On success, switch to the Calendar view. + + final AddToCalendarState calendarState = addToCalendarViewModel.getState(); + calendarState.setCalendarItems(response.getCalendarItems()); + this.addToCalendarViewModel.setState(calendarState); + this.addToCalendarViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(addToCalendarViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + +// @Override + public void placeholderForSeansCode(SuggestedLocationsOutputData response) { // On success, switch to the selected locations view. final SelectedLocationState selectedLocationState = selectedLocationViewModel.getState(); diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java index 0221540c9..68cc341cd 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java @@ -1,7 +1,9 @@ package interface_adapter.suggestlocation; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import entity.Place; @@ -11,6 +13,7 @@ public class SuggestedLocationsState { private List suggestedLocations = new ArrayList<>(); + private Map calendarItems = new HashMap<>(); private String error; public List getSuggestedLocations() { @@ -21,6 +24,14 @@ public void setSuggestedLocations(List suggestedLocations) { this.suggestedLocations = suggestedLocations; } + public Map getCalendarItems() { + return calendarItems; + } + + public void setCalendarItems(Map calendarItems) { + this.calendarItems = calendarItems; + } + public String getError() { return error; } diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java new file mode 100644 index 000000000..13f07fc05 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java @@ -0,0 +1,32 @@ +package use_case.add_to_calendar; + +import entity.Place; + +/** + * Interface for the AddToCalendar DAO. It consists of methods for adding locations to the calendar. + */ +public interface AddToCalendarDataAccessInterface { + + /** + * Checks if the given Place exists. + * @param location the name of the location to look for. + * @return true if a Place with the given name exists; false otherwise + */ + boolean hasLocation(Place location); + + /** + * Checks if the given time is available. + * @param time the time of the visit to look for + * @return true if the timeslot is already full; false otherwise + */ + boolean hasTime(String time); + + /** + * Saves the location and time to calendar. + * @param location the location to save + * @param time the time to save + */ + void save(Place location, String time); + + +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java new file mode 100644 index 000000000..f3bd6b104 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java @@ -0,0 +1,17 @@ +package use_case.add_to_calendar; + +import use_case.DataAccessException; + +/** +* The Add to Calendar Use Case. +*/ +public interface AddToCalendarInputBoundary { + + /** + * Execute the Add To Calendar Use Case. + * + * @param addToCalendarInputData the input data for this use case + * @throws DataAccessException if data cannot be accessed at any time + */ + void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException; +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java new file mode 100644 index 000000000..a81445c4e --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java @@ -0,0 +1,21 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The input data for the Add to Calendar Use Case. + */ +public class AddToCalendarInputData { + + private final Map addToCalendarPlace; + + public AddToCalendarInputData(Map addToCalendarPlace) { + this.addToCalendarPlace = addToCalendarPlace; + } + + public Map getAddToCalendarPlace() { + return addToCalendarPlace; + } +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java new file mode 100644 index 000000000..c41f02319 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java @@ -0,0 +1,37 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; +import use_case.DataAccessException; + +/** + * The Add to Calendar Interactor. + */ +public class AddToCalendarInteractor implements AddToCalendarInputBoundary { + private final AddToCalendarDataAccessInterface calendarDataAccessObject; + private final AddToCalendarOutputBoundary calendarPresenter; + + public AddToCalendarInteractor(AddToCalendarDataAccessInterface calendarDataAccessObject, + AddToCalendarOutputBoundary calendarPresenter) { + this.calendarDataAccessObject = calendarDataAccessObject; + this.calendarPresenter = calendarPresenter; + } + + @Override + public void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException { + final Map addToCalendarPlace = addToCalendarInputData.getAddToCalendarPlace(); + for (Map.Entry entry : addToCalendarPlace.entrySet()) { + final Place location = entry.getKey(); + final String time = entry.getValue(); + if (calendarDataAccessObject.hasTime(time)) { + calendarPresenter.prepareFailView(time + " is already full."); + } + else { + calendarDataAccessObject.save(location, time); + } + } + final AddToCalendarOutputData addToCalendarOutputData = new AddToCalendarOutputData(addToCalendarPlace); + calendarPresenter.prepareSuccessView(addToCalendarOutputData); + } +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java new file mode 100644 index 000000000..1c6f2e480 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java @@ -0,0 +1,19 @@ +package use_case.add_to_calendar; + +/** + * The output boundary for the Add to Calendar Use Case. + */ +public interface AddToCalendarOutputBoundary { + + /** + * Prepares the success view for the AddToCalendar Use Case. + * @param outputData the output data + */ + void prepareSuccessView(AddToCalendarOutputData outputData); + + /** + * Prepares the failure view for the AddToCalendar Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java new file mode 100644 index 000000000..153eb5aa5 --- /dev/null +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java @@ -0,0 +1,21 @@ +package use_case.add_to_calendar; + +import java.util.Map; + +import entity.Place; + +/** + * The output data for the Add to Calendar Use Case. + */ +public class AddToCalendarOutputData { + + private final Map calendarItems; + + public AddToCalendarOutputData(Map addToCalendarPlace) { + this.calendarItems = addToCalendarPlace; + } + + public Map getcalendarItems() { + return calendarItems; + } +} diff --git a/src/main/java/use_case/locations/LocationsOutputBoundary.java b/src/main/java/use_case/locations/LocationsOutputBoundary.java index 2be723519..904014a0b 100644 --- a/src/main/java/use_case/locations/LocationsOutputBoundary.java +++ b/src/main/java/use_case/locations/LocationsOutputBoundary.java @@ -15,9 +15,4 @@ public interface LocationsOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); - -// /** -// * Switches to the Suggested Locations View. -// */ -// void switchToSuggestedLocationsView(); } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java index 4c32334c1..585d7e52f 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInputData.java @@ -1,6 +1,7 @@ package use_case.suggested_locations; import java.util.List; +import java.util.Map; import entity.Place; @@ -9,14 +10,14 @@ */ public class SuggestedLocationsInputData { - private final List suggestedLocations; + private final Map calendarItems; - public SuggestedLocationsInputData(List suggestedLocations) { - this.suggestedLocations = suggestedLocations; + public SuggestedLocationsInputData(Map calendarItems) { + this.calendarItems = calendarItems; } - public List getSuggestedLocations() { - return suggestedLocations; + public Map getSuggestedLocations() { + return calendarItems; } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java index a615eafd1..3843f22ea 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -1,6 +1,7 @@ package use_case.suggested_locations; import java.util.List; +import java.util.Map; import entity.Place; @@ -9,14 +10,20 @@ */ public class SuggestedLocationsOutputData { + private final Map calendarItems; private final List selectedLocations; private final boolean useCaseFailed; - public SuggestedLocationsOutputData(List selectedLocations, boolean useCaseFailed) { + public SuggestedLocationsOutputData(Map calendarItems, List selectedLocations, boolean useCaseFailed) { this.selectedLocations = selectedLocations; + this.calendarItems = calendarItems; this.useCaseFailed = useCaseFailed; } + public Map getCalendarItems() { + return calendarItems; + } + public List getSelectedLocations() { return selectedLocations; } diff --git a/src/main/java/view/CalendarView.java b/src/main/java/view/CalendarView.java new file mode 100644 index 000000000..54599fbb0 --- /dev/null +++ b/src/main/java/view/CalendarView.java @@ -0,0 +1,110 @@ +package view; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; + +import entity.Place; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import use_case.DataAccessException; + +/** + * The View for when the user is viewing their calendar. + */ +public class CalendarView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "Calendar"; + private final AddToCalendarViewModel calendarViewModel; + private final AddToCalendarController addToCalendarController; + + private final JPanel calendarPanel; + private final JButton newSearchButton; + + private String[] calendarTimes = new String[]{"7:00AM", "8:00AM", "9:00AM", "10:00AM", "11:00AM", "12:00PM", + "1:00PM", "2:00PM", "3:00PM", "4:00PM", "5:00PM", "6:00PM", "7:00PM", "8:00PM", "9:00PM", "10:00PM"}; + + private final int viewWidth = 800; + private final int viewHeight = 1200; + + public CalendarView(AddToCalendarViewModel calendarViewModel, AddToCalendarController addToCalendarController) { + this.calendarViewModel = calendarViewModel; + this.calendarViewModel.addPropertyChangeListener(this); + this.addToCalendarController = addToCalendarController; + + this.setLayout(new BorderLayout()); + + final JLabel title = new JLabel("Calendar"); + title.setFont(new Font("Arial", Font.BOLD, 24)); + final JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + titlePanel.add(title); + this.add(titlePanel, BorderLayout.NORTH); + + this.calendarPanel = new JPanel(); + this.calendarPanel.setLayout(new BoxLayout(calendarPanel, BoxLayout.Y_AXIS)); + this.add(calendarPanel, BorderLayout.WEST); + + this.newSearchButton = new JButton("New Search"); + newSearchButton.addActionListener(this); + final JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(newSearchButton); + this.add(bottomPanel, BorderLayout.SOUTH); + + System.out.println(calendarViewModel.getState().getCalendarItems()); + updateCalendarView(calendarViewModel.getState()); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(newSearchButton)) { + final AddToCalendarState currentState = calendarViewModel.getState(); + try { + addToCalendarController.execute(currentState.getCalendarItems()); + } + catch (DataAccessException e) { + throw new RuntimeException(); + } + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("state".equals(evt.getPropertyName())) { + System.out.println("update (calendar view)"); + updateCalendarView((AddToCalendarState) evt.getNewValue()); + } + } + + private void updateCalendarView(AddToCalendarState state) { + final Map calendarItems = state.getCalendarItems(); + System.out.println("line 75"); + for (int i = 0; i < calendarTimes.length; i++) { + final JPanel timePanel = new JPanel(); + final JTextField timeField = new JTextField(calendarTimes[i]); + timePanel.add(timeField); + for (Map.Entry entry : calendarItems.entrySet()) { + if (entry.getValue().equals(calendarTimes[i])) { + final JTextField locationField = new JTextField(entry.getKey().getName()); + final JTextField addressField = new JTextField(entry.getKey().getAddress()); + timePanel.add(locationField); + timePanel.add(addressField); + } + } +// timePanel.add(Box.createVerticalStrut(calendarTimes.length)); +// timePanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + calendarPanel.add(timePanel); + } + calendarPanel.revalidate(); + calendarPanel.repaint(); + this.setPreferredSize(new Dimension(viewWidth, viewHeight)); + } + + public String getViewName() { + return viewName; + } +} diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 6f0641a1e..2f3407abe 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -5,15 +5,25 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.time.LocalDate; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.swing.*; import entity.Place; +import interface_adapter.add_to_calendar.AddToCalendarController; +import interface_adapter.add_to_calendar.AddToCalendarState; +import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import interface_adapter.location.LocationController; +import interface_adapter.location.LocationState; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsState; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.DataAccessException; /** * The View for when the user receives a list of suggested locations in the program. @@ -21,18 +31,29 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, PropertyChangeListener { private final String viewName = "Suggested Locations"; +// private final LocationViewModel locationViewModel; +// private final LocationController locationController; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; + private final AddToCalendarViewModel calendarViewModel; private final JPanel suggestedLocationsPanel; private final JButton newSearchButton; + private final JButton saveToCalendarButton; private final List selectedLocations; + private final Map calendarLocations; + + private final int numLocationsDisplayed = 5; + private final int viewWidth = 800; + private final int viewHeight = 1200; public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, - SuggestedLocationsController suggestedLocationsController) { + SuggestedLocationsController suggestedLocationsController, + AddToCalendarViewModel calendarViewModel) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; + this.calendarViewModel = calendarViewModel; final JLabel title = new JLabel("List of Suggested Locations:"); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -42,24 +63,23 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.newSearchButton = new JButton("New Search"); newSearchButton.addActionListener(this); + newSearchButton.setAlignmentX(Component.CENTER_ALIGNMENT); + + this.saveToCalendarButton = new JButton("Save to Calendar"); + saveToCalendarButton.addActionListener(this); this.selectedLocations = new ArrayList<>(); + this.calendarLocations = new HashMap<>(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); this.add(suggestedLocationsPanel); this.add(newSearchButton); + this.add(saveToCalendarButton); updateSuggestedLocations(suggestedLocationsViewModel.getState()); } - @Override - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(newSearchButton)) { - // Handle new search button click - } - } - @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equals(evt.getPropertyName())) { @@ -71,11 +91,11 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { suggestedLocationsPanel.removeAll(); final List suggestedLocations = state.getSuggestedLocations(); if (suggestedLocations != null) { - for (int i = 0; i < Math.min(10, suggestedLocations.size()); i++) { + for (int i = 0; i < Math.min(numLocationsDisplayed, suggestedLocations.size()); i++) { final Place location = suggestedLocations.get(i); - JPanel locationPanel = new JPanel(); - locationPanel.setLayout(new BoxLayout(locationPanel, BoxLayout.Y_AXIS)); - JCheckBox checkBox = new JCheckBox(); + final JPanel locationPanel = new JPanel(); + locationPanel.setLayout(new FlowLayout()); + final JCheckBox checkBox = new JCheckBox(); checkBox.addActionListener(e -> { if (checkBox.isSelected()) { selectedLocations.add(location); @@ -84,22 +104,67 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { selectedLocations.remove(location); } }); + // array of string containing cities + final String[] times = new String[]{"None", "7:00AM", "8:00AM", "9:00AM", "10:00AM", "11:00AM", + "12:00PM", "1:00PM", "2:00PM", "3:00PM", "4:00PM", "5:00PM", "6:00PM", "7:00PM", "8:00PM", + "9:00PM", "10:00PM"}; + // create checkbox + final JComboBox timeSelection = new JComboBox<>(times); + // add ItemListener + timeSelection.addItemListener(e -> { + // if the state combobox is changed + if (e.getSource() == timeSelection) { + if (timeSelection.getSelectedItem().equals("None")) { + calendarLocations.remove(location); + } + else { + calendarLocations.put(location, timeSelection.getSelectedItem().toString()); + } + } + }); locationPanel.add(checkBox); locationPanel.add(new JLabel(location.getName())); locationPanel.add(new JLabel(location.getAddress())); - locationPanel.add(Box.createVerticalStrut(10)); + locationPanel.add(Box.createVerticalStrut(numLocationsDisplayed)); + locationPanel.add(timeSelection); + locationPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); suggestedLocationsPanel.add(locationPanel); } + final AddToCalendarState currentState = calendarViewModel.getState(); + currentState.setCalendarItems(calendarLocations); + calendarViewModel.setState(currentState); } else { JOptionPane.showMessageDialog(this, "No suggested locations available.", "Info", JOptionPane.INFORMATION_MESSAGE); } suggestedLocationsPanel.revalidate(); suggestedLocationsPanel.repaint(); - this.setPreferredSize(new Dimension(800, 1200)); + this.setPreferredSize(new Dimension(viewWidth, viewHeight)); } + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(newSearchButton)) { +// final LocationState currentState = locationViewModel.getState(); +// try { +// locationController.execute(currentState.getAddress(), currentState.getLocationType()); +// } +// catch (DataAccessException e) { +// throw new RuntimeException(); +// } + } + if (evt.getSource().equals(saveToCalendarButton)) { + final AddToCalendarState currentState = calendarViewModel.getState(); + try { + suggestedLocationsController.execute(currentState.getCalendarItems()); + } + catch (DataAccessException e) { + throw new RuntimeException(e); + } + } + } + public String getViewName() { return viewName; } -} \ No newline at end of file +} diff --git a/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java new file mode 100644 index 000000000..88ed09b70 --- /dev/null +++ b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java @@ -0,0 +1,87 @@ +package use_case.add_to_calendar; + +import data_access.InMemoryCalendarDataAccessObject; +import entity.Place; +import entity.SuggestedPlace; +import entity.SuggestedPlaceFactory; +import org.junit.Test; +import use_case.DataAccessException; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class AddToCalendarInteractorTest { + + @Test + public void successTest() { + SuggestedPlaceFactory factory = new SuggestedPlaceFactory(); + Place inputPlace = factory.create("University of Toronto","27 King's College Cir, Toronto"); + Map inputData = new HashMap<>(); + String inputTime = "12:30"; + inputData.put(inputPlace, inputTime); + AddToCalendarInputData calendarInputData = new AddToCalendarInputData(inputData); + AddToCalendarDataAccessInterface calendarRepository = new InMemoryCalendarDataAccessObject(); + + // Add University of Toronto to the data access repository. + calendarRepository.save(inputPlace, inputTime); + + // Create a successPresenter to test the test case + AddToCalendarOutputBoundary successPresenter = new AddToCalendarOutputBoundary() { + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + assertEquals("University of Toronto", inputPlace.getName()); + } + + @Override + public void prepareFailView(String errorMessage) { + fail("Use case failure is unexpected."); + } + }; + + AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); + try{ + interactor.execute(calendarInputData); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } + } + + @Test + public void failureTimeslotBookedTest() { + SuggestedPlaceFactory factory = new SuggestedPlaceFactory(); + Place inputPlace = factory.create("University of Toronto","27 King's College Cir, Toronto"); + Map inputData = new HashMap<>(); + String inputTime = "12:30"; + inputData.put(inputPlace, inputTime); + String inputTime2 = "12:30"; + inputData.put(inputPlace, inputTime2); + AddToCalendarInputData calendarInputData = new AddToCalendarInputData(inputData); + AddToCalendarDataAccessInterface calendarRepository = new InMemoryCalendarDataAccessObject(); + + // Add University of Toronto to the data access repository. + calendarRepository.save(inputPlace, inputTime); + + // Create a successPresenter to test the test case + AddToCalendarOutputBoundary successPresenter = new AddToCalendarOutputBoundary() { + @Override + public void prepareSuccessView(AddToCalendarOutputData outputData) { + fail("Use case success is unexpected."); + } + + @Override + public void prepareFailView(String errorMessage) { + assertEquals("12:30 is already full.", errorMessage); + } + }; + + AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); + try{ + interactor.execute(calendarInputData); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } + } +} From a740fc68c5f406746bb506dbee09d2df2aa1a03e Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Sun, 1 Dec 2024 04:51:07 -0500 Subject: [PATCH 098/113] created execute method in interactor to check for filters and change suggested locations as needed --- .../DBLocationDataAccessObject.java | 1 + .../location/LocationController.java | 8 +-- .../locations/LocationsInputBoundary.java | 5 +- .../locations/LocationsInteractor.java | 35 ++++++++++--- src/main/java/view/LocationView.java | 51 +++++-------------- 5 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 6957731ed..0e6298100 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -81,4 +81,5 @@ else if (responseBody.has("error")) { throw new DataAccessException(ex.getMessage()); } } + } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 3742b54ed..2a95fc71b 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -28,15 +28,11 @@ public LocationController(LocationsInputBoundary locationInteractor) { */ - public void execute(String address, String locationType) throws DataAccessException { + public void execute(String address, String locationType, String currentFilter) throws DataAccessException { final LocationsInputData locationInputData = new LocationsInputData( address, locationType); - locationInput.execute(locationInputData); - } - - public void clearSaved() { - + locationInput.execute(locationInputData, currentFilter); } // /** diff --git a/src/main/java/use_case/locations/LocationsInputBoundary.java b/src/main/java/use_case/locations/LocationsInputBoundary.java index 96d2b9c63..838406368 100644 --- a/src/main/java/use_case/locations/LocationsInputBoundary.java +++ b/src/main/java/use_case/locations/LocationsInputBoundary.java @@ -10,7 +10,8 @@ public interface LocationsInputBoundary { * Execute the Suggest Locations Use Case. * * @param locationsInputData the input data for this use case + * @param currentFilter * @throws DataAccessException if data cannot be accessed at any time */ - void execute(LocationsInputData locationsInputData) throws DataAccessException; -} \ No newline at end of file + void execute(LocationsInputData locationsInputData, String currentFilter) throws DataAccessException; +} diff --git a/src/main/java/use_case/locations/LocationsInteractor.java b/src/main/java/use_case/locations/LocationsInteractor.java index 26e0e4ce5..ab5d99564 100644 --- a/src/main/java/use_case/locations/LocationsInteractor.java +++ b/src/main/java/use_case/locations/LocationsInteractor.java @@ -1,7 +1,11 @@ package use_case.locations; +import entity.Place; import use_case.DataAccessException; +import entity.User; +import java.util.List; +import java.util.Map; /** * The Suggest Locations Interactor. @@ -17,11 +21,28 @@ public LocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceData } @Override - public void execute(LocationsInputData locationsInputData) throws DataAccessException { - final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject.searchLocation( - locationsInputData.getAddress(), - locationsInputData.getLocationType()), - false); - placePresenter.prepareSuccessView(locationsOutputData); - } + public void execute(LocationsInputData locationsInputData, String currentFilter) throws DataAccessException { + final List suggestedPlaces = placeDataAccessObject + .searchLocation(locationsInputData.getAddress(), locationsInputData.getLocationType()); + + if ("None".equals(currentFilter)) { + final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject + .searchLocation(locationsInputData.getAddress(), locationsInputData.getLocationType()), + false); + placePresenter.prepareSuccessView(locationsOutputData); + } + else if ("Remove Saved Locations".equals(currentFilter)) { + for (Place place : suggestedPlaces) { + final User user = userDataAccessObject.getUser(); + for (Map.Entry> entry : user.getSavedPlaces().entrySet()) { + if (entry.getValue().contains(place)) { + suggestedPlaces.remove(place); + } + } + } + final LocationsOutputData locationsOutputData = new LocationsOutputData(suggestedPlaces, false); + placePresenter.prepareSuccessView(locationsOutputData); + } +} + } diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 0d87fffb1..4165bdd54 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -54,7 +54,7 @@ public LocationView(LocationViewModel locationViewModel, LocationController loca suggestLocationsButton = new JButton("Suggest Locations"); buttons.add(suggestLocationsButton); final JLabel filterLabel = new JLabel("Filters:"); - final String[] filters = {"None", "Remove Disliked Locations", "Removed Saved Locations"}; + final String[] filters = {"None", "Remove Disliked Locations", "Remove Saved Locations"}; filtersDropDown = new JComboBox<>(filters); buttons.add(filterLabel); buttons.add(filtersDropDown); @@ -128,38 +128,14 @@ public void changedUpdate(DocumentEvent e) { suggestLocationsButton.addActionListener(evt -> { if (evt.getSource().equals(suggestLocationsButton)) { - currentFilter = filtersDropDown.getSelectedItem().toString(); - - if ("None".equals(currentFilter)) { - final LocationState currentState = locationViewModel.getState(); - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } - catch (DataAccessException e) { - throw new RuntimeException(e); - } + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType(), currentFilter); } - - if ("Removed Saved Locations".equals(currentFilter)) { - final LocationState currentState = locationViewModel.getState(); - try { - locationController.clearSaved(); - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } - catch (DataAccessException e) { - throw new RuntimeException(e); + catch (DataAccessException e) { + throw new RuntimeException(e); } - } -// if ("Remove Disliked Locations".equals(currentFilter)) { -// final LocationState currentState = locationViewModel.getState(); -// try { -// locationController.execute(currentState.getAddress(), currentState.getLocationType()); -// } -// catch (DataAccessException e) { -// throw new RuntimeException(e); -// } -// } } }); } @@ -167,15 +143,12 @@ public void changedUpdate(DocumentEvent e) { @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { - if ("None".equals(currentFilter)) { - final LocationState currentState = locationViewModel.getState(); - - try { - locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } - catch (DataAccessException e) { - throw new RuntimeException(e); - } + final LocationState currentState = locationViewModel.getState(); + try { + locationController.execute(currentState.getAddress(), currentState.getLocationType(), currentFilter); + } + catch (DataAccessException e) { + throw new RuntimeException(e); } } } From 44813d5ebb7dfb7a7e34989f35da6150299700d0 Mon Sep 17 00:00:00 2001 From: teddy Date: Sun, 1 Dec 2024 05:40:23 -0500 Subject: [PATCH 099/113] fixed user entity --- src/main/java/entity/User.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index f16678913..9d5833990 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The representation of a password-protected user for our program. @@ -10,7 +11,7 @@ public class User { private final String name; private final String password; - private final HashMap> savedPlaces; + private final Map> savedPlaces; public User(String name, String password, HashMap> savedPlaces) { this.name = name; @@ -26,7 +27,7 @@ public String getPassword() { return password; } - public HashMap> getSavedPlaces() { + public Map> getSavedPlaces() { return savedPlaces; } } From b79ccfb3851ae492aea516286fb5872bf0e88ca9 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 1 Dec 2024 06:05:15 -0500 Subject: [PATCH 100/113] fixed some bugs --- src/main/java/app/MainWithDB.java | 4 +- .../app/SelectedLocationsUseCaseFactory.java | 9 ++- .../app/SuggestedLocationsUseCaseFactory.java | 3 +- .../ReviewLocationController.java | 2 +- .../SelectedLocationsController.java | 8 ++- .../SelectedLocationsPresenter.java | 17 ++++- .../SelectedLocationsState.java | 10 +++ src/main/java/view/SelectedLocationView.java | 69 ++++++++++--------- 8 files changed, 80 insertions(+), 42 deletions(-) diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 17bfdda34..dbbc48622 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -1,5 +1,6 @@ package app; +import data_access.DBCoordinatesDataAccessObject; import data_access.DBLocationDataAccessObject; import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; @@ -46,6 +47,7 @@ public static void main(String[] args) { final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); + final DBCoordinatesDataAccessObject coordinatesDataAccessObject = new DBCoordinatesDataAccessObject(); final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, suggestedLocationsViewModel, locationDataAccessObject); @@ -56,7 +58,7 @@ public static void main(String[] args) { views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel, - selectedLocationsViewModel); + selectedLocationsViewModel, coordinatesDataAccessObject); views.add(selectedLocationView, selectedLocationView.getViewName()); viewManagerModel.setState(locationView.getViewName()); diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java index bb3405638..32ba8b16a 100644 --- a/src/main/java/app/SelectedLocationsUseCaseFactory.java +++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java @@ -1,5 +1,6 @@ package app; +import data_access.DBCoordinatesDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.selectedlocation.SelectedLocationsController; import interface_adapter.selectedlocation.SelectedLocationsPresenter; @@ -30,18 +31,20 @@ private SelectedLocationsUseCaseFactory() { */ public static SelectedLocationView create( ViewManagerModel viewManagerModel, - SelectedLocationsViewModel selectedLocationsViewModel) { + SelectedLocationsViewModel selectedLocationsViewModel, + DBCoordinatesDataAccessObject coordinatesDataAccessObject) { final SelectedLocationsController selectedLocationsController = createSelectedLocationUseCase(viewManagerModel, - selectedLocationsViewModel); + selectedLocationsViewModel, coordinatesDataAccessObject); return new SelectedLocationView(selectedLocationsViewModel, selectedLocationsController); } private static SelectedLocationsController createSelectedLocationUseCase( ViewManagerModel viewManagerModel, - SelectedLocationsViewModel selectedLocationsViewModel) { + SelectedLocationsViewModel selectedLocationsViewModel, + DBCoordinatesDataAccessObject coordinatesDataAccessObject) { // final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( // viewManagerModel, selectedLocationsViewModel); // final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 1528e9a54..2a45f4a40 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -38,7 +38,8 @@ public static SuggestedLocationsView create( suggestedLocationsViewModel, selectedLocationsViewModel); // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) - return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); + return new SuggestedLocationsView(suggestedLocationsViewModel, + suggestedLocationsController, selectedLocationsViewModel); } private static SuggestedLocationsController createSuggestedLocationUseCase( diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java index 29c270af8..fdb1dcd9a 100644 --- a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java @@ -2,6 +2,6 @@ public class ReviewLocationController { - private final + } diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java index a62677988..4f04181dd 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java @@ -6,6 +6,8 @@ import use_case.selected_locations.SelectedLocationsInputBoundary; import use_case.selected_locations.SelectedLocationsInputData; +import java.util.List; + public class SelectedLocationsController { private final SelectedLocationsInputBoundary selectedLocationsInteractor; @@ -14,8 +16,10 @@ public SelectedLocationsController(SelectedLocationsInputBoundary selectedLocati this.selectedLocationsInteractor = selectedLocationsInteractor; } - public void execute() throws DataAccessException { - final SelectedLocationsInputData selectedLocationsInputData = new SelectedLocationsInputData(); + public void execute(List selectedLocations) throws DataAccessException { + final SelectedLocationsInputData selectedLocationsInputData = + new SelectedLocationsInputData(selectedLocations); + selectedLocationsInteractor.execute(selectedLocationsInputData); } } diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java index 0943271ba..9e7b6c0bd 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java @@ -1,15 +1,30 @@ package interface_adapter.selectedlocation; +import interface_adapter.ViewManagerModel; +import interface_adapter.suggestlocation.SuggestedLocationsState; import use_case.selected_locations.SelectedLocationsOutputBoundary; import use_case.selected_locations.SelectedLocationsOutputData; public class SelectedLocationsPresenter implements SelectedLocationsOutputBoundary { + private final SelectedLocationsViewModel selectedLocationsViewModel; + private final ViewManagerModel viewManagerModel; + public SelectedLocationsPresenter(SelectedLocationsViewModel selectedLocationsViewModel, + ViewManagerModel viewManagerModel) { + this.selectedLocationsViewModel = selectedLocationsViewModel; + this.viewManagerModel = viewManagerModel; + } @Override public void prepareSuccessView(SelectedLocationsOutputData outputData) { - + final SelectedLocationsState selectedLocationsState = + selectedLocationsViewModel.getState(); + selectedLocationsState.setPlaceToCoordinates(outputData.getLocationCoordinatesMap()); + this.selectedLocationsViewModel.setState(selectedLocationsState); + this.selectedLocationsViewModel.firePropertyChanged(); + this.viewManagerModel.setState(selectedLocationsViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); } @Override diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java index e6214082c..60a7b6a21 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java @@ -3,6 +3,7 @@ import entity.Place; import java.util.List; +import java.util.Map; /** * The state representing selected location-related data, including a list of @@ -11,6 +12,7 @@ public class SelectedLocationsState { private List selectedLocations; + private Map placeToCoordinates; private String error; public List getSelectedLocations() { @@ -21,6 +23,14 @@ public void setSelectedLocations(List selectedLocations) { this.selectedLocations = selectedLocations; } + public void setPlaceToCoordinates(Map placeToCoordinates) { + this.placeToCoordinates = placeToCoordinates; + } + + public Map getPlaceToCoordinates() { + return placeToCoordinates; + } + public String getError() { return error; } diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java index 103ebf2d8..fbbb2c4fa 100644 --- a/src/main/java/view/SelectedLocationView.java +++ b/src/main/java/view/SelectedLocationView.java @@ -1,23 +1,27 @@ package view; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.net.URI; import java.util.List; +import java.util.Map; import entity.Place; import interface_adapter.selectedlocation.SelectedLocationsController; +import interface_adapter.selectedlocation.SelectedLocationsState; import interface_adapter.selectedlocation.SelectedLocationsViewModel; -import use_case.selected_locations.SelectedLocationsOutputData; +import use_case.DataAccessException; /** * The View for when the user has selected a location in the program. */ public class SelectedLocationView extends JPanel implements ActionListener, PropertyChangeListener { - private final String viewName = "Selected Location"; + private final String viewName = "Selected Locations"; private final SelectedLocationsViewModel selectedLocationsViewModel; private final SelectedLocationsController selectedLocationsController; @@ -29,60 +33,59 @@ public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewMode this.selectedLocationsViewModel.addPropertyChangeListener(this); this.selectedLocationsController = selectedLocationsController; + final JLabel title = new JLabel("Selected Locations:"); + title.setAlignmentX(JLabel.CENTER_ALIGNMENT); + this.selectedLocationPanel = new JPanel(); this.selectedLocationPanel.setLayout(new BoxLayout(selectedLocationPanel, BoxLayout.Y_AXIS)); + this.add(title); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(selectedLocationPanel); - updateSelectedLocations(selectedLocationsViewModel.getState().getSelectedLocations()); - } - - @Override - public void actionPerformed(ActionEvent e) { - final JButton sourceButton = (JButton) e.getSource(); - final String locationName = sourceButton.getText().replace("Get " + "Address for ", ""); - final List selectedLocations = selectedLocationsViewModel.getState().getSelectedLocations(); - - for (Place location : selectedLocations) { - if (location.getName().equals(locationName)) { - try { - String coordinates = - SelectedLocationsOutputData.getLocationCoordinatesMap().get(location); - String message = - "https://maps.google.com/?q=" + coordinates[0] + "," + coordinates[1]; - } - catch (Exception ex) { - JOptionPane.showMessageDialog(this, "Failed to fetch coordinates for " + locationName, "Error", JOptionPane.ERROR_MESSAGE); - } - break; - } - } + updateSelectedLocations(selectedLocationsViewModel.getState()); } @Override public void propertyChange(PropertyChangeEvent evt) { - if ("selectedLocations".equals(evt.getPropertyName())) { - updateSelectedLocations((List) evt.getNewValue()); + if ("state".equals(evt.getPropertyName())) { + updateSelectedLocations((SelectedLocationsState) evt.getNewValue()); } } - private void updateSelectedLocations(List selectedLocations) { + private void updateSelectedLocations(SelectedLocationsState state) { selectedLocationPanel.removeAll(); + final List selectedLocations = state.getSelectedLocations(); for (Place location : selectedLocations) { final JLabel nameLabel = new JLabel(location.getName()); final JLabel addressLabel = new JLabel(location.getAddress()); - final JButton actionButton = - new JButton("Get Address for " + location.getName()); - actionButton.addActionListener(this); + final JButton actionButton = new JButton("Get Directions to " + location.getName()); + final Map map = + selectedLocationsViewModel.getState().getPlaceToCoordinates(); + actionButton.addActionListener(evt -> { + if (actionButton.isSelected()) { + String coordinates = map.get(location); + String url = "https://maps.google.com/?q=" + coordinates; + JOptionPane.showMessageDialog(this, url, "Directions", JOptionPane.INFORMATION_MESSAGE); + } + } + ); selectedLocationPanel.add(nameLabel); selectedLocationPanel.add(addressLabel); selectedLocationPanel.add(actionButton); selectedLocationPanel.add(Box.createVerticalStrut(10)); + + selectedLocationPanel.revalidate(); + selectedLocationPanel.repaint(); } - selectedLocationPanel.revalidate(); - selectedLocationPanel.repaint(); + } + + /** + * This method is not used in this class. + */ + @Override + public void actionPerformed(ActionEvent e) { } public String getViewName() { From aa0f65c94ab771761e5bf79f7130edf850f81035 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Sun, 1 Dec 2024 18:31:34 -0500 Subject: [PATCH 101/113] fixed some bugs --- src/main/java/data_access/DBLocationDataAccessObject.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 6957731ed..3fdc90ba5 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -55,7 +55,8 @@ public List searchLocation(String address, String locationType) throws Da final StringBuilder places = new StringBuilder(); final JSONArray jsonArray = responseBody.getJSONArray("places"); for (int i = 0; i < jsonArray.length(); i++) { - final JSONObject jsonObject = jsonArray.getJSONObject(i); + final JSONObject jsonObject = + jsonArray.getJSONmicsObject(i); places.append(jsonObject.getString("formattedAddress")).append(">").append(jsonObject .getJSONObject("displayName").getString("text")).append("<"); } From 743f25f03365c24db2aeb0eb67dfc5aac0b7e425 Mon Sep 17 00:00:00 2001 From: yasmatopia Date: Sun, 1 Dec 2024 19:04:41 -0500 Subject: [PATCH 102/113] fixed sign up and log in views, etc. --- src/main/java/app/LoginUseCaseFactory.java | 58 ++++++ src/main/java/app/MainWithDB.java | 21 ++- src/main/java/app/SignupUseCaseFactory.java | 40 +++- .../java/app/UserProfileUseCaseFactory.java | 4 +- ...java => InMemoryUserDataAccessObject.java} | 2 +- .../location/LocationSearchFailed.java | 7 - .../login/LoginController.java | 28 +++ .../login/LoginPresenter.java | 45 +++++ .../interface_adapter/login/LoginState.java | 35 ++++ .../login/LoginViewModel.java | 15 ++ .../signup/SignupPresenter.java | 33 +++- .../interface_adapter/signup/SignupState.java | 67 +++++++ .../signup/SignupViewModel.java | 14 +- .../use_case/login/LoginInputBoundary.java | 13 ++ .../java/use_case/login/LoginInputData.java | 24 +++ .../java/use_case/login/LoginInteractor.java | 39 ++++ .../use_case/login/LoginOutputBoundary.java | 18 ++ .../java/use_case/login/LoginOutputData.java | 20 ++ .../login/LoginUserDataAccessInterface.java | 41 ++++ .../use_case/signup/SignupInteractor.java | 16 +- .../use_case/signup/SignupOutputBoundary.java | 2 +- src/main/java/view/LoginView.java | 150 +++++++++++++++ src/main/java/view/SignupView.java | 176 +++++++++++++++--- 23 files changed, 793 insertions(+), 75 deletions(-) create mode 100644 src/main/java/app/LoginUseCaseFactory.java rename src/main/java/data_access/{InMemoryUserDataAccess.java => InMemoryUserDataAccessObject.java} (94%) delete mode 100644 src/main/java/interface_adapter/location/LocationSearchFailed.java create mode 100644 src/main/java/interface_adapter/login/LoginController.java create mode 100644 src/main/java/interface_adapter/login/LoginPresenter.java create mode 100644 src/main/java/interface_adapter/login/LoginState.java create mode 100644 src/main/java/interface_adapter/login/LoginViewModel.java create mode 100644 src/main/java/interface_adapter/signup/SignupState.java create mode 100644 src/main/java/use_case/login/LoginInputBoundary.java create mode 100644 src/main/java/use_case/login/LoginInputData.java create mode 100644 src/main/java/use_case/login/LoginInteractor.java create mode 100644 src/main/java/use_case/login/LoginOutputBoundary.java create mode 100644 src/main/java/use_case/login/LoginOutputData.java create mode 100644 src/main/java/use_case/login/LoginUserDataAccessInterface.java create mode 100644 src/main/java/view/LoginView.java diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java new file mode 100644 index 000000000..b532463b4 --- /dev/null +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -0,0 +1,58 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.user_profile.UserProfileViewModel; +import interface_adapter.login.LoginController; +import interface_adapter.login.LoginPresenter; +import interface_adapter.login.LoginViewModel; +import use_case.login.LoginInputBoundary; +import use_case.login.LoginInteractor; +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginUserDataAccessInterface; +import view.LoginView; + +/** + * This class contains the static factory function for creating the LoginView. + */ +public final class LoginUseCaseFactory { + + /** Prevent instantiation. */ + private LoginUseCaseFactory() { + + } + + /** + * Factory function for creating the LoginView. + * @param viewManagerModel the ViewManagerModel to inject into the LoginView + * @param loginViewModel the LoginViewModel to inject into the LoginView + * @param userProfileViewModel the LoggedInViewModel to inject into the LoginView + * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView + * @return the LoginView created for the provided input classes + */ + public static LoginView create( + ViewManagerModel viewManagerModel, + LoginViewModel loginViewModel, + UserProfileViewModel userProfileViewModel, + LoginUserDataAccessInterface userDataAccessObject) { + + final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel, + userProfileViewModel, userDataAccessObject); + return new LoginView(loginViewModel, loginController); + + } + + private static LoginController createLoginUseCase( + ViewManagerModel viewManagerModel, + LoginViewModel loginViewModel, + UserProfileViewModel userProfileViewModel, + LoginUserDataAccessInterface userDataAccessObject) { + + // Notice how we pass this method's parameters to the Presenter. + final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, + userProfileViewModel, loginViewModel); + final LoginInputBoundary loginInteractor = new LoginInteractor( + userDataAccessObject, loginOutputBoundary); + + return new LoginController(loginInteractor); + } +} diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index d39040354..d02ecdb75 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -1,14 +1,14 @@ package app; import data_access.DBLocationDataAccessObject; +import data_access.InMemoryUserDataAccessObject; import entity.SuggestedPlaceFactory; import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationViewModel; +import interface_adapter.login.LoginViewModel; +import interface_adapter.signup.SignupViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; -import view.LocationView; -import view.SuggestedLocationsView; -import view.UserProfileView; -import view.ViewManager; +import view.*; import javax.swing.*; import java.awt.*; @@ -37,7 +37,9 @@ public static void main(String[] args) { final ViewManagerModel viewManagerModel = new ViewManagerModel(); new ViewManager(views, cardLayout, viewManagerModel); + final LoginViewModel loginViewModel = new LoginViewModel(); + final SignupViewModel signupViewModel = new SignupViewModel(); final LocationViewModel locationViewModel = new LocationViewModel(); final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); // add any future view models here in the same way @@ -45,6 +47,17 @@ public static void main(String[] args) { final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); + final InMemoryUserDataAccessObject userDataAccessObject = new InMemoryUserDataAccessObject(); + + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, + signupViewModel, userDataAccessObject); + views.add(signupView, signupView.getViewName()); + + final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, + userProfileViewModel, userDataAccessObject); + // logged in = user profile view + views.add(loginView, loginView.getViewName()); + final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, suggestedLocationsViewModel, locationDataAccessObject); views.add(locationView, locationView.getViewName()); diff --git a/src/main/java/app/SignupUseCaseFactory.java b/src/main/java/app/SignupUseCaseFactory.java index 0055b3e80..fafc1303b 100644 --- a/src/main/java/app/SignupUseCaseFactory.java +++ b/src/main/java/app/SignupUseCaseFactory.java @@ -1,14 +1,15 @@ package app; -import data_access.InMemoryUserDataAccess; import entity.UserFactory; -import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginViewModel; import interface_adapter.signup.SignupController; import interface_adapter.signup.SignupPresenter; import interface_adapter.signup.SignupViewModel; +import interface_adapter.ViewManagerModel; import use_case.signup.SignupInputBoundary; import use_case.signup.SignupInteractor; import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupUserDataAccessInterface; import view.SignupView; /** @@ -18,22 +19,43 @@ public final class SignupUseCaseFactory { /** Prevent instantiation. */ private SignupUseCaseFactory() { + } /** * Factory method for creating the SignupView. * * @param viewManagerModel the ViewManagerModel + * @param loginViewModel the log in view model + * @param signupViewModel the sign up view model + * @param userDataAccessObject the user DAO * @return a SignupView instance */ - public static SignupView create(ViewManagerModel viewManagerModel) { - final InMemoryUserDataAccess userDataAccess = new InMemoryUserDataAccess(); - final SignupViewModel signupViewModel = new SignupViewModel(); - final SignupOutputBoundary signupPresenter = new SignupPresenter(viewManagerModel, signupViewModel); - final UserFactory userFactory = new UserFactory(); - final SignupInputBoundary signupInteractor = new SignupInteractor(userDataAccess, signupPresenter, userFactory); - final SignupController signupController = new SignupController(signupInteractor); + public static SignupView create(ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, + SignupViewModel signupViewModel, + SignupUserDataAccessInterface userDataAccessObject) { + final SignupController signupController = createUserSignupUseCase(viewManagerModel, signupViewModel, + loginViewModel, userDataAccessObject); return new SignupView(signupController, signupViewModel); } + + private static SignupController createUserSignupUseCase(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel, + SignupUserDataAccessInterface userDataAccessObject) { + + // Notice how we pass this method's parameters to the Presenter. + final SignupOutputBoundary signupOutputBoundary = new SignupPresenter(viewManagerModel, + signupViewModel, loginViewModel); + + final UserFactory userFactory = new UserFactory(); + + final SignupInputBoundary userSignupInteractor = new SignupInteractor( + userDataAccessObject, signupOutputBoundary, userFactory); + + return new SignupController(userSignupInteractor); + } } + + diff --git a/src/main/java/app/UserProfileUseCaseFactory.java b/src/main/java/app/UserProfileUseCaseFactory.java index 413260acf..52454ef09 100644 --- a/src/main/java/app/UserProfileUseCaseFactory.java +++ b/src/main/java/app/UserProfileUseCaseFactory.java @@ -1,6 +1,6 @@ package app; -import data_access.InMemoryUserDataAccess; +import data_access.InMemoryUserDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.user.UserProfileController; import interface_adapter.user.UserProfilePresenter; @@ -25,7 +25,7 @@ private UserProfileUseCaseFactory() { * @return a UserProfileView instance */ public static UserProfileView create(ViewManagerModel viewManagerModel) { - final InMemoryUserDataAccess userDataAccess = new InMemoryUserDataAccess(); + final InMemoryUserDataAccessObject userDataAccess = new InMemoryUserDataAccessObject(); final UserViewModel userViewModel = new UserViewModel(); final UserProfilePresenter userProfilePresenter = new UserProfilePresenter(viewManagerModel, userViewModel); final UserProfileInputBoundary userProfileInteractor = diff --git a/src/main/java/data_access/InMemoryUserDataAccess.java b/src/main/java/data_access/InMemoryUserDataAccessObject.java similarity index 94% rename from src/main/java/data_access/InMemoryUserDataAccess.java rename to src/main/java/data_access/InMemoryUserDataAccessObject.java index 06b542ec1..b17777a21 100644 --- a/src/main/java/data_access/InMemoryUserDataAccess.java +++ b/src/main/java/data_access/InMemoryUserDataAccessObject.java @@ -13,7 +13,7 @@ /** * In-memory implementation for storing user data for both sign-up and user profile. */ -public class InMemoryUserDataAccess implements SignupUserDataAccessInterface, UserProfileDataAccessInterface { +public class InMemoryUserDataAccessObject implements SignupUserDataAccessInterface, UserProfileDataAccessInterface { private final Map userDatabase = new HashMap<>(); diff --git a/src/main/java/interface_adapter/location/LocationSearchFailed.java b/src/main/java/interface_adapter/location/LocationSearchFailed.java deleted file mode 100644 index e5abeaa8c..000000000 --- a/src/main/java/interface_adapter/location/LocationSearchFailed.java +++ /dev/null @@ -1,7 +0,0 @@ -package interface_adapter.location; - -public class LocationSearchFailed extends RuntimeException { - public LocationSearchFailed(String error) { - super(error); - } -} diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/interface_adapter/login/LoginController.java new file mode 100644 index 000000000..57e950666 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginController.java @@ -0,0 +1,28 @@ +package interface_adapter.login; + +import use_case.login.LoginInputBoundary; +import use_case.login.LoginInputData; + +/** + * The controller for the Login Use Case. + */ +public class LoginController { + + private final LoginInputBoundary loginUseCaseInteractor; + + public LoginController(LoginInputBoundary loginUseCaseInteractor) { + this.loginUseCaseInteractor = loginUseCaseInteractor; + } + + /** + * Executes the Login Use Case. + * @param username the username of the user logging in + * @param password the password of the user logging in + */ + public void execute(String username, String password) { + final LoginInputData loginInputData = new LoginInputData( + username, password); + + loginUseCaseInteractor.execute(loginInputData); + } +} diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java new file mode 100644 index 000000000..e92727f72 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginPresenter.java @@ -0,0 +1,45 @@ +package interface_adapter.login; + +import interface_adapter.ViewManagerModel; +import interface_adapter.user_profile.UserProfileState; +import interface_adapter.user_profile.UserProfileViewModel; +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginOutputData; + +/** + * The Presenter for the Login Use Case. + */ +public class LoginPresenter implements LoginOutputBoundary { + + private final LoginViewModel loginViewModel; + private final UserProfileViewModel userProfileViewModel; + private final ViewManagerModel viewManagerModel; + + public LoginPresenter(ViewManagerModel viewManagerModel, + UserProfileViewModel userProfileViewModel, + LoginViewModel loginViewModel) { + this.viewManagerModel = viewManagerModel; + this.userProfileViewModel = userProfileViewModel; + this.loginViewModel = loginViewModel; + } + + @Override + public void prepareSuccessView(LoginOutputData response) { + // On success, switch to the logged in view. + + final UserProfileState userProfileState = userProfileViewModel.getState(); + userProfileState.setUsername(response.getUsername()); + this.userProfileViewModel.setState(userProfileState); + this.userProfileViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(userProfileViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + final LoginState loginState = loginViewModel.getState(); + loginState.setLoginError(error); + loginViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/login/LoginState.java b/src/main/java/interface_adapter/login/LoginState.java new file mode 100644 index 000000000..e42632034 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginState.java @@ -0,0 +1,35 @@ +package interface_adapter.login; + +/** + * The state for the Login View Model. + */ +public class LoginState { + private String username = ""; + private String loginError; + private String password = ""; + + public String getUsername() { + return username; + } + + public String getLoginError() { + return loginError; + } + + public String getPassword() { + return password; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setLoginError(String usernameError) { + this.loginError = usernameError; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/src/main/java/interface_adapter/login/LoginViewModel.java b/src/main/java/interface_adapter/login/LoginViewModel.java new file mode 100644 index 000000000..41bea7a2e --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginViewModel.java @@ -0,0 +1,15 @@ +package interface_adapter.login; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Login View. + */ +public class LoginViewModel extends ViewModel { + + public LoginViewModel() { + super("log in"); + setState(new LoginState()); + } + +} diff --git a/src/main/java/interface_adapter/signup/SignupPresenter.java b/src/main/java/interface_adapter/signup/SignupPresenter.java index f5c04eaf8..d8216ec02 100644 --- a/src/main/java/interface_adapter/signup/SignupPresenter.java +++ b/src/main/java/interface_adapter/signup/SignupPresenter.java @@ -1,6 +1,8 @@ package interface_adapter.signup; import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; import use_case.signup.SignupOutputBoundary; import use_case.signup.SignupOutputData; @@ -8,30 +10,41 @@ * Presenter for the signup use case. */ public class SignupPresenter implements SignupOutputBoundary { - private final ViewManagerModel viewManagerModel; + private final SignupViewModel signupViewModel; + private final LoginViewModel loginViewModel; + private final ViewManagerModel viewManagerModel; - public SignupPresenter(ViewManagerModel viewManagerModel, SignupViewModel signupViewModel) { + public SignupPresenter(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel) { this.viewManagerModel = viewManagerModel; this.signupViewModel = signupViewModel; + this.loginViewModel = loginViewModel; } @Override - public void prepareSuccessView(SignupOutputData outputData) { - signupViewModel.setUsername(outputData.getUsername()); - viewManagerModel.setState("LoggedIn"); + public void prepareSuccessView(SignupOutputData response) { + // On success, switch to the login view. + final LoginState loginState = loginViewModel.getState(); + loginState.setUsername(response.getUsername()); + this.loginViewModel.setState(loginState); + loginViewModel.firePropertyChanged(); + + viewManagerModel.setState(loginViewModel.getViewName()); viewManagerModel.firePropertyChanged(); } @Override - public void prepareFailView(String errorMessage) { - signupViewModel.setErrorMessage(errorMessage); - viewManagerModel.firePropertyChanged(); + public void prepareFailView(String error) { + final SignupState signupState = signupViewModel.getState(); + signupState.setUsernameError(error); + signupViewModel.firePropertyChanged(); } @Override - public void prepareSwitchToLoginView() { - viewManagerModel.setState("Login"); + public void switchToLoginView() { + viewManagerModel.setState(loginViewModel.getViewName()); viewManagerModel.firePropertyChanged(); } } diff --git a/src/main/java/interface_adapter/signup/SignupState.java b/src/main/java/interface_adapter/signup/SignupState.java new file mode 100644 index 000000000..ead93994c --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupState.java @@ -0,0 +1,67 @@ +package interface_adapter.signup; + +public class SignupState { + private String username = ""; + private String usernameError; + private String password = ""; + private String passwordError; + private String repeatPassword = ""; + private String repeatPasswordError; + + public String getUsername() { + return username; + } + + public String getUsernameError() { + return usernameError; + } + + public String getPassword() { + return password; + } + + public String getPasswordError() { + return passwordError; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public String getRepeatPasswordError() { + return repeatPasswordError; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setUsernameError(String usernameError) { + this.usernameError = usernameError; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setPasswordError(String passwordError) { + this.passwordError = passwordError; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + + public void setRepeatPasswordError(String repeatPasswordError) { + this.repeatPasswordError = repeatPasswordError; + } + + @Override + public String toString() { + return "SignupState{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", repeatPassword='" + repeatPassword + '\'' + + '}'; + } +} diff --git a/src/main/java/interface_adapter/signup/SignupViewModel.java b/src/main/java/interface_adapter/signup/SignupViewModel.java index 247afcd01..636bffe44 100644 --- a/src/main/java/interface_adapter/signup/SignupViewModel.java +++ b/src/main/java/interface_adapter/signup/SignupViewModel.java @@ -2,17 +2,20 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import interface_adapter.ViewModel; + /** * ViewModel for the signup process, holding state for the signup view. */ -public class SignupViewModel { +public class SignupViewModel extends ViewModel { private String username; private String errorMessage; private final PropertyChangeSupport support; public SignupViewModel() { - this.support = new PropertyChangeSupport(this); + super("sign up"); + setState(new SignupState()); } public String getUsername() { @@ -30,10 +33,6 @@ public void setUsername(String username) { support.firePropertyChange("username", oldUsername, username); } - public String getErrorMessage() { - return errorMessage; - } - /** * Sets the error message and notifies listeners of the change. * @@ -62,4 +61,7 @@ public void addPropertyChangeListener(PropertyChangeListener listener) { public void removePropertyChangeListener(PropertyChangeListener listener) { support.removePropertyChangeListener(listener); } + + public SignupState getState() { + } } diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java new file mode 100644 index 000000000..faf72dc96 --- /dev/null +++ b/src/main/java/use_case/login/LoginInputBoundary.java @@ -0,0 +1,13 @@ +package use_case.login; + +/** + * Input Boundary for actions which are related to logging in. + */ +public interface LoginInputBoundary { + + /** + * Executes the login use case. + * @param loginInputData the input data + */ + void execute(LoginInputData loginInputData); +} diff --git a/src/main/java/use_case/login/LoginInputData.java b/src/main/java/use_case/login/LoginInputData.java new file mode 100644 index 000000000..363316832 --- /dev/null +++ b/src/main/java/use_case/login/LoginInputData.java @@ -0,0 +1,24 @@ +package use_case.login; + +/** + * The Input Data for the Login Use Case. + */ +public class LoginInputData { + + private final String username; + private final String password; + + public LoginInputData(String username, String password) { + this.username = username; + this.password = password; + } + + String getUsername() { + return username; + } + + String getPassword() { + return password; + } + +} diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java new file mode 100644 index 000000000..2ed57f690 --- /dev/null +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -0,0 +1,39 @@ +package use_case.login; + +import entity.User; + +/** + * The Login Interactor. + */ +public class LoginInteractor implements LoginInputBoundary { + private final LoginUserDataAccessInterface userDataAccessObject; + private final LoginOutputBoundary loginPresenter; + + public LoginInteractor(LoginUserDataAccessInterface userDataAccessInterface, + LoginOutputBoundary loginOutputBoundary) { + this.userDataAccessObject = userDataAccessInterface; + this.loginPresenter = loginOutputBoundary; + } + + @Override + public void execute(LoginInputData loginInputData) { + final String username = loginInputData.getUsername(); + final String password = loginInputData.getPassword(); + if (!userDataAccessObject.existsByName(username)) { + loginPresenter.prepareFailView(username + ": Account does not exist."); + } + else { + final String pwd = userDataAccessObject.get(username).getPassword(); + if (!password.equals(pwd)) { + loginPresenter.prepareFailView("Incorrect password for \"" + username + "\"."); + } + else { + + final User user = userDataAccessObject.get(loginInputData.getUsername()); + userDataAccessObject.setCurrentUser(user.getName()); + final LoginOutputData loginOutputData = new LoginOutputData(user.getName(), false); + loginPresenter.prepareSuccessView(loginOutputData); + } + } + } +} diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java new file mode 100644 index 000000000..08bc4731f --- /dev/null +++ b/src/main/java/use_case/login/LoginOutputBoundary.java @@ -0,0 +1,18 @@ +package use_case.login; + +/** + * The output boundary for the Login Use Case. + */ +public interface LoginOutputBoundary { + /** + * Prepares the success view for the Login Use Case. + * @param outputData the output data + */ + void prepareSuccessView(LoginOutputData outputData); + + /** + * Prepares the failure view for the Login Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/login/LoginOutputData.java b/src/main/java/use_case/login/LoginOutputData.java new file mode 100644 index 000000000..3ea119a8f --- /dev/null +++ b/src/main/java/use_case/login/LoginOutputData.java @@ -0,0 +1,20 @@ +package use_case.login; + +/** + * Output Data for the Login Use Case. + */ +public class LoginOutputData { + + private final String username; + private final boolean useCaseFailed; + + public LoginOutputData(String username, boolean useCaseFailed) { + this.username = username; + this.useCaseFailed = useCaseFailed; + } + + public String getUsername() { + return username; + } + +} diff --git a/src/main/java/use_case/login/LoginUserDataAccessInterface.java b/src/main/java/use_case/login/LoginUserDataAccessInterface.java new file mode 100644 index 000000000..72a1baca9 --- /dev/null +++ b/src/main/java/use_case/login/LoginUserDataAccessInterface.java @@ -0,0 +1,41 @@ +package use_case.login; + +import entity.User; + +/** + * DAO for the Login Use Case. + */ +public interface LoginUserDataAccessInterface { + + /** + * Checks if the given username exists. + * @param username the username to look for + * @return true if a user with the given username exists; false otherwise + */ + boolean existsByName(String username); + + /** + * Saves the user. + * @param user the user to save + */ + void save(User user); + + /** + * Returns the user with the given username. + * @param username the username to look up + * @return the user with the given username + */ + User get(String username); + + /** + * Sets the current user. + * @param name is the name of the user. + */ + void setCurrentUser(String name); + + /** + * Gets the current user. + * @return the current username. + */ + String getCurrentUser(); +} diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java index cfc9c7bf5..ece1512ec 100644 --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -9,14 +9,14 @@ */ public class SignupInteractor implements SignupInputBoundary { private final SignupUserDataAccessInterface userDataAccess; - private final SignupOutputBoundary signupOutputBoundary; + private final SignupOutputBoundary userPresenter; private final UserFactory userFactory; public SignupInteractor(SignupUserDataAccessInterface userDataAccess, SignupOutputBoundary signupOutputBoundary, UserFactory userFactory) { this.userDataAccess = userDataAccess; - this.signupOutputBoundary = signupOutputBoundary; + this.userPresenter = signupOutputBoundary; this.userFactory = userFactory; } @@ -28,26 +28,26 @@ public void execute(SignupInputData signupInputData) { try { if (userDataAccess.existsByName(username)) { - signupOutputBoundary.prepareFailView("User already exists."); + userPresenter.prepareFailView("User already exists."); } else if (!password.equals(repeatPassword)) { - signupOutputBoundary.prepareFailView("Passwords don't match."); + userPresenter.prepareFailView("Passwords don't match."); } else { final User newUser = userFactory.create(username, password); userDataAccess.save(newUser); - final SignupOutputData signupOutputData = new SignupOutputData(username, false); - signupOutputBoundary.prepareSuccessView(signupOutputData); + final SignupOutputData signupOutputData = new SignupOutputData(newUser.getName(), false); + userPresenter.prepareSuccessView(signupOutputData); } } catch (DataAccessException error) { - signupOutputBoundary.prepareFailView("An error occurred while signing up."); + userPresenter.prepareFailView("An error occurred while signing up."); } } @Override public void switchToLoginView() { - signupOutputBoundary.prepareSwitchToLoginView(); + userPresenter.switchToLoginView(); } } diff --git a/src/main/java/use_case/signup/SignupOutputBoundary.java b/src/main/java/use_case/signup/SignupOutputBoundary.java index f3d71adcd..316de4aca 100644 --- a/src/main/java/use_case/signup/SignupOutputBoundary.java +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -21,5 +21,5 @@ public interface SignupOutputBoundary { /** * Prepares the view to switch to the login view. */ - void prepareSwitchToLoginView(); + void switchToLoginView(); } diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java new file mode 100644 index 000000000..b963637bb --- /dev/null +++ b/src/main/java/view/LoginView.java @@ -0,0 +1,150 @@ +package view; + +import interface_adapter.login.LoginController; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The View for when the user is logging into the program. + */ +public class LoginView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "log in"; + private final LoginViewModel loginViewModel; + + private final JTextField usernameInputField = new JTextField(15); + private final JLabel usernameErrorField = new JLabel(); + + private final JPasswordField passwordInputField = new JPasswordField(15); + private final JLabel passwordErrorField = new JLabel(); + + private final JButton logIn; + private final JButton cancel; + private final LoginController loginController; + + public LoginView(LoginViewModel loginViewModel, LoginController controller) { + + this.loginController = controller; + this.loginViewModel = loginViewModel; + this.loginViewModel.addPropertyChangeListener(this); + + final JLabel title = new JLabel("Login Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel usernameInfo = new LabelTextPanel( + new JLabel("Username"), usernameInputField); + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel("Password"), passwordInputField); + + final JPanel buttons = new JPanel(); + logIn = new JButton("log in"); + buttons.add(logIn); + cancel = new JButton("cancel"); + buttons.add(cancel); + + logIn.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(logIn)) { + final LoginState currentState = loginViewModel.getState(); + + loginController.execute( + currentState.getUsername(), + currentState.getPassword() + ); + } + } + } + ); + + cancel.addActionListener(this); + + usernameInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final LoginState currentState = loginViewModel.getState(); + currentState.setUsername(usernameInputField.getText()); + loginViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + passwordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final LoginState currentState = loginViewModel.getState(); + currentState.setPassword(new String(passwordInputField.getPassword())); + loginViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + + this.add(title); + this.add(usernameInfo); + this.add(usernameErrorField); + this.add(passwordInfo); + this.add(buttons); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final LoginState state = (LoginState) evt.getNewValue(); + setFields(state); + usernameErrorField.setText(state.getLoginError()); + } + + private void setFields(LoginState state) { + usernameInputField.setText(state.getUsername()); + } + + public String getViewName() { + return viewName; + } +} diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java index 297018203..0e665eda8 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/SignupView.java @@ -1,58 +1,180 @@ package view; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import interface_adapter.signup.SignupController; +import interface_adapter.signup.SignupState; import interface_adapter.signup.SignupViewModel; /** * View for the signup process. */ -public class SignupView extends JPanel { +public class SignupView extends JPanel implements ActionListener, PropertyChangeListener { + private final String viewName = "sign up"; + private final JTextField usernameInputField = new JTextField(15); private final JPasswordField passwordInputField = new JPasswordField(15); private final JPasswordField repeatPasswordInputField = new JPasswordField(15); private final SignupController signupController; + private final SignupViewModel signupViewModel; public SignupView(SignupController signupController, SignupViewModel signupViewModel) { this.signupController = signupController; - signupViewModel.addPropertyChangeListener(evt -> { - final String errorMessage = (String) evt.getNewValue(); - if (errorMessage != null) { - JOptionPane.showMessageDialog(this, errorMessage); - } - }); + this.signupViewModel = signupViewModel; + signupViewModel.addPropertyChangeListener(this); + final JLabel title = new JLabel("Sign Up"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - add(new JLabel("Username:")); + add(new JLabel("Pick a Username:")); add(usernameInputField); - add(new JLabel("Password:")); + add(new JLabel("Pick a Password:")); add(passwordInputField); - add(new JLabel("Repeat Password:")); + add(new JLabel("Confirm Password:")); add(repeatPasswordInputField); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + final JPanel buttons = new JPanel(); final JButton signUpButton = new JButton("Sign Up"); - signUpButton.addActionListener(new ActionListener() { + buttons.add(signUpButton); + final JButton gotoLoginButton = new JButton("Go to Login"); + buttons.add(gotoLoginButton); + + signUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (e.getSource() == signUpButton) { + final SignupState currentState = signupViewModel.getState(); + signupController.execute( + currentState.getUsername(), currentState.getPassword(), + currentState.getRepeatPassword() + ); + + } + } + } + ); + gotoLoginButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + signupController.switchToLoginView(); + } + } + ); + + addUsernameListener(); + addPasswordListener(); + addRepeatPasswordListener(); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + this.add(title); + this.add(usernameInputField); + this.add(passwordInputField); + this.add(repeatPasswordInputField); + this.add(buttons); + } + + private void addRepeatPasswordListener() { + repeatPasswordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setRepeatPassword(new String(repeatPasswordInputField.getPassword())); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } + + private void addPasswordListener() { + passwordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setPassword(new String(passwordInputField.getPassword())); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } + + private void addUsernameListener() { + usernameInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setUsername(usernameInputField.getText()); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + @Override - public void actionPerformed(ActionEvent e) { - signupController.execute( - usernameInputField.getText(), - new String(passwordInputField.getPassword()), - new String(repeatPasswordInputField.getPassword()) - ); + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); } }); + } + + @Override + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(this, "Cancel not implemented yet."); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final SignupState state = (SignupState) evt.getNewValue(); + if (state.getUsernameError() != null) { + JOptionPane.showMessageDialog(this, state.getUsernameError()); + } + } - add(signUpButton); + public String getViewName() { + return viewName; } } From ad9099e51972a6e69abd1e919e1f2f4e933d0b9c Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 1 Dec 2024 20:27:22 -0500 Subject: [PATCH 103/113] fixed DAO and now it opens in new browser --- .../app/SuggestedLocationsUseCaseFactory.java | 23 +++++++++++- .../DBCoordinatesDataAccessObject.java | 13 +++---- .../DBLocationDataAccessObject.java | 2 +- .../SelectedLocationsInteractor.java | 5 +-- .../SelectedLocationsOutputData.java | 7 ++-- src/main/java/view/LocationView.java | 3 +- src/main/java/view/SelectedLocationView.java | 36 +++++++++++++++---- .../java/view/SuggestedLocationsView.java | 8 +++-- 8 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 2a45f4a40..d71997bfa 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -1,13 +1,19 @@ package app; +import data_access.DBCoordinatesDataAccessObject; import interface_adapter.ViewManagerModel; +import interface_adapter.selectedlocation.SelectedLocationsPresenter; import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.selected_locations.SelectedLocationsInputBoundary; +import use_case.selected_locations.SelectedLocationsInteractor; +import use_case.selected_locations.SelectedLocationsOutputBoundary; import use_case.suggested_locations.SuggestedLocationsInteractor; import use_case.suggested_locations.SuggestedLocationsInputBoundary; +import interface_adapter.selectedlocation.SelectedLocationsController; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import view.SuggestedLocationsView; @@ -37,9 +43,12 @@ public static SuggestedLocationsView create( final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, suggestedLocationsViewModel, selectedLocationsViewModel); + final SelectedLocationsController selectedLocationController = createSelectedLocationUseCase(viewManagerModel, + selectedLocationsViewModel, new DBCoordinatesDataAccessObject()); + // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) return new SuggestedLocationsView(suggestedLocationsViewModel, - suggestedLocationsController, selectedLocationsViewModel); + suggestedLocationsController, selectedLocationsViewModel, selectedLocationController); } private static SuggestedLocationsController createSuggestedLocationUseCase( @@ -54,6 +63,18 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( return new SuggestedLocationsController(suggestedLocationsInteractor); } + + private static SelectedLocationsController createSelectedLocationUseCase( + ViewManagerModel viewManagerModel, + SelectedLocationsViewModel selectedLocationsViewModel, + DBCoordinatesDataAccessObject coordinatesDataAccessObject) { + final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( + selectedLocationsViewModel, viewManagerModel); + final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( + selectedLocationsOutputBoundary, coordinatesDataAccessObject); + + return new SelectedLocationsController(selectedLocationsInteractor); + } } diff --git a/src/main/java/data_access/DBCoordinatesDataAccessObject.java b/src/main/java/data_access/DBCoordinatesDataAccessObject.java index 9fbb5c2d5..2b6f11c0b 100644 --- a/src/main/java/data_access/DBCoordinatesDataAccessObject.java +++ b/src/main/java/data_access/DBCoordinatesDataAccessObject.java @@ -22,16 +22,13 @@ public class DBCoordinatesDataAccessObject implements CoordinateDataAccessInterf public String searchCoordinates(Place place) throws DataAccessException { final OkHttpClient client = new OkHttpClient().newBuilder() .build(); - - final JSONObject requestBody = new JSONObject(); - requestBody.put("key", API_KEY); - requestBody.put("address", place.getAddress()); - final RequestBody body = RequestBody.create( - requestBody.toString(), MediaType.parse(CONTENT_TYPE_JSON)); + HttpUrl url = HttpUrl.parse("https://maps.googleapis.com/maps/api/geocode/json").newBuilder() + .addQueryParameter("key", API_KEY) + .addQueryParameter("address", place.getAddress()) + .build(); // POST METHOD final Request request = new Request.Builder() - .url("https://maps.googleapis.com/maps/api/geocode/json") - .post(body) + .url(url) .build(); try (Response response = client.newCall(request).execute()) { final JSONObject responseBody = new JSONObject(response.body().string()); diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 3fdc90ba5..678b026a2 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -56,7 +56,7 @@ public List searchLocation(String address, String locationType) throws Da final JSONArray jsonArray = responseBody.getJSONArray("places"); for (int i = 0; i < jsonArray.length(); i++) { final JSONObject jsonObject = - jsonArray.getJSONmicsObject(i); + jsonArray.getJSONObject(i); places.append(jsonObject.getString("formattedAddress")).append(">").append(jsonObject .getJSONObject("displayName").getString("text")).append("<"); } diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java index c3b9aa5c5..9490c8599 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; +import java.util.Map; public class SelectedLocationsInteractor implements SelectedLocationsInputBoundary { private final CoordinateDataAccessInterface coordinateDataAccessInterface; @@ -20,11 +21,11 @@ public SelectedLocationsInteractor(SelectedLocationsOutputBoundary selectedLocat @Override public void execute(SelectedLocationsInputData selectedLocationsInputData) throws DataAccessException { final List selectedLocations = selectedLocationsInputData.getSelectedLocations(); - final HashMap locationCoordinatesMap = new HashMap<>(); + final Map locationCoordinatesMap = new HashMap<>(); for (Place location : selectedLocations) { try { - String coordinates = coordinateDataAccessInterface.searchCoordinates(location); + final String coordinates = coordinateDataAccessInterface.searchCoordinates(location); locationCoordinatesMap.put(location, coordinates); } catch (DataAccessException e) { diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java index 6975b2563..cc26545ef 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsOutputData.java @@ -3,16 +3,17 @@ import entity.Place; import java.util.HashMap; +import java.util.Map; public class SelectedLocationsOutputData { - private final HashMap locationCoordinatesMap; + private final Map locationCoordinatesMap; - public SelectedLocationsOutputData(HashMap locationCoordinatesMap) { + public SelectedLocationsOutputData(Map locationCoordinatesMap) { this.locationCoordinatesMap = locationCoordinatesMap; } - public HashMap getLocationCoordinatesMap() { + public Map getLocationCoordinatesMap() { return locationCoordinatesMap; } diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 2ffabc063..1da9c74d9 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -124,7 +124,8 @@ public void changedUpdate(DocumentEvent e) { final LocationState currentState = locationViewModel.getState(); try { locationController.execute(currentState.getAddress(), currentState.getLocationType()); - } catch (DataAccessException e) { + } + catch (DataAccessException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java index fbbb2c4fa..9ffe6ae46 100644 --- a/src/main/java/view/SelectedLocationView.java +++ b/src/main/java/view/SelectedLocationView.java @@ -6,7 +6,9 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.util.List; import java.util.Map; @@ -61,15 +63,35 @@ private void updateSelectedLocations(SelectedLocationsState state) { final JLabel addressLabel = new JLabel(location.getAddress()); final JButton actionButton = new JButton("Get Directions to " + location.getName()); final Map map = - selectedLocationsViewModel.getState().getPlaceToCoordinates(); + state.getPlaceToCoordinates(); actionButton.addActionListener(evt -> { - if (actionButton.isSelected()) { - String coordinates = map.get(location); - String url = "https://maps.google.com/?q=" + coordinates; - JOptionPane.showMessageDialog(this, url, "Directions", JOptionPane.INFORMATION_MESSAGE); - + if (evt.getSource() == actionButton) { + try { + // Define the URL to open + final String coordinates = map.get(location); + final URI url = new URI("https://maps.google.com/?q=" + coordinates ); + + // Check if Desktop is supported + if (Desktop.isDesktopSupported()) { + final Desktop desktop = Desktop.getDesktop(); + + // Check if browsing is supported + if (desktop.isSupported(Desktop.Action.BROWSE)) { + desktop.browse(url); + } + else { + JOptionPane.showMessageDialog(this, "Browsing is not supported on your system."); + } + } + else { + JOptionPane.showMessageDialog(this, "Desktop is not supported on your system."); + } + } + catch (IOException | URISyntaxException ex) { + JOptionPane.showMessageDialog(this, "Failed to open the URL: " + ex.getMessage()); + } + } } - } ); selectedLocationPanel.add(nameLabel); selectedLocationPanel.add(addressLabel); diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 3e9e905c9..63f45d553 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -11,6 +11,7 @@ import javax.swing.*; import entity.Place; +import interface_adapter.selectedlocation.SelectedLocationsController; import interface_adapter.selectedlocation.SelectedLocationsState; import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; @@ -26,6 +27,7 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr private final String viewName = "Suggested Locations"; private final SuggestedLocationsViewModel suggestedLocationsViewModel; private final SuggestedLocationsController suggestedLocationsController; + private final SelectedLocationsController selectedLocationsController; private final SelectedLocationsViewModel selectedLocationsViewModel; private final JPanel suggestedLocationsPanel; @@ -34,10 +36,12 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, SuggestedLocationsController suggestedLocationsController, - SelectedLocationsViewModel selectedLocationsViewModel) { + SelectedLocationsViewModel selectedLocationsViewModel, + SelectedLocationsController selectedLocationsController) { this.suggestedLocationsViewModel = suggestedLocationsViewModel; this.suggestedLocationsViewModel.addPropertyChangeListener(this); this.suggestedLocationsController = suggestedLocationsController; + this.selectedLocationsController = selectedLocationsController; this.selectedLocationsViewModel = selectedLocationsViewModel; final JLabel title = new JLabel("List of Suggested Locations:"); @@ -108,7 +112,7 @@ public void actionPerformed(ActionEvent evt) { if (evt.getSource() == saveSelectionButton) { final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); try { - suggestedLocationsController.execute(selectedLocationsState.getSelectedLocations()); + selectedLocationsController.execute(selectedLocationsState.getSelectedLocations()); } catch (DataAccessException e) { throw new RuntimeException(e); From 8aafbb8df630a9a321cb3c9f83e335411ed56891 Mon Sep 17 00:00:00 2001 From: Ray Fang <155117488+rayf5372@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:29:29 -0500 Subject: [PATCH 104/113] Create accessibility report --- accessibility-report | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 accessibility-report diff --git a/accessibility-report b/accessibility-report new file mode 100644 index 000000000..bb8c4a461 --- /dev/null +++ b/accessibility-report @@ -0,0 +1,33 @@ +The following paragraphs summarises how features in our program adhere to the Principle of Universal Design. + +Principle 1: Equitable Use + +The TravelAdvisor provides activity recommendations based on user-selected interests, benefiting all users equally. The activity suggestions are based solely on personal preferences in our profile creating feature, and our interest-selecting feature allows the users to enter any interest they may have, ensuring a diverse group of users can interact equitably. The profile creation and sign-up processes are identical for all users, fostering an equal and inclusive experience. + +Principle 2: Flexibility in Use + +Users can save places they are interested in and access them later, providing flexibility in how they interact with the app. The save places feature allows users to add different types of information, such as reviews and ratings, based on their preferences. Additionally, the interest-selection feature offers flexibility similar to a Google search, allowing users to input any interest they have. + +Principle 3: Simple and Intuitive Use + +The user interface follows a straightforward flow—users create a profile, select preferences, and receive personalized recommendations. Clear labels for text fields and buttons make the interface intuitive and easy to use. The platform delivers the intended service efficiently, without requiring extensive effort or comprehension from the user. + +Principle 4: Perceptible Information + +We use JSwing to present views, combining both textual and visual elements to enhance information accessibility. Labels, buttons, and other interface components are clearly labeled across all views, ensuring that users can easily perceive and understand the information and actions available. + +Principle 5: Tolerance in Error + +Error messages are displayed if, for instance, users try to create a profile with a username that already exists. This helps users easily identify and correct their mistakes. + +Principle 6: Low Physical Effort + +All elements of the user interface are designed to be simple to use and minimize repetitive actions. Users can navigate through different views intuitively, with large buttons and clear text fields. Features like the "New Search" button allow users to return to the search view directly after seeing suggested locations, reducing unnecessary steps and physical effort. + +Principle 7: Size and Space for Approach and Use + +All views in the TravelAdvisor provide a clean and well-organized layout, with adequate spacing between buttons and text fields, ensuring ease of interaction without feeling cramped. A future development goal is to integrate user accessibility tools, such as text-to-speech, to further enhance accessibility for all users. + +Our program is designed to be used by anyone interested in exploring new places or discovering interesting parts of their city. Our primary target audience for marketing would be frequent travelers, as they are more likely to be dissatisfied with generic interest recommendations found on platforms like Google Maps and would appreciate a more personalized experience. Another potential target audience could be local explorers—people who enjoy uncovering hidden gems within their own city. These users may be looking for unique recommendations that go beyond the popular tourist spots, tailored specifically to their personal interests. Additionally, our program could appeal to individuals who have specific niche hobbies, such as vinyl lovers seeking second-hand record stores, or history enthusiasts searching for lesser-known historical sites. + +When considering the medical model of disability, one demographic that is less likely to use our program would be individuals with visual impairment. In our program, individuals with visual impairments may face challenges since all features currently rely on visual cues, such as reading labels, navigating buttons, and being redirected to external pages. This reliance on visual interaction presents a significant barrier for visually impaired users, who might find it difficult or even impossible to use the program without external assistance. From 1016c739b532322fd5e85bc95a2b05f91294045c Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Sun, 1 Dec 2024 20:31:28 -0500 Subject: [PATCH 105/113] Add files via upload --- accessibility-report.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 accessibility-report.md diff --git a/accessibility-report.md b/accessibility-report.md new file mode 100644 index 000000000..bb8c4a461 --- /dev/null +++ b/accessibility-report.md @@ -0,0 +1,33 @@ +The following paragraphs summarises how features in our program adhere to the Principle of Universal Design. + +Principle 1: Equitable Use + +The TravelAdvisor provides activity recommendations based on user-selected interests, benefiting all users equally. The activity suggestions are based solely on personal preferences in our profile creating feature, and our interest-selecting feature allows the users to enter any interest they may have, ensuring a diverse group of users can interact equitably. The profile creation and sign-up processes are identical for all users, fostering an equal and inclusive experience. + +Principle 2: Flexibility in Use + +Users can save places they are interested in and access them later, providing flexibility in how they interact with the app. The save places feature allows users to add different types of information, such as reviews and ratings, based on their preferences. Additionally, the interest-selection feature offers flexibility similar to a Google search, allowing users to input any interest they have. + +Principle 3: Simple and Intuitive Use + +The user interface follows a straightforward flow—users create a profile, select preferences, and receive personalized recommendations. Clear labels for text fields and buttons make the interface intuitive and easy to use. The platform delivers the intended service efficiently, without requiring extensive effort or comprehension from the user. + +Principle 4: Perceptible Information + +We use JSwing to present views, combining both textual and visual elements to enhance information accessibility. Labels, buttons, and other interface components are clearly labeled across all views, ensuring that users can easily perceive and understand the information and actions available. + +Principle 5: Tolerance in Error + +Error messages are displayed if, for instance, users try to create a profile with a username that already exists. This helps users easily identify and correct their mistakes. + +Principle 6: Low Physical Effort + +All elements of the user interface are designed to be simple to use and minimize repetitive actions. Users can navigate through different views intuitively, with large buttons and clear text fields. Features like the "New Search" button allow users to return to the search view directly after seeing suggested locations, reducing unnecessary steps and physical effort. + +Principle 7: Size and Space for Approach and Use + +All views in the TravelAdvisor provide a clean and well-organized layout, with adequate spacing between buttons and text fields, ensuring ease of interaction without feeling cramped. A future development goal is to integrate user accessibility tools, such as text-to-speech, to further enhance accessibility for all users. + +Our program is designed to be used by anyone interested in exploring new places or discovering interesting parts of their city. Our primary target audience for marketing would be frequent travelers, as they are more likely to be dissatisfied with generic interest recommendations found on platforms like Google Maps and would appreciate a more personalized experience. Another potential target audience could be local explorers—people who enjoy uncovering hidden gems within their own city. These users may be looking for unique recommendations that go beyond the popular tourist spots, tailored specifically to their personal interests. Additionally, our program could appeal to individuals who have specific niche hobbies, such as vinyl lovers seeking second-hand record stores, or history enthusiasts searching for lesser-known historical sites. + +When considering the medical model of disability, one demographic that is less likely to use our program would be individuals with visual impairment. In our program, individuals with visual impairments may face challenges since all features currently rely on visual cues, such as reading labels, navigating buttons, and being redirected to external pages. This reliance on visual interaction presents a significant barrier for visually impaired users, who might find it difficult or even impossible to use the program without external assistance. From eb601c0b5ba79b716d6eb105a2c5381abdbbbbe7 Mon Sep 17 00:00:00 2001 From: teddyyang8 Date: Sun, 1 Dec 2024 20:31:44 -0500 Subject: [PATCH 106/113] Delete accessibility-report --- accessibility-report | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 accessibility-report diff --git a/accessibility-report b/accessibility-report deleted file mode 100644 index bb8c4a461..000000000 --- a/accessibility-report +++ /dev/null @@ -1,33 +0,0 @@ -The following paragraphs summarises how features in our program adhere to the Principle of Universal Design. - -Principle 1: Equitable Use - -The TravelAdvisor provides activity recommendations based on user-selected interests, benefiting all users equally. The activity suggestions are based solely on personal preferences in our profile creating feature, and our interest-selecting feature allows the users to enter any interest they may have, ensuring a diverse group of users can interact equitably. The profile creation and sign-up processes are identical for all users, fostering an equal and inclusive experience. - -Principle 2: Flexibility in Use - -Users can save places they are interested in and access them later, providing flexibility in how they interact with the app. The save places feature allows users to add different types of information, such as reviews and ratings, based on their preferences. Additionally, the interest-selection feature offers flexibility similar to a Google search, allowing users to input any interest they have. - -Principle 3: Simple and Intuitive Use - -The user interface follows a straightforward flow—users create a profile, select preferences, and receive personalized recommendations. Clear labels for text fields and buttons make the interface intuitive and easy to use. The platform delivers the intended service efficiently, without requiring extensive effort or comprehension from the user. - -Principle 4: Perceptible Information - -We use JSwing to present views, combining both textual and visual elements to enhance information accessibility. Labels, buttons, and other interface components are clearly labeled across all views, ensuring that users can easily perceive and understand the information and actions available. - -Principle 5: Tolerance in Error - -Error messages are displayed if, for instance, users try to create a profile with a username that already exists. This helps users easily identify and correct their mistakes. - -Principle 6: Low Physical Effort - -All elements of the user interface are designed to be simple to use and minimize repetitive actions. Users can navigate through different views intuitively, with large buttons and clear text fields. Features like the "New Search" button allow users to return to the search view directly after seeing suggested locations, reducing unnecessary steps and physical effort. - -Principle 7: Size and Space for Approach and Use - -All views in the TravelAdvisor provide a clean and well-organized layout, with adequate spacing between buttons and text fields, ensuring ease of interaction without feeling cramped. A future development goal is to integrate user accessibility tools, such as text-to-speech, to further enhance accessibility for all users. - -Our program is designed to be used by anyone interested in exploring new places or discovering interesting parts of their city. Our primary target audience for marketing would be frequent travelers, as they are more likely to be dissatisfied with generic interest recommendations found on platforms like Google Maps and would appreciate a more personalized experience. Another potential target audience could be local explorers—people who enjoy uncovering hidden gems within their own city. These users may be looking for unique recommendations that go beyond the popular tourist spots, tailored specifically to their personal interests. Additionally, our program could appeal to individuals who have specific niche hobbies, such as vinyl lovers seeking second-hand record stores, or history enthusiasts searching for lesser-known historical sites. - -When considering the medical model of disability, one demographic that is less likely to use our program would be individuals with visual impairment. In our program, individuals with visual impairments may face challenges since all features currently rely on visual cues, such as reading labels, navigating buttons, and being redirected to external pages. This reliance on visual interaction presents a significant barrier for visually impaired users, who might find it difficult or even impossible to use the program without external assistance. From f0cdb87bc26e6f3b7ede03441afe59f779d64553 Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Sun, 1 Dec 2024 21:46:09 -0500 Subject: [PATCH 107/113] rays user use case finished --- src/main/java/app/LoginUseCaseFactory.java | 8 +- src/main/java/app/MainWithDB.java | 14 +-- .../app/SuggestedLocationsUseCaseFactory.java | 1 - .../java/app/UserProfileUseCaseFactory.java | 53 +++++---- .../InMemoryUserDataAccessObject.java | 16 +-- .../login/LoginPresenter.java | 8 +- .../signup/SignupViewModel.java | 101 +++++++++--------- .../interface_adapter/user/UserState.java | 20 ---- .../interface_adapter/user/UserViewModel.java | 31 ------ .../UserProfileController.java | 4 +- .../UserProfilePresenter.java | 21 ++-- .../user_profile/UserProfileState.java | 49 +++++++++ .../user_profile/UserProfileViewModel.java | 36 +++++++ .../java/use_case/login/LoginInteractor.java | 2 +- .../login/LoginUserDataAccessInterface.java | 12 --- .../UserProfileDataAccessInterface.java | 2 +- .../UserProfileInputBoundary.java | 2 +- .../UserProfileInputData.java | 2 +- .../UserProfileInteractor.java | 6 +- .../UserProfileOutputBoundary.java | 2 +- src/main/java/view/SignupView.java | 20 ++-- src/main/java/view/UserProfileView.java | 84 ++++++++++----- 22 files changed, 289 insertions(+), 205 deletions(-) delete mode 100644 src/main/java/interface_adapter/user/UserState.java delete mode 100644 src/main/java/interface_adapter/user/UserViewModel.java rename src/main/java/interface_adapter/{user => user_profile}/UserProfileController.java (90%) rename src/main/java/interface_adapter/{user => user_profile}/UserProfilePresenter.java (51%) create mode 100644 src/main/java/interface_adapter/user_profile/UserProfileState.java create mode 100644 src/main/java/interface_adapter/user_profile/UserProfileViewModel.java rename src/main/java/use_case/{user => user_profile}/UserProfileDataAccessInterface.java (97%) rename src/main/java/use_case/{user => user_profile}/UserProfileInputBoundary.java (94%) rename src/main/java/use_case/{user => user_profile}/UserProfileInputData.java (95%) rename src/main/java/use_case/{user => user_profile}/UserProfileInteractor.java (90%) rename src/main/java/use_case/{user => user_profile}/UserProfileOutputBoundary.java (93%) diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java index b532463b4..7478d33a5 100644 --- a/src/main/java/app/LoginUseCaseFactory.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -1,6 +1,7 @@ package app; import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; import interface_adapter.user_profile.UserProfileViewModel; import interface_adapter.login.LoginController; import interface_adapter.login.LoginPresenter; @@ -26,6 +27,7 @@ private LoginUseCaseFactory() { * @param viewManagerModel the ViewManagerModel to inject into the LoginView * @param loginViewModel the LoginViewModel to inject into the LoginView * @param userProfileViewModel the LoggedInViewModel to inject into the LoginView + * @param locationViewModel the LocationViewModel to inject into the LoginView * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView * @return the LoginView created for the provided input classes */ @@ -33,10 +35,11 @@ public static LoginView create( ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, UserProfileViewModel userProfileViewModel, + LocationViewModel locationViewModel, LoginUserDataAccessInterface userDataAccessObject) { final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel, - userProfileViewModel, userDataAccessObject); + userProfileViewModel, locationViewModel, userDataAccessObject); return new LoginView(loginViewModel, loginController); } @@ -45,11 +48,12 @@ private static LoginController createLoginUseCase( ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, UserProfileViewModel userProfileViewModel, + LocationViewModel locationViewModel, LoginUserDataAccessInterface userDataAccessObject) { // Notice how we pass this method's parameters to the Presenter. final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, - userProfileViewModel, loginViewModel); + userProfileViewModel, loginViewModel, locationViewModel); final LoginInputBoundary loginInteractor = new LoginInteractor( userDataAccessObject, loginOutputBoundary); diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index d02ecdb75..c4da854b9 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -8,6 +8,7 @@ import interface_adapter.login.LoginViewModel; import interface_adapter.signup.SignupViewModel; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import interface_adapter.user_profile.UserProfileViewModel; import view.*; import javax.swing.*; @@ -37,16 +38,16 @@ public static void main(String[] args) { final ViewManagerModel viewManagerModel = new ViewManagerModel(); new ViewManager(views, cardLayout, viewManagerModel); - final LoginViewModel loginViewModel = new LoginViewModel(); + final LoginViewModel loginViewModel = new LoginViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); final LocationViewModel locationViewModel = new LocationViewModel(); final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel(); + final UserProfileViewModel userProfileViewModel = new UserProfileViewModel(); // add any future view models here in the same way final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( new SuggestedPlaceFactory()); - final InMemoryUserDataAccessObject userDataAccessObject = new InMemoryUserDataAccessObject(); final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, @@ -54,7 +55,7 @@ public static void main(String[] args) { views.add(signupView, signupView.getViewName()); final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - userProfileViewModel, userDataAccessObject); + userProfileViewModel, locationViewModel, userDataAccessObject); // logged in = user profile view views.add(loginView, loginView.getViewName()); @@ -66,10 +67,11 @@ public static void main(String[] args) { suggestedLocationsViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); - final UserProfileView userProfileView = UserProfileUseCaseFactory.create(viewManagerModel); - views.add(userProfileView, "User Profile"); + final UserProfileView userProfileView = UserProfileUseCaseFactory.create(viewManagerModel, + userProfileViewModel, userDataAccessObject); + views.add(userProfileView, userProfileView.getViewName()); - viewManagerModel.setState(locationView.getViewName()); + viewManagerModel.setState(signupView.getViewName()); viewManagerModel.firePropertyChanged(); application.pack(); diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 70564c274..8bbb4c7a7 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -33,7 +33,6 @@ public static SuggestedLocationsView create( final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(viewManagerModel, suggestedLocationsViewModel); - // didnt pass in the card layout and parent panel (since teddy idk if ur doing it in the view) return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController); } diff --git a/src/main/java/app/UserProfileUseCaseFactory.java b/src/main/java/app/UserProfileUseCaseFactory.java index 52454ef09..8b89f5dc6 100644 --- a/src/main/java/app/UserProfileUseCaseFactory.java +++ b/src/main/java/app/UserProfileUseCaseFactory.java @@ -2,11 +2,14 @@ import data_access.InMemoryUserDataAccessObject; import interface_adapter.ViewManagerModel; -import interface_adapter.user.UserProfileController; -import interface_adapter.user.UserProfilePresenter; -import interface_adapter.user.UserViewModel; -import use_case.user.UserProfileInputBoundary; -import use_case.user.UserProfileInteractor; +import interface_adapter.user_profile.UserProfileController; +import interface_adapter.user_profile.UserProfilePresenter; +import interface_adapter.user_profile.UserProfileViewModel; +import use_case.user_profile.UserProfileDataAccessInterface; +import use_case.user_profile.UserProfileInputBoundary; +import use_case.user_profile.UserProfileInteractor; +import use_case.user_profile.UserProfileOutputBoundary; +import view.SuggestedLocationsView; import view.UserProfileView; /** @@ -19,19 +22,33 @@ private UserProfileUseCaseFactory() { } /** - * Factory method for creating the UserProfileView. - * - * @param viewManagerModel the ViewManagerModel - * @return a UserProfileView instance + * Factory function for creating the LocationView. + * @param viewManagerModel the ViewManagerModel to inject + * @param userProfileViewModel the SuggestedLocationsViewModel to inject + * @param userDataAccessObject the In memory user data access object + * @return the LocationView created for the provided input classes. */ - public static UserProfileView create(ViewManagerModel viewManagerModel) { - final InMemoryUserDataAccessObject userDataAccess = new InMemoryUserDataAccessObject(); - final UserViewModel userViewModel = new UserViewModel(); - final UserProfilePresenter userProfilePresenter = new UserProfilePresenter(viewManagerModel, userViewModel); - final UserProfileInputBoundary userProfileInteractor = - new UserProfileInteractor(userDataAccess, userProfilePresenter); - final UserProfileController userProfileController = new UserProfileController(userProfileInteractor); - - return new UserProfileView(userProfileController, userViewModel); + public static UserProfileView create( + ViewManagerModel viewManagerModel, + UserProfileViewModel userProfileViewModel, + UserProfileDataAccessInterface userDataAccessObject) { + + final UserProfileController userProfileController = createUserProfileUseCase(viewManagerModel, + userProfileViewModel, userDataAccessObject); + + return new UserProfileView(userProfileController, userProfileViewModel); + } + + private static UserProfileController createUserProfileUseCase( + ViewManagerModel viewManagerModel, + UserProfileViewModel userProfileViewModel, + UserProfileDataAccessInterface userDataAccessObject) { + + final UserProfileOutputBoundary userProfileOutputBoundary = new UserProfilePresenter( + viewManagerModel, userProfileViewModel); + final UserProfileInputBoundary userProfileInteractor = new UserProfileInteractor(userDataAccessObject, + userProfileOutputBoundary); + + return new UserProfileController(userProfileInteractor); } } diff --git a/src/main/java/data_access/InMemoryUserDataAccessObject.java b/src/main/java/data_access/InMemoryUserDataAccessObject.java index b17777a21..d817b91a9 100644 --- a/src/main/java/data_access/InMemoryUserDataAccessObject.java +++ b/src/main/java/data_access/InMemoryUserDataAccessObject.java @@ -7,24 +7,28 @@ import entity.Place; import entity.User; import use_case.DataAccessException; +import use_case.login.LoginUserDataAccessInterface; import use_case.signup.SignupUserDataAccessInterface; -import use_case.user.UserProfileDataAccessInterface; +import use_case.user_profile.UserProfileDataAccessInterface; /** * In-memory implementation for storing user data for both sign-up and user profile. */ -public class InMemoryUserDataAccessObject implements SignupUserDataAccessInterface, UserProfileDataAccessInterface { +public class InMemoryUserDataAccessObject implements SignupUserDataAccessInterface, + LoginUserDataAccessInterface, UserProfileDataAccessInterface { private final Map userDatabase = new HashMap<>(); @Override - public void save(User user) throws DataAccessException { - if (userDatabase.containsKey(user.getName())) { - throw new DataAccessException("User already exists."); - } + public void save(User user) { userDatabase.put(user.getName(), user); } + @Override + public User get(String username) { + return userDatabase.get(username); + } + @Override public User getUser(String username) throws DataAccessException { final User user = userDatabase.get(username); diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java index e92727f72..9777bfb49 100644 --- a/src/main/java/interface_adapter/login/LoginPresenter.java +++ b/src/main/java/interface_adapter/login/LoginPresenter.java @@ -1,6 +1,7 @@ package interface_adapter.login; import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; import interface_adapter.user_profile.UserProfileState; import interface_adapter.user_profile.UserProfileViewModel; import use_case.login.LoginOutputBoundary; @@ -13,14 +14,17 @@ public class LoginPresenter implements LoginOutputBoundary { private final LoginViewModel loginViewModel; private final UserProfileViewModel userProfileViewModel; + private final LocationViewModel locationViewModel; private final ViewManagerModel viewManagerModel; public LoginPresenter(ViewManagerModel viewManagerModel, UserProfileViewModel userProfileViewModel, - LoginViewModel loginViewModel) { + LoginViewModel loginViewModel, + LocationViewModel locationViewModel) { this.viewManagerModel = viewManagerModel; this.userProfileViewModel = userProfileViewModel; this.loginViewModel = loginViewModel; + this.locationViewModel = locationViewModel; } @Override @@ -32,7 +36,7 @@ public void prepareSuccessView(LoginOutputData response) { this.userProfileViewModel.setState(userProfileState); this.userProfileViewModel.firePropertyChanged(); - this.viewManagerModel.setState(userProfileViewModel.getViewName()); + this.viewManagerModel.setState(locationViewModel.getViewName()); this.viewManagerModel.firePropertyChanged(); } diff --git a/src/main/java/interface_adapter/signup/SignupViewModel.java b/src/main/java/interface_adapter/signup/SignupViewModel.java index 636bffe44..df3903f7e 100644 --- a/src/main/java/interface_adapter/signup/SignupViewModel.java +++ b/src/main/java/interface_adapter/signup/SignupViewModel.java @@ -9,59 +9,60 @@ * ViewModel for the signup process, holding state for the signup view. */ public class SignupViewModel extends ViewModel { - private String username; - private String errorMessage; - private final PropertyChangeSupport support; +// private String username; +// private String errorMessage; +// private final PropertyChangeSupport support; public SignupViewModel() { super("sign up"); setState(new SignupState()); } - - public String getUsername() { - return username; - } - - /** - * Sets the username and notifies listeners of the change. - * - * @param username the username - */ - public void setUsername(String username) { - final String oldUsername = this.username; - this.username = username; - support.firePropertyChange("username", oldUsername, username); - } - - /** - * Sets the error message and notifies listeners of the change. - * - * @param errorMessage the error message - */ - public void setErrorMessage(String errorMessage) { - final String oldErrorMessage = this.errorMessage; - this.errorMessage = errorMessage; - support.firePropertyChange("errorMessage", oldErrorMessage, errorMessage); - } - - /** - * Adds a property change listener. - * - * @param listener the listener - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - support.addPropertyChangeListener(listener); - } - - /** - * Removes a property change listener. - * - * @param listener the listener - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - support.removePropertyChangeListener(listener); - } - - public SignupState getState() { - } +// +// public String getUsername() { +// return username; +// } +// +// /** +// * Sets the username and notifies listeners of the change. +// * +// * @param username the username +// */ +// public void setUsername(String username) { +// final String oldUsername = this.username; +// this.username = username; +// support.firePropertyChange("username", oldUsername, username); +// } +// +// /** +// * Sets the error message and notifies listeners of the change. +// * +// * @param errorMessage the error message +// */ +// public void setErrorMessage(String errorMessage) { +// final String oldErrorMessage = this.errorMessage; +// this.errorMessage = errorMessage; +// support.firePropertyChange("errorMessage", oldErrorMessage, errorMessage); +// } +// +// /** +// * Adds a property change listener. +// * +// * @param listener the listener +// */ +// public void addPropertyChangeListener(PropertyChangeListener listener) { +// support.addPropertyChangeListener(listener); +// } +// +// /** +// * Removes a property change listener. +// * +// * @param listener the listener +// */ +// public void removePropertyChangeListener(PropertyChangeListener listener) { +// support.removePropertyChangeListener(listener); +// } +// +// public SignupState getState() { +// return +// } } diff --git a/src/main/java/interface_adapter/user/UserState.java b/src/main/java/interface_adapter/user/UserState.java deleted file mode 100644 index bb78f6350..000000000 --- a/src/main/java/interface_adapter/user/UserState.java +++ /dev/null @@ -1,20 +0,0 @@ -package interface_adapter.user; - -/** - * Represents the state of a user. - */ -public class UserState { - private String username; - - public UserState(String username) { - this.username = username; - } - - public String getName() { - return username; - } - - public void setName(String username) { - this.username = username; - } -} diff --git a/src/main/java/interface_adapter/user/UserViewModel.java b/src/main/java/interface_adapter/user/UserViewModel.java deleted file mode 100644 index c413fcbd6..000000000 --- a/src/main/java/interface_adapter/user/UserViewModel.java +++ /dev/null @@ -1,31 +0,0 @@ -package interface_adapter.user; - -import interface_adapter.ViewModel; - -/** - * View model for the user profile. - */ -public class UserViewModel extends ViewModel { - private String successMessage; - private String errorMessage; - - public UserViewModel() { - super("User Profile"); - } - - public String getSuccessMessage() { - return successMessage; - } - - public void setSuccessMessage(String successMessage) { - this.successMessage = successMessage; - } - - public String getErrorMessage() { - return errorMessage; - } - - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } -} diff --git a/src/main/java/interface_adapter/user/UserProfileController.java b/src/main/java/interface_adapter/user_profile/UserProfileController.java similarity index 90% rename from src/main/java/interface_adapter/user/UserProfileController.java rename to src/main/java/interface_adapter/user_profile/UserProfileController.java index 63f2f3610..736d02b61 100644 --- a/src/main/java/interface_adapter/user/UserProfileController.java +++ b/src/main/java/interface_adapter/user_profile/UserProfileController.java @@ -1,10 +1,10 @@ -package interface_adapter.user; +package interface_adapter.user_profile; import java.util.List; import java.util.Map; import entity.Place; -import use_case.user.UserProfileInputBoundary; +import use_case.user_profile.UserProfileInputBoundary; /** * Controller for the User Profile use case. diff --git a/src/main/java/interface_adapter/user/UserProfilePresenter.java b/src/main/java/interface_adapter/user_profile/UserProfilePresenter.java similarity index 51% rename from src/main/java/interface_adapter/user/UserProfilePresenter.java rename to src/main/java/interface_adapter/user_profile/UserProfilePresenter.java index 1ce04bbe6..e73b819bf 100644 --- a/src/main/java/interface_adapter/user/UserProfilePresenter.java +++ b/src/main/java/interface_adapter/user_profile/UserProfilePresenter.java @@ -1,34 +1,29 @@ -package interface_adapter.user; +package interface_adapter.user_profile; import interface_adapter.ViewManagerModel; -import use_case.user.UserProfileOutputBoundary; +import use_case.user_profile.UserProfileOutputBoundary; /** * Presenter for user profile creation. */ public class UserProfilePresenter implements UserProfileOutputBoundary { private final ViewManagerModel viewManagerModel; - private final UserViewModel userViewModel; + private final UserProfileViewModel userViewModel; - public UserProfilePresenter(ViewManagerModel viewManagerModel, UserViewModel userViewModel) { + public UserProfilePresenter(ViewManagerModel viewManagerModel, UserProfileViewModel userViewModel) { this.viewManagerModel = viewManagerModel; this.userViewModel = userViewModel; } @Override public void prepareSuccessView(String message) { - userViewModel.setSuccessMessage(message); - - userViewModel.firePropertyChanged("Place save successfuly!"); - - viewManagerModel.setState("PlacesSaved"); - viewManagerModel.firePropertyChanged(); + //teddy u can implement this for urs } @Override public void prepareFailView(String errorMessage) { - userViewModel.setErrorMessage(errorMessage); - - userViewModel.firePropertyChanged("Error in saving place"); + final UserProfileState userProfileState = userViewModel.getState(); + userProfileState.setError(errorMessage); + userViewModel.firePropertyChanged(); } } diff --git a/src/main/java/interface_adapter/user_profile/UserProfileState.java b/src/main/java/interface_adapter/user_profile/UserProfileState.java new file mode 100644 index 000000000..1424d3682 --- /dev/null +++ b/src/main/java/interface_adapter/user_profile/UserProfileState.java @@ -0,0 +1,49 @@ +package interface_adapter.user_profile; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import entity.Place; + +/** + * Represents the state of a user. + */ +public class UserProfileState { + private String username = ""; + private Map> savedPlaces = new HashMap<>(); + private String error; + + public UserProfileState(UserProfileState copy) { + username = copy.username; + savedPlaces = copy.savedPlaces; + } + + public UserProfileState() { + + } + + public String getName() { + return username; + } + + public Map> getSavedPlaces() { + return savedPlaces; + } + + public void setSavedPlaces(Map> savedPlaces) { + this.savedPlaces = savedPlaces; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } +} diff --git a/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java b/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java new file mode 100644 index 000000000..d050dea1a --- /dev/null +++ b/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java @@ -0,0 +1,36 @@ +package interface_adapter.user_profile; + +import interface_adapter.ViewModel; + +/** + * View model for the user profile. + */ +public class UserProfileViewModel extends ViewModel { + + public UserProfileViewModel() { + super("User Profile"); + setState(new UserProfileState()); + } +// private String successMessage; +// private String errorMessage; +// +// public UserProfileViewModel() { +// super("User Profile"); +// } +// +// public String getSuccessMessage() { +// return successMessage; +// } +// +// public void setSuccessMessage(String successMessage) { +// this.successMessage = successMessage; +// } +// +// public String getErrorMessage() { +// return errorMessage; +// } +// +// public void setErrorMessage(String errorMessage) { +// this.errorMessage = errorMessage; +// } +} diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java index 2ed57f690..1e8721e4a 100644 --- a/src/main/java/use_case/login/LoginInteractor.java +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -1,6 +1,7 @@ package use_case.login; import entity.User; +import use_case.user_profile.UserProfileDataAccessInterface; /** * The Login Interactor. @@ -30,7 +31,6 @@ public void execute(LoginInputData loginInputData) { else { final User user = userDataAccessObject.get(loginInputData.getUsername()); - userDataAccessObject.setCurrentUser(user.getName()); final LoginOutputData loginOutputData = new LoginOutputData(user.getName(), false); loginPresenter.prepareSuccessView(loginOutputData); } diff --git a/src/main/java/use_case/login/LoginUserDataAccessInterface.java b/src/main/java/use_case/login/LoginUserDataAccessInterface.java index 72a1baca9..60e744d78 100644 --- a/src/main/java/use_case/login/LoginUserDataAccessInterface.java +++ b/src/main/java/use_case/login/LoginUserDataAccessInterface.java @@ -26,16 +26,4 @@ public interface LoginUserDataAccessInterface { * @return the user with the given username */ User get(String username); - - /** - * Sets the current user. - * @param name is the name of the user. - */ - void setCurrentUser(String name); - - /** - * Gets the current user. - * @return the current username. - */ - String getCurrentUser(); } diff --git a/src/main/java/use_case/user/UserProfileDataAccessInterface.java b/src/main/java/use_case/user_profile/UserProfileDataAccessInterface.java similarity index 97% rename from src/main/java/use_case/user/UserProfileDataAccessInterface.java rename to src/main/java/use_case/user_profile/UserProfileDataAccessInterface.java index eb83d4d0c..e1c965c6b 100644 --- a/src/main/java/use_case/user/UserProfileDataAccessInterface.java +++ b/src/main/java/use_case/user_profile/UserProfileDataAccessInterface.java @@ -1,4 +1,4 @@ -package use_case.user; +package use_case.user_profile; import java.util.List; import java.util.Map; diff --git a/src/main/java/use_case/user/UserProfileInputBoundary.java b/src/main/java/use_case/user_profile/UserProfileInputBoundary.java similarity index 94% rename from src/main/java/use_case/user/UserProfileInputBoundary.java rename to src/main/java/use_case/user_profile/UserProfileInputBoundary.java index 4240a8f8e..a2faa4844 100644 --- a/src/main/java/use_case/user/UserProfileInputBoundary.java +++ b/src/main/java/use_case/user_profile/UserProfileInputBoundary.java @@ -1,4 +1,4 @@ -package use_case.user; +package use_case.user_profile; import java.util.List; import java.util.Map; diff --git a/src/main/java/use_case/user/UserProfileInputData.java b/src/main/java/use_case/user_profile/UserProfileInputData.java similarity index 95% rename from src/main/java/use_case/user/UserProfileInputData.java rename to src/main/java/use_case/user_profile/UserProfileInputData.java index 9492cd9b3..8caa8a5dc 100644 --- a/src/main/java/use_case/user/UserProfileInputData.java +++ b/src/main/java/use_case/user_profile/UserProfileInputData.java @@ -1,4 +1,4 @@ -package use_case.user; +package use_case.user_profile; import java.util.List; diff --git a/src/main/java/use_case/user/UserProfileInteractor.java b/src/main/java/use_case/user_profile/UserProfileInteractor.java similarity index 90% rename from src/main/java/use_case/user/UserProfileInteractor.java rename to src/main/java/use_case/user_profile/UserProfileInteractor.java index 2390642dc..e35fa9c27 100644 --- a/src/main/java/use_case/user/UserProfileInteractor.java +++ b/src/main/java/use_case/user_profile/UserProfileInteractor.java @@ -1,4 +1,4 @@ -package use_case.user; +package use_case.user_profile; import java.util.List; import java.util.Map; @@ -13,9 +13,9 @@ public class UserProfileInteractor implements UserProfileInputBoundary { private final UserProfileDataAccessInterface userProfileDataAccess; private final UserProfileOutputBoundary userProfileOutputBoundary; - public UserProfileInteractor(UserProfileDataAccessInterface userProfileDataAccess, + public UserProfileInteractor(UserProfileDataAccessInterface userProfileDataAccessObject, UserProfileOutputBoundary userProfileOutputBoundary) { - this.userProfileDataAccess = userProfileDataAccess; + this.userProfileDataAccess = userProfileDataAccessObject; this.userProfileOutputBoundary = userProfileOutputBoundary; } diff --git a/src/main/java/use_case/user/UserProfileOutputBoundary.java b/src/main/java/use_case/user_profile/UserProfileOutputBoundary.java similarity index 93% rename from src/main/java/use_case/user/UserProfileOutputBoundary.java rename to src/main/java/use_case/user_profile/UserProfileOutputBoundary.java index 97cc2840d..c0fc4e470 100644 --- a/src/main/java/use_case/user/UserProfileOutputBoundary.java +++ b/src/main/java/use_case/user_profile/UserProfileOutputBoundary.java @@ -1,4 +1,4 @@ -package use_case.user; +package use_case.user_profile; /** * Output boundary for the User Profile use case. diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java index 0e665eda8..2514ca8d0 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/SignupView.java @@ -33,14 +33,14 @@ public SignupView(SignupController signupController, SignupViewModel signupViewM final JLabel title = new JLabel("Sign Up"); title.setAlignmentX(Component.CENTER_ALIGNMENT); - add(new JLabel("Pick a Username:")); - add(usernameInputField); - add(new JLabel("Pick a Password:")); - add(passwordInputField); - add(new JLabel("Confirm Password:")); - add(repeatPasswordInputField); + final LabelTextPanel usernameInfo = new LabelTextPanel( + new JLabel("Pick a username:"), usernameInputField); + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel("Pick a password:"), passwordInputField); + final LabelTextPanel repeatPasswordInfo = new LabelTextPanel( + new JLabel("Re-enter password:"), repeatPasswordInputField); - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); final JPanel buttons = new JPanel(); final JButton signUpButton = new JButton("Sign Up"); @@ -77,9 +77,9 @@ public void actionPerformed(ActionEvent e) { this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); - this.add(usernameInputField); - this.add(passwordInputField); - this.add(repeatPasswordInputField); + this.add(usernameInfo); + this.add(passwordInfo); + this.add(repeatPasswordInfo); this.add(buttons); } diff --git a/src/main/java/view/UserProfileView.java b/src/main/java/view/UserProfileView.java index 304a1c91f..52add2369 100644 --- a/src/main/java/view/UserProfileView.java +++ b/src/main/java/view/UserProfileView.java @@ -1,5 +1,9 @@ package view; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -16,13 +20,18 @@ import entity.Place; import entity.SavedPlace; -import interface_adapter.user.UserProfileController; -import interface_adapter.user.UserViewModel; +import interface_adapter.user_profile.UserProfileController; +import interface_adapter.user_profile.UserProfileViewModel; /** * View for the user profile. */ -public class UserProfileView extends JPanel { +public class UserProfileView extends JPanel implements PropertyChangeListener, ActionListener { + + private final String viewName = "User Profile"; + private final UserProfileViewModel userProfileViewModel; + private final UserProfileController userProfileController; + private final JTextField placeNameField = new JTextField(20); private final JTextField placeAddressField = new JTextField(20); private final JTextField placeReviewField = new JTextField(20); @@ -30,10 +39,11 @@ public class UserProfileView extends JPanel { private final JButton addPlaceButton = new JButton("Add Place"); private final JTextArea placesListArea = new JTextArea(10, 30); private final JButton logOutButton = new JButton("Log Out"); - private final UserProfileController userProfileController; - public UserProfileView(UserProfileController userProfileController, UserViewModel userViewModel) { + public UserProfileView(UserProfileController userProfileController, UserProfileViewModel userProfileViewModel) { this.userProfileController = userProfileController; + this.userProfileViewModel = userProfileViewModel; + this.userProfileViewModel.addPropertyChangeListener(this); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); // Add UI elements for adding a place @@ -59,34 +69,60 @@ public UserProfileView(UserProfileController userProfileController, UserViewMode final Map> newPlaceMap = new HashMap<>(); newPlaceMap.put(placeName, placeList); - userProfileController.savePlaces(userViewModel.getState().getName(), newPlaceMap); + userProfileController.savePlaces(userProfileViewModel.getState().getName(), newPlaceMap); }); // Display list of saved places add(new JLabel("Saved Places:")); add(new JScrollPane(placesListArea)); - userViewModel.addPropertyChangeListener(evt -> { - if ("savedPlaces".equals(evt.getPropertyName())) { - final Map> savedPlaces = (Map>) evt.getNewValue(); - final StringBuilder placesString = new StringBuilder(); - for (Map.Entry> entry : savedPlaces.entrySet()) { - placesString.append(entry.getKey()).append(":\n"); - for (Place place : entry.getValue()) { - if (place instanceof SavedPlace) { - final SavedPlace savedPlace = (SavedPlace) place; - placesString.append(" - Address: ").append(savedPlace.getAddress()).append("\n"); - placesString.append(" - Review: ").append(savedPlace.getReview()).append("\n"); - placesString.append(" - Liked: ").append(savedPlace.getRating() ? "Yes" : "No").append("\n"); - } - } - } - placesListArea.setText(placesString.toString()); - } - }); + final Map> savedPlaces = userProfileViewModel.getState().getSavedPlaces(); + for (final Map.Entry> entry : savedPlaces.entrySet()) { + final JPanel listNamePanel = new JPanel(); + final JLabel listName = new JLabel(entry.getKey()); + final JButton viewListButton = new JButton("View List"); + listNamePanel.add(listName); + listNamePanel.add(viewListButton); + //teddy u can add the action listener for the button here + } + +// userProfileViewModel.addPropertyChangeListener(evt -> { +// // if this doesn't work, try changing the "save places" to state, and in the presenter get rid of "save places" +// if ("save places".equals(evt.getPropertyName())) { +// final Map> savedPlaces = (Map>) evt.getNewValue(); +// final StringBuilder placesString = new StringBuilder(); +// for (Map.Entry> entry : savedPlaces.entrySet()) { +// placesString.append(entry.getKey()).append(":\n"); +// for (Place place : entry.getValue()) { +// if (place instanceof SavedPlace) { +// final SavedPlace savedPlace = (SavedPlace) place; +// placesString.append(" - Address: ").append(savedPlace.getAddress()).append("\n"); +// placesString.append(" - Review: ").append(savedPlace.getReview()).append("\n"); +// placesString.append(" - Liked: ").append(savedPlace.getRating() ? "Yes" : "No").append("\n"); +// } +// } +// } +// placesListArea.setText(placesString.toString()); +// } +// }); // Log out button add(logOutButton); logOutButton.addActionListener(evt -> userProfileController.logOut()); } + + @Override + public void actionPerformed(ActionEvent e) { + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + } + + public String getViewName() { + return viewName; + } + } From f9ea67d07bf09fbd03ae13e3d47e2f2a68c11e11 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 1 Dec 2024 22:18:19 -0500 Subject: [PATCH 108/113] fixed DAO and now it opens in new browser --- .../reviewlocation/ReviewLocationController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java index 29c270af8..7498dbc2d 100644 --- a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java +++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java @@ -2,6 +2,4 @@ public class ReviewLocationController { - private final - } From 2d85dc93434351c579116827d3e634139a2eff95 Mon Sep 17 00:00:00 2001 From: teddyyang Date: Sun, 1 Dec 2024 22:18:40 -0500 Subject: [PATCH 109/113] fixed DAO and now it opens in new browser --- .../suggested_locations/SuggestedLocationsOutputData.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java index 9ceffc864..06e95698e 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -22,6 +22,7 @@ public SuggestedLocationsOutputData(List selectedLocations, Map getSelectedLocations() { return selectedLocations; + } public Map getCalendarItems() { return calendarItems; From 06e5ff4d9b826653b4bb3e1767d17e23719ae69b Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:16:36 -0500 Subject: [PATCH 110/113] implemented more buttons and functionalities. --- src/main/java/app/CalendarUseCaseFactory.java | 12 +++-- src/main/java/app/LocationUseCaseFactory.java | 14 +++-- src/main/java/app/LoginUseCaseFactory.java | 12 +++-- src/main/java/app/MainWithDB.java | 16 ++---- .../app/SuggestedLocationsUseCaseFactory.java | 53 ++++++++++++++----- .../DBCoordinatesDataAccessObject.java | 2 +- .../AddToCalendarController.java | 4 ++ .../AddToCalendarPresenter.java | 13 ++++- .../location/LocationController.java | 8 +-- .../location/LocationState.java | 9 ++++ .../login/LoginController.java | 4 ++ .../login/LoginPresenter.java | 16 +++++- .../SuggestedLocationsPresenter.java | 2 +- .../AddToCalendarInputBoundary.java | 6 +++ .../AddToCalendarInteractor.java | 5 ++ .../AddToCalendarOutputBoundary.java | 5 ++ .../locations/LocationsInputData.java | 8 ++- .../locations/LocationsInteractor.java | 18 ++++--- .../use_case/login/LoginInputBoundary.java | 5 ++ .../java/use_case/login/LoginInteractor.java | 5 ++ .../use_case/login/LoginOutputBoundary.java | 5 ++ .../CoordinateDataAccessInterface.java | 5 +- .../SelectedLocationsInteractor.java | 1 - .../SuggestedLocationsInteractor.java | 8 +-- .../SuggestedLocationsOutputData.java | 24 +++++---- src/main/java/view/CalendarView.java | 8 +-- src/main/java/view/LocationView.java | 6 ++- src/main/java/view/LoginView.java | 10 +++- .../java/view/SuggestedLocationsView.java | 27 ++++------ .../AddToCalendarInteractorTest.java | 10 ++++ 30 files changed, 224 insertions(+), 97 deletions(-) rename src/main/java/use_case/{ => selected_locations}/CoordinateDataAccessInterface.java (87%) diff --git a/src/main/java/app/CalendarUseCaseFactory.java b/src/main/java/app/CalendarUseCaseFactory.java index 582cf5310..60dcc7f63 100644 --- a/src/main/java/app/CalendarUseCaseFactory.java +++ b/src/main/java/app/CalendarUseCaseFactory.java @@ -4,6 +4,7 @@ import interface_adapter.add_to_calendar.AddToCalendarController; import interface_adapter.add_to_calendar.AddToCalendarPresenter; import interface_adapter.add_to_calendar.AddToCalendarViewModel; +import interface_adapter.location.LocationViewModel; import use_case.add_to_calendar.AddToCalendarDataAccessInterface; import use_case.add_to_calendar.AddToCalendarInputBoundary; import use_case.add_to_calendar.AddToCalendarInteractor; @@ -25,13 +26,15 @@ private CalendarUseCaseFactory() { * @param viewManagerModel the ViewManagerModel to inject * @param calendarViewModel the AddToCalendarViewModel to inject * @param calendarDataAccessObject the AddToCalendarDataAccessObject to inject + * @param locationViewModel the LocationViewModel to inject * @return the LocationView created for the provided input classes. */ public static CalendarView create(ViewManagerModel viewManagerModel, AddToCalendarViewModel calendarViewModel, - AddToCalendarDataAccessInterface calendarDataAccessObject) { + AddToCalendarDataAccessInterface calendarDataAccessObject, + LocationViewModel locationViewModel) { final AddToCalendarController calendarController = createCalendarUseCase(viewManagerModel, - calendarViewModel, calendarDataAccessObject); + calendarViewModel, calendarDataAccessObject, locationViewModel); return new CalendarView(calendarViewModel, calendarController); } @@ -39,9 +42,10 @@ public static CalendarView create(ViewManagerModel viewManagerModel, private static AddToCalendarController createCalendarUseCase( ViewManagerModel viewManagerModel, AddToCalendarViewModel calendarViewModel, - AddToCalendarDataAccessInterface calendarDataAccessObject) { + AddToCalendarDataAccessInterface calendarDataAccessObject, + LocationViewModel locationViewModel) { final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel, - viewManagerModel); + viewManagerModel, locationViewModel); final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject, calendarOutputBoundary); diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java index 899f8e188..6ec20dc30 100644 --- a/src/main/java/app/LocationUseCaseFactory.java +++ b/src/main/java/app/LocationUseCaseFactory.java @@ -9,6 +9,7 @@ import use_case.locations.LocationsInputBoundary; import use_case.locations.LocationsInteractor; import use_case.locations.LocationsOutputBoundary; +import use_case.user_profile.UserProfileDataAccessInterface; import view.LocationView; /** @@ -27,16 +28,18 @@ private LocationUseCaseFactory() { * @param locationViewModel the LocationViewModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject * @param locationDataAccessObject the LocationDataAccessInterface to inject + * @param userDataAccessObject the UserProfileDataAccessInterface to inject * @return the LocationView created for the provided input classes. */ public static LocationView create( ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, SuggestedLocationsViewModel suggestedLocationsViewModel, - LocationDataAccessInterface locationDataAccessObject) { + LocationDataAccessInterface locationDataAccessObject, + UserProfileDataAccessInterface userDataAccessObject) { final LocationController locationController = createLocationUseCase(viewManagerModel, locationViewModel, - suggestedLocationsViewModel, locationDataAccessObject); + suggestedLocationsViewModel, locationDataAccessObject, userDataAccessObject); return new LocationView(locationViewModel, locationController); } @@ -45,12 +48,13 @@ private static LocationController createLocationUseCase( ViewManagerModel viewManagerModel, LocationViewModel locationViewModel, SuggestedLocationsViewModel suggestedLocationsViewModel, - LocationDataAccessInterface userDataAccessObject) { + LocationDataAccessInterface locationDataAccessObject, + UserProfileDataAccessInterface userDataAccessObject) { final LocationsOutputBoundary locationsOutputBoundary = new LocationPresenter(locationViewModel, suggestedLocationsViewModel, viewManagerModel); - final LocationsInputBoundary locationInteractor = new LocationsInteractor(userDataAccessObject, - locationsOutputBoundary); + final LocationsInputBoundary locationInteractor = new LocationsInteractor(locationDataAccessObject, + locationsOutputBoundary, userDataAccessObject); return new LocationController(locationInteractor); } diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java index 7478d33a5..7d58eb83b 100644 --- a/src/main/java/app/LoginUseCaseFactory.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -2,6 +2,7 @@ import interface_adapter.ViewManagerModel; import interface_adapter.location.LocationViewModel; +import interface_adapter.signup.SignupViewModel; import interface_adapter.user_profile.UserProfileViewModel; import interface_adapter.login.LoginController; import interface_adapter.login.LoginPresenter; @@ -29,6 +30,7 @@ private LoginUseCaseFactory() { * @param userProfileViewModel the LoggedInViewModel to inject into the LoginView * @param locationViewModel the LocationViewModel to inject into the LoginView * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView + * @param signupViewModel the SignupViewModel to inject into the LoginView * @return the LoginView created for the provided input classes */ public static LoginView create( @@ -36,10 +38,11 @@ public static LoginView create( LoginViewModel loginViewModel, UserProfileViewModel userProfileViewModel, LocationViewModel locationViewModel, - LoginUserDataAccessInterface userDataAccessObject) { + LoginUserDataAccessInterface userDataAccessObject, + SignupViewModel signupViewModel) { final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel, - userProfileViewModel, locationViewModel, userDataAccessObject); + userProfileViewModel, locationViewModel, userDataAccessObject, signupViewModel); return new LoginView(loginViewModel, loginController); } @@ -49,11 +52,12 @@ private static LoginController createLoginUseCase( LoginViewModel loginViewModel, UserProfileViewModel userProfileViewModel, LocationViewModel locationViewModel, - LoginUserDataAccessInterface userDataAccessObject) { + LoginUserDataAccessInterface userDataAccessObject, + SignupViewModel signUpViewModel) { // Notice how we pass this method's parameters to the Presenter. final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, - userProfileViewModel, loginViewModel, locationViewModel); + userProfileViewModel, loginViewModel, locationViewModel, signUpViewModel); final LoginInputBoundary loginInteractor = new LoginInteractor( userDataAccessObject, loginOutputBoundary); diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index a0dfae4c5..6ba6720fb 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -64,7 +64,6 @@ public static void main(String[] args) { final AddToCalendarViewModel calendarViewModel = new AddToCalendarViewModel(); final SelectedLocationsViewModel selectedLocationsViewModel = new SelectedLocationsViewModel(); final UserProfileViewModel userProfileViewModel = new UserProfileViewModel(); - final AddToCalendarViewModel calendarViewModel = new AddToCalendarViewModel(); // add any future view models here in the same way final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject( @@ -72,22 +71,22 @@ public static void main(String[] args) { final InMemoryCalendarDataAccessObject calendarDataAccessObject = new InMemoryCalendarDataAccessObject(); final DBCoordinatesDataAccessObject coordinatesDataAccessObject = new DBCoordinatesDataAccessObject(); final InMemoryUserDataAccessObject userDataAccessObject = new InMemoryUserDataAccessObject(); - final InMemoryCalendarDataAccessObject calendarDataAccessObject = new InMemoryCalendarDataAccessObject(); final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); views.add(signupView, signupView.getViewName()); final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - userProfileViewModel, locationViewModel, userDataAccessObject); + userProfileViewModel, locationViewModel, userDataAccessObject, signupViewModel); views.add(loginView, loginView.getViewName()); final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel, - suggestedLocationsViewModel, locationDataAccessObject); + suggestedLocationsViewModel, locationDataAccessObject, userDataAccessObject); views.add(locationView, locationView.getViewName()); final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel, - suggestedLocationsViewModel, calendarViewModel); + suggestedLocationsViewModel, calendarViewModel, selectedLocationsViewModel, coordinatesDataAccessObject, + calendarDataAccessObject, locationViewModel); views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel, @@ -95,7 +94,7 @@ public static void main(String[] args) { views.add(selectedLocationView, selectedLocationView.getViewName()); final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel, - calendarDataAccessObject); + calendarDataAccessObject, locationViewModel); views.add(calendarView, calendarView.getViewName()); final UserProfileView userProfileView = UserProfileUseCaseFactory.create(viewManagerModel, @@ -103,11 +102,6 @@ public static void main(String[] args) { views.add(userProfileView, userProfileView.getViewName()); viewManagerModel.setState(signupView.getViewName()); - final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel, - calendarDataAccessObject); - views.add(calendarView, calendarView.getViewName()); - - viewManagerModel.setState(locationView.getViewName()); viewManagerModel.firePropertyChanged(); application.pack(); diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 43e1ccaf7..92e6d66d9 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -1,17 +1,20 @@ package app; - -import data_access.DBCoordinatesDataAccessObject; import interface_adapter.ViewManagerModel; +import interface_adapter.add_to_calendar.AddToCalendarPresenter; +import interface_adapter.location.LocationViewModel; import interface_adapter.selectedlocation.SelectedLocationsPresenter; -import interface_adapter.selectedlocation.SelectedLocationsViewModel;/ +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.add_to_calendar.AddToCalendarController; import interface_adapter.add_to_calendar.AddToCalendarViewModel; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; +import use_case.add_to_calendar.AddToCalendarDataAccessInterface; +import use_case.add_to_calendar.AddToCalendarInputBoundary; +import use_case.add_to_calendar.AddToCalendarInteractor; +import use_case.add_to_calendar.AddToCalendarOutputBoundary; +import use_case.selected_locations.CoordinateDataAccessInterface; import use_case.selected_locations.SelectedLocationsInputBoundary; import use_case.selected_locations.SelectedLocationsInteractor; import use_case.selected_locations.SelectedLocationsOutputBoundary; @@ -36,24 +39,35 @@ private SuggestedLocationsUseCaseFactory() { * @param viewManagerModel the ViewManagerModel to inject * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject * @param selectedLocationsViewModel the SelectedLocationsViewModel to inject - * @param calendarViewModel the LocationViewModel to inject + * @param calendarViewModel the CalendarViewModel to inject + * @param coordinateDataAccessObject the CoordinateDataAccessInterface to inject + * @param calendarDataAccessObject the AddToCalendarDataAccessInterface to inject + * @param locationViewModel the LocationViewModel to inject * @return the LocationView created for the provided input classes. */ public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, - AddToCalendarViewModel calendarViewModel - SelectedLocationsViewModel selectedLocationsViewModel) { + AddToCalendarViewModel calendarViewModel, + SelectedLocationsViewModel selectedLocationsViewModel, + CoordinateDataAccessInterface coordinateDataAccessObject, + AddToCalendarDataAccessInterface calendarDataAccessObject, + LocationViewModel locationViewModel) { final SelectedLocationsController selectedLocationController = createSelectedLocationUseCase(viewManagerModel, - selectedLocationsViewModel, new DBCoordinatesDataAccessObject()); + selectedLocationsViewModel, coordinateDataAccessObject); final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase( viewManagerModel, suggestedLocationsViewModel, - calendarViewModel); + calendarViewModel, + selectedLocationsViewModel); + + final AddToCalendarController calendarController = createAddToCalendarUseCase(viewManagerModel, + calendarViewModel, calendarDataAccessObject, locationViewModel); - return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel, selectedLocationsViewModel, selectedLocationController); + return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel, + calendarController, selectedLocationsViewModel, selectedLocationController); } private static SuggestedLocationsController createSuggestedLocationUseCase( @@ -74,7 +88,7 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( private static SelectedLocationsController createSelectedLocationUseCase( ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel, - DBCoordinatesDataAccessObject coordinatesDataAccessObject) { + CoordinateDataAccessInterface coordinatesDataAccessObject) { final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( selectedLocationsViewModel, viewManagerModel); final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( @@ -82,6 +96,21 @@ private static SelectedLocationsController createSelectedLocationUseCase( return new SelectedLocationsController(selectedLocationsInteractor); } + + private static AddToCalendarController createAddToCalendarUseCase( + ViewManagerModel viewManagerModel, + AddToCalendarViewModel calendarViewModel, + AddToCalendarDataAccessInterface calendarDataAccessObject, + LocationViewModel locationViewModel) { + + final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel, + viewManagerModel, locationViewModel); + + final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject, + calendarOutputBoundary); + + return new AddToCalendarController(calendarInteractor); + } } diff --git a/src/main/java/data_access/DBCoordinatesDataAccessObject.java b/src/main/java/data_access/DBCoordinatesDataAccessObject.java index 2b6f11c0b..ec81e2e40 100644 --- a/src/main/java/data_access/DBCoordinatesDataAccessObject.java +++ b/src/main/java/data_access/DBCoordinatesDataAccessObject.java @@ -9,7 +9,7 @@ import org.json.JSONObject; import use_case.DataAccessException; -import use_case.locations.CoordinateDataAccessInterface; +import use_case.selected_locations.CoordinateDataAccessInterface; /** * The DAO for accessing places using Google Places API. diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java index a25366c0c..7d8ed2f2d 100644 --- a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java @@ -29,4 +29,8 @@ public void execute(Map addToCalendarData) throws DataAccessExcep addToCalendarInteractor.execute(calendarInputData); } + + public void switchToLocationView() { + addToCalendarInteractor.switchToLocationView(); + } } diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java index dd4bea06b..343d4d72c 100644 --- a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java @@ -1,6 +1,7 @@ package interface_adapter.add_to_calendar; import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; import use_case.add_to_calendar.AddToCalendarOutputBoundary; import use_case.add_to_calendar.AddToCalendarOutputData; @@ -11,15 +12,19 @@ public class AddToCalendarPresenter implements AddToCalendarOutputBoundary { private final AddToCalendarViewModel calendarViewModel; private final ViewManagerModel viewManagerModel; + private final LocationViewModel locationViewModel; - public AddToCalendarPresenter(AddToCalendarViewModel calendarViewModel, ViewManagerModel viewManagerModel) { + public AddToCalendarPresenter(AddToCalendarViewModel calendarViewModel, ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel) { this.calendarViewModel = calendarViewModel; this.viewManagerModel = viewManagerModel; + this.locationViewModel = locationViewModel; } @Override public void prepareSuccessView(AddToCalendarOutputData outputData) { + // On success, switch to the Calendar view. final AddToCalendarState calendarState = calendarViewModel.getState(); calendarState.setCalendarItems(outputData.getcalendarItems()); this.calendarViewModel.setState(calendarState); @@ -35,4 +40,10 @@ public void prepareFailView(String errorMessage) { calendarState.setAddError(errorMessage); calendarViewModel.firePropertyChanged(); } + + @Override + public void switchToLocationView() { + viewManagerModel.setState(locationViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java index 8870cf35e..64614657b 100644 --- a/src/main/java/interface_adapter/location/LocationController.java +++ b/src/main/java/interface_adapter/location/LocationController.java @@ -22,13 +22,13 @@ public LocationController(LocationsInputBoundary locationInteractor) { * Executes the show location. * @param address the location to show. * @param locationType the type of location to search. + * @param currentFilter the type of filter to search with. + * @param username the username of the current user. * @throws DataAccessException if data cannot be accessed */ - - - public void execute(String address, String locationType, String currentFilter) throws DataAccessException { + public void execute(String address, String locationType, String currentFilter, String username) throws DataAccessException { final LocationsInputData locationInputData = new LocationsInputData( - address, locationType); + address, locationType, username); locationInput.execute(locationInputData, currentFilter); } diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java index 2e93d8b3a..d3c061d0c 100644 --- a/src/main/java/interface_adapter/location/LocationState.java +++ b/src/main/java/interface_adapter/location/LocationState.java @@ -7,6 +7,7 @@ public class LocationState { private String address = ""; private String locationType = ""; + private String username = ""; private String error; public String getAddress() { @@ -32,5 +33,13 @@ public String getError() { public void setError(String error) { this.error = error; } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } } diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/interface_adapter/login/LoginController.java index 57e950666..6f58ab10b 100644 --- a/src/main/java/interface_adapter/login/LoginController.java +++ b/src/main/java/interface_adapter/login/LoginController.java @@ -25,4 +25,8 @@ public void execute(String username, String password) { loginUseCaseInteractor.execute(loginInputData); } + + public void switchToSignUpView() { + loginUseCaseInteractor.switchToSignUpView(); + } } diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java index 9777bfb49..6f04e738b 100644 --- a/src/main/java/interface_adapter/login/LoginPresenter.java +++ b/src/main/java/interface_adapter/login/LoginPresenter.java @@ -1,7 +1,9 @@ package interface_adapter.login; import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationState; import interface_adapter.location.LocationViewModel; +import interface_adapter.signup.SignupViewModel; import interface_adapter.user_profile.UserProfileState; import interface_adapter.user_profile.UserProfileViewModel; import use_case.login.LoginOutputBoundary; @@ -16,15 +18,18 @@ public class LoginPresenter implements LoginOutputBoundary { private final UserProfileViewModel userProfileViewModel; private final LocationViewModel locationViewModel; private final ViewManagerModel viewManagerModel; + private final SignupViewModel signUpViewModel; public LoginPresenter(ViewManagerModel viewManagerModel, UserProfileViewModel userProfileViewModel, LoginViewModel loginViewModel, - LocationViewModel locationViewModel) { + LocationViewModel locationViewModel, + SignupViewModel signUpViewModel) { this.viewManagerModel = viewManagerModel; this.userProfileViewModel = userProfileViewModel; this.loginViewModel = loginViewModel; this.locationViewModel = locationViewModel; + this.signUpViewModel = signUpViewModel; } @Override @@ -35,6 +40,9 @@ public void prepareSuccessView(LoginOutputData response) { userProfileState.setUsername(response.getUsername()); this.userProfileViewModel.setState(userProfileState); this.userProfileViewModel.firePropertyChanged(); + final LocationState locationState = locationViewModel.getState(); + locationState.setUsername(response.getUsername()); + this.locationViewModel.setState(locationState); this.viewManagerModel.setState(locationViewModel.getViewName()); this.viewManagerModel.firePropertyChanged(); @@ -46,4 +54,10 @@ public void prepareFailView(String error) { loginState.setLoginError(error); loginViewModel.firePropertyChanged(); } + + @Override + public void switchToSignUpView() { + viewManagerModel.setState(signUpViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java index 1b57a99a1..61df96697 100644 --- a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java +++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java @@ -34,7 +34,7 @@ public void prepareSuccessView(SuggestedLocationsOutputData response) { // On success, switch to the Calendar view. final AddToCalendarState calendarState = addToCalendarViewModel.getState(); - calendarState.setCalendarItems(response.getCalendarItems()); +// calendarState.setCalendarItems(response.getCalendarItems()); this.addToCalendarViewModel.setState(calendarState); this.addToCalendarViewModel.firePropertyChanged(); diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java index f3bd6b104..aec1930cf 100644 --- a/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java @@ -14,4 +14,10 @@ public interface AddToCalendarInputBoundary { * @throws DataAccessException if data cannot be accessed at any time */ void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException; + + /** + * Execute the switch to location view. + */ + void switchToLocationView(); + } diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java index c41f02319..a3a94f763 100644 --- a/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java @@ -34,4 +34,9 @@ public void execute(AddToCalendarInputData addToCalendarInputData) throws DataAc final AddToCalendarOutputData addToCalendarOutputData = new AddToCalendarOutputData(addToCalendarPlace); calendarPresenter.prepareSuccessView(addToCalendarOutputData); } + + @Override + public void switchToLocationView() { + calendarPresenter.switchToLocationView(); + } } diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java index 1c6f2e480..7abf6266e 100644 --- a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java +++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java @@ -16,4 +16,9 @@ public interface AddToCalendarOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); + + /** + * Execute the switch to location view. + */ + void switchToLocationView(); } diff --git a/src/main/java/use_case/locations/LocationsInputData.java b/src/main/java/use_case/locations/LocationsInputData.java index 2bbd46878..86b44a84f 100644 --- a/src/main/java/use_case/locations/LocationsInputData.java +++ b/src/main/java/use_case/locations/LocationsInputData.java @@ -7,10 +7,12 @@ public class LocationsInputData { private final String address; private final String locationType; + private final String username; - public LocationsInputData(String address, String locationType) { + public LocationsInputData(String address, String locationType, String username) { this.address = address; this.locationType = locationType; + this.username = username; } public String getAddress() { @@ -21,4 +23,8 @@ public String getLocationType() { return locationType; } + public String getUsername() { + return username; + } + } diff --git a/src/main/java/use_case/locations/LocationsInteractor.java b/src/main/java/use_case/locations/LocationsInteractor.java index ab5d99564..d8a805436 100644 --- a/src/main/java/use_case/locations/LocationsInteractor.java +++ b/src/main/java/use_case/locations/LocationsInteractor.java @@ -1,9 +1,12 @@ package use_case.locations; - +import data_access.InMemoryUserDataAccessObject; import entity.Place; +import interface_adapter.user_profile.UserProfileState; import use_case.DataAccessException; import entity.User; +import use_case.user_profile.UserProfileDataAccessInterface; + import java.util.List; import java.util.Map; @@ -13,11 +16,14 @@ public class LocationsInteractor implements LocationsInputBoundary { private final LocationDataAccessInterface placeDataAccessObject; private final LocationsOutputBoundary placePresenter; + private final UserProfileDataAccessInterface userDataAccessObject; public LocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface, - LocationsOutputBoundary locationsOutputBoundary) { + LocationsOutputBoundary locationsOutputBoundary, + UserProfileDataAccessInterface userDataAccessObject) { this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface; this.placePresenter = locationsOutputBoundary; + this.userDataAccessObject = userDataAccessObject; } @Override @@ -30,10 +36,9 @@ public void execute(LocationsInputData locationsInputData, String currentFilter) .searchLocation(locationsInputData.getAddress(), locationsInputData.getLocationType()), false); placePresenter.prepareSuccessView(locationsOutputData); - } - else if ("Remove Saved Locations".equals(currentFilter)) { + } else if ("Remove Saved Locations".equals(currentFilter)) { for (Place place : suggestedPlaces) { - final User user = userDataAccessObject.getUser(); + final User user = userDataAccessObject.getUser(locationsInputData.getUsername()); for (Map.Entry> entry : user.getSavedPlaces().entrySet()) { if (entry.getValue().contains(place)) { suggestedPlaces.remove(place); @@ -43,6 +48,5 @@ else if ("Remove Saved Locations".equals(currentFilter)) { final LocationsOutputData locationsOutputData = new LocationsOutputData(suggestedPlaces, false); placePresenter.prepareSuccessView(locationsOutputData); } -} - + } } diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java index faf72dc96..cb696b1e8 100644 --- a/src/main/java/use_case/login/LoginInputBoundary.java +++ b/src/main/java/use_case/login/LoginInputBoundary.java @@ -10,4 +10,9 @@ public interface LoginInputBoundary { * @param loginInputData the input data */ void execute(LoginInputData loginInputData); + + /** + * Executes the switch back to sign up view + */ + void switchToSignUpView(); } diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java index 1e8721e4a..a856b9f56 100644 --- a/src/main/java/use_case/login/LoginInteractor.java +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -36,4 +36,9 @@ public void execute(LoginInputData loginInputData) { } } } + + @Override + public void switchToSignUpView() { + loginPresenter.switchToSignUpView(); + } } diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java index 08bc4731f..81c6934f3 100644 --- a/src/main/java/use_case/login/LoginOutputBoundary.java +++ b/src/main/java/use_case/login/LoginOutputBoundary.java @@ -15,4 +15,9 @@ public interface LoginOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); + + /** + * Switches to the SignUp View. + */ + void switchToSignUpView(); } diff --git a/src/main/java/use_case/CoordinateDataAccessInterface.java b/src/main/java/use_case/selected_locations/CoordinateDataAccessInterface.java similarity index 87% rename from src/main/java/use_case/CoordinateDataAccessInterface.java rename to src/main/java/use_case/selected_locations/CoordinateDataAccessInterface.java index 98e47acd7..40f09bbca 100644 --- a/src/main/java/use_case/CoordinateDataAccessInterface.java +++ b/src/main/java/use_case/selected_locations/CoordinateDataAccessInterface.java @@ -1,7 +1,4 @@ -package use_case.locations; - -import java.util.HashMap; -import java.util.List; +package use_case.selected_locations; import entity.Place; import use_case.DataAccessException; diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java index 9490c8599..1f9c4271c 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -2,7 +2,6 @@ import entity.Place; import use_case.DataAccessException; -import use_case.locations.CoordinateDataAccessInterface; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java index fa5a4c01d..fa0fb02c3 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsInteractor.java @@ -1,6 +1,7 @@ package use_case.suggested_locations; import use_case.DataAccessException; +import use_case.selected_locations.SelectedLocationsInputData; /** * The Suggested Locations Interactor. @@ -14,8 +15,9 @@ public SuggestedLocationsInteractor(SuggestedLocationsOutputBoundary suggestedLo @Override public void execute(SuggestedLocationsInputData suggestedLocationsInputData) { - final SuggestedLocationsOutputData suggestedLocationsOutputData = new SuggestedLocationsOutputData( - suggestedLocationsInputData.getSuggestedLocations(), false); - placePresenter.prepareSuccessView(suggestedLocationsOutputData); +// final SuggestedLocationsOutputData suggestedLocationsOutputData = new SuggestedLocationsOutputData( +// suggestedLocationsInputData.getSuggestedLocations(), false); +// placePresenter.prepareSuccessView(suggestedLocationsOutputData) + System.out.println("got here somehow"); } } diff --git a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java index a26eded06..56aeb653b 100644 --- a/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java +++ b/src/main/java/use_case/suggested_locations/SuggestedLocationsOutputData.java @@ -10,26 +10,28 @@ */ public class SuggestedLocationsOutputData { - private final Map calendarItems; +// private final Map calendarItems; private final List selectedLocations; private final boolean useCaseFailed; - public SuggestedLocationsOutputData(Map calendarItems, boolean useCaseFailed) { - this.calendarItems = calendarItems; - this.useCaseFailed = useCaseFailed; - } - - public pleaceholderforSeancode(List selectedLocations, Map calendarItems, boolean useCaseFailed) { + public SuggestedLocationsOutputData(List selectedLocations, + boolean useCaseFailed) { +// this.calendarItems = calendarItems; this.selectedLocations = selectedLocations; - this.calendarItems = calendarItems; this.useCaseFailed = useCaseFailed; } +// public pleaceholderforSeancode(List selectedLocations, Map calendarItems, boolean useCaseFailed) { +// this.selectedLocations = selectedLocations; +// this.calendarItems = calendarItems; +// this.useCaseFailed = useCaseFailed; +// } + public List getSelectedLocations() { return selectedLocations; } - public Map getCalendarItems() { - return calendarItems; - } +// public Map getCalendarItems() { +// return calendarItems; +// } } diff --git a/src/main/java/view/CalendarView.java b/src/main/java/view/CalendarView.java index 54599fbb0..1e957b554 100644 --- a/src/main/java/view/CalendarView.java +++ b/src/main/java/view/CalendarView.java @@ -62,13 +62,7 @@ public CalendarView(AddToCalendarViewModel calendarViewModel, AddToCalendarContr @Override public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(newSearchButton)) { - final AddToCalendarState currentState = calendarViewModel.getState(); - try { - addToCalendarController.execute(currentState.getCalendarItems()); - } - catch (DataAccessException e) { - throw new RuntimeException(); - } + addToCalendarController.switchToLocationView(); } } diff --git a/src/main/java/view/LocationView.java b/src/main/java/view/LocationView.java index 4165bdd54..47c908770 100644 --- a/src/main/java/view/LocationView.java +++ b/src/main/java/view/LocationView.java @@ -131,7 +131,8 @@ public void changedUpdate(DocumentEvent e) { currentFilter = filtersDropDown.getSelectedItem().toString(); final LocationState currentState = locationViewModel.getState(); try { - locationController.execute(currentState.getAddress(), currentState.getLocationType(), currentFilter); + locationController.execute(currentState.getAddress(), currentState.getLocationType(), + currentFilter, currentState.getUsername()); } catch (DataAccessException e) { throw new RuntimeException(e); @@ -145,7 +146,8 @@ public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(suggestLocationsButton)) { final LocationState currentState = locationViewModel.getState(); try { - locationController.execute(currentState.getAddress(), currentState.getLocationType(), currentFilter); + locationController.execute(currentState.getAddress(), currentState.getLocationType(), currentFilter, + currentState.getUsername()); } catch (DataAccessException e) { throw new RuntimeException(e); diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java index b963637bb..8fc91c043 100644 --- a/src/main/java/view/LoginView.java +++ b/src/main/java/view/LoginView.java @@ -66,7 +66,15 @@ public void actionPerformed(ActionEvent evt) { } ); - cancel.addActionListener(this); + cancel.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(cancel)) { + loginController.switchToSignUpView(); + } + } + } + ); usernameInputField.getDocument().addDocumentListener(new DocumentListener() { diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 1ba0e9409..7905df482 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -41,6 +41,7 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr private final SelectedLocationsController selectedLocationsController; private final SelectedLocationsViewModel selectedLocationsViewModel; private final AddToCalendarViewModel calendarViewModel; + private final AddToCalendarController calendarController; private final JPanel suggestedLocationsPanel; private final JButton saveSelectionButton; @@ -57,6 +58,7 @@ public class SuggestedLocationsView extends JPanel implements ActionListener, Pr public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsViewModel, SuggestedLocationsController suggestedLocationsController, AddToCalendarViewModel calendarViewModel, + AddToCalendarController calendarController, SelectedLocationsViewModel selectedLocationsViewModel, SelectedLocationsController selectedLocationsController) { @@ -65,8 +67,8 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.suggestedLocationsController = suggestedLocationsController; this.selectedLocationsController = selectedLocationsController; this.selectedLocationsViewModel = selectedLocationsViewModel; - // property change listener? this.calendarViewModel = calendarViewModel; + this.calendarController = calendarController; this.selectedLocations = new ArrayList<>(); this.calendarLocations = new HashMap<>(); @@ -151,8 +153,7 @@ private void updateSuggestedLocations(SuggestedLocationsState state) { final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); selectedLocationsState.setSelectedLocations(selectedLocations); selectedLocationsViewModel.setState(selectedLocationsState); - } - else { + final AddToCalendarState currentState = calendarViewModel.getState(); currentState.setCalendarItems(calendarLocations); calendarViewModel.setState(currentState); @@ -171,32 +172,26 @@ public void actionPerformed(ActionEvent evt) { final SelectedLocationsState selectedLocationsState = selectedLocationsViewModel.getState(); try { selectedLocationsController.execute(selectedLocationsState.getSelectedLocations()); + } + catch (DataAccessException e) { + throw new RuntimeException(); + } + } if (evt.getSource().equals(newSearchButton)) { // final LocationState currentState = locationViewModel.getState(); // try { // locationController.execute(currentState.getAddress(), currentState.getLocationType()); -// } -// catch (DataAccessException e) { -// throw new RuntimeException(); -// } } if (evt.getSource().equals(saveToCalendarButton)) { final AddToCalendarState currentState = calendarViewModel.getState(); try { - suggestedLocationsController.execute(currentState.getCalendarItems()); + calendarController.execute(currentState.getCalendarItems()); } catch (DataAccessException e) { throw new RuntimeException(e); } - -// final AddToCalendarState currentState = calendarViewModel.getState(); -// try { -// calendarController.execute(currentState.getCalendarItems()); -// } -// catch (DataAccessException e) { -// throw new RuntimeException(e); -// } } + } public String getViewName() { diff --git a/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java index 88ed09b70..87afabc3c 100644 --- a/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java +++ b/src/test/java/use_case/add_to_calendar/AddToCalendarInteractorTest.java @@ -39,6 +39,11 @@ public void prepareSuccessView(AddToCalendarOutputData outputData) { public void prepareFailView(String errorMessage) { fail("Use case failure is unexpected."); } + + @Override + public void switchToLocationView() { + System.out.println("Switch view success"); + } }; AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); @@ -75,6 +80,11 @@ public void prepareSuccessView(AddToCalendarOutputData outputData) { public void prepareFailView(String errorMessage) { assertEquals("12:30 is already full.", errorMessage); } + + @Override + public void switchToLocationView() { + System.out.println("Switch view success"); + } }; AddToCalendarInputBoundary interactor = new AddToCalendarInteractor(calendarRepository, successPresenter); From a8399f759df4e70240bc6c45353a1291d3c2fe7c Mon Sep 17 00:00:00 2001 From: shirleyyzhang <163909578+shirleyyzhang@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:57:40 -0500 Subject: [PATCH 111/113] implemented more buttons and functionalities. --- src/main/java/app/MainWithDB.java | 2 +- .../app/SelectedLocationsUseCaseFactory.java | 33 ++++++++++--------- .../app/SuggestedLocationsUseCaseFactory.java | 9 ++--- .../AddToCalendarController.java | 3 ++ .../SelectedLocationsController.java | 7 ++++ .../SelectedLocationsPresenter.java | 13 ++++++-- .../SelectedLocationsInputBoundary.java | 4 +++ .../SelectedLocationsInteractor.java | 5 +++ .../SelectedLocationsOutputBoundary.java | 5 +++ src/main/java/view/SelectedLocationView.java | 20 +++++++---- .../java/view/SuggestedLocationsView.java | 1 + 11 files changed, 72 insertions(+), 30 deletions(-) diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java index 6ba6720fb..d6d5ff536 100644 --- a/src/main/java/app/MainWithDB.java +++ b/src/main/java/app/MainWithDB.java @@ -90,7 +90,7 @@ public static void main(String[] args) { views.add(suggestedLocationsView, suggestedLocationsView.getViewName()); final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel, - selectedLocationsViewModel, coordinatesDataAccessObject); + selectedLocationsViewModel, coordinatesDataAccessObject, locationViewModel); views.add(selectedLocationView, selectedLocationView.getViewName()); final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel, diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java index 32ba8b16a..de2b0d3b4 100644 --- a/src/main/java/app/SelectedLocationsUseCaseFactory.java +++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java @@ -2,6 +2,7 @@ import data_access.DBCoordinatesDataAccessObject; import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; import interface_adapter.selectedlocation.SelectedLocationsController; import interface_adapter.selectedlocation.SelectedLocationsPresenter; import interface_adapter.selectedlocation.SelectedLocationsViewModel; @@ -24,34 +25,34 @@ private SelectedLocationsUseCaseFactory() { /** * Factory function for creating the LocationView. * @param viewManagerModel the ViewManagerModel to inject - * - * @param selectedLocationsViewModel the SelectedLocationsViewModel to - * inject + * @param selectedLocationsViewModel the SelectedLocationsViewModel to inject + * @param locationViewModel the LocationViewModel to inject + * @param coordinatesDataAccessObject the DBCoordinatesDataAccessObject to inject. * @return the LocationView created for the provided input classes. */ public static SelectedLocationView create( ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel, - DBCoordinatesDataAccessObject coordinatesDataAccessObject) { + DBCoordinatesDataAccessObject coordinatesDataAccessObject, + LocationViewModel locationViewModel) { final SelectedLocationsController selectedLocationsController = - createSelectedLocationUseCase(viewManagerModel, - selectedLocationsViewModel, coordinatesDataAccessObject); + createSelectedLocationUseCase(viewManagerModel, selectedLocationsViewModel, + coordinatesDataAccessObject, locationViewModel); return new SelectedLocationView(selectedLocationsViewModel, selectedLocationsController); -} + } private static SelectedLocationsController createSelectedLocationUseCase( ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel, - DBCoordinatesDataAccessObject coordinatesDataAccessObject) { -// final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( -// viewManagerModel, selectedLocationsViewModel); -// final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( -// selectedLocationsOutputBoundary); - -// return new SelectedLocationsController(selectedLocationsInteractor); - return null; - // TODO: Implement this method + DBCoordinatesDataAccessObject coordinatesDataAccessObject, + LocationViewModel locationViewModel) { + final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( + selectedLocationsViewModel, viewManagerModel, locationViewModel); + final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( + selectedLocationsOutputBoundary, coordinatesDataAccessObject); + + return new SelectedLocationsController(selectedLocationsInteractor); } } diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 92e6d66d9..4006503a0 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -55,7 +55,7 @@ public static SuggestedLocationsView create( LocationViewModel locationViewModel) { final SelectedLocationsController selectedLocationController = createSelectedLocationUseCase(viewManagerModel, - selectedLocationsViewModel, coordinateDataAccessObject); + selectedLocationsViewModel, coordinateDataAccessObject, locationViewModel); final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase( viewManagerModel, @@ -79,7 +79,7 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( viewManagerModel, suggestedLocationsViewModel, calendarViewModel, selectedLocationsViewModel); - final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( + final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( suggestedLocationsOutputBoundary); return new SuggestedLocationsController(suggestedLocationsInteractor); @@ -88,9 +88,10 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( private static SelectedLocationsController createSelectedLocationUseCase( ViewManagerModel viewManagerModel, SelectedLocationsViewModel selectedLocationsViewModel, - CoordinateDataAccessInterface coordinatesDataAccessObject) { + CoordinateDataAccessInterface coordinatesDataAccessObject, + LocationViewModel locationViewModel) { final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter( - selectedLocationsViewModel, viewManagerModel); + selectedLocationsViewModel, viewManagerModel, locationViewModel); final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor( selectedLocationsOutputBoundary, coordinatesDataAccessObject); diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java index 7d8ed2f2d..9841903b3 100644 --- a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java +++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java @@ -30,6 +30,9 @@ public void execute(Map addToCalendarData) throws DataAccessExcep addToCalendarInteractor.execute(calendarInputData); } + /** + * Executes the switch to location view. + */ public void switchToLocationView() { addToCalendarInteractor.switchToLocationView(); } diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java index 4f04181dd..918ca9dc7 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java @@ -22,4 +22,11 @@ public void execute(List selectedLocations) throws DataAccessException { selectedLocationsInteractor.execute(selectedLocationsInputData); } + /** + * Switches to the location view. + */ + public void switchToLocationView() { + selectedLocationsInteractor.switchToLocationView(); + } + } diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java index 9e7b6c0bd..f7f7cf8af 100644 --- a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java +++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java @@ -1,7 +1,7 @@ package interface_adapter.selectedlocation; - import interface_adapter.ViewManagerModel; +import interface_adapter.location.LocationViewModel; import interface_adapter.suggestlocation.SuggestedLocationsState; import use_case.selected_locations.SelectedLocationsOutputBoundary; import use_case.selected_locations.SelectedLocationsOutputData; @@ -9,11 +9,14 @@ public class SelectedLocationsPresenter implements SelectedLocationsOutputBoundary { private final SelectedLocationsViewModel selectedLocationsViewModel; private final ViewManagerModel viewManagerModel; + private final LocationViewModel locationViewModel; public SelectedLocationsPresenter(SelectedLocationsViewModel selectedLocationsViewModel, - ViewManagerModel viewManagerModel) { + ViewManagerModel viewManagerModel, + LocationViewModel locationViewModel) { this.selectedLocationsViewModel = selectedLocationsViewModel; this.viewManagerModel = viewManagerModel; + this.locationViewModel = locationViewModel; } @Override @@ -31,4 +34,10 @@ public void prepareSuccessView(SelectedLocationsOutputData outputData) { public void prepareFailView(String errorMessage) { } + + @Override + public void switchToLocationView() { + viewManagerModel.setState(locationViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java b/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java index e22bda0cc..c07647b15 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInputBoundary.java @@ -14,4 +14,8 @@ public interface SelectedLocationsInputBoundary { */ void execute(SelectedLocationsInputData selectedLocationsInputData) throws DataAccessException; + /** + * Switches to the location view. + */ + public void switchToLocationView(); } diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java index 1f9c4271c..baa065152 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsInteractor.java @@ -36,4 +36,9 @@ public void execute(SelectedLocationsInputData selectedLocationsInputData) throw new SelectedLocationsOutputData(locationCoordinatesMap); selectedLocationsPresenter.prepareSuccessView(selectedLocationsOutputData); } + + @Override + public void switchToLocationView() { + selectedLocationsPresenter.switchToLocationView(); + } } diff --git a/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java b/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java index 6d074f364..715e0a774 100644 --- a/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java +++ b/src/main/java/use_case/selected_locations/SelectedLocationsOutputBoundary.java @@ -16,4 +16,9 @@ public interface SelectedLocationsOutputBoundary { * @param errorMessage The explanation of the failure */ void prepareFailView(String errorMessage); + + /** + * Switches to the location view. + */ + void switchToLocationView(); } diff --git a/src/main/java/view/SelectedLocationView.java b/src/main/java/view/SelectedLocationView.java index 9ffe6ae46..aba6177d7 100644 --- a/src/main/java/view/SelectedLocationView.java +++ b/src/main/java/view/SelectedLocationView.java @@ -27,6 +27,7 @@ public class SelectedLocationView extends JPanel implements ActionListener, Prop private final SelectedLocationsViewModel selectedLocationsViewModel; private final SelectedLocationsController selectedLocationsController; + private final JButton newSearchButton; private final JPanel selectedLocationPanel; public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewModel, @@ -45,9 +46,21 @@ public SelectedLocationView(SelectedLocationsViewModel selectedLocationsViewMode this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(selectedLocationPanel); + this.newSearchButton = new JButton("New Search"); + newSearchButton.addActionListener(this); + newSearchButton.setAlignmentX(Component.CENTER_ALIGNMENT); + this.add(newSearchButton); + updateSelectedLocations(selectedLocationsViewModel.getState()); } + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource().equals(newSearchButton)) { + selectedLocationsController.switchToLocationView(); + } + } + @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equals(evt.getPropertyName())) { @@ -103,13 +116,6 @@ private void updateSelectedLocations(SelectedLocationsState state) { } } - /** - * This method is not used in this class. - */ - @Override - public void actionPerformed(ActionEvent e) { - } - public String getViewName() { return viewName; } diff --git a/src/main/java/view/SuggestedLocationsView.java b/src/main/java/view/SuggestedLocationsView.java index 7905df482..949436eea 100644 --- a/src/main/java/view/SuggestedLocationsView.java +++ b/src/main/java/view/SuggestedLocationsView.java @@ -89,6 +89,7 @@ public SuggestedLocationsView(SuggestedLocationsViewModel suggestedLocationsView this.saveToCalendarButton = new JButton("Save to Calendar"); saveToCalendarButton.addActionListener(this); + saveToCalendarButton.setAlignmentX(Component.CENTER_ALIGNMENT); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.add(title); From 5e563e8a4b0b5f939956117c11d5e94f22e630b7 Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Mon, 2 Dec 2024 03:59:15 -0500 Subject: [PATCH 112/113] fixed some checkstyle errors --- .../app/SuggestedLocationsUseCaseFactory.java | 25 ++++++++----------- .../DBCoordinatesDataAccessObject.java | 14 +++++++---- .../DBLocationDataAccessObject.java | 24 ++++++++++++------ .../InMemoryUserDataAccessObject.java | 7 +++--- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java index 43e1ccaf7..2d2b85c30 100644 --- a/src/main/java/app/SuggestedLocationsUseCaseFactory.java +++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java @@ -1,30 +1,26 @@ package app; - import data_access.DBCoordinatesDataAccessObject; import interface_adapter.ViewManagerModel; -import interface_adapter.selectedlocation.SelectedLocationsPresenter; -import interface_adapter.selectedlocation.SelectedLocationsViewModel;/ -import interface_adapter.add_to_calendar.AddToCalendarController; import interface_adapter.add_to_calendar.AddToCalendarViewModel; -import interface_adapter.location.LocationController; -import interface_adapter.location.LocationViewModel; +import interface_adapter.selectedlocation.SelectedLocationsController; +import interface_adapter.selectedlocation.SelectedLocationsPresenter; +import interface_adapter.selectedlocation.SelectedLocationsViewModel; import interface_adapter.suggestlocation.SuggestedLocationsController; import interface_adapter.suggestlocation.SuggestedLocationsPresenter; import interface_adapter.suggestlocation.SuggestedLocationsViewModel; import use_case.selected_locations.SelectedLocationsInputBoundary; import use_case.selected_locations.SelectedLocationsInteractor; import use_case.selected_locations.SelectedLocationsOutputBoundary; -import use_case.suggested_locations.SuggestedLocationsInteractor; import use_case.suggested_locations.SuggestedLocationsInputBoundary; -import interface_adapter.selectedlocation.SelectedLocationsController; +import use_case.suggested_locations.SuggestedLocationsInteractor; import use_case.suggested_locations.SuggestedLocationsOutputBoundary; import view.SuggestedLocationsView; /** * This class contains the static factory function for creating the SuggestedLocationView. */ -public class SuggestedLocationsUseCaseFactory { +public final class SuggestedLocationsUseCaseFactory { /** Prevent instantiation. */ private SuggestedLocationsUseCaseFactory() { @@ -42,7 +38,7 @@ private SuggestedLocationsUseCaseFactory() { public static SuggestedLocationsView create( ViewManagerModel viewManagerModel, SuggestedLocationsViewModel suggestedLocationsViewModel, - AddToCalendarViewModel calendarViewModel + AddToCalendarViewModel calendarViewModel, SelectedLocationsViewModel selectedLocationsViewModel) { final SelectedLocationsController selectedLocationController = createSelectedLocationUseCase(viewManagerModel, @@ -51,9 +47,10 @@ public static SuggestedLocationsView create( final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase( viewManagerModel, suggestedLocationsViewModel, - calendarViewModel); + calendarViewModel, selectedLocationsViewModel); - return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel, selectedLocationsViewModel, selectedLocationController); + return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, + calendarViewModel, selectedLocationsViewModel, selectedLocationController); } private static SuggestedLocationsController createSuggestedLocationUseCase( @@ -65,7 +62,7 @@ private static SuggestedLocationsController createSuggestedLocationUseCase( final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter( viewManagerModel, suggestedLocationsViewModel, calendarViewModel, selectedLocationsViewModel); - final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( + final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor( suggestedLocationsOutputBoundary); return new SuggestedLocationsController(suggestedLocationsInteractor); @@ -83,5 +80,3 @@ private static SelectedLocationsController createSelectedLocationUseCase( return new SelectedLocationsController(selectedLocationsInteractor); } } - - diff --git a/src/main/java/data_access/DBCoordinatesDataAccessObject.java b/src/main/java/data_access/DBCoordinatesDataAccessObject.java index 2b6f11c0b..0117f943b 100644 --- a/src/main/java/data_access/DBCoordinatesDataAccessObject.java +++ b/src/main/java/data_access/DBCoordinatesDataAccessObject.java @@ -2,12 +2,15 @@ import java.io.IOException; -import entity.Place; -import okhttp3.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import entity.Place; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import use_case.DataAccessException; import use_case.locations.CoordinateDataAccessInterface; @@ -16,13 +19,13 @@ */ public class DBCoordinatesDataAccessObject implements CoordinateDataAccessInterface { private static final String API_KEY = System.getenv("API_KEY"); - private static final String CONTENT_TYPE_JSON = "application/json"; @Override public String searchCoordinates(Place place) throws DataAccessException { final OkHttpClient client = new OkHttpClient().newBuilder() .build(); - HttpUrl url = HttpUrl.parse("https://maps.googleapis.com/maps/api/geocode/json").newBuilder() + final HttpUrl url = HttpUrl.parse("https://maps.googleapis" + + ".com/maps/api/geocode/json").newBuilder() .addQueryParameter("key", API_KEY) .addQueryParameter("address", place.getAddress()) .build(); @@ -47,7 +50,8 @@ public String searchCoordinates(Place place) throws DataAccessException { return coordinates.toString(); } else if (responseBody.has("error_message")) { - throw new DataAccessException("API Error: " + responseBody.getJSONObject("error_message").getString("message")); + throw new DataAccessException("API Error: " + responseBody.getJSONObject("error_message") + .getString("message")); } else { throw new DataAccessException("Unexpected API response format."); diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java index 1c707f428..c1ec0328d 100644 --- a/src/main/java/data_access/DBLocationDataAccessObject.java +++ b/src/main/java/data_access/DBLocationDataAccessObject.java @@ -4,13 +4,17 @@ import java.util.ArrayList; import java.util.List; -import entity.Place; -import entity.PlaceFactory; -import okhttp3.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import entity.Place; +import entity.PlaceFactory; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import use_case.DataAccessException; import use_case.locations.LocationDataAccessInterface; @@ -24,6 +28,9 @@ public class DBLocationDataAccessObject implements LocationDataAccessInterface { private static final String CONTENT_TYPE_LABEL = "Content-Type"; private static final String CONTENT_TYPE_JSON = "application/json"; private static final String API_KEY = System.getenv("API_KEY"); + private static final String API_URL = "https://places.googleapis.com/v1/places:searchText"; + private static final String LEFT_ARROW = "<"; + private static final String RIGHT_ARROW = ">"; private final PlaceFactory placeFactory; public DBLocationDataAccessObject(PlaceFactory placeFactory) { @@ -41,7 +48,7 @@ public List searchLocation(String address, String locationType) throws Da requestBody.toString(), MediaType.parse(CONTENT_TYPE_JSON)); // POST METHOD final Request request = new Request.Builder() - .url("https://places.googleapis.com/v1/places:searchText") + .url(API_URL) .post(body) .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) .addHeader(API_HEADER, API_KEY) @@ -57,15 +64,16 @@ public List searchLocation(String address, String locationType) throws Da for (int i = 0; i < jsonArray.length(); i++) { final JSONObject jsonObject = jsonArray.getJSONObject(i); - places.append(jsonObject.getString("formattedAddress")).append(">").append(jsonObject - .getJSONObject("displayName").getString("text")).append("<"); + places.append(jsonObject.getString("formattedAddress")).append(RIGHT_ARROW).append(jsonObject + .getJSONObject("displayName").getString("text")).append(LEFT_ARROW); } final String placesString = places.toString(); - final String[] locationsList = placesString.split("<"); + final String[] locationsList = placesString.split(LEFT_ARROW); final List suggestedPlaces = new ArrayList<>(); for (String location : locationsList) { - final Place place = placeFactory.create(location.split(">")[1], location.split(">")[0]); + final Place place = placeFactory.create(location.split(RIGHT_ARROW)[1], + location.split(RIGHT_ARROW)[0]); suggestedPlaces.add(place); } return suggestedPlaces; diff --git a/src/main/java/data_access/InMemoryUserDataAccessObject.java b/src/main/java/data_access/InMemoryUserDataAccessObject.java index d817b91a9..1faa11526 100644 --- a/src/main/java/data_access/InMemoryUserDataAccessObject.java +++ b/src/main/java/data_access/InMemoryUserDataAccessObject.java @@ -17,6 +17,7 @@ public class InMemoryUserDataAccessObject implements SignupUserDataAccessInterface, LoginUserDataAccessInterface, UserProfileDataAccessInterface { + private static final String USER_NOT_FOUND = "User not found."; private final Map userDatabase = new HashMap<>(); @Override @@ -33,7 +34,7 @@ public User get(String username) { public User getUser(String username) throws DataAccessException { final User user = userDatabase.get(username); if (user == null) { - throw new DataAccessException("User not found."); + throw new DataAccessException(USER_NOT_FOUND); } return user; } @@ -50,7 +51,7 @@ public void savePlaces(String username, Map> places) throws user.getSavedPlaces().putAll(places); } else { - throw new DataAccessException("User not found."); + throw new DataAccessException(USER_NOT_FOUND); } } @@ -61,7 +62,7 @@ public Map> getSavedPlaces(String username) throws DataAcces return user.getSavedPlaces(); } else { - throw new DataAccessException("User not found."); + throw new DataAccessException(USER_NOT_FOUND); } } From 506be545ed8ca1afaa18411314d7117feb3ca24f Mon Sep 17 00:00:00 2001 From: Sean Woo Date: Tue, 3 Dec 2024 20:34:22 -0500 Subject: [PATCH 113/113] added strategy --- .../java/entity/DislikedLocationFilter.java | 16 ++++++++++++++++ src/main/java/entity/LocationFilterContext.java | 17 +++++++++++++++++ .../java/entity/LocationFilterStrategy.java | 8 ++++++++ src/main/java/entity/SavedLocationFilter.java | 16 ++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/main/java/entity/DislikedLocationFilter.java create mode 100644 src/main/java/entity/LocationFilterContext.java create mode 100644 src/main/java/entity/LocationFilterStrategy.java create mode 100644 src/main/java/entity/SavedLocationFilter.java diff --git a/src/main/java/entity/DislikedLocationFilter.java b/src/main/java/entity/DislikedLocationFilter.java new file mode 100644 index 000000000..62c1ea342 --- /dev/null +++ b/src/main/java/entity/DislikedLocationFilter.java @@ -0,0 +1,16 @@ +package entity; + +import java.util.Set; + +public class DislikedLocationFilter implements LocationFilterStrategy { + private Set dislikedLocations; + + public DislikedLocationFilter(Set dislikedLocations) { + this.dislikedLocations = dislikedLocations; + } + + @Override + public boolean filter(String location) { + return !dislikedLocations.contains(location); + } +} diff --git a/src/main/java/entity/LocationFilterContext.java b/src/main/java/entity/LocationFilterContext.java new file mode 100644 index 000000000..cef58a9a9 --- /dev/null +++ b/src/main/java/entity/LocationFilterContext.java @@ -0,0 +1,17 @@ +package entity; + +public class LocationFilterContext { + private LocationFilterStrategy strategy; + + public LocationFilterContext(LocationFilterStrategy strategy) { + this.strategy = strategy; + } + + public void setStrategy(LocationFilterStrategy strategy) { + this.strategy = strategy; + } + + public boolean applyFilter(String location) { + return strategy.filter(location); + } +} diff --git a/src/main/java/entity/LocationFilterStrategy.java b/src/main/java/entity/LocationFilterStrategy.java new file mode 100644 index 000000000..d0b27e733 --- /dev/null +++ b/src/main/java/entity/LocationFilterStrategy.java @@ -0,0 +1,8 @@ +package entity; + +/** + * The representation of a filter in our program. + */ +public interface LocationFilterStrategy { + boolean filter(String location); +} diff --git a/src/main/java/entity/SavedLocationFilter.java b/src/main/java/entity/SavedLocationFilter.java new file mode 100644 index 000000000..02948ec99 --- /dev/null +++ b/src/main/java/entity/SavedLocationFilter.java @@ -0,0 +1,16 @@ +package entity; + +import java.util.Set; + +public class SavedLocationFilter implements LocationFilterStrategy { + private Set savedLocations; + + public SavedLocationFilter(Set savedLocations) { + this.savedLocations = savedLocations; + } + + @Override + public boolean filter(String location) { + return savedLocations.contains(location); + } +}