From 180612031ff4b5ccb1858c15e20e2442259cfa98 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Mon, 4 Nov 2024 18:41:38 -0500 Subject: [PATCH 01/62] set up 1 --- .gitignore | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 650c91720..e35e9fda2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,21 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + ### IntelliJ IDEA ### -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ -.idea/easycode.ignore +token.txt +.idea/modules.xml +.idea/compiler.xml +.idea/encodings.xml +.idea/misc.xml +.idea/workspace.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + -target/ ### Eclipse ### .apt_generated From 987d83e9cc3c6dea5085e1b93a82356543aef8ba Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Mon, 4 Nov 2024 21:32:04 -0500 Subject: [PATCH 02/62] Entities completed --- src/main/java/entity/Joke.java | 27 +++++++++++++++++++++++++++ src/main/java/entity/User.java | 14 +++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/java/entity/Joke.java diff --git a/src/main/java/entity/Joke.java b/src/main/java/entity/Joke.java new file mode 100644 index 000000000..4d63ad1ea --- /dev/null +++ b/src/main/java/entity/Joke.java @@ -0,0 +1,27 @@ +package entity; + +// there should be a joke factory, a user factory +public class Joke { + + private final String content; + private String explanation; + private final int score; + + public Joke(String content, int score) { + this.content = content; + this.explanation = "explanation"; + this.score = score; + } + + public String getContent() { + return content; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } +} diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index e0c57e9a6..746754ea2 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,10 +9,12 @@ public class User { private final String name; private final String password; + private List favorites; - public User(String name, String password) { + public User(String name, String password, List favorites) { this.name = name; this.password = password; + this.favorites = favorites; } public String getName() { @@ -21,4 +25,12 @@ public String getPassword() { return password; } + public List getFavorites() { + return favorites; + } + + public void addToFavorites(Joke joke) { + this.favorites.add(joke); + } + } From a2cc47e96f97462406df47c62a206373f6c5fa2d Mon Sep 17 00:00:00 2001 From: GUO YU HE <162621600+GuoYuHeJason@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:24:24 -0500 Subject: [PATCH 03/62] Update .gitignore --- .gitignore | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index e35e9fda2..26559eb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,10 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - ### IntelliJ IDEA ### -token.txt -.idea/modules.xml -.idea/compiler.xml -.idea/encodings.xml -.idea/misc.xml -.idea/workspace.xml -.idea/libraries/ -*.iws -*.iml -*.ipr - +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +.idea/easycode.ignore +target/ ### Eclipse ### .apt_generated @@ -40,4 +29,4 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store From c5aba0d7e7dca352e6289e3b0a2fca1062eb0b4d Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Tue, 5 Nov 2024 11:33:03 -0500 Subject: [PATCH 04/62] set up 2 --- .gitignore | 5 +++++ .idea/vcs.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 26559eb1d..f2bd707a3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,11 @@ out/ .idea/easycode.ignore target/ +token.txt +.idea/compiler.xml +.idea/encodings.xml +.idea/misc.xml +.idea/workspace.xml ### Eclipse ### .apt_generated 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 From 18de28fbd0a22fa57de433431d0bcdbd242661c0 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Tue, 5 Nov 2024 13:13:14 -0500 Subject: [PATCH 05/62] set up 3 and Demo --- .../ExplanationDataAccessObject.java | 79 +++++++++++++++++++ .../data_access/JokeDataAccessObject.java | 63 +++++++++++++++ .../MockExplanationDataAccessObject.java | 11 +++ src/main/java/entity/User.java | 5 ++ .../interface_adapter/note/NoteViewModel.java | 2 +- .../ExplanationDataAccessInterface.java | 5 ++ .../generate/GenerateDataAccessInterface.java | 5 ++ .../generate/GenerateInputBoundary.java | 9 +++ .../use_case/generate/GenerateInteractor.java | 31 ++++++++ .../generate/GenerateOuputBoundary.java | 15 ++++ .../generate/adapter/DemoBuilder.java | 10 +++ .../adapter/DemoGeneratePresenter.java | 49 ++++++++++++ .../generate/adapter/GenerateController.java | 22 ++++++ .../ViewModel.java | 2 +- src/test/java/use_case/generate/DemoTest.java | 10 +++ 15 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 src/main/java/data_access/ExplanationDataAccessObject.java create mode 100644 src/main/java/data_access/JokeDataAccessObject.java create mode 100644 src/main/java/data_access/MockExplanationDataAccessObject.java create mode 100644 src/main/java/use_case/explain/ExplanationDataAccessInterface.java create mode 100644 src/main/java/use_case/generate/GenerateDataAccessInterface.java create mode 100644 src/main/java/use_case/generate/GenerateInputBoundary.java create mode 100644 src/main/java/use_case/generate/GenerateInteractor.java create mode 100644 src/main/java/use_case/generate/GenerateOuputBoundary.java create mode 100644 src/main/java/use_case/generate/adapter/DemoBuilder.java create mode 100644 src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java create mode 100644 src/main/java/use_case/generate/adapter/GenerateController.java rename src/main/java/{interface_adapter => view}/ViewModel.java (98%) create mode 100644 src/test/java/use_case/generate/DemoTest.java diff --git a/src/main/java/data_access/ExplanationDataAccessObject.java b/src/main/java/data_access/ExplanationDataAccessObject.java new file mode 100644 index 000000000..72b934cde --- /dev/null +++ b/src/main/java/data_access/ExplanationDataAccessObject.java @@ -0,0 +1,79 @@ +package data_access; + +import okhttp3.*; +import org.json.JSONException; +import org.json.JSONObject; +import use_case.explain.ExplanationDataAccessInterface; + +import java.io.IOException; + +public class ExplanationDataAccessObject implements ExplanationDataAccessInterface { + + private static final String TOKEN = "token"; + private static final String GOOGLE_API_KEY = System.getenv(TOKEN); + private static final String API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=" + GOOGLE_API_KEY; + private static final String APPLICATION_JSON = "application/json"; + + // uses java sdk instead of https +// const genAI = new GoogleGenerativeAI(process.env.API_KEY); +//const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); +// +//const prompt = "Write a story about a magic backpack."; +// +//const result = await model.generateContent(prompt); +//console.log(result.response.text()); + + @Override + public String getExplanation(String joke) { + + String prompt = "explain this joke" + joke; + + // Build client + final OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + + // type of request body is json + final MediaType mediaType = MediaType.parse(APPLICATION_JSON); + //make request body + final JSONObject requestBody = new JSONObject() +// .put("generationConfig", new JSONObject().put("maxOutputTokens", 1)) + .put("contents", new JSONObject() + .put("parts", new JSONObject() + .put("text", prompt) + ) + ); + // RequestBody takes in type and content (string) + final RequestBody body = RequestBody.create(mediaType, requestBody.toString()); + + // add arguments to url, or add headers as needed + final Request request = new Request.Builder() + .url(String.format(API_URL)) + .post(body) + .build(); + + // Hint: look at the API documentation to understand what the response looks like. + try { + + // Client creates a Call with Request + // Call returns the Response from execute() + final Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONObject candidates = responseBody.getJSONArray("candidates").getJSONObject(0); + if (candidates.getString("finishReason").equals("STOP")) { + return candidates + .getJSONObject("content") + .getJSONArray("parts").getJSONObject(0) + .getString("text"); + } else { + return "this joke is too inappropriate for me!"; + } + } else { + throw new RuntimeException(response.message()); + } + } catch (IOException | JSONException event) { + throw new RuntimeException(event); + } + } +} \ No newline at end of file diff --git a/src/main/java/data_access/JokeDataAccessObject.java b/src/main/java/data_access/JokeDataAccessObject.java new file mode 100644 index 000000000..3d6600bec --- /dev/null +++ b/src/main/java/data_access/JokeDataAccessObject.java @@ -0,0 +1,63 @@ +package data_access; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.JSONException; +import org.json.JSONObject; +import use_case.generate.GenerateDataAccessInterface; + +import java.io.IOException; + + +public class JokeDataAccessObject implements GenerateDataAccessInterface { + + private static final String MESSAGE = "message"; + private static final String API_URL = "https://v2.jokeapi.dev/joke/Any"; + + @Override + public String getJokeContent() { + + // Build client + // Build the request to get joke. + // client sends request + final OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + // add arguments to url, or add headers as needed + final Request request = new Request.Builder() + .url(String.format(API_URL)) + .build(); + + // Hint: look at the API documentation to understand what the response looks like. + try { + // Client creates a Call with Request + // Call returns the Response from execute() + final Response response = client.newCall(request).execute(); + + // JSONObject is a dictionary that can be written to a JSON file + // a JSON file has multiple JSONObjects: + // file -> String -> JSONArray -> JSONObject + // String jsonString = Files.readString(Paths.get(getClass().getClassLoader().getResource(filename).toURI())) + // JSONArray jsonArray = new JSONArray(jsonString); + // JSONObject jsonObject = jsonArray.getJSONObject(i); + final JSONObject responseBody = new JSONObject(response.body().string()); + + // Response body (the JSONObject) varies for API. + if (responseBody.getBoolean("error")) { + throw new RuntimeException(responseBody.getString(MESSAGE)); + } else { + switch (responseBody.getString("type")) { + case "single": + return responseBody.getString("joke"); + case "twopart": + return responseBody.getString("setup") + responseBody.getString("delivery"); + default: + return "something funny"; + } + } + } + catch (IOException | JSONException event) { + throw new RuntimeException(event); + } + } +} diff --git a/src/main/java/data_access/MockExplanationDataAccessObject.java b/src/main/java/data_access/MockExplanationDataAccessObject.java new file mode 100644 index 000000000..f8675b18a --- /dev/null +++ b/src/main/java/data_access/MockExplanationDataAccessObject.java @@ -0,0 +1,11 @@ +package data_access; + +import use_case.explain.ExplanationDataAccessInterface; + +public class MockExplanationDataAccessObject implements ExplanationDataAccessInterface { + + @Override + public String getExplanation(String joke) { + return "haha, that's funny"; + } +} diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index 746754ea2..e5fb79e60 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -11,6 +11,11 @@ public class User { private final String password; private List favorites; + public User(String name, String password) { + this.name = name; + this.password = password; + } + public User(String name, String password, List favorites) { this.name = name; this.password = password; diff --git a/src/main/java/interface_adapter/note/NoteViewModel.java b/src/main/java/interface_adapter/note/NoteViewModel.java index 6e185d0fa..f085f6df8 100644 --- a/src/main/java/interface_adapter/note/NoteViewModel.java +++ b/src/main/java/interface_adapter/note/NoteViewModel.java @@ -1,6 +1,6 @@ package interface_adapter.note; -import interface_adapter.ViewModel; +import view.ViewModel; /** * The ViewModel for the NoteView. diff --git a/src/main/java/use_case/explain/ExplanationDataAccessInterface.java b/src/main/java/use_case/explain/ExplanationDataAccessInterface.java new file mode 100644 index 000000000..b0c9d853c --- /dev/null +++ b/src/main/java/use_case/explain/ExplanationDataAccessInterface.java @@ -0,0 +1,5 @@ +package use_case.explain; + +public interface ExplanationDataAccessInterface { + String getExplanation(String joke); +} diff --git a/src/main/java/use_case/generate/GenerateDataAccessInterface.java b/src/main/java/use_case/generate/GenerateDataAccessInterface.java new file mode 100644 index 000000000..9dc1412a6 --- /dev/null +++ b/src/main/java/use_case/generate/GenerateDataAccessInterface.java @@ -0,0 +1,5 @@ +package use_case.generate; + +public interface GenerateDataAccessInterface { + String getJokeContent() throws RuntimeException; +} diff --git a/src/main/java/use_case/generate/GenerateInputBoundary.java b/src/main/java/use_case/generate/GenerateInputBoundary.java new file mode 100644 index 000000000..be449bcc0 --- /dev/null +++ b/src/main/java/use_case/generate/GenerateInputBoundary.java @@ -0,0 +1,9 @@ +package use_case.generate; + +public interface GenerateInputBoundary { + + /** + * Executes the generate use case. + */ + void executeGenerate(); +} diff --git a/src/main/java/use_case/generate/GenerateInteractor.java b/src/main/java/use_case/generate/GenerateInteractor.java new file mode 100644 index 000000000..aa4a9e613 --- /dev/null +++ b/src/main/java/use_case/generate/GenerateInteractor.java @@ -0,0 +1,31 @@ +package use_case.generate; + +import use_case.note.DataAccessException; +import use_case.note.NoteDataAccessInterface; +import use_case.note.NoteOutputBoundary; + +/** + * The "Use Case Interactor" for generating joke + */ +public class GenerateInteractor implements GenerateInputBoundary{ + + private final GenerateDataAccessInterface generateDataAccessInterface; + private final GenerateOuputBoundary generateOuputBoundary; + + public GenerateInteractor(GenerateDataAccessInterface generateDataAccessInterface, + GenerateOuputBoundary generateOuputBoundary) { + this.generateDataAccessInterface = generateDataAccessInterface; + this.generateOuputBoundary = generateOuputBoundary; + } + + @Override + public void executeGenerate() { + try { + final String jokeContent = generateDataAccessInterface.getJokeContent(); + generateOuputBoundary.prepareSuccessView(jokeContent); + } + catch (RuntimeException ex) { + generateOuputBoundary.prepareFailView(ex.getMessage()); + } + } +} diff --git a/src/main/java/use_case/generate/GenerateOuputBoundary.java b/src/main/java/use_case/generate/GenerateOuputBoundary.java new file mode 100644 index 000000000..56e21cf19 --- /dev/null +++ b/src/main/java/use_case/generate/GenerateOuputBoundary.java @@ -0,0 +1,15 @@ +package use_case.generate; + +public interface GenerateOuputBoundary { + /** + * Prepares the success view for the Note related Use Cases. + * @param jokeContent the output data + */ + void prepareSuccessView(String jokeContent); + + /** + * Prepares the failure view. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/generate/adapter/DemoBuilder.java b/src/main/java/use_case/generate/adapter/DemoBuilder.java new file mode 100644 index 000000000..a61891367 --- /dev/null +++ b/src/main/java/use_case/generate/adapter/DemoBuilder.java @@ -0,0 +1,10 @@ +package use_case.generate.adapter; + +import data_access.JokeDataAccessObject; +import use_case.generate.GenerateInteractor; + +public class DemoBuilder { + public static void build() { + new GenerateController(new GenerateInteractor(new JokeDataAccessObject(), new DemoGeneratePresenter())).execute(); + } +} diff --git a/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java b/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java new file mode 100644 index 000000000..b0ed6e798 --- /dev/null +++ b/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java @@ -0,0 +1,49 @@ +package use_case.generate.adapter; + +import data_access.ExplanationDataAccessObject; +import data_access.MockExplanationDataAccessObject; +import use_case.explain.ExplanationDataAccessInterface; +import use_case.generate.GenerateOuputBoundary; + +import javax.swing.*; + +/** + * simple presenter for demo, need to change (view model and stuff) + */ +public class DemoGeneratePresenter implements GenerateOuputBoundary { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + @Override + public void prepareSuccessView(String jokeContent) { + ExplanationDataAccessInterface explainator = new MockExplanationDataAccessObject(); +// ExplanationDataAccessInterface explainator = new ExplanationDataAccessObject(); + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Joke"); + frame.setSize(WIDTH, HEIGHT); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(new JTextArea(jokeContent + explainator.getExplanation(jokeContent))); + + frame.add(panel); + frame.setVisible(true); + } + + @Override + public void prepareFailView(String errorMessage) { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Joke"); + frame.setSize(WIDTH, HEIGHT); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(new JTextArea(5, 20)); + + + frame.add(panel); + frame.setVisible(true); + } +} diff --git a/src/main/java/use_case/generate/adapter/GenerateController.java b/src/main/java/use_case/generate/adapter/GenerateController.java new file mode 100644 index 000000000..0064ca811 --- /dev/null +++ b/src/main/java/use_case/generate/adapter/GenerateController.java @@ -0,0 +1,22 @@ +package use_case.generate.adapter; + +import use_case.generate.GenerateInputBoundary; + +/** + * Controller for our generate Use Cases. + */ +public class GenerateController { + + private final GenerateInputBoundary generateInputBoundary; + + public GenerateController(GenerateInputBoundary generateInputBoundary) { + this.generateInputBoundary = generateInputBoundary; + } + + /** + * Executes the generate related Use Cases. + */ + public void execute() { + generateInputBoundary.executeGenerate(); + } +} diff --git a/src/main/java/interface_adapter/ViewModel.java b/src/main/java/view/ViewModel.java similarity index 98% rename from src/main/java/interface_adapter/ViewModel.java rename to src/main/java/view/ViewModel.java index 130d797a1..136b800f8 100644 --- a/src/main/java/interface_adapter/ViewModel.java +++ b/src/main/java/view/ViewModel.java @@ -1,4 +1,4 @@ -package interface_adapter; +package view; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; diff --git a/src/test/java/use_case/generate/DemoTest.java b/src/test/java/use_case/generate/DemoTest.java new file mode 100644 index 000000000..4442dcdf6 --- /dev/null +++ b/src/test/java/use_case/generate/DemoTest.java @@ -0,0 +1,10 @@ +package use_case.generate; + +import org.junit.Test; +import use_case.generate.adapter.DemoBuilder; + +public class DemoTest { + public static void main(String[] args) { + DemoBuilder.build(); + } +} From a10afd8a2192ba825cac41cae325354930401775 Mon Sep 17 00:00:00 2001 From: five Date: Sat, 9 Nov 2024 16:01:17 -0500 Subject: [PATCH 06/62] Complete use case interface, basic view --- .../search/SearchController.java | 4 + .../search/SearchPresenter.java | 4 + .../interface_adapter/search/SearchState.java | 4 + .../search/SearchViewModel.java | 4 + .../search/SearchDataAccessInterface.java | 10 +++ .../use_case/search/SearchInputBoundary.java | 9 ++ .../use_case/search/SearchInteractor.java | 24 +++++ .../use_case/search/SearchOutputBoundary.java | 16 ++++ src/main/java/view/SearchView.java | 90 +++++++++++++++++++ 9 files changed, 165 insertions(+) create mode 100644 src/main/java/interface_adapter/search/SearchController.java create mode 100644 src/main/java/interface_adapter/search/SearchPresenter.java create mode 100644 src/main/java/interface_adapter/search/SearchState.java create mode 100644 src/main/java/interface_adapter/search/SearchViewModel.java create mode 100644 src/main/java/use_case/search/SearchDataAccessInterface.java create mode 100644 src/main/java/use_case/search/SearchInputBoundary.java create mode 100644 src/main/java/use_case/search/SearchInteractor.java create mode 100644 src/main/java/use_case/search/SearchOutputBoundary.java create mode 100644 src/main/java/view/SearchView.java diff --git a/src/main/java/interface_adapter/search/SearchController.java b/src/main/java/interface_adapter/search/SearchController.java new file mode 100644 index 000000000..1e3712665 --- /dev/null +++ b/src/main/java/interface_adapter/search/SearchController.java @@ -0,0 +1,4 @@ +package interface_adapter.search; + +public class SearchController { +} diff --git a/src/main/java/interface_adapter/search/SearchPresenter.java b/src/main/java/interface_adapter/search/SearchPresenter.java new file mode 100644 index 000000000..eebd90b28 --- /dev/null +++ b/src/main/java/interface_adapter/search/SearchPresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.search; + +public class SearchPresenter { +} diff --git a/src/main/java/interface_adapter/search/SearchState.java b/src/main/java/interface_adapter/search/SearchState.java new file mode 100644 index 000000000..70a54441b --- /dev/null +++ b/src/main/java/interface_adapter/search/SearchState.java @@ -0,0 +1,4 @@ +package interface_adapter.search; + +public class SearchState { +} diff --git a/src/main/java/interface_adapter/search/SearchViewModel.java b/src/main/java/interface_adapter/search/SearchViewModel.java new file mode 100644 index 000000000..1a716b6cd --- /dev/null +++ b/src/main/java/interface_adapter/search/SearchViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.search; + +public class SearchViewModel { +} diff --git a/src/main/java/use_case/search/SearchDataAccessInterface.java b/src/main/java/use_case/search/SearchDataAccessInterface.java new file mode 100644 index 000000000..5372efdb6 --- /dev/null +++ b/src/main/java/use_case/search/SearchDataAccessInterface.java @@ -0,0 +1,10 @@ +package use_case.search; + +public interface SearchDataAccessInterface { + /** + * Search jokes with the keyword and show them. + * @param keyword the keyword that want to be searched. + * @return return a String of joke that we want + */ + String searchJoke(String keyword); +} diff --git a/src/main/java/use_case/search/SearchInputBoundary.java b/src/main/java/use_case/search/SearchInputBoundary.java new file mode 100644 index 000000000..4ff527a45 --- /dev/null +++ b/src/main/java/use_case/search/SearchInputBoundary.java @@ -0,0 +1,9 @@ +package use_case.search; + +public interface SearchInputBoundary { + /** + * Search jokes by keyword. + * @param keyword the keyword that wants to be searched. + */ + void executeSearch(String keyword); +} diff --git a/src/main/java/use_case/search/SearchInteractor.java b/src/main/java/use_case/search/SearchInteractor.java new file mode 100644 index 000000000..51680cfac --- /dev/null +++ b/src/main/java/use_case/search/SearchInteractor.java @@ -0,0 +1,24 @@ +package use_case.search; + +public class SearchInteractor implements SearchInputBoundary { + private final SearchDataAccessInterface searchDataAccessObject; + private final SearchOutputBoundary searchPresenter; + + public SearchInteractor(SearchDataAccessInterface searchDataAccessObject, + SearchOutputBoundary searchPresenter) { + this.searchDataAccessObject = searchDataAccessObject; + this.searchPresenter = searchPresenter; + } + + @Override + public void executeSearch(String keyword) { + try { + final String jokeContent = searchDataAccessObject.searchJoke(keyword); + searchPresenter.prepareSuccessView(jokeContent); + } + catch (RuntimeException ex) { + final String message = "failed to find a joke"; + searchPresenter.prepareFailureView(message); + } + } +} diff --git a/src/main/java/use_case/search/SearchOutputBoundary.java b/src/main/java/use_case/search/SearchOutputBoundary.java new file mode 100644 index 000000000..9decc12cc --- /dev/null +++ b/src/main/java/use_case/search/SearchOutputBoundary.java @@ -0,0 +1,16 @@ +package use_case.search; + +public interface SearchOutputBoundary { + /** + * Prepares the success view. + * @param joke the joke we want to present. + */ + void prepareSuccessView(String joke); + + /** + * Prepares the failure view. + * @param errormessage a message when fails. + */ + void prepareFailureView(String errormessage); + // How to determine what is failure or success, depends on the format of API return_value +} diff --git a/src/main/java/view/SearchView.java b/src/main/java/view/SearchView.java new file mode 100644 index 000000000..d02fa2be7 --- /dev/null +++ b/src/main/java/view/SearchView.java @@ -0,0 +1,90 @@ +package view; + +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.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; + +import interface_adapter.search.SearchController; +import interface_adapter.search.SearchState; +import interface_adapter.search.SearchViewModel; + +public class SearchView extends JPanel implements ActionListener, PropertyChangeListener { + + private final SearchViewModel searchViewModel; + + private final JLabel search = new JLabel("Enter keyword to find a joke:"); + private final JTextArea keywordInputField = new JTextArea(); + + private final JButton searchButton = new JButton("Search"); + private SearchController searchController; + + public SearchView(SearchViewModel searchViewModel) { + + search.setAlignmentX(Component.LEFT_ALIGNMENT); + this.searchViewModel = noteViewModel; + this.searchViewModel.addPropertyChangeListener(this); + + final JPanel buttons = new JPanel(); + buttons.add(searchButton); + + searchButton.addActionListener( + evt -> { + if (evt.getSource().equals(saveButton)) { + noteController.execute(noteInputField.getText()); + + } + } + ); + + refreshButton.addActionListener( + evt -> { + if (evt.getSource().equals(refreshButton)) { + noteController.execute(null); + + } + } + ); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + this.add(noteName); + this.add(noteInputField); + 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 NoteState state = (NoteState) evt.getNewValue(); + setFields(state); + if (state.getError() != null) { + JOptionPane.showMessageDialog(this, state.getError(), + "Error", JOptionPane.ERROR_MESSAGE); + } + } + + private void setFields(NoteState state) { + noteInputField.setText(state.getNote()); + } + + public void setNoteController(NoteController controller) { + this.noteController = controller; + } +} + From 291838c825e797241208818787c25ae214a82fdd Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 10 Nov 2024 16:08:04 -0500 Subject: [PATCH 07/62] joke view --- src/main/java/view/NoteView.java | 115 +++++++++++++++++-------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index 331d76493..d0588a42b 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -5,91 +5,100 @@ 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.JTextArea; -import interface_adapter.note.NoteController; -import interface_adapter.note.NoteState; -import interface_adapter.note.NoteViewModel; +import interface_adapter.joke.JokeController; +import interface_adapter.joke.JokeState; +import interface_adapter.joke.JokeViewModel; /** - * The View for when the user is viewing a note in the program. + * The View for displaying jokes and interacting with the Joke Application. */ -public class NoteView extends JPanel implements ActionListener, PropertyChangeListener { - - 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 NoteController noteController; - - public NoteView(NoteViewModel noteViewModel) { +public class JokeAppView extends JPanel implements ActionListener, PropertyChangeListener { - noteName.setAlignmentX(Component.CENTER_ALIGNMENT); - this.noteViewModel = noteViewModel; - this.noteViewModel.addPropertyChangeListener(this); + private final String viewName = "joke view"; + private final JokeViewModel jokeViewModel; - final JPanel buttons = new JPanel(); - buttons.add(saveButton); - buttons.add(refreshButton); + private final JLabel userIdLabel = new JLabel("User ID: "); + private final JLabel jokeDisplayArea = new JLabel("Your joke will appear here"); + private final JButton generateJokeButton = new JButton("Generate Joke"); + private final JButton searchJokeButton = new JButton("Search Joke"); + private final JButton favoriteJokeButton = new JButton("Favorite Joke"); + private JokeController jokeController; - saveButton.addActionListener( - evt -> { - if (evt.getSource().equals(saveButton)) { - noteController.execute(noteInputField.getText()); + public JokeAppView(JokeViewModel jokeViewModel) { + this.jokeViewModel = jokeViewModel; + this.jokeViewModel.addPropertyChangeListener(this); - } - } - ); - - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - noteController.execute(null); - - } - } - ); + setupButtons(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(title); + this.add(userIdLabel); + this.add(jokeDisplayArea); + this.add(generateJokeButton); + this.add(searchJokeButton); + this.add(favoriteJokeButton); + } - this.add(noteName); - this.add(noteInputField); - this.add(buttons); + /** + * Configures the actions for each button. + */ + private void setupButtons() { + // Generate Joke Action + generateJokeButton.addActionListener(e -> jokeController.execute("Generate a joke", "")); + + // Search Joke Action + searchJokeButton.addActionListener(e -> { + String query = JOptionPane.showInputDialog(this, "Search for a joke:"); + if (query != null && !query.trim().isEmpty()) { + jokeController.execute("search", query); + } + }) + favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); } /** * React to a button click that results in evt. * @param evt the ActionEvent to react to */ + @Override public void actionPerformed(ActionEvent evt) { System.out.println("Click " + evt.getActionCommand()); } + /** + * Handles updates from the JokeViewModel, updating the UI display accordingly. + */ @Override public void propertyChange(PropertyChangeEvent evt) { - final NoteState state = (NoteState) evt.getNewValue(); - setFields(state); - if (state.getError() != null) { - JOptionPane.showMessageDialog(this, state.getError(), - "Error", JOptionPane.ERROR_MESSAGE); + if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { + JokeState jokeState = (JokeState) evt.getNewValue(); + updateFields(jokeState); + } else if ("error".equals(evt.getPropertyName())) { + JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); } } - private void setFields(NoteState state) { - noteInputField.setText(state.getNote()); + /** + * Updates the UI fields based on the current state of JokeState. + * @param state the current JokeState + */ + private void updateFields(JokeState state) { + jokeDisplayArea.setText(state.getJokeText()); + favoriteJokeButton.setText(state.isFavorite() ? "Unfavourite Joke" : "Favorite Joke"); + userIdLabel.setText("User ID: " + state.getErrorMessage()); } - public void setNoteController(NoteController controller) { - this.noteController = controller; + public String getViewName() { + return viewName; } -} + public void setJokeController(JokeController jokeController) { + this.jokeController = jokeController; + } +} From 9734d1d195e58832599ea9220905d8214ca2c4e0 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 10 Nov 2024 16:08:57 -0500 Subject: [PATCH 08/62] joke view --- src/main/java/view/NoteView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index d0588a42b..c79099c4a 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -85,7 +85,7 @@ public void propertyChange(PropertyChangeEvent evt) { } /** - * Updates the UI fields based on the current state of JokeState. + * Updates the UI fields based on the current state of JokeState * @param state the current JokeState */ private void updateFields(JokeState state) { From 4201f4b82f71d3cde1d40d80b277df7c0dfbaeee Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 10 Nov 2024 16:11:40 -0500 Subject: [PATCH 09/62] joke view --- src/main/java/view/NoteView.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index c79099c4a..a4bf2b260 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -44,7 +44,6 @@ public JokeAppView(JokeViewModel jokeViewModel) { this.add(searchJokeButton); this.add(favoriteJokeButton); } - /** * Configures the actions for each button. */ From 31698aeab7bb1a34f2c8f0ce82c2f54b57502a95 Mon Sep 17 00:00:00 2001 From: cheryllin2154 Date: Sun, 10 Nov 2024 16:15:39 -0500 Subject: [PATCH 10/62] Update README.md --- README.md | 93 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 5e1d8b77c..d00d06e94 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,73 @@ -# Note Application +**Joke Machine** -This is a minimal example demonstrating usage of the -password-protected user part of the API used in lab 5. +Team Name: Joke Machine +Domain: Joke Generation and Explanation +Project for Group #269 -You can find more information about the API endpoints in -[the documentation](https://www.postman.com/cloudy-astronaut-813156/csc207-grade-apis-demo/documentation/fg3zkjm/5-password-protected-user). +Table of Contents + Software Specification + Features + User Stories + Entities + Proposed API + Setup and Installation + Usage + Contributing + License + Contact -If your team is considering an application for which it would be convenient to -store data in something like a database, you may find that the API calls demonstrated -here will be useful in your project, as this will allow you to store -an arbitrary JSON object associated with a username and password. +Software Specification +Joke Machine is a joke generation and explanation platform that allows users to generate, search for, save, and understand jokes. Users can generate or search up jokes, ask for explanations, and sort their list of favorite jokes based on rating of the jokes. Joke Machine integrates with external APIs for joke generation and explanation to provide rich and diverse humor content. -In this application, a single note has a name (the "username" in terms of the API) and the note -can be read by anyone who knows the name — but only edited by someone who -knows the password for it. +Features + Joke Generation: Generate new jokes with a variety of themes and styles. + Joke Explanation: Explain jokes, whether generated by the app or provided by the user. + Favorites Management: Save favorite jokes to revisit later. + Search and Filter: + Search for jokes by title or keywords (e.g., themes like "911"). + Search for jokes within saved list of jokes + Filter jokes by rating to find the "funniest" jokes. -You can see the documentation in the various files for more information. +User Stories + Bob generates a joke. He then keeps generating new jokes with different specifications until he is tired. + Bob was told a joke but he doesn't understand it. He runs the joke explanation program and the program explains to him what is funny about the joke. + Bob finds some jokes funny and saves them as favorite. He later wants to revisit the jokes that were favorited, so he revisits his list of saved jokes. + Bob remembers a joke vaguely, he only remembers that it was about 911. He searches “911” and a few different jokes pop up. + Bob wants to find a specific saved joke, he doesn’t remember what the joke said but he remembers the explanation. He then goes into his list of saved jokes and searches by keywords in the explanation. + Bob wants to find some really funny jokes. He presses the “Funniest” button in the saved view, then the program returns the joke with the highest score. -## Testing +Entities + User + Attributes: + name: User's name for login. + password: User’s password. + favorite: A list of saved jokes marked as favorites. + Joke + Attributes: + content: The joke text. + explanation: The joke's explanation or humorous insight. + score: Humor rating to indicate how funny the joke is. + +Proposed API + Google Gemini: Used for natural language understanding and generation. Assists in explaining user-provided jokes. + JokeAPI: Used for joke retrieval and generation, allowing for a diverse and randomized joke collection. -The repo also includes an example of a use case interactor test, as well as -an example of an end-to-end test which automates button clicks and inspects -the contents of the actual views. This is something we discussed in the lectures -about testing in CA but had not provided a code example of before. Note, one -could also inspect the contents of the ViewModel objects instead when testing -CA to make a similar test which would be less dependent on the details of the -specific UI implementation. +Setup and Installation + Clone the Repository: + Install Dependencies: + Run the Application: -## Project Starter Code - -Your team may choose to use this repo as starter code for your project. You could -also use the lab 5 code — or start from an empty repo if your team prefers. - -If you choose to use one of the repositories we have provided, you can either make -a fork of it or copy the subset of code you want into a completely new repository. +Usage + Generating Jokes + Select the "Generate" button to create a new joke. + Or + Search up joke by title or keyword + Explaining Jokes + If you don’t understand a joke, click on the "Explain Joke" button. + The system will provide an explanation of the joke's humor or meaning. + Saving Favorites + Click "favorite" to add a joke to your favorites list. + Access your favorites anytime from the "favorited" section. + Searching and Filtering + Keyword Search: Enter a keyword (e.g., "911") to find jokes related to that theme. + Funniest Jokes: Use the "Funniest" filter to sort saved jokes by their humor rating. From 5d93c9de06b62159443af4f009ea5585de7f7c3e Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 10 Nov 2024 16:22:11 -0500 Subject: [PATCH 11/62] joke view name update --- src/main/java/view/JokeView.java | 104 +++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/main/java/view/JokeView.java diff --git a/src/main/java/view/JokeView.java b/src/main/java/view/JokeView.java new file mode 100644 index 000000000..fe4de1b42 --- /dev/null +++ b/src/main/java/view/JokeView.java @@ -0,0 +1,104 @@ +package view; + +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.JOptionPane; +import javax.swing.JPanel; + +import interface_adapter.joke.JokeController; +import interface_adapter.joke.JokeState; +import interface_adapter.joke.JokeViewModel; + +/** + * The View for displaying jokes and interacting with the Joke Application. + */ +public class JokeAppView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "joke view"; + private final JokeViewModel jokeViewModel; + + private final JLabel userIdLabel = new JLabel("User ID: "); + private final JLabel jokeDisplayArea = new JLabel("Your joke will appear here"); + private final JButton generateJokeButton = new JButton("Generate Joke"); + private final JButton searchJokeButton = new JButton("Search Joke"); + private final JButton favoriteJokeButton = new JButton("Favorite Joke"); + private JokeController jokeController; + + public JokeAppView(JokeViewModel jokeViewModel) { + this.jokeViewModel = jokeViewModel; + this.jokeViewModel.addPropertyChangeListener(this); + + setupButtons(); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(title); + this.add(userIdLabel); + this.add(jokeDisplayArea); + this.add(generateJokeButton); + this.add(searchJokeButton); + this.add(favoriteJokeButton); + } + + /** + * Configures the actions for each button. + */ + private void setupButtons() { + + generateJokeButton.addActionListener(e -> jokeController.execute("Generate", "")); + + searchJokeButton.addActionListener(e -> { + String query = JOptionPane.showInputDialog(this, "Search Joke:"); + if (query != null && !query.trim().isEmpty()) { + jokeController.execute("search", query); + } + }); + + favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + @Override + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + /** + * Handles updates from the JokeViewModel, updating the UI display accordingly. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { + JokeState jokeState = (JokeState) evt.getNewValue(); + updateFields(jokeState); + } else if ("error".equals(evt.getPropertyName())) { + JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); + } + } + + /** + * Updates the UI fields based on the current state of JokeState. + * @param state the current JokeState + */ + private void updateFields(JokeState state) { + jokeDisplayArea.setText(state.getJokeText()); + favoriteJokeButton.setText(state.isFavorite() ? "Unfavourite Joke" : "Favourite Joke"); + userIdLabel.setText("User ID: " + state.getErrorMessage()); + } + + public String getViewName() { + return viewName; + } + + public void setJokeController(JokeController jokeController) { + this.jokeController = jokeController; + } +} From 6dcdd8d3474e61f36cd711f93e78cc1b3d852bda Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 10 Nov 2024 16:49:18 -0500 Subject: [PATCH 12/62] joke ui update --- .../interface_adapter/ViewManagerModel.java | 13 ++++ .../java/interface_adapter/ViewModel.java | 61 +++++++++++++++++++ .../joke/JokeController.java | 27 ++++++++ .../interface_adapter/joke/JokePresenter.java | 40 ++++++++++++ .../interface_adapter/joke/JokeState.java | 25 ++++++++ .../interface_adapter/joke/JokeViewModel.java | 14 +++++ 6 files changed, 180 insertions(+) create mode 100644 src/main/java/interface_adapter/ViewManagerModel.java create mode 100644 src/main/java/interface_adapter/ViewModel.java create mode 100644 src/main/java/interface_adapter/joke/JokeController.java create mode 100644 src/main/java/interface_adapter/joke/JokePresenter.java create mode 100644 src/main/java/interface_adapter/joke/JokeState.java create mode 100644 src/main/java/interface_adapter/joke/JokeViewModel.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..7c66f615c --- /dev/null +++ b/src/main/java/interface_adapter/ViewManagerModel.java @@ -0,0 +1,13 @@ +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/interface_adapter/ViewModel.java b/src/main/java/interface_adapter/ViewModel.java new file mode 100644 index 000000000..b67420a16 --- /dev/null +++ b/src/main/java/interface_adapter/ViewModel.java @@ -0,0 +1,61 @@ +package interface_adapter; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * The ViewModel for our CA implementation. + * This class delegates work to a PropertyChangeSupport object for + * managing the property change events. + * + * @param The type of state object contained in the model. + */ +public class ViewModel { + + private final String viewName; + + private final PropertyChangeSupport support = new PropertyChangeSupport(this); + + private T state; + + public ViewModel(String viewName) { + this.viewName = viewName; + } + + public String getViewName() { + return this.viewName; + } + + public T getState() { + return this.state; + } + + public void setState(T state) { + this.state = state; + } + + /** + * Fires a property changed event for the state of this ViewModel. + */ + public void firePropertyChanged() { + this.support.firePropertyChange("state", null, this.state); + } + + /** + * 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. + * @param propertyName the label for the property that was changed + */ + public void firePropertyChanged(String propertyName) { + this.support.firePropertyChange(propertyName, null, this.state); + } + + /** + * Adds a PropertyChangeListener to this ViewModel. + * @param listener The PropertyChangeListener to be added + */ + public void addPropertyChangeListener(PropertyChangeListener listener) { + this.support.addPropertyChangeListener(listener); + } +} diff --git a/src/main/java/interface_adapter/joke/JokeController.java b/src/main/java/interface_adapter/joke/JokeController.java new file mode 100644 index 000000000..70889dc48 --- /dev/null +++ b/src/main/java/interface_adapter/joke/JokeController.java @@ -0,0 +1,27 @@ +package interface_adapter.joke; + +import use_case.joke.JokeInputBoundary; +import use_case.joke.JokeInputData; + +/** + * The controller for the Joke Use Case. + */ +public class JokeController { + + private final JokeInputBoundary jokeUseCaseInteractor; + + public JokeController(JokeInputBoundary jokeUseCaseInteractor) { + this.jokeUseCaseInteractor = jokeUseCaseInteractor; + } + + /** + * Executes the Joke Use Case. + * @param actionType the type of action (e.g., "generate", "search", "favorite") + * @param query the search query for finding a joke, if applicable + */ + public void execute(String actionType, String query) { + JokeInputData jokeInputData = new JokeInputData(actionType, query); + + jokeUseCaseInteractor.execute(jokeInputData); + } +} diff --git a/src/main/java/interface_adapter/joke/JokePresenter.java b/src/main/java/interface_adapter/joke/JokePresenter.java new file mode 100644 index 000000000..91898ffd7 --- /dev/null +++ b/src/main/java/interface_adapter/joke/JokePresenter.java @@ -0,0 +1,40 @@ +package interface_adapter.joke; + +import interface_adapter.ViewManagerModel; +import use_case.joke.JokeOutputBoundary; +import use_case.joke.JokeOutputData; + +/** + * The Presenter for the Joke Use Case. + */ +public class JokePresenter implements JokeOutputBoundary { + + private final JokeViewModel jokeViewModel; + private final ViewManagerModel viewManagerModel; + + public JokePresenter(ViewManagerModel viewManagerModel, JokeViewModel jokeViewModel) { + this.viewManagerModel = viewManagerModel; + this.jokeViewModel = jokeViewModel; + } + + @Override + public void prepareSuccessView(JokeOutputData response) { + // Update the JokeState with the new joke + JokeState jokeState = jokeViewModel.getState(); + jokeState.setJokeText(response.getJokeText()); + jokeState.setFavoriteStatus(response.isFavorite()); + jokeViewModel.setState(jokeState); + jokeViewModel.firePropertyChanged(); + + viewManagerModel.setState(jokeViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + JokeState jokeState = jokeViewModel.getState(); + jokeState.setErrorMessage(error); + jokeViewModel.setState(jokeState); + jokeViewModel.firePropertyChanged("error"); + } +} diff --git a/src/main/java/interface_adapter/joke/JokeState.java b/src/main/java/interface_adapter/joke/JokeState.java new file mode 100644 index 000000000..97277eb1e --- /dev/null +++ b/src/main/java/interface_adapter/joke/JokeState.java @@ -0,0 +1,25 @@ +package interface_adapter.joke; + +/** + * The state for the Joke View Model. + */ +public class JokeState { + private String jokeText = ""; + private String errorMessage; + + public String getJokeText() { + return jokeText; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setJokeText(String jokeText) { + this.jokeText = jokeText; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +} diff --git a/src/main/java/interface_adapter/joke/JokeViewModel.java b/src/main/java/interface_adapter/joke/JokeViewModel.java new file mode 100644 index 000000000..2e036a31e --- /dev/null +++ b/src/main/java/interface_adapter/joke/JokeViewModel.java @@ -0,0 +1,14 @@ +package interface_adapter.joke; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Joke View. + */ +public class JokeViewModel extends ViewModel { + + public JokeViewModel() { + super("joke view"); + setState(new JokeState()); // Initialize with a new JokeState + } +} From 8b304b6e1f89dad51392a9aec27cd280b6ae97f6 Mon Sep 17 00:00:00 2001 From: dengxues Date: Sun, 10 Nov 2024 16:58:13 -0500 Subject: [PATCH 13/62] FavouriteView first update --- .../favourite/FavouriteController.java | 4 + .../favourite/FavouritePresenter.java | 4 + .../favourite/FavouriteState.java | 4 + .../favourite/FavouriteViewModel.java | 4 + src/main/java/view/FavouriteView.java | 86 +++++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 src/main/java/interface_adapter/favourite/FavouriteController.java create mode 100644 src/main/java/interface_adapter/favourite/FavouritePresenter.java create mode 100644 src/main/java/interface_adapter/favourite/FavouriteState.java create mode 100644 src/main/java/interface_adapter/favourite/FavouriteViewModel.java create mode 100644 src/main/java/view/FavouriteView.java diff --git a/src/main/java/interface_adapter/favourite/FavouriteController.java b/src/main/java/interface_adapter/favourite/FavouriteController.java new file mode 100644 index 000000000..446b23e6a --- /dev/null +++ b/src/main/java/interface_adapter/favourite/FavouriteController.java @@ -0,0 +1,4 @@ +package interface_adapter.favourite; + +public class FavouriteController { +} diff --git a/src/main/java/interface_adapter/favourite/FavouritePresenter.java b/src/main/java/interface_adapter/favourite/FavouritePresenter.java new file mode 100644 index 000000000..d14dc09b0 --- /dev/null +++ b/src/main/java/interface_adapter/favourite/FavouritePresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.favourite; + +public class FavouritePresenter { +} diff --git a/src/main/java/interface_adapter/favourite/FavouriteState.java b/src/main/java/interface_adapter/favourite/FavouriteState.java new file mode 100644 index 000000000..6f9d31e42 --- /dev/null +++ b/src/main/java/interface_adapter/favourite/FavouriteState.java @@ -0,0 +1,4 @@ +package interface_adapter.favourite; + +public class FavouriteState { +} diff --git a/src/main/java/interface_adapter/favourite/FavouriteViewModel.java b/src/main/java/interface_adapter/favourite/FavouriteViewModel.java new file mode 100644 index 000000000..25d6f3d2a --- /dev/null +++ b/src/main/java/interface_adapter/favourite/FavouriteViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.favourite; + +public class FavouriteViewModel { +} diff --git a/src/main/java/view/FavouriteView.java b/src/main/java/view/FavouriteView.java new file mode 100644 index 000000000..d1b92bf18 --- /dev/null +++ b/src/main/java/view/FavouriteView.java @@ -0,0 +1,86 @@ +package view; + +import interface_adapter.favourite.FavouriteViewModel; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.*; + +import interface_adapter.favourite.FavouriteController; +import interface_adapter.favourite.FavouriteState; +import interface_adapter.favourite.FavouriteViewModel; + +public class FavouriteView extends JPanel implements ActionListener, PropertyChangeListener { + + private final FavouriteController favouriteController; + private final FavouriteViewModel favouriteviewmodel; + + private final String viewName = "Favourite"; + private FavouriteView favouriteView; + + private final JLabel search = new JLabel("Enter keyword to find a joke:"); + private final JTextArea keywordInputField = new JTextArea(); + + private final JTextField searchBox = new JTextField(15); + private final JButton searchButton; + private final JButton funniestButton; + + public FavouriteView(FavouriteViewModel favouriteviewmodel, FavouriteController favouritecontroller, FavouriteViewModel favouriteviewmodel1) { + this.favouriteController = favouritecontroller; + this.favouriteviewmodel = favouriteviewmodel1; + this.favouriteviewmodel.addPropertyChangeListener(this); + + final JLabel title = new JLabel("Favourite"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JPanel buttons = new JPanel(); + funniestButton = new JButton("Funniest"); + buttons.add(funniestButton); + searchButton = new JButton("search"); + buttons.add(searchButton); + + funniestButton.addActionListener( + evt -> { + if (evt.getSource().equals(funniestButton)) { + favouriteController.execute(favouriteInputField.getText()); + + } + } + ); + + refreshButton.addActionListener( + evt -> { + if (evt.getSource().equals(refreshButton)) { + favouriteController.execute(null); + + } + } + ); + } + + /** + * 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()); + } + + public void propertyChange(PropertyChangeEvent evt) { + final FavouriteState state = (FavouriteState) evt.getNewValue(); + setFields(state); + usernameErrorField.setText(state.getFavouriteError()); + } + + private void setFields(FavouriteState state) { + usernameInputField.setText(state.getUsername()); + } + + public String getViewName() { + return viewName; + } +} From 548494770e8f21c966134968bc29272b47a7b9bb Mon Sep 17 00:00:00 2001 From: cheryllin2154 Date: Mon, 11 Nov 2024 20:06:46 -0500 Subject: [PATCH 14/62] Add files via upload --- Csc207 Group project view 2.pdf | Bin 0 -> 653458 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Csc207 Group project view 2.pdf diff --git a/ Csc207 Group project view 2.pdf b/ Csc207 Group project view 2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1d81c06300c05a6dfb74a36e09dbed02d73ed63d GIT binary patch literal 653458 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

uv$t>l^x` zIbIltX`EuUqwp#{ylyizk~&|v@_=jP?%m$dz+ERoXadPlOI4^9Md|j&=DNW-h7KZ) zy4^m8GUZTD=G2J|UZ#KL!<5lc)#%Wc?2L0u;JodivRiSo+i|hz2aEYeuAd(ybQf)Zicw`<>*KO<|Ll(4tC4ipT}+zd z#*k5vH@7BpfYi&?zFVKJnC=83ka4YeBAPqpbxNQ%)tsweXYp*-eZ`~{4J@eVWJ7?< zVl1snlRe1GZb8-$Nhd?x86URPY&XVc}&g?EqYTMk>Nuoq@<$`#yH;@@F28K!hBy;51FUk5uF*wtrP5Awr)!A zp&EV7>n8y#Vc@P;z$^$a(o`uhO5>?Xu4AjBnP#5XYU$fSyvA-X<|E2>qiCjgG%4|f zb*)%Y#~28q4jrWWJMCp!XzL8N-QXj9^H$YJ!wW8Q&xv|f{KSFWh1(y)zI5?~25iI| zth`jE2`Q1;?T@iN6^Pgn9r|>5>zzAUzoiK#;Ufje8a_Nbe_tNbH+JRVzsZM(RAu;R>Si^jeYX zSn?p_?HE&+>!y3gN3a;~T1hT!Bo)DM$v=&>n|P2LdbU@9(^hpVD`cIjv%6tj#2Cg6 z9gS<1mJdMecXp{Dapanmc^zb5eY|e6qi-nY9J{rC8D_b)xMYwj2!}?uF4mRB4c0}N zb(=?UdyCsX2$w2bx`~rB&Bx0#DhO6?ZmFXE+u$C6G?XuOUz@n^?U?e=s$gMZ zT#ek*w?DqVTfsS){RvIKezFX23C`gfJ(?3UeEX$tKB}JyYlt++}Er$0!WGY~GO?;x)*W1s>z z6B2z_ZH=BAgwl8Skko2=I&x3%o6L1T*$p-cILOpKkcxHOKx5fK2%_t^cL^J-C2XYX z1O*{2juXI1o73+_*KhO-1c=q$syy9#3tyZ=8-`dIFj7yA-a4yQG1wlxX_dp(X_AV4 z|ELwX2GKbqt)CMAbTC#eEFm6Mze0Zf>4>k8wy3cfRKLxUD#dXx3aw@&g46?FDx4YG-?#!hX zUn@3X9K&5)v3&isX(yH$$ia3j%wzI7tP?nkylo>{H< zbK7xx-R{0~`R0>vd9>MA6h`@4HH~k@7pXjI6$yr^AeYFaO)hNf40dbcpE28dJsp|3 zj>LkbTWtR4?F#l;6Zb3&#ErjJb12nsx;>oqrA`zEA{>0Ij`8gbYSVM2ok5DzW-B{1 z2m|S7Z@m)V^M9cvEY{;nGs?fJSX_;AzZ-MB_s%bEz{bOI@{6C{5q zGm+Dv1^91E5>Ct#3F6%s0;|opS;oq4E7+U>#orY=tPOV4I2g!^^)#7)3P_#?G<@in z_ub)A?B|Hrs_HHQ2rG970IrUwk(J-pAf$8S{#x~RRDy=vTM^5YVGz>xrlV(knCumd z{Te;SRVzs<$Dw(wg0P6rn!}+psiI~+{hpcBZ12}nC((R<|8a{nGd}pBEOL00*7Od%n*x!1Vn

{(s{IsZeD>W9@Whs|gLXvQ9h=iSX# zqw!`s)Md^Yh$rKz@OzWi60QoIesFWEbmuxZhjSqo_ad)Q^EsXjxcU(=iP0TcxTGcA zGCS1g#c{ZI3&2WFkHYC*-7)jAln04Uj0AGN9#SO({r30P>FD_N|s zesz16-17HoGeeyo%%8X2s3+qnj=@sW#{JFx}|`KU(V0ZPK`Ygu=r~miAi7!q|4% ze79~PyIbX|^lkz8$=C0EZ5CB|-^8Zv9_otgG@UP%pAsl6{7ol;W3hZNlk@NDoH z*C5a5t=o}FV^e9a(IXQU`<*yt=S}w=)8A6EZg+U-4K5Ai9UW$RXRy-6mPwbpb*l^U zodMnaU}EYKJ@(SKXIp_M_IEL6=j1u%MQ*n4(>rm3;;zciwcu%M{#;2<-Jq3@JN@A} zIIfJH#+7FRgcJ=;^u2|Zf|QOFM4g^PW{m3DT3B^!vY1>s5J8r;3SidL%Cg=f z@nG}CLnSfb8h{|Qx;cV*|AKr-apa2&uOF5aU7!yr0AVX0?NH2dBFkiWe?mI36Nnh8 z(Nfc*0sojLV<7tu-=5y4afg&15l*8wZzL0hAd3c)Q897Lq{&1B+Pp9@7^3O6RJA1w zt<5k9QJ85CE80{6E(po=@gfO1!7Bap*j%|)EnGbHI3Wgd$AT42a5i{0d#$L?9eJMS z_yq_J;re0g@9@sXsFB3N*QgBhAUSfb+wl}n=x!X+;JdAqnK0gL6yUmfC-v5}Z>MzR z)sU#op4i<*z*8btI*i*MU5NhP8HgZ0$Ws$ox<@G*<@y~ebEB+V?-Dx#GWuP*tk)pD zVA;`8+|NX{6wcK36Gl#|6dE8wHbYJd`r*5oqw z2HH-NZ{s^=t)%W6Ex5apm;Ks6PtY0a*xUv`KC5Ea>zBkEa!aMyNWJg5RU*+g915Sz z5@HA`AVY4qXKLwod$$1dzgGt3!=z4G6mFcTvEKY`yH6i0!W=(F>kP`WGx#F$uEAdZ z2Dz;BAifW?kyc6nu8-W>mWfZfS`F^?cB{l~up|`MKy417+k3q*pMw#st&+vo=f7(u zO47->MVH!2|A-i3MWwJl1%AGhATOsrvl8bDLgj0u<=Q-4TGN3{a1v3zLcWC*_;Gdj z!r#_SzQpva&a(n+Yn3@0IeALm*%`c?v>?ChQp7 zIc;(_BBWNur2XoLCc+o-+`8T+H7DKEl8vZQUu`(IBJ!v zcm3$;N9C^i>qf6R$Ba@QZAG^ez^)7X^B`p+Mu%*rqjFhLQ_KQ6j&(bO%yD2!15}A< zy(0Eoq$9hVfI-*IX3tN6#xqvyXLH9Kq#7>}yRA%j*;(H~VF7O|J#lU%uBMw$Hq@bV z=Xzraj-;HHw;X4;7l(34q5U43e&N!~kGdhhWg_cFhpAEa{ll)D%(NLYwf9+f;-lXf z{P;x{^-fZ+a&cOuuc169YLnNAYI-Z`jmOAD#irXEr+#bXlss1}>hF}UpA3q(-@A7# zrBlOlyY(4u{jvz69Nxa`Hj+PfpPw#8E0R zS6^Pq>vur~A)jI|t-i3BSLU@^eKdfw;_mlQj1J4!9OP4d-MkL>U=)kSS;pBxdLIZP zPb7Rc@)M^~`HW7mh1H!q@o=l84Ic&VA@}-G=%+Miz^Bz2YkA?(i&h`xx`}k$lGfx1 z?;Tg&l*!$qD!9LaK9=DU-}W5)N3a4U(TjddrEGiWe}gYd(Y1gkD z&gSD@c!x020Z=`Rnw0I8paQz*6hJ*b8RR@xo$8cWZ4Q;x$eW2){KoBb$2Zg1qdun? zZSI?jl)jyT-TNV{?zwdRd~W6TAv^XM7B^Y^LgQEd5V}#;VQF^L_`|uC9Oax9+VC$O z)?QJpKorOgr3%CiPK4fcmU%+s(HF`+UxjYiOS=57BI?l)o4koq?wNK83l*`xyS(;{tbPqE?3MYJrFs2!7 zVly(Cof?FYe23f7t<7-^W1UFaSa;x-5+4O|u18+Qvj$0NxcTz7+)#%(3BM0bJ(t?8 z_!CE2t)oAR-bV8bzcLJBGl6ytR46n%$ewD~%Cox$D?o~D1`!7yrh3ZpEZk=&3IA3V zqE>`xBL#VJ77XZ?4wj&)6}2$UmdEiD=b4e`L;`ubr`O6S6-{@%mCPM80=Rti#OrPt zh$2Kt45X!nD6sh33H0f3YxRV14;I%ZN74FKY5u3*rDZOO`?ZQ%ETDpr2N}}M7iqkH z)ZVq?%(zxUdflNPa|20A`CJ>~_*-Y66Ii3-by16|7&p)-@}=V(K((?n?=(8bZUyIu z4l+>R-_=>$5nH*h5?!VcM}DHZ@XN^F$c@O*gP$yY{@%HO4Ff0|2s;G^Vx}fxkox2 z7!LutA6~!Rf)pATtHJ5%9YGq+LjdR@pl@xw`-H#MivHs@@cPl%yLE*$=6T8AvHMHr zec0tpxjT*H(D`?t9M5rkhFZjwzhk!mzv)7@%>QHgI9A*4Zd@q$vpAz6sV^b737Sf402k*AmN*G z`o1(+n|zVM7Jq9t&rrg6Ppor(f#4q3&!g|1U8_9So)0DzfQSUVk$NR_kee-!CX%bo z_eR_!N^}uKf2~T#7_;EExKvRr)a7}oWCY#;mj^OTVud!F)Eg&+TNOnO6y)fO1LkZN zpmJmCCS~Lf+>-7{I315Das`c0M7qiVzMmhEJBQ>W4TFsKlhy=3Xe zHQe9dVYF$K0>a93npEdZSCAM;`tb*`2(SuG{JE7(cV}+&H&Q{W2ibhrFPN3(97L4Pmb7Nm$r0MX!$Gxwi?$9WGC_{NbAUMOf*C;p#JKQGup9x?H`9ZRWI zYFG=OuR^~C`GUB+44p=rD-}c@;lu$Lmv~43bW{p-<+Dcz(Q`TWabHv1p2FuSlnDE&~I`c#;x8aRcl%h6#!EJA&mpc+H zR1Wadh-z{GzOOpncZ474Ft=dlL6RZ0%3*zwY=Iyh_#?(8Cxh_@&)kIs8@|oJ^PvS7 zK8SL(M-~nW6Vs2!>I4fS@EmFDk{|uhx%>pJlxIyuMNVn@^~<&X5JgoOZ0Sg?RE+3| zpXy%0Es!x*{bHUEPt_u8D2moK@-55bbj#q}mV2agZB%V|{XV*10f)8PlQ<)BqCQj= zFsvW-A_lxx3s8WGv{vU%2Fwy5yBqP$ASB`415a+d8^PGCt$`!AcfUbkF$kwAArT<0 z9_IQBnz?R@>S`oaKnBk(%0n27DtSP1*7`Y?q)TBN*W~&!KvIp$UUiuoea|+7xP!NV zw4d3#M!sIG>l0P_Orat^g1`x~Bd0~;ZXns3 zEj!<<**4NYdjFZ~@Xx5OZoj# z2U-2y>-XG*B1ygQtra&$BSAg=ae$R*ae^gRzh3t`$2p_iYg7tny(l%e-Fqu4h(h5= z%Wf#>!63nuWa;Fb^As}>*1_$LZ_X-fb00+BIjtH+FqdUy!H!xZ>fk>|aj#&8CH26m z=@h2Alxc)k|EBY-{Fd2e+5Aybc}}#GTjM`GWJM)l`Ach4WGn!xe}GGi)1-jwb;G6J zP^&s-_SJQ)AET%>n*DOFK<55?D_S0w(FgmnvmzQx6vkZ_LeXLip*Hk4#Re&+Uh_k&$$g5*A+cHbxs`rBf{B@M%a>S6Xo3Q;+9DCzhiQF75+4r$t zvD6E7p|`IeZ&?IB(z{hIibPd*1veWx)yP;!NnJPFdjd&9RTQW-ac|%Kq9K2betr>} zVb5=_pKOh{b?T$6KZ{33& z-irA0C0{ou&=FudvCXsQh8uV0o&u+__L zbF&6Ph=!Y=y+Kh9@*KOhQf_VimY5x2&tk4y7E}X0aXc~pY5ugCv-HBjDgJ>RXF}72 zX~Y-q!>=>Wr-c{I8V3(z>FMeS7>WJX>W|6V-v;^tG}-lfpu!$m>Be~wL3i}s}+jcYr;Wh*}5aWAzr@>{}?FCcJ^4U_Sg&zsW^rpOSFikPH{O1WDde+d+RI; zHJH1xRYCBBtn7IG=DVoh#cTeDZ)}xY0;cLbYBpyzix_O) zr>gQe>k|fi7`j!>r^`~4LVmhcDThtGp?kc&r!Oc#$Wq zq>Q_)$`tUrUn`m$ts6v{4hOD{Oo*F}lfBvr=En&r|YNs#MRNm zdGc6XKaG47hYYys2q*X66JH67?sx+|r<)gXG~Cxp=E9zSt!DhS>MSLXaEjiBO*gtU zgoAra$jrckiK+uI&9SR|82^?X+(5#RBg|+vMwt|uSAqLFXNm;`$>J_Q@so#pChQ1s zQx3eG2^#UsgV3=qRjY1AO3Ho}vVQ})we^G7tDjV>cwc%RLHR}^p^AEQOT=eubNyWJ zmmCk4*_|(WEU(Q7*TM?#q+@+#@r6nd-84?E7Fo!9qBhZ?MY-X)Z-#ixNSjq%v(Eoy z&`Dl=uy{S$^bre#9A*B8qBoCH{d$*Ozme3P3~GyO7aJ;dw{jc6 zjYQc#E%ctG0~Cy^C14a50GWk5(13{HEK-nb+!6mFPFq-E=gpr*z(f z7f8v!b@NH6%nuZzT=+(Jv#r2sda-k=vCDTOQDe`B(&{ppJG^IA&`^#DsPx+}YI&>x z@A}SQPwNaWfP2`ai64h1v7c^EPr8w~0pA%E@i|!5%#cu7q|sqs&qGu$!YK3K47G22 zEj`k7-|iIR6l+xxruxlPyMA*(1|xCb+It`qq&%WwGrvFp-qR$o)7$f*8%j>yTJ0%R zt=^*nI(tSz5Pa~64vGFUY@|jsmJHz*RgTf|Lsmf=D{pOOUp5_K)8>GviU*o@Trz9w zW7k0Nq84nwTMwn@P8{qrw47!L2iaM6C^a9XJo%wb#`!w}Ar9--N)q{@gf4!N3ZJz# z^6pN_Bi4^FXL7CEp^a!e_L#x5UaCACuK!WA`p(UDzoGHiqY7b-Yn6G{WITaKCdBit zku}i=$(xMkUN;E!u=F6$)c19><7l#Jj$I;{bYlXo*Xz{KWJaMP5N2XrmLgGQuw_iz zq(#OXrKC0#|M7H1&e$gR^Bn8kj{*XiZb}DKA8S_5}G5(6=7>kdsekGxhID@R{!bC_{zBZKuZa%b7Z0lez@+h#9HEd7Sfk|Xttpt!~ zoN#+ya1cnWEqR#pYsZw6-9Ju3J}r&Rzr@|-=u^0+_nxfHN#RVGq12*D_$sg#6uBNG(waNbX<(W=V(ho;`bwq36vri4*S=HCLs zg$%C0WcNEtteN2RC*SROMDc1)c@fW#a3_ogkj2!buT`(Br%WyVsIlJzr>R_TsDwTp z6@A4!YBc@hRJXSPP2gnu-O-?=6-%lv)gBXHFOyLePxMEo2(4bI>3kMokPosv`VfaM zvnJC^uY6Y!i>_OlQIput8-JvP;x5U%x=~`0WjgR`&4T!t;SXYXagx2 ze}bI3bVHp@cShCkt$qxzR{-d!lp*#k)5{qubX{eOY zAg_8~H{krEVDeROd&_gJ)%+5=#qsPnz#KC{Z1a}MRdPE<)Hk@K+7_;rj+;&*9!dZy zn}y$NvpuYMPC#mbuoc78g1zC1^;hkmd41yJO$VD(6}fCJpxnz;fcO1vO0J;T?9aU1~xQVT|d- z?d!{EgpIHt$MJrr!ZSKR_9cV*p_1EPip=gkj2GJum)`K*=orb7DHeUFk_$E+Nh^VmJG*T; z$U_U$vBa?;qx0sQsJwo@i57}&hTDAv_wt3CJ*-|t)_x_5Q>vKtwsx5@SDI*n0)@ljY)@y9u_^I(w|W3j)p zX8mH=q-}rh&SMMzC}bP#UKL2k%XJbYf6y3%Z?vt67t@_3PfstVT10$gF(5EzDTqAK zLgKZe#n5<q*B)5!?BJf zLgDezPkSEziVn5}xubW31hkGWSU(5B10mR=2(LVa-7|TKAu3u)eM*WQLoTEK$wQXw z2>{5uk|J912Mtj^Zx*6JiaHO$G9Nz3?Kq^v*|mD7@LhD@0J#n0Wks|a=rJtasK{Tp zPN8hnHxSZ(kcA=iUy!31+vWwFl0gaMyX>{}Sx2ak|T$sWaq1qX@bg+AK6GiOC=r{datIlyF zS95cGjFWl*Y(SI0-6VR7X9dD=TW8AUh&uK;EtAB!YIYzMsy%*SS9kgFzq<@x^hIUP zY=L8hPcv^PAQfu8emHy^2IHDEpH?Y6gM9o49lVjUTwcF4$F=H%8P{)D-KyHmL8gfs z`>{KNm+E{=KvQd!$rNPI{(}4@4vVIr46x;rH*3YPyXhD+vFYLl2=EX!nr1AlGTva` zxZajAglpxhAMX}<>=rv;^2JE8wujFA5>MBpVYg0>ldtf_a>;{u*cnMBlhH$H0i#qJ zD<|02sb7XT*OO!ETv*%p?1y4lfT(Uv($C*Y>5pq<>`i)cqOo@ZC@PYC$shR?76etM z-e5T}+l!$6O~(d58l$*$P#xNoV&Z>m#V@=HVAQckRPl#Jr}G- zC@N*lQMH9>z;~MlLKPpSs7^Uy+nyQiqZJl}3N^poZGBo^)+S$UL? zx4LDg4spbP+82$mRi#D^>9n`g?_G3jG+!KewBk=90NbC@uO1;@yhIW!U@~;`NT}(l zjMndS2P;$?T9O$YGd(1 zPIt5E-Kuv}D~~pgD_)ip^{(fn z8)zOxO%nLGNM#95H|Kjjl)KqCznk4fb_n@Y8hPR9NP#b~k|BeYxW2=K)~!j{Fus+8 zdY4wedBOrA;1QE<(WKT7F~3&4eS_d-x6I|?)z1Yv z6{XSNxp-qF#@6Wm@A{QeI!J+@&6nDK+v5g2!H26}D>07vloOs1h**~u;hD`93~ea5 zh%mZ+QwQK_na&_G`X2FIPC7;7zLM6#h|ed)k)3M#J1PR{v=8^Weg$_XbhODP==2h9 z(|Q}d(*v>YGo4R^2RR$YGOwx~gdo31hrCF2;{sUVJf_5)9YmBe3~)?PLSh?QsXP(8 zVb@e?Ymj+6^Pdz|2qIK=jFR}7?GB~{XlNl)d}N?Tm`R7%KSr8~mi(9?y>7Y9S<``- z{@quirD{6Ozh^{23bT*s2#85E$V6FpJGoyDnX*6cG}%mdrIhM_kkcx3lZ{za9%+^g z(5c+h;Q-ls0LtUPi+BVb=zL{ea#XZN%T$OAX>GgquksBOb z|3S`I#AK_4FoQ`yipEhdOVK3@vh-j$5#P845WuYxq>;j9v9&RW8NdWnkmZJiOY;Vx zXdQC*t#jSbGkxI>T%v(iASYhX$;U3FrKVKnBz)2uw?EY2&T{*Iq`}!&=GmD?~#i8$A9d4Gdly$)+g znQT$#lC+iHG6j)3`KBu${w?#o_qs9lEz0(|>%st6S;7pUcnJV!@bvFIs2qgDr+$=%6P>l1@?-GI%+^Ze7Jn>~TUg0R+wGmV){psS)UVZj{}elJNX!KS zrj89VT`yRq)>zcPkmA0~Y!5Kr190^;2RU2@JNB;;4@+yh&!lK{>~Nvc?l4Gx$5sh; z*&$#BcWy895Q@K0F>a*enM+PwH-n2x-%v$Y*X`a3Yt)<78wl@cIyVhj-cYBSm@fKU zD~w^S#GUR~WQ5#S=CXauoIt|-QgPbceH zqCwEqrxe5?cj;yw9uml{RsfRQ^$ulreUQ@$5dGOHLdS<+4ZMXzNc)ove}BmaV(13g9l$khwz!_{O*O@tPX@ab>U*1#BQw^Tk$i|@mc zmECP{l7_AlE_uOFv7WP+9DS~r~i*6r0y3jp~t zm-uJCGobZ5VcmqY@9ZvZHApG7^^*m3ZN!xhmpOlm#A_u9>nKCC;1=a|eCS0Nvu(7I zuY1@8y9euR1$k8eP~I!|2$|37XbYu9!62&lpue;353#) zDl5j2!l>{M@;Dmk~HGRcqg+8Lw`D%FM&#-oX8G!N4L$# zE&X#cyP;tD>vxIHBMQQ=cW2D6(5YKzR@iNs_xaYoC&-7G$%SkPtkaemO4(fgkkhp43+5u#A+-zZE!0c-N1i{e&Y_N$!XP6|PME1@SQK zt)at<>ua^=y8tYK$28`9)V*qA4<+9xavWHfkqG{-i_H9Et(T%_cdqsS&Dp&qTb3hN zn(oIaIE3(Eyf~ifR3o!h^B1Y_Uy6O*jKXSUHOTP048R5y3Vj3T6Nn^41Yi8~2ri;> zG!XQRR|^7+Dx3s2t={*9wH_Pv)bSY>#Eq zHxh=t6_d)h>lGA?UE{yEdk%Utx9h!qvwiu}6I`Yr32_Nw(yCILT6wL!)i|-$oR2Qu zVhCaOeEUbnoYY`V3s0h+YEk`?2jzB#j5|Y;WYhkCV=1lBQ*otxSPSODSb;`^m74tv zlihS;^;%T}98#Ic5M^RJA~1=FS`iABb*|rHTD!aD=i5V6T9{V|s{@fidNmYi_e>#v z%ghoX-9A{GJt!8?EAAw7je4zb-TFn9Aq$Mus>sSAWwSQWovixp)rK&}!i`iFf34i8 z!wYM3LsLm3@#a(#+^q~=D1wG8_zzhU{Buw`h3gkFX{Yi^wTfN*?Rp4??e9fT zW_*8?M2SQjr!(8UMsk~Rr~fFOH(&;41$TK+58JU?BKf{$ul15RAku!iooLOz{JQPT z=EgfQo6?zk&U%yk<#RTvMDOdz`7~CCx6{$2gz0?GLET->hy*ie!-=(fPCfUZd zQp{x}$7?A~h+6#kKHK4qm@4DXcqye(1FzS_q~!! z*U#@)-r(wi@tEB2cePbMtG4UwxzJX=-@rzs1-C<%`?8MbWeu9W#3<_4>$+vvw_3vdA)a8^YFEK^ z`^{lHnkbCFX-cBCO-u@R-!~H9`Vd0$W9Q2KjYWdJQ|D&LHCkz5WMX_q%IwKA2P0hq zW`nPA0U{`It@g~~cJ68fSUwKO<1d7|ZMkCK`rVHJ%y(>>kV{oU;<)3>d2ZYClzpux zs*Ve@m_mr^5h|PFeNTA!zQ@`Xo~+f~fU0RpZy9Ko#Qj?<$l~6x>?cL&1z!%j_dngMEvV2d+L|Jd>X*%zR|a#)wgFR*Jf_4 z>xEshJF>iAKNKfoKx|U#hED@Y4&3J!cuQ?vz{)@p#ul7z%f4!86g%}71qM``kk({I ze#fW0*c9m!z3V#>C&xo!g3Ys2jMnIlX3Za6bvZy~)#mccO>uzr$LmJh+=f1dJL z4h-%x5Vca<;*@8o^dmc+jo%HNAG4=D>v0`HfxqR}X{p}hFxK0h2HZlKXtgJ=?|`OC zAo3J*&-AnF(W=n=Qzq)qZm!1}PXEq=CTdz1>CtUgL)~^spuzF$b?diW2iSp)YQ$z=f?E$Je}7j_V){6Olv+$LJO!=JnYI4#jKL zYjU-^7fkh23IC9#>>+OdFOs;?i!e0$$?YUr1C;?23cSy?xK7KrwtG%lC(*OpJ&*A7 zx-{~wwL2(ht{T_#I9+Eu^gIv1Jbt&;qR0@}BY3y%`lFhffMBYir zy);>y8S*Db@1fUW)$013tC}sgRuct7en$HEL^2*%?;A z?4It8F8E?rYD=YRS!Y^_W#BM%D74ZoSblcPQ&1v|a^&pCDXSjwTH$N7Obn!i_9o6v zNouR%A+Jr zh`RMr^Y5xdcE<*$N(VJvsBsnPrip0?$VFU>>ec36uPDB{UsD*?Bgc!MSKBvaWrqbo z3g_xJb7H>X3i=0?=g$lKw=;F)`(4Cmhx=A1kDI^hMC`t}R`S5U?^2cL zp*pQYwmMjz`9V1{?qabcjwquEfb3@&^tG2eb*oGC>bglIJ3kP`=a1(qb0ZEDT<`q6 zdJ`CKWf&Ms-n!2v8y+9B(OPdQ!ug5XbhhkWH_bj#;9)BK1X&?h1NA6NfauWMg8M<8 zVY`N;6*I9($tvton-Gd`h`8}Fp%RZ723o0RzvbEOi+Ao&wh+}$YHK+|*um(C`rTNU^Dpgk?}HL|@7 z2SuKg!G@lhU4f*N_GWorgoAu>dLvzRd}_AiRKKnsWz6{LiB(;}p6MbAH~!M-tE+Gk zq%BxCm1C<9|#K!V> zc8dFElpHB{MW|Mc>RXAdCnIRc=BW1A%KE#Xxx16&ZLf!|>NGZ;JZbFR#DiQ7LI|=a zWnluywihN(a0i8rW1Ct_kG`+X@{bU2%-<{x(bf8kB6X!6QDiKR2C8nzYsf-?y16U& zv8C$)2p(2?dW~{9h7j?uo1E8>)^tRnJu$)h<$(6N{Ge;KzePGwN(S-s#R<`h=gV)j;h7iUG)T@$q0gg^&H69&=kIILQSuN=X}A8??M3J$+;2~=POLV~|0ZcpIKHp-n}IhvpME3tO#F~Z zhT3$G>GdmY2qN=N#7b3Mx9*eIi`l2{P!pg1dND4o*Gb`5wE>;}#WEz+`cb((&8(k^kgyXO}=N0A3>!sP88zvTm~oC8k(6vbJ$tEBSTa;3Kg%pf#L#(i^K#(!dPOc_n)b|fsdJxYq3+wZwT zOqCn_c|Li)1KP+D|$AbNI*>qE>n@wA; z^R!h3w(oNp%=?_WrL_{{Pg`;?@*(QCcjFInhOVCwbN*DVp1$r1-u0UeuAijU8|h1h z4#T_kyX>sd^ZSQ9&Y^%`lkU;q=R}HbF{;6DQbhR;o~^fOGC^)BOSfJ>A?+KBQoiMh zs~j~+@*4@AUYln*XZ;i)X;Rjow9M;zTTI%v=X{ROS!A-_8Bcf4EY`0xn*F6Pz&S8d z&u17(mG{!$AywTrPsUwZxK{L9oXP%EBm0md@Us%<)Yiu94fV^GJR*Q%P3Go>*EJ$; zAdJ!}v4$=MTQ>=r9s=2riPCcoT-!UN)#$L-c`5thSHAj@WFUjyf$he z^Er-J>HBdCkC7C=HcaSRvACo2HcEW`y#JNj`aZU~cn$r6!s|tI_(nZ)xTt9n_lID5 zI$3U{lek73oSMG$Mctlxv08>3=d}AmPhYoYo}G{aT%(zoGfF7ZA)mpMIeFa}^s^Iq zhsQetM>mdh`3Bks8<{x$nWWdb&Q6(S9OY=Pjig$l&q4ZSgv}^#tIrVytgplT+W~pC zn|4aESvs1B2vaB2V0+iIR(Q5u&s0q*hV;x)$jXa`^h0X;Ib_O$u9ZqmQq4i!j|N_= zHq&8c{MnR7dT(wz<{}_R1Sx|P5BCcUwUWO0?k5}xoWxNxVKiS?E5G?_o`oq2wKsY{ zijXj5{W+TrR6;YUX3O@tLD;gLgs;yYSzg%$36eLrfl^?WmqsY|GK}&iw8^K>rd92b z4iv1a+Whr9Rh{2n)Tv434W!T&wI30@2hd146K|(HB)HG1P+2Kn)6`ct6Bk3>KvG|6 z8~?N`hT81jNVb`;l*H_F%)#p?TyR7<*Pc7J#7j+H388LepEDJ9&+R5<15q(I0sd8+0ujI7a@E3o{*e6KeeP*< zt*Z0R{Uhm)C}M+6+#Y^rNMn_R^*xD~8-2G2YGs{AClzb)s*zs$xH;^?WLSZgW+i5v z@X_xAN{}BHm;!rb!3QyvRz2mh)pU<5Y?(2EPa+4N~MALf}5@PNKva8oXb@h&c zsGFqduC9dHbgL=jYIT+xy9EhV?^^|r8Hu1+@XCw6P~)zRUgSaU8dZ&ssf>HcazkNBcG^8A-byN{qI;$-YG8kKNu*bFeQ2O27m>7GR!GJ=Q02wW7+fWh`cOt~6Zc192 zDj5%yb&(*zm@y z)=0`Ki}p73Powz$H^8l(IPMorRJ}0$klt$3#bHq38L~J40C%LD2TdpbQ#7SopdnSf z@#RTgqI5|06(LG?eeQkw9o_<;N3mmOPe-vdv6a(&nvmkN`on zeA%WNRnZ-w$n9oCeqJxK`YnZoXmOuplbn>~q7$iEee!iYAn8rClx zs6APbHbfleZEkOZ+$587HBxidN=%YNH$M4$>MKN1K&$1>Q65JU+1n;gjd2+@ikY%n zAR?1T5+?ewAn&n=eXT?iZ>Z`&Z=Z_j)QyE2;FX=@B!=e4CI0PrkaO_kVu2(~Ga zo%;0}!F9`Y+$04kvQ=xe2-X^PWh{iH94U2Uk8ia!+fTpL&8YhX6{&ypmQickx^;i3 zBdOppPQINXjSPe?>ke@C)`-#V^QHC%+;z94?{vy6HR92`%l)eu)n@ODp<%)dGDX z?BVuBxFzo~L?Y#oUZWk)@o&=*85e*`ch{)LwhrO^e2pIB_Z`-xEW~yDYj51VZn4;`{&@Ap2}4}( z`G&?$?{iAbHWnK-{h0MP9v5%w9@davkZdGHGT$_na&@GP-u;-hVhL^}URC0%k=~s6 zsvlLjK%FUL^^a@S?XV$b?uRHyz4hJmX2W(nOg}Ot1!45e{rYuVc0dQdbGHi~w>)MV zBM#=}>1(yRwh#ihBb*63nW7}WB;56r5j}CthD6RdN{VkIv6+umq+j;A%uK!Fusws* z$?p-C4emLD_qn}r0okL(H%;;Mn}YZuqUeWvZV$x1(=3?2;6>EEva-=>1%yGd6` zeXccy@aXS|-MgMaGwq{*RQPpsk?Mr+KZ+r&&0a>=rkc49c|-M3T>VI&CgpRxgF)6W zbKErdAV|`Gw#l33f@m;;?DjxvqLCn82Qrc^-+NmS7T77k=sQ6JW0;N&86~G%c#57{ zwg-Ejt&s#PPnGeTs$mXWJ<=5S?Lx}jIF!3{xRr3<&Ip99-WKV0Z?#sA`<-b#p90J% z$g|aERR~rWwzw^<6umh?x)NWjf2#~w8%c{eMZwxJrbbsC*?yh~G3~`xA+tCdNLVnz zQw7X3lnAJvjtwg|6$M_9phi=Pcy2kXx=};#u=Z@whH^$ylZ#xm78B^2={Wp1g>Y&@ zK6O8uW;JY;9yw5b#E_}p6;^drfZaaUka7 z9t=d8?VU~`hnY_>Lbg`ZF3r@bIAJhp+el?zu89c24i!jJ;x@}MxkjdPtt_cSt$)8q zxUH(nAa?EOj5&-6GpUd}=bP?;h+nr|kbT{H@@H5VhikP8)(~enqChwuqnlvZQH8Kx zzE&$vam0jR>W#GL>4tpTB^Tg6C$w`?TUO@=m%u)OxNF@vPAuzz1rr(C>@f=?3HQG?bH>}uB4!&$ zK5(;CXL^!Nzt0}`los=>Ii1){bBQ+%*>Afw_Tra8SIiqEM6pJA_L~$-y*8?x3cb;Z zounhC4Djveg3xi8#Om9Fii$!=syo%LZqA|z>nBbci%WAH{cV(FZ5)PGyALxaNXGX$ z=W@9h-FCw&L@@1`M<%Zqy~P<;$Epnu{SJa_d^ZIQ-5xknKOEiLIw5=Vs_&`cIl=8L zc0p@%XzI0ceovY4lAFhHjl^Zmlp`*FLll#dwZ&=WU1K@->#p;N=dz&CU>Oo z@!|>|N0#$cAiX&^LJ5vFHl%A6M@{Ffx%2g^d~J{S5blr?eA{*I+3V*=HR^{qa#A&~>^LsmiQWCs`}K@Ajl0a((un`%$&UwO2Z!wRG!Q}ceQviUx00fA?VM|3TP*|XAz#?acHJ?^ z@_G(k`7wvs>#xf-bSUWmlm@zQb$eUAUBntVjDO_44i@u(|x()Ue{k-OzqJ$=2W%a^ljjmM`CJcNL>2rrpV};YT`GWZJ)48vIR^XP)ISG+7s6ZEV3yo_%l#~hpSbV1 zAPiH+X#AOFejy5A+bSZ@9<7aH|6>Hv(M0q5X_6jFwdsUc>Qp{(5fal(J2&&Nl$6!5 z3L_Mx5}6^n_d_ZT9dbXQFs#cbVYZ`IKL5E`J!f^uYN)jl<^B2IaotGu`bi9IB)QJ` zpfK-FXS9FvqS0qF!u~mxL^qrv9rB36WJs*l@14a;c^cti?rasQ;g*NXXj#N5TwiIJiQ zK3yRCHDPhqtq5j>OP-A}gcQ|8-`A=Ys0sDlItYQP60e&uT9brjh;JZuJ{!qJxcizD ze{B>w9BUfALbrXd>eu?+pNx?md!<0Jah1{b_k)%kUEppJEw zp4{L{GMa$n+cmcOF&mD%uAZ&6P!<;=v8cK&;&yXV4tJ|#lpm9D9;PEyn<_23Nu3#1 z{i(P9YyjVrVD^(ykm_@9ll+H`g9(Q>1smR5Awzy*7}=5QNAYbd7csehyEms$p(hy1~%MjMm!&VOJ4dBb69*K3bjYLJ@^0)%EV}<|f{~B?-y?;p0 zgof;Gs^#Vish4D&iY}63~R(Csk}hU|phI3PZJaP*Bqp${qv&kJ@GnHNUnSV!{SaQWOfS42 zbjwSGh|-Q!_3K6cVO$k)kg!Vk~$1=ZutiLx>8R2HBRTV_dNh|ys z()Fw%4(fn8s%t{hecis#<$2x&o@7<@A9amb&A)D|_IcfQCA^`~Yi+JbL8Do8^^(%w z=iO$T+6*fhv7z#<0xkzt>j`cD(KE6&5z+pc&N*&y+NKvZv%{*I>m)9O}hZlx~bgn278#x8_mfn zTCxy=7g`D?zQv+@l-%F-$)|@iMf`RP2$=RS*Fr1wVIC# z_+3_>1TAzrX<5D;S8{Y*lrfz?0OKDUOvMAcWQf}Xk+-O58&LexB3dy>E^^o&^9$kT zh7=t|#1I9@30_E5eAllX83&%Vnep1BnXa2qd8_BJ`=47OA zagf*$Qp#*&SL}I6wp!m`nQ?7OPu%J}Y0^0`gKnGG>N%UO_pQ#0D5uMr&tE@T)x+?6 zCrY4}OJO9@rRHSlsaBQKO)};iRJN){LX;;P zX!zHS*=4mI@t?JE{ob)Zd9B}SV|UDV7$F5>*RLCx_qpDSxUrPH?t8v@-(!8XoB01~ zfe4IOLKBva)L3k~>n8;Bs>aHB)KB$VYtg2N#M^`2mJ93V*Y<8NqCn<7Ztwafll3b$ zT0i?a3DFd8$Cu#UT8hin;x3>!j)}ZpJkxUsvr}utFgS|uF5Tv3dA`%FvSZrs%Oc)6~oOxS7HgpWkyJE(+z?5#i4AJixn0ft(@9tGzt64H7 z_h(M($7GY77pu;wR*47eAikUNytLK z?!&!Z5P1DI56N$y@)fPGU0CrC!Cyvk$fc0YygL8;9$k9#Tw!&stn-NO-rj8kANa9- zHv9EE^IzDna6sLdToEq~TF8M0rp+2!cL>=Nm?Iksdlh6Umxsz z61&iXbxF{+NnEvfKje1}d3uvo((4v2%{lI&+sq55d7H_s$q)|V?_Mj{t)h}P1-EL$ zHW0SDa2wk`6~*hqbktV6SG~+!b^@Vy-p?(>>`M;m5w5SGK_BMEV|m z`HriXZ!BvwD+TZs#WX8IAv#n+`U15)tgoNzRms-OwpqEn$wDU~Y^o zjL12gDYBRyM2PPNLze1^4fmsf=_F~yw>~8;=d;jL9jc{_qg3YJ{{C$jm{1kBtA^iQ z%PtdkK<&++7$Ldfe>d4WpYA2@nynoZXL6(-kU0jT;mzRJMvGF1{EYLE_qFSHSSc{i zFaPC#ZLA+`KV|mk=n=bn;XhOOfE#Mle2_|;Z*|6gg#$Db2*<)>fpZl$+x&OJw|L?gQ`+u1G z3g|BNz;&HrWB-cmB;8m)tsebQ z^hWwl(x2aZ$ngYK#T(_g$cXq4&kFtT{}`6n9F`LmK*Rs%0Qax|K17h@ny8=Yh}8=3 z-cUTTW~xv@?amT+9q3^D+iQM3X|SU!-&+ImmwuQKy`^7X)y8 zOwSW!nL_^@Qr-T5Ze-Pj!TPU5b_L#0W$M@iYn6o>BBaqY3FcIG2<>ze5YkWO%RZPU zW0N-fXf>Q#mitN+*9uwt8%rSz+M^&>C3iMl2C+CYdbXZ^@_=BJUgp#%fOE3%*l zRc(O7DFDtvpCdtTr{A7f35AE+aQvT;iSLs=8P%~pYOs@aFxA623?vPe|Z}I7kq_!rqq_1q*>(`Z? zFzNe$+(j5(P-2j?)xP_5{)n^j4JcEN0~!S=we^mD^sCo;b_f@_hk zp=sO@8}%V9@*&+f`udH{b79Qw`fU>+CI1eQeOSL;xBjr3lj^6h-$;-x_S@P3{l3Qc zIZ?8Pl2DH|g*~#mLVC14pt_vKlzZYRWbOTdKTbytAzcV zqi{p>W-&#!#&-U<{YMY0s73ZZEB*B@VQr#ab`yKAS$FU$*e6LV0b2EfB{+~vos;ig`k;J*9;~%Tj3d7ye zgdFH+4K@-I1SnZMK;78wfV&sM8yd~OMY%r|N%uT=h=ibxgE$=Z!$9{n5SBV2*5y_@#9`|H zPN*u;3t_08UMZH?LIC#+WP2bc{0~FHgrf{Ds+SwTfeM&xpUN%mb000KsN(8jk_@%V zp^)H>3;tF8UdV5{?mKe5>J*3Z-~PciZujyfgZ$3xO+oUu^-&O&88!vGcx{xIAEk)9 zY8`4tnjf>^)mEGyqdPWrzo)j5#7R!lW9cVR?CWdPeem(Lxc}?+1gP69C$Q%^{oPO$ zM33OLKGhO^uG=}|dyYxbOo1a4cw7hTu2ko@~Y`leT`l|bV!bFh{q7l;Az1f zsdj)=t&!(>n?QPQval-@@d*U6Z^L1e1y;=PiNEOoF+D`m^pLIsMkbcjcMz*2AL;PI zZ4>V}qBt}a#W#>zwpOQKWn!(4(O!kfux^1*s&(NaMDp^EG+XKj-WABYWv=MNw<%8) zD+xG75;`qMeMq8gB*EiPWOt_`&Q<4pT9xibk`7}TjRs~6Btd<>hotUftioE^@QQBN zs=CXLoU1yKM8Drocs?<+T;Rq(Z?v9+=-hKoOGJfL&*aC%P<-|d;3Q<$^Gvt);2DPP z?3C2otNJbSziH_oKpg*jvPdNK_Ql{mK2jr=NTe!yu(@-=%GQN+V`FV3oo>yOu}Mg4 zzBYs?lKYz_e_xXmII0MleP1(nYcqCbcsKS9?GssP1}^bX6TdWevdNUHuixNlgtaQ4 z6;kNw5ILqp3Xi>^jIg1~MbvHAR@ZI9*w?yPGoY6i+Rm^C6~P=JP_?!4Y~HLR*19D= zt{ZFVD2bv+fvyMa^SKQTM3NsOp*fcO9lAE1k9u+0ZbN!Gb3k>G_pRsn%$fdUYvlpG zuRnTF{s-XPZ)IxDA_%^zM6MZ0``0QNP5OlNw6?`&8W&%yvhbSM>O@QjtKUf+ z+xA9JZJgS3I=V;Xse)4uBZ(rJJ1P#SQS?(rQia9Zm_VQF35Jelr#L|tvY%NvL&8>s zC_r!GIV;wA{RrcmrZa4LJY|XBLp-ct=R&r*jo42&UG3A~nX_iWd{`n4Sb#ws|S4}e40S850 zkFIr4GgJ9Ib?baT16#)Yn2@7-+F#AaI~8XWJs0x&(fKK8Tis9f^gZ5u--8s{57}d> zA(E+g=3u>FHdE%z@XEcpWX;M^k9*Q|bK9wqZrvVLL~f%B$EU1JbYk`PJt8JKB*a1d zb_}o~6RUFoD?P7#;l4zX`mG%C>|jptoxF%Za)dD~+pJ{xHb$$M?G6X^ z(MU1Yi6RkzCY6^zKQkk4gVPLYIE5ftZgtDMqEFgA3{VMP7;T%ok4ehjL>7;v^*P>D zH&)<?&PMfs5s3TD{ikaORD10x6eV!X+#z@ z?;1v!EBcAn!d_WaA@*t`?dos{cjWt?pP*SI5&4@Xg>;%l9xI-9JbOmFZsIDF5U_uB zmo`j&8ko%cK^g zeXU&gHp^tzWJvu~s|Bz-f4ZIXo+-hkQn`9hh#1J*kO|t%XG+++k>0GH!jjXmR zkBOcN6GFPDKOptmB#Q?;mCGqUl89R+{BS3)$7+e_-d=B(-TV3aReu}C6>XM`_!Mi% zp5_QCr9Ffmm_ruU(@3@Qpwmrrud^MJg9Fk9 zYc&(TU}R=i{l*jvSO3uR;;$t8+%}B_I-4Y^iU+n@SDE^psK-@et3&BzMN2}d5~L9P z-L8zmlMLE)L#u-!PCC=m=+!v|C#tmGK7<`Yg%O3+VM1JHb*KuQsu(yBC zZe@Nq`eX)&Ek7$nA<}Fw*LHUGa#)8z?ZLFhMpDom1I4+HKyCK;Zu5j?zJ+o1>c>y- zrJikQN$?N_2)BQWdDgFZ&W^f0ZO!pek4&te!+$4D4D&{kK)!j3nz(;&Rt32W$izUs z7BTL~M2o`R4<2x@&yVPC89nTFuir1aHs0;71)Cv)n^2EN9+Pnczg}->wRo>pzc5li z0m?TL6+8nN){Czj%Prg6^mNFOXc8BcXdRGtyU+a+S5Q(=t8XRDg<}=f0M`wxeMdoF z|9$PYJa1-_CF_1$2ce!uHerW-4&lh38*9JN8!1<@-e#^!cF1oh_RcZQD%52(@r?@T zJI5WYF)XVur$1yjwQ8ltqb+u5i-t9RclpQYFxjZFnP5`eu3to}6+7$t70eD0OgujK zl@~EqM3Igw1iYPz5n24I?xjI*c~_PZB(8Fl@TjIrzK?zE-pEOA;lNA=B;c0Z;kshx4N_IoSgMwZgMSSCV7}y3JFW%*h&>VT=b; zlW>?j6A>K|J`0U^mdvo7-L7pUw#2AXz-M6sP=#vSg%kORuYzVkmz&0Ne7@JM$7+p~ z7aZ+kgA29Wjh+D8=Hb=#+ufzx1PUhU<6?w|n70-o;Nt&~)Sl&v3`Slc%Ct1JsIsvB52{1yNdE&J^-amd8jovf1#2Sq1 zvK&}1E(Da^?QcTOuJnAKz|auJ>*T-G!19g_)cwI4NuFJ!lvM!EH_O8D_lw?PIhMm5 zOd>cL$P}xVldZ_GQBo_RBTMA)!yR0bj}u&O`Tm(QfS7m8RU-!&_|16fL5PM_*f>z z)LNKJ?LmGdH4>r@qUCX!UQPtY!)pr6Y}B*~l;LzY#Py>#0aCh=>rc8J+lBRBSeS~I z+l47POu>S_z2kw{1iQ+sPG9|^WFoMA^i8ck??bbA1!2$lDfhFZ z32_Ia#j(wMTy0+~Hq_pg`pBU(gE30>deXz+v{xLLKZqx+f~?&!1c_bWYAM7v4&A%l zQLDW<65{8fkw=s14BtDJoZ<@va#&W^~vtN-;33o>m zRgWr&xkE>S=HNC>|90Xc5xOXL$3c(+|M43YPbco1brkt+9N(GM7BBg3#PEZ6k?bHBvJ0sW+`wv(>(L;k40l=ObS6 z>>*8Wl3?F@@*BQYSOCZwmf*6-UZ zR>8DHV`X1#aC&Zy?x6XcIc;RRVbWhv>@=!etHl^$ zuGKzjW;)kuZ*Jw!mLQz4*^3x`k1t*gcCEY%(fSZ^2OGk;Y<-Sg*BY9^ep8`-YzzUH zH!Ei}Gpp0PM%x2sR}YdlvIBRkqa1cNnp4F}GtS0heP4pZZc=w+Lx@1&^>Z-i7!tuM zBl=p3HU@@}so85zKvzmas^t4vETax&2Db^U;%g+To#9vQPmV>OtHR?p!CS6}u|s%C z&e?IaR)PeHE#a4br>FJ48zEt?7{mw!ZWeEdpGQp?Og*+dL6d$+DrTMTzVE4ZILy25 zZ;My(r2R{d;xj|epuUO5)FoiS(PwRDj-2B;08co%cRsK&krlLj^` zp^lzGx>kuO2wn;Cy}dLzOxWa3@jrT`vsOaX*UC2JPeRITPePQKYo4&)8>9!uE>=+$62Mn}q+{NU_9DF`=`{ zfGqHy$7-mo{1|az(E-)dHg6)o&kUOag|O;ldowtp1*vp3#DKS6*hv-XS7Y)QxW?(E2xFbiP_z8$IN`TEU2?U1b`a>wYj zWO@Cn8>pWyH#&>4nUi6ikow6pChZ|7W%2<}V6tC6!8gfJ%2)>_IS8E$AZ*`Nf`TOhl5tt9ka8PHaNHc1{X1oNeJ7WzOt0IGpZ1ty_(wCp0a4q3Pd?R zLkfn3$SJfsGkWY_l$4kW5;91_LQdKsfrGGaf*QwKtjJ?6txkRutjl!Q@2a>;T_}aT zk+SM-6rpxRX>@~z-9iZLR1AHvFR=+uoeD18cE>KfQ!SkI_6UIL`t*DW{S?B`GC_za z#5chn5gw*uF*2f%f1TSQZQB{;+wjD$pKEC2E_M83z3%hpTdH zVHYL}>#lp8Bc5=hs}MfKMX!#)+MKWx^uBp+tn)j>>LNm}+~d=|Onb;1yKqa}Jytr| z%6&L4k^Oo|xA(8jn}Cvqvu^8`R~v)>gig-H&+L5jUR{nRHs?%%W;uZi%VUa~?j=MO zXQ%fn`y9{r*o66aXU-NCHmud+Cc5DSl+5YJaRq6~7T(aS2uWIm3kSC-eMQ zyc-kex+ECS&W!9c#pt9}1vmvVl=r=yyJ9q9t9l}0dlY}CKyh8)W1$pE-q>9vk0@O9 zJk_1L48;(4jXGm&vM&0E*c@7^nfK#~^_!W$<)y)Evmf#sRW70nne9Ywl=QrhaX=$x z0v31F%>qtPDJ!{w_Jc)JofU0fKi4eVmaOm{FiTlH6N0;|0+^y~B;It2xqejFvN4s_%zfWE*&>gsuAWOmXj zpZfVWcKr5|$UkdB(a6UsER-fC?1RkuvBG+gA;j-9o!0r)RC5LdJ$He2KBj;|_l>#G zVONHY3N0*Tbq_6hr8Vw}?t(&q9AxLItE0=H!I-et2VreC(PBXf)sS9=Y7cPH%!jaL zxnOw4ey-KC*Bo0@hsea8U|>Lw$-`PO0XjFdzn9%f%ueV)cG)X-@*u?oXxN!~d59_T zkbYt>#`HkPLn^NutL6#4)k(XLec4&j#Cm&8qgH;A;npjTY0n`N1D6j#jBOT7p7KWT zY04T=oZNf^QC`T@smox$&w1^k^8-r*ZVOg_1Yu}9iEYy)e~9$pHlZLA!~Vi}ttQNZ!{_ettJh&$eJ@=$&Z3*o{MX-Mkq_N0eI4)J4pxmHMrQVkEB$ zY{)i~q!W7hzPFmF8(#J^?EVe*zDR+m2aFCm4}p2h%tqyZkDh_W!P?|Xr!L8ZdNJScOT247?OBw z>o}1;I2NW>I<6q8TDe$Ft(cVUdB}pXnMc|ji;)Yrp=T4U)yMZq@eTd#EyZ?In_)`e$4{$L zU#kg7+|%PM*RKa$;yG5v`I$`5IZB`F3DUap zJ#U)R-4PS^oeuTBoP5ZxzT5;-6CpVlL!R*hlY@C!&v4YrLAd3SMt6d+Us@RnE(uek z)d2)`PvUhu*&`Zz0^`zWwJ8uPMzg{1YxeHCNgLi;Eb6{5PWFh>Gt9R-Oxl^sdn*)R zAb#+%nE3aJmA1MjF322*S=_3=;?~{6)lJN<6C_C5L(UD70{F`-T+J*zzjkj}s_}?M#x)GOy8dE-g11+P&IO6EL!)VlixSeZvut=I;W389Vg zU@LwKV~(~7c4&EWh&R#(ta8@hnK&JNZT#549ewVW(*Y5hIN{?gk!%nG#*BP_FS6E8 z@NOW6?IEiXZ5!FRCE4e^@_GSbK-QYnShAjYAV6aTt5CwVv(KJ)Ie3^9MU2oj46~_~NwhWE ztgO0=crj^{hg~p66bK92(gL$P>#TwmMnZ&-BNh*={i|P&(6$2Rmt%*xg4yQOO1`5u zg6c`UJU5iRep$5#ZBjlrJK6Vlqu|%?v)U%jVM;Api;;G<6(Wy)>!pcXFJvV#+Gsn& zrm@bBfr+SXPWy3}sG?t+)kw2YLQwr?xvWgzlQmc)f-Hv3e9FsfXu1_|WGhjUuUkKd zRJePY>e!FU% ztdVhy&p5w$(MT+$46%^CX>>y4wytc+XUlf`sYVQdI3Fvg;sQ$C52&K0ufcZIYgDQs zM6VM_XB3B2Yqfr7?1B7S8`aoKmFp&1^BPsDJcMz$HlnY$1A zo9SFO!K++{QLu3)^&)g>BSr zm(<$Y7kJ3Q6 z)oCX??(LaX+eSHhvd+$Aq9r%PTIG5d}e>2*o0r zP_dm9Yp=zIt*$g=H_{_#NrP>sy3)3nBlPO*YL)RnEK|6C41r@60p)lVa@VkP_s(M- zHXR=pXJ)^A{!@}?-4=NDIl# zGB31sGLt5{u@g_W-|oRKR%C}(X$Jsa{DDxYn-d%pFht7w*J=K#mB4VwiLjL}4Czi@ zGE@rCDX*WePKK49dSiLgw6R6Bu8p-eX_B`rdc7#IIsY)4B6<^H&X2{?8NIUGVx_B- zm^9QL!hu-E%`)x3)9FloN`vffB*(niux@IHI^`EM+~Q^rv;(D9M@iAcyy*~xZwEr! zw+L~8{Xt9U6K@iI*Qg&qoUZG4Uh3x5HISIu^Ttg<(&t(&Gti_i<<4x9Al-7$%F_)` z{4DOG+L!^jwJ0%ZagbH&80dFHH>9)W*p4Hy*X7mBi+UUOi5{CKRgr$aUp(UJB(qZiXV@3@Fk^VngD{JIRg4Y ztur`H3}$ z*_2@n_&3t#q}6xj&;Q=o)yH+BHcPu-zuid)=z`vW9@Za8@@+zdnx`X>WIrwGG5qvr zNip>9vDgrvYKu#d5Z*)n@lzDEcR7b$S^0MGCe_tXy=b2!TMu!+?N(Ob4wz)lQLV(M z-cl}i2}xhq#u2+&Qj^ZhwqP~nD;3yV>sr0SdTl%nx_()D(S*M3E>WHli%so&6BFgk4241YD~U5Kic^WULR zdJ-j@!1e zir8T)5HanZ+n-~sl~3oOuGRIMYCJ?;LWhU%x*UJs>xa^=AA98H`Rbzj#|5(t;9Qkl zDPGpR^}d}ebT%22Ij5kgM#5)LRM6?`X12P;`exS0*ke6jPB*Yxb5BeO`EC=0VUBh9 z%y@#usI=qJawUfCo$ABmT}*i0_B>GxS3N@AWGjv>Z40Hbq1dd)yjph%h|pEw>bIA~ z+H#uaJL6tbObF^5q-nHA-)-Q}4A?1%+8(F#QX0__gnh<&4rj3FZ z!)Fo|yL=nhRkz5?ki89O`yC=JbOMd=h`45wfmgrsGq)?w(-i}`A(73OaYHoLMAYH- zwvxivO?J3#(W-lW{6QS@cBvAW zAHCy0Px323KW=i?PB{?Dr>|DJlk_M&_2#MCFLomN_jH)iGmy7zo)A;{ z`cbtLU_uP-omO2DSgW>dNM$KQisBz#qU)fA_H?TPEkMN(%dv5?V1~4Zua}?LIIOo< zYUSa->n8+p9Nt>>6O7v9Y^cGHkCnLCApt|E_wZCd;1G#0%FmKpML`pkWKuLR7Y< zd(CoDSV)yEYmz{^Niyr&mWIl_)M%yYA-3X3LIeFQk3*O)$0sC;hrsLRjI4Cism-PwsnBDl6Z4YX8lWC3AzCz-c&G`FH(_KI1stxM znxPX%dmX)7Xaw9H*siHT;%Wii%w93hwn%+gT`gt&5 zh&u+!HAposwc%{P?jv#>l$uNuuPMR^>d_uNyNV>ZI;-G>u31h=@H*Esl*r~E6a{0KT zr^EZ4LzvyYEiS#VgK&mXtTB1$uoNWUc4DXNR=j9K@gb6a?4c`-vBObk$e94FDVw!^ zmGw+f7Z%�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

1pJS->HX$MLyKpd*eC5E)CZx&u_ zptI#?WqT}7$=J^fNzXUB%`8PPPAzYs?U@k;F;-3&Iv84emSr0!kUk9BjJVooi_Qr& zh_AHwKa3wVrm^PjhD4soD?MuDO^z49a|IL)N*IlAU|Q9=^{ODwkJWa-_r|y3q3s~v zRu|OdO2ZY9!3aP`;7@T6Mtgj0XI-Q7dirrUi75!|Rl8rMnD}P8&dcZ^PuMbOD{a#) zRoY8Ht~F<_PBl38>7~H>HG3#gvnE=CS~ukLmZb+{j#?>G4wB-0=A6x#kEtS@9Au41 zt+8ow;lg?c*-bpK^|MFAU^C6(7kt5hh6n-TP0P-Q>mCCUH5ZQ{!;E)s9NX%rpOcgw zad>=Am@MjBhL=u616YyO-PeJ~T_R*u^HGoy@}q!#GopwK!B9Fa-pH11gi`%%W&2Rk z&C)H{7<3*9G;W+1=2EZ5Pws0ruNinr7sc>oT4Vfmas8^fg_r_LXRSEG0|HA4AZJFW z#Y8C&?wyBjd60pnd0HM)oIUCx-}~g`od)bz5nrBQMuKc0;<0ECC=Uct?N<5|t4sk- zJY?rd5TU&D&Js zn%8G3oH!(9jRSlTz#J3=)mQz4r|#BUN*9(8z4BeK`}-9pP> z#YQp?D{%|2?0TzzmTVHrhc{ZQyt>-)vpU!kLbnRNm}7soshoH}H6e=WgWzmiye zfU)%*jpYw3Qj~HBy(hb*#x<%#3c6askV<1+v|_Kf+GA$<%i!a1d=aAHMQ#$jl)N7k zn!>BzWLsh^h9+7Q7=E(Gt?w-&ZUst_VIF~M*cF@~6L&B}V#(*mXt#)9Z&rUGN#7!HJJ^7;pAcq83_@}1no+4}(UBP(@b z8JtsmO!;>EyurZHp}@s&X}y_{#j^n$*k&pNf)y3Rw`(Wgol$&mtS+3kdwB_0te^&h z=_UbEc7F3BUe~AHP9^wnPG%^`16d=4U6MFX{o8)lwfQmZzrTD$K9qXw!1Z*L_5Bt7 zD_2fLkBaQu>=VS29DK>#!R<8hL-_=|VOQExe0hf#D+6|*8#vIqVQdo2^-7G=u!CDJ zuEJi6jRn6_<8Y>lC5&m*qvpkMOewG9c$6M>m*!xLl>P&*oLqA?1O= zU-c+?nTIHvSclD_c1W4cz?&=M#3pHa+Iyk(yAOA1tgaIf*U3**s!o0(TqbsUKRGje z*sAF^$RaPSw*$r=J)k|A$IeN@t*OGhEg-9)Y`xJ~%m`);$#3=Ya@hXd8u5sGtz|Jk zL=t4Y+cVZ4W|MT%$xM@T-gV|A)cWP^3Sp>mHu%Fvdq0)8j7qCViU}Lf7u88 zl-DUA;LLkX;-diLWUo^fpNId@L%|%hS~1&a1tg!$-TMd=q+RgIH`Bii$FeMXxQ<5+!7qi_Nj-C)L-s@;lr`{WboM7t)_O_MY3dAMg zIP5NrwFb3*xqHnxjh}i4>}qi2T$UeElX3-wE#D~DdYGQ=>WrSDd?-TMvl>+|^C>d2 zr_OY~b>3p7%Hae*_m{c;6P37d!>5X$(WT3QJ7FD_yD8;L8gf*qUQa(8-)1*h)ObX( z&75ho-VM^P-u#plV?C1I@XQ)>#~&7Jr#MYM87LCF?bK`&dq$sPKiNCpPv&CRVB}S& zvfn7oSoy(XGWBR%fA1W7vJ7?ke%BDmQ09}Ma;;Y7d2Z?@7m1bS-Z4y4y*(8HcO-c{ z8^rj^SBuCD37Pg_gu*bf)z7;R&Kvj@Z>};ev!q)+4+e7P0b|X2C zw#N1RdOGT-QwAyYe3s=7k`_d^m!>Wz`cE)lRTv{Uak??SGrM5gP2G}yIYsk-=Gcm! z&G8*>G_+wMgKTY6e{WoYOzn}cdPoKmc zMBh;HF3pt;TSTiOt4JKngy1nGbx%6QhB&b6w9|`n4|`P@er{k*xm4qpN}ZNfuu9N) z*XZXXt-yz4{sHyHP*$iK!t`ir9}9&kTH?5(*BsC(ne3iuG+=Y{LUkwi*YX5kf+&PJ ztji`(SB!1B$ne|@xT+d8m%WKjDfZI3RIX(**QkL9KnkNrHUj8hH2$$!pY7X6+Tjg; zYGdPSoutt11DB!Y7FOmyryDo*3I`2)ReeEzQy;rC0!?n9n=O7kit~gqQBP*K@{yyA z1AL$i{jKUOq0mmtG)rWa=oB880~Tkon$iLMR=S4d`Z!tmE>X&84d(8(f{9(7`p8j| zdRrAmk;xLxj)Vsif4=+E8HK=0)4F!E7lWi+nSU_vguSvw%h*p&?(?txz;~6>XtONx z0M|HFFgL$Ft%@m$0U9>%$zdFg6hR##diUN|D|KR4|8Z91>;CcO?Xp$v_Jm{>;FS4v z`f>rxuPeueB-YkpZ~~9zmHP@F;*Fza@HU}9`0g=A>YiwT4-B4ATQt&L^cW+UK_dl= zdjob^9Fwf}b^TBj0)@bjhbKe{{yx31D`t5avj7;IS^)qaGc|6IeAwz89%Vjh)Hzmr z^#_RzBQaETo_E>Mcm`KuBCElo1<8RD35Jh?i8JYxiyj;cK^apMrsrO97Su|Nv#YB%sWRad~ejX#^d{3E2Wts8MIAKo7FfsT` zwXz{q9FYXWKlxz7(2M51fC#yKBL4I{%UY9(IHIz}(gal=@_P?%fCIzxUGOX5&t25y zVo{4)wEc@=p(nAb%DT_|or6^B)Djd%18=Qe#HRu?^E?TAv99!;lI!{vtP&oq<)4=) zpMat1Tb45th>6BVe!J0KJ&MRN&$7R~1~OT{!i4rHGGC+B-f!d+K*rc8voh(EXh{&W zjd)LD-TCl(Z_-;SxhxcA12Zvq9tF?Zi49e>%%`mipu0OBR%NSuzCUPwtqk-iw*(hD zogL&z-7_A9*0>o}t=o~7Am81|%P_51wN)0QYGQ^DHn9~QQEfKE-d7#Mai5Q{i^h@D z-F!@4-}sWgpuihZesYib@&-{ZtH>+sb(vi^6CwuoJVb&L^3TK%24(R60Qy=FM9VX$bIchZMERf~++QXP> z3iV^E(AMgqw_H1Sbq&%apv=29IN#|hLC|7Muc4LB-E(tyZd*e@X!bdnC9 zsJ%w9i-039!jh4$O_w1vN+I*A1v>2M_GDw4zPO&3*-FKk2re)!sVXGhr4=b>Q4+i# z6buf^<)rHQ=3`8R#3DMS?A5{qESI+_hm<@LEyP#Yg;%%&TGvx6%` z@s^!WflHr8PfF;I>sspi*&$`Ewpi2#m8C`aS%&s?Dz%IdD6*LhU7Q7M!AZ@tQP}i` zx7fbkRduP*&xOlMdM8!4#~g0c3FX>B*{MIB23YN|FKeRntEsFe%b(I@!NrKY{lv+3 z30*CY>)t8R%Tj}1%#v?f-*(e_6pTx}C57i$4CF?tQFp?RnHLNs0N(9>NSWmr$%aWO zL9X8Jjh>A~#UB-GuGAZY$l^Btwbz8(U;N1U^u-<{xrSiB{Bp}^5!V$41?8NKEtZp`O$dEJnln^wHaaWONGiNE777a zy!0{I_k%}gioxobny|*Ct;@=+K|OPviZbAA%Ct81S8BJ(BbaY4@f4YjEu}^T#B|Uh zcJM!iAZoCX-Xl%Ci${!S)>@6P%{uLP&yIiC6DN+OhA-#d?Kx@EQ)r#r!Rd@ z;U{c8%07He12g0&0}k_Gp~(#NMuyM=?+ye7%2xLFQRkQVw!;sWg`b;M?GyN(0mHUd z3;B)x4W!Fl*vN(!qA5qh_o7O`RXtwCkor%Abc+VHoIV9;-xE{(PT2h3B>KKBR%r62 zXP5knBn5u9R;Mf_3|XsekmuL=7RIk}Emf2K%c^|#cc~g}JXEYh1H>@+5`azIm--Mr zrsm_hapCfWt&;j96=`TiTaCt@A?jynlTC!u{KD}pT~Tj`9KnWVAI7#uBIlAP9 zzAWO$y-FnhHJ`d~5;27u00n$~@vD|w-U&-isRgnF0UDXXLi;Ji>X4)*mk&rL8Su_y zZzm0DmzL4K0CR*2ZN}ZgZkvHUrrse_%Vbz-4*qcOm|i2$Qj7VjBM@gq48z~M5L2qT zFv9JMI)f>keJ?Q4(MAiX%{#?C^4sM+{)T+DDmTi++T=hU~$qocUDH{Vld zWRq2xO(if8ma#DfYh`;*Xw5I+UEQeT=ll&!m$m-5~Av_?3 zp7DuqRYUk&Erp7&u9O}m(aeL#ja)q$5O}wE+8w~&`tOYh5}9%OL$rJO55j8P7^)~> zOP-1~gCC~OeiZm*qTJElC3+KinY%2t(*3%Y0iMRGL#7<(&M))et+raIndVhz<0S61 z!JkWx2(?+GdB@ICeHCR7oL_wnAD!dI*JP{i%hV@hG9b_vqdJ`6PKK4`zpyOwjGRVU z>|zhstGCJ$4Qlb!S_AC@)D|8^Cpj#kSoCJ}9Y3f|;t)qLc2-xw7RA@_*lTfTiNt=g z!}3$Vz!O?HeHg6G@S}+Q}-W7c!a^65@XUzm4~||vFtIp?ZXMj45zo; zq`em{+xM-~L$7d1p6UJQMs1V7Pf_&M>M{n(hDhx(tMB{EukQTLd9FTIOqB6_TM`wa z8&=gq38J0`4>|1B>kk7;qpVzMY}U*;w29)KEe?R>rPmw)Uk7W=iL)$Bm$-DO_20MBMXglnyF;+2ucE<-+gzFF~QzG zBnc@62l_7shSB1CY=lx`^O@#;bTJGA<3p`)R1e}ke<$!`d@(TQ$Ysx1jw7%#@d9@ICt z#Sez`Uf~?dzy99t`h1g1CH{KELc#kwS#);P(>j*h<1}zlYu}xQTQy9Ek@@CI#~_NX z_Sf1(q@jf;dOoR|$1Ov3v}imxL$xQDQKaK-r~kMdT6q@W=t$}bahF2Huh>*0Sjxbp zTUba?(3Nx)Or>oHkrZ=t>r;CH2S>0UVl|2Mb+TDP6oXN2UgiA{*pDO2l4b-o4P@L4 zkQs)^7dx?Hm#w1F6!i`(bzaO3A}6yJy=CI*8^^mm^+<{J6gY4U4I5wjHJzsfcSW=E z-ngHT2(3|xq>wbJsY94?4D30!Ch{F-!#(frNV=OnG-;2Y5c_y2Tk0%NpiWnaKKwdL z74u{`Pm>vs{PeCS$zhotxX@=cAjXE@Mt<`mryA8_>8sqNk|V*}wc(Ssj4YZ&9SV*V$As#+ApI`ZM{Hcd0z+o4ET6*XBl6^}@z5Z0}Sz!pTsbcV1+ci4~!;vL(q zul#P3dhlPq+AfjQPxTy3mOF29J#+)<*QlcJoTzPgvBlB`=w{kNQN*$UCn|(%Sb9 z3%*}LYL(aTvf{9pAJn+SS68v4*+N7!xOzC38c%4RTIQvMIghgIZ-r zJoO&B-y@HGcx$V$qqvItVme*$)k%G$Gcp}%wv#&gxUcUBptrhg9?3lNt`2b&ad1+j z)Nf$krqSehpJa6>#i4c+NBnw%C^o?Ul%~y7f_uE}7n>CO=8b>HjCyeKY7PT3fhViJ zZ(`cs`Kb!AZNUo5QYk;8*8oZR6Y7&(3H#dn_c&8cNZ{9+sbrsbrbp(hA3T@irg+14QEeqBnCHob;>ZUMBPryfr}dwg9av%sH~ z4DIK!Xe9G6`Gr+ztDY4gm^-FCi_*UVx1kgb(RVgT5kVOTg8g~65a)hg#`HFVWV1@} z?pTdNoy5@5fVa>cY;fnekIEZ2KKaBS>S?V-AEU%d8bgW45gnOaBA^{pL>TxF^HT#s_d)>IUCbuu9* z0k3hm)hWcunBAkuD?O~N2;xXb(Gsv*;+Cn1(~jhExGepIVJWyDWz+PRN%1j zvFh7k!#u-_ddPv*t@!+h6x%T zdlMUz!}6-CZjR0aX|rV0!c?q_VJ8ApE$i$`XJ^Eu4%%&8I3dJXZrFyk{je3|Yd9|4 z@^F@_F=b#H+eSX*FHC5xa8%k9t0!bzWsl`{P~8Ka#N1!5eo7?8Oa)*?c$N>F5mc;` zQeF&0X%v2pva7iv4Q8Q>Q>W^XbE`0SI{;thUA+xEVik`V`(8(uLL2lcpdfgIN3@3& zii^YY`Pzf*3~du#;mcNl{yQ7HH;w{dsTdZWJv-W&?`abp;ir`0&!?D+-pq;nmVy0l${vyM6u_;cD$ zsr}azh-y~kI)r#>bB;6PkPT}=OgXZW+#2LxrFb0M8-|Q8ImmI@c-9(3DN`7l)Edfc zfu9w-HNI(=(8%3R)PB@km4x50&hWaoYCHx&_93xhb2#u@eK+!$+({_rySXHqw2x)g zqt#i6w{&nq@vIo|NRX#b(JO`0^bdfq#drD2{BcZqa`;$~Oh~mVmqMMsqH+>%{9QA= zPb$nL9(SQ+CM`;g&C|5CO*RwSLCI53oELPH1Bzw5fv7cyO2GT8%i76X?nG%OpHE~l z!;C=Wx^?*CWo@sr7#z6CcZC(1P6PYHa8UTt#>NaZeJ!chw)INaVH9B@*y2m&A>&Ey zerP!tHNQSKsn1)?UUCzK62-wCJKI_gc)8?_`a9v5DAVe}We0o#e@7PWiX@@sdA-!S z>aQhb@wFyw7cvagr_AlS+I{2cBfOiwr2*tk`ZM1#+o8LUYy{`HJrX~ ziOKlbg^{($a}JKnc`D5?azb6Z@Kk|ufftW%u_=zC#+vRhTDw(oGvPV&D-1{(cfO_`vc`EU zt2OE=T|ud3nX(#WZYexkUZGX4OlEj%D6l4dTcs5Uf4rnp9=};9(@^9Mx2fAeg$Rzi z9*6Ve;r;f^g}58csn#ipM7s+!zA}|_Y1`Bg7D?X+wep_sE#nsxsVNTh2dom*7t6uN zwOPGZjS+PQ$aDv{`pN`pqNQiPWM)ZpFR^ul(I&{tepLcyD6h$*(G8h_@lW1WS+l>w zuWGll&bfEyZjG;}k4*NwMName%^%%>;RLsm%zGpa&EJ?hsHBlsunWR6CcHd2QTk~e z3^RE0V}anG+Qc9o$1&$jvC#xtS8qyUI@biN^p|C2f3;i;a**v(+}1UPrWo*LAz%VFiK4Fc`;=K=488agG0W!<26>Wbgsk<~*eN;o73B$4WA1n3 zPaO*4?bU4ChKUoCUY9F%{*{cC55%Q=_P3-b>42l$Ko^YAHT=a<=fyHdy8|j=g(A3i)K(A&@vQ89hL`+;Pg&4=MLMj>Q=WO)Fp1)1Jp)LOKt3k zzx8$rwOG@H3EV7SdOYS-CcG(uHS=6AO2Fg@9GcCb*qMR<8F*qonZ91JfPlpfv!q10 zFh6u^MUK;eiJuRT;hH<4%}Ksf_PskR@cDs;4?K*TMV=1z!$x*nC%S!3SG1%W^Gv3S zMk$1QeG6)c?@jnm0-S;G=(QYvv@!KvhnLXmcBXGmpJc>t#U6RSpC1P{kA?7u)ZIE; zJClColx$o@t4Oui^I6%#9TxR7Kc18RxE#ZHc}38#VfkH4vRRoLM{u)oWss*)MdNic z-6Iz?r!~>CO)T-~A=gTxrYXU`2|c_Jal-<{aD;_uq(pd=N2p#H+KYNc#S@)!hWi5= zj?6{=N@-58L@bBR6S3~24UzFZQN<2xm@d>h($8vg({a_@(# zaGmbL)eoeN85p2oQk<*p-l`}i8hx{9Qnin0 z!;p$yvFyU*RW6j`EM2j>NM%Z(QIT6sgXgsrDXH2BSR#(f$@c8V-#7{)U^YI+B1(OuJud^`gL(zldO&_DzmYnjzGSqP&95|F|XZ?V;l*_79#UY(TUxM|B5G5s68e#c&kP;O$)#X_uLj0HoM+v zsMvwk&8b~Z8@bl6KiuNE{cEviVC~NP1t0Y)8v)M9+R(w#-bn9t4!O0VjlMY?1Ardz zd;94VfKJiP)(Ai+t7r1ZUwb2KM*!pNVR-Tro|c7;g+mLDhvy%K{r>Vl3X`?BF;Fma1ZcdLC?xV) zxRI+PfKJ@%wRC~Mwt|0c#Q|CXIzbyt8+!#?Jp&`a@45;)FaQ|-s0`feJ|lpE^^c11 z@Brw9T^&Ug9Q7RkJW=%ZM8-dB{rjNEYsLS#fTH5-1z7&9y`tjl1=xP?!_g@!G65La z|M599fPv#5`z!#)-#7Q#9Eysp0LI@f_s2dPfbp+pQdDFIF#g#huQyGnDx+_1WbkKk z;#LfRze*FgVg&qI+t=G=0{l_#?>l7%{8g;D6${|6QpK%U0SteX3io;j8-U@jQpK&< z0k4hxM-9ZSH~8L(Tl;r$|7h($AMHOXM5o}S@A${V{-eDCbSh?sj-~*X*DKPA z8JU@wI{vvY{`!#ZZEY-nx22=KlhJEa|L>>3_}A?yNb5OR02u$eBLOo<2U#O~K^rSu z8|&Xah#f#DWn^vgdU+;h7N*w+U}pJxQ8+r0-&YkfGO#f;`d#P0dZjD)=>!8f7#LW0 z_H&5|w0AI{UZ)TE8)yVfdR@>Cs1ZOt0Ym|a0uTit3P2QqC;(9aq5wnzh=PBXf;(tv ze;9`ET4+KyPwEud_k#^g$GWC;(9aq5wnzhyoA=APPVf{H=uiE$aSt z67sK+w;%}#l8~U78z|-mq5wnzhyoA=APPVffG7Y_0HWaEn1a8RkiSLUzf3|h{WVP# zBq9Hey9y}g28y|XVs0P`Koo!|08s#<07Lx2pTsy@&j3ffta51ZhZ6)D0AM15p5? z07LKPaT=!A@%%?yl0?e*N?=)|oZjqGi0 zEcG0X0FL%fuSfqMq$2|ZD;t1L#LV*bJFnZ{UlKAhurV|O@bJJnINBTOS;4u2pH47< zgMoo{XFr$hTfGhD(*vy<`p>Q!3bKzN`v|g+|1Apce8KU(xqAQWLc5Ir{4z-(V+x8z zgW`*zH!}Y*6#Tt0{pS}902$N&m~Qmn`T+->4DxyZNBX>fZ%qIB)VUyI3Nof3&lKdD z{>M=8x5o63%;5jrxEqi${g3HJAZHWgZ2pgQHvd~4`|pkEKc7qmWK2QE6y%wLJk$Re z3jW@h{`0enLB{kyrW^gYe!xK|gWTBvk#6kY8`FP&dJV{!f{ZE1GX;63|1lK&y)peg zdk_>e1&vn)jaPjGawPvpI+FjNE2O_Qri}m9m@L&D(=V5;$ z%Jy~12?_76hFid%m$O{1r9SnmtuO93&M%srd(O9j$^P<#>~>TI_hHUaMLj$2(nLlX z?zx4)LF`tBpG)rC6-5_U4S%#}K$o-62crF!$meL&zpb3=IY+ zJj?pYixguQB3_}k7mM))a_B07f-#VR5j_Vsw~TPRr_%DKXpagwn4CnqlY^}`hSkcP z84i?POC{ON3x~|nOeWbd$@}uws7+Bk6>RsGe0usWT?&jIHAQD+pESoZgi#n3>n!9a z1Q<+w4@ay0`>=Zs(@ZeeLX(|P$PjV;LZta*v)zLMS-Tq+Y^+)>a3vob~npp&H-RQp}^|a(l7A>Ewy8Nwh+kR!%j{t9l*0JXsHg^ z9<%&xhB^W{Zc~QO9+kNYF?fB6#L<|Hgm(*z3MGX`MiAa7jT=7QBED>Qa+r+{ey2{) z>cqGRI8c&1h==tLF$D&E@>PwdHH7o`p564uWF>ox<&|N9YU-o|<{7{t+a&&Wz=j)4 zkmwDuHLp8_=dlJN1KdD+t7&;mr9%{>`}6(-KD=hA^`;a*p~Bt`LX@FBNiH>3-nzeK z7X)(jTgPlTW?x!*2x{GTxIRp_Z`J@{{yt)eZxY|oib0t1LDul|EP%oBGc15Re>JxS zoAGs@fc)&oY74CisnYq*79PPzln*YjOOhUZ&DRXZ?*}4UF8{Y^^!yJg0&|Es>M(AC z{Icw*Z+Znoq7h^H?k7l#F)6=(%Mq02z9MqOZh_JI`jGv00>BLY1n%jNlngPg_ih2K z!Dq3G3l~PTdw4_06)pWOM(6UTL=!sC`^IjJO`IQK)B!r(aWH%XFmEPBRAF!~gao2h ziNTQwEMf@rAxeZ(qu=M_G)IWV*zLT54$9F>#zgPK+740+-_%#uo70z|pG`JMR+hrp zV>L!(^1b&f(4Va?R3$6pb%td{N{gWBQPz#p)u>9UezTx=!iD?3zY}W<*Vd~EQrd zTM{cGV#DmiJozJaGt2oF%QzASBD(cx>QhulF7UUCdFhPq6fkf($vooF0W(q+>2V0m0=j77q6k_U-Q{Ctv2k`8SanGS)s#B<@VCJ4DM zzAgpdyej1!kB0Q^`w{n19Cj*pJ2n=!5_S@E9}8Bhb?RX1 zZt6aBf1Rm1d_AQ4uKIqxHhn_M*@&VsNo^QMPI<*?5zQn|{%R?Axj}KQs!87G+A$QZ zSXvD>{zlD41s4GsNjg@~r$0(GCsoq0R}wl5QA(T32ySXikS-re5Br z0nxXZ(n-oZ^*pXVc7q1H&C^`u&8 z8F=;wnr|D_juo!%)t8shtUGs{dUB;|Rjr}}KLf{a-ro>Dl0GuLBOy@xzGpe8j$Uk5$j=0{7xm(<9Xf$qzB2Vg2z%ar@Zg@Y=yil`1hRm5s5t z`se27MLe85Av_U0DDBSerJi(mdQT8f&JU}X^FQ_<<{xDs*&)kd58(14MIe>m^1w5~ zB11Vre(wVB0{Y?8P3aJ8&Y(jG{1S8y_yo&>poR9}fJsZuTt<50)}-X><>~@Sqc1EZ z*aH-c8kiao4U0gRM0XJx6zvtB6_pnD5Ka=7Oj4y*tKAU^R}Tjia--wppm`8G+n3x< ztx5)MpKQTxpV2aDCf1%T+1Kxu43Aet>vXBvQR3m?e_Tg=2|?*D*_Eoe(rI?tg`AHA z20g~^_fhRfTxi`H{fdE1@~`oq6iVvR3Na9`5JwZ=hLGW}-*BqY`RTh;5+5C(N5NDw zSu$$oUw2nGEkL3dT1BPB#7)*l_nkS9Ua)1zZ1zkEC6{k9MvB})%@~**`7CuU7EYW- z@>LDK*1TrTMARs2NNxma?`kJ?$9nkV;N{?>7mG2Ai<3#a^K;;@E|xQk_vHa|6`IS< zpIx-NS~joSkE5&rR$_}khDC-WjBwViL)T{HvgNAUbxmu}_xc2y1>`o{XvQ?&TlQL_ zS)Q&M*Or?vClP8-Uh5BUg>K1^ti&F#t9h#2ua4aKpSBg;6g;|YIK#NCtRA*ps;20x zX)jJxY-pA5j{MC1*$7lQX;;?Mu+#lu7G)S!$5>p`CQ)fFI$LyiDmAcn<yd8lrp0qN@+AZ3O&IjU8Ew1A zi}nilq37Du`$go1}EFOWN0T1sNI{umBVn%)lRpm=V$O_(gr@^X1>GtnRH z`C&16oWd)yR@~0+%Km z*H2ecE91TOTmQ?)|2kWW;U8YC27pdnP*6b6!N?Hshqo#Z(E4BA>;E}F^)rCs|Hga$ zJ=^quxvxx2>@5H9?rVX{TTKO(WnQ*hq&V;Tl&F$==+>H};EIRkig zMoKC&ycfo_GLZqCi5Ut*Dzv$Y0G-|_opIR1{k<2xr>3VyHoc%~_6L$iO3b%lU$-8& zHRoGXV5vc33O0nJW__PXKO9K|_sM=|C?(5{qH&1? zM5-_mq89qGL4DsR0o=(jX@yMGiiNZzBkuDX`oS!%4wz)Y{a5u<2uhlQ7iB`{GaYJVMBwVnu3jDFLK>tK{ zq9>cwGa1WmdFowJb@zQYGwkhaFAl0|vLmp^W|->l}!@DsC9L-ZzKD7Id)Ycr)A6Ty=v)MNh%vyIEaV0gnuxbsCi zf{H03c9XeYfx%4DvD~0xrMWXARO1`t0`s678CBJ|ckBCpfMm9@ z8Dl;#LH3*4xh;^AXz^Jeqp5)b`|IKyexh^XcK)y%HroAMgJjQBY8 zlZFEJsb?}Q6yZuXhIGtZOcq3}P@0*B3p1Mno={#tQ8ydgVS1k>XC!NTgQS zDQQkDd}ah{qvK)Fp$j0Sp|_N_$5xI5sOEMPHg9ve@d9B^Yt-nNL%$&k_Wi7*qD;eG`& z6w;NW?SwEYA^Ai@&daie8emZdt?j#e zk*NiFeDdsuy&O40;}*!)Lt~B01Cr!!qdJB~Ot>4e)btVv4QW0Vck;1rOW?S)K%D$;T7T)?~?Hq!z*3_ zj=E8G3i7AV7GW*Y0so$T0I7g$XZ(+A@a*9bLpdm;QkGKKC$YGr2BR>e?4zcmiP7oN zHPLl4)zLyFV&)~23~3r^Q?&fFqLrJK&z0Ym(v=&PvTB@_9F@7MJ$3IQ^71n>Gm^gy zRy50RGz3fhCBMSL!^3kV5+yn%3Pxe$AmdnZ zk=PAb-Lq=t7*zZ9hO5mvnCqDHtShZHZCuzat?a465O2iZFh|Hd#^1!yWHl0 z&u0sdmrw0J8$K&OduRHKc=KxudBu5!hSi2u0eXE?Ae{BA`?$xr)ofg5PD}eW1z99x zN>=UD^$WLu4(N)UC4?nJifD_#C2}MjUmt^w%q0F4++_By?=CQJHz;vKw-!k(Ut=`-2=NsqS^2>RHc@Tip zj{$*e7~zRY!Bo_Gr$?mAXi0KUXE(C8!7-+3+cx%|a2cQ6rQN99J`Y?0w^g@wypX$a zU$tKa=fLDpwV$+m-q>zYZ+L3O*l?(~Z~JX->6l^DwtQW#U)Phwzt+3#pZE0}3L!!$ zq65(#k#lru)Hh)cr_cQpLo&K3qG-Hf^{x?ZWMWDBvUvqq$-1&JrhTY)>Nh366LzF> z+&EXVwbIYN*|Pmqe$fQOfwo9hojWgZz`qre1Gm@a>%ilXArR%;j`w``G0^#_9#H!NtRmHN^w~}JExuV z&U`VoI8FK`nIQRO!k*?24XX;Sia|+uajo>#9}eTqU~8-;xy51Y8Q|k%>f`(40I*3hT2)_tD7xxmSp5yKCz-&OX!w z=WQNrFyI34TO{BB_uxqGXPP~$NBdjbw&`6gs1R4Vk4vjt`;(8C)Ytd9DtkS9hnvVn z)fMTO`JUxohny!Fe`3S$;q&mbN`=b0q}jIiX8Xw%%1pWO9jw~OLfEx{@Kbe@#4|B~ z;f4X0y7HF~Kco5XfytGLw6kQC=|p4lSc!3o;T+Y!htsw+?et$X7Y6;>^`<1PPP2op z;;S*Vm{0VGhTWD?=gHX=f@w`tYpFkP+UJ%v7#0{YbcDYNzu$UgEJ~{HS5^8-w)%*B zkprBqH-^psruWpLs(oqA)Yew`w`KQzjxp}^Zoi&HU}VuT)I92S*kjnInXSyM1XaCM zFBqtH{#)3ru>HH*u&Q43;rey?gk?jyVz-yyDcoCNYx+3)PoCqihP_Xlc5_FQhs;&b zuTtG~d+!$Y`lrp-eEYbqnO055fRD7-sx96@Pqvkfm6gllEBej1i`rEED?{Ia9VJH< zL;asMhl%T2ei+|b4lj1LOZJ^E7b5dKKf}FmoR2y`w0n8iBH5#Oa7d_1q{5K<5XIh^ z*XMr)<)ZcxJxHAXmLEImWSx?gf9gw| z6ZCI;=I@JM5+oUY4D8Nt&$#YW#uOzPybWwRFWo!dqUX|9t5WK6+cCYa9-k5~1h@Bh z+t+cHyq_%YXSUibw$D3%weR>+z05vziF-y|{|b-!y#ihX#f~ITwEAWH*@x)n?LlyZ z2)usfzB~0zcumOtR=J((%8fQ;_pkA`yK664>v_>K)Y?megrC$HHTK%8u^?z1p{J#n+|G(r6 zCo?k>>;KhPIh-?P_n5DygC?#Vm- z-PHTt1;r8tN)AQJw6ozpJ?Uz(@-jE~bN7~)CwOVd5OMV7@Ba#H6zs!SXgl4yeswuY zm8*}&r!@6dWioKc#PO`_<6j0nd|%P+Pm?b z`}y9A{h2?OnmV$6;gf$BoF6_AxI}{5+1Sbf{Ur1`XvTTiYdk>O` zVEgmdc==#Ur^(CP)s#P*QNSQLfA(ru6tScKpN%AOgfE`9bV!F8KL=f34~~6DWjj;9 z+xBj*N3Jd$Gj^t~x&;mL>c&2%o}74M0{h`dp}>hZz|tT8v{0OkX}9> zB987(I`^*P=L}ug4E?>mb_E08{+|B4e~#3Bzc30tKVSu13hsTrBYhpL?fo1|zpm|p zy*kbret$jG^-gQ|GKepCe?R}|tOMO<25W^+zb8@a7{|VzMh6ub+js+h%#43-ZLwSe zz7N|zeb@N|?p9jksg$319t`{9zurFSgJ<=}-f#e-Z`0ogodMi=bsrx~zJRZ7S7o!+;+Iyr263z?WiP+tpT* z>(8rSyP3|napT1|fJNZ)r7h#*+b7q4kF)cYar*rL5%ja@hp_SM^LwXX5b;y-;b!gO zhNuAVOFW}R!GeB#9;=xbUF=J@z+P_a|LDQdSN6~Q(FZ^?Bo?rGo zkA?Urx}EGN+Uf^m;hQcPX)P~|LGhH>C4f$UHy0`5XzFX0nRy6!;v>M&*=^?qA3)f@ z?5JJ#(|doKaFhTA>cN#uN_DM2_Vwl^*sWKG|DW4)_!(r$$PRQzH!}Rhyo7iC#Ll{P zk{AQG?8mWh1OjBU6(>ubcqRnAO#DuQ=atZC! zb$c=;pR`!a$tG7+^f%J(Q_ejU*+*9=KHcW-n$2uJFJI^1(5@kW_j>OqErBeQ5mwos z80<<{2e24L=Z=gS7dQ$&5r6u=9*DkgpEQ+V&-Tj&Y(J1M4I9{CjtCA>^cTb#aqo#T7K9?tIbx*f$rK6X=I zfld+F4A4(Uz)zPBeH8hG@*f<)sISUU{SaHX@1`A|_0x6pUg7)Lrc8mu<*1!28lY`w z>aJT-RmfOSY}c{vZEcR5{E0U3#n{oT6cBrvFRU@FVe|N0&{vJQ}{x!$JISLxJ9j)0@?M z=Z&*EmE$q%Z79m!17Ydutxu}$9$rGo2gCUFQT(Bgx4t)x6nu;KccebAcX|gOp?<=d zLokk%&(NyIKBI<45IOSVORC^YRhsvWkDp;Ot|P;PEb8IRZ>KlV4B!CSD{yOX<$XPL z;_2IEon(PWkYj*%HXJix^y-G(y}pn6?b~OBK90VN&=AooRWbhObo2Y7IAZ7N#EnPB zRW2Gdz}NTK@N>tK*{_0r@N((*phd=zeEgUy*A+uv+)chu*KIOtk5~HX zkOO!1WN{V3G0xZfrhnS!XDd*~xgVeuj|ZVH#8wU2lP4iYGXA|hi;3HLbN~*Vc0ofF zet@7r_CnZa{dTTq)jz>6I+|id5q7Df476_|*^Wlvo)XV@>fHS~>?TEjp zuTktA%Zp%6O1X4R%GBMbOStRqBR(_4^bn zsair)OID5n@`XLt!Y3DzyPL=AU6_mj-XXj)ivUuW37y+R|MA-|ZiE}f9!vT;pScY1 z;xES|enV(MNp-{gh9AM*hdY0~o44TLfd_3HKerv-w)>{xaViOcij<`*8-rt1m|ouA z6YBO?sLR5+4APr8Ke5NF=$fs!gf=3j$^?mTO7Usm{yzX6E{~pxn5J>)OnL){et7D3{@{DA{@{NLw_} z_@P)&O5FLBz$Wr9rfJBmj?G^+*B*N)T3?i+zpzUWul_W!a24cST*0TeV%Q}*P)uzb zHFa1*&I!3)IJ9jD2>e{Xan=<@L5Os(4Gh}(7}>Jn<-BmBlHEAB6+AdE1>kr_#Szro zVP5xoW4fuX{emZ&!w;uC4WES?51-{^T6=wDnzuVLZVf_*8C)Qjt3Q=P%HKzE>AhlI z4H9zuv+bdY`d8wq^Pc|#;{MJV2=1$eLDPcg@oooMd7=0G=gVG_4AsDxU+@%8r*!pc0NFTT3CiG7n4Q|NSx;27qNNfY}@4)-iA9IIFs zNd&m2fz(`Ygg;DY!t#!%Rztzp`i?c9L3ZUA(-a*EUhz#P0M(%9XDsU1H#Pv~@h>*) zD&fVHc$}cnJi2b{02t`#(q;Mu8Hj|y4_)K}vKA>Jr8N#UeiwU6bL_8+><=z7{q9m~ zKwN{!iQ1q&nD!6YCdmTZQH}{qVorJN6U4uHBb7;7kM|bLMv7sD$5M6rJV=Fb+{Ci*!;x_}FGr_8V=OTGh51zm84CE!Tc`oe0mF+Q96$~TBWga}4o(6e`|Tu+|4TdE4P1hd zlF5#%YzV8}+$r-whED+bJDtN4aQ!H%>`vb;iQvJ(sNww*GQjP!N5)yj{ZUt`W*89bv7wFq4cqwWc0Z!gQrS4QV z9ON(M=wAC3`M3J(iZ#ao!P*+deJk(ELx@pGMTAQtY8o2#;unvioo%`kkOrCYs_;58 z@sW&x^jxdmY|a1jaaK!d3j)@~jm09DxoYVX8O)ym1|9h)+aD%4vU|s2HZwE!7#5K3 z=J`SQ@E_rDP=+S}af*)JA%aDL*i4-rzwAIPi8d_~*<h`JoWH8mU zko0;9crFq$?u{imW_Hr3YP>i}^56tSIJBV`4oRcDToTaEG)RBl_6s?xS-9i#zwJ|~ ztq?yBLWomD$kD%>iC82kkF6MoGwfWM@hC2+$;Z>6yY6*~seZ7>VdTy66q>(kp&nH~ zcB+G?v|g-u5N977kVOWg4G=ZSl*aGe1Vf>?8n(_l@n%(Y2$Z3lMQrn1;Ji&a{D!*) z_T#dflqgPs(yCyx6GcqN8z0wSC~<8=snqD7%eDD61Wqr zU=GH&tPxC~p{*h|r86g(8)9U|3cfT4O9*$MVGB1Prk*Uv;alM0ZbcaA&QXVu!3Ahi z(TH~7E3J7vkF|bc|744wS$}4w!ee;nuS9s*0dY+!KqkIoGh;PPu68q5mjmPuoE;(3 zY9#>;{`N`U2+wmRtm>>FF$0t3E2|ZbfoSAsx{gJpLg!07ltB*KHZbnO`ORYnm!R!= z_Z$aFZ!M#jNLgweP1f$HpbLi}HAH4SgK?b`{%VlRU|5AJQw0cU434FnN(N*W{At>v z0(=|Y6iYB6;5C;MFnBuZufO2zpW1mJot=WF$F2+8jT<)0K_F%ZKB$3}PS8{?erHEA z)Y#HnJ!u)9OMp9>!V;N~T#T%Ijg<>Hr_vu}8)liA_E~oQz#!t%5P3%_aowGy$Dn*) z$SkT=ycUoBY+p!A5!QaSNTcbQdZ#2Ie~Mi0g})aLY^xZ*%>;|WTgtDf`Us!Z9wlBY z?bv5Rt+sej3k56@r-izR=O-;dh||dl$@SDAMfVuiKZ1%OTVhxoad`)tTc)=07G>$8 z?-~ytO6@X0kuq{bJm}F>vy;vd7Lc;A-T)wIV1Xwf*}YoA=*yMjN!WujZNKRWxkOY6DK_QN%*|mn{ICZaZj#Ux31_FmmVq@18F&FVVPJBte zB%n;*OX#6Tub=}XPhJ+f2)C(tFUY^~#f~C|BcO zFgQuthQEfIyrAp{PiH#L7el4m$5jHc@HmclRuXkKVieqkF|e#WVNpiUX5Ky9RZa+Z zTr}qrK9?6~F$m2lQ#W!REifD`D01;%;iL8!YVy3L-pfq{*J9*sw-1^N7s|xJsDd1X1Tf4gEioD~kkU?J1xXPW%)tX%>_B9lEPqTT zz%tND6rL3lH6XeN>gP^yv&G=e_cfp_`tkHc_LnuN95-SkFKw@6_g2wUs^t`jy(qjCW60aPjg zSvkp)>#jtVLw^876q&jx0}+2TWGAudnuuJtnHm7Mw<8*}wnK3ow#|yi2%oGkhW%DC z!(`?y5T+RvTQz5Gg278vPvGCu4P)s^K3(S2t|`QFkFh}}a@%|jPB(S%=8Z8fu`Z*K zpgQIq;_n?{zZECNiihlWBKF|RP7-_w0E5N3bmU7kh%b&^kuk%M+@uiZi2nspr&qQK zS$hNtFQroiZ)rL8Rtz{41`&1cse* z=ZKqyM?3gX=KNHC~hLxd@k*38bmwjYv!RKmA`EugZwumvvp(2^z0%uVnw zd1aPD8Ly2$uWodW`53l9| zeGa;jsOzM=J4DzC=dM+)8f&)AB(&_5B87OMSkm3J;%v<`lA3NFxOS{;+7h6ZPm%Nq z7MY;e3kiSs%EgQ=q)?j=8SVEqwy&1pjOZ92dQWCq_<7i6U6O_n<*uuypG_JV?Oh=7 zKeMkZERgw)_Be2PNg|aXe^X(Mr3CCawV*e)n20Qt3~NjQ>!gTY2uDt^^^ZoxD@n5n z&m80qN*3b2T`3C4?&Ep5_#Ti6Vwl+&d|ITF#^+EFbRY{MkZWRE;#Fm~EJ+x$3x#3E zjCVUPzQ{eD(o4T;%ek2B2}vbq;l6!({$H4uA;(%Z2r_^6hF&pt{-zlZO-RX(H;1IO z$_tTZhb73)^uOr|?pM&N`j}*juzD(zSo^ydeD9-Qvt=9dbbODC+$2fYSY-a>Y!0uF zqC&H0?CC&BVWoepU`JdLRi!L;mdBk+NNnhpAUz6%7%`P0F zIS~~zP<^r{p#us7=uDx)It4JDSdFTOQOhb z;3*$4r23S$wZ+OLTrb=t9cblG5 zODGGoN}1;3T*WGbQn?KF)xs@A2SY7A1kqGX>yoa?i2&);ST)e}_VgU$(Gj;{64@|b zeMw&DyFu21v`rD{(ndDu(Du*&BRur=g~-M8XKK#u&$fehj+BvFg%195h@h4sPDg{WBA?oN>A<+mql@)YJj|E`Z z*m?9)r!OQgh9b*CV=q?vd2qN%f(ZFm42+S#+qvLk4HkKz^jD%CiaK3` zSRHZI4xI5IyF?tK#l@5Tiz1Y^ip0{uNQm8|p*V|kK3*Lu{nOQE zrB!#F$2p{t*HIxHDD?PI;%{0h)Zef z!YVTxVBxFice_wGNQmN#T!@vOt2>A$0#J~BVmjQH@yFTZL83mGaHOw*VTS)UaKzROiq@i#VZVj>a>uP@` z!WO_s+wx()bC*L?n(&ilC8M~owJ)kmP!Y$*qhO(W%txV1DmLhfJy8Vl`zwXDV1=O* zV$9GGPTL*FWdEAFqJ^Q5RuGZ`JLSV^K0)nYZo&Ct`*RV?MqO;FfM?g0m9UsO8}U%p zy`O+Atrrk}@oildsV-g{7R-E1Nq zoa9hHx74q_te=R^(rIH5?oV!#4RZKkhsD%y$~sFD=xsXt2$dH90;E_?a@rzLRBlcrHllNBnvR%S9B4B5@bX& z`CFb-li;9}2{q@$+n<>bWd-j{YfFco9f&`KNg#n$#qZbu9wmwh@%+ zNZQR=ef5S51GIRW*OP?)DVed#6z+p=!C)mKeoIYaOV$s1PC=(c=tj(P zjftTBBT*=^+9upUzVyq1GYKzu$e$=MrgTIMwZX~ua5CdSgh$+mX~iDiv^qV@?___% zB3(wUi(9(W`ad~xck-ZNaaWG?q!XjjaOHzJhbg&;-;sSDBPiU<)K;L2fP&&18V)fz zr-WvXF|yF$oOFjv`EocIydgh>4;w~$LvyN9eG|P%Arm-$tF9%ujX3KRj&Lf;Tr{k6 zV3Us}S+3>!TGG76;Y#XhrjA-W!$ZPq3G!-wx-oN?SetSQrE;aYKG803@!yXbl~8Rp>i z*uZ!m*B3%UdE$g7Q4Jhq!}d2Ui9BGneFdCgQem*L7+m+EKw@h=xxs_XX~_Y_8i;9s zsHBG1x&kq@41wIrg*eQXglx7YC%FS?)i7R?f`YnB&r%6IFJJv~4_X)Jn8y>tDpg0- z7RoQvZI#iMT#LPE=LqLJW>UaMa@lr3uIf@e>wFc0h8xh6SH>0fUNFEt!NDC~Y9>{m zz%dD|@M2vQ|G^QC_}gCEMP>{pI+YXi(;93YrNRFk!`&BO6E{qzFg3K#GyzflOKKwT zPj=haZIaw?_XAXr>x9A`hv5Oe5`S;86sBegdHwkRJQabcaFo_A1Z?$7t1u^iC`GMZ z7ov{Snr1J^ycow?#6n}mmstnyKp=-?l!TJB7$ws6|EmzqlB=ce&C$;mtgIS*IXHy2LA@r1#51DE_|%%j9f z_`c|u(~GPBwW2KGN)z@ttf&!Ju!Lwec%x$nmAGMIBT7Q`x$tNEk1LYxEGgczBQLR9 z-m;=(+#-r#qJkId(}$k_BTXUAhJ|y;ty5PiB$p;TUii*sGQQ#{WT@{hAcxhZjatX2 zAnO)Ko)cCpnMRQudx3$klPHq}fDaThm??Ira6~dd=bF}Ql!)M9GY|v-!pi`)LHlMC zn%I$di-ByIiLmT1mu_mQ=k=y=S*lLo$G<`Hhq4jKgy|q+;8!68J(gUQ4Z)jCL_k_w z+riBvBg?i=THn>6gQ_1JN7ca9k!iCX=0yW6D{8a$S_D`eioAR++87)e-*7hLxNHCVju_P$38iL{0!g!cVOZj8sBD zz*n2223O)pA*hWPy{|YV*QJllUV}K1$4&wvpp>W6@447}oCkAHlv#ype5Ab_Y)KhV zp$}jrP5di|uwmeIt<@GuT~>IVv$WYRoJ_jT95qN1-+heV(MXMf{5M4z?Y=VMaDIQ{7JIYzm9R15^<{1 z)^BNm$FXiQiKn=Gnk*i`V3@8W z-P17fnv*W4Nf}oYV1kxnsntEv&#{tKwFaOEk4`Nlh7Hk{2R<^>Pr$Vt0gvyqF(qj_L!$8m;`aUKHZs{6iZI+5h zQ&woEVenbUwF+^RK->(>ajy?*p>5Pe-@?UbZ_(88&P&95CvuY!oy)|^akc<#W21Cs zH&hBYwqat7grLCK)`DXihYU>}mXhzj;6J)lxT-i~)jdbszvO4_QmWA`Rt*f)T0VF! zVdeY(?vhy78DXIW&!ECOodNuuurOj~%_Y_x@)s$1GQ7 zPy>w|n?^oqImE$Pakix<(zb~^rAh8FB85&@>NDbK*!CBgB#_ga+0%|Y5}hb@G{g1Y z#6zLAES$LbdZ+s6fkm}Zeei#7S6NX>-e;+3Q`{FllNQe+xJisbfN9VV9#M6m4YX3# zPEH0f(p9^h#p|(KJo@TvtoG31ZV-UX7)&E~D{NWtNQq*9UgVNShjmG2OP-4b((j;? zdk?1w%Tx^#!`tO8UbYR2baH^iHLY+DuLOiDF%iS5POc>s@KFUv8le~g*{#sMhTm09 zL>eDIlJ~RD2kV`DwGAIidpYY`I``>f(%I$#0y5U*T5lh%{t`)*Ro@sq4Ny+nY@EzS1s}@YjurN!yMjMH7*KSH3&qU5JDni$zF;EoQnfJ*Ba;?8oK8$vUe6t1LE5i8gHg6hg)VA70{ zNxd`jiFG*A8XH3+)NUR(|#sodd<(Z;eADouegA8n1mDqA+1^mr9hR4qQJoPY^ibl|KH-u^`{_itUvYh+Iq6Zxj2)7PNlA$>|L_eITKOWEY6Q|` z4tatH2aRMFDt1y}^l-VubD|PE3QkQ3S#Nj6Qyv|UF}jiy-p(a7x=l+PKhSt0HWVS_ z3x%ErkXPj=PS>PW0JyQ{>fD>Z1&JEM2yA!ZSxt||3>U%7`A-*)z#nSV!46rKQCd9; zD07-nkaLt6c_cO+w9Niqvn4nEsvEhZ&h)X&(C7q9~$5b%k*K zc9boZ%@Yu(gfuUM*0YGrld`ZiI<9jr8kh-3{f&Xx*DXXbR5I!Q>*%UhAS zBq7{nwze5-V^UCJY4v=+SCvvIc6vPt=V_rGp*j-cpT8ie8{~I?Mi5ZE#A_rGO_6T0 zo?HYR*Ua;WX}PH4XTwB!H|3UUYRj3XNPwdms(du1RV`yeyQhd|w21iI)oMon+!yCO zAHtldpecY-pLO=t)6N3#zZ$8E4sO&?(IMK@lsD-#sE&wl3r^!xeX-)NilBg4Y11S| zOuinIxuHw_-NtdVqcWW?<_eONEtCnY$NPToW`tB&lCA#gq5Y(*)?tiiQqU}F#u7Ti zA%+bAQsa5Vux~eInN|{`R|6A>K{#mwYM?{-p;0$g-heN&&MGn;@~^{RJLS-q^Z%fH z+ywZRIR3=IiyClji>3e{C2rO62hm<{+|aYiS-)J3u$6G&!8I|1W%Gw(!$p;$gVGlH zg|8~{A2V-s(SN~mF?v&pFz_5^ffwrA?Q71P;3m=f z(iMz0;?>YjpGR3W`xsCsus#F%=$W=UmQrxP4duh>UfT*qUOqt%9LA(B#>`@ZFg9K! zK$dNTod^P>@#R5PUm`?!IH5%Pl1k~|Csh|{G!?wo?V3)t1qAK_S>i}2`O2#oL&{K0 z`d&wRG5Uo3Tqc5;Kql4tnS#JVBG##Dl=!Db=swBYsLZO#^%6`}*Xd;(3yXXyh>LV( zll(gbPyOVQuND}QWVt$5@U_!|*glNWX%V$lMUI~zX0#Sa?MV4vk8RbXf~|l9e>TJYz5r00ldNG;!OY74f~=rZ9NrxRV8|GQJ0YQhi6)M_tFZ8r$t|P#--|ijj4(yf#G3*q_}WK5rjv{)JD4iuQfi)9Ik# zY|6Rw7iiJrVT3Oc9~j)B5OK2;H0y02;;)CHJx>0*KtT>YYIl|Z#KeIGROzycLRyHr z9y$XEDqd&9LgnfdkD2Z^E|1OYJtl`Dg4<>GDE{eSCu-q87SW66O?8WL}yLO2XZlr%tqGF{Yx^7-jb19cX4; zG^ik8{(!fjC?5p}BK_T7b~^@0YvX0ry1p?;dBb;!@%KmtE+4m%;d*Oc#)zqTUqknZ zxfrW`YUlAJZU0j`AP03+{j$^t0DZF%sV@@tBtYts5m+FiPk<1+KOebMycl;Xeo4l6 zXwID@t*!}TN5P|vN*I%v^l_$8T_wVYrF1*_7^}VzstW0EC7zs>5BM zn<@BjP@r?8Z}x5}5=Lmf&v86C3tk9abworK87g_K65V@LzmnwU@}FlAcTj_A>CY@L z3Ki;!)qYBYD7rL>VM{(5Y^VybNx5(egv4X7SU4l{G=6%c9ig1O;_|oWjv-4 z1r&8X7E&AV%0QH2HzW}=OJXg@>m7ewQK87c5b8m9oWj_?^pg^(=*Uc~4inpOx3vbA z;DYvIjSFZZ-&9c&I7ICAEDA1D6&Io_VTd3N22Kh^tF=N^FwC%l)QfN<{~U0jZb+L7 z+LZWyp@d>A!b+Bbql7s7%jF+eok6YC0;z8p{xLCZ!v2EbcXKVwDiTe`0v*-dCa4$2 zCpiU{LKb5w{ACl3`FF@AJGtuu=AvzLndSmdbBnWzy=obY>ka3ip#5U+|8 zG=O9n@QS9dpk+tOSJ_eEGx z%ZQ`r9J!0VV}3{;1N);+74YpX%1~8Wo01duw;cPi8JqSA!Yw3S5AREd4V;3V??fuQ zVF}c>9|N0rPKrDs=4N3p7X5E#0YZ8kUIAcZV}Q)j*wSVIOxPvEq5VwB5+17=3S^?~ zHlm@M@*IpB{#r^a8`P-2?u{f=A;Rk##w%jdAis-xT)j@{@UF4&*1M~v8bn$uE6D^p z%3@ME>-@--8=NivF*wV-CgW>*21rU?NmM4RU5x~dwr~1MRjG043N}DZi$**`W@(=G zFQ?%VRYAHh?a`_u!vv|Bhv=Un-22f>BQ=|R$k;HbN{sC{M|2WJ!PQnA#c+SfNw>N! zXSc_~kbw;_X{=;44CPnSNMPoUvvQ7xMBPzxzPOTL(Cv8lr|?&c3ElB=_cQB*)g&x@ z$^h1z5H9DuM^xkhj=d4?#|G`vbI4^5l4OdjjNo*tMf_dZFlBZk0rr?A$fi6ux&mNz zQo!2%EjZhGQ;GQ`+}bp`{Hs6H*Qwg8E^)n42AV@7xFD*F{9E4z^P`68Qn3ea*ablg zQvuZSAGq!3)V18aTPMs=zBHL5P~vr4K8R{pN0!ru|Dw()wb~zhM05aQndV^#=ImFBXHQsFey_H+wMbo&h19Uck!F0$A_fmh<^KD zPKcqr<+J%F-{7DpLenh9k=Dzw zME?spK*qlSxg+d2UMj7yg-yV{FrVe{5GefW?pWZEiVtsQpn2a;f>KF1_97LXc7L}> z%3%kQ|rO=V1o=!N?Gp5N|wnYZPG4PMQlxkyue{D_m@TpdXd+ zZ9^<)iFRJt0`4C9^o1gk$_+Eqg7vBd<&QNzp6NH9m6W3O}t_*5c} z#vZmvVO0$m0FwjVOHDEWxnc$cIoJ^+tcy!rRySi1Ey@73)Eh!7j#!?krIo{`-7=W` zj0LMh@wX5aC7%i&)qYO;9i^0fKw^s~31}<-q#vU`xdIH#FO9hvGQCAH53Gt=7DKd| zABZ5RwOu=~NuF^9QQFc?k0wUP`ZQw>B(Y|-t~c52rX4mz;TV=m@^vT&C&b*dPJmgW z(`05O)I)9~K)|FxL@6UB?epp!A# zoL^M{N1&@~L#y>9kR9D6l`mxtIH@%yjD1ez0!Wpw@hJPtY<#-I^|PMh1X%q|b2t*V zvqh_NxMa%$>8&RI1kZGlpow$q;u4KvOk4zyf+I~g1}x2MG;_v9B}vFOLQz))VVQSv zMn@PC!Bsm?!+NGO;g{wtH&!S{;0omVK3u{U5Oby{0?#5D39E3`FcN`wHZwm7BEey+ z*o8Q1i8{$FSBbzI(+Do&cavx26eV(OXORQ}G%Kpr1>M+-rLCgbTFO9>DCGrgyAn5o zvuHa_w3k82CiGMZQi^aEm$0!YO_>RRR<5xU<)70rGi46J7sAc{45Su_2rqxa%-j(O zgy#wtonX3_yhuV6W4_}Zd=XzLHS_$YD*<15%$*;@>lq3na2C!tNovq_kLxa)(u?4o zyX=9JN}m<%;<`iCg!3~HGFhYmnPv0fRLKialK_%#jJ)zfqBZ(N%Fw zH)iQl^Exd9wU7&xC6)*vmlm@dOB+h9grQtAJ8X3*SwY{u2&6ag>DMrpZN_{67V!+I zqE8oU3V28xc%GzS8+PZ2mN{(lHfRTyuadaRRP(a{h^6cThE*&;tn3!W^s5m{zuxGe zUxk?cVrc;B#F6x+S71q42+FZ>+hSoUCzT*rPnc|S6e;*7yIO`LU<4|FG#Lg5<{p}+ zRkN!~?g}+vxF01A2-$7>nTX+`wwv*GTdisxQVG*9IzY*(8tW2#&&own8^l4mD1tbF;IG+DNZ1_OnHY|+ z>M@R-cx+px!qkI`U`oI4mtx1zWk9?k>~zGpm{$m#&vde&iph01!5g(1p)IVB2>_Ep z)2dfFfF#sno1`Kc$w#8IJz*n#5Xmq^T8(#(gUA5|5`kzxq@ZZAU*sQhI28`A)8{3! zPG7Uk%C`!AUHPID6SNwH@XLV@{dt9$mmVr)@PLbADqKV{Or0z&qoc$vDuhwz^De3vEYA_8q6cM$K##-Nw9@6EI z39Whz_>H-Y3ncjq0NC7NM|j<2mu>JIN-pJbIAwU2xp)LtUjzR>3L)e&I zB5E2W;pM{E^K|PiDqWgx4N=n+8v!F8B?1BXh^;cR41Rc@Dkq~DULvX2C$&;U!fXx| zt^$Jl76=ifauqRcsn9S}9VZb$0)w$kVED&C;sXnb)S``158GfZm5Uj@rCoXgS_d2o zH10Mz>6o=Zh~v2e&e>X@QZ#C}YkMCBT;p|`sIEcjkpRrgNLp-7YLIb(2Yd4-8fI`_(tMWsv=fQQN7AUv7$X^s@4;( zTZYDaIKAGdM3xdisl@Lc3j{uc+-6b&zI@l2tHEQzgQtWc6uopxGz9a#Q_)QE$+N7AI zJa*^=Us8F6^~nXR%!Sm~SkWHU!lfGuq22gXEKB4Zg+$#6{)PwuvZ5NWK>?`~Q%}y- zHXHRCF$z|sh~{69jU9_hMz5mRHdGt2C{mA%s0S9Lz)UObi%-#7 zQFLUkcyeGA+H{$4jstM=K4_<@LIq7q?SNtUizqOjWePDKDTM2ht`0x3CaiiJNzXEY zRiHrMk!_HNCBOcG;%U1RHqLVz4yZM6FRbd;y^{(A|Gg0Nrx}beQdJURtLALjO7EyoZb4sbl1a(csn*)rMP57C2>oFVvNEpKDO$EELg=34W-yEpj==R z1Q96J4Z9_{4bepa0^!ZZ(kd)ab%eL81`=n58we z;?{TvBDm63@(GoJOhLbkYDtaLh4BsiMHa#MDNJ#`ghC)^Zz0Wegu#ob_2?7MhNwe; zCaFv}<8mPs@&qAPU>F=j(w;61={ErF#kLiNAg4hUh~7Ur8z{_Yjc7$RsGCCsnJ*WR z00Mwk3;=-*I~nWsTQi|SO=~_5PCihQ*R{!$Q+n;?XNnkm0D$~DoA@S70vpo}7s+v4 zhnP5NT1U$O$!lBC39wed0E-4=pjA|d72v9Y_%)gi)R3ryuS|0tIaz`4ou*Opb2M3* zXNpG40gRNiLY8Ep$3~c+9h<%bi7sM6R4Rr{Xw^b9HkZ4G_Orq+IEf7lgdm(}0{*yuL?+u6DUsNocg!DnKi9E5f@ZA22^i?{@<9eU3^B6R^CY@+GIEnxAAho1 z$?1^BG3^okD<3PBfpB=xHiVcgE0h6g73HeZSh#B0i3=0; zvKx>U_duqVU6DX5T$kXrjlh4-Ah!YAEh{3%UN(&xH>j`)~ap!15v_88fuU`Hk_1)RWx&p=JRtqR* zYdqLmDaSi}MH}DzWc98GaaXn}uzWS&sf^oj{8k$BO3MHS^C7l}vI*Ps+c zAtikzKK5ll+>se6REG4(-Q)IarH$T1JXY#2Rt%bwd_~1udkAq!;_{4RTNE%B-{jUx z0!FyO-N1fv6wfA$WAVYEMiS7Cqp4^^MNbm#z>w^oLfE#gS_|h&4Sv}V=~g1dQVfLy zLsFK)VJxgwAn>8wN~~M{cS#MefV`9$1;&=04jxUcj#lIbdklUHC~XLrhUid#IZhj` zCx!^7K@UQ@B0@%;42(NF76L&y&&4))IUOn2CDJSYi{VG$@Utny7USyie6>w-5Jr%#WEfO_c?~3Bz)!`}+ zz)kE(=O!7lGp=W^ucLCk7cNSO{H(AoRtkg$q$v+g6Z-?`-5PkpV#xL)LsFu^_jWeo zQ)Ao`E%LbOmDj1n|J)rHW<{rGk~d%gdb;T~80Bd6LEQ~ONdqzq1{A3{2Jdl=!yTP&Qh1Kkh2`;%3 zd0)A5UJ_Bxp|@6k2yIuz;wwO5A?-7DD6NnZG*|YgSQZGiZ>1n=8oN$ljVU5)lX9dL zeob3ZRM?St!=jLRmD)yG3&cn*%`|Et3`lBqZR7RNh*ir^L<=>LrOlW=HrZ-jV&rGw zNuE=!QSP8sJO?Ku$_?gNHHC*6$?qBl&_o~BnO05bB0pAEz)(>dfs*Cc`310aONlij z^ORo23}e^V1r|ri6X^8{St#O>6WGcYmV#iFeP4%GWPmcdav@?pk#XklLyy|?aLpiO z46a*rkX!4jG1!c(IyTDE6Lr-MUDs?b;3dR;@z4 zRUWSJAoEHk5YoA|KJsEp`}MjRtq@9{u2J!5EaX*$l8|w}DTl72C0#PNhbRt{BH>fr z;wZHo|9kcx{4cWAgVeTzMq^@u6wcpuZ>)qc*1TnU)Qc7a_}4+7Gg_Z0&;gEWEe2FDSMc}+#an`LYY=W-t;TJ8EM+! zs&$poFZK%KWau71f{-&=7lcK-a7(X}GX5Sc+{xDAdh&%B$kSpOYsAsxuEI-+x24sD z$*A;`DbuElr2hPMm6OY7b8W@lJ!J>#D47oW_3jan6&2*5dIiCFfa(kY!Cku{bU93p zfLLB{6Kl1Mu*U6K`T--)>D1QCw#l7bAk^TvOxy?j&X|&%{)(THkl~NEiY4Nr;?w~l zkZwP8rg?@EU2|@lTNP(MU6nTEDJrQ5H%VYP;11Yc!@h|43MS=Aa#_0IK1IXsw$L}B zj<}wIjU2+Pue2l&S(K;#GEK%v@;zng%aMk5$mSH6jn8qw{JE=qh4^mKta1e}xp}7X zo>f-tw_>_umw2!)mm*@mN^34@OHlM{+8kP?@;D<|hX_^>JE0WaGw_P&2&(XK>z)}K z80UxwIvh+qPRIurQ{xdx>m@Z4T671jH!h%-M2Z0PNneS@7(W1vH@O1{D#RTF!k~ok z1!;Q;Y3*AePLJi|w=ZmyK%o7AwSpa34N)M;yx1x>Ds9+$=@)yr^Fe^o=d{A0Q_%23 z>q%)|iD}d=+2oiJ6;S+fr2%mby3XFZg38cTo@fGFrB*U7JsDt_!0eA75@w+lCa`B^ za~A+$#d5fVS@F-`IIT9y`=YiAk@1(@T@mo+=!#8(ZmvMXiDOYBgO?N(1LHV72F|SY zV6?*hWnaI1q-kSFfJC-q187m-Ahd;n)yHV*GASKY>;DW|n{? zxP-LOMhN1t>&Bui$Kpc`cHx}j&ALmsJ6ukgSZx#rSOsE)4_zZiVUQuXP3#>A29?4$ z3re*CF!c5iJ;EUUDDFxlzTqy(;bBJ$&@G>PagoBdvMs-F351||r^AqO*|b^r5vdz3 z2>|0j7@Z&TVyUfq?Un(C=F#zWV(~y1<)8@5=Y%hc0*ulQl!PW5$)y4Y##mjwNY|Ly z2bR}G#mTxp1f=8Sds1oB2kpfiCXgs_tekGJi_jO6=p$`-`j7#DP`a|6T&~ChYqbrn zP@AP2S}OZOC-OK$dMCQn1-H8w|EM)aE7ZVnE2c{!xoN0ps~()j7(*s<)>R-yENhX+9-J*Lm}RH%L1eZlBsh9E=jrq0-^Im+NctR#MS7s z1EAo1lNC6*gy`^AQ{0$F32vq`K|*n8H))#|HWXAy-lHr41g4FF+_$|(A7-T0t>O}A zW`?dGZ4*%JI7tDnk=EF3H)H1t5v{n^KX^>STF8_GvjXZhivX-jNES$w>7=srP$2*; zUYnQ#Z)z48iCo46)=HT(X@q!64Bor|5Ll;ZBko;PlE_F@iB^4a(pGuFlas`+b-zM9 z98=fUEP38ijKvy|3D%>Vu~jl|$@jY9)ejOR_EtKv-{`(ZRcuAse~6dBPv;{(QZ|eP z?tHDEfDQ7DE#0V&mkZ*q$OS-ZxB$UCi48<}p=G8x6}1Y0)PcenN^JuDkVMRjxr{_y zXu$??2_%jYC7eQ*3DSi`Er9Y7VTPy&oud|PmG1|6dOX7l@__KYG3_bke1h%pz2Wm= zpVs{#I&<%URuGx1(tu3-3P|lR(K(K_u&h(0M{5dEo#bGQz&ld<<@lO$DGWA|T_Llf z*96Bo_Jp}@tIlru-+M#|%$LVV+C$TMG70|u!dpD1AT1amvp@l!x8 zBz3|-NG=T#Cnai|WkK1hXyD}%wGx1SqzF_+=mnyw8x%JuEKKnUh`=@d1Bl5H$y$mv zp%Es+^j(w(UN}A|X&ZahOrhx+k%6dntyV<$E(BArR&`DhRmDB;VN0-h{0&EGpUjmX zA|6#QOjG3rdB%iKsPRLWd_S^(GvI~>PIV>GKHhG!ljbtuzK=5QXr$1 zqI|`Gt-NkXE3%k9Oo*xdtmki=`FIDd8aA+B0`x-G2Y`Ug8RXfhwprF0v8^>$kjH!t z{J8Q6Wky=JVlb1-Q_h!!g7d}W(h>=Rp@uw4k(EE%xrsntVEPmfm!_|L`wN|c=GL46 zM&63$03lq+W@U!tIe}E>0znt&P%r4IJTEGY3il_zzKmR?KL9GGz?y(waY1HJz+70r z(+n&wtdL%8B}$wkBq5E~8aJ-K0tOFwIKB_2UF4!F_ECXxqkwETVtDT>d<6`tR&%KK z2oQ8`1uQN^M`9-)GrG{*!q6wK_H|&R>&hd>4(SYO7Ah;U=A-{ zh-8XSw<@*>10dM;>R(tOY8OZzoRi(B@`?{9j&>lTm8S*#mN1)Tsq&dIfwYNf4s#%y zmAb&V!zNc4iZl6TtLAm##k_zK$Rw(AJ*@ru`58vX_F%8JDvdHyWKYJ9_CpAm{hRq( zp>5Jv%ZAO61CX}St;o7i$GpD>r12XXg@R~9V#>Xkm(j3N!1%gDklDI6cIVey@Ster zE4DV``T?TLZhd=G!$FyClQ(COleuEZ<})wkwDIL{l0RR(CBvv9#XQFt1H!4c9u=t( zX$1s93_7h&kgwS?FdyP540Ga%ihA5grL!Z2LWT6UGV`h2?MI@g)w!IJ`A8I-Fg#v% z1PS2iW-Ouyg)}PfSgp}<03_b5p^r0}J(BfU)qEA!yn^|3AviUR&3xW#`1t%gsZ_Z5 zbhW17q*7qe)hkEl&xlZ1fa@d`aHral(%t27rps?<|@Fik%2zkV3?_(ZveT& z7%&A1h=35E3j0UEO#TRRfe(Ysw$@CqyIKffx(4}!(6A{B<(i(PRoFsb4+77$_KcW0%Z*FI+Ag6<&Ov0`3j-m>)IGAZ-+giVZpXN0&wtbGKhIy!D}1N-DSQa zVz%-)*=+dZQz&8QuqZi9L@XB06iN`LaVLyO8KMygb~xW41p>1{I6H_{yDt#xofJI4 z$dB+h?XT50v9m9obszV;q~l}Xc05g1siX4TB51u)Jk z!*ful#L5a#Lyk;TC1OdKPcmfXl-6>XK(zUVaI0c=taTWO$+Foo-&$!uRa?4Y-`J@4 zNitm#M~HDluh(cGMGOjKO*Zn?9wF%PLUJR9oCMq6@QX_4d&Ot~>I*uZWdb;RY-JW{ zsd~P#>UFAFBt85VFP@F|0kg4uG9ud160VvSR|G2&g;Eg-46?G5FTf~ZY^B4(%^~vV z+BJb-hY^6%ZCB9+B&PrZG4C1?<6Hx!8|IKNQ5TVfCmagF%L4#2(m+VDb+cO=)c+#6 zfuR&rZT-3^GTNkFA4f7y1k=2kPiM4Lu?<8jp(pSFp@wR0FN?y0Bvb_sI6`B{yq<(6 zirBH_B8M^%r&EByldBbrLf!i~nviXz4MMTa;`>)vSM|`Z3on4rIzR00p^-Sq0=9t$ zPg@&fWrNLaEYxao{?N*Ec^v8C^tM)-M`3dz*#1KY*hjA$mRJy+MGF_gJatGa7ZhlP zMio(zU5W$jhgXx&R#V4Q1_I{AeMy*fZ3pMfLg9I9%3h|qgzymClGxTrFcRF7HxXzB zvnedVU1Bdnj33B$#2HIt9G<>=m^0NDv?7@xBXaujkA?UZMEM?Pxik&TCto8A5(&4J zY$}AOeTo$z=g3u9A#O@rxdv0%qkeQG3efX?+oWNxfpw@<$p*sS(=Vm?Z8K8Mhku7Q zUq@GBvP#_WbR%pf2LX8_px<+lg;cbnh-+C!4K~(F>dx zE!}T6BL*Hpoe^7~@HC@si+aEGZs$iXT^ie#j(mj&&U!zOFkbC~MQ1fbt~^K4M9- zTYyJmSTOOhh+$v}Kb06}?65X_DIroQg)p94!;4H%EM zKrFOELZhE==C=s-2*H*|yb0;!frMuHqh>KMt}h^Afe@RVe!L102q9l^lCilH`?0XZ z%D*suOJBXN<_6#z-bT1cz;1Jio98&NP81(6tVcTHyD1n_MJn;0>JFFG4x*{+iJ z0$_An_0Ej_EKwFh^)W{&q+huWEKlwWGesX9SR^JO{)}gx9)w{#6ZiTt(S-S^h&}M6 zi#6hD*egQvd1BfSM>Rqq48mX7M(YAVWp*0`HPCo=%VUamW5w-7u%=tJpfkPlKnrb1 zfVfe{NyJ`AtK9=5G@Gpwk@e7MwH8Tbq394|S~nwMPjot5%+AM~a3vCsVvxqisM1fH zm0r25xVC1P9T>$w-5XA{$HCzdlc5)Eknbh{!G&BTLZP+&s8)+My%YPv$pB)xF9t0h zmNu&^LY-I)~7pZnANVxB=~!7@Z)$z=0FsMK$-r zI9~58#Ogz5vkcE}w2Ia2n!Ety;H7^IAqEHlBuk?xDBpPRY+kHmC}gskc)JlilbTFS z<>(A`8QljdNVd`m_#ulF7_TXmOHxV$cCnDK&A=r-j#z?D`qf-vpt3M>{7wfXQEoVi zjEBnvg5yR%qUzih7&fK4udIue)srHDKf=Q+6ZYe(O8bEn4Y0rxd1NdeIxC-^^CTh= z@{=9{442EGLV8zK7#E#7AEB($3bZH^Xhnp-3`Ghr5WGn(uu!X2*0!QNV>p4&*#ttx zZ%29~_SoNV=t){8cZI=LUU*a(k_5`#WMB}Z*rHW(A7VMy?H#LlXqqe5!IfLpJ*Exe zf7bvabAKBMkIoiCM7A76QF;lF14sy+Rz4iT4(VsC!jXLIEP#B;OaQXL9n(vuunms8 z=fKvjE(gHuvam%xW(kG3pLQcCP_|b7+K8%xu85#dA>7FA$OOmN8vU?DhoWLW{Se#T zE%HSifsroRh)?ID>ZHPe;B1@Z<#E@Xqa+!d+KX(0HMbWRcG@dxCI{~OB(@?yo2e+5 zZX1rSjTJ&SLQv#4~ zI%#a}O0wJ!4~5>72)IgyFuR=7EAv3O0a76&hnWNgMvA<`0t{5hP`c&pjA&PZtiq> zY?4NN9iqp?)uvK12-01u@HjxwsS zqTA4*8a9IyW(05VMNkD3`aty|s`x^NMQhO!yt^G(WW11bzSTu51U!S0R!K%9fCM9j zVQ)AkjjZKUYhly5ESzmCGYXN$fDptq=NMQj@_}(!9)vN4j6@W*LdHAlF|AN!rE&CE zZd1budi_}wPa(T({hJ(U(n!u`A?I+Es?D$wFmFXkb<{N$K(w+aOe8~z#yUh!G2Bd| zdeiE1@maP<%jb&y4v!+$(=<6+5sxtr3=UHPN8N%PAbdr*t3H z1@V|xL|~MS-XMrdHaa5T0YLy(tdYUYqddYak&=E$!FUGrGfE-3(%s+5Sb3{P6r_IH zQ^8)f4MuUE00M#qDpJ5(zGvmhHBak_Q{y0QdYUXw$SqH=0l^0oO%Pa~%MfB^v-4S= zuI~j5K~Yl)MeKfU#Ro9bCNFT?#?N%EekN0e`30f0%4cMOAn9hLM}lU5>R%`kdy1a= z>4+xDoYS=+P8g*&(kq9Q;w>Roun6G>gFB=j+4*2gszP51BaYfRQQ)o~k4+oHenjEL zGBQbl+tp)yx@%xQJ(JN>*&xIsfID{RkvV?wqV{Yb4 zWHF%VM~_Kr5nHIw%e=6wt&q$*g+OvKQ;2!-u9FmB$BJoVE6i5U z!G6Y#g!o2TA$dk1W7VdxRb;c$C3c+=MRF&nunyAhM> z!u3U6C7e{fqb`vqd`rN+q0!tMWe?uL z=@FPO7DO<$oWSkDazgF|+YMzf5bxrs!r{D>P0@wy?42#k5t3YkK4TCsKy0(-^q zx)2ngY=v=;3WOcGP=uI|$^@pq0D#_~ZYfFFK^m!5Yqv&=QTK_k3nR}@@W^VztQ&(Z zH$-==Hx*90ex^dzJghjEjL}$lM2Jivxz7t=Vxj#8N9x0q^H93}LN(ZS(g&k3E90CyZfrpp4?sUs%FCkbGnZYKlxIE-$2=tky2o>ZW zI`%rahr?L_O2p~-L6=0dAQ8fAm?9}=b1$jM$AHETr8QL0XLE)4T?w;g7@K*)H!uqj z#Ci2NBVir|g5Xty5?=Mybf?1`$orDO2SM z%l%p)5RDuP1Uoq+wKmF;BvR*Now+5=e9X%M~gA-E`OXT*74Dgc5%3!;E54Nk338J!ctMW-8TA;~!! z#XUA)Y9jB8EH!h}9}Uk%IeD4}rj!UsDoN&If=Z?`fuL4yp$eYC+GONgNz|GAIB7 zFN$4+ajwS$fn%KxF2jt>85nr=x`k{l!f8W!Zhj|FPr5HPZU$l>|h*dE`jbr$7pbh`}m81M)A=67&DIh28T>5uI?i}c^2#T$^)YKJN$s=ziWkF-q~P)P2ZWgKdgWnlhT|I@K0S|EJK zrBv7#m4J*j#19sGv>!ip1t<>1w%84G@g`NE{Vj%D=oU8DjK@9v#3|5S31?n`Bw3YaB_lPxx zt$qt1yKZfnBdJc^9`S~{U%*n%4}`iYi%m1ICpCNzcMQLcUvDVqRBl*0Mwmj~1o zqq&*@#H$I6B;&+^aaG(atFWcGOuXPB#{!k#RHAH{vLm;LwPS$XWg@+xkt~X=g_}VR z=A)@9&s-G?Bw`zTw^8V{N;#e4F9l|f#AAYt1YT1Q%zV^eG93#sK_i!@5^fPf znxo{y;}$NQeablPN5OgxG-yjCu+K;_q)}8n0PAq+roL(5!`B*aWf-7<|R9v6BY}kmo}M=dqt}s&lYqidAZI;vG;AG`Qax(Yt{j&U;~oZW*CQvC7o>( zzf1Yz2K`KE-khNc^}e-CGy+Go=TihWit6{|a(!Ef$#YK$iCNMCW;LoXTrx?A+3K8e zmed`BGZvl81hgRtw(Tsj6Ac>annoCT9tYgo?^=qqFb@!>75iq!R-=4dMD*v&8jMZh zBMSkN+a|8aY98nm5LTjR#KKbw34~aT;t|6r#w>^L<*&41-(h@S^*iP{WfDy7Rj5vsUL!M*pF}4J06d4HDZU$m~k*gFt*&MC#rr55b(PTJ) zBm@Q|2bPg=hNmAs*bs>hB8_m| zcoCq&^7s`nYFMF<44xQ2yUO=ZgyfC@ZSoAb%M=#5q`mA9LY73sTf+nw!tz*>Bh?)c zmfAOAIeU;0mqqO8$J3%u<mdFS(b{T-xpEF! zP76fGO9;9}x_9jGCyeXU64S3<67<6d8M3N=gheV#eA9k@_E{Pu=~=D8k2q+|P2HS5QsRBj_OJej$in>&t3Lxs!?Ga7&NKs%?qFlvLxxpnYuSo)dO*$Rn zx%R_|7X`9MjWt>k(&^HPj;YQu>B?w~lu8gG!^11N1&F$?HIyt5gp#lFKI~C!qA{ck zcH+kpicJot@&Ln;J=o8R16yI64y0)^`k8WQKhk_zud*J-yHfQpgPw^(dRT$ z_ja~90}{^JE*F@#Q`u&Vj}b&g2{90{rL27zTdEqfuoTkO*Jy7xfK&Mxqvm zX}G2X5tKL4=aCw~sMQeT@UX5J08F9^4blYc5(p95vLcDA9G$RP6XeY1?A8DY<5+!> zZjq1zssht1aYpIC2oDwoTwasH@pZzL0smXwYGnY+*En53qOG)wEhr$-6#+iC(%DEB zb|?ZhJp{r?ERsfv6Vi!)VLhuM=VCAt~DkON;q#1Q5EFU5O z<|4sYT?E#aBn=Rva83q9%IkqQhY8~Q>9WLfJUAL9DhWy`CMX1RiZuprtV51gsA^!- z3bU@_Irkd~2I5-Is=d+gbijxKd2(Pb@`^|)H2`c@ry+ik<-`m zIKsGT0Qv?lT+reGM<&o}#)tH6?T147c@gHv9@RsisT%i-`&3`k&vg1Sh``(@}r z#4bmw>H&by;yCb^A%Tp<5i6}Emz)6P>BxHN3Pd{b!a_$u#xBuJaqP4zC2^fj3gA{vnxU}<(+!m?5qy7OMW-JqphMxaqc2T3Z}wTPIS$0#Z&WBp-repwu%v z9X5sjgM$->&7^MvOkHLdZ zT6u5MGtS5C?UsvV9{M?W5|Ze0?Dgy}pmIXLBW$;#Jcd6+1LUnU5*LMsaj;TlMo3Vr zfFPo;i8ZbREMa7y&*`d&h$m7kgmfkSu+hxbfGc77`YbR4yqJqX`eZ2(UhI?~Eul>g z42Z$Q_Cs1r*TQtEX+?-|AYm*3MA>0%npm~aZuq^T-N9qx*exaw5EYT*tXf_?+-g8p z0FQU5_?oUMp(zG}Izb~43}NvJWxC5=>J|Az>6qf_`~Wku#>eARbsiQ?!GRtdydWPY6pcdBHMGLep@+lsL1+1D5+i zRL+13i&9y3X}47(M6k9NmarIfDD#R^m$bx)MS_{%izm*H{#s{HTR7c3Ul3NSk2T39 z0%E4q>ul-PEYiqajfliofNEB+MyT8$_4@-N^&R)u)#>gNAg5FIv9CYf;Rdw zDmPUwc^f5?MvGm3@_86<)i@Au^GD|b+ss@7!mu(Bq|huX;a?%~Qnl>xSy&|?tv@K0 zs}sm6f1lWKbDsj50Yve8xztX?tP-io`KsTA#28Vo8XC!iRb(C@3Tvc-Ng82*yKGwL z9epAA-9WUFl?*_lI0@yP8iN2rEu12aLIKJO@>mQ;Kp|k8qhXQQWr{C;80Q`sR+xKJ zZA9u|^yQsMmQ4+eCy6p|vH;u1xUT00%v<;31V7Ys1Cj@@fbge*^il?R}`DAx%Lk=|A1oQ1@_w_jcq5K^Ag>WoMO5+{f@ z)F;f?;WZ#gwwg~{FCxb!iPqQ92Ac9r*hybNf+jT@gpK%%@^&)hU{XHFy|{ z51B{>Nt#2%Kp=HT(z?y(_ud&BY|qzy5pMO796v!)LEf}+0`SRTz7*Vq0ZZjYGOkl% z7O$HF80XQoz$oYH!VsnQg9E96&PZff*u9X%e6?u^u7Rt7f-Cn!cL8xjm>(PQ6G&45 zZRM%cEf%^EUtuW{6a_+B+@~#71{Rj=9EibQ0YgB*xkrNz$kjL@EHfivf<=)97PUnT z%uHqa^+*$dpOLZ!M#}SNP*D3RS%IaDQAiX7fIjW&l0rd5cs0tn^AhExca#Dox%Pr{&XQdif0g!APeJt=j+t$Hz2iR@7d@YoRRv{eBI z6al3|2tUzim6O7mV9PdMf>LP^CnyO777$FJD01w$E7&RVs{_gAj5m$ApjFCyu{nG_ zx!n@wz+@^L(uBGac8hsq9CvV%q7zLOudCXxFNOoj4NuPi#&-W0dWo;oO6A~piiNop z05zuQ6*CwBAye6sk*)D{Htmx!f~FIspb$Wf^6Bv~7xZs00tK&vQ1zh&z!hERf+l+% z5^`Ar^j<zE3@^DGH>L#1W(*OwcIzK#Va?CZd+g2h#r%_~J#4pf? za{0@ge*%7zyD`*alI?nyM&(KqbG=nFE7WZ|C%HJ9EV+cg*9sb7pnwHHu}P{j5C!V4 z8=EAbc?Lqpx5Uh*>aM`4nEmV*ZI&WsHiKy_%jvO3exe?*h_XxrKapn`NGUO)6&Xm0 z7bVLZ9vO*1m4`sg!e{W^p1RUT5K*4>2f$jy9Ved`k63u6F2`e}#52GKh(OiiFrNr6 ziElbIyp#v+!8d-FcrzZ1|I;&otQ{Lzyl7gnSaqNI@TzQx%5Fq1CPHhYiVtjM9WMaH zifBzEq`*jukhu`DtHY@XFX>xFX*H9pOu`Qcw-osk5ZCN z5FHP(a!nPS>Z*|pV0F+~KrASc*_R|(WWqE+xH_lsU?W5%f=uYDwlYRhqT95B(29b- zG$*N4&w@;er=+4{V=T@(sWe()+qiJ#MQVW@Y1KmDi!Q;pmB{yvR$K8-CnMuhNzayS*6CZ zgToYcqHrDBtzTTA4Gz~ja#H3J219Ym?Ux7MfZ)KF&pG-cj;za?ul12e2Rt}ttID)j zbY>t7*m0Hth(_;WGSc*GqK`GjrgWqv=c*1^8t)7Vb6dyseg4pV@EjO$i5`N zrk_WrJi2D~FlY)9| zBK>SP9PdckuWlV@0ihvsm6UM^5d>5D5ttHIQP6J?(keB*KrZnuY~wa)@#=U0r@s0qM%QJ&eO;VvQ>Wl6R7UP`=zYmSb`%ysFbrc+tqu2k}O&(JSd$K2ll$nDPw- zkT3tW8%19o>Hl(eFUgkeR+gUYYz3PT5hUZ1?a7J?Qc3+c)Ax^wb*?*8X-bpPNctWJ zZ%oWLuu!36uM|lfcT#G?86tuffyKej%LjX&IN0)9yeKYk(&lBWPLx63u(|HGQA79w&ctRa&j!{0 zDz#j12vawLsvd>qHsL-Y8@7;|<;CG|oI(hU5?f9ay=}okZqJdy{1@nATumW~;I{`9 zq)0Amy6t7{j2VLdb$7N<;U3vWmpoC8DRr}Lf$&)zT?%%NJHaSe9gZk$Ww79QA=;ff zr^J1W9D;<#onSP{RYI~+Grj6G;k*^~3L)TbNzlT)gRmZkX_b8Vb7dG3w;(js8zSAa zT8fsk)I$2_y-1)*9%jpCMNh#>or}qYOunfnf$QpptvlGHP%Vvpq~EpQ0jO#O$8~xu zG83#-T1es=m+;thIliWa>ds0UF9dJ<>d6v3-p^39Us`u*zLwgrj1tIwWCy~j@=cE- zd8J(5zCGa7s-@R@^?bYImPHo8R}X``ao%fK(E#t%jeI$JAu_7gk_gH%2iUG%*af#W zOsi5~!mH$t)&;U#Xzf%{__o22_uw#WA%uXtFhK8}ff_QW8lamJSBu->&KS=^tD?|F z7IQ5dTfib@8s;p&!(+uRmH-=*XbF~&T&a;736#I zihRArF19A1Ww`>dfmR8!`xy}NmZQ1+YFA50@mg~CE|nmk#_mCs%#)1usSE_&5kqM& zZx+VUbHu}jusD#y8OCHLOKckQw&@?9)Leg+ngqthm&9BtJ}a#!_ovL%-=4ULeH?)` zD$m!gl#jYP-Vk2bMlf~zMm{4wCE>_R87b+FiFUsv3oGYJMRQ>RNMza$xJ25b(Du7= zbOc5#@kbbazdfKxOMqHS(j||af0yI)(Ry_B(g#({!J2TV5736!m=DTDKJ*HlWsULH z#iFt&X8p|mI`ZiX)#_P>`4^R&+Q<-7@)lLur`+^HZFL%xun)L^{3jjIuF5U}c8MI$c)gm85W{77$PjV=8x2o{e zj|JD(qefOE?`IFqp4ZfAT*6K*Euf`s5564NfX&{Iu9Hs{S{SfG)Ad7y=tuhG#8(aH zZV^-)1r>6b#u%_okGOK?thbAiwZg>dH8sZ?gj~Pr_NWmJ9@Co59b4HJaI5d)mWC)o z5$EjF7MHwYXPRsWHlK_`EK_KDz1MJYkH{Ri?Bfqex5!PjlM)es%1tvT7GLPe0jlU7JFO$0VPwh;)4&m$Qf})WBCE3z#EH)eZ!)uj zVSDYXanf9^281we1eHlkGy+EDsY@m?(;miscC9bH*ua@BmPa*_l!lqd%YwBDn!hE90VK z%)&Td<_V0~;zq?}Z!L>X&9tFQE+H(0J6FBb+qs-UI9Y3eUB!O_?iM#DGmW=e7rV{S zJ$Gl=+1$FNSg#&EIk92_Ggp=IZO}$!;?EZav*QMr#NEYKt72sip@7;Sh?9~EYoV8o z2lLOnHSQmiaS+bQwi6<)VP(#J7g8Aa=(z_C*Op5fwT=odi$yoxv>LzK3Ordp0pIK3 z=*X(L&M^57>1oAd+21EbB#E~T#MT_k)w)gKq=?!L0d|=cmTW#-Pl^*KHQvH@q9D?L znu}`h0kE)pK+395KZJ0UzEVYQ1Fm;|l<5*7vhz1amUgEt?QRC3rl+Vw#C>1AztPwm zBg(?UZU8&>5Ndea*^nYuh_tC&6BhHhjQ6NNnJK>5`8U`zr;*Vdw;pUZH-9o)DI7~3 z?GfiM8p4roN)YRn3WC`8`ph2*+vm|J#@Z+o?IUPZB(2oKK^8Dp&FcUr5b`C1un%ul z!WQ0DYEQVWRH=&9nsH zA~U4rHSxV^R!f&v07+TA{wOS+7bl1XwL$SRe)amtwe%V~!BSKEaPJyVVF@ahsV_>J+Ic#Fr{`_Vf9J2RX zMmkiZriR}fgJd?9n=oqn{29(eYN$kn_xRhIcH;bJo8_<4!0-aMe6(QfDoWMNSPkaTL=@VN6xntq?`#wyhd- zPwZ<4lkf0KaeKr;^Krx%@>Xq(lWW&ovAP?!IFp0c7|*+%*_rH2Fkj9Px8S!TREx`m z&lHU#A|-Fobq2b)y-{{#r*aa}29VUWD|fe%9TrLZO<*;~e2`NE4E8P%6MFA%65tGeM6JI?}hem~(E-cHsj7fIl?p_6;>jHI$ z4R{9Tnj-5As-WA4OpLa?+(TDJF#XkI{oN2GBG+9}&TGiKW{sOxiWpFZv!4!Hcj?Fz zVp%fL1B6L&Yk;SI^%8<9$mG z!e!IODYbkQ2!-*r^!#2hhHcYTiW04*r1RKE-E2vIm;BQP;s;se(yNW~ocS<&f+;xk z@6qj@$B_3(RjHr`96~s4bxSQsc?i3RCG*m zJ|ty7g!jX)hOnCk$VuEnfx1XP>=h{%cE2O^m_@l$Lz1P}naGH@{A&6(K|3@pUsi$4 zAyjAO&s-Tw_^X$Le^|GL*Lqi(LL9Igc1$KfipZ%0tfZ2|!wB3cj`okf1NKsx-?pq~ z(ByMSgvE%$viR*KBxS9S%{VaEJvV19BdV8dU8y|CVf6T00vESK(7?XSs|+vSAzrZf zIOx1$mAd;%O1W!S>y)K#^liHBh~Mo9N^LL8K?-v@F>*u!+1@L4?;fG9G}w@PH8$zO z`*(xni0`OJmLm2I`{x>p!2315N2~0BQna;pGl5xeSmPdV1<$4 z7%8-2?%@Qb#MN&yh&a{{DaWe``#|gQCZaa!8`dRnD_$uqC@S#KUc3>~OA#TKV3!AA zZUEL+npkoH!b9~A%aYU}g7^_#DG}!sGQVZ}gkercV@6Qx-7ZfzQbtxwBS==B^$lYJ z9VWbW2an!Tf2{sFiIu?>TdA_>5oz0pTFhb4-Mq04dA^67>Pa|v?>)pTN0`Hij2&{A zpg}yBP*2IPl&v_y|2qpi#ujhJZd)u_760nG3x3_ZaKk8z$sMOBw|k|W%R`v3SH?}6 zu_&cv*j`)2P1+_I-#xPG(LW={PRdTUmfrmUSlW4oEQ1{c(4X500>k?bhsc9M{FK#h zJGEAnt8NR1N#1GFkR4icIl~jsa#V!UaifH>!`2j+;WhrZl=79Df3SwKy>rFxCG)|away;RskoPsw@Y0ifcS{o*x@vVwGCW+&O7lnWI@}pe6N3vRvg;#3X z&Etw^!nSfw;*j^8jZ%21rV{$MD8gj*MkBd9%GxP2dB}?o)OKlst9IE&m7=L$y?0|( zE>5edrS6p6D3Mt!l?L@zlbwC7yD)hpNHyBzzDm+S8l(Naywnyz1R#V z&KU;|OYI1w`Msrd0Z&UP^ulFLe^e3IQ1}Lk5i|no;k_Awg;PC-e0OgpO*MZ+%z>Jg zr#pEC5Bu)J;)xAYsd-c?v&jNF4_~zrK~24^c<$5Jn-jUF`ACkBNqLy?)D$DL%~bC@ zEX3FWr7CSiRPIfeQufCafdiruR!VIXx$a!=3=t_7N0a?FexhFjuV+p~9D#9M(g^ zVMVO2ahpHF5U#$}>?VKfEoA!b0gd_yQw~GDQHrEYt(5U6^f5}776hNlrF47Fwr(-8 zN?)K_sR`Z?>3~LI&Z*~9xUwAZWM`cjRK1pH$>RJ+hQTlbqY8&GxL1u z!8sP*Zu8H6)%Z;7jdFM|KPXkUN(k#EdNb@U350kT?W;!`ob0>!9$mYX>c2Z2j z;WfQfh^-psrb3yLPeRM#J?gfjw~&jM)zB`f-L|3lYaIW|Ow5Yj5pUe4@93V=>Ex8* zcD3aH-1$21vr;?7wcV@ARZ9i50XTS6bBduAvtO0kOOok@{$3m)?8k-f#JmZ6L|d5_ zOo+5HV$r8@DPBVHVfC27`V0T%SltmpNbP*r6UF9o>6!zXxf)(ox zy9~EVd0hCA-6{#euMg=du(}&|-LVte%k|fKYn>)>Wl9;nw%-|4FR%WvC9t;ud8a~p z{&X$9>1&CS@lCIrEo)uI-zMw^)3wArjd|p_dTNWzjbjxs*5hmaEhVk$W_)iMsK?v! z$`lv8<>V`T7^>Z)zA+Z$O@1d6m%84QV=3@_odWka|A3JUU|)<($7-&hguV z@6MlRBCfaT^-YaC{1$hw5O20JO;bVF_yCH@_5OVBar&o^aan)8J#9~{>_}p;GrgP>58wwM3&k)(|#{ zVT((HTRnmI)ng6E8*1sDFY44U^^U^0zF&W-bnCA@TfLmxLq20gTlosZV>*A`#9Rxh0dd;P8w}qoNdR3vt(<*ngi*sFZ8SSC0$$xD%!BbTYKjYYWYW`>9Qa zNGaR=O#SBPSX~(*&r^2_&1-b)a`)Xrt`Jq=HFT~_r;3wiELx$zKWj)%>1(_@kkOB2 zX+yiL^lTWX|pE}g$pHhY9$0_gyfvF@Z;nBI_CTz7lvugupFU8KWU zrqARyB+K~f@h^2iVdXJa3Q@n7?n@;O1%L zt2p^>-K~i*+sVXCsq5`2d|3Q9NWJA0VL@fKu2decA$ydgQ8w=ow%id4>~yXfqBj?h z79XifU^LgBVT&V)Qm7 z$e!*{OI~5a&N6>qp@iF0mCJ#fgd`;1RKAwz)wkT-GJ!9`Sayo|L|2Z@5U zv=~KYUfjbFnC-XVcU2)W`^0AN$4t8`QKnk_5SBzsNwCTus)8U${3_2>spFiAOSTIl0Wk5I(1iwl!h#_?@C0VQ1w*;81M z<%+Ji&oc!(x4Q{O&*BHngd5{UOCe9kXC|LS;y6Bnvk2L3RoiO`HO&zFke!qW?edf> z^-Y(Yf2Ew2Eda~@hApErnp3Zg*!D%eQ>b86Jp0=)pZ+deD=KK1BNSy!>8rPIE!9?1 zai#jC+gi6f*V2UxYWuMZZIxQIQhOtO{msj!l;eCY^%6{FSe&PIwhB8NHsM=@Q+snd z&84Ww7!fNvUjEJQaaC4yI;Y^oj%M1^7{uk{Z3bDX`v{=zXwnrLi|m#@+)EuV3{eH11*lKvIO z-F`Zcz;DQyaqS40!J^V5+4Fg#0)aVLe_sBFOu- zQl}VE7p2jyCE}>b#quA=7P0A-&oI3C2(w$J0ds6b&Ev)W=JvS_Ut-ghnPq1$d$?fD zTw1WuOs@J6CfmnQFyU)kOvoUucdEq>xo0WK2Z-*gM}dB3O;`dwjH&8uwoeyKHn|*X zLvWI{UdG7IJ`gmufXy&+B=6!_mFXS)gsU-x}&DH9`N)rx4ZO8yZWjUsedSd>N zPWJv_fK@4CpDUt=0f}x0nh1+yey`~{~peiFh@@k=r+hNMV$h=Z5 zi86)M_S1V{12T;c*;%Q`d7szxxJ>E^O{-Fr{1f;tSG{_rL2ih?+O(C_SwY5OnMSMk zY0HjiWSDwFFtoPR{%??6_(%7GRj>6g%|WKdn_Mo)*WYnN%=3x+SxBvH7qC}GpzklO zzm(TwDGc9_PS{GfOfK3THF*I2W>=8DYD|kqI6Px1L1Bfh8@T0ekdV(cBlYYW!l^5R z8D>o#d6ml)MAf`%w8p5U9emr(5$YYBbuO->Pi}b~LF}3QEZCK>#GIG?6k0 z(Eatct7M5457o7D4*w^7tn%A}?txXWWV~CF9teC*A(%V!b1;xJ8G|u~&&;z}s@Va& zqa?KE=52?FLa9;^+7kxMYpDA=Axq1zJDjQLUSzQ}Nz|DQqbkAvu)4y*`!8|5<2NMz9`QE3D8h{+$Xuw{+Fv8w7y0ydu zvU9Bb!dD92Comf~6>8OXLuUkjM^2f%iOtu6c}?#OAP)MsWy5TH-eXJhvWj8Uw8Jh( z6!LjKU4=USB0ScTSnb>~cLsL)!-$@Cz#f!KMDC#^EjY=5tRi{pC$U_0*Acp7Ra*5eI%7Z+vat91&Ou7Tovae z)z&fvLQX9z4J1_RghtPIkw> zQhn{JdhWe+TtX&k)Vq%q4?9;LOs>$ibef=+cG0PNm*bUYb-_Pa5AhJAY!))EhS(Z) z=P%vR7&5Os*F!gUZ+0#lwh?H03EHYraE^X`V&fWOCq(x%qK=Eo5*^DX5U0_p_BkMR zxV~KNJj%$?bA8dbA4%;-rb_NDJVY0p>pu%uM^I8ukEtouI~>DKTZXtRGeq$l<1^(W z*ULVw^^b|zuZR=!Lh1Xg>H#g0-h9IM8|9^;!TzK4%(ZhY)cu+_x6+SSP1fE|wWk`h ze6BN@T5phCV%I%gV+@d|LZ7K7MJsph_dUHdb#ZqH)%sK{yQhZh|2@Yx` z0i;?D#SE~U8zi?~nA5SlSxRwz-kCt0tz;&`9R3c@b18*PWPZJK!|$9XN$fNdlZ=@$cNLYK~|5+AS0>`QOITU_!Rr0_^-Yb8o_IGnZ(t zo{JPuNl4$jws_QT%lGNZ=4X4Kw`?{Apld*N_jhLR8~Gkb8aA0xp~vfGsN6b@DJ0+S z(A?!~*2 z(y2@~bh;2}=di3HSDP!6QnZiI?~t5^2wSwggLINuL(9_%K{7YW_N-xs%^Q*Kg4X<= zi^k8rH+4JqNw0Tm+p%frc5&%7mAXjEkeiz`esL<-fSYFew4gCQ1b+rz1 zqk4~TNx}K42TS^`rE43);C4=bM(`om7GtVY`BQ3h8*s^~-(;0oZ~x=3|3^<^{Xn|B9h&#j~GL&D|qow4RKCG+vBjib7g@o~|MqVuu8^U^<00^Tz zuPH8jTpNOi9kOgT+u0*Sf7ysiU5fni&n5UZa+5q{Y#f45VG7FhT+2?#OEal$+AiM7 z-!$W+{x9tUGIuY8+`I)~mWlDBoc_b@?6BR@f0b z%k9^rdoJ%ECg5;=$lI|U!4DHUx}|z8m2=KIt8Ln~U0_UxJPNrZ_b{1%-&y%7_d89l z_5X=V|DAFlZGDILe@UfQBF1B~yf|)({L?=_e{qB9VgGmMBK0{<{*NLRq+SP; zQCPZB*x&Xum*al!=4S;29H|fr&{~q|VGOz})$I)?3-(-CQX%GgNc)vy4-rNGsudj4 zl+{ZBS4zOKQf{c^RS1#yVCNyi%u!<)*-QY#+-v&h5Etp`gAhvIe?#)MrtZ2o!($Qg zhtcI56$`L0GElV8Y($HAX#7RZyZmkUw7nm^h0mY?aVoiOhxm|w3rE>pIU zyIulNK?9iT-Y79zwoZG%t|=8=Fc)9Q*8!3DQ*ZdCb^1#PA+Xuu6f!g$B|Da4_gBu8 z9HfnM)NlwF#kDscEv<*EaRPFgW)ZL(qmdZl#zitB&jTO8Yuic4;M)nZ&iI_UIUJZ(g*s;TwFBfz z!yUX`5bEG@$%ZUa$70Y_-o_n{ykF#X2bQhSZt@AY869*x*5sU;ZYb9uRwqc8$|<;=sb?sVeS!+nGz+hKCVj>Vs(BLna(G*GqplKg>?`))?8Ztoz( z`^3PF2{&}r$YyrMw?X>)kASK{0%oe|3}c;{htvAEG2*?*F-~7738ixiwQ)!QUzfSE zx#8No+Zg5z3mb>C?_N{7jO_cdetuYc3*oh0HD5Z_lr11e5MiYp?$&GKr^KL%nsLL# zmf(L&Lj1U!bmESG4^=>rb#p0h8pS2H(kGIV$)l^b?@NYx+v^Hhud5~v+PP4TB!9?# zJ0mH{_-)3dd$(DK%-a%DB=g^q@{u=y$#P#)I3)Rh|jDCHp#lDc{eU4>lc(_wj2 z!g9MG@`mJ;9s8vmb`Fre*}m@N01py_u`wEV^`Y6OX<+Cf4mL#KGE%u}G8jx3)GejT zP1NB8145 zZ{xHycYBC~w^71+dACxC_0=m?5r8u%YZU1TjSy^RL>IOTEq2#KhRx2nr!XdL`j+z{ zc{w0lbGIn5wMou+wz&OT&yyH8#%XVQii9YP>RZc#1W54X^i9qX-*)f+XVkHqEnpvN66!e9PvoyY-B7iM3t)RN{x^5m>uzQi%@QZsMM zdqN@z?`lk#Xjf`O1nY1*2#HvCB!4tiHEe%TWteDL-T8;km1^A1X!Sg-70qkXDSC1m z9ko!o%iNL)ur*b7OB% z-D6ojo~hRoo_8Z~l3%?eU|fEb*#Jhr=_fI$hFMO1TaNV`=9=x7mmjtO)u38AL zn}UDH)V`EF;^w+r>ddqrg6~?|1*M2}N@XqOT1L^Mf~!W6x&y?HxbrIVbEQt#u9^&- z9VuM<+jC3Mpd6r{Cf=YHF%0R> zusfaxHC?Imn$G2Sc3veoC_aK_ir*1_{Az;0~M2cm5A!EDcL>bk%D6`I4Ure)_|85t-9)VCtr~6c7R386 zw;&YvvKA^O;ps-zyL3Z@g}?rG=qa=Xa~r3i>bH=X#A~ax$gzfQt!_3&0&4pL8O^UP zx&CB+Up-WQe9n9Ex89`-t)V_eQ$tjnkI%aMb!~UGy+Q=r^~U0O?0Jcrsv&@%YE0*A zikZJ^vu!JsLR~vgI5AdF4-YClx-vUoAy0<5?)2DhM`2~|nV4(plfDtb4f4^Aa~UZ& z>|d3Jw?sOV4E=3R1C^c zj$7sx(Az{;Bfu}`7!MQFu$dt<$RIBKyfWlc^+bw~=#<*B7zKKmfhJ9xx|hS+Jigstkz>_JO|%-B486xtct z+x3T@I|oII#OPKJscVUYF+au-u}Nj3RAhDa1mN!+EMaz~`s{0^SU|7d%p=;4=Re*K z?9;RrqNUuiqqSZ&sV8?Z4C!c|0sI|&53O8xvMEj&6mnX3dyBLIEG~6~`AHQr=olJ0 zIR)fQX%tTFHMy**8Ela9ByVzZNFE<7>!wm{w~y+dtS4(9a*z0re(AG2P(S((bLtKv z9@(N~&&{r)Cn3SQ(|ET#S`;_wS_1BmkINJu9{=DGzlI#~TNK_>MQ_DVWScK`H%jWgMVZP;P*v*h%WZ(TCvp5j z#(=g%eroj&(2z1*s^w{bubsCi{3FNGc4?sAnADsQx4m&y1mw`o3P>K1TsV5Jq}Gk- z?WN7?aaquOM!lW|u2dNY+e{XPD+EK9QKT9r`b-6X>kBG1CCjN{_5jE;O}I?VmZ{P8 zjB|KALc#JE?9b&2v(0=rE}u^fh}R8OPs5DcMqA3}+YobXVBchlnv&2tqd1t}7vW|eY1q*T_(fO*me z(_SyxFARTbHn7R^+<;prK-Ul};)t}qn!ezEm=4|$s9Y;`nKDXwGvH{IGIG-shB#Wu zUT6e(c3CMkgg|OM755zt*}?H0tJ3Y2bVuFwmV8(Sdw^hG!%lwXyn%4f)!S@~lkJwE zk9Q3_hZ$Dw0SUBf;$hdd6l* zSv&QI=%N#wss4To9N$t3jvSvAiMq{|QT3@j?kC?UrR`sDy>MPbT&*9UHMSw$WD^@*9AsTfaf_SH12E({3tfN2fDtCsNw6NOB;YcUE_!2FVG~ z*LG2lu_CTW0~bVn8y%`Iz>C#nO>;lj=?Hl%#SxAYmw;)9B4Z%grW3qSgTjM@NcuaO1YYjeU zfHa`xiVz@k)3!;}&R8W*UZl5e<#*q^|1 zP@J7LMRmQ?Y%}bN?vU;^#M^i)C->*)q%O^>DfcOmx?>ZcO4egg1D1uX2n+I4zUMR7yt8U_!@7ZNw*RCEGsiL@Q-;?<(pZvppq2((0|Yhf=;ZIR~Ob z-5joQh291vnbzGdNH>qn_QYnvqBYfi&%w~JU)|*SOfS`#f9HG=~!cCP=)rKNC@Y`=`N`G20$Wy zI&L}GtM|OGitkdKdJMrP9P+x`E9{moXqvc%x*#-UM4t-vnZ!pt6?vmns3eoEZ&~qc z$YHT`hFj|GkkgIPzWm263dy(&_U+xmhz7tV9@|6?X1;p5YvGWQRcb9;i-ZZ*z^FdO zOf;coilv;C;9jU5TFs~8TGnnBgt@PGW0KB&N5ieE>UE%>)h3nUV<}#8yn`>7=54v> zo3xZr;1;Z2r&WIsxh8F+li+X%-$#2QXcP*4zZwYOKrt(o)Ez29DaQR0fk2hcT z6S7Sg8iSh)xVe$2AJ-K|exy8=B<=rE?LJXeZ>~#U5x4v32*)dXh;&Vz4eQ{Ybfz2Q zFPq)IR$ZAPwcfC9R={SJjVh_=v4PjggC7{4_zxHHb8#uFdBs~>q$ ziQ5C`<(MwkvEI`Bc>1C@^m6=lF1vb*ZO=7$YV3#H0TYINeCadcIPtzipk8BAFP-sP z+TKBW-r$gFe2_l-@b&kqEhVf0EOSmn{26z4u)!OESD%hjl!`~!T^|9cZFeEAkOjX{ zx~TV^dD_(VCYpTJKHHbUaZBJ4jdsr1_H?6`3GQz#1&Z6wx_!pCSjROaYxJf|FM0zg zUVPnof9PR7C{yc#K#3GBF-H&SW649lxsh=vF8j;owtHUooBQVw1b2)Hd;W1;v6(c4 z*Gk`4FKU_`DAi@Fjlvp2XI%YQ6HRvrF8#hSu4w zezh=~N?^UWj$wDY45TgMjXXzu`Z2%xkdK>rmGq}t3B5Jt2&M;+$9*~?gcs-*qjwIw~_ zEA`dO)NTYW8oid@FhS|YYrGq2Tk`Yz8UXk)eWm#OZcM^vtH#Djq-NfYa1E_EMcrY<+y*PPG@v^=V;(IX<}u`Aax)1& zK|ob)#zw08rguf{3{-FABh=|D7GK_-k4pwdPyVN1a>2_&fA z`ervEwIdZ*K#qZP)}8uAK|N9Mr`u*K62C+op=!iad9=ABtklViT+0DPLF^{ga+k$I z?yKlwTr+JItgokqxRZaq{YO`c=4@%N8>PIx9RsCH0}T3mpB$_Z$KWBnzYQC5(LL%w znT3sVgL^syy~Us)mm5s<^rrI$(9>TjA2LC|*|9BdU;gv5XLWq8!6eNW4mtJGwmwqP z^R603uK7f3{D-d+k0<=^69=y(1UHOSMtgJ=h@j4HmEi4ZuM5yOxmwjem z!w8?#(kx0&q8CEj`Q_-jG6mIc%X!LTD!-JPYA~eFmF_5NYAyXFHP2Cf^&FFS0n(S< zs^=cjokgy*R=l}b*7{TG{G-liYSIwbMwFssOVd51%LgHX|2NK@R8wv`{a1*0ya8Bp zOw7t*5CxF#kg0#ubFu$;=3@{}#2qM0aaM?nzjaTcxM!)Fu;6fui7?JNYRQ+p+G**c zePyK2D$+h1^>xO8ud|d;Jn#x_dZTMXB`GnKWl8Dl;9SGS#?;q7&vADi}x_wlR>@$ua9N(ekExLgCA z@}7`ip*t=x*NR5H^D5hv^7K~XxC|iw>)VqONVjvCu2Qk~C-2#;;9kZl%G{3uF1 z07qclbPcJs+1_E}W#kU&)^H@3GFf*DS-4TJB#9^7HLyaM!-q`2MX5PFubzPBoif-B zs(1C*l7sk=OQDOx9}`XVPBnv-ztsqEfc7%u6RC#~>d*9yoL+ye#)f_b-Y1RyE|~F@ zpeK)U*^ke2rM|P%Ws0dz*L$_b3sFM)(Y51%USBM^AFM4%FMF-`Ny=;Kf*V?jcUMoT zZ#%sd(y6Bk6eQk8#as^AJhGVy%d6+b`I`$JJ=T|^@%)*(YY((-t8bhyi977HCu5NC zv_sza?CY)%xvEBoDViQ43HV|+mUlt}(RKZnlYV0u`^AQ-9-BcRfBb_%9W&Z3=y*u_Y)lXC6>%Z9DK5n=E z&aO75;;FAcvTLo&wQe%AzHe1f;hj6F6%l>=`iMoT^WVaH+Ha>bj$0|`=<4yTzLvVC zQ-A8^)mW+1jxmSJS8Dg)LVb#$l*2blw!^9ZvO?Yle@^W@NFy;{t2^>#i`_9mHA3tg zlQf<-&r$BXtJl9j4QcbYzWmN3vGl#CJ_(yO7c`T;SE*hE4{#9bZanpdNqXF6ps;BL z=5*SrYQ0w5CUE#Q71(^R#iH$8RxxJLNWSAF-jGkjWsu;gtg2jgXvkVA)D zJlG)jUV7(8BX7q&;dD(c*QUm~R~lrT)>^bEth{U{;y!Y`MX}XaYVU?sib8ozO(Mk| zJb!wM3W4;|O0WFYmRo7Z{BpjmKbp#&Jh|YYN5anDXD(hf zhSXOLt9$jt7fr?@e!QLm_W0WAl-i~sJuc>wOq(FB>C!?_&&9H6Vwb}Wk(9VHy8+X( zpu4?9p`LfW8Wm*m06=+_19rtx5u)OUH17_EBhfQ`mFmio#*wxG5AnX!olRTzF=@SB zDO-G{SOzVN2D%VfOSdgJB#-Oc1jg)%T%9y1bpPqO1i&F|v9@!R`LQGFSB=A%G^=NJ z*)|a2#v#9JI0YmBWB+l*71vhNi0NF#@k=HB1;d0XAb$yQedC`>IfkW;|A)wYd1D_? zOJeLjf&4)M(uw~ypk`JiJ*!1n|<8?Lk^%TUoD z=spHPlP>qBGJW3Q*VYa})xY%luwTX{!25#47 zhu|7v8|Q}&*;IaO=^>B)ey4}Oes#r+evZM1{ki);?fuZh&-nkO2W^$#+9TxOfePWY zKMLQ8`ay2|Z%(h&FC_7m`+db~{nz#SnbZHq8veP9Kl6KQQRZr&ET?U9a&cu?i(fI$ z6O5^(mkhN^NpQf%pKI~vF>?&)?!ksv^uJq9jEGEN(*cMFpo!l5}pD>@ud6;>-^c?LnZ^i@qgH# zqt*IPOE=cn-_s0+{p{1N#SgaK{F&3wj{l6|Lta}PK*Z=rJwG!Hc`cF5OC|hY(8X8x zSGxGHKX?46y&oC~d35$0Cf@lAU3B^M?)m>o*AKb999{gB`h_k&>`%I=$66ol{H)g- z!_VsfjP!q6!$0@2GCOVWjJPF?!~OlQRH%H9{~5o4aZ&y4unu>Kpd=}xl)M5K(-20H zG_@?~bfd%QC1DF{`v3fs{br3&e*D8M93~ZgtkABYgi-M*p!!|vYY4|OMGNB2;?*;xP0k^*VyJ2w}Qr(es}Yq72J086H$G2yy|)!kaVH_40*>hn%mN$B=@A z`wYt`8R9{m_Q?gKy?fiW^qfyM%__L=3PQ6@HmEENPk``-{kJV}>3-LOL&^kizAT2! zt(D5$+8XRevr^u!Jj5jyELeBk*MHMePmEfp>UHYgCeYk%6@<^}wuQy{kgnFRze|x? zDR-$hs;To;>kX%dDVTTjm7`s?URas!x@!5Oh80$>TKOUaqO>c5W)JxWX$5ahN-l2) zdLUdGE6}?OA#z$P;u(TIJ@r4fo2~^N(J|mUay`S$hON}T#So>)@@Xx52#Z47nmB2F z7A4G!hDTwd*>?zqI*-Cw&b8zil*4rO{Hw`@l}O+pcIuU4$&Ob4s|Vm$ro8^I9@FUR z73foMZ#{)@?zab!%*&N=3$O!J>)*i_p*~jN++0gt0$a7>gjLHzzgi2>4C3I~m~fQZ zrkmt*zG~ubL(2Jj^;~vYQ~z3mUj26^YOCqi&$X0SbO^80SFi6ZhcV4=lw9&x?_Qg( zrHsSMAflpqn_XXqSX;a7rWA_4)}>+I`nqQL>U9z4>Pf9UN{Fp&RJ*IY*7pi#EtLp# zh@HB6y9GY1i+_zksnI>ETpZ>$b{JBVGCM^O9T9B$nq zrDcY=#Bj6+%U{#(@HV!E$&f5mh+R5F*zVD%w5hjRF16H_Qp@o659u8bQM&11GDn^~ z2jko;{m9r6KT>D?oiyQQJsRR8eBHg3(#@mu-9gYyFN)PUd3WThxxeV95dU|o7VZg? zOMeY>SSNj@ zm~pwpTkJd;vZTsZc*|ceAuR7)fR!@78YdfeHz*{JzqQ~B$(0_`6B;38TK<{C5*%UO zCm%BD7P4z()hj?y8CJo!-N|4`pCYJ|3=xx!J&is3M_V@FN49$rs@e9pT$pX*t)pf> z?qrBJ9MmvzyRF_T84&;3)$6)MTRUz0%f(_9K511|aP+IcUlYGzs63O|8m6Fd{XE^-F3PrRlLk?f~xKcd6 z|D`SBbMG=i_$D1Bgu}qJZ_#22mXVjh!KbmN8i;Ap@naD z{^g~4v4;frbPS|a_M6s*3kMvZl*OF_;?wv9N zb02msxdd?4yHpB4 zGF<sf? zjk`=3CqTn`vu;IE#x!ec3Nyc3w?pcVZ=vnv|DBc#5goimDKz7nMN>hM?SOg(lD13< zfwjG+E$-#F2YKi1w#ikB_;KFK^!hesud_p3q@}S#$nIN9dVT2wVa`N@GP^{-{#_Hg zhHOEzLtdAcQ{(2c9iY6mCfY97vB@o_JtUt|2)_6Aw!GwFxrJ8>4QNTJT^gvRzQQu( z+XJJNoj7da=|(AUwqdHrC#0p)Vnj+BrYl6(-@LA!vl1{09N6-1_YawuDTF0=h~)e4 z2vZ>vCRSL?P`w!4XR;UBp34m72ZRsou!Tk$bxkHXaE} zKCShXnAO|!U-jo6-L>R%*6+AtKexyK+D+q1HTfI)cw|W1U@BdSxl_&y_L^GmiE5HG zZV?FoH@)IF)w3@jM?~GXoc?yD$_Lv*%|>qEzcC~Iol;9ViiT34mKkyjPn!$d#fcC% zRO7FZeMtj?cQ+mNdf@)fabetHGKJzuZ0SA(7hm3bgrp?}bmesXHBF5~2;*~T@Ll=d zv4!jyD?Ot`5nA$bL|Eb2s$uYHdX*a6>gy)kWJr8yWy-_2QSKJauwH#wz1teaP58Cs z^lV6dGVSUyuW#t$xDj^Uj1){N#dt`zd-bf$H$4v2R=9Z@L#15)?$9W;m}kh$#w}D6>`UMgDTzpYN68^!woKEUn8y-LpvMKw#cHrb8HFP0>< z16_Rxqlh*WOr~dZR!Y=*h{WPXT{0a0Q@!LG_JN@-Z4EO6mJ1 z)x(3kLAAM*Cll8wkR2c?Eo&~?drFNw=5Nb=W2jQoZW7>j>^3Des_-%7tiTC*E!Cak z>6DY#*{eGY%;WXP%YI0i@C`r?)U8UQ>XBiYE(TRY(-Qf1%I6FD{rv1y{f)RxLyrj- zHYWGIa=6EHI=25LO8*ifBHSVry={qAL)>?aWhRUzz`U_=Y{E&Zj2D3KxA6Ye$`iAr zE~MT1Dg-)NL6J1Qke;HbGq;pbVaPwG4?=Rrzj{I_*OWAtm3p+Q)WlE&m`VXi0k~@7 z!8dN3wps*4^rTR?E9;G8uk{T+-Kszx&%6iT6NW8 z#UV?*uT~#%8gQPoL2qq|-&+!l;N%hy!cCSl?^;HZBLemQ*1JscdrIdG(hbNEqJ260 zqFap6judg&v$iG&bHV10l$XFeiJYTryr^Il*9#)sf5g;oRf~br?dKhgU2%qZJ?3%8 z)mmaAcgCch%)*-YbG01%^5i<2WcHOI3m@yB zVv7%OCawr(c@C+zaI3qB=T#HazEWHyoeQ%5i2`nhW1!AL35WGoea8vXRpjx%g zOVjA|KfVjXoE~Q1DBmMC}ll(w0O-2@831qSejG{~0t3GNKTNAS{tW6li9eCw5x#+AC5sW`ex zGg@X>1kdWM@q8ie5@g9tAw2Q#FfsF2ru5u6no@4Rb#!{PCc_)j$IaGIL5YChc+iP^ z+Zlm2sxGO|BEg`0F>F|$I!PSNJ_>uVF#G%`#+W&@i_a4nQ zxHCiBhb={G7>iat!ZHmvL|T!9S(#CR@XkG1HmHYMA|8756(YvdtdZDqu2jQ`AJN~l zm*ett{%hPjTaWQ(xz`=rBw`h+WY;Uym6-qhTN&{?FbExd zNbhM>hHrPQr&5bB8M-OGdW?acA>!cG>*cGa=Xjp1QSU@IHrk9ew5yq|3tv!ty&~^? zdbfV+R9JEGx1lSvN1fXkA@-qz;^wFgak7UH+sU?ec1N9%OSD{njLTXlKX#9*QnyY?ln5cDbFwnH_YQX0 zn1oXQHJJ!W7Om9o2v%?YrL{fYy2hun*LblEh^OCLCxc2Y7}DLuA$tt-u(7g6UUq|O z&v1e4@z4-Yec4S&2FuOvDJrlMMHO;g{st*!;~}T%lh*jctCkaJO;Lc~R&|wSjW3N} zOXnx5+PUmO{&|I5e0hY?_57;cm3n2KoPxwiZc?cWnHo@DbUp-T(5Y8AqIlyFncX#ZA~&>e|h+|lrR|?XsPV{m^*U1bFR@-?ep#=zqQm8 ziWOo*-gf>+H-SS;Zm#w=wB+zyH_7UVpft^Xdy(Pz#e8-{x*gOY$pY`|uM`6#Et_aR z-H`gV2U8$KbPHEYPZhlsxFBrqblvtA>y7lcBS_d(nSaMX`H{{6M}4~|rM62?qdeop9-aFd^(?bh z_pV5ECZa>H@?CEz`C)U%D@D0DncUZsYnbQ%=DH{4Uo~>&nz9fh5(>vFwO1^f?S*7? zhgh!Kv~DzhR7*@PrrwD5%>tENv^^bR#Co+jI$md~*tN{KSnqx6=#ZX=Yij#A=vCth zj6ymGubz8tx7U&pZ)$zI=j5d#SB)xDSz)POsIkq zQWfGX%vuRKj_XyLSF0O;O)lBEcHC92FTYPV>;04bBGpX|BI)CC^L;aD<3_Djvpg-N zsg)`c!q*XE_EJ+`XQbw*>J&gxibi*9dkG=c%O)P1yvy!ut3k%&wz;K)tR07>E3}p1 z6l-fa080gaQ%ea7lV)@)vKt<;ck=9=B#N0bL}Oozx&3yJzP5GoN?JnW>Dt4nXFJ!++J54G^igqjK_;`%0li9dB#3Xv7^k=Y@uPwUB%x z>VQsCRcH(*cf@A9Y7rBu)_t5#YGKtij`{D3bx5z`REiI;4WB6ic&5bJ7j*yL^e9h9 zj_My-j6U??c{{5B)5ZxaE+jiO_gjv!MAMioL*V3@?!V{fyG6GeI06ylt0J4sYV z+z@xWK50ppXb2{@i!4gvg%+lKphXT1$-2;LLV6CmwKB|}e;tNUhFDm1P)jXGW!xLM zA@PIXFkvWoNly+}@)4)(ji1KpG&f<$g7G1FUami-Z|w8AR!W5RS`sq4{_HiCKJCxfsERUo%4lUny5qvVDs4St=>|O|M#JDdjK-hba{ZZ_-M0@I{P9$ud zzIyY2g*mZJhThdzDMskssUNaLzDQsG#-x%G|DU?$^*Be@&FyZbxvzE&$)7hnnKz7dq&?TL>1x%Z& zncF6kvugGXCSS@y?YKa32bQz$BQOgdM#rMASU9?&69GZTM<%|0)Nj>$Z}iBki-AGN zrBy@UI10o%9MxcQQCnui<1%^n8(|ULA`6|ceNZ&o67P+LJF4@i<;)JLGm0c%04n9v zI89TI{+$!|Mj|#PauZa>b7)^JO4gkdm!pmi^ccokk{NfsL0*|hA`bmR1U0o}*BXx! zcTDE>4C%#=b;sJ?^22h;4%>^|N?jcOj@J#GX>pv%UGrn2>h$s3za^s1kR0v7K9T{(YNLDOZxVlc_5MqMut!ufM-)r%M(4e+-mP&@kJ}HvoxY z_`;eZhHiSgYwd8RY23Q=3czu+-`KPMIE8%WX_<37n@#1H3WLbyJg3*^bMu!~s2O52E=)LZeXIK&b|`{vS#Z}09} zuxfifEriB#qilWWWK3b`7T!wD&|xWc4QKQ1eq5r*`v()YO3@rz@uekPe|vd9q{UcE zn9wV8pZuvU-8Cxp++5RoamfjqY{e|A$X7f^8T5+{jW*NLCN+$6N`X?6!lEdGbTR`% z6+MJqdh?@H8rDj2u1A{$%Gsz^A>P`NnobarpB){<1G8Fm(ngtjym%;yP#87DW}HI; zBfhye2y6cJnrq!KbdM=e98eIYf0IKB4O8Q3SUNMBi>uj%9oo(o<>; z6ZiY3$A5g2kymo7DMoUfNu>A?IXSlkj_h&E(L-AvZ_Mz~y7=+6#8-T~AUXENxt+e{ zlsItwqhRr!gTjQh?XBX#AQ-JWl#8thYwsHPEyFvM*+HNj$9 zILPepREvAqbC}yVhQO|A>LFvxA}N|8X(7OgM86!IW?Es^7L1tsQ-5a2CT*N~+t@8$K7A&^=~Apvpgb z7rP}h7|;=uq=Gw5XPqeXn_-|{<^p=WTq_zuAN7-erI6(pQXZ*GSLSIu3%0AXZ$MXz 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
j-W#m4yaof*XY^a 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

#6miE5>&@#h+N^~@_UJ5x4}Bxu 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≠51af;%FZ|H`=znVUY9qi2qggQD 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

}U>gZ3J~IQ;s9R&N?q1Xl`H_9THz6 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 literal 0 HcmV?d00001 From f8224ccad0866736847172aec45a21e72ab8068c Mon Sep 17 00:00:00 2001 From: cheryl Date: Mon, 11 Nov 2024 20:14:06 -0500 Subject: [PATCH 15/62] readme updated --- README.md | 95 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index d00d06e94..5eb93025a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,28 @@ -**Joke Machine** +# Joke Machine -Team Name: Joke Machine -Domain: Joke Generation and Explanation -Project for Group #269 +### Project for Group #269 +#### Team Name: Joke Machine +#### Domain: Joke Generation and Explanation -Table of Contents - Software Specification - Features - User Stories - Entities - Proposed API - Setup and Installation - Usage - Contributing - License - Contact -Software Specification + +## Table of Contents + +* Software Specification +* Features +* User Stories +* Entities +* Proposed API +* Setup and Installation +* Usage +* Contributing +* License +* Contact + +## Software Specification Joke Machine is a joke generation and explanation platform that allows users to generate, search for, save, and understand jokes. Users can generate or search up jokes, ask for explanations, and sort their list of favorite jokes based on rating of the jokes. Joke Machine integrates with external APIs for joke generation and explanation to provide rich and diverse humor content. -Features +## Features Joke Generation: Generate new jokes with a variety of themes and styles. Joke Explanation: Explain jokes, whether generated by the app or provided by the user. Favorites Management: Save favorite jokes to revisit later. @@ -28,46 +31,44 @@ Features Search for jokes within saved list of jokes Filter jokes by rating to find the "funniest" jokes. -User Stories - Bob generates a joke. He then keeps generating new jokes with different specifications until he is tired. - Bob was told a joke but he doesn't understand it. He runs the joke explanation program and the program explains to him what is funny about the joke. - Bob finds some jokes funny and saves them as favorite. He later wants to revisit the jokes that were favorited, so he revisits his list of saved jokes. - Bob remembers a joke vaguely, he only remembers that it was about 911. He searches “911” and a few different jokes pop up. - Bob wants to find a specific saved joke, he doesn’t remember what the joke said but he remembers the explanation. He then goes into his list of saved jokes and searches by keywords in the explanation. - Bob wants to find some really funny jokes. He presses the “Funniest” button in the saved view, then the program returns the joke with the highest score. +## User Stories +* Bob generates a joke. He then keeps generating new jokes with different specifications until he is tired. +* Bob was told a joke but he doesn't understand it. He runs the joke explanation program and the program explains to him what is funny about the joke. +* Bob finds some jokes funny and saves them as favorite. He later wants to revisit the jokes that were favorited, so he revisits his list of saved jokes. +* Bob remembers a joke vaguely, he only remembers that it was about 911. He searches “911” and a few different jokes pop up. +* Bob wants to find a specific saved joke, he doesn’t remember what the joke said but he remembers the explanation. He then goes into his list of saved jokes and searches by keywords in the explanation. +* Bob wants to find some really funny jokes. He presses the “Funniest” button in the saved view, then the program returns the joke with the highest score. -Entities - User +## Entities +### User Attributes: name: User's name for login. password: User’s password. favorite: A list of saved jokes marked as favorites. - Joke +### Joke Attributes: content: The joke text. explanation: The joke's explanation or humorous insight. score: Humor rating to indicate how funny the joke is. -Proposed API - Google Gemini: Used for natural language understanding and generation. Assists in explaining user-provided jokes. - JokeAPI: Used for joke retrieval and generation, allowing for a diverse and randomized joke collection. +## Proposed API +* Google Gemini: Used for natural language understanding and generation. Assists in explaining user-provided jokes. +* JokeAPI: Used for joke retrieval and generation, allowing for a diverse and randomized joke collection. -Setup and Installation - Clone the Repository: - Install Dependencies: - Run the Application: +## Setup and Installation +* Clone the Repository +* Install Dependencies: +* Run the Application: -Usage - Generating Jokes - Select the "Generate" button to create a new joke. - Or - Search up joke by title or keyword - Explaining Jokes - If you don’t understand a joke, click on the "Explain Joke" button. +## Usage +### Generating Jokes +* Select the "Generate" button to create a new joke or search up joke by title or keyword +### Explaining Jokes +* If you don’t understand a joke, click on the "Explain Joke" button. The system will provide an explanation of the joke's humor or meaning. - Saving Favorites - Click "favorite" to add a joke to your favorites list. - Access your favorites anytime from the "favorited" section. - Searching and Filtering - Keyword Search: Enter a keyword (e.g., "911") to find jokes related to that theme. - Funniest Jokes: Use the "Funniest" filter to sort saved jokes by their humor rating. +### Saving Favorites +* Click "favorite" to add a joke to your favorites list. +* Access your favorites anytime from the "favorited" section. +### Searching and Filtering +* Keyword Search: Enter a keyword (e.g., "911") to find jokes related to that theme. +* Funniest Jokes: Use the "Funniest" filter to sort saved jokes by their humor rating. From 924b297416071a80f9b3c4bf6caef66f0d596e26 Mon Sep 17 00:00:00 2001 From: dengxues Date: Mon, 11 Nov 2024 20:16:13 -0500 Subject: [PATCH 16/62] Add UserFactory and Create Favourite use_case folder --- src/main/java/entity/UserFactory.java | 25 +++++++++++++++++++ .../favourite/FavouriteInputBoundary.java | 15 +++++++++++ .../favourite/FavouriteInputData.java | 4 +++ .../favourite/FavouriteInteractor.java | 4 +++ .../favourite/FavouriteOutputBoundary.java | 4 +++ .../favourite/FavouriteOutputData.java | 4 +++ .../FavouriteUserDataAccessInterface.java | 4 +++ src/main/java/view/NoteView.java | 2 +- 8 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/main/java/entity/UserFactory.java create mode 100644 src/main/java/use_case/favourite/FavouriteInputBoundary.java create mode 100644 src/main/java/use_case/favourite/FavouriteInputData.java create mode 100644 src/main/java/use_case/favourite/FavouriteInteractor.java create mode 100644 src/main/java/use_case/favourite/FavouriteOutputBoundary.java create mode 100644 src/main/java/use_case/favourite/FavouriteOutputData.java create mode 100644 src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java new file mode 100644 index 000000000..6f54b420e --- /dev/null +++ b/src/main/java/entity/UserFactory.java @@ -0,0 +1,25 @@ +package entity; + +import java.util.List; + +/** + * Factory for creating users. + */ +public class UserFactory { + /** + * Creates a new User. + * + * @param name the name of the new user + * @param password the password of the new user + * @param favorites the list of user's favourite joke(s) + * @return the new user + */ + User create(String name, String password, List favorites) { + return new User(name, password, favorites); + } + + User create(String name, String password) { + return new User(name, password); + } + +} diff --git a/src/main/java/use_case/favourite/FavouriteInputBoundary.java b/src/main/java/use_case/favourite/FavouriteInputBoundary.java new file mode 100644 index 000000000..bd26d63ec --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteInputBoundary.java @@ -0,0 +1,15 @@ +package use_case.favourite; + +public interface FavouriteInputBoundary { + + /** + * Executes the favourite use case. + * @param favouriteInputData the input data + */ + void execute(FavouriteInputData favouriteInputData); + + /** + * Executes the switch to login view use case. + */ + void switchToFavouriteView(); +} diff --git a/src/main/java/use_case/favourite/FavouriteInputData.java b/src/main/java/use_case/favourite/FavouriteInputData.java new file mode 100644 index 000000000..857a5c28d --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteInputData.java @@ -0,0 +1,4 @@ +package use_case.favourite; + +public class FavouriteInputData { +} diff --git a/src/main/java/use_case/favourite/FavouriteInteractor.java b/src/main/java/use_case/favourite/FavouriteInteractor.java new file mode 100644 index 000000000..ec5b9874f --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteInteractor.java @@ -0,0 +1,4 @@ +package use_case.favourite; + +public class FavouriteInteractor { +} diff --git a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java new file mode 100644 index 000000000..cd33b5d66 --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java @@ -0,0 +1,4 @@ +package use_case.favourite; + +public interface FavouriteOutputBoundary { +} diff --git a/src/main/java/use_case/favourite/FavouriteOutputData.java b/src/main/java/use_case/favourite/FavouriteOutputData.java new file mode 100644 index 000000000..6faf05ff0 --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteOutputData.java @@ -0,0 +1,4 @@ +package use_case.favourite; + +public class FavouriteOutputData { +} diff --git a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java new file mode 100644 index 000000000..7b3e7b4f2 --- /dev/null +++ b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java @@ -0,0 +1,4 @@ +package use_case.favourite; + +public interface FavouriteUserDataAccessInterface { +} diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index a4bf2b260..81e52e1a6 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -57,7 +57,7 @@ private void setupButtons() { if (query != null && !query.trim().isEmpty()) { jokeController.execute("search", query); } - }) + }); favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); } From 950ae9b64bac859b411327b449061872c585527d Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Mon, 11 Nov 2024 20:43:55 -0500 Subject: [PATCH 17/62] set up 3 and Demo --- .../generate/adapter/DemoBuilder.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/use_case/generate/adapter/DemoBuilder.java b/src/main/java/use_case/generate/adapter/DemoBuilder.java index a61891367..15032db6e 100644 --- a/src/main/java/use_case/generate/adapter/DemoBuilder.java +++ b/src/main/java/use_case/generate/adapter/DemoBuilder.java @@ -3,8 +3,23 @@ import data_access.JokeDataAccessObject; import use_case.generate.GenerateInteractor; +import javax.swing.*; + public class DemoBuilder { - public static void build() { - new GenerateController(new GenerateInteractor(new JokeDataAccessObject(), new DemoGeneratePresenter())).execute(); + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + public static JFrame build() { + + + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Joke Machine"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(new DemoAppView()); + + return frame; + } } From a3146e710ff4eee7d56e9ad23bfeb9532621874d Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Mon, 11 Nov 2024 20:50:53 -0500 Subject: [PATCH 18/62] Structure --- src/main/java/use_case/add_to_fav/AddInteractor.java | 4 ++++ src/main/java/use_case/fav_search/FavSearchInteractor.java | 4 ++++ src/main/java/use_case/funniest/FunniestInteractor.java | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 src/main/java/use_case/add_to_fav/AddInteractor.java create mode 100644 src/main/java/use_case/fav_search/FavSearchInteractor.java create mode 100644 src/main/java/use_case/funniest/FunniestInteractor.java diff --git a/src/main/java/use_case/add_to_fav/AddInteractor.java b/src/main/java/use_case/add_to_fav/AddInteractor.java new file mode 100644 index 000000000..645a062c4 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddInteractor.java @@ -0,0 +1,4 @@ +package use_case.add_to_fav; + +public class AddInteractor { +} diff --git a/src/main/java/use_case/fav_search/FavSearchInteractor.java b/src/main/java/use_case/fav_search/FavSearchInteractor.java new file mode 100644 index 000000000..e0d87365b --- /dev/null +++ b/src/main/java/use_case/fav_search/FavSearchInteractor.java @@ -0,0 +1,4 @@ +package use_case.fav_search; + +public class FavSearchInteractor { +} diff --git a/src/main/java/use_case/funniest/FunniestInteractor.java b/src/main/java/use_case/funniest/FunniestInteractor.java new file mode 100644 index 000000000..5c4622185 --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestInteractor.java @@ -0,0 +1,4 @@ +package use_case.funniest; + +public class FunniestInteractor { +} From edaf94008db6cb124158be708037478f3875dc03 Mon Sep 17 00:00:00 2001 From: five Date: Mon, 11 Nov 2024 20:51:43 -0500 Subject: [PATCH 19/62] DemoSearchView complete --- .../search/SearchController.java | 4 -- .../interface_adapter/search/SearchState.java | 4 -- .../search/SearchViewModel.java | 4 -- .../search/adapter/SearchBuilder.java | 24 +++++++ .../search/adapter/SearchController.java | 7 ++ .../search/adapter}/SearchPresenter.java | 2 +- .../use_case/search/adapter/SearchState.java | 4 ++ .../search/adapter/SearchViewModel.java | 11 +++ src/main/java/view/SearchView.java | 68 +++++++------------ .../view/helper_functions/LabelTextPanel.java | 15 ++++ .../java/use_case/search/DemoSearchTest.java | 10 +++ 11 files changed, 97 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/interface_adapter/search/SearchController.java delete mode 100644 src/main/java/interface_adapter/search/SearchState.java delete mode 100644 src/main/java/interface_adapter/search/SearchViewModel.java create mode 100644 src/main/java/use_case/search/adapter/SearchBuilder.java create mode 100644 src/main/java/use_case/search/adapter/SearchController.java rename src/main/java/{interface_adapter/search => use_case/search/adapter}/SearchPresenter.java (50%) create mode 100644 src/main/java/use_case/search/adapter/SearchState.java create mode 100644 src/main/java/use_case/search/adapter/SearchViewModel.java create mode 100644 src/main/java/view/helper_functions/LabelTextPanel.java create mode 100644 src/test/java/use_case/search/DemoSearchTest.java diff --git a/src/main/java/interface_adapter/search/SearchController.java b/src/main/java/interface_adapter/search/SearchController.java deleted file mode 100644 index 1e3712665..000000000 --- a/src/main/java/interface_adapter/search/SearchController.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.search; - -public class SearchController { -} diff --git a/src/main/java/interface_adapter/search/SearchState.java b/src/main/java/interface_adapter/search/SearchState.java deleted file mode 100644 index 70a54441b..000000000 --- a/src/main/java/interface_adapter/search/SearchState.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.search; - -public class SearchState { -} diff --git a/src/main/java/interface_adapter/search/SearchViewModel.java b/src/main/java/interface_adapter/search/SearchViewModel.java deleted file mode 100644 index 1a716b6cd..000000000 --- a/src/main/java/interface_adapter/search/SearchViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.search; - -public class SearchViewModel { -} diff --git a/src/main/java/use_case/search/adapter/SearchBuilder.java b/src/main/java/use_case/search/adapter/SearchBuilder.java new file mode 100644 index 000000000..21a4a059c --- /dev/null +++ b/src/main/java/use_case/search/adapter/SearchBuilder.java @@ -0,0 +1,24 @@ +package use_case.search.adapter; + +import view.SearchView; + +import javax.swing.*; + +public class SearchBuilder { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + public static JFrame build() { + + final JFrame frame = new JFrame(); + final SearchViewModel viewModel = new SearchViewModel(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Search"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(new SearchView(viewModel)); + + return frame; + + } +} diff --git a/src/main/java/use_case/search/adapter/SearchController.java b/src/main/java/use_case/search/adapter/SearchController.java new file mode 100644 index 000000000..40df52389 --- /dev/null +++ b/src/main/java/use_case/search/adapter/SearchController.java @@ -0,0 +1,7 @@ +package use_case.search.adapter; + +public class SearchController { + public void execute(String text) { + + } +} diff --git a/src/main/java/interface_adapter/search/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java similarity index 50% rename from src/main/java/interface_adapter/search/SearchPresenter.java rename to src/main/java/use_case/search/adapter/SearchPresenter.java index eebd90b28..65ad6eaf2 100644 --- a/src/main/java/interface_adapter/search/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -1,4 +1,4 @@ -package interface_adapter.search; +package use_case.search.adapter; public class SearchPresenter { } diff --git a/src/main/java/use_case/search/adapter/SearchState.java b/src/main/java/use_case/search/adapter/SearchState.java new file mode 100644 index 000000000..bc016ca1a --- /dev/null +++ b/src/main/java/use_case/search/adapter/SearchState.java @@ -0,0 +1,4 @@ +package use_case.search.adapter; + +public class SearchState { +} diff --git a/src/main/java/use_case/search/adapter/SearchViewModel.java b/src/main/java/use_case/search/adapter/SearchViewModel.java new file mode 100644 index 000000000..71bcbedc3 --- /dev/null +++ b/src/main/java/use_case/search/adapter/SearchViewModel.java @@ -0,0 +1,11 @@ +package use_case.search.adapter; + +import view.SearchView; + +public class SearchViewModel { + public static final String TITLE_LABEL = "Search"; + + public void addPropertyChangeListener(SearchView searchView) { + + } +} diff --git a/src/main/java/view/SearchView.java b/src/main/java/view/SearchView.java index d02fa2be7..86d6d5699 100644 --- a/src/main/java/view/SearchView.java +++ b/src/main/java/view/SearchView.java @@ -9,82 +9,64 @@ 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.JTextField; -import interface_adapter.search.SearchController; -import interface_adapter.search.SearchState; -import interface_adapter.search.SearchViewModel; +import use_case.search.adapter.SearchController; +import use_case.search.adapter.SearchViewModel; +import view.helper_functions.LabelTextPanel; public class SearchView extends JPanel implements ActionListener, PropertyChangeListener { - + private final String viewName = "Search"; private final SearchViewModel searchViewModel; private final JLabel search = new JLabel("Enter keyword to find a joke:"); - private final JTextArea keywordInputField = new JTextArea(); + private final JTextField keywordInputField = new JTextField(15); private final JButton searchButton = new JButton("Search"); + private final JButton cancelButton = new JButton("Cancel"); private SearchController searchController; public SearchView(SearchViewModel searchViewModel) { - - search.setAlignmentX(Component.LEFT_ALIGNMENT); - this.searchViewModel = noteViewModel; + this.searchViewModel = searchViewModel; this.searchViewModel.addPropertyChangeListener(this); + final JLabel title = new JLabel(SearchViewModel.TITLE_LABEL); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel searchBox = new LabelTextPanel(this.search, this.keywordInputField); + final JPanel buttons = new JPanel(); buttons.add(searchButton); + buttons.add(cancelButton); searchButton.addActionListener( - evt -> { - if (evt.getSource().equals(saveButton)) { - noteController.execute(noteInputField.getText()); - + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(searchButton)) { + searchController.execute(keywordInputField.getText()); + } } } ); - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - noteController.execute(null); - - } - } - ); + cancelButton.addActionListener(this); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(noteName); - this.add(noteInputField); + this.add(title); + this.add(searchBox); 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 actionPerformed(ActionEvent e) { + } @Override public void propertyChange(PropertyChangeEvent evt) { - final NoteState state = (NoteState) evt.getNewValue(); - setFields(state); - if (state.getError() != null) { - JOptionPane.showMessageDialog(this, state.getError(), - "Error", JOptionPane.ERROR_MESSAGE); - } - } - - private void setFields(NoteState state) { - noteInputField.setText(state.getNote()); - } - public void setNoteController(NoteController controller) { - this.noteController = controller; } } diff --git a/src/main/java/view/helper_functions/LabelTextPanel.java b/src/main/java/view/helper_functions/LabelTextPanel.java new file mode 100644 index 000000000..0b74cc6cb --- /dev/null +++ b/src/main/java/view/helper_functions/LabelTextPanel.java @@ -0,0 +1,15 @@ +package view.helper_functions; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +/** + * A panel containing a label and a text field. + */ +public class LabelTextPanel extends JPanel { + public LabelTextPanel(JLabel label, JTextField textField) { + this.add(label); + this.add(textField); + } +} \ No newline at end of file diff --git a/src/test/java/use_case/search/DemoSearchTest.java b/src/test/java/use_case/search/DemoSearchTest.java new file mode 100644 index 000000000..cf1f89e27 --- /dev/null +++ b/src/test/java/use_case/search/DemoSearchTest.java @@ -0,0 +1,10 @@ +package use_case.search; + +import org.junit.Test; +import use_case.search.adapter.SearchBuilder; + +public class DemoSearchTest { + public static void main(String[] args) { + SearchBuilder.build().setVisible(true); + } +} From 452e9cf69651cef47bea1e4f33a0861db6d07372 Mon Sep 17 00:00:00 2001 From: GUO YU HE <162621600+GuoYuHeJason@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:00:34 -0500 Subject: [PATCH 20/62] Create ProjectLog --- ProjectLog | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ProjectLog diff --git a/ProjectLog b/ProjectLog new file mode 100644 index 000000000..72d144064 --- /dev/null +++ b/ProjectLog @@ -0,0 +1,17 @@ +Jason GenerateDataAccessObjects, sending requests to joke api, google gemni api +All initial draft design +Alex intitial main gui (View, ViewModel) +Cheyl Read.md completed +Cheyl Finalized UI design +Jason User and Joke entity +K1bbu7z User factory, Favrite UI + + +TODO +K1bbu7z : Funnist Use Case +Mika: Search Use Case +Alex: Fav_search Use Case +Cheyl: add to fav Use Case, Fav joke display pannel + + + From a275e92f6b8116d1848f7a8de33969de00d4e983 Mon Sep 17 00:00:00 2001 From: dengxues Date: Mon, 11 Nov 2024 21:01:34 -0500 Subject: [PATCH 21/62] class over --- src/main/java/entity/UserFactory.java | 4 +-- .../favourite/FavouriteState.java | 4 --- .../favourite/FavouriteViewModel.java | 4 --- .../adapter}/FavouriteController.java | 2 +- .../adapter}/FavouritePresenter.java | 2 +- .../favourite/adapter/FavouriteState.java | 4 +++ .../favourite/adapter/FavouriteViewModel.java | 19 ++++++++++++ src/main/java/view/FavouriteView.java | 30 +++++++++++-------- src/main/java/view/ViewManagerModel.java | 14 +++++++++ 9 files changed, 58 insertions(+), 25 deletions(-) delete mode 100644 src/main/java/interface_adapter/favourite/FavouriteState.java delete mode 100644 src/main/java/interface_adapter/favourite/FavouriteViewModel.java rename src/main/java/{interface_adapter/favourite => use_case/favourite/adapter}/FavouriteController.java (50%) rename src/main/java/{interface_adapter/favourite => use_case/favourite/adapter}/FavouritePresenter.java (50%) create mode 100644 src/main/java/use_case/favourite/adapter/FavouriteState.java create mode 100644 src/main/java/use_case/favourite/adapter/FavouriteViewModel.java create mode 100644 src/main/java/view/ViewManagerModel.java diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java index 6f54b420e..e8fcdb71e 100644 --- a/src/main/java/entity/UserFactory.java +++ b/src/main/java/entity/UserFactory.java @@ -9,8 +9,8 @@ public class UserFactory { /** * Creates a new User. * - * @param name the name of the new user - * @param password the password of the new user + * @param name the name of the new user + * @param password the password of the new user * @param favorites the list of user's favourite joke(s) * @return the new user */ diff --git a/src/main/java/interface_adapter/favourite/FavouriteState.java b/src/main/java/interface_adapter/favourite/FavouriteState.java deleted file mode 100644 index 6f9d31e42..000000000 --- a/src/main/java/interface_adapter/favourite/FavouriteState.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.favourite; - -public class FavouriteState { -} diff --git a/src/main/java/interface_adapter/favourite/FavouriteViewModel.java b/src/main/java/interface_adapter/favourite/FavouriteViewModel.java deleted file mode 100644 index 25d6f3d2a..000000000 --- a/src/main/java/interface_adapter/favourite/FavouriteViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.favourite; - -public class FavouriteViewModel { -} diff --git a/src/main/java/interface_adapter/favourite/FavouriteController.java b/src/main/java/use_case/favourite/adapter/FavouriteController.java similarity index 50% rename from src/main/java/interface_adapter/favourite/FavouriteController.java rename to src/main/java/use_case/favourite/adapter/FavouriteController.java index 446b23e6a..e54b9bd93 100644 --- a/src/main/java/interface_adapter/favourite/FavouriteController.java +++ b/src/main/java/use_case/favourite/adapter/FavouriteController.java @@ -1,4 +1,4 @@ -package interface_adapter.favourite; +package use_case.favourite.adapter; public class FavouriteController { } diff --git a/src/main/java/interface_adapter/favourite/FavouritePresenter.java b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java similarity index 50% rename from src/main/java/interface_adapter/favourite/FavouritePresenter.java rename to src/main/java/use_case/favourite/adapter/FavouritePresenter.java index d14dc09b0..8426f3996 100644 --- a/src/main/java/interface_adapter/favourite/FavouritePresenter.java +++ b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java @@ -1,4 +1,4 @@ -package interface_adapter.favourite; +package use_case.favourite.adapter; public class FavouritePresenter { } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteState.java b/src/main/java/use_case/favourite/adapter/FavouriteState.java new file mode 100644 index 000000000..18962f73d --- /dev/null +++ b/src/main/java/use_case/favourite/adapter/FavouriteState.java @@ -0,0 +1,4 @@ +package use_case.favourite.adapter; + +public class FavouriteState { +} diff --git a/src/main/java/use_case/favourite/adapter/FavouriteViewModel.java b/src/main/java/use_case/favourite/adapter/FavouriteViewModel.java new file mode 100644 index 000000000..13bf01d57 --- /dev/null +++ b/src/main/java/use_case/favourite/adapter/FavouriteViewModel.java @@ -0,0 +1,19 @@ +package use_case.favourite.adapter; + +import view.ViewModel; + +public class FavouriteViewModel extends ViewModel { + public static final String TITLE_LABEL = "Favourite"; + + public static final String KEYWORD_LABEL = "Enter keyword to find a joke:"; + + public static final String SEARCH_BUTTOM_LABEL = "search"; + public static final String FUNNIEST_BUTTOM_LABEL = "funniest"; + public static final String CANCEL_BUTTOM_LABEL = "cancel"; + + public FavouriteViewModel(){ + super("Favourite"); + setState(new FavouriteState()); + } + +} diff --git a/src/main/java/view/FavouriteView.java b/src/main/java/view/FavouriteView.java index d1b92bf18..9b7d7fb17 100644 --- a/src/main/java/view/FavouriteView.java +++ b/src/main/java/view/FavouriteView.java @@ -1,6 +1,7 @@ package view; -import interface_adapter.favourite.FavouriteViewModel; +import use_case.favourite.adapter.FavouriteViewModel; +import view.helper_functions.LabelTextPanel; import java.awt.*; import java.awt.event.ActionEvent; @@ -10,38 +11,41 @@ import javax.swing.*; -import interface_adapter.favourite.FavouriteController; -import interface_adapter.favourite.FavouriteState; -import interface_adapter.favourite.FavouriteViewModel; +import use_case.favourite.adapter.FavouriteController; +import use_case.favourite.adapter.FavouriteState; public class FavouriteView extends JPanel implements ActionListener, PropertyChangeListener { private final FavouriteController favouriteController; - private final FavouriteViewModel favouriteviewmodel; + private final FavouriteViewModel favouriteViewModel; private final String viewName = "Favourite"; private FavouriteView favouriteView; - private final JLabel search = new JLabel("Enter keyword to find a joke:"); private final JTextArea keywordInputField = new JTextArea(); private final JTextField searchBox = new JTextField(15); private final JButton searchButton; private final JButton funniestButton; + private final JButton cancelButton; - public FavouriteView(FavouriteViewModel favouriteviewmodel, FavouriteController favouritecontroller, FavouriteViewModel favouriteviewmodel1) { - this.favouriteController = favouritecontroller; - this.favouriteviewmodel = favouriteviewmodel1; - this.favouriteviewmodel.addPropertyChangeListener(this); + public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController controller) { + this.favouriteController = controller; + this.favouriteViewModel = favouriteViewModel; + this.favouriteViewModel.addPropertyChangeListener(this); - final JLabel title = new JLabel("Favourite"); + final JLabel title = new JLabel(FavouriteViewModel.TITLE_LABEL); title.setAlignmentX(Component.CENTER_ALIGNMENT); + final LabelTextPanel search = new LabelTextPanel(new JLabel(FavouriteViewModel.KEYWORD_LABEL), searchBox); + final JPanel buttons = new JPanel(); - funniestButton = new JButton("Funniest"); + funniestButton = new JButton(FavouriteViewModel.FUNNIEST_BUTTOM_LABEL); buttons.add(funniestButton); - searchButton = new JButton("search"); + searchButton = new JButton(FavouriteViewModel.SEARCH_BUTTOM_LABEL); buttons.add(searchButton); + cancelButton = new JButton(FavouriteViewModel.CANCEL_BUTTOM_LABEL; + buttons.add(cancelButton); funniestButton.addActionListener( evt -> { diff --git a/src/main/java/view/ViewManagerModel.java b/src/main/java/view/ViewManagerModel.java new file mode 100644 index 000000000..6fac7568c --- /dev/null +++ b/src/main/java/view/ViewManagerModel.java @@ -0,0 +1,14 @@ +package view; + +/** + * 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(""); + } + +} From 366c1319e058b02a27b69f0ad32bf963b78c6380 Mon Sep 17 00:00:00 2001 From: GUO YU HE <162621600+GuoYuHeJason@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:06:38 -0500 Subject: [PATCH 22/62] Update ProjectLog --- ProjectLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ProjectLog b/ProjectLog index 72d144064..03cf9d730 100644 --- a/ProjectLog +++ b/ProjectLog @@ -12,6 +12,10 @@ K1bbu7z : Funnist Use Case Mika: Search Use Case Alex: Fav_search Use Case Cheyl: add to fav Use Case, Fav joke display pannel +Jason: New generate presenter, Joke view... +Other(Jason) +ViewManagerModel +Login Signup logout: logic (create user from DB/File Data, write Data from curr User). From be0bf92e06c95d2c82920b6f4ccb816934e0678d Mon Sep 17 00:00:00 2001 From: GUO YU HE <162621600+GuoYuHeJason@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:12:05 -0500 Subject: [PATCH 23/62] Update ProjectLog --- ProjectLog | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ProjectLog b/ProjectLog index 03cf9d730..ab83c66b8 100644 --- a/ProjectLog +++ b/ProjectLog @@ -12,10 +12,11 @@ K1bbu7z : Funnist Use Case Mika: Search Use Case Alex: Fav_search Use Case Cheyl: add to fav Use Case, Fav joke display pannel -Jason: New generate presenter, Joke view... +Jason: Generate Use Case, Joke view -Other(Jason) +Other ViewManagerModel -Login Signup logout: logic (create user from DB/File Data, write Data from curr User). +Login Signup logout logic (3 use cases)(create user from DB/File Data, write Data from curr User). +DataAccessObject (getting user info) From 337ea31546a416a820ec1b35faaf8e7a3bb754cd Mon Sep 17 00:00:00 2001 From: dengxues Date: Mon, 11 Nov 2024 21:22:10 -0500 Subject: [PATCH 24/62] FavouriteView Update --- .../favourite/adapter/FavouriteBuilder.java | 24 +++++ src/main/java/view/FavouriteView.java | 95 ++++++++++--------- .../use_case/favourite/DemoFavouriteTest.java | 9 ++ 3 files changed, 83 insertions(+), 45 deletions(-) create mode 100644 src/main/java/use_case/favourite/adapter/FavouriteBuilder.java create mode 100644 src/test/java/use_case/favourite/DemoFavouriteTest.java diff --git a/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java b/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java new file mode 100644 index 000000000..0cbddba98 --- /dev/null +++ b/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java @@ -0,0 +1,24 @@ +package use_case.favourite.adapter; + +import view.FavouriteView; + +import javax.swing.*; + +public class FavouriteBuilder { + public static final int HEIGHT = 300; + public static final int WIDTH = 400; + + public static JFrame build() { + + final JFrame frame = new JFrame(); + final FavouriteViewModel viewModel = new FavouriteViewModel(); + final FavouriteController controller = new FavouriteController(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Search"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(new FavouriteView(viewModel, controller)); + + return frame; + } +} diff --git a/src/main/java/view/FavouriteView.java b/src/main/java/view/FavouriteView.java index 9b7d7fb17..19ed4922c 100644 --- a/src/main/java/view/FavouriteView.java +++ b/src/main/java/view/FavouriteView.java @@ -14,7 +14,7 @@ import use_case.favourite.adapter.FavouriteController; import use_case.favourite.adapter.FavouriteState; -public class FavouriteView extends JPanel implements ActionListener, PropertyChangeListener { +public class FavouriteView extends JPanel { private final FavouriteController favouriteController; private final FavouriteViewModel favouriteViewModel; @@ -32,7 +32,7 @@ public class FavouriteView extends JPanel implements ActionListener, PropertyCha public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController controller) { this.favouriteController = controller; this.favouriteViewModel = favouriteViewModel; - this.favouriteViewModel.addPropertyChangeListener(this); +// this.favouriteViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel(FavouriteViewModel.TITLE_LABEL); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -40,51 +40,56 @@ public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController final LabelTextPanel search = new LabelTextPanel(new JLabel(FavouriteViewModel.KEYWORD_LABEL), searchBox); final JPanel buttons = new JPanel(); - funniestButton = new JButton(FavouriteViewModel.FUNNIEST_BUTTOM_LABEL); - buttons.add(funniestButton); searchButton = new JButton(FavouriteViewModel.SEARCH_BUTTOM_LABEL); buttons.add(searchButton); - cancelButton = new JButton(FavouriteViewModel.CANCEL_BUTTOM_LABEL; + funniestButton = new JButton(FavouriteViewModel.FUNNIEST_BUTTOM_LABEL); + buttons.add(funniestButton); + cancelButton = new JButton(FavouriteViewModel.CANCEL_BUTTOM_LABEL); buttons.add(cancelButton); - funniestButton.addActionListener( - evt -> { - if (evt.getSource().equals(funniestButton)) { - favouriteController.execute(favouriteInputField.getText()); - - } - } - ); - - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - favouriteController.execute(null); - - } - } - ); - } - - /** - * 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()); - } - - public void propertyChange(PropertyChangeEvent evt) { - final FavouriteState state = (FavouriteState) evt.getNewValue(); - setFields(state); - usernameErrorField.setText(state.getFavouriteError()); - } - - private void setFields(FavouriteState state) { - usernameInputField.setText(state.getUsername()); - } - - public String getViewName() { - return viewName; + this.add(title); + this.add(search); + this.add(buttons); + +// funniestButton.addActionListener( +// evt -> { +// if (evt.getSource().equals(funniestButton)) { +// favouriteController.execute(favouriteInputField.getText()); +// +// } +// } +// ); +// +// refreshButton.addActionListener( +// evt -> { +// if (evt.getSource().equals(refreshButton)) { +// favouriteController.execute(null); +// +// } +// } +// ); +// } +// +// /** +// * 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()); +// } +// +// public void propertyChange(PropertyChangeEvent evt) { +// final FavouriteState state = (FavouriteState) evt.getNewValue(); +// setFields(state); +// usernameErrorField.setText(state.getFavouriteError()); +// } +// +// private void setFields(FavouriteState state) { +// usernameInputField.setText(state.getUsername()); +// } +// +// public String getViewName() { +// return viewName; +// } } -} +} \ No newline at end of file diff --git a/src/test/java/use_case/favourite/DemoFavouriteTest.java b/src/test/java/use_case/favourite/DemoFavouriteTest.java new file mode 100644 index 000000000..a5dbd69d1 --- /dev/null +++ b/src/test/java/use_case/favourite/DemoFavouriteTest.java @@ -0,0 +1,9 @@ +package use_case.favourite; + +import use_case.favourite.adapter.FavouriteBuilder; + +public class DemoFavouriteTest { + public static void main(String[] args) { + FavouriteBuilder.build().setVisible(true); + } +} From 839a56f7bf59f671196d5f70b66180196d8fa02e Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Wed, 13 Nov 2024 19:52:23 -0500 Subject: [PATCH 25/62] Implementing JokeView TODO ExplanationController, GeneratePresenter, JokeFrameBuilder --- src/main/java/entity/JokeFactory.java | 7 + .../use_case/add_to_fav/AddController.java | 8 + .../explain/ExplanationController.java | 8 + src/main/java/view/joke_view/JokeState.java | 31 ++++ src/main/java/view/joke_view/JokeView.java | 165 ++++++++++++++++++ .../java/view/joke_view/JokeViewModel.java | 18 ++ 6 files changed, 237 insertions(+) create mode 100644 src/main/java/entity/JokeFactory.java create mode 100644 src/main/java/use_case/add_to_fav/AddController.java create mode 100644 src/main/java/use_case/explain/ExplanationController.java create mode 100644 src/main/java/view/joke_view/JokeState.java create mode 100644 src/main/java/view/joke_view/JokeView.java create mode 100644 src/main/java/view/joke_view/JokeViewModel.java diff --git a/src/main/java/entity/JokeFactory.java b/src/main/java/entity/JokeFactory.java new file mode 100644 index 000000000..ae88e7009 --- /dev/null +++ b/src/main/java/entity/JokeFactory.java @@ -0,0 +1,7 @@ +package entity; + +public class JokeFactory { + public Joke create(String content, int score) { + return new Joke(content, score); + } +} diff --git a/src/main/java/use_case/add_to_fav/AddController.java b/src/main/java/use_case/add_to_fav/AddController.java new file mode 100644 index 000000000..d5cf72a0a --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddController.java @@ -0,0 +1,8 @@ +package use_case.add_to_fav; + +public class AddController { + public void execute(String jokeContent, String explanation) { + //TODO cheyl implement this + } +} + diff --git a/src/main/java/use_case/explain/ExplanationController.java b/src/main/java/use_case/explain/ExplanationController.java new file mode 100644 index 000000000..2588b146f --- /dev/null +++ b/src/main/java/use_case/explain/ExplanationController.java @@ -0,0 +1,8 @@ +package use_case.explain; + +public class ExplanationController { + + public void execute(String jokeContent) { + //TODO Jason implement this + } +} diff --git a/src/main/java/view/joke_view/JokeState.java b/src/main/java/view/joke_view/JokeState.java new file mode 100644 index 000000000..4b9a4b4f2 --- /dev/null +++ b/src/main/java/view/joke_view/JokeState.java @@ -0,0 +1,31 @@ +package view.joke_view; + +public class JokeState { + // info that can change + private String jokeContent = ""; + private String explanation = ""; + + @Override + public String toString() { + return "JokeState{" + + "jokeContent='" + getJokeContent() + '\'' + + ", explanation='" + getExplanation() + '\'' + + '}'; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } + + public String getJokeContent() { + return jokeContent; + } + + public void setJokeContent(String jokeContent) { + this.jokeContent = jokeContent; + } +} diff --git a/src/main/java/view/joke_view/JokeView.java b/src/main/java/view/joke_view/JokeView.java new file mode 100644 index 000000000..a38ea910f --- /dev/null +++ b/src/main/java/view/joke_view/JokeView.java @@ -0,0 +1,165 @@ +package view.joke_view; + +import use_case.add_to_fav.AddController; +import use_case.explain.ExplanationController; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +public class JokeView extends JPanel implements PropertyChangeListener, ActionListener { + + private final String viewName; + private final JokeViewModel jokeViewModel; + + private final JTextArea jokeContent = new JTextArea(3, 20); + private final JTextArea explanation = new JTextArea(10, 20); + + // Controllers + // each function of a controller is a button + private final JButton explain; + private final JButton addToFav; + private AddController addController; + private ExplanationController explanationController; + + public JokeView(JokeViewModel jokeViewModel) { + + this.jokeViewModel = jokeViewModel; + this.jokeViewModel.addPropertyChangeListener(this); + this.viewName = jokeViewModel.getViewName(); + + final JLabel title = new JLabel(JokeViewModel.TITLE_LABEL); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + final JLabel explanationLabel = new JLabel(JokeViewModel.EXPLANATION_LABEL); + explanationLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JPanel buttons = new JPanel(); + explain = new JButton(JokeViewModel.EXPLANATION_BUTTON_LABEL); + buttons.add(explain); + addToFav = new JButton(JokeViewModel.ADD_BUTTON_LABEL); + buttons.add(addToFav); + + explain.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(explain)) { + final JokeState currentState = jokeViewModel.getState(); + + explanationController.execute( + currentState.getJokeContent() + ); + } + } + } + ); + + addToFav.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(addToFav)) { + final JokeState currentState = jokeViewModel.getState(); + //can change depending on how addController is implemented + addController.execute( + currentState.getJokeContent(), + currentState.getExplanation() + ); + } + } + } + ); + + // a smaller (than view) observer pattern + jokeContent.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final JokeState currentState = jokeViewModel.getState(); + currentState.setJokeContent(jokeContent.getText()); + jokeViewModel.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)); + + explanation.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final JokeState currentState = jokeViewModel.getState(); + currentState.setExplanation(explanation.getText()); + jokeViewModel.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(jokeContent); + this.add(explanationLabel); + this.add(explanation); + 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 JokeState state = (JokeState) evt.getNewValue(); + setFields(state); + } + + private void setFields(JokeState state) { + jokeContent.setText(state.getJokeContent()); + explanation.setText(state.getExplanation()); + } + + public String getViewName() { + return viewName; + } + + public void setExplanationController(ExplanationController explanationController) { + this.explanationController = explanationController; + } + + public void setAddController(AddController addController) { + this.addController = addController; + } +} diff --git a/src/main/java/view/joke_view/JokeViewModel.java b/src/main/java/view/joke_view/JokeViewModel.java new file mode 100644 index 000000000..24b37f21f --- /dev/null +++ b/src/main/java/view/joke_view/JokeViewModel.java @@ -0,0 +1,18 @@ +package view.joke_view; + +import view.ViewModel; + + +public class JokeViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Joke"; + public static final String EXPLANATION_BUTTON_LABEL = "Explain"; + public static final String ADD_BUTTON_LABEL = "Add to Favorite"; + public static final String EXPLANATION_LABEL = "Explanation"; + + public JokeViewModel() { + super("Joke"); + setState(new JokeState()); + } + // a wrapper for all the info you need to build a view +} From 3b4f0cecc63f2551942bfd5f98b2ed6ec4886d4f Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Thu, 14 Nov 2024 21:31:37 -0500 Subject: [PATCH 26/62] Semi-Final Generate UseCase Joke View, Joke Frame Builder. (should be used for Search Presenter as well) Created some files needed to run without error --- .../ExplanationDataAccessObject.java | 2 +- .../MockExplanationDataAccessObject.java | 2 +- .../use_case/add_to_fav/AddController.java | 4 +- .../ExplanationController.java | 5 +- .../ExplanationDataAccessInterface.java | 2 +- .../explanation/ExplanationInputBoundary.java | 4 ++ .../explanation/ExplanationInteractor.java | 6 ++ .../ExplanationOutputBoundary.java | 4 ++ .../explanation/ExplanationPresenter.java | 8 +++ .../generate/GenerateInputBoundary.java | 1 + .../generate/adapter/DemoBuilder.java | 25 -------- .../generate/adapter/GenerateController.java | 1 + .../generate/adapter/GeneratePresenter.java | 49 +++++++++++++++ .../java/view/joke_view/JokeFrameBuilder.java | 63 +++++++++++++++++++ src/main/java/view/joke_view/JokeView.java | 6 +- .../java/use_case/generate/GenerateTest.java | 14 +++++ 16 files changed, 163 insertions(+), 33 deletions(-) rename src/main/java/use_case/{explain => explanation}/ExplanationController.java (51%) rename src/main/java/use_case/{explain => explanation}/ExplanationDataAccessInterface.java (75%) create mode 100644 src/main/java/use_case/explanation/ExplanationInputBoundary.java create mode 100644 src/main/java/use_case/explanation/ExplanationInteractor.java create mode 100644 src/main/java/use_case/explanation/ExplanationOutputBoundary.java create mode 100644 src/main/java/use_case/explanation/ExplanationPresenter.java delete mode 100644 src/main/java/use_case/generate/adapter/DemoBuilder.java create mode 100644 src/main/java/use_case/generate/adapter/GeneratePresenter.java create mode 100644 src/main/java/view/joke_view/JokeFrameBuilder.java create mode 100644 src/test/java/use_case/generate/GenerateTest.java diff --git a/src/main/java/data_access/ExplanationDataAccessObject.java b/src/main/java/data_access/ExplanationDataAccessObject.java index 72b934cde..4c9e31fbe 100644 --- a/src/main/java/data_access/ExplanationDataAccessObject.java +++ b/src/main/java/data_access/ExplanationDataAccessObject.java @@ -3,7 +3,7 @@ import okhttp3.*; import org.json.JSONException; import org.json.JSONObject; -import use_case.explain.ExplanationDataAccessInterface; +import use_case.explanation.ExplanationDataAccessInterface; import java.io.IOException; diff --git a/src/main/java/data_access/MockExplanationDataAccessObject.java b/src/main/java/data_access/MockExplanationDataAccessObject.java index f8675b18a..99f8693fd 100644 --- a/src/main/java/data_access/MockExplanationDataAccessObject.java +++ b/src/main/java/data_access/MockExplanationDataAccessObject.java @@ -1,6 +1,6 @@ package data_access; -import use_case.explain.ExplanationDataAccessInterface; +import use_case.explanation.ExplanationDataAccessInterface; public class MockExplanationDataAccessObject implements ExplanationDataAccessInterface { diff --git a/src/main/java/use_case/add_to_fav/AddController.java b/src/main/java/use_case/add_to_fav/AddController.java index d5cf72a0a..7df089bd3 100644 --- a/src/main/java/use_case/add_to_fav/AddController.java +++ b/src/main/java/use_case/add_to_fav/AddController.java @@ -1,7 +1,9 @@ package use_case.add_to_fav; +import entity.User; + public class AddController { - public void execute(String jokeContent, String explanation) { + public void execute(String jokeContent, String explanation, User user) { //TODO cheyl implement this } } diff --git a/src/main/java/use_case/explain/ExplanationController.java b/src/main/java/use_case/explanation/ExplanationController.java similarity index 51% rename from src/main/java/use_case/explain/ExplanationController.java rename to src/main/java/use_case/explanation/ExplanationController.java index 2588b146f..26927204d 100644 --- a/src/main/java/use_case/explain/ExplanationController.java +++ b/src/main/java/use_case/explanation/ExplanationController.java @@ -1,7 +1,10 @@ -package use_case.explain; +package use_case.explanation; public class ExplanationController { + public ExplanationController(ExplanationInputBoundary explanationInteractor) { + } + public void execute(String jokeContent) { //TODO Jason implement this } diff --git a/src/main/java/use_case/explain/ExplanationDataAccessInterface.java b/src/main/java/use_case/explanation/ExplanationDataAccessInterface.java similarity index 75% rename from src/main/java/use_case/explain/ExplanationDataAccessInterface.java rename to src/main/java/use_case/explanation/ExplanationDataAccessInterface.java index b0c9d853c..99fa3c61c 100644 --- a/src/main/java/use_case/explain/ExplanationDataAccessInterface.java +++ b/src/main/java/use_case/explanation/ExplanationDataAccessInterface.java @@ -1,4 +1,4 @@ -package use_case.explain; +package use_case.explanation; public interface ExplanationDataAccessInterface { String getExplanation(String joke); diff --git a/src/main/java/use_case/explanation/ExplanationInputBoundary.java b/src/main/java/use_case/explanation/ExplanationInputBoundary.java new file mode 100644 index 000000000..f8330f80d --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationInputBoundary.java @@ -0,0 +1,4 @@ +package use_case.explanation; + +public interface ExplanationInputBoundary { +} diff --git a/src/main/java/use_case/explanation/ExplanationInteractor.java b/src/main/java/use_case/explanation/ExplanationInteractor.java new file mode 100644 index 000000000..1a2661a1f --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationInteractor.java @@ -0,0 +1,6 @@ +package use_case.explanation; + +public class ExplanationInteractor implements ExplanationInputBoundary { + public ExplanationInteractor(ExplanationDataAccessInterface explanationDataAccessObject, ExplanationOutputBoundary explanationOutputBoundary) { + } +} diff --git a/src/main/java/use_case/explanation/ExplanationOutputBoundary.java b/src/main/java/use_case/explanation/ExplanationOutputBoundary.java new file mode 100644 index 000000000..dce3e45e8 --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationOutputBoundary.java @@ -0,0 +1,4 @@ +package use_case.explanation; + +public interface ExplanationOutputBoundary { +} diff --git a/src/main/java/use_case/explanation/ExplanationPresenter.java b/src/main/java/use_case/explanation/ExplanationPresenter.java new file mode 100644 index 000000000..e95ef8be9 --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationPresenter.java @@ -0,0 +1,8 @@ +package use_case.explanation; + +import view.joke_view.JokeViewModel; + +public class ExplanationPresenter implements ExplanationOutputBoundary { + public ExplanationPresenter(JokeViewModel jokeViewModel) { + } +} diff --git a/src/main/java/use_case/generate/GenerateInputBoundary.java b/src/main/java/use_case/generate/GenerateInputBoundary.java index be449bcc0..785fe6b1a 100644 --- a/src/main/java/use_case/generate/GenerateInputBoundary.java +++ b/src/main/java/use_case/generate/GenerateInputBoundary.java @@ -5,5 +5,6 @@ public interface GenerateInputBoundary { /** * Executes the generate use case. */ + //TODO change to using inputData void executeGenerate(); } diff --git a/src/main/java/use_case/generate/adapter/DemoBuilder.java b/src/main/java/use_case/generate/adapter/DemoBuilder.java deleted file mode 100644 index 15032db6e..000000000 --- a/src/main/java/use_case/generate/adapter/DemoBuilder.java +++ /dev/null @@ -1,25 +0,0 @@ -package use_case.generate.adapter; - -import data_access.JokeDataAccessObject; -import use_case.generate.GenerateInteractor; - -import javax.swing.*; - -public class DemoBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - - public static JFrame build() { - - - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Joke Machine"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(new DemoAppView()); - - return frame; - - } -} diff --git a/src/main/java/use_case/generate/adapter/GenerateController.java b/src/main/java/use_case/generate/adapter/GenerateController.java index 0064ca811..dfd9b2a0e 100644 --- a/src/main/java/use_case/generate/adapter/GenerateController.java +++ b/src/main/java/use_case/generate/adapter/GenerateController.java @@ -19,4 +19,5 @@ public GenerateController(GenerateInputBoundary generateInputBoundary) { public void execute() { generateInputBoundary.executeGenerate(); } + //may change to add user } diff --git a/src/main/java/use_case/generate/adapter/GeneratePresenter.java b/src/main/java/use_case/generate/adapter/GeneratePresenter.java new file mode 100644 index 000000000..275cc4df3 --- /dev/null +++ b/src/main/java/use_case/generate/adapter/GeneratePresenter.java @@ -0,0 +1,49 @@ +package use_case.generate.adapter; + +import entity.Joke; +import use_case.generate.GenerateOuputBoundary; +import use_case.note.NoteOutputBoundary; +import view.joke_view.JokeFrameBuilder; +import view.joke_view.JokeViewModel; + +import javax.swing.*; + +public class GeneratePresenter implements GenerateOuputBoundary { + // not a typical presenter, more similar to main + + private final JokeFrameBuilder jokeFrameBuilder; + + public GeneratePresenter(JokeFrameBuilder jokeFrameBuilder) { + this.jokeFrameBuilder = jokeFrameBuilder; + } + + /** + * Prepares the success view for the Note related Use Cases. + * + * @param jokeContent the output data + */ + @Override + public void prepareSuccessView(String jokeContent) { + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(jokeContent) + .addExplanationUseCase() + .addAddToFavUseCase() + .build(); + + frame.pack(); + frame.setVisible(true); + } + + /** + * Prepares the failure view for the Note related Use Cases. + * + * @param errorMessage the explanation of the failure + */ + //TODO implement + @Override + public void prepareFailView(String errorMessage) { +// jokeViewModel.getState().setError(errorMessage); +// jokeViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java new file mode 100644 index 000000000..b3dc3d388 --- /dev/null +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -0,0 +1,63 @@ +package view.joke_view; + +import data_access.ExplanationDataAccessObject; +import data_access.MockExplanationDataAccessObject; +import entity.JokeFactory; +import entity.UserFactory; +import use_case.explanation.*; +import use_case.generate.adapter.DemoAppView; + +import javax.swing.*; + +public class JokeFrameBuilder { +// public static final int HEIGHT = 300; +// public static final int WIDTH = 400; + // joke/user factory made before +// private final JokeFactory jokeFactory = new JokeFactory(); + + private JokeView jokeView; + private JokeViewModel jokeViewModel; + // view doesn't change, so don't need ViewManager(cardPanel, cardLayout, viewManagerModel); + + //TODO change mock + private final ExplanationDataAccessInterface explanationDataAccessObject = new MockExplanationDataAccessObject(); + + public JokeFrameBuilder() { + } + + public JokeFrameBuilder addJokeView() { + jokeViewModel = new JokeViewModel(); + jokeView = new JokeView(jokeViewModel); + return this; + } + + public JokeFrameBuilder setJokeContent(String content) { + jokeViewModel.getState().setJokeContent(content); + jokeViewModel.firePropertyChanged(); + return this; + } + + public JokeFrameBuilder addExplanationUseCase() { + final ExplanationOutputBoundary explanationOutputBoundary = new ExplanationPresenter(jokeViewModel); + final ExplanationInputBoundary explanationInteractor = new ExplanationInteractor( + explanationDataAccessObject, explanationOutputBoundary); + + final ExplanationController explanationController = new ExplanationController(explanationInteractor); + jokeView.setExplanationController(explanationController); + return this; + } + + //TODO do this + public JokeFrameBuilder addAddToFavUseCase() { + return this; + } + + public JFrame build() { + final JFrame frame = new JFrame("Joke"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + frame.add(jokeView); + + return frame; + } +} diff --git a/src/main/java/view/joke_view/JokeView.java b/src/main/java/view/joke_view/JokeView.java index a38ea910f..e5dfcd665 100644 --- a/src/main/java/view/joke_view/JokeView.java +++ b/src/main/java/view/joke_view/JokeView.java @@ -1,7 +1,7 @@ package view.joke_view; import use_case.add_to_fav.AddController; -import use_case.explain.ExplanationController; +import use_case.explanation.ExplanationController; import java.awt.*; import java.awt.event.ActionEvent; @@ -67,8 +67,8 @@ public void actionPerformed(ActionEvent evt) { //can change depending on how addController is implemented addController.execute( currentState.getJokeContent(), - currentState.getExplanation() - ); + currentState.getExplanation(), + null); } } } diff --git a/src/test/java/use_case/generate/GenerateTest.java b/src/test/java/use_case/generate/GenerateTest.java new file mode 100644 index 000000000..eb4ed17a7 --- /dev/null +++ b/src/test/java/use_case/generate/GenerateTest.java @@ -0,0 +1,14 @@ +package use_case.generate; + +import data_access.JokeDataAccessObject; +import use_case.generate.adapter.GenerateController; +import use_case.generate.adapter.GeneratePresenter; +import view.joke_view.JokeFrameBuilder; + +public class GenerateTest { + public static void main(String[] args) { + //pretend that the generate button is pressed + // this is not a unit test + new GenerateController(new GenerateInteractor(new JokeDataAccessObject(), new GeneratePresenter(new JokeFrameBuilder()))).execute(); + } +} From f64933fb3b44727265fb9cd8e4828513576b81a2 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Fri, 15 Nov 2024 14:11:17 -0500 Subject: [PATCH 27/62] Changing generate usecase to use output data part of explanation implemented --- .../explanation/ExplanationController.java | 11 ---------- .../explanation/ExplanationInputBoundary.java | 5 +++++ .../explanation/ExplanationInputData.java | 18 ++++++++++++++++ .../explanation/ExplanationInteractor.java | 20 ++++++++++++++++++ .../ExplanationOutputBoundary.java | 11 ++++++++++ .../explanation/ExplanationOutputData.java | 18 ++++++++++++++++ .../explanation/ExplanationPresenter.java | 8 ------- .../adapter/ExplanationController.java | 18 ++++++++++++++++ .../adapter/ExplanationPresenter.java | 21 +++++++++++++++++++ .../use_case/generate/GenerateInteractor.java | 5 ++++- .../generate/GenerateOuputBoundary.java | 2 +- .../use_case/generate/GenerateOutputData.java | 18 ++++++++++++++++ .../generate/adapter/GenerateController.java | 1 + .../generate/adapter/GeneratePresenter.java | 7 ++++--- .../java/view/joke_view/JokeFrameBuilder.java | 6 ++---- src/main/java/view/joke_view/JokeView.java | 2 +- 16 files changed, 142 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/use_case/explanation/ExplanationController.java create mode 100644 src/main/java/use_case/explanation/ExplanationInputData.java create mode 100644 src/main/java/use_case/explanation/ExplanationOutputData.java delete mode 100644 src/main/java/use_case/explanation/ExplanationPresenter.java create mode 100644 src/main/java/use_case/explanation/adapter/ExplanationController.java create mode 100644 src/main/java/use_case/explanation/adapter/ExplanationPresenter.java create mode 100644 src/main/java/use_case/generate/GenerateOutputData.java diff --git a/src/main/java/use_case/explanation/ExplanationController.java b/src/main/java/use_case/explanation/ExplanationController.java deleted file mode 100644 index 26927204d..000000000 --- a/src/main/java/use_case/explanation/ExplanationController.java +++ /dev/null @@ -1,11 +0,0 @@ -package use_case.explanation; - -public class ExplanationController { - - public ExplanationController(ExplanationInputBoundary explanationInteractor) { - } - - public void execute(String jokeContent) { - //TODO Jason implement this - } -} diff --git a/src/main/java/use_case/explanation/ExplanationInputBoundary.java b/src/main/java/use_case/explanation/ExplanationInputBoundary.java index f8330f80d..205ff33d1 100644 --- a/src/main/java/use_case/explanation/ExplanationInputBoundary.java +++ b/src/main/java/use_case/explanation/ExplanationInputBoundary.java @@ -1,4 +1,9 @@ package use_case.explanation; public interface ExplanationInputBoundary { + + /** + * Executes the explanation use case. + */ + void executeExplanation(ExplanationInputData explanationInputData); } diff --git a/src/main/java/use_case/explanation/ExplanationInputData.java b/src/main/java/use_case/explanation/ExplanationInputData.java new file mode 100644 index 000000000..c52ad6cf1 --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationInputData.java @@ -0,0 +1,18 @@ +package use_case.explanation; + +/** + * The Input Data for the Login Use Case. + */ +public class ExplanationInputData { + + private final String jokeContent; + + public ExplanationInputData(String jokeContent) { + this.jokeContent = jokeContent; + } + + String getJokeContent() { + return jokeContent; + } + +} diff --git a/src/main/java/use_case/explanation/ExplanationInteractor.java b/src/main/java/use_case/explanation/ExplanationInteractor.java index 1a2661a1f..a19a390d6 100644 --- a/src/main/java/use_case/explanation/ExplanationInteractor.java +++ b/src/main/java/use_case/explanation/ExplanationInteractor.java @@ -1,6 +1,26 @@ package use_case.explanation; +import use_case.generate.GenerateDataAccessInterface; +import use_case.generate.GenerateOuputBoundary; + public class ExplanationInteractor implements ExplanationInputBoundary { + + private final ExplanationDataAccessInterface explanationDataAccessObject; + private final ExplanationOutputBoundary explanationOutputBoundary; + public ExplanationInteractor(ExplanationDataAccessInterface explanationDataAccessObject, ExplanationOutputBoundary explanationOutputBoundary) { + this.explanationDataAccessObject = explanationDataAccessObject; + this.explanationOutputBoundary = explanationOutputBoundary; + } + + @Override + public void executeExplanation(ExplanationInputData explanationInputData) { + try { + final String explanation = explanationDataAccessObject.getExplanation(explanationInputData.getJokeContent()); + explanationOutputBoundary.prepareSuccessView(new ExplanationOutputData(explanation)); + } + catch (RuntimeException ex) { + explanationOutputBoundary.prepareFailView(ex.getMessage()); + } } } diff --git a/src/main/java/use_case/explanation/ExplanationOutputBoundary.java b/src/main/java/use_case/explanation/ExplanationOutputBoundary.java index dce3e45e8..cdd828990 100644 --- a/src/main/java/use_case/explanation/ExplanationOutputBoundary.java +++ b/src/main/java/use_case/explanation/ExplanationOutputBoundary.java @@ -1,4 +1,15 @@ package use_case.explanation; public interface ExplanationOutputBoundary { + /** + * Prepares the success view for the Note related Use Cases. + * @param explanationOutputData the output data + */ + void prepareSuccessView(ExplanationOutputData explanationOutputData); + + /** + * Prepares the failure view. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); } diff --git a/src/main/java/use_case/explanation/ExplanationOutputData.java b/src/main/java/use_case/explanation/ExplanationOutputData.java new file mode 100644 index 000000000..d974b4acf --- /dev/null +++ b/src/main/java/use_case/explanation/ExplanationOutputData.java @@ -0,0 +1,18 @@ +package use_case.explanation; + +/** + * Output Data for the Explanation Use Case. + */ +public class ExplanationOutputData { + + private final String explanation; + + public ExplanationOutputData(String explanation) { + this.explanation = explanation; +// this.useCaseFailed = useCaseFailed; + } + + public String getExplanation() { + return explanation; + } +} diff --git a/src/main/java/use_case/explanation/ExplanationPresenter.java b/src/main/java/use_case/explanation/ExplanationPresenter.java deleted file mode 100644 index e95ef8be9..000000000 --- a/src/main/java/use_case/explanation/ExplanationPresenter.java +++ /dev/null @@ -1,8 +0,0 @@ -package use_case.explanation; - -import view.joke_view.JokeViewModel; - -public class ExplanationPresenter implements ExplanationOutputBoundary { - public ExplanationPresenter(JokeViewModel jokeViewModel) { - } -} diff --git a/src/main/java/use_case/explanation/adapter/ExplanationController.java b/src/main/java/use_case/explanation/adapter/ExplanationController.java new file mode 100644 index 000000000..084a0a521 --- /dev/null +++ b/src/main/java/use_case/explanation/adapter/ExplanationController.java @@ -0,0 +1,18 @@ +package use_case.explanation.adapter; + +import use_case.explanation.ExplanationInputBoundary; +import use_case.explanation.ExplanationInputData; + +public class ExplanationController { + + private final ExplanationInputBoundary explanationInputBoundary; + + public ExplanationController(ExplanationInputBoundary explanationInteractor) { + this.explanationInputBoundary = explanationInteractor; + } + + public void execute(String jokeContent) { + ExplanationInputData input = new ExplanationInputData(jokeContent); + explanationInputBoundary.executeExplanation(input); + } +} diff --git a/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java b/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java new file mode 100644 index 000000000..30f2e82f0 --- /dev/null +++ b/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java @@ -0,0 +1,21 @@ +package use_case.explanation.adapter; + +import use_case.explanation.ExplanationOutputBoundary; +import view.joke_view.JokeViewModel; + +public class ExplanationPresenter implements ExplanationOutputBoundary { + //TODO implement + + public ExplanationPresenter(JokeViewModel jokeViewModel) { + } + + @Override + public void prepareSuccessView(String explanation) { + + } + + @Override + public void prepareFailView(String errorMessage) { + + } +} diff --git a/src/main/java/use_case/generate/GenerateInteractor.java b/src/main/java/use_case/generate/GenerateInteractor.java index aa4a9e613..382c1bb0c 100644 --- a/src/main/java/use_case/generate/GenerateInteractor.java +++ b/src/main/java/use_case/generate/GenerateInteractor.java @@ -22,7 +22,10 @@ public GenerateInteractor(GenerateDataAccessInterface generateDataAccessInterfac public void executeGenerate() { try { final String jokeContent = generateDataAccessInterface.getJokeContent(); - generateOuputBoundary.prepareSuccessView(jokeContent); + // interactor gets input data and outputs output data + final GenerateOutputData generateOutputData = new GenerateOutputData(jokeContent); + + generateOuputBoundary.prepareSuccessView(generateOutputData); } catch (RuntimeException ex) { generateOuputBoundary.prepareFailView(ex.getMessage()); diff --git a/src/main/java/use_case/generate/GenerateOuputBoundary.java b/src/main/java/use_case/generate/GenerateOuputBoundary.java index 56e21cf19..db8836c1c 100644 --- a/src/main/java/use_case/generate/GenerateOuputBoundary.java +++ b/src/main/java/use_case/generate/GenerateOuputBoundary.java @@ -5,7 +5,7 @@ public interface GenerateOuputBoundary { * Prepares the success view for the Note related Use Cases. * @param jokeContent the output data */ - void prepareSuccessView(String jokeContent); + void prepareSuccessView(GenerateOutputData generateOutputData); /** * Prepares the failure view. diff --git a/src/main/java/use_case/generate/GenerateOutputData.java b/src/main/java/use_case/generate/GenerateOutputData.java new file mode 100644 index 000000000..c95ea0d13 --- /dev/null +++ b/src/main/java/use_case/generate/GenerateOutputData.java @@ -0,0 +1,18 @@ +package use_case.generate; + +/** + * Output Data for the Generate Use Case. + */ +public class GenerateOutputData { + + private final String jokeContent; + + public GenerateOutputData(String jokeContent) { + this.jokeContent = jokeContent; +// this.useCaseFailed = useCaseFailed; + } + + public String getJokeContent() { + return jokeContent; + } +} diff --git a/src/main/java/use_case/generate/adapter/GenerateController.java b/src/main/java/use_case/generate/adapter/GenerateController.java index dfd9b2a0e..07efb3d59 100644 --- a/src/main/java/use_case/generate/adapter/GenerateController.java +++ b/src/main/java/use_case/generate/adapter/GenerateController.java @@ -20,4 +20,5 @@ public void execute() { generateInputBoundary.executeGenerate(); } //may change to add user + //controller is responsible for changing raw info from view states to inputData } diff --git a/src/main/java/use_case/generate/adapter/GeneratePresenter.java b/src/main/java/use_case/generate/adapter/GeneratePresenter.java index 275cc4df3..2dc854d21 100644 --- a/src/main/java/use_case/generate/adapter/GeneratePresenter.java +++ b/src/main/java/use_case/generate/adapter/GeneratePresenter.java @@ -2,6 +2,7 @@ import entity.Joke; import use_case.generate.GenerateOuputBoundary; +import use_case.generate.GenerateOutputData; import use_case.note.NoteOutputBoundary; import view.joke_view.JokeFrameBuilder; import view.joke_view.JokeViewModel; @@ -20,13 +21,13 @@ public GeneratePresenter(JokeFrameBuilder jokeFrameBuilder) { /** * Prepares the success view for the Note related Use Cases. * - * @param jokeContent the output data + * @param generateOutputData the output data */ @Override - public void prepareSuccessView(String jokeContent) { + public void prepareSuccessView(GenerateOutputData generateOutputData) { final JFrame frame = jokeFrameBuilder .addJokeView() - .setJokeContent(jokeContent) + .setJokeContent(generateOutputData.getJokeContent()) .addExplanationUseCase() .addAddToFavUseCase() .build(); diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java index b3dc3d388..9bca40470 100644 --- a/src/main/java/view/joke_view/JokeFrameBuilder.java +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -1,11 +1,9 @@ package view.joke_view; -import data_access.ExplanationDataAccessObject; import data_access.MockExplanationDataAccessObject; -import entity.JokeFactory; -import entity.UserFactory; import use_case.explanation.*; -import use_case.generate.adapter.DemoAppView; +import use_case.explanation.adapter.ExplanationController; +import use_case.explanation.adapter.ExplanationPresenter; import javax.swing.*; diff --git a/src/main/java/view/joke_view/JokeView.java b/src/main/java/view/joke_view/JokeView.java index e5dfcd665..5b5f25d63 100644 --- a/src/main/java/view/joke_view/JokeView.java +++ b/src/main/java/view/joke_view/JokeView.java @@ -1,7 +1,7 @@ package view.joke_view; import use_case.add_to_fav.AddController; -import use_case.explanation.ExplanationController; +import use_case.explanation.adapter.ExplanationController; import java.awt.*; import java.awt.event.ActionEvent; From 69f519775c6d41a6746c52179a8a4ea22f17ead1 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Fri, 15 Nov 2024 17:17:34 -0500 Subject: [PATCH 28/62] Changing generate usecase to use output data part of explanation implemented --- .../adapter/ExplanationPresenter.java | 15 +++++--- .../java/view/joke_view/JokeFrameBuilder.java | 5 ++- src/main/java/view/joke_view/JokeView.java | 34 ++++++++----------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java b/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java index 30f2e82f0..21d07a55b 100644 --- a/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java +++ b/src/main/java/use_case/explanation/adapter/ExplanationPresenter.java @@ -1,21 +1,28 @@ package use_case.explanation.adapter; import use_case.explanation.ExplanationOutputBoundary; +import use_case.explanation.ExplanationOutputData; +import view.joke_view.JokeState; import view.joke_view.JokeViewModel; public class ExplanationPresenter implements ExplanationOutputBoundary { - //TODO implement + + private final JokeViewModel jokeViewModel; public ExplanationPresenter(JokeViewModel jokeViewModel) { + this.jokeViewModel = jokeViewModel; } @Override - public void prepareSuccessView(String explanation) { - + public void prepareSuccessView(ExplanationOutputData explanationOutputData) { + final JokeState jokeState = jokeViewModel.getState(); + jokeState.setExplanation(explanationOutputData.getExplanation()); + jokeViewModel.setState(jokeState); + jokeViewModel.firePropertyChanged(); } @Override + //TODO to be continued public void prepareFailView(String errorMessage) { - } } diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java index 9bca40470..d3ff33ab4 100644 --- a/src/main/java/view/joke_view/JokeFrameBuilder.java +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -1,5 +1,6 @@ package view.joke_view; +import data_access.ExplanationDataAccessObject; import data_access.MockExplanationDataAccessObject; import use_case.explanation.*; import use_case.explanation.adapter.ExplanationController; @@ -18,7 +19,7 @@ public class JokeFrameBuilder { // view doesn't change, so don't need ViewManager(cardPanel, cardLayout, viewManagerModel); //TODO change mock - private final ExplanationDataAccessInterface explanationDataAccessObject = new MockExplanationDataAccessObject(); + private final ExplanationDataAccessInterface explanationDataAccessObject = new ExplanationDataAccessObject(); public JokeFrameBuilder() { } @@ -52,6 +53,8 @@ public JokeFrameBuilder addAddToFavUseCase() { public JFrame build() { final JFrame frame = new JFrame("Joke"); + + //TODO may need to change frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.add(jokeView); diff --git a/src/main/java/view/joke_view/JokeView.java b/src/main/java/view/joke_view/JokeView.java index 5b5f25d63..011abcdb7 100644 --- a/src/main/java/view/joke_view/JokeView.java +++ b/src/main/java/view/joke_view/JokeView.java @@ -46,30 +46,26 @@ public JokeView(JokeViewModel jokeViewModel) { buttons.add(addToFav); explain.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(explain)) { - final JokeState currentState = jokeViewModel.getState(); - - explanationController.execute( - currentState.getJokeContent() - ); - } + evt -> { + if (evt.getSource().equals(explain)) { + final JokeState currentState = jokeViewModel.getState(); + + explanationController.execute( + currentState.getJokeContent() + ); } } ); addToFav.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(addToFav)) { - final JokeState currentState = jokeViewModel.getState(); - //can change depending on how addController is implemented - addController.execute( - currentState.getJokeContent(), - currentState.getExplanation(), - null); - } + evt -> { + if (evt.getSource().equals(addToFav)) { + final JokeState currentState = jokeViewModel.getState(); + //can change depending on how addController is implemented + addController.execute( + currentState.getJokeContent(), + currentState.getExplanation(), + null); } } ); From efdbd277699d570310054adc1a21791556f527d3 Mon Sep 17 00:00:00 2001 From: GUO YU HE <162621600+GuoYuHeJason@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:12:34 -0500 Subject: [PATCH 29/62] Update ProjectLog --- ProjectLog | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/ProjectLog b/ProjectLog index ab83c66b8..af7d102c6 100644 --- a/ProjectLog +++ b/ProjectLog @@ -4,18 +4,36 @@ Alex intitial main gui (View, ViewModel) Cheyl Read.md completed Cheyl Finalized UI design Jason User and Joke entity -K1bbu7z User factory, Favrite UI +K1bbu7z User factory, Favrite UI +Jason: generate usecse, explain use case TODO -K1bbu7z : Funnist Use Case +If time permits: +K1bbu7z : Funnist Use Case, fav use case +Mika: Search Use Case, sign up usecase, log out usecase, user data access object +Alex: Fav_search Use Case, login usecase +Cheyl: add to fav Use Case, Fav joke display pannel +Jason: ViewManagerModel, AppBuilder + +If not 1: +no login, sign up, log out, user data access object, user entity has no username and password. everything gone upon closing. +No funniest? +K1bbu7z : fav use case (including display pannel) Mika: Search Use Case Alex: Fav_search Use Case -Cheyl: add to fav Use Case, Fav joke display pannel -Jason: Generate Use Case, Joke view +Cheyl: add to fav Use Case +Jason: ViewManagerModel, AppBuilder + +If not 2 (not well thought out): +No funniest, No fav_search +K1bbu7z : fav use case (just display), AppBuilder +Mika: Search Use Case, user data access object +Alex: login,sign up usecase, +Cheyl: add to fav Use Case, log out usecase +Jason: ViewManagerModel -Other -ViewManagerModel +notes Login Signup logout logic (3 use cases)(create user from DB/File Data, write Data from curr User). DataAccessObject (getting user info) From 36c5378a164c0c2b1b760dc7a3c23697296852ce Mon Sep 17 00:00:00 2001 From: cheryl Date: Sun, 17 Nov 2024 14:00:18 -0500 Subject: [PATCH 30/62] favorite panel --- src/main/java/view/FavoritePanel.java | 135 ++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/main/java/view/FavoritePanel.java diff --git a/src/main/java/view/FavoritePanel.java b/src/main/java/view/FavoritePanel.java new file mode 100644 index 000000000..aaf7a324f --- /dev/null +++ b/src/main/java/view/FavoritePanel.java @@ -0,0 +1,135 @@ +package view; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionListener; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; + +/** + * A FavoritePanel that includes a scrollable list of favorite jokes. + */ +public class FavoritePanel extends JPanel { + + // UI Components + private final JTextField keywordField = new JTextField(20); // Text field to enter a keyword + private final JButton searchButton = new JButton("Search"); + private final JButton funniestButton = new JButton("Funniest"); + private final JButton cancelButton = new JButton("Cancel"); + private final DefaultListModel jokeListModel = new DefaultListModel<>(); + private final JList jokeList = new JList<>(jokeListModel); // Scrollable joke list + private final JScrollPane scrollPane = new JScrollPane(jokeList); // Scroll pane for the list + private final JButton goToJokePageButton = new JButton("Go to Joke Page"); + private final JButton goToLoginPageButton = new JButton("Go to Login Page"); + + public FavoritePanel() { + // Set layout + setLayout(new BorderLayout()); + + // Top Panel: Search bar and action buttons + final JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + topPanel.add(new JLabel("Enter Keyword:")); + topPanel.add(keywordField); + topPanel.add(searchButton); + topPanel.add(funniestButton); + topPanel.add(cancelButton); + add(topPanel, BorderLayout.NORTH); + + // Main Content: Scrollable list of favorite jokes + jokeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(scrollPane, BorderLayout.CENTER); + + // Bottom Panel: Navigation buttons + final JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(goToJokePageButton); + bottomPanel.add(goToLoginPageButton); + add(bottomPanel, BorderLayout.SOUTH); + + // Populate with dummy data for demonstration + populateDummyData(); + } + + /** + * Populates the joke list with dummy data for testing. + * Remove this method in production. + */ + private void populateDummyData() { + for (int i = 1; i <= 50; i++) { + jokeListModel.addElement("Favorite Joke " + i); + } + } + + /** + * Updates the joke list with the provided list of jokes. + * + * @param jokes the list of jokes to display + */ + public void updateJokeList(java.util.List jokes) { + jokeListModel.clear(); + for (String joke : jokes) { + jokeListModel.addElement(joke); + } + } + + /** + * Gets the keyword entered in the search field. + * + * @return the entered keyword + */ + public String getEnteredKeyword() { + return keywordField.getText().trim(); + } + + /** + * Sets the ActionListener for the search button. + * + * @param listener the ActionListener for the search button + */ + public void setSearchButtonListener(ActionListener listener) { + searchButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the funniest button. + * + * @param listener the ActionListener for the funniest button + */ + public void setFunniestButtonListener(ActionListener listener) { + funniestButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the cancel button. + * + * @param listener the ActionListener for the cancel button + */ + public void setCancelButtonListener(ActionListener listener) { + cancelButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the "Go to Joke Page" button. + * + * @param listener the ActionListener for the navigation button + */ + public void setGoToJokePageButtonListener(ActionListener listener) { + goToJokePageButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the "Go to Login Page" button. + * + * @param listener the ActionListener for the navigation button + */ + public void setGoToLoginPageButtonListener(ActionListener listener) { + goToLoginPageButton.addActionListener(listener); + } +} From 770232ef886ab469d0a113efccf3a0956cb794ba Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 17 Nov 2024 16:01:33 -0500 Subject: [PATCH 31/62] joke ui update --- .../SearchFavouritesController.java | 16 ++++++++ .../SearchFavouritesPresenter.java | 27 +++++++++++++ .../SearchFavouritesInputBoundary.java | 8 ++++ .../SearchFavouritesInteractor.java | 39 +++++++++++++++++++ .../SearchFavouritesOutputBoundary.java | 9 +++++ src/main/java/view/JokeView.java | 33 +++++++++------- 6 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java create mode 100644 src/main/java/interface_adapter/search_favourites/SearchFavouritesPresenter.java create mode 100644 src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java create mode 100644 src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java create mode 100644 src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java diff --git a/src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java b/src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java new file mode 100644 index 000000000..e2067102f --- /dev/null +++ b/src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java @@ -0,0 +1,16 @@ +package interface_adapter.search_favourites; + +import use_case.search_favourites.SearchFavouritesInputBoundary; + +public class SearchFavouritesController { + + private final SearchFavouritesInputBoundary interactor; + + public SearchFavouritesController(SearchFavouritesInputBoundary interactor) { + this.interactor = interactor; + } + + public void executeSearch(String keyword) { + interactor.searchFavourites(keyword); + } +} diff --git a/src/main/java/interface_adapter/search_favourites/SearchFavouritesPresenter.java b/src/main/java/interface_adapter/search_favourites/SearchFavouritesPresenter.java new file mode 100644 index 000000000..933f20b9b --- /dev/null +++ b/src/main/java/interface_adapter/search_favourites/SearchFavouritesPresenter.java @@ -0,0 +1,27 @@ +package interface_adapter.search_favourites; + +import use_case.search_favourites.SearchFavouritesOutputBoundary; + +public class SearchFavouritesPresenter implements SearchFavouritesOutputBoundary { + + private String resultMessage; + private String errorMessage; + + @Override + public void presentFavouritesSearchResult(String result) { + this.resultMessage = result; + } + + @Override + public void presentFavouritesSearchError(String error) { + this.errorMessage = error; + } + + public String getResultMessage() { + return resultMessage; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java b/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java new file mode 100644 index 000000000..d36b44a50 --- /dev/null +++ b/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java @@ -0,0 +1,8 @@ +package use_case.search_favourites; + +/** + * Input boundary for the Search Favourites use case. + */ +public interface SearchFavouritesInputBoundary { + void searchFavourites(String query); +} diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java new file mode 100644 index 000000000..717660704 --- /dev/null +++ b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java @@ -0,0 +1,39 @@ +package use_case.search_favourites; + +import data_access.JokeDataAccessObject; +import entity.Joke; + +import java.util.List; +import java.util.stream.Collectors; + +public class SearchFavouritesInteractor implements SearchFavouritesInputBoundary { + + private final JokeDataAccessObject jokeDataAccessObject; + private final SearchFavouritesOutputBoundary outputBoundary; + + public SearchFavouritesInteractor(JokeDataAccessObject jokeDataAccessObject, + SearchFavouritesOutputBoundary outputBoundary) { + this.jokeDataAccessObject = jokeDataAccessObject; + this.outputBoundary = outputBoundary; + } + + @Override + public void searchFavourites(String keyword) { + try { + List favourites = jokeDataAccessObject.getFavourites(); + List matchingFavourites = favourites.stream() + .filter(joke -> joke.getText().toLowerCase().contains(keyword.toLowerCase())) + .collect(Collectors.toList()); + if (matchingFavourites.isEmpty()) { + outputBoundary.presentFavouritesSearchResult("No matching jokes found in favourites."); + } else { + String result = matchingFavourites.stream() + .map(Joke::getText) + .collect(Collectors.joining("\n")); + outputBoundary.presentFavouritesSearchResult(result); + } + } catch (Exception e) { + outputBoundary.presentFavouritesSearchError("An error occurred while searching favourites."); + } + } +} diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java b/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java new file mode 100644 index 000000000..8969a439a --- /dev/null +++ b/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java @@ -0,0 +1,9 @@ +package use_case.search_favourites; + +/** + * Output boundary for the Search Favourites use case. + */ +public interface SearchFavouritesOutputBoundary { + void presentFavouritesSearchResult(String result); + void presentFavouritesSearchError(String error); +} diff --git a/src/main/java/view/JokeView.java b/src/main/java/view/JokeView.java index fe4de1b42..b3537b3a7 100644 --- a/src/main/java/view/JokeView.java +++ b/src/main/java/view/JokeView.java @@ -1,10 +1,10 @@ package view; -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; @@ -24,10 +24,10 @@ public class JokeAppView extends JPanel implements ActionListener, PropertyChang private final JokeViewModel jokeViewModel; private final JLabel userIdLabel = new JLabel("User ID: "); - private final JLabel jokeDisplayArea = new JLabel("Your joke will appear here"); private final JButton generateJokeButton = new JButton("Generate Joke"); private final JButton searchJokeButton = new JButton("Search Joke"); - private final JButton favoriteJokeButton = new JButton("Favorite Joke"); + private final JButton favoriteJokeButton = new JButton("Favourite Joke"); + private final JButton logoutButton = new JButton("Log out"); private JokeController jokeController; public JokeAppView(JokeViewModel jokeViewModel) { @@ -36,20 +36,19 @@ public JokeAppView(JokeViewModel jokeViewModel) { setupButtons(); + // Set up layout this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(title); this.add(userIdLabel); - this.add(jokeDisplayArea); this.add(generateJokeButton); this.add(searchJokeButton); this.add(favoriteJokeButton); + this.add(logoutButton); } /** * Configures the actions for each button. */ private void setupButtons() { - generateJokeButton.addActionListener(e -> jokeController.execute("Generate", "")); searchJokeButton.addActionListener(e -> { @@ -60,6 +59,7 @@ private void setupButtons() { }); favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); + logoutButton.addActionListener(e -> System.out.println("Logout action triggered")); // Placeholder for logout action } /** @@ -78,20 +78,27 @@ public void actionPerformed(ActionEvent evt) { public void propertyChange(PropertyChangeEvent evt) { if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { JokeState jokeState = (JokeState) evt.getNewValue(); - updateFields(jokeState); + displayJoke(jokeState.getJokeText()); + updateFavoriteButton(jokeState.isFavorite()); } else if ("error".equals(evt.getPropertyName())) { JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); } } /** - * Updates the UI fields based on the current state of JokeState. - * @param state the current JokeState + * Displays the joke in a pop-up dialog. + * @param jokeText the joke text to display + */ + private void displayJoke(String jokeText) { + JOptionPane.showMessageDialog(this, jokeText, "Here's Your Joke", JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Updates the favorite button text based on the favorite status. + * @param isFavorite the favorite status */ - private void updateFields(JokeState state) { - jokeDisplayArea.setText(state.getJokeText()); - favoriteJokeButton.setText(state.isFavorite() ? "Unfavourite Joke" : "Favourite Joke"); - userIdLabel.setText("User ID: " + state.getErrorMessage()); + private void updateFavoriteButton(boolean isFavorite) { + favoriteJokeButton.setText(isFavorite ? "Unfavourite Joke" : "Favourite Joke"); } public String getViewName() { From 05f3345905dafbd26e3c5aaff10ad40997f7b643 Mon Sep 17 00:00:00 2001 From: cheryl Date: Sun, 17 Nov 2024 16:19:19 -0500 Subject: [PATCH 32/62] favorite panel --- src/main/java/use_case/addToFavorite/favoriteDataAcessInterface | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/java/use_case/addToFavorite/favoriteDataAcessInterface diff --git a/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface b/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface new file mode 100644 index 000000000..e69de29bb From 503bc4029fb4c0ee5dace5ed92306677a35c024b Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 17 Nov 2024 16:22:53 -0500 Subject: [PATCH 33/62] search favourite function typo fix --- .../use_case/search_favourites/SearchFavouritesInteractor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java index 717660704..b24a4110e 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java +++ b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java @@ -20,7 +20,7 @@ public SearchFavouritesInteractor(JokeDataAccessObject jokeDataAccessObject, @Override public void searchFavourites(String keyword) { try { - List favourites = jokeDataAccessObject.getFavourites(); + List favourites = jokeDataAccessObject.getFavorites(); List matchingFavourites = favourites.stream() .filter(joke -> joke.getText().toLowerCase().contains(keyword.toLowerCase())) .collect(Collectors.toList()); From bcc9d331103d78c21ccfeef0ca8d02385c82259c Mon Sep 17 00:00:00 2001 From: five Date: Sun, 17 Nov 2024 17:03:14 -0500 Subject: [PATCH 34/62] Search Use case mostly complete, and DataaccessObject complete --- .../data_access/JokeDataAccessObject.java | 35 ++++++++++++++++++- .../use_case/search/SearchOutputBoundary.java | 4 +-- .../use_case/search/SearchOutputData.java | 14 ++++++++ .../search/adapter/SearchBuilder.java | 3 +- .../search/adapter/SearchController.java | 13 +++++-- .../search/adapter/SearchPresenter.java | 27 ++++++++++++-- .../use_case/search/adapter/SearchState.java | 4 --- .../search/adapter/SearchViewModel.java | 11 ------ .../java/view/search_view/SearchState.java | 31 ++++++++++++++++ .../view/{ => search_view}/SearchView.java | 27 +++++++------- .../view/search_view/SearchViewModel.java | 16 +++++++++ .../java/use_case/search/SearchJokeTest.java | 12 +++++++ 12 files changed, 162 insertions(+), 35 deletions(-) create mode 100644 src/main/java/use_case/search/SearchOutputData.java delete mode 100644 src/main/java/use_case/search/adapter/SearchState.java delete mode 100644 src/main/java/use_case/search/adapter/SearchViewModel.java create mode 100644 src/main/java/view/search_view/SearchState.java rename src/main/java/view/{ => search_view}/SearchView.java (67%) create mode 100644 src/main/java/view/search_view/SearchViewModel.java create mode 100644 src/test/java/use_case/search/SearchJokeTest.java diff --git a/src/main/java/data_access/JokeDataAccessObject.java b/src/main/java/data_access/JokeDataAccessObject.java index 3d6600bec..36f82f4f0 100644 --- a/src/main/java/data_access/JokeDataAccessObject.java +++ b/src/main/java/data_access/JokeDataAccessObject.java @@ -6,14 +6,17 @@ import org.json.JSONException; import org.json.JSONObject; import use_case.generate.GenerateDataAccessInterface; +import use_case.search.SearchDataAccessInterface; import java.io.IOException; -public class JokeDataAccessObject implements GenerateDataAccessInterface { +public class JokeDataAccessObject implements GenerateDataAccessInterface, + SearchDataAccessInterface { private static final String MESSAGE = "message"; private static final String API_URL = "https://v2.jokeapi.dev/joke/Any"; + private static final String API_SEARCH_URL = "https://v2.jokeapi.dev/joke/Any?contains="; @Override public String getJokeContent() { @@ -60,4 +63,34 @@ public String getJokeContent() { throw new RuntimeException(event); } } + + @Override + public String searchJoke(String keyword) { + final OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + final Request request = new Request.Builder() + .url(String.format(API_SEARCH_URL + keyword)) + .build(); + try { + final Response response = client.newCall(request).execute(); + final JSONObject responseBody = new JSONObject(response.body().string()); + + if (responseBody.getBoolean("error")) { + throw new RuntimeException(responseBody.getString(MESSAGE)); + } + else { + switch (responseBody.getString("type")) { + case "single": + return responseBody.getString("joke"); + case "twopart": + return responseBody.getString("setup") + responseBody.getString("delivery"); + default: + return "something funny"; + } + } + } + catch (IOException | JSONException event) { + throw new RuntimeException(event); + } + } } diff --git a/src/main/java/use_case/search/SearchOutputBoundary.java b/src/main/java/use_case/search/SearchOutputBoundary.java index 9decc12cc..96c824383 100644 --- a/src/main/java/use_case/search/SearchOutputBoundary.java +++ b/src/main/java/use_case/search/SearchOutputBoundary.java @@ -3,9 +3,9 @@ public interface SearchOutputBoundary { /** * Prepares the success view. - * @param joke the joke we want to present. + * @param jokeContent the joke we want to present. */ - void prepareSuccessView(String joke); + void prepareSuccessView(SearchOutputData jokeContent); /** * Prepares the failure view. diff --git a/src/main/java/use_case/search/SearchOutputData.java b/src/main/java/use_case/search/SearchOutputData.java new file mode 100644 index 000000000..0e825881e --- /dev/null +++ b/src/main/java/use_case/search/SearchOutputData.java @@ -0,0 +1,14 @@ +package use_case.search; + +public class SearchOutputData { + + private final String jokeContent; + + public SearchOutputData(String jokeContent) { + this.jokeContent = jokeContent; + } + + public String getJokeContent() { + return jokeContent; + } +} \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchBuilder.java b/src/main/java/use_case/search/adapter/SearchBuilder.java index 21a4a059c..1ee3294b3 100644 --- a/src/main/java/use_case/search/adapter/SearchBuilder.java +++ b/src/main/java/use_case/search/adapter/SearchBuilder.java @@ -1,6 +1,7 @@ package use_case.search.adapter; -import view.SearchView; +import view.search_view.SearchView; +import view.search_view.SearchViewModel; import javax.swing.*; diff --git a/src/main/java/use_case/search/adapter/SearchController.java b/src/main/java/use_case/search/adapter/SearchController.java index 40df52389..07348ebf7 100644 --- a/src/main/java/use_case/search/adapter/SearchController.java +++ b/src/main/java/use_case/search/adapter/SearchController.java @@ -1,7 +1,16 @@ package use_case.search.adapter; +import use_case.search.SearchInputBoundary; + public class SearchController { - public void execute(String text) { + private final SearchInputBoundary searchInputBoundary; + + public SearchController(SearchInputBoundary searchInteractor) { + this.searchInputBoundary = searchInteractor; + } + + public void execute(String keywords) { + searchInputBoundary.executeSearch(keywords); } -} +} \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java index 65ad6eaf2..c34fc0978 100644 --- a/src/main/java/use_case/search/adapter/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -1,4 +1,27 @@ package use_case.search.adapter; -public class SearchPresenter { -} +import use_case.search.SearchOutputBoundary; +import use_case.search.SearchOutputData; +import view.search_view.SearchState; +import view.search_view.SearchViewModel; + +public class SearchPresenter implements SearchOutputBoundary { + + private final SearchViewModel searchViewModel; + + public SearchPresenter(SearchViewModel searchViewModel) { + this.searchViewModel = searchViewModel; + } + + @Override + public void prepareSuccessView(SearchOutputData searchOutputData) { +// final SearchState searchState = searchViewModel.getState(); +// searchState.setExplanation(explanationOutputData.getExplanation()); +// searchViewModel.setState(searchState); +// searchViewModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + } +} \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchState.java b/src/main/java/use_case/search/adapter/SearchState.java deleted file mode 100644 index bc016ca1a..000000000 --- a/src/main/java/use_case/search/adapter/SearchState.java +++ /dev/null @@ -1,4 +0,0 @@ -package use_case.search.adapter; - -public class SearchState { -} diff --git a/src/main/java/use_case/search/adapter/SearchViewModel.java b/src/main/java/use_case/search/adapter/SearchViewModel.java deleted file mode 100644 index 71bcbedc3..000000000 --- a/src/main/java/use_case/search/adapter/SearchViewModel.java +++ /dev/null @@ -1,11 +0,0 @@ -package use_case.search.adapter; - -import view.SearchView; - -public class SearchViewModel { - public static final String TITLE_LABEL = "Search"; - - public void addPropertyChangeListener(SearchView searchView) { - - } -} diff --git a/src/main/java/view/search_view/SearchState.java b/src/main/java/view/search_view/SearchState.java new file mode 100644 index 000000000..61a6f8590 --- /dev/null +++ b/src/main/java/view/search_view/SearchState.java @@ -0,0 +1,31 @@ +package view.search_view; + +public class SearchState { + // info that can change + private String jokeContent = ""; + private String explanation = ""; + + @Override + public String toString() { + return "JokeState{" + + "jokeContent='" + getJokeContent() + '\'' + + ", explanation='" + getExplanation() + '\'' + + '}'; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } + + public String getJokeContent() { + return jokeContent; + } + + public void setJokeContent(String jokeContent) { + this.jokeContent = jokeContent; + } +} \ No newline at end of file diff --git a/src/main/java/view/SearchView.java b/src/main/java/view/search_view/SearchView.java similarity index 67% rename from src/main/java/view/SearchView.java rename to src/main/java/view/search_view/SearchView.java index 86d6d5699..b468e9caf 100644 --- a/src/main/java/view/SearchView.java +++ b/src/main/java/view/search_view/SearchView.java @@ -1,4 +1,4 @@ -package view; +package view.search_view; import java.awt.Component; import java.awt.event.ActionEvent; @@ -12,40 +12,43 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import use_case.search.SearchInteractor; import use_case.search.adapter.SearchController; -import use_case.search.adapter.SearchViewModel; import view.helper_functions.LabelTextPanel; public class SearchView extends JPanel implements ActionListener, PropertyChangeListener { - private final String viewName = "Search"; + + private final String viewName; private final SearchViewModel searchViewModel; - private final JLabel search = new JLabel("Enter keyword to find a joke:"); + private final JLabel searchLabel; private final JTextField keywordInputField = new JTextField(15); - private final JButton searchButton = new JButton("Search"); - private final JButton cancelButton = new JButton("Cancel"); + private final JButton searchButton; + private final JButton cancelButton; private SearchController searchController; public SearchView(SearchViewModel searchViewModel) { this.searchViewModel = searchViewModel; + this.viewName = searchViewModel.getViewName(); this.searchViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel(SearchViewModel.TITLE_LABEL); title.setAlignmentX(Component.CENTER_ALIGNMENT); - final LabelTextPanel searchBox = new LabelTextPanel(this.search, this.keywordInputField); + searchLabel = new JLabel(SearchViewModel.SEARCH_LABEL); + final LabelTextPanel searchBox = new LabelTextPanel(searchLabel, this.keywordInputField); final JPanel buttons = new JPanel(); + searchButton = new JButton(SearchViewModel.SEARCH_BUTTON_LABEL); buttons.add(searchButton); + cancelButton = new JButton(SearchViewModel.CANCEL_BUTTON_LABEL); buttons.add(cancelButton); searchButton.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(searchButton)) { - searchController.execute(keywordInputField.getText()); - } + evt -> { + if (evt.getSource().equals(searchButton)) { + searchController.execute(keywordInputField.getText()); } } ); diff --git a/src/main/java/view/search_view/SearchViewModel.java b/src/main/java/view/search_view/SearchViewModel.java new file mode 100644 index 000000000..6ef48d0d8 --- /dev/null +++ b/src/main/java/view/search_view/SearchViewModel.java @@ -0,0 +1,16 @@ +package view.search_view; + +import view.ViewModel; + +public class SearchViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Search"; + public static final String SEARCH_LABEL = "Enter keyword to find a joke:"; + public static final String SEARCH_BUTTON_LABEL = "Search"; + public static final String CANCEL_BUTTON_LABEL = "Cancel"; + + public SearchViewModel() { + super("Search"); + setState(new SearchState()); + } +} diff --git a/src/test/java/use_case/search/SearchJokeTest.java b/src/test/java/use_case/search/SearchJokeTest.java new file mode 100644 index 000000000..4907dd248 --- /dev/null +++ b/src/test/java/use_case/search/SearchJokeTest.java @@ -0,0 +1,12 @@ +package use_case.search; + +import data_access.JokeDataAccessObject; + +public class SearchJokeTest { + + public static void main(String[] args) { + JokeDataAccessObject jokeDataAccessObject = new JokeDataAccessObject(); + String joke = jokeDataAccessObject.searchJoke("bees"); + System.out.println(joke); + } +} From c52d56be07dbc79917e55b37ae0f324169efd33d Mon Sep 17 00:00:00 2001 From: five Date: Sun, 17 Nov 2024 17:08:04 -0500 Subject: [PATCH 35/62] a little bug fixed for search use case --- src/main/java/use_case/search/SearchInteractor.java | 3 ++- .../java/use_case/search/adapter/SearchPresenter.java | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/use_case/search/SearchInteractor.java b/src/main/java/use_case/search/SearchInteractor.java index 51680cfac..5989a8b3a 100644 --- a/src/main/java/use_case/search/SearchInteractor.java +++ b/src/main/java/use_case/search/SearchInteractor.java @@ -14,7 +14,8 @@ public SearchInteractor(SearchDataAccessInterface searchDataAccessObject, public void executeSearch(String keyword) { try { final String jokeContent = searchDataAccessObject.searchJoke(keyword); - searchPresenter.prepareSuccessView(jokeContent); + final SearchOutputData searchOutputData = new SearchOutputData(jokeContent); + searchPresenter.prepareSuccessView(searchOutputData); } catch (RuntimeException ex) { final String message = "failed to find a joke"; diff --git a/src/main/java/use_case/search/adapter/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java index c34fc0978..9d63283cb 100644 --- a/src/main/java/use_case/search/adapter/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -15,13 +15,14 @@ public SearchPresenter(SearchViewModel searchViewModel) { @Override public void prepareSuccessView(SearchOutputData searchOutputData) { -// final SearchState searchState = searchViewModel.getState(); -// searchState.setExplanation(explanationOutputData.getExplanation()); -// searchViewModel.setState(searchState); -// searchViewModel.firePropertyChanged(); + final SearchState searchState = searchViewModel.getState(); + searchState.setExplanation(searchOutputData.getJokeContent()); + searchViewModel.setState(searchState); + searchViewModel.firePropertyChanged(); } @Override - public void prepareFailView(String errorMessage) { + public void prepareFailureView(String errormessage) { + } } \ No newline at end of file From 5091fe7083ce945b7708df288bb29cc613643af7 Mon Sep 17 00:00:00 2001 From: five Date: Mon, 18 Nov 2024 10:25:56 -0500 Subject: [PATCH 36/62] Ported logout and signup use case from lab5 --- .../use_case/logout/LogoutInputBoundary.java | 13 ++ .../java/use_case/logout/LogoutInputData.java | 16 ++ .../use_case/logout/LogoutInteractor.java | 24 +++ .../use_case/logout/LogoutOutputBoundary.java | 18 ++ .../use_case/logout/LogoutOutputData.java | 23 +++ .../logout/LogoutUserDataAccessInterface.java | 19 ++ .../logout/adapter/LogoutController.java | 27 +++ .../logout/adapter/LogoutPresenter.java | 50 +++++ .../use_case/signup/SignupInputBoundary.java | 18 ++ .../java/use_case/signup/SignupInputData.java | 29 +++ .../use_case/signup/SignupInteractor.java | 43 ++++ .../use_case/signup/SignupOutputBoundary.java | 24 +++ .../use_case/signup/SignupOutputData.java | 24 +++ .../signup/SignupUserDataAccessInterface.java | 22 ++ .../signup/adapter/SignupController.java | 36 ++++ .../signup/adapter/SignupPresenter.java | 50 +++++ .../use_case/signup/adapter/SignupState.java | 70 +++++++ .../signup/adapter/SignupViewModel.java | 25 +++ src/main/java/view/SignupView.java | 193 ++++++++++++++++++ 19 files changed, 724 insertions(+) create mode 100644 src/main/java/use_case/logout/LogoutInputBoundary.java create mode 100644 src/main/java/use_case/logout/LogoutInputData.java create mode 100644 src/main/java/use_case/logout/LogoutInteractor.java create mode 100644 src/main/java/use_case/logout/LogoutOutputBoundary.java create mode 100644 src/main/java/use_case/logout/LogoutOutputData.java create mode 100644 src/main/java/use_case/logout/LogoutUserDataAccessInterface.java create mode 100644 src/main/java/use_case/logout/adapter/LogoutController.java create mode 100644 src/main/java/use_case/logout/adapter/LogoutPresenter.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 create mode 100644 src/main/java/use_case/signup/adapter/SignupController.java create mode 100644 src/main/java/use_case/signup/adapter/SignupPresenter.java create mode 100644 src/main/java/use_case/signup/adapter/SignupState.java create mode 100644 src/main/java/use_case/signup/adapter/SignupViewModel.java create mode 100644 src/main/java/view/SignupView.java diff --git a/src/main/java/use_case/logout/LogoutInputBoundary.java b/src/main/java/use_case/logout/LogoutInputBoundary.java new file mode 100644 index 000000000..189f50168 --- /dev/null +++ b/src/main/java/use_case/logout/LogoutInputBoundary.java @@ -0,0 +1,13 @@ +package use_case.logout; + +/** + * Input Boundary for actions which are related to logging in. + */ +public interface LogoutInputBoundary { + + /** + * Executes the Logout use case. + * @param LogoutInputData the input data + */ + void execute(LogoutInputData LogoutInputData); +} diff --git a/src/main/java/use_case/logout/LogoutInputData.java b/src/main/java/use_case/logout/LogoutInputData.java new file mode 100644 index 000000000..917fc0767 --- /dev/null +++ b/src/main/java/use_case/logout/LogoutInputData.java @@ -0,0 +1,16 @@ +package use_case.logout; + +/** + * The Input Data for the Logout Use Case. + */ +public class LogoutInputData { + + private final String username; + + public LogoutInputData(String username) { + this.username = username; + } + + String getUsername() {return username; } + +} diff --git a/src/main/java/use_case/logout/LogoutInteractor.java b/src/main/java/use_case/logout/LogoutInteractor.java new file mode 100644 index 000000000..90ca7f559 --- /dev/null +++ b/src/main/java/use_case/logout/LogoutInteractor.java @@ -0,0 +1,24 @@ +package use_case.logout; + +/** + * The Logout Interactor. + */ +public class LogoutInteractor implements LogoutInputBoundary { + private LogoutUserDataAccessInterface userDataAccessObject; + private LogoutOutputBoundary logoutPresenter; + + public LogoutInteractor(LogoutUserDataAccessInterface userDataAccessInterface, + LogoutOutputBoundary logoutOutputBoundary) { + this.userDataAccessObject = userDataAccessInterface; + this.logoutPresenter = logoutOutputBoundary; + } + + @Override + public void execute(LogoutInputData logoutInputData) { + final String username = logoutInputData.getUsername(); + userDataAccessObject.setCurrentUsername(null); + final LogoutOutputData logoutOutputData = new LogoutOutputData(username, false); + logoutPresenter.prepareSuccessView(logoutOutputData); + } +} + diff --git a/src/main/java/use_case/logout/LogoutOutputBoundary.java b/src/main/java/use_case/logout/LogoutOutputBoundary.java new file mode 100644 index 000000000..935a06bdc --- /dev/null +++ b/src/main/java/use_case/logout/LogoutOutputBoundary.java @@ -0,0 +1,18 @@ +package use_case.logout; + +/** + * The output boundary for the Login Use Case. + */ +public interface LogoutOutputBoundary { + /** + * Prepares the success view for the Login Use Case. + * @param outputData the output data + */ + void prepareSuccessView(LogoutOutputData 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/logout/LogoutOutputData.java b/src/main/java/use_case/logout/LogoutOutputData.java new file mode 100644 index 000000000..9f8e20539 --- /dev/null +++ b/src/main/java/use_case/logout/LogoutOutputData.java @@ -0,0 +1,23 @@ +package use_case.logout; + +/** + * Output Data for the Logout Use Case. + */ +public class LogoutOutputData { + + private String username; + private boolean useCaseFailed; + + public LogoutOutputData(String username, boolean useCaseFailed) { + this.username = username; + this.useCaseFailed = useCaseFailed; + } + + public String getUsername() { + return username; + } + + public boolean isUseCaseFailed() { + return useCaseFailed; + } +} diff --git a/src/main/java/use_case/logout/LogoutUserDataAccessInterface.java b/src/main/java/use_case/logout/LogoutUserDataAccessInterface.java new file mode 100644 index 000000000..8263700e2 --- /dev/null +++ b/src/main/java/use_case/logout/LogoutUserDataAccessInterface.java @@ -0,0 +1,19 @@ +package use_case.logout; + +/** + * DAO for the Logout Use Case. + */ +public interface LogoutUserDataAccessInterface { + + /** + * Returns the username of the curren user of the application. + * @return the username of the current user + */ + String getCurrentUsername(); + + /** + * Sets the username indicating who is the current user of the application. + * @param username the new current username + */ + void setCurrentUsername(String username); +} diff --git a/src/main/java/use_case/logout/adapter/LogoutController.java b/src/main/java/use_case/logout/adapter/LogoutController.java new file mode 100644 index 000000000..304b0833c --- /dev/null +++ b/src/main/java/use_case/logout/adapter/LogoutController.java @@ -0,0 +1,27 @@ +package use_case.logout.adapter; + +import use_case.logout.LogoutInputBoundary; +import use_case.logout.LogoutInputData; + +/** + * The controller for the Logout Ue Case. + */ +public class LogoutController { + + private LogoutInputBoundary logoutUseCaseInteractor; + + public LogoutController(LogoutInputBoundary logoutUseCaseInteractor) { + this.logoutUseCaseInteractor = logoutUseCaseInteractor; + } + + /** + * Executes the Logout Use Case. + * @param username the username of the user logging in + */ + public void execute(String username) { + + final LogoutInputData logoutInputData = new LogoutInputData(username); + + logoutUseCaseInteractor.execute(logoutInputData); + } +} diff --git a/src/main/java/use_case/logout/adapter/LogoutPresenter.java b/src/main/java/use_case/logout/adapter/LogoutPresenter.java new file mode 100644 index 000000000..f28e1c40d --- /dev/null +++ b/src/main/java/use_case/logout/adapter/LogoutPresenter.java @@ -0,0 +1,50 @@ +package use_case.logout.adapter; + +import interface_adapter.ViewManagerModel; +import interface_adapter.change_password.LoggedInState; +import interface_adapter.change_password.LoggedInViewModel; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; +import use_case.logout.LogoutOutputBoundary; +import use_case.logout.LogoutOutputData; + +/** + * The Presenter for the Logout Use Case. + */ +public class LogoutPresenter implements LogoutOutputBoundary { + + private final LoggedInViewModel loggedInViewModel; + private final ViewManagerModel viewManagerModel; + private final LoginViewModel loginViewModel; + + public LogoutPresenter(ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel, + LoginViewModel loginViewModel) { + this.loggedInViewModel = loggedInViewModel; + this.viewManagerModel = viewManagerModel; + this.loginViewModel = loginViewModel; + } + + @Override + public void prepareSuccessView(LogoutOutputData response) { + final LoggedInState loggedInState = loggedInViewModel.getState(); + loggedInState.setUsername(""); + loggedInViewModel.setState(loggedInState); + loggedInViewModel.firePropertyChanged(); + final LoginState loginState = loginViewModel.getState(); + loginState.setUsername(""); + loginState.setPassword(""); + loginViewModel.setState(loginState); + loginViewModel.firePropertyChanged(); + this.viewManagerModel.setState(loggedInViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + this.viewManagerModel.setState(loginViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + // No need to add code here. We'll assume that logout can't fail. + // Thought question: is this a reasonable assumption? + } +} 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..1cb69e02e --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputBoundary.java @@ -0,0 +1,18 @@ +package use_case.signup; + +/** + * Input Boundary for actions which are related to signing up. + */ +public interface SignupInputBoundary { + + /** + * Executes the signup use case. + * @param signupInputData the input data + */ + void execute(SignupInputData signupInputData); + + /** + * Executes the switch to login view use case. + */ + 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..86c5e8abc --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputData.java @@ -0,0 +1,29 @@ +package use_case.signup; + +/** + * The Input Data for the Signup Use Case. + */ +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; + } + + String getUsername() { + return username; + } + + 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..3fd6560c7 --- /dev/null +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -0,0 +1,43 @@ +package use_case.signup; + +import entity.User; +import entity.UserFactory; + +/** + * The Signup Interactor. + */ +public class SignupInteractor implements SignupInputBoundary { + private final SignupUserDataAccessInterface userDataAccessObject; + private final SignupOutputBoundary userPresenter; + private final UserFactory userFactory; + + public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, + SignupOutputBoundary signupOutputBoundary, + UserFactory userFactory) { + this.userDataAccessObject = signupDataAccessInterface; + this.userPresenter = signupOutputBoundary; + this.userFactory = userFactory; + } + + @Override + public void execute(SignupInputData signupInputData) { + if (userDataAccessObject.existsByName(signupInputData.getUsername())) { + userPresenter.prepareFailView("User already exists."); + } + else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword())) { + userPresenter.prepareFailView("Passwords don't match."); + } + else { + final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); + userDataAccessObject.save(user); + + final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); + userPresenter.prepareSuccessView(signupOutputData); + } + } + + @Override + public void switchToLoginView() { + userPresenter.switchToLoginView(); + } +} 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..314376b93 --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -0,0 +1,24 @@ +package use_case.signup; + +/** + * The output boundary for the Signup Use Case. + */ +public interface SignupOutputBoundary { + + /** + * Prepares the success view for the Signup Use Case. + * @param outputData the output data + */ + void prepareSuccessView(SignupOutputData outputData); + + /** + * Prepares the failure view for the Signup Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); + + /** + * Switches to the Login View. + */ + void switchToLoginView(); +} 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..6dc74d2fb --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputData.java @@ -0,0 +1,24 @@ +package use_case.signup; + +/** + * Output Data for the Signup Use Case. + */ +public class SignupOutputData { + + private final String username; + + private final boolean useCaseFailed; + + public SignupOutputData(String username, boolean useCaseFailed) { + this.username = username; + this.useCaseFailed = useCaseFailed; + } + + public String getUsername() { + return username; + } + + public boolean isUseCaseFailed() { + return useCaseFailed; + } +} 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..b9d60f585 --- /dev/null +++ b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java @@ -0,0 +1,22 @@ +package use_case.signup; + +import entity.User; + +/** + * DAO for the Signup Use Case. + */ +public interface SignupUserDataAccessInterface { + + /** + * 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); +} diff --git a/src/main/java/use_case/signup/adapter/SignupController.java b/src/main/java/use_case/signup/adapter/SignupController.java new file mode 100644 index 000000000..7f81a5963 --- /dev/null +++ b/src/main/java/use_case/signup/adapter/SignupController.java @@ -0,0 +1,36 @@ +package use_case.signup.adapter; + +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInputData; + +/** + * Controller for the Signup Use Case. + */ +public class SignupController { + + private final SignupInputBoundary userSignupUseCaseInteractor; + + public SignupController(SignupInputBoundary userSignupUseCaseInteractor) { + this.userSignupUseCaseInteractor = userSignupUseCaseInteractor; + } + + /** + * Executes the Signup Use Case. + * @param username the username to sign up + * @param password1 the password + * @param password2 the password repeated + */ + public void execute(String username, String password1, String password2) { + final SignupInputData signupInputData = new SignupInputData( + username, password1, password2); + + userSignupUseCaseInteractor.execute(signupInputData); + } + + /** + * Executes the "switch to LoginView" Use Case. + */ + public void switchToLoginView() { + userSignupUseCaseInteractor.switchToLoginView(); + } +} diff --git a/src/main/java/use_case/signup/adapter/SignupPresenter.java b/src/main/java/use_case/signup/adapter/SignupPresenter.java new file mode 100644 index 000000000..bf7dfa08e --- /dev/null +++ b/src/main/java/use_case/signup/adapter/SignupPresenter.java @@ -0,0 +1,50 @@ +package use_case.signup.adapter; + +import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupOutputData; + +/** + * The Presenter for the Signup Use Case. + */ +public class SignupPresenter implements SignupOutputBoundary { + + private final SignupViewModel signupViewModel; + private final LoginViewModel loginViewModel; + private final ViewManagerModel viewManagerModel; + + public SignupPresenter(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel) { + this.viewManagerModel = viewManagerModel; + this.signupViewModel = signupViewModel; + this.loginViewModel = loginViewModel; + } + + @Override + 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 error) { + final SignupState signupState = signupViewModel.getState(); + signupState.setUsernameError(error); + signupViewModel.firePropertyChanged(); + } + + @Override + public void switchToLoginView() { + viewManagerModel.setState(loginViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } +} diff --git a/src/main/java/use_case/signup/adapter/SignupState.java b/src/main/java/use_case/signup/adapter/SignupState.java new file mode 100644 index 000000000..a7c746149 --- /dev/null +++ b/src/main/java/use_case/signup/adapter/SignupState.java @@ -0,0 +1,70 @@ +package use_case.signup.adapter; + +/** + * The state for the Signup View Model. + */ +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/use_case/signup/adapter/SignupViewModel.java b/src/main/java/use_case/signup/adapter/SignupViewModel.java new file mode 100644 index 000000000..a096ea6e1 --- /dev/null +++ b/src/main/java/use_case/signup/adapter/SignupViewModel.java @@ -0,0 +1,25 @@ +package use_case.signup.adapter; + +import view.ViewModel; + +/** + * The ViewModel for the Signup View. + */ +public class SignupViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Sign Up View"; + public static final String USERNAME_LABEL = "Choose username"; + public static final String PASSWORD_LABEL = "Choose password"; + public static final String REPEAT_PASSWORD_LABEL = "Enter password again"; + + public static final String SIGNUP_BUTTON_LABEL = "Sign up"; + public static final String CANCEL_BUTTON_LABEL = "Cancel"; + + public static final String TO_LOGIN_BUTTON_LABEL = "Go to Login"; + + public SignupViewModel() { + super("sign up"); + setState(new SignupState()); + } + +} diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java new file mode 100644 index 000000000..4edae975e --- /dev/null +++ b/src/main/java/view/SignupView.java @@ -0,0 +1,193 @@ +package view; + +import use_case.signup.adapter.SignupController; +import use_case.signup.adapter.SignupState; +import use_case.signup.adapter.SignupViewModel; +import view.helper_functions.LabelTextPanel; + +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 the Signup Use Case. + */ +public class SignupView extends JPanel implements ActionListener, PropertyChangeListener { + private final String viewName = "sign up"; + + private final SignupViewModel signupViewModel; + private final JTextField usernameInputField = new JTextField(15); + private final JPasswordField passwordInputField = new JPasswordField(15); + private final JPasswordField repeatPasswordInputField = new JPasswordField(15); + private SignupController signupController; + + private final JButton signUp; + private final JButton cancel; + private final JButton toLogin; + + public SignupView(SignupViewModel signupViewModel) { + this.signupViewModel = signupViewModel; + signupViewModel.addPropertyChangeListener(this); + + final JLabel title = new JLabel(SignupViewModel.TITLE_LABEL); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel usernameInfo = new LabelTextPanel( + new JLabel(SignupViewModel.USERNAME_LABEL), usernameInputField); + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel(SignupViewModel.PASSWORD_LABEL), passwordInputField); + final LabelTextPanel repeatPasswordInfo = new LabelTextPanel( + new JLabel(SignupViewModel.REPEAT_PASSWORD_LABEL), repeatPasswordInputField); + + final JPanel buttons = new JPanel(); + toLogin = new JButton(SignupViewModel.TO_LOGIN_BUTTON_LABEL); + buttons.add(toLogin); + signUp = new JButton(SignupViewModel.SIGNUP_BUTTON_LABEL); + buttons.add(signUp); + cancel = new JButton(SignupViewModel.CANCEL_BUTTON_LABEL); + buttons.add(cancel); + + signUp.addActionListener( + // This creates an anonymous subclass of ActionListener and instantiates it. + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(signUp)) { + final SignupState currentState = signupViewModel.getState(); + + signupController.execute( + currentState.getUsername(), + currentState.getPassword(), + currentState.getRepeatPassword() + ); + } + } + } + ); + + toLogin.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + signupController.switchToLoginView(); + } + } + ); + + cancel.addActionListener(this); + + addUsernameListener(); + addPasswordListener(); + addRepeatPasswordListener(); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + this.add(title); + this.add(usernameInfo); + this.add(passwordInfo); + this.add(repeatPasswordInfo); + this.add(buttons); + } + + 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 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 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(); + } + }); + } + + @Override + public void actionPerformed(ActionEvent evt) { + 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()); + } + } + + public String getViewName() { + return viewName; + } + + public void setSignupController(SignupController controller) { + this.signupController = controller; + } +} From eb5d4a3637389a56649a39464d49c1eac16f44bd Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Mon, 18 Nov 2024 19:56:53 -0500 Subject: [PATCH 37/62] mainview update --- src/main/java/view/JokeView.java | 111 ------------------------------- src/main/java/view/MainView.java | 106 +++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 111 deletions(-) delete mode 100644 src/main/java/view/JokeView.java create mode 100644 src/main/java/view/MainView.java diff --git a/src/main/java/view/JokeView.java b/src/main/java/view/JokeView.java deleted file mode 100644 index b3537b3a7..000000000 --- a/src/main/java/view/JokeView.java +++ /dev/null @@ -1,111 +0,0 @@ -package view; - -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 interface_adapter.joke.JokeController; -import interface_adapter.joke.JokeState; -import interface_adapter.joke.JokeViewModel; - -/** - * The View for displaying jokes and interacting with the Joke Application. - */ -public class JokeAppView extends JPanel implements ActionListener, PropertyChangeListener { - - private final String viewName = "joke view"; - private final JokeViewModel jokeViewModel; - - private final JLabel userIdLabel = new JLabel("User ID: "); - private final JButton generateJokeButton = new JButton("Generate Joke"); - private final JButton searchJokeButton = new JButton("Search Joke"); - private final JButton favoriteJokeButton = new JButton("Favourite Joke"); - private final JButton logoutButton = new JButton("Log out"); - private JokeController jokeController; - - public JokeAppView(JokeViewModel jokeViewModel) { - this.jokeViewModel = jokeViewModel; - this.jokeViewModel.addPropertyChangeListener(this); - - setupButtons(); - - // Set up layout - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(userIdLabel); - this.add(generateJokeButton); - this.add(searchJokeButton); - this.add(favoriteJokeButton); - this.add(logoutButton); - } - - /** - * Configures the actions for each button. - */ - private void setupButtons() { - generateJokeButton.addActionListener(e -> jokeController.execute("Generate", "")); - - searchJokeButton.addActionListener(e -> { - String query = JOptionPane.showInputDialog(this, "Search Joke:"); - if (query != null && !query.trim().isEmpty()) { - jokeController.execute("search", query); - } - }); - - favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); - logoutButton.addActionListener(e -> System.out.println("Logout action triggered")); // Placeholder for logout action - } - - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ - @Override - public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); - } - - /** - * Handles updates from the JokeViewModel, updating the UI display accordingly. - */ - @Override - public void propertyChange(PropertyChangeEvent evt) { - if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { - JokeState jokeState = (JokeState) evt.getNewValue(); - displayJoke(jokeState.getJokeText()); - updateFavoriteButton(jokeState.isFavorite()); - } else if ("error".equals(evt.getPropertyName())) { - JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); - } - } - - /** - * Displays the joke in a pop-up dialog. - * @param jokeText the joke text to display - */ - private void displayJoke(String jokeText) { - JOptionPane.showMessageDialog(this, jokeText, "Here's Your Joke", JOptionPane.INFORMATION_MESSAGE); - } - - /** - * Updates the favorite button text based on the favorite status. - * @param isFavorite the favorite status - */ - private void updateFavoriteButton(boolean isFavorite) { - favoriteJokeButton.setText(isFavorite ? "Unfavourite Joke" : "Favourite Joke"); - } - - public String getViewName() { - return viewName; - } - - public void setJokeController(JokeController jokeController) { - this.jokeController = jokeController; - } -} diff --git a/src/main/java/view/MainView.java b/src/main/java/view/MainView.java new file mode 100644 index 000000000..7702cea68 --- /dev/null +++ b/src/main/java/view/MainView.java @@ -0,0 +1,106 @@ +package view; + +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 interface_adapter.joke.JokeController; +import interface_adapter.joke.JokeViewModel; +import use_case.favourite.adapter.FavouriteController; +import use_case.generate.adapter.GenerateController; +import use_case.search.adapter.SearchController; + +/** + * The Main View for interacting with the Joke Application. + */ +public class MainView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "joke view"; + private final JokeViewModel jokeViewModel; + + private final JLabel userIdLabel = new JLabel("User ID: "); + private final JButton generateJokeButton = new JButton("Generate Joke"); + private final JButton searchJokeButton = new JButton("Search Joke"); + private final JButton favouritePageButton = new JButton("Go to Favourites"); + private final JButton logoutButton = new JButton("Log out"); + private JokeController jokeController; + private GenerateController generateController; + private FavouriteController favouriteController; + private SearchController searchController; + + public MainView(JokeViewModel jokeViewModel) { + this.jokeViewModel = jokeViewModel; + + this.jokeViewModel.addPropertyChangeListener(this); + + setupButtons(); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(userIdLabel); + this.add(generateJokeButton); + this.add(searchJokeButton); + this.add(favouritePageButton); + this.add(logoutButton); + } + + /** + * Configures the actions for each button. + */ + private void setupButtons() { + generateJokeButton.addActionListener(event -> jokeController.execute("Generate", "")); + + searchJokeButton.addActionListener(event -> { + final String query = JOptionPane.showInputDialog(this, "Search Joke:"); + if (query != null && !query.trim().isEmpty()) { + jokeController.execute("search", query); + } + }); + favouritePageButton.addActionListener(event -> { + }); + logoutButton.addActionListener(event -> { + }); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + @Override + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + /** + * Handles updates from the JokeViewModel. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("error".equals(evt.getPropertyName())) { + JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } + + public String getViewName() { + return viewName; + } + + public void setGenerateController(GenerateController generateController) { + this.generateController = generateController; + } + + public void setSearchController(SearchController searchController) { + this.searchController = searchController; + } + + public void setFavouriteController(FavouriteController favouriteController) { + this.favouriteController = favouriteController; + } +} From 0bfa97d59707844794cdaa0d3abc6042c0faf668 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Mon, 18 Nov 2024 20:06:16 -0500 Subject: [PATCH 38/62] mainview update --- src/main/java/view/MainView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/view/MainView.java b/src/main/java/view/MainView.java index 7702cea68..2eba5e82a 100644 --- a/src/main/java/view/MainView.java +++ b/src/main/java/view/MainView.java @@ -92,6 +92,10 @@ public String getViewName() { return viewName; } + public void setFavouriteController(FavouriteController favouriteController) { + this.favouriteController = favouriteController; + } + public void setGenerateController(GenerateController generateController) { this.generateController = generateController; } @@ -99,8 +103,4 @@ public void setGenerateController(GenerateController generateController) { public void setSearchController(SearchController searchController) { this.searchController = searchController; } - - public void setFavouriteController(FavouriteController favouriteController) { - this.favouriteController = favouriteController; - } } From 31751d538e7f1dbe8ddb213dfa32068f3f1e1bdb Mon Sep 17 00:00:00 2001 From: dengxues Date: Mon, 18 Nov 2024 21:07:49 -0500 Subject: [PATCH 39/62] 11.18 lab --- .../favourite/FavouriteInputData.java | 11 + .../favourite/FavouriteOutputBoundary.java | 11 + .../favourite/FavouriteOutputData.java | 13 ++ .../FavouriteUserDataAccessInterface.java | 6 + .../adapter/FavouriteController.java | 16 ++ .../favourite/adapter/FavouritePresenter.java | 1 + .../favourite/adapter/FavouriteState.java | 22 ++ .../funniest/FunniestInputBoundary.java | 5 + .../use_case/funniest/FunniestInputData.java | 17 ++ .../use_case/funniest/FunniestInteractor.java | 19 ++ .../funniest/FunniestOutputBoundary.java | 15 ++ .../use_case/funniest/FunniestOutputData.java | 15 ++ .../adapter/DemoGeneratePresenter.java | 98 ++++----- src/main/java/view/NoteView.java | 206 +++++++++--------- 14 files changed, 303 insertions(+), 152 deletions(-) create mode 100644 src/main/java/use_case/funniest/FunniestInputBoundary.java create mode 100644 src/main/java/use_case/funniest/FunniestInputData.java create mode 100644 src/main/java/use_case/funniest/FunniestOutputBoundary.java create mode 100644 src/main/java/use_case/funniest/FunniestOutputData.java diff --git a/src/main/java/use_case/favourite/FavouriteInputData.java b/src/main/java/use_case/favourite/FavouriteInputData.java index 857a5c28d..a100dc392 100644 --- a/src/main/java/use_case/favourite/FavouriteInputData.java +++ b/src/main/java/use_case/favourite/FavouriteInputData.java @@ -1,4 +1,15 @@ package use_case.favourite; +import entity.User; + public class FavouriteInputData { + private final User user; + + public FavouriteInputData(User user) { + this.user = user; + } + + User getUser() { + return user; + } } diff --git a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java index cd33b5d66..66130662f 100644 --- a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java +++ b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java @@ -1,4 +1,15 @@ package use_case.favourite; public interface FavouriteOutputBoundary { + /** + * Prepares the success view for the Note related Use Cases. + * @param favouriteOutputData the output data + */ + void prepareSuccessView(FavouriteOutputData favouriteOutputData); + + /** + * Prepares the failure view. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); } diff --git a/src/main/java/use_case/favourite/FavouriteOutputData.java b/src/main/java/use_case/favourite/FavouriteOutputData.java index 6faf05ff0..34d2c8e63 100644 --- a/src/main/java/use_case/favourite/FavouriteOutputData.java +++ b/src/main/java/use_case/favourite/FavouriteOutputData.java @@ -1,4 +1,17 @@ package use_case.favourite; +import java.util.List; + +import entity.Joke; + public class FavouriteOutputData { + private List favouriteJokeList; + + public FavouriteOutputData(List favouriteJokeList) { + this.favouriteJokeList = favouriteJokeList; + } + + public List getFavouriteJokeList() { + return favouriteJokeList; + } } diff --git a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java index 7b3e7b4f2..ee6e88503 100644 --- a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java +++ b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java @@ -1,4 +1,10 @@ package use_case.favourite; +import java.util.List; + +import entity.Joke; +import entity.User; + public interface FavouriteUserDataAccessInterface { + List getFavouriteUsers(User user); } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteController.java b/src/main/java/use_case/favourite/adapter/FavouriteController.java index e54b9bd93..3ba37644d 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteController.java +++ b/src/main/java/use_case/favourite/adapter/FavouriteController.java @@ -1,4 +1,20 @@ package use_case.favourite.adapter; +import entity.User; +import use_case.favourite.FavouriteInputBoundary; +import use_case.favourite.FavouriteInputData; +import use_case.favourite.FavouriteInteractor; +import use_case.favourite.FavouriteOutputBoundary; + public class FavouriteController { + private final FavouriteInputBoundary userFavouriteUseCaseInteractor; + + public FavouriteController(FavouriteInputBoundary userFavouriteUseCaseInteractor) { + this.userFavouriteUseCaseInteractor = userFavouriteUseCaseInteractor; + } + + public void execute(User user) { + FavouriteInputData input = new FavouriteInputData(user); + userFavouriteUseCaseInteractor.execute(input); + }; } diff --git a/src/main/java/use_case/favourite/adapter/FavouritePresenter.java b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java index 8426f3996..3bb4fdc37 100644 --- a/src/main/java/use_case/favourite/adapter/FavouritePresenter.java +++ b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java @@ -1,4 +1,5 @@ package use_case.favourite.adapter; public class FavouritePresenter { + } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteState.java b/src/main/java/use_case/favourite/adapter/FavouriteState.java index 18962f73d..9df55c786 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteState.java +++ b/src/main/java/use_case/favourite/adapter/FavouriteState.java @@ -1,4 +1,26 @@ package use_case.favourite.adapter; +import java.util.List; + +import entity.Joke; + public class FavouriteState { + private String keyWord; + private List favourites; + + public List getFavourites() { + return favourites; + } + + public void setFavourites(List favourites) { + this.favourites = favourites; + } + + public String getKeyWord() { + return keyWord; + } + + public void setKeyWord(String keyWord) { + this.keyWord = keyWord; + } } diff --git a/src/main/java/use_case/funniest/FunniestInputBoundary.java b/src/main/java/use_case/funniest/FunniestInputBoundary.java new file mode 100644 index 000000000..9f8c21cd9 --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestInputBoundary.java @@ -0,0 +1,5 @@ +package use_case.funniest; + +public interface FunniestInputBoundary { + void execute(FunniestInputData funniestInputData); +} diff --git a/src/main/java/use_case/funniest/FunniestInputData.java b/src/main/java/use_case/funniest/FunniestInputData.java new file mode 100644 index 000000000..2943d68ae --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestInputData.java @@ -0,0 +1,17 @@ +package use_case.funniest; + +import java.util.List; + +import entity.Joke; + +public class FunniestInputData { + private final List favouriteJokeList; + + public FunniestInputData(List favouriteJokeList) { + this.favouriteJokeList = favouriteJokeList; + } + + List getFavouriteJokeList() { + return favouriteJokeList; + } +} diff --git a/src/main/java/use_case/funniest/FunniestInteractor.java b/src/main/java/use_case/funniest/FunniestInteractor.java index 5c4622185..76b02b77b 100644 --- a/src/main/java/use_case/funniest/FunniestInteractor.java +++ b/src/main/java/use_case/funniest/FunniestInteractor.java @@ -1,4 +1,23 @@ package use_case.funniest; +import use_case.explanation.ExplanationInputData; +import use_case.explanation.ExplanationOutputData; +import use_case.favourite.FavouriteOutputBoundary; + public class FunniestInteractor { + private final FavouriteOutputBoundary favouriteOutputBoundary; + + public FunniestInteractor(FavouriteOutputBoundary outputBoundary) { + this.favouriteOutputBoundary = outputBoundary; + } + + public void executeFunniest(FavouriteOutputBoundary explanationInputData) { + try { + final String explanation = explanationDataAccessObject.getExplanation(explanationInputData.getJokeContent()); + explanationOutputBoundary.prepareSuccessView(new ExplanationOutputData(explanation)); + } + catch (RuntimeException ex) { + explanationOutputBoundary.prepareFailView(ex.getMessage()); + } + } } diff --git a/src/main/java/use_case/funniest/FunniestOutputBoundary.java b/src/main/java/use_case/funniest/FunniestOutputBoundary.java new file mode 100644 index 000000000..da46843c7 --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestOutputBoundary.java @@ -0,0 +1,15 @@ +package use_case.funniest; + +public interface FunniestOutputBoundary { + /** + * Prepares the success view for the Note related Use Cases. + * @param funniestOutputData the output data + */ + void prepareSuccessView(FunniestOutputData funniestOutputData); + + /** + * Prepares the failure view. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/funniest/FunniestOutputData.java b/src/main/java/use_case/funniest/FunniestOutputData.java new file mode 100644 index 000000000..bc6085ff0 --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestOutputData.java @@ -0,0 +1,15 @@ +package use_case.funniest; + +import entity.Joke; + +public class FunniestOutputData { + private final Joke joke; + + public FunniestOutputData(Joke joke) { + this.joke = joke; + } + + Joke getJoke() { + return joke; + } +} diff --git a/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java b/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java index b0ed6e798..b769568da 100644 --- a/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java +++ b/src/main/java/use_case/generate/adapter/DemoGeneratePresenter.java @@ -1,49 +1,49 @@ -package use_case.generate.adapter; - -import data_access.ExplanationDataAccessObject; -import data_access.MockExplanationDataAccessObject; -import use_case.explain.ExplanationDataAccessInterface; -import use_case.generate.GenerateOuputBoundary; - -import javax.swing.*; - -/** - * simple presenter for demo, need to change (view model and stuff) - */ -public class DemoGeneratePresenter implements GenerateOuputBoundary { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - - @Override - public void prepareSuccessView(String jokeContent) { - ExplanationDataAccessInterface explainator = new MockExplanationDataAccessObject(); -// ExplanationDataAccessInterface explainator = new ExplanationDataAccessObject(); - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Joke"); - frame.setSize(WIDTH, HEIGHT); - - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - panel.add(new JTextArea(jokeContent + explainator.getExplanation(jokeContent))); - - frame.add(panel); - frame.setVisible(true); - } - - @Override - public void prepareFailView(String errorMessage) { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Joke"); - frame.setSize(WIDTH, HEIGHT); - - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - panel.add(new JTextArea(5, 20)); - - - frame.add(panel); - frame.setVisible(true); - } -} +//package use_case.generate.adapter; +// +//import data_access.ExplanationDataAccessObject; +//import data_access.MockExplanationDataAccessObject; +//import use_case.explain.ExplanationDataAccessInterface; +//import use_case.generate.GenerateOuputBoundary; +// +//import javax.swing.*; +// +///** +// * simple presenter for demo, need to change (view model and stuff) +// */ +//public class DemoGeneratePresenter implements GenerateOuputBoundary { +// public static final int HEIGHT = 300; +// public static final int WIDTH = 400; +// +// @Override +// public void prepareSuccessView(String jokeContent) { +// ExplanationDataAccessInterface explainator = new MockExplanationDataAccessObject(); +//// ExplanationDataAccessInterface explainator = new ExplanationDataAccessObject(); +// final JFrame frame = new JFrame(); +// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); +// frame.setTitle("Joke"); +// frame.setSize(WIDTH, HEIGHT); +// +// JPanel panel = new JPanel(); +// panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); +// panel.add(new JTextArea(jokeContent + explainator.getExplanation(jokeContent))); +// +// frame.add(panel); +// frame.setVisible(true); +// } +// +// @Override +// public void prepareFailView(String errorMessage) { +// final JFrame frame = new JFrame(); +// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); +// frame.setTitle("Joke"); +// frame.setSize(WIDTH, HEIGHT); +// +// JPanel panel = new JPanel(); +// panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); +// panel.add(new JTextArea(5, 20)); +// +// +// frame.add(panel); +// frame.setVisible(true); +// } +//} diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java index 81e52e1a6..e83522bd5 100644 --- a/src/main/java/view/NoteView.java +++ b/src/main/java/view/NoteView.java @@ -1,103 +1,103 @@ -package view; - -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.JOptionPane; -import javax.swing.JPanel; - -import interface_adapter.joke.JokeController; -import interface_adapter.joke.JokeState; -import interface_adapter.joke.JokeViewModel; - -/** - * The View for displaying jokes and interacting with the Joke Application. - */ -public class JokeAppView extends JPanel implements ActionListener, PropertyChangeListener { - - private final String viewName = "joke view"; - private final JokeViewModel jokeViewModel; - - private final JLabel userIdLabel = new JLabel("User ID: "); - private final JLabel jokeDisplayArea = new JLabel("Your joke will appear here"); - private final JButton generateJokeButton = new JButton("Generate Joke"); - private final JButton searchJokeButton = new JButton("Search Joke"); - private final JButton favoriteJokeButton = new JButton("Favorite Joke"); - private JokeController jokeController; - - public JokeAppView(JokeViewModel jokeViewModel) { - this.jokeViewModel = jokeViewModel; - this.jokeViewModel.addPropertyChangeListener(this); - - setupButtons(); - - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.add(title); - this.add(userIdLabel); - this.add(jokeDisplayArea); - this.add(generateJokeButton); - this.add(searchJokeButton); - this.add(favoriteJokeButton); - } - /** - * Configures the actions for each button. - */ - private void setupButtons() { - // Generate Joke Action - generateJokeButton.addActionListener(e -> jokeController.execute("Generate a joke", "")); - - // Search Joke Action - searchJokeButton.addActionListener(e -> { - String query = JOptionPane.showInputDialog(this, "Search for a joke:"); - if (query != null && !query.trim().isEmpty()) { - jokeController.execute("search", query); - } - }); - favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); - } - - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ - @Override - public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); - } - - /** - * Handles updates from the JokeViewModel, updating the UI display accordingly. - */ - @Override - public void propertyChange(PropertyChangeEvent evt) { - if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { - JokeState jokeState = (JokeState) evt.getNewValue(); - updateFields(jokeState); - } else if ("error".equals(evt.getPropertyName())) { - JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); - } - } - - /** - * Updates the UI fields based on the current state of JokeState - * @param state the current JokeState - */ - private void updateFields(JokeState state) { - jokeDisplayArea.setText(state.getJokeText()); - favoriteJokeButton.setText(state.isFavorite() ? "Unfavourite Joke" : "Favorite Joke"); - userIdLabel.setText("User ID: " + state.getErrorMessage()); - } - - public String getViewName() { - return viewName; - } - - public void setJokeController(JokeController jokeController) { - this.jokeController = jokeController; - } -} +//package view; +// +//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.JOptionPane; +//import javax.swing.JPanel; +// +//import interface_adapter.joke.JokeController; +//import interface_adapter.joke.JokeState; +//import interface_adapter.joke.JokeViewModel; +// +///** +// * The View for displaying jokes and interacting with the Joke Application. +// */ +//public class JokeAppView extends JPanel implements ActionListener, PropertyChangeListener { +// +// private final String viewName = "joke view"; +// private final JokeViewModel jokeViewModel; +// +// private final JLabel userIdLabel = new JLabel("User ID: "); +// private final JLabel jokeDisplayArea = new JLabel("Your joke will appear here"); +// private final JButton generateJokeButton = new JButton("Generate Joke"); +// private final JButton searchJokeButton = new JButton("Search Joke"); +// private final JButton favoriteJokeButton = new JButton("Favorite Joke"); +// private JokeController jokeController; +// +// public JokeAppView(JokeViewModel jokeViewModel) { +// this.jokeViewModel = jokeViewModel; +// this.jokeViewModel.addPropertyChangeListener(this); +// +// setupButtons(); +// +// this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); +// this.add(title); +// this.add(userIdLabel); +// this.add(jokeDisplayArea); +// this.add(generateJokeButton); +// this.add(searchJokeButton); +// this.add(favoriteJokeButton); +// } +// /** +// * Configures the actions for each button. +// */ +// private void setupButtons() { +// // Generate Joke Action +// generateJokeButton.addActionListener(e -> jokeController.execute("Generate a joke", "")); +// +// // Search Joke Action +// searchJokeButton.addActionListener(e -> { +// String query = JOptionPane.showInputDialog(this, "Search for a joke:"); +// if (query != null && !query.trim().isEmpty()) { +// jokeController.execute("search", query); +// } +// }); +// favoriteJokeButton.addActionListener(e -> jokeController.execute("Favourite", "")); +// } +// +// /** +// * React to a button click that results in evt. +// * @param evt the ActionEvent to react to +// */ +// @Override +// public void actionPerformed(ActionEvent evt) { +// System.out.println("Click " + evt.getActionCommand()); +// } +// +// /** +// * Handles updates from the JokeViewModel, updating the UI display accordingly. +// */ +// @Override +// public void propertyChange(PropertyChangeEvent evt) { +// if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof JokeState) { +// JokeState jokeState = (JokeState) evt.getNewValue(); +// updateFields(jokeState); +// } else if ("error".equals(evt.getPropertyName())) { +// JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", JOptionPane.ERROR_MESSAGE); +// } +// } +// +// /** +// * Updates the UI fields based on the current state of JokeState +// * @param state the current JokeState +// */ +// private void updateFields(JokeState state) { +// jokeDisplayArea.setText(state.getJokeText()); +// favoriteJokeButton.setText(state.isFavorite() ? "Unfavourite Joke" : "Favorite Joke"); +// userIdLabel.setText("User ID: " + state.getErrorMessage()); +// } +// +// public String getViewName() { +// return viewName; +// } +// +// public void setJokeController(JokeController jokeController) { +// this.jokeController = jokeController; +// } +//} From db118cbab55547d1ba43d9f428bd471d98a1fbdb Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Mon, 25 Nov 2024 19:15:04 -0500 Subject: [PATCH 40/62] Mainview constant change and relocation --- .../interface_adapter/joke/JokeViewModel.java | 14 --------- .../interface_adapter/joke/MainState.java | 7 +++++ .../interface_adapter/joke/MainViewModel.java | 14 +++++++++ .../java/view/joke_view/JokeViewModel.java | 18 ------------ .../JokeState.java => main/MainState.java} | 4 +-- src/main/java/view/{ => main}/MainView.java | 29 ++++++++++++------- src/main/java/view/main/MainViewModel.java | 18 ++++++++++++ 7 files changed, 59 insertions(+), 45 deletions(-) delete mode 100644 src/main/java/interface_adapter/joke/JokeViewModel.java create mode 100644 src/main/java/interface_adapter/joke/MainState.java create mode 100644 src/main/java/interface_adapter/joke/MainViewModel.java delete mode 100644 src/main/java/view/joke_view/JokeViewModel.java rename src/main/java/view/{joke_view/JokeState.java => main/MainState.java} (93%) rename src/main/java/view/{ => main}/MainView.java (80%) create mode 100644 src/main/java/view/main/MainViewModel.java diff --git a/src/main/java/interface_adapter/joke/JokeViewModel.java b/src/main/java/interface_adapter/joke/JokeViewModel.java deleted file mode 100644 index 2e036a31e..000000000 --- a/src/main/java/interface_adapter/joke/JokeViewModel.java +++ /dev/null @@ -1,14 +0,0 @@ -package interface_adapter.joke; - -import interface_adapter.ViewModel; - -/** - * The View Model for the Joke View. - */ -public class JokeViewModel extends ViewModel { - - public JokeViewModel() { - super("joke view"); - setState(new JokeState()); // Initialize with a new JokeState - } -} diff --git a/src/main/java/interface_adapter/joke/MainState.java b/src/main/java/interface_adapter/joke/MainState.java new file mode 100644 index 000000000..50ed380f9 --- /dev/null +++ b/src/main/java/interface_adapter/joke/MainState.java @@ -0,0 +1,7 @@ +package interface_adapter.joke; + +/** + * The state for the Joke View Model. + */ +public class MainState { +} diff --git a/src/main/java/interface_adapter/joke/MainViewModel.java b/src/main/java/interface_adapter/joke/MainViewModel.java new file mode 100644 index 000000000..61a93c8bf --- /dev/null +++ b/src/main/java/interface_adapter/joke/MainViewModel.java @@ -0,0 +1,14 @@ +package interface_adapter.joke; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Joke View. + */ +public class MainViewModel extends ViewModel { + + public MainViewModel() { + super("joke view"); + setState(new MainState()); + } +} diff --git a/src/main/java/view/joke_view/JokeViewModel.java b/src/main/java/view/joke_view/JokeViewModel.java deleted file mode 100644 index 24b37f21f..000000000 --- a/src/main/java/view/joke_view/JokeViewModel.java +++ /dev/null @@ -1,18 +0,0 @@ -package view.joke_view; - -import view.ViewModel; - - -public class JokeViewModel extends ViewModel { - - public static final String TITLE_LABEL = "Joke"; - public static final String EXPLANATION_BUTTON_LABEL = "Explain"; - public static final String ADD_BUTTON_LABEL = "Add to Favorite"; - public static final String EXPLANATION_LABEL = "Explanation"; - - public JokeViewModel() { - super("Joke"); - setState(new JokeState()); - } - // a wrapper for all the info you need to build a view -} diff --git a/src/main/java/view/joke_view/JokeState.java b/src/main/java/view/main/MainState.java similarity index 93% rename from src/main/java/view/joke_view/JokeState.java rename to src/main/java/view/main/MainState.java index 4b9a4b4f2..63361fe7c 100644 --- a/src/main/java/view/joke_view/JokeState.java +++ b/src/main/java/view/main/MainState.java @@ -1,6 +1,6 @@ -package view.joke_view; +package view.main; -public class JokeState { +public class MainState { // info that can change private String jokeContent = ""; private String explanation = ""; diff --git a/src/main/java/view/MainView.java b/src/main/java/view/main/MainView.java similarity index 80% rename from src/main/java/view/MainView.java rename to src/main/java/view/main/MainView.java index 2eba5e82a..c744847f7 100644 --- a/src/main/java/view/MainView.java +++ b/src/main/java/view/main/MainView.java @@ -1,4 +1,4 @@ -package view; +package view.main; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -12,30 +12,33 @@ import javax.swing.JPanel; import interface_adapter.joke.JokeController; -import interface_adapter.joke.JokeViewModel; +import interface_adapter.joke.MainViewModel; import use_case.favourite.adapter.FavouriteController; import use_case.generate.adapter.GenerateController; import use_case.search.adapter.SearchController; +import static view.main.MainViewModel.*; + /** * The Main View for interacting with the Joke Application. */ public class MainView extends JPanel implements ActionListener, PropertyChangeListener { - private final String viewName = "joke view"; - private final JokeViewModel jokeViewModel; + private final String viewName = TITLE_LABEL; + private final MainViewModel jokeViewModel; private final JLabel userIdLabel = new JLabel("User ID: "); - private final JButton generateJokeButton = new JButton("Generate Joke"); - private final JButton searchJokeButton = new JButton("Search Joke"); - private final JButton favouritePageButton = new JButton("Go to Favourites"); - private final JButton logoutButton = new JButton("Log out"); + private final JButton generateJokeButton = new JButton(GENERATE_BUTTON_LABEL); + private final JButton searchJokeButton = new JButton(SEARCH_BUTTON_LABEL); + private final JButton favouritePageButton = new JButton(FAVOURITE_BUTTON_LABEL); + private final JButton logoutButton = new JButton(LOGOUT_BUTTON_LABEL); + private JokeController jokeController; private GenerateController generateController; private FavouriteController favouriteController; private SearchController searchController; - public MainView(JokeViewModel jokeViewModel) { + public MainView(MainViewModel jokeViewModel) { this.jokeViewModel = jokeViewModel; this.jokeViewModel.addPropertyChangeListener(this); @@ -57,14 +60,18 @@ private void setupButtons() { generateJokeButton.addActionListener(event -> jokeController.execute("Generate", "")); searchJokeButton.addActionListener(event -> { - final String query = JOptionPane.showInputDialog(this, "Search Joke:"); + final String query = JOptionPane.showInputDialog(this, SEARCH_BUTTON_LABEL + ":"); if (query != null && !query.trim().isEmpty()) { jokeController.execute("search", query); } }); + favouritePageButton.addActionListener(event -> { + // Navigate to favourites }); + logoutButton.addActionListener(event -> { + // Logout logic }); } @@ -83,7 +90,7 @@ public void actionPerformed(ActionEvent evt) { @Override public void propertyChange(PropertyChangeEvent evt) { if ("error".equals(evt.getPropertyName())) { - JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), "Error", + JOptionPane.showMessageDialog(this, evt.getNewValue().toString(), ERROR_DIALOG_TITLE, JOptionPane.ERROR_MESSAGE); } } diff --git a/src/main/java/view/main/MainViewModel.java b/src/main/java/view/main/MainViewModel.java new file mode 100644 index 000000000..c066cf0ab --- /dev/null +++ b/src/main/java/view/main/MainViewModel.java @@ -0,0 +1,18 @@ +package view.main; + +import view.ViewModel; + +public class MainViewModel extends ViewModel { + // Constants for UI labels + public static final String TITLE_LABEL = "Joke Application"; + public static final String GENERATE_BUTTON_LABEL = "Generate Joke"; + public static final String SEARCH_BUTTON_LABEL = "Search Joke"; + public static final String FAVOURITE_BUTTON_LABEL = "Go to Favourites"; + public static final String LOGOUT_BUTTON_LABEL = "Log out"; + public static final String ERROR_DIALOG_TITLE = "Error"; + + public MainViewModel() { + super("Joke"); + setState(new MainState()); + } +} From 42ee75db40c8d699f8c18c9163500c55dc348755 Mon Sep 17 00:00:00 2001 From: five Date: Mon, 25 Nov 2024 19:35:15 -0500 Subject: [PATCH 41/62] change path of search adapters; add addtoSearchView in signin use case; adjust structure of SearchDataAccess and interactor --- .../data_access/FileDataAccessObject.java | 4 +++ .../data_access/JokeDataAccessObject.java | 3 +- .../use_case/search/SearchInteractor.java | 12 +++---- .../use_case/search/SearchOutputData.java | 11 +++++++ .../search/adapter/SearchBuilder.java | 15 +++++++-- .../search/adapter/SearchPresenter.java | 32 +++++++++++++------ .../use_case/search/adapter/SearchState.java | 21 ++++++++++++ .../search/adapter}/SearchViewModel.java | 2 +- .../use_case/signup/SignupInputBoundary.java | 2 ++ .../use_case/signup/SignupInteractor.java | 4 +++ .../use_case/signup/SignupOutputBoundary.java | 2 ++ .../signup/adapter/SignupController.java | 5 +++ .../signup/adapter/SignupPresenter.java | 11 ++++++- .../view/{search_view => }/SearchView.java | 8 +++-- .../java/view/joke_view/JokeFrameBuilder.java | 2 +- .../java/view/search_view/SearchState.java | 31 ------------------ 16 files changed, 109 insertions(+), 56 deletions(-) create mode 100644 src/main/java/data_access/FileDataAccessObject.java create mode 100644 src/main/java/use_case/search/adapter/SearchState.java rename src/main/java/{view/search_view => use_case/search/adapter}/SearchViewModel.java (93%) rename src/main/java/view/{search_view => }/SearchView.java (92%) delete mode 100644 src/main/java/view/search_view/SearchState.java diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java new file mode 100644 index 000000000..50b931a84 --- /dev/null +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -0,0 +1,4 @@ +package data_access; + +public class FileDataAccessObject { +} diff --git a/src/main/java/data_access/JokeDataAccessObject.java b/src/main/java/data_access/JokeDataAccessObject.java index 36f82f4f0..231474fe9 100644 --- a/src/main/java/data_access/JokeDataAccessObject.java +++ b/src/main/java/data_access/JokeDataAccessObject.java @@ -74,9 +74,8 @@ public String searchJoke(String keyword) { try { final Response response = client.newCall(request).execute(); final JSONObject responseBody = new JSONObject(response.body().string()); - if (responseBody.getBoolean("error")) { - throw new RuntimeException(responseBody.getString(MESSAGE)); + return responseBody.getString(MESSAGE); } else { switch (responseBody.getString("type")) { diff --git a/src/main/java/use_case/search/SearchInteractor.java b/src/main/java/use_case/search/SearchInteractor.java index 5989a8b3a..e766bf874 100644 --- a/src/main/java/use_case/search/SearchInteractor.java +++ b/src/main/java/use_case/search/SearchInteractor.java @@ -12,14 +12,14 @@ public SearchInteractor(SearchDataAccessInterface searchDataAccessObject, @Override public void executeSearch(String keyword) { - try { - final String jokeContent = searchDataAccessObject.searchJoke(keyword); - final SearchOutputData searchOutputData = new SearchOutputData(jokeContent); - searchPresenter.prepareSuccessView(searchOutputData); - } - catch (RuntimeException ex) { + final String jokeContent = searchDataAccessObject.searchJoke(keyword); + final SearchOutputData searchOutputData = new SearchOutputData(jokeContent); + if (searchOutputData.getError()) { final String message = "failed to find a joke"; searchPresenter.prepareFailureView(message); } + else { + searchPresenter.prepareSuccessView(searchOutputData); + } } } diff --git a/src/main/java/use_case/search/SearchOutputData.java b/src/main/java/use_case/search/SearchOutputData.java index 0e825881e..6516c0e40 100644 --- a/src/main/java/use_case/search/SearchOutputData.java +++ b/src/main/java/use_case/search/SearchOutputData.java @@ -1,5 +1,7 @@ package use_case.search; +import org.json.JSONObject; + public class SearchOutputData { private final String jokeContent; @@ -11,4 +13,13 @@ public SearchOutputData(String jokeContent) { public String getJokeContent() { return jokeContent; } + + public Boolean getError() { + if ("No matching joke found".equals(jokeContent)) { + return Boolean.TRUE; + } + else { + return Boolean.FALSE; + } + } } \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchBuilder.java b/src/main/java/use_case/search/adapter/SearchBuilder.java index 1ee3294b3..a1a67d977 100644 --- a/src/main/java/use_case/search/adapter/SearchBuilder.java +++ b/src/main/java/use_case/search/adapter/SearchBuilder.java @@ -1,7 +1,9 @@ package use_case.search.adapter; -import view.search_view.SearchView; -import view.search_view.SearchViewModel; +import data_access.JokeDataAccessObject; +import use_case.search.SearchInteractor; +import view.joke_view.JokeFrameBuilder; +import view.SearchView; import javax.swing.*; @@ -13,11 +15,18 @@ public static JFrame build() { final JFrame frame = new JFrame(); final SearchViewModel viewModel = new SearchViewModel(); + final SearchView searchView = new SearchView(viewModel); + final JokeFrameBuilder frameBuilder = new JokeFrameBuilder(); + final JokeDataAccessObject jokeDataAccessObject = new JokeDataAccessObject(); + final SearchPresenter searchPresenter = new SearchPresenter(frameBuilder); + final SearchInteractor searchInteractor = new SearchInteractor(jokeDataAccessObject, searchPresenter); + final SearchController searchController = new SearchController(searchInteractor); + searchView.setSearchController(searchController); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setTitle("Search"); frame.setSize(WIDTH, HEIGHT); - frame.add(new SearchView(viewModel)); + frame.add(searchView); return frame; diff --git a/src/main/java/use_case/search/adapter/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java index 9d63283cb..f8d8f9dcb 100644 --- a/src/main/java/use_case/search/adapter/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -2,27 +2,41 @@ import use_case.search.SearchOutputBoundary; import use_case.search.SearchOutputData; -import view.search_view.SearchState; -import view.search_view.SearchViewModel; +import view.joke_view.JokeFrameBuilder; + +import javax.swing.*; public class SearchPresenter implements SearchOutputBoundary { - private final SearchViewModel searchViewModel; + private final JokeFrameBuilder jokeFrameBuilder; - public SearchPresenter(SearchViewModel searchViewModel) { - this.searchViewModel = searchViewModel; + public SearchPresenter(JokeFrameBuilder jokeFrameBuilder) { + this.jokeFrameBuilder = jokeFrameBuilder; } @Override public void prepareSuccessView(SearchOutputData searchOutputData) { - final SearchState searchState = searchViewModel.getState(); - searchState.setExplanation(searchOutputData.getJokeContent()); - searchViewModel.setState(searchState); - searchViewModel.firePropertyChanged(); + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(searchOutputData.getJokeContent()) + .addExplanationUseCase() + .addAddToFavUseCase() + .build(); + + frame.pack(); + frame.setVisible(true); } @Override public void prepareFailureView(String errormessage) { + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(errormessage) + .addExplanationUseCase() + .addAddToFavUseCase() + .build(); + frame.pack(); + frame.setVisible(true); } } \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchState.java b/src/main/java/use_case/search/adapter/SearchState.java new file mode 100644 index 000000000..20be341a1 --- /dev/null +++ b/src/main/java/use_case/search/adapter/SearchState.java @@ -0,0 +1,21 @@ +package use_case.search.adapter; + +public class SearchState { + // info that can change + private String keyWord = ""; + + @Override + public String toString() { + return "SearchState{" + + "keyWord='" + getKeyWord() + '\'' + + '}'; + } + + public String getKeyWord() { + return keyWord; + } + + public void setKeyWord(String keyWord) { + this.keyWord = keyWord; + } +} \ No newline at end of file diff --git a/src/main/java/view/search_view/SearchViewModel.java b/src/main/java/use_case/search/adapter/SearchViewModel.java similarity index 93% rename from src/main/java/view/search_view/SearchViewModel.java rename to src/main/java/use_case/search/adapter/SearchViewModel.java index 6ef48d0d8..6565ea22a 100644 --- a/src/main/java/view/search_view/SearchViewModel.java +++ b/src/main/java/use_case/search/adapter/SearchViewModel.java @@ -1,4 +1,4 @@ -package view.search_view; +package use_case.search.adapter; import view.ViewModel; diff --git a/src/main/java/use_case/signup/SignupInputBoundary.java b/src/main/java/use_case/signup/SignupInputBoundary.java index 1cb69e02e..cd73d0a56 100644 --- a/src/main/java/use_case/signup/SignupInputBoundary.java +++ b/src/main/java/use_case/signup/SignupInputBoundary.java @@ -15,4 +15,6 @@ public interface SignupInputBoundary { * Executes the switch to login view use case. */ void switchToLoginView(); + + void switchToSearchView(); } diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java index 3fd6560c7..31f7a41a6 100644 --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -40,4 +40,8 @@ else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword public void switchToLoginView() { userPresenter.switchToLoginView(); } + + public void switchToSearchView() { + userPresenter.switchToSearchView(); + } } diff --git a/src/main/java/use_case/signup/SignupOutputBoundary.java b/src/main/java/use_case/signup/SignupOutputBoundary.java index 314376b93..6dc1f0e3d 100644 --- a/src/main/java/use_case/signup/SignupOutputBoundary.java +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -21,4 +21,6 @@ public interface SignupOutputBoundary { * Switches to the Login View. */ void switchToLoginView(); + + void switchToSearchView(); } diff --git a/src/main/java/use_case/signup/adapter/SignupController.java b/src/main/java/use_case/signup/adapter/SignupController.java index 7f81a5963..d5dd0b882 100644 --- a/src/main/java/use_case/signup/adapter/SignupController.java +++ b/src/main/java/use_case/signup/adapter/SignupController.java @@ -33,4 +33,9 @@ public void execute(String username, String password1, String password2) { public void switchToLoginView() { userSignupUseCaseInteractor.switchToLoginView(); } + // TODO Task: add a switchtoSearchView for controller, presenter + // TODO Task: add a file data access object for users. + public void switchtoSearchView() { + userSignupUseCaseInteractor.switchToSearchView(); + } } diff --git a/src/main/java/use_case/signup/adapter/SignupPresenter.java b/src/main/java/use_case/signup/adapter/SignupPresenter.java index bf7dfa08e..e5e6f4702 100644 --- a/src/main/java/use_case/signup/adapter/SignupPresenter.java +++ b/src/main/java/use_case/signup/adapter/SignupPresenter.java @@ -3,6 +3,7 @@ import interface_adapter.ViewManagerModel; import interface_adapter.login.LoginState; import interface_adapter.login.LoginViewModel; +import use_case.search.adapter.SearchViewModel; import use_case.signup.SignupOutputBoundary; import use_case.signup.SignupOutputData; @@ -13,14 +14,17 @@ public class SignupPresenter implements SignupOutputBoundary { private final SignupViewModel signupViewModel; private final LoginViewModel loginViewModel; + private final SearchViewModel searchViewModel; private final ViewManagerModel viewManagerModel; public SignupPresenter(ViewManagerModel viewManagerModel, SignupViewModel signupViewModel, - LoginViewModel loginViewModel) { + LoginViewModel loginViewModel, + SearchViewModel searchViewModel) { this.viewManagerModel = viewManagerModel; this.signupViewModel = signupViewModel; this.loginViewModel = loginViewModel; + this.searchViewModel = searchViewModel; } @Override @@ -47,4 +51,9 @@ public void switchToLoginView() { viewManagerModel.setState(loginViewModel.getViewName()); viewManagerModel.firePropertyChanged(); } + + public void switchToSearchView() { + viewManagerModel.setState(searchViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/view/search_view/SearchView.java b/src/main/java/view/SearchView.java similarity index 92% rename from src/main/java/view/search_view/SearchView.java rename to src/main/java/view/SearchView.java index b468e9caf..fc44d15a5 100644 --- a/src/main/java/view/search_view/SearchView.java +++ b/src/main/java/view/SearchView.java @@ -1,4 +1,4 @@ -package view.search_view; +package view; import java.awt.Component; import java.awt.event.ActionEvent; @@ -12,9 +12,9 @@ import javax.swing.JPanel; import javax.swing.JTextField; -import use_case.search.SearchInteractor; import use_case.search.adapter.SearchController; import view.helper_functions.LabelTextPanel; +import use_case.search.adapter.SearchViewModel; public class SearchView extends JPanel implements ActionListener, PropertyChangeListener { @@ -71,5 +71,9 @@ public void actionPerformed(ActionEvent e) { public void propertyChange(PropertyChangeEvent evt) { } + + public void setSearchController(SearchController searchController) { + this.searchController = searchController; + } } diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java index d3ff33ab4..0ad00c8e7 100644 --- a/src/main/java/view/joke_view/JokeFrameBuilder.java +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -19,7 +19,7 @@ public class JokeFrameBuilder { // view doesn't change, so don't need ViewManager(cardPanel, cardLayout, viewManagerModel); //TODO change mock - private final ExplanationDataAccessInterface explanationDataAccessObject = new ExplanationDataAccessObject(); + private final ExplanationDataAccessInterface explanationDataAccessObject = new MockExplanationDataAccessObject(); public JokeFrameBuilder() { } diff --git a/src/main/java/view/search_view/SearchState.java b/src/main/java/view/search_view/SearchState.java deleted file mode 100644 index 61a6f8590..000000000 --- a/src/main/java/view/search_view/SearchState.java +++ /dev/null @@ -1,31 +0,0 @@ -package view.search_view; - -public class SearchState { - // info that can change - private String jokeContent = ""; - private String explanation = ""; - - @Override - public String toString() { - return "JokeState{" - + "jokeContent='" + getJokeContent() + '\'' - + ", explanation='" + getExplanation() + '\'' - + '}'; - } - - public String getExplanation() { - return explanation; - } - - public void setExplanation(String explanation) { - this.explanation = explanation; - } - - public String getJokeContent() { - return jokeContent; - } - - public void setJokeContent(String jokeContent) { - this.jokeContent = jokeContent; - } -} \ No newline at end of file From 2700b73fb98ddcb48aae5c0eff0162a1a413c738 Mon Sep 17 00:00:00 2001 From: cheryl Date: Mon, 25 Nov 2024 19:42:19 -0500 Subject: [PATCH 42/62] add to fav --- .../AddToFavDataAccessInterface.java | 33 ++++++++++ .../add_to_fav/AddToFavInputBoundary.java | 15 +++++ .../add_to_fav/AddToFavInputData.java | 39 ++++++++++++ .../add_to_fav/AddToFavInteractor.java | 63 +++++++++++++++++++ .../add_to_fav/AddToFavOutputBoundary.java | 23 +++++++ .../add_to_fav/AddToFavOutputData.java | 26 ++++++++ .../add_to_fav/AddToFavRequestModel.java | 29 +++++++++ .../add_to_fav/AddToFavResponseModel.java | 22 +++++++ .../adapter/AddToFavController.java | 44 +++++++++++++ .../add_to_fav/adapter/AddToFavPresenter.java | 35 +++++++++++ 10 files changed, 329 insertions(+) create mode 100644 src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavInputData.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavInteractor.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavOutputData.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavRequestModel.java create mode 100644 src/main/java/use_case/add_to_fav/AddToFavResponseModel.java create mode 100644 src/main/java/use_case/add_to_fav/adapter/AddToFavController.java create mode 100644 src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java diff --git a/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java new file mode 100644 index 000000000..1fb0f19f1 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java @@ -0,0 +1,33 @@ +package use_case.add_to_fav; + +import entity.Joke; +import entity.User; + +/** + * The AddToFavDataAccessInterface defines methods for accessing + * user and joke data in the data storage layer. + */ +public interface AddToFavDataAccessInterface { + /** + * Retrieves a user by username. + * + * @param username the username of the user + * @return the User object, or null if not found + */ + User getUser(String username); + + /** + * Retrieves a joke by ID. + * + * @param jokeId the ID of the joke + * @return the Joke object, or null if not found + */ + Joke getJoke(String jokeId); + + /** + * Saves the updated user to the data storage. + * + * @param user the User object to save + */ + void saveUser(User user); +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java b/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java new file mode 100644 index 000000000..71f8c6e76 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java @@ -0,0 +1,15 @@ +package use_case.add_to_fav; + +/** + * The AddToFavInputBoundary interface defines the input boundary + * for the Add to Favorites use case. + */ +public interface AddToFavInputBoundary { + /** + * Adds a joke to a user's favorites list. + * + * @param inputData the input data containing the username and joke ID + * @return a response model indicating the result of the operation + */ + AddToFavOutputData addToFavorites(AddToFavInputData inputData); +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavInputData.java b/src/main/java/use_case/add_to_fav/AddToFavInputData.java new file mode 100644 index 000000000..0a65d4c00 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavInputData.java @@ -0,0 +1,39 @@ +package use_case.add_to_fav; + +/** + * The AddToFavInputData class represents the input data + * for the Add to Favorites use case. + */ +public class AddToFavInputData { + private final String username; + private final String jokeId; + + /** + * Constructs an AddToFavInputData with the specified username and joke ID. + * + * @param username the username of the user + * @param jokeId the ID of the joke to add to favorites + */ + public AddToFavInputData(String username, String jokeId) { + this.username = username; + this.jokeId = jokeId; + } + + /** + * Gets the username of the user. + * + * @return the username of the user + */ + public String getUsername() { + return username; + } + + /** + * Gets the ID of the joke. + * + * @return the joke ID + */ + public String getJokeId() { + return jokeId; + } +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavInteractor.java b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java new file mode 100644 index 000000000..091f112b6 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java @@ -0,0 +1,63 @@ +package use_case.add_to_fav; + +import entity.User; +import entity.Joke; + +/** + * The AddToFavInteractor class implements the business logic for adding jokes + * to a user's favorites list. It communicates with the data access layer to + * retrieve and save data, and uses the output boundary (presenter) to format + * the response. + */ +public class AddToFavInteractor implements AddToFavInputBoundary { + private final AddToFavDataAccessInterface dataAccess; + private final AddToFavOutputBoundary outputBoundary; + + /** + * Constructs an AddToFavInteractor with the specified data access interface + * and output boundary (presenter). + * + * @param dataAccess the interface for accessing user and joke data + * @param outputBoundary the presenter that formats output data + */ + public AddToFavInteractor(AddToFavDataAccessInterface dataAccess, AddToFavOutputBoundary outputBoundary) { + this.dataAccess = dataAccess; + this.outputBoundary = outputBoundary; + } + + /** + * Handles the business logic for adding a joke to a user's favorites list. + * + * @param inputData the input data containing the username and joke ID + * @return a response model indicating the result of the operation + */ + @Override + public AddToFavOutputData addToFavorites(AddToFavInputData inputData) { + // Retrieve the user by username + final User user = dataAccess.getUser(inputData.getUsername()); + if (user == null) { + return outputBoundary.prepareFailResponse("User not found."); + } + + // Retrieve the joke by joke ID + final Joke joke = dataAccess.getJoke(inputData.getJokeId()); + if (joke == null) { + return outputBoundary.prepareFailResponse("Joke not found."); + } + + // Attempt to add the joke to the user's favorites + if (user.addToFavorites()) { + // Save the updated user in the data store + dataAccess.saveUser(user); + + // Prepare a success response + return outputBoundary.prepareSuccessResponse( + new AddToFavOutputData("Joke added to favorites successfully!") + ); + } + else { + // Joke was already in the favorites list + return outputBoundary.prepareFailResponse("Joke is already in the favorites list."); + } + } +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java b/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java new file mode 100644 index 000000000..e6dcf02c1 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java @@ -0,0 +1,23 @@ +package use_case.add_to_fav; + +/** + * The AddToFavOutputBoundary interface defines the output boundary + * for the Add to Favorites use case. + */ +public interface AddToFavOutputBoundary { + /** + * Prepares a successful response for the operation. + * + * @param outputData the data to include in the success response + * @return a formatted response model + */ + AddToFavOutputData prepareSuccessResponse(AddToFavOutputData outputData); + + /** + * Prepares a failure response for the operation. + * + * @param errorMessage the error message to include in the response + * @return a formatted response model + */ + AddToFavOutputData prepareFailResponse(String errorMessage); +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavOutputData.java b/src/main/java/use_case/add_to_fav/AddToFavOutputData.java new file mode 100644 index 000000000..7930b5baa --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavOutputData.java @@ -0,0 +1,26 @@ +package use_case.add_to_fav; + +/** + * Represents the output data for the Add to Favorites use case. + */ +public class AddToFavOutputData { + private final String message; + + /** + * Constructs an AddToFavOutputData with the specified message. + * + * @param message the message describing the result of the operation + */ + public AddToFavOutputData(String message) { + this.message = message; + } + + /** + * Gets the message describing the result of the operation. + * + * @return the result message + */ + public String getMessage() { + return message; + } +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java b/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java new file mode 100644 index 000000000..2089858f1 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java @@ -0,0 +1,29 @@ +package use_case.add_to_fav; + +/** + * The AddToFavRequestModel class represents the input data + * for the Add to Favorites use case. + */ +public class AddToFavRequestModel { + private final String username; + private final String jokeId; + + /** + * Constructs an AddToFavRequestModel with the specified username and joke ID. + * + * @param username the username of the user + * @param jokeId the ID of the joke to add to favorites + */ + public AddToFavRequestModel(String username, String jokeId) { + this.username = username; + this.jokeId = jokeId; + } + + public String getUsername() { + return username; + } + + public String getJokeId() { + return jokeId; + } +} diff --git a/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java b/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java new file mode 100644 index 000000000..db1d699b7 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java @@ -0,0 +1,22 @@ +package use_case.add_to_fav; + +/** + * The AddToFavResponseModel class represents the output data + * for the Add to Favorites use case. + */ +public class AddToFavResponseModel { + private final String message; + + /** + * Constructs an AddToFavResponseModel with the specified message. + * + * @param message the message describing the result of the operation + */ + public AddToFavResponseModel(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java b/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java new file mode 100644 index 000000000..33d12fa03 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java @@ -0,0 +1,44 @@ +package use_case.add_to_fav.adapter; + +import use_case.add_to_fav.AddToFavInputBoundary; +import use_case.add_to_fav.AddToFavInputData; +import use_case.add_to_fav.AddToFavOutputData; +import use_case.add_to_fav.AddToFavResponseModel; + +/** + * The AddToFavController class handles user requests for adding a joke to their favorites. + * It delegates the request to the interactor via the input boundary and returns a response + * to the user interface layer. + */ +public class AddToFavController { + private final AddToFavInputBoundary interactor; + + /** + * Constructs an AddToFavController with the specified input boundary (interactor). + * + * @param interactor the interactor that handles the business logic for adding to favorites + */ + public AddToFavController(AddToFavInputBoundary interactor) { + this.interactor = interactor; + } + + /** + * Adds a joke to the user's list of favorites. + * + * @param username the username of the user + * @param jokeId the ID of the joke to add to favorites + * @return a response model containing the result of the operation + */ + public AddToFavResponseModel addToFavorites(String username, String jokeId) { + // Create the input data object for the interactor + final AddToFavInputData inputData = new AddToFavInputData(username, jokeId); + + // Pass the input data to the interactor + final AddToFavOutputData outputData = interactor.addToFavorites(inputData); + + // Return the formatted response + return new AddToFavResponseModel(outputData.getMessage()); + } +} + + diff --git a/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java b/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java new file mode 100644 index 000000000..4c33ce530 --- /dev/null +++ b/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java @@ -0,0 +1,35 @@ +package use_case.add_to_fav.adapter; + +import use_case.add_to_fav.AddToFavOutputBoundary; +import use_case.add_to_fav.AddToFavOutputData; + +/** + * The AddToFavPresenter class formats the output of the Add to Favorites use case + * for the view layer. + */ +public class AddToFavPresenter implements AddToFavOutputBoundary { + + /** + * Prepares a success response for the Add to Favorites use case. + * + * @param outputData the output data containing the success message + * @return the formatted output data + */ + @Override + public AddToFavOutputData prepareSuccessResponse(AddToFavOutputData outputData) { + // Simply return the output data for success cases (can format further if needed) + return outputData; + } + + /** + * Prepares a failure response for the Add to Favorites use case. + * + * @param errorMessage the error message describing the failure + * @return the formatted output data with the error message + */ + @Override + public AddToFavOutputData prepareFailResponse(String errorMessage) { + // Return an output data object with the error message + return new AddToFavOutputData(errorMessage); + } +} From dd3af6879b3bdae54b64265ebc0d28d6ec0feefe Mon Sep 17 00:00:00 2001 From: dengxues Date: Mon, 25 Nov 2024 21:00:54 -0500 Subject: [PATCH 43/62] class over 11.24 --- .../FavouriteDataAccessObject.java | 4 +++ .../favourite/FavouriteInputBoundary.java | 2 ++ .../favourite/FavouriteInteractor.java | 30 ++++++++++++++++- .../favourite/FavouriteOutputBoundary.java | 2 ++ .../FavouriteUserDataAccessInterface.java | 3 +- .../favourite/adapter/FavouriteBuilder.java | 24 -------------- .../favourite/adapter/FavouritePresenter.java | 32 +++++++++++++++++-- .../funniest/FunniestDataAccessInterface.java | 7 ++++ .../use_case/funniest/FunniestInteractor.java | 15 ++++----- .../favourite_view}/FavouriteState.java | 9 +++++- .../{ => favourite_view}/FavouriteView.java | 16 +++++----- .../favourite_view}/FavouriteViewModel.java | 4 +-- .../use_case/favourite/DemoFavouriteTest.java | 9 ------ 13 files changed, 99 insertions(+), 58 deletions(-) create mode 100644 src/main/java/data_access/FavouriteDataAccessObject.java delete mode 100644 src/main/java/use_case/favourite/adapter/FavouriteBuilder.java create mode 100644 src/main/java/use_case/funniest/FunniestDataAccessInterface.java rename src/main/java/{use_case/favourite/adapter => view/favourite_view}/FavouriteState.java (74%) rename src/main/java/view/{ => favourite_view}/FavouriteView.java (89%) rename src/main/java/{use_case/favourite/adapter => view/favourite_view}/FavouriteViewModel.java (87%) delete mode 100644 src/test/java/use_case/favourite/DemoFavouriteTest.java diff --git a/src/main/java/data_access/FavouriteDataAccessObject.java b/src/main/java/data_access/FavouriteDataAccessObject.java new file mode 100644 index 000000000..d9a19da49 --- /dev/null +++ b/src/main/java/data_access/FavouriteDataAccessObject.java @@ -0,0 +1,4 @@ +package data_access; + +public class FavouriteDataAccessObject { +} diff --git a/src/main/java/use_case/favourite/FavouriteInputBoundary.java b/src/main/java/use_case/favourite/FavouriteInputBoundary.java index bd26d63ec..962e424f7 100644 --- a/src/main/java/use_case/favourite/FavouriteInputBoundary.java +++ b/src/main/java/use_case/favourite/FavouriteInputBoundary.java @@ -12,4 +12,6 @@ public interface FavouriteInputBoundary { * Executes the switch to login view use case. */ void switchToFavouriteView(); + + void executeFunniest(); } diff --git a/src/main/java/use_case/favourite/FavouriteInteractor.java b/src/main/java/use_case/favourite/FavouriteInteractor.java index ec5b9874f..3a4d84879 100644 --- a/src/main/java/use_case/favourite/FavouriteInteractor.java +++ b/src/main/java/use_case/favourite/FavouriteInteractor.java @@ -1,4 +1,32 @@ package use_case.favourite; -public class FavouriteInteractor { +import entity.Joke; + +import java.util.List; + +/** + * The "Use Case Interactor" for getting user's favourite + */ +public class FavouriteInteractor implements FavouriteInputBoundary { + + private final FavouriteUserDataAccessInterface favouriteUserDataAccessInterface; + private final FavouriteOutputBoundary favouriteOutputBoundary; + + public FavouriteInteractor(FavouriteUserDataAccessInterface favouriteUserDataAccessInterface, FavouriteOutputBoundary favouriteOutputBoundary) { + this.favouriteUserDataAccessInterface = favouriteUserDataAccessInterface; + this.favouriteOutputBoundary = favouriteOutputBoundary; + } + + public void executeFavourite() { + try { + final List jokeList = favouriteUserDataAccessInterface.getFavourite(); + // interactor gets input data and outputs output data + final FavouriteOutputData favouriteOutputData = new FavouriteOutputData(jokeList); + + favouriteOutputBoundary.prepareSuccessView(favouriteOutputData); + } + catch (RuntimeException ex) { + favouriteOutputBoundary.prepareFailView(ex.getMessage()); + } + } } diff --git a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java index 66130662f..0724fa469 100644 --- a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java +++ b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java @@ -12,4 +12,6 @@ public interface FavouriteOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); + + void prepareFailureView(String errormessage); } diff --git a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java index ee6e88503..e2b6bebbb 100644 --- a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java +++ b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java @@ -3,8 +3,7 @@ import java.util.List; import entity.Joke; -import entity.User; public interface FavouriteUserDataAccessInterface { - List getFavouriteUsers(User user); + List getFavourite(); } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java b/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java deleted file mode 100644 index 0cbddba98..000000000 --- a/src/main/java/use_case/favourite/adapter/FavouriteBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -package use_case.favourite.adapter; - -import view.FavouriteView; - -import javax.swing.*; - -public class FavouriteBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - - public static JFrame build() { - - final JFrame frame = new JFrame(); - final FavouriteViewModel viewModel = new FavouriteViewModel(); - final FavouriteController controller = new FavouriteController(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Search"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(new FavouriteView(viewModel, controller)); - - return frame; - } -} diff --git a/src/main/java/use_case/favourite/adapter/FavouritePresenter.java b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java index 3bb4fdc37..0f3685713 100644 --- a/src/main/java/use_case/favourite/adapter/FavouritePresenter.java +++ b/src/main/java/use_case/favourite/adapter/FavouritePresenter.java @@ -1,5 +1,33 @@ package use_case.favourite.adapter; -public class FavouritePresenter { +import use_case.favourite.FavouriteOutputBoundary; +import use_case.favourite.FavouriteOutputData; +import view.favourite_view.FavouriteState; +import view.favourite_view.FavouriteViewModel; -} +public class FavouritePresenter implements FavouriteOutputBoundary { + + private final FavouriteViewModel favouriteViewModel; + + public FavouritePresenter(FavouriteViewModel favouriteViewModel) { + this.favouriteViewModel = favouriteViewModel; + } + + @Override + public void prepareSuccessView(FavouriteOutputData favouriteOutputData) { + final FavouriteState favouriteState = favouriteViewModel.getState(); + favouriteState.setFavourites(favouriteOutputData.getFavouriteJokeList()); + favouriteViewModel.setState(favouriteState); + favouriteViewModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + + } + + @Override + public void prepareFailureView(String errormessage) { + + } +} \ No newline at end of file diff --git a/src/main/java/use_case/funniest/FunniestDataAccessInterface.java b/src/main/java/use_case/funniest/FunniestDataAccessInterface.java new file mode 100644 index 000000000..1c4cee745 --- /dev/null +++ b/src/main/java/use_case/funniest/FunniestDataAccessInterface.java @@ -0,0 +1,7 @@ +package use_case.funniest; + +import entity.Joke; + +public interface FunniestDataAccessInterface { + Joke getFunniestJoke(); +} diff --git a/src/main/java/use_case/funniest/FunniestInteractor.java b/src/main/java/use_case/funniest/FunniestInteractor.java index 76b02b77b..e996cbaac 100644 --- a/src/main/java/use_case/funniest/FunniestInteractor.java +++ b/src/main/java/use_case/funniest/FunniestInteractor.java @@ -1,23 +1,20 @@ package use_case.funniest; -import use_case.explanation.ExplanationInputData; -import use_case.explanation.ExplanationOutputData; +import use_case.favourite.FavouriteInputBoundary; import use_case.favourite.FavouriteOutputBoundary; -public class FunniestInteractor { +public class FunniestInteractor implements FavouriteInputBoundary { + private final FavouriteOutputBoundary favouriteOutputBoundary; public FunniestInteractor(FavouriteOutputBoundary outputBoundary) { this.favouriteOutputBoundary = outputBoundary; } - public void executeFunniest(FavouriteOutputBoundary explanationInputData) { + @Override + public void executeFunniest() { try { - final String explanation = explanationDataAccessObject.getExplanation(explanationInputData.getJokeContent()); - explanationOutputBoundary.prepareSuccessView(new ExplanationOutputData(explanation)); - } - catch (RuntimeException ex) { - explanationOutputBoundary.prepareFailView(ex.getMessage()); + } } } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteState.java b/src/main/java/view/favourite_view/FavouriteState.java similarity index 74% rename from src/main/java/use_case/favourite/adapter/FavouriteState.java rename to src/main/java/view/favourite_view/FavouriteState.java index 9df55c786..26ad82548 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteState.java +++ b/src/main/java/view/favourite_view/FavouriteState.java @@ -1,13 +1,20 @@ -package use_case.favourite.adapter; +package view.favourite_view; import java.util.List; import entity.Joke; +import entity.User; public class FavouriteState { private String keyWord; + private User user; private List favourites; + @Override + public String toString() { + return super.toString(); + } + public List getFavourites() { return favourites; } diff --git a/src/main/java/view/FavouriteView.java b/src/main/java/view/favourite_view/FavouriteView.java similarity index 89% rename from src/main/java/view/FavouriteView.java rename to src/main/java/view/favourite_view/FavouriteView.java index 19ed4922c..d6471ba47 100644 --- a/src/main/java/view/FavouriteView.java +++ b/src/main/java/view/favourite_view/FavouriteView.java @@ -1,18 +1,12 @@ -package view; +package view.favourite_view; -import use_case.favourite.adapter.FavouriteViewModel; import view.helper_functions.LabelTextPanel; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import javax.swing.*; import use_case.favourite.adapter.FavouriteController; -import use_case.favourite.adapter.FavouriteState; public class FavouriteView extends JPanel { @@ -32,7 +26,7 @@ public class FavouriteView extends JPanel { public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController controller) { this.favouriteController = controller; this.favouriteViewModel = favouriteViewModel; -// this.favouriteViewModel.addPropertyChangeListener(this); + this.favouriteViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel(FavouriteViewModel.TITLE_LABEL); title.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -51,6 +45,12 @@ public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController this.add(search); this.add(buttons); + final JPanel jokeListPanel = new JPanel(); + + final JFrame mainPanel = new JFrame(viewName); + mainPanel.add(buttons, BorderLayout.NORTH); + mainPanel.add(jokeListPanel, BorderLayout.SOUTH); + // funniestButton.addActionListener( // evt -> { // if (evt.getSource().equals(funniestButton)) { diff --git a/src/main/java/use_case/favourite/adapter/FavouriteViewModel.java b/src/main/java/view/favourite_view/FavouriteViewModel.java similarity index 87% rename from src/main/java/use_case/favourite/adapter/FavouriteViewModel.java rename to src/main/java/view/favourite_view/FavouriteViewModel.java index 13bf01d57..97631706c 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteViewModel.java +++ b/src/main/java/view/favourite_view/FavouriteViewModel.java @@ -1,4 +1,4 @@ -package use_case.favourite.adapter; +package view.favourite_view; import view.ViewModel; @@ -11,7 +11,7 @@ public class FavouriteViewModel extends ViewModel { public static final String FUNNIEST_BUTTOM_LABEL = "funniest"; public static final String CANCEL_BUTTOM_LABEL = "cancel"; - public FavouriteViewModel(){ + public FavouriteViewModel() { super("Favourite"); setState(new FavouriteState()); } diff --git a/src/test/java/use_case/favourite/DemoFavouriteTest.java b/src/test/java/use_case/favourite/DemoFavouriteTest.java deleted file mode 100644 index a5dbd69d1..000000000 --- a/src/test/java/use_case/favourite/DemoFavouriteTest.java +++ /dev/null @@ -1,9 +0,0 @@ -package use_case.favourite; - -import use_case.favourite.adapter.FavouriteBuilder; - -public class DemoFavouriteTest { - public static void main(String[] args) { - FavouriteBuilder.build().setVisible(true); - } -} From c56ecad9fcdafca19748023f24e1e1e5a52d6770 Mon Sep 17 00:00:00 2001 From: five Date: Wed, 27 Nov 2024 16:31:09 -0500 Subject: [PATCH 44/62] Complete FileDataAccessObject --- .../data_access/FileDataAccessObject.java | 108 +++++++++++++++++- src/main/java/entity/UserFactory.java | 4 +- .../signup/adapter/SignupController.java | 3 +- src/main/resources/Users.json | 3 + 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/Users.json diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index 50b931a84..5fe602b67 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -1,4 +1,110 @@ package data_access; -public class FileDataAccessObject { +import java.io.*; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; + +import org.json.JSONArray; +import org.json.JSONObject; + +import entity.Joke; +import entity.JokeFactory; +import entity.User; +import entity.UserFactory; +import use_case.signup.SignupUserDataAccessInterface; + +/** + * DAO for user data implemented using a File to persist the data. + */ +public class FileDataAccessObject implements SignupUserDataAccessInterface { + + private File jsonFile; + private List users = new ArrayList<>(); + private UserFactory userFactory = new UserFactory(); + private JokeFactory jokeFactory = new JokeFactory(); + + /** + * Constructs a Data Access Object populated using data from the specified resources file. + * @param filename the name of the file in resources to load the data from + * @throws RuntimeException if the resource file can't be loaded properly + */ + public FileDataAccessObject(String filename) { + // read the file to get the data to populate things... + try { + + final String jsonString = Files.readString( + Paths.get(getClass().getClassLoader().getResource(filename).toURI())); + + final JSONArray jsonArray = new JSONArray(jsonString); + + // this for loop makes the instance variables what's said in comments + for (int i = 0; i < jsonArray.length(); i++) { + final JSONObject jsonObject = jsonArray.getJSONObject(i); + final String username = jsonObject.getString("username"); + final String password = jsonObject.getString("password"); + final JSONArray favorites = jsonObject.getJSONArray("favorites"); + final List jokeList = new ArrayList<>(); + for (int j = 0; j < favorites.length(); j++) { + final JSONObject jokeObject = favorites.getJSONObject(j); + final String jokeContent = jokeObject.getString("content"); + final String jokeExplanation = jokeObject.getString("explanation"); + final int jokeScore = jokeObject.getInt("score"); + final Joke joke = jokeFactory.create(jokeContent, jokeScore); + joke.setExplanation(jokeExplanation); + jokeList.add(joke); + } + final User user = userFactory.create(username, password, jokeList); + users.add(user); + } + + } + catch (IOException | URISyntaxException ex) { + throw new RuntimeException(ex); + } + } + + private void save() { + final JSONArray jsonArray = new JSONArray(); + + // Convert each user into a JSONObject and add to the JSONArray + for (User user : users) { + final JSONObject jsonObject = new JSONObject(); + jsonObject.put("Username", user.getName()); + jsonObject.put("Password", user.getPassword()); + jsonObject.put("favorites", user.getFavorites()); + jsonArray.put(jsonObject); + } + + // Write the JSON array to the file + try (FileWriter fileWriter = new FileWriter("Users.json")) { + fileWriter.write(jsonArray.toString()); + System.out.println("Users saved successfully to " + "Users.json"); + } + catch (IOException ex) { + System.err.println("Error saving users: " + ex.getMessage()); + } + } + + @Override + public boolean existsByName(String username) { + return false; + } + + @Override + public void save(User user) { + users.add(user); + this.save(); + } + + public User get(String username) { + for (int i = 0; i < users.size(); i++) { + final User currentuser = users.get(i); + if (currentuser.getName().equals(username)) { + return currentuser; + } + } + return null; + } } diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java index e8fcdb71e..a80963cee 100644 --- a/src/main/java/entity/UserFactory.java +++ b/src/main/java/entity/UserFactory.java @@ -14,11 +14,11 @@ public class UserFactory { * @param favorites the list of user's favourite joke(s) * @return the new user */ - User create(String name, String password, List favorites) { + public User create(String name, String password, List favorites) { return new User(name, password, favorites); } - User create(String name, String password) { + public User create(String name, String password) { return new User(name, password); } diff --git a/src/main/java/use_case/signup/adapter/SignupController.java b/src/main/java/use_case/signup/adapter/SignupController.java index d5dd0b882..894a67f5e 100644 --- a/src/main/java/use_case/signup/adapter/SignupController.java +++ b/src/main/java/use_case/signup/adapter/SignupController.java @@ -33,8 +33,7 @@ public void execute(String username, String password1, String password2) { public void switchToLoginView() { userSignupUseCaseInteractor.switchToLoginView(); } - // TODO Task: add a switchtoSearchView for controller, presenter - // TODO Task: add a file data access object for users. + public void switchtoSearchView() { userSignupUseCaseInteractor.switchToSearchView(); } diff --git a/src/main/resources/Users.json b/src/main/resources/Users.json new file mode 100644 index 000000000..395fb2f11 --- /dev/null +++ b/src/main/resources/Users.json @@ -0,0 +1,3 @@ +[{"Username": "Mika", "Password": "12345678", + "favorites": [{"content": "123", "explanation": "456", "score": 0}, + {"content": "789", "explanation": "101112", "score": 1}]}] \ No newline at end of file From e7c84b1bdd2cac649f1a513d5c0ede19245dbeaa Mon Sep 17 00:00:00 2001 From: five Date: Thu, 28 Nov 2024 18:58:09 -0500 Subject: [PATCH 45/62] Complete Logout and Signup Use case --- .../data_access/FileDataAccessObject.java | 25 ++++++++++++++----- .../java/use_case/logout/LogoutInputData.java | 3 ++- .../use_case/logout/LogoutInteractor.java | 13 +++++++--- .../use_case/signup/SignupInteractor.java | 8 +++--- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index 5fe602b67..c8495122e 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -13,17 +13,20 @@ import entity.JokeFactory; import entity.User; import entity.UserFactory; +import use_case.logout.LogoutUserDataAccessInterface; import use_case.signup.SignupUserDataAccessInterface; /** * DAO for user data implemented using a File to persist the data. */ -public class FileDataAccessObject implements SignupUserDataAccessInterface { +public class FileDataAccessObject implements SignupUserDataAccessInterface, + LogoutUserDataAccessInterface { private File jsonFile; private List users = new ArrayList<>(); private UserFactory userFactory = new UserFactory(); private JokeFactory jokeFactory = new JokeFactory(); + private String currentUserName; /** * Constructs a Data Access Object populated using data from the specified resources file. @@ -87,11 +90,6 @@ private void save() { } } - @Override - public boolean existsByName(String username) { - return false; - } - @Override public void save(User user) { users.add(user); @@ -107,4 +105,19 @@ public User get(String username) { } return null; } + + @Override + public boolean existsByName(String username) { + return false; + } + + @Override + public String getCurrentUsername() { + return this.currentUserName; + } + + @Override + public void setCurrentUsername(String username) { + this.currentUserName = username; + } } diff --git a/src/main/java/use_case/logout/LogoutInputData.java b/src/main/java/use_case/logout/LogoutInputData.java index 917fc0767..660e855fe 100644 --- a/src/main/java/use_case/logout/LogoutInputData.java +++ b/src/main/java/use_case/logout/LogoutInputData.java @@ -11,6 +11,7 @@ public LogoutInputData(String username) { this.username = username; } - String getUsername() {return username; } + String getUsername() { + return username; } } diff --git a/src/main/java/use_case/logout/LogoutInteractor.java b/src/main/java/use_case/logout/LogoutInteractor.java index 90ca7f559..9a468dd11 100644 --- a/src/main/java/use_case/logout/LogoutInteractor.java +++ b/src/main/java/use_case/logout/LogoutInteractor.java @@ -1,22 +1,27 @@ package use_case.logout; +import data_access.FileDataAccessObject; +import entity.User; + /** * The Logout Interactor. */ public class LogoutInteractor implements LogoutInputBoundary { - private LogoutUserDataAccessInterface userDataAccessObject; + private FileDataAccessObject fileDataAccessObject; private LogoutOutputBoundary logoutPresenter; - public LogoutInteractor(LogoutUserDataAccessInterface userDataAccessInterface, + public LogoutInteractor(FileDataAccessObject userDataAccessInterface, LogoutOutputBoundary logoutOutputBoundary) { - this.userDataAccessObject = userDataAccessInterface; + this.fileDataAccessObject = userDataAccessInterface; this.logoutPresenter = logoutOutputBoundary; } @Override public void execute(LogoutInputData logoutInputData) { final String username = logoutInputData.getUsername(); - userDataAccessObject.setCurrentUsername(null); + final User currentUser = fileDataAccessObject.get(username); + fileDataAccessObject.save(currentUser); + fileDataAccessObject.setCurrentUsername(null); final LogoutOutputData logoutOutputData = new LogoutOutputData(username, false); logoutPresenter.prepareSuccessView(logoutOutputData); } diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java index 31f7a41a6..9b0e57715 100644 --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -7,21 +7,21 @@ * The Signup Interactor. */ public class SignupInteractor implements SignupInputBoundary { - private final SignupUserDataAccessInterface userDataAccessObject; + private final SignupUserDataAccessInterface fileDataAccessObject; private final SignupOutputBoundary userPresenter; private final UserFactory userFactory; public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, SignupOutputBoundary signupOutputBoundary, UserFactory userFactory) { - this.userDataAccessObject = signupDataAccessInterface; + this.fileDataAccessObject = signupDataAccessInterface; this.userPresenter = signupOutputBoundary; this.userFactory = userFactory; } @Override public void execute(SignupInputData signupInputData) { - if (userDataAccessObject.existsByName(signupInputData.getUsername())) { + if (fileDataAccessObject.existsByName(signupInputData.getUsername())) { userPresenter.prepareFailView("User already exists."); } else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword())) { @@ -29,7 +29,7 @@ else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword } else { final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); - userDataAccessObject.save(user); + fileDataAccessObject.save(user); final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); userPresenter.prepareSuccessView(signupOutputData); From 2d23ee48fd994f1b444f1a37b3446d29409ed7e0 Mon Sep 17 00:00:00 2001 From: cheryl Date: Fri, 29 Nov 2024 17:06:38 -0500 Subject: [PATCH 46/62] Readme updated. --- README.md | 86 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 5eb93025a..3dccf5aac 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,11 @@ ## Table of Contents * Software Specification -* Features -* User Stories -* Entities -* Proposed API -* Setup and Installation -* Usage -* Contributing +* Features +* Installation Instructions +* Usage * License -* Contact +* Feedback and Contributions ## Software Specification Joke Machine is a joke generation and explanation platform that allows users to generate, search for, save, and understand jokes. Users can generate or search up jokes, ask for explanations, and sort their list of favorite jokes based on rating of the jokes. Joke Machine integrates with external APIs for joke generation and explanation to provide rich and diverse humor content. @@ -31,34 +27,32 @@ Joke Machine is a joke generation and explanation platform that allows users to Search for jokes within saved list of jokes Filter jokes by rating to find the "funniest" jokes. -## User Stories -* Bob generates a joke. He then keeps generating new jokes with different specifications until he is tired. -* Bob was told a joke but he doesn't understand it. He runs the joke explanation program and the program explains to him what is funny about the joke. -* Bob finds some jokes funny and saves them as favorite. He later wants to revisit the jokes that were favorited, so he revisits his list of saved jokes. -* Bob remembers a joke vaguely, he only remembers that it was about 911. He searches “911” and a few different jokes pop up. -* Bob wants to find a specific saved joke, he doesn’t remember what the joke said but he remembers the explanation. He then goes into his list of saved jokes and searches by keywords in the explanation. -* Bob wants to find some really funny jokes. He presses the “Funniest” button in the saved view, then the program returns the joke with the highest score. - -## Entities -### User - Attributes: - name: User's name for login. - password: User’s password. - favorite: A list of saved jokes marked as favorites. -### Joke - Attributes: - content: The joke text. - explanation: The joke's explanation or humorous insight. - score: Humor rating to indicate how funny the joke is. - -## Proposed API -* Google Gemini: Used for natural language understanding and generation. Assists in explaining user-provided jokes. -* JokeAPI: Used for joke retrieval and generation, allowing for a diverse and randomized joke collection. - ## Setup and Installation -* Clone the Repository -* Install Dependencies: -* Run the Application: +* Before setting up the project, make sure you have the correct software installed。 + 1. Java Development Kit (JDK) version 11 or higher: + 2. https://www.oracle.com/java/technologies/javase-downloads.html + 2. IntelliJ IDEA Community or Ultimate Edition: + 3. https://www.jetbrains.com/idea/download/ + + +* Once you have the software setup: + 1. Clone the repository: + 2. "https://github.com/GuoYuHeJason/CSC207GroupProject.git" + + 2. Open the Project in IntelliJ: + 3. Launch IntelliJ IDEA. + 4. Go to file and click New --> Project From Version Control. + 5. Paste the clone and open project. + + 5. Install Dependencies: + 6. Ensure that your project dependencies are configured in a build.gradle or pom.xml file. + 7. If using Maven, IntelliJ will automatically import dependencies defined in pom.xml. + If using Gradle, open the build.gradle file, and IntelliJ will synchronize the dependencies. + + 6. Run the Application: + 6. Locate the Main class (or equivalent entry point) in your project. + 7. Right-click on the file and select Run 'Main'. + ## Usage ### Generating Jokes @@ -72,3 +66,25 @@ Joke Machine is a joke generation and explanation platform that allows users to ### Searching and Filtering * Keyword Search: Enter a keyword (e.g., "911") to find jokes related to that theme. * Funniest Jokes: Use the "Funniest" filter to sort saved jokes by their humor rating. + +## License +This project is released under the Creative Commons CC0 1.0 Universal (CC0) Public Domain Dedication. See LICENSE for details. + +## Feedback and Contributions +Contributing to the Project: +1. Fork the Repository: + * Click the "Fork" button on the top right of the repository page to create a copy of the project under your GitHub account. +2. Clone the Repository: + * "git clone https://github.com/your-username/joke-machine.git" +3. Create a New Branch: + 4. "git checkout -b feature/new-feature" +4. Make Your Changes: + 5. add or change features +5. Submit a Pull Request: + 6. Commit and push your changes to your fork and open a pull request in the main repository. + 7. provide a description of your changes explaining why they are valuable. + +We appreciate you for engaging with our Joke Machine! + + + From 15062535bd7a9001536e85bff22adc8956a90118 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sat, 30 Nov 2024 00:27:02 -0500 Subject: [PATCH 47/62] login files --- .../login/LoginController.java | 28 ++++++++++++ .../login/LoginPresenter.java | 45 +++++++++++++++++++ .../interface_adapter/login/LoginState.java | 4 ++ .../login/LoginViewModel.java | 4 ++ .../use_case/login/LoginInputBoundary.java | 13 ++++++ .../java/use_case/login/LoginInputData.java | 24 ++++++++++ .../java/use_case/login/LoginInteractor.java | 40 +++++++++++++++++ .../use_case/login/LoginOutputBoundary.java | 18 ++++++++ .../java/use_case/login/LoginOutputData.java | 20 +++++++++ .../login/LoginUserDataAccessInterface.java | 41 +++++++++++++++++ 10 files changed, 237 insertions(+) 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/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 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..9fed78261 --- /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.joke.MainState; +import interface_adapter.joke.JokeViewModel; +import interface_adapter.joke.MainViewModel; +import use_case.joke.JokeOutputBoundary; +import use_case.joke.JokeOutputData; +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginOutputData; + +/** + * The Presenter for the Joke Use Case. + */ +public class LoginPresenter implements LoginOutputBoundary { + + private final MainViewModel mainViewModel; + private final ViewManagerModel viewManagerModel; + private final LoginViewModel loginViewModel; + + public LoginPresenter(ViewManagerModel viewManagerModel, MainViewModel mainViewModel, + LoginViewModel loginViewModel) { + this.viewManagerModel = viewManagerModel; + this.mainViewModel = mainViewModel; + } + + @Override + public void prepareSuccessView(LoginOutputData response) { + MainState mainState = mainViewModel.getState(); + mainState.setJokeText(response.getJokeText()); + mainViewModel.setState(jokeState); + mainViewModel.firePropertyChanged(); + + viewManagerModel.setState(mainViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + MainState mainState = mainViewModel.getState(); + jokeState.setErrorMessage(error); + mainViewModel.setState(jokeState); + mainViewModel.firePropertyChanged("error"); + } +} 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..4b5e28fc7 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginState.java @@ -0,0 +1,4 @@ +package interface_adapter.login; + +public class LoginState { +} 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..a93900bee --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.login; + +public class LoginViewModel { +} 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..5b36ddcd8 --- /dev/null +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -0,0 +1,40 @@ +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.setCurrentUsername(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..681e8a52e --- /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); + + /** + * Returns the username of the curren user of the application. + * @return the username of the current user; null indicates that no one is logged into the application. + */ + String getCurrentUsername(); + + /** + * Sets the username indicating who is the current user of the application. + * @param username the new current username; null to indicate that no one is currently logged into the application. + */ + void setCurrentUsername(String username); +} From f1a4fc01675759eae70453a64088ea100ccb567f Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sat, 30 Nov 2024 00:40:02 -0500 Subject: [PATCH 48/62] searchfavourites update --- .../SearchFavouritesDataAccessInterface.java | 13 ++++++ .../SearchFavouritesInputBoundary.java | 9 ++-- .../SearchFavouritesInteractor.java | 44 ++++++++++--------- .../SearchFavouritesOutputBoundary.java | 17 ++++--- .../SearchFavouritesOutputData.java | 15 +++++++ .../adapter}/SearchFavouritesController.java | 4 +- .../adapter/SearchFavouritesPresenter.java | 41 +++++++++++++++++ 7 files changed, 111 insertions(+), 32 deletions(-) create mode 100644 src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java create mode 100644 src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java rename src/main/java/{interface_adapter/search_favourites => use_case/search_favourites/adapter}/SearchFavouritesController.java (79%) create mode 100644 src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java b/src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java new file mode 100644 index 000000000..61f2120ea --- /dev/null +++ b/src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java @@ -0,0 +1,13 @@ +package use_case.search_favourites; + +import entity.Joke; + +import java.util.List; + +public interface SearchFavouritesDataAccessInterface { + /** + * Get the user's favourites list. + * @return a list of jokes marked as favourites. + */ + List getFavourites(); +} diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java b/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java index d36b44a50..4683ab531 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java +++ b/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java @@ -1,8 +1,9 @@ package use_case.search_favourites; -/** - * Input boundary for the Search Favourites use case. - */ public interface SearchFavouritesInputBoundary { - void searchFavourites(String query); + /** + * Search for jokes in the user's favourites. + * @param keyword the keyword to search for. + */ + void executeSearch(String keyword); } diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java index b24a4110e..f5502b7d6 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java +++ b/src/main/java/use_case/search_favourites/SearchFavouritesInteractor.java @@ -1,39 +1,41 @@ package use_case.search_favourites; -import data_access.JokeDataAccessObject; import entity.Joke; import java.util.List; import java.util.stream.Collectors; public class SearchFavouritesInteractor implements SearchFavouritesInputBoundary { + private final SearchFavouritesDataAccessInterface dataAccess; + private final SearchFavouritesOutputBoundary presenter; - private final JokeDataAccessObject jokeDataAccessObject; - private final SearchFavouritesOutputBoundary outputBoundary; - - public SearchFavouritesInteractor(JokeDataAccessObject jokeDataAccessObject, - SearchFavouritesOutputBoundary outputBoundary) { - this.jokeDataAccessObject = jokeDataAccessObject; - this.outputBoundary = outputBoundary; + public SearchFavouritesInteractor(SearchFavouritesDataAccessInterface dataAccess, + SearchFavouritesOutputBoundary presenter) { + this.dataAccess = dataAccess; + this.presenter = presenter; } @Override - public void searchFavourites(String keyword) { + public void executeSearch(String keyword) { try { - List favourites = jokeDataAccessObject.getFavorites(); - List matchingFavourites = favourites.stream() - .filter(joke -> joke.getText().toLowerCase().contains(keyword.toLowerCase())) + final List favourites = dataAccess.getFavourites(); + final List matchingJokes = favourites.stream() + .filter(joke -> joke.getContent().toLowerCase().contains(keyword.toLowerCase())) .collect(Collectors.toList()); - if (matchingFavourites.isEmpty()) { - outputBoundary.presentFavouritesSearchResult("No matching jokes found in favourites."); - } else { - String result = matchingFavourites.stream() - .map(Joke::getText) - .collect(Collectors.joining("\n")); - outputBoundary.presentFavouritesSearchResult(result); + + if (matchingJokes.isEmpty()) { + presenter.presentFailure("No matching jokes found in favourites."); } - } catch (Exception e) { - outputBoundary.presentFavouritesSearchError("An error occurred while searching favourites."); + else { + final Joke selectedJoke = matchingJokes.get(0); + final SearchFavouritesOutputData outputData = new SearchFavouritesOutputData( + selectedJoke.getContent() + ); + presenter.prepareSuccessView(outputData); + } + } catch (RuntimeException e) { + presenter.presentFailure("Error searching favourites: " + e.getMessage()); } } + } diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java b/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java index 8969a439a..e672f370c 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java +++ b/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java @@ -1,9 +1,16 @@ package use_case.search_favourites; -/** - * Output boundary for the Search Favourites use case. - */ public interface SearchFavouritesOutputBoundary { - void presentFavouritesSearchResult(String result); - void presentFavouritesSearchError(String error); + + /** + * Prepares the view for successful search results. + * @param searchFavouritesOutputData the output data containing the joke content. + */ + void prepareSuccessView(SearchFavouritesOutputData searchFavouritesOutputData); + + /** + * Presents an error message if the search fails. + * @param message the error message. + */ + void presentFailure(String message); } diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java b/src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java new file mode 100644 index 000000000..c813c7613 --- /dev/null +++ b/src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java @@ -0,0 +1,15 @@ +package use_case.search_favourites; + +public class SearchFavouritesOutputData { + + private final String jokeContent; + + public SearchFavouritesOutputData(String jokeContent) { + + this.jokeContent = jokeContent; + } + + public String getJokeContent() { + return jokeContent; + } +} diff --git a/src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java b/src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java similarity index 79% rename from src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java rename to src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java index e2067102f..2704f26a3 100644 --- a/src/main/java/interface_adapter/search_favourites/SearchFavouritesController.java +++ b/src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java @@ -1,4 +1,4 @@ -package interface_adapter.search_favourites; +package use_case.search_favourites.adapter; import use_case.search_favourites.SearchFavouritesInputBoundary; @@ -11,6 +11,6 @@ public SearchFavouritesController(SearchFavouritesInputBoundary interactor) { } public void executeSearch(String keyword) { - interactor.searchFavourites(keyword); + interactor.executeSearch(keyword); } } diff --git a/src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java b/src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java new file mode 100644 index 000000000..dbfc0688a --- /dev/null +++ b/src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java @@ -0,0 +1,41 @@ +package use_case.search_favourites.adapter; + +import use_case.search_favourites.SearchFavouritesOutputBoundary; +import use_case.search_favourites.SearchFavouritesOutputData; +import view.FavouriteView; +import view.joke_view.JokeFrameBuilder; + +import javax.swing.*; + +/** + Search favourites presenter. + */ + +public class SearchFavouritesPresenter implements SearchFavouritesOutputBoundary { + + private final FavouriteView favouriteView; + private final JokeFrameBuilder jokeFrameBuilder; + + public SearchFavouritesPresenter(FavouriteView favouriteView, JokeFrameBuilder jokeFrameBuilder) { + this.favouriteView = favouriteView; + this.jokeFrameBuilder = jokeFrameBuilder; + } + + @Override + public void prepareSuccessView(SearchFavouritesOutputData searchFavouritesOutputData) { + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(searchFavouritesOutputData.getJokeContent()) + .addExplanationUseCase() + .addAddToFavUseCase() + .build(); + + frame.pack(); + frame.setVisible(true); + } + + @Override + public void presentFailure(String message) { + + } +} From b1a1e6e6d13c20c8fc20b0d4508239214ca5dd1a Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Sat, 30 Nov 2024 12:39:34 -0500 Subject: [PATCH 49/62] AppBuilder and Main --- src/main/java/app/AppBuilder.java | 299 ++++++++++++++++++++++++++++ src/main/java/app/Main.java | 33 +++ src/main/java/view/ViewManager.java | 33 +++ 3 files changed, 365 insertions(+) create mode 100644 src/main/java/app/AppBuilder.java create mode 100644 src/main/java/app/Main.java create mode 100644 src/main/java/view/ViewManager.java diff --git a/src/main/java/app/AppBuilder.java b/src/main/java/app/AppBuilder.java new file mode 100644 index 000000000..7a1702897 --- /dev/null +++ b/src/main/java/app/AppBuilder.java @@ -0,0 +1,299 @@ +package app; + +import data_access.FileDataAccessObject; +import data_access.JokeDataAccessObject; +import data_access.SearchDataAccessObject; +import entity.UserFactory; +import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginController; +import interface_adapter.login.LoginPresenter; +import interface_adapter.login.LoginViewModel; +import use_case.fav_search.*; +import use_case.favourite.FavouriteInputBoundary; +import use_case.favourite.FavouriteInteractor; +import use_case.favourite.FavouriteOutputBoundary; +import use_case.favourite.adapter.FavouriteController; +import use_case.favourite.adapter.FavouritePresenter; +import use_case.funniest.FunniestInputBoundary; +import use_case.funniest.FunniestInteractor; +import use_case.funniest.FunniestOutputBoundary; +import use_case.generate.GenerateInputBoundary; +import use_case.generate.GenerateInteractor; +import use_case.generate.GenerateOuputBoundary; +import use_case.generate.adapter.GenerateController; +import use_case.generate.adapter.GeneratePresenter; +import use_case.login.LoginInputBoundary; +import use_case.login.LoginInteractor; +import use_case.login.LoginOutputBoundary; +import use_case.logout.LogoutInputBoundary; +import use_case.logout.LogoutInteractor; +import use_case.logout.LogoutOutputBoundary; +import use_case.logout.adapter.LogoutController; +import use_case.logout.adapter.LogoutPresenter; +import use_case.search.SearchDataAccessInterface; +import use_case.search.SearchInputBoundary; +import use_case.search.SearchInteractor; +import use_case.search.SearchOutputBoundary; +import use_case.search.adapter.SearchController; +import use_case.search.adapter.SearchPresenter; +import use_case.search.adapter.SearchViewModel; +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInteractor; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.adapter.SignupController; +import use_case.signup.adapter.SignupPresenter; +import use_case.signup.adapter.SignupViewModel; +import view.LoggedInView; +import view.LoginView; +import view.SearchView; +import view.SignupView; +import view.ViewManager; +import view.favourite_view.FavouriteView; +import view.favourite_view.FavouriteViewModel; +import view.joke_view.JokeFrameBuilder; +import view.main.MainView; +import view.main.MainViewModel; + +import javax.swing.*; +import java.awt.*; + +/** + * The AppBuilder class is responsible for putting together the pieces of + * our CA architecture; piece by piece. + *

+ * This is done by adding each View and then adding related Use Cases. + */ +// Checkstyle note: you can ignore the "Class Data Abstraction Coupling" +// and the "Class Fan-Out Complexity" issues for this lab; we encourage +// your team to think about ways to refactor the code to resolve these +// if your team decides to work with this as your starter code +// for your final project this term. +public class AppBuilder { + private final JPanel cardPanel = new JPanel(); + private final CardLayout cardLayout = new CardLayout(); + // thought question: is the hard dependency below a problem? + private final UserFactory userFactory = new UserFactory(); + private final ViewManagerModel viewManagerModel = new ViewManagerModel(); + private final ViewManager viewManager = new ViewManager(cardPanel, cardLayout, viewManagerModel); + + // thought question: is the hard dependency below a problem? + private final FileDataAccessObject userDataAccessObject = new FileDataAccessObject("src/main/resources/Users.json"); + private final JokeDataAccessObject jokeDataAccessObject = new JokeDataAccessObject(); + private final JokeFrameBuilder jokeFrameBuilder = new JokeFrameBuilder(); + + private SignupView signupView; + private SignupViewModel signupViewModel; + private LoginView loginView; + private LoginViewModel loginViewModel; + private MainView mainView; + private MainViewModel mainViewModel; + private SearchView searchView; + private SearchViewModel searchViewModel; + private FavouriteView favouriteView; + private FavouriteViewModel favouriteViewModel; + + public AppBuilder() { + cardPanel.setLayout(cardLayout); + } + + /** + * Adds the Signup View to the application. + * @return this builder + */ + public AppBuilder addSignupView() { + signupViewModel = new SignupViewModel(); + signupView = new SignupView(signupViewModel); + cardPanel.add(signupView, signupView.getViewName()); + return this; + } + + /** + * Adds the Login View to the application. + * @return this builder + */ + public AppBuilder addLoginView() { + loginViewModel = new LoginViewModel(); + loginView = new LoginView(loginViewModel); + cardPanel.add(loginView, loginView.getViewName()); + return this; + } + + /** + * Adds the LoggedIn View to the application. + * @return this builder + */ + public AppBuilder addMainView() { + mainViewModel = new MainViewModel(); + mainView = new MainView(mainViewModel); + cardPanel.add(mainView, mainView.getViewName()); + return this; + } + + /** + * Adds the LoggedIn View to the application. + * @return this builder + */ + public AppBuilder addSearchView() { + searchViewModel = new SearchViewModel(); + searchView = new SearchView(searchViewModel); + cardPanel.add(searchView, searchView.getViewName()); + return this; + } + + public AppBuilder addFavouriteView() { + favouriteViewModel = new FavouriteViewModel(); + favouriteView = new FavouriteView(favouriteViewModel); + cardPanel.add(favouriteView, favouriteView.getViewName()); + return this; + } + + + /** + * Adds the Signup Use Case to the application. + * @return this builder + */ + public AppBuilder addSignupUseCase() { + final SignupOutputBoundary signupOutputBoundary = new SignupPresenter(viewManagerModel, + signupViewModel, loginViewModel, searchViewModel); + final SignupInputBoundary userSignupInteractor = new SignupInteractor( + userDataAccessObject, signupOutputBoundary, userFactory); + + final SignupController controller = new SignupController(userSignupInteractor); + signupView.setSignupController(controller); + return this; + } + + /** + * Adds the Login Use Case to the application. + * @return this builder + */ + public AppBuilder addLoginUseCase() { + // viewModels Injected to Presenter here. + final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, + mainViewModel, loginViewModel); + final LoginInputBoundary loginInteractor = new LoginInteractor( + userDataAccessObject, loginOutputBoundary); + + final LoginController loginController = new LoginController(loginInteractor); + loginView.setLoginController(loginController); + return this; + } + + /** + * Adds the Change Password Use Case to the application. + * @return this builder + */ + public AppBuilder addSearchUseCase() { + final SearchOutputBoundary searchOutputBoundary = + new SearchPresenter(jokeFrameBuilder); + + final SearchInputBoundary searchInteractor = + new SearchInteractor(jokeDataAccessObject, searchOutputBoundary); + + final SearchController searchController = + new SearchController(searchInteractor); + mainView.setSearchController(searchController); + searchView.setSearchController(searchController); + return this; + } + + /** + * Adds the Change Password Use Case to the application. + * @return this builder + */ + public AppBuilder addFavouriteUseCase() { + final FavouriteOutputBoundary favouriteOutputBoundary = + new FavouritePresenter(favouriteViewModel); + + final FavouriteInputBoundary favouriteInputBoundary = + new FavouriteInteractor(userDataAccessObject, favouriteOutputBoundary); + + final FavouriteController favouriteController = + new FavouriteController(favouriteInputBoundary); + mainView.setFavouriteController(favouriteController); + return this; + } + + /** + * Adds the Change Password Use Case to the application. + * @return this builder + */ + public AppBuilder addFavSearchUseCase() { + final FavSearchOutputBoundary favSearchOutputBoundary = + new FavSearchPresenter(favouriteViewModel, jokeFrameBuilder); + + final FavSearchInputBoundary favSearchInteractor = + new FavSearchInteractor(favSearchOutputBoundary); + + final FavSearchController favSearchController = + new FavSearchController(favSearchInteractor); + favouriteView.setFavSearchController(favSearchController); + return this; + } + + /** + * Adds the Change Password Use Case to the application. + * @return this builder + */ + public AppBuilder addFunniestUseCase() { + final FunniestOutputBoundary funniestOutputBoundary = + new FunniestPresenter(favouriteViewModel); + + final FunniestInputBoundary funniestInputBoundary = + new FunniestInteractor(funniestOutputBoundary); + + final FunniestController funniestController = + new FunniestController(funniestInputBoundary); + favouriteView.setFunniestController(funniestController); + return this; + } + + /** + * Adds the Change Password Use Case to the application. + * @return this builder + */ + public AppBuilder addGenerateUseCase() { + final GenerateOuputBoundary generateOuputBoundary = + new GeneratePresenter(jokeFrameBuilder); + + final GenerateInputBoundary generateInputBoundary = + new GenerateInteractor(jokeDataAccessObject, generateOuputBoundary); + + final GenerateController generateController = + new GenerateController(generateInputBoundary); + mainView.setGenerateController(generateController); + return this; + } + + /** + * Adds the Logout Use Case to the application. + * @return this builder + */ + public AppBuilder addLogoutUseCase() { + final LogoutOutputBoundary logoutOutputBoundary = new LogoutPresenter(viewManagerModel, + mainViewModel, loginViewModel); + + final LogoutInputBoundary logoutInteractor = + new LogoutInteractor(userDataAccessObject, logoutOutputBoundary); + + final LogoutController logoutController = new LogoutController(logoutInteractor); + mainView.setLogoutController(logoutController); + return this; + } + + /** + * Creates the JFrame for the application and initially sets the SignupView to be displayed. + * @return the application + */ + public JFrame build() { + final JFrame application = new JFrame("Joke Machine"); + application.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + application.add(cardPanel); + + viewManagerModel.setState(signupView.getViewName()); + viewManagerModel.firePropertyChanged(); + + return application; + } +} diff --git a/src/main/java/app/Main.java b/src/main/java/app/Main.java new file mode 100644 index 000000000..4fbdf659e --- /dev/null +++ b/src/main/java/app/Main.java @@ -0,0 +1,33 @@ +package app; + +import javax.swing.*; + +/** + * The Main class of our application. + */ +public class Main { + /** + * Builds and runs the CA architecture of the application. + * @param args unused arguments + */ + public static void main(String[] args) { + final AppBuilder appBuilder = new AppBuilder(); + final JFrame application = appBuilder + .addLoginView() + .addSignupView() + .addMainView() + .addFavouriteView() + .addSignupUseCase() + .addLoginUseCase() + .addSearchUseCase() + .addFavouriteUseCase() + .addGenerateUseCase() + .addFunniestUseCase() + .addFavSearchUseCase() + .addLogoutUseCase() + .build(); + + application.pack(); + application.setVisible(true); + } +} diff --git a/src/main/java/view/ViewManager.java b/src/main/java/view/ViewManager.java new file mode 100644 index 000000000..0b3a63ae9 --- /dev/null +++ b/src/main/java/view/ViewManager.java @@ -0,0 +1,33 @@ +package view; + +import interface_adapter.ViewManagerModel; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The View Manager for the program. It listens for property change events + * in the ViewManagerModel and updates which View should be visible. + */ +public class ViewManager implements PropertyChangeListener { + private final CardLayout cardLayout; + private final JPanel views; + private final ViewManagerModel viewManagerModel; + + public ViewManager(JPanel views, CardLayout cardLayout, ViewManagerModel viewManagerModel) { + this.views = views; + this.cardLayout = cardLayout; + this.viewManagerModel = viewManagerModel; + this.viewManagerModel.addPropertyChangeListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("state")) { + final String viewModelName = (String) evt.getNewValue(); + cardLayout.show(views, viewModelName); + } + } +} From 976c1035f110649dee2011b8aae974391dd23179 Mon Sep 17 00:00:00 2001 From: cheryl Date: Sat, 30 Nov 2024 14:09:27 -0500 Subject: [PATCH 50/62] Readme updated. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3dccf5aac..8685db9ae 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,10 @@ Contributing to the Project: 3. Create a New Branch: 4. "git checkout -b feature/new-feature" 4. Make Your Changes: - 5. add or change features + 5. Add or change features 5. Submit a Pull Request: 6. Commit and push your changes to your fork and open a pull request in the main repository. - 7. provide a description of your changes explaining why they are valuable. + 7. Provide a description of your changes explaining why they are valuable. We appreciate you for engaging with our Joke Machine! From 22bac7f3e0a052faf3d251840dda1e35bee981a0 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Sat, 30 Nov 2024 16:10:43 -0500 Subject: [PATCH 51/62] Update ff --- .../java/view/joke_view/JokeFrameBuilder.java | 18 ++++++-- src/main/java/view/joke_view/JokeState.java | 42 +++++++++++++++++++ src/main/java/view/joke_view/JokeView.java | 14 ++++--- .../java/view/joke_view/JokeViewModel.java | 18 ++++++++ 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/main/java/view/joke_view/JokeState.java create mode 100644 src/main/java/view/joke_view/JokeViewModel.java diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java index 0ad00c8e7..58fabca6f 100644 --- a/src/main/java/view/joke_view/JokeFrameBuilder.java +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -1,7 +1,14 @@ package view.joke_view; import data_access.ExplanationDataAccessObject; +import data_access.FileDataAccessObject; import data_access.MockExplanationDataAccessObject; +import use_case.add_to_fav.AddToFavDataAccessInterface; +import use_case.add_to_fav.AddToFavInputBoundary; +import use_case.add_to_fav.AddToFavInteractor; +import use_case.add_to_fav.AddToFavOutputBoundary; +import use_case.add_to_fav.adapter.AddToFavController; +import use_case.add_to_fav.adapter.AddToFavPresenter; import use_case.explanation.*; import use_case.explanation.adapter.ExplanationController; import use_case.explanation.adapter.ExplanationPresenter; @@ -20,6 +27,7 @@ public class JokeFrameBuilder { //TODO change mock private final ExplanationDataAccessInterface explanationDataAccessObject = new MockExplanationDataAccessObject(); + private AddToFavDataAccessInterface addToFavDataAccessObject; public JokeFrameBuilder() { } @@ -46,15 +54,19 @@ public JokeFrameBuilder addExplanationUseCase() { return this; } - //TODO do this - public JokeFrameBuilder addAddToFavUseCase() { + public JokeFrameBuilder addAddToFavUseCase(AddToFavDataAccessInterface addToFavDataAccessObject) { + final AddToFavOutputBoundary addToFavOutputBoundary = new AddToFavPresenter(jokeViewModel); + final AddToFavInputBoundary addToFavInteractor = new AddToFavInteractor( + addToFavDataAccessObject, addToFavOutputBoundary); + + final AddToFavController addToFavController = new AddToFavController(addToFavInteractor); + jokeView.setAddController(addToFavController); return this; } public JFrame build() { final JFrame frame = new JFrame("Joke"); - //TODO may need to change frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.add(jokeView); diff --git a/src/main/java/view/joke_view/JokeState.java b/src/main/java/view/joke_view/JokeState.java new file mode 100644 index 000000000..e72a2298a --- /dev/null +++ b/src/main/java/view/joke_view/JokeState.java @@ -0,0 +1,42 @@ +package view.joke_view; + +import static view.joke_view.JokeViewModel.ADD_BUTTON_LABEL; + +public class JokeState { + // info that can change + private String jokeContent = ""; + private String explanation = ""; + private String addToFav = ADD_BUTTON_LABEL; + + @Override + public String toString() { + return "JokeState{" + + "jokeContent='" + getJokeContent() + '\'' + + ", explanation='" + getExplanation() + '\'' + + '}'; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } + + public String getJokeContent() { + return jokeContent; + } + + public void setJokeContent(String jokeContent) { + this.jokeContent = jokeContent; + } + + public void setAddToFavText(String added) { + this.addToFav = added; + } + + public String getAddToFav(){ + return this.addToFav; + } +} diff --git a/src/main/java/view/joke_view/JokeView.java b/src/main/java/view/joke_view/JokeView.java index 011abcdb7..33bdeb6e9 100644 --- a/src/main/java/view/joke_view/JokeView.java +++ b/src/main/java/view/joke_view/JokeView.java @@ -1,6 +1,6 @@ package view.joke_view; -import use_case.add_to_fav.AddController; +import use_case.add_to_fav.adapter.AddToFavController; import use_case.explanation.adapter.ExplanationController; import java.awt.*; @@ -25,7 +25,7 @@ public class JokeView extends JPanel implements PropertyChangeListener, ActionLi // each function of a controller is a button private final JButton explain; private final JButton addToFav; - private AddController addController; + private AddToFavController addController; private ExplanationController explanationController; public JokeView(JokeViewModel jokeViewModel) { @@ -64,8 +64,7 @@ public JokeView(JokeViewModel jokeViewModel) { //can change depending on how addController is implemented addController.execute( currentState.getJokeContent(), - currentState.getExplanation(), - null); + currentState.getExplanation()); } } ); @@ -140,6 +139,7 @@ public void actionPerformed(ActionEvent evt) { public void propertyChange(PropertyChangeEvent evt) { final JokeState state = (JokeState) evt.getNewValue(); setFields(state); + changeAddToFavText(state); } private void setFields(JokeState state) { @@ -155,7 +155,11 @@ public void setExplanationController(ExplanationController explanationController this.explanationController = explanationController; } - public void setAddController(AddController addController) { + public void setAddController(AddToFavController addController) { this.addController = addController; } + + public void changeAddToFavText(JokeState jokeState) { + addToFav.setText(jokeState.getAddToFav()); + } } diff --git a/src/main/java/view/joke_view/JokeViewModel.java b/src/main/java/view/joke_view/JokeViewModel.java new file mode 100644 index 000000000..24b37f21f --- /dev/null +++ b/src/main/java/view/joke_view/JokeViewModel.java @@ -0,0 +1,18 @@ +package view.joke_view; + +import view.ViewModel; + + +public class JokeViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Joke"; + public static final String EXPLANATION_BUTTON_LABEL = "Explain"; + public static final String ADD_BUTTON_LABEL = "Add to Favorite"; + public static final String EXPLANATION_LABEL = "Explanation"; + + public JokeViewModel() { + super("Joke"); + setState(new JokeState()); + } + // a wrapper for all the info you need to build a view +} From 659d028a5d122f066590df94bc267712dd29ef4d Mon Sep 17 00:00:00 2001 From: five Date: Sat, 30 Nov 2024 16:15:44 -0500 Subject: [PATCH 52/62] A little adjust to File DAO and SearchView --- src/main/java/app/AppBuilder.java | 2 -- src/main/java/data_access/FileDataAccessObject.java | 6 +++++- src/main/java/view/SearchView.java | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/app/AppBuilder.java b/src/main/java/app/AppBuilder.java index 7a1702897..9cff186cd 100644 --- a/src/main/java/app/AppBuilder.java +++ b/src/main/java/app/AppBuilder.java @@ -2,7 +2,6 @@ import data_access.FileDataAccessObject; import data_access.JokeDataAccessObject; -import data_access.SearchDataAccessObject; import entity.UserFactory; import interface_adapter.ViewManagerModel; import interface_adapter.login.LoginController; @@ -30,7 +29,6 @@ import use_case.logout.LogoutOutputBoundary; import use_case.logout.adapter.LogoutController; import use_case.logout.adapter.LogoutPresenter; -import use_case.search.SearchDataAccessInterface; import use_case.search.SearchInputBoundary; import use_case.search.SearchInteractor; import use_case.search.SearchOutputBoundary; diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index c8495122e..ba0c8613b 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -92,6 +92,10 @@ private void save() { @Override public void save(User user) { + if (this.existsByName(user.getName())) { + final User currentUser = this.get(user.getName()); + users.remove(currentUser); + } users.add(user); this.save(); } @@ -108,7 +112,7 @@ public User get(String username) { @Override public boolean existsByName(String username) { - return false; + return this.get(username) != null; } @Override diff --git a/src/main/java/view/SearchView.java b/src/main/java/view/SearchView.java index fc44d15a5..214f6b651 100644 --- a/src/main/java/view/SearchView.java +++ b/src/main/java/view/SearchView.java @@ -75,5 +75,9 @@ public void propertyChange(PropertyChangeEvent evt) { public void setSearchController(SearchController searchController) { this.searchController = searchController; } + + public String getViewName() { + return viewName; + } } From da743b04d0415710da75225cae61dd158a7c3c36 Mon Sep 17 00:00:00 2001 From: cheryl Date: Sat, 30 Nov 2024 16:23:52 -0500 Subject: [PATCH 53/62] add to favorite --- .../addToFavorite/favoriteDataAcessInterface | 0 .../AddToFavDataAccessInterface.java | 15 +++---- .../add_to_fav/AddToFavInputBoundary.java | 2 +- .../add_to_fav/AddToFavInputData.java | 22 +++++----- .../add_to_fav/AddToFavInteractor.java | 36 +++++----------- .../add_to_fav/AddToFavOutputBoundary.java | 17 ++------ .../adapter/AddToFavController.java | 23 +++------- .../add_to_fav/adapter/AddToFavPresenter.java | 37 ++++++++-------- src/main/java/view/joke_view/JokeState.java | 42 +++++++++++++++++++ .../java/view/joke_view/JokeViewModel.java | 18 ++++++++ 10 files changed, 115 insertions(+), 97 deletions(-) delete mode 100644 src/main/java/use_case/addToFavorite/favoriteDataAcessInterface create mode 100644 src/main/java/view/joke_view/JokeState.java create mode 100644 src/main/java/view/joke_view/JokeViewModel.java diff --git a/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface b/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java index 1fb0f19f1..c49091152 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java +++ b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java @@ -1,3 +1,4 @@ + package use_case.add_to_fav; import entity.Joke; @@ -14,20 +15,14 @@ public interface AddToFavDataAccessInterface { * @param username the username of the user * @return the User object, or null if not found */ - User getUser(String username); - - /** - * Retrieves a joke by ID. - * - * @param jokeId the ID of the joke - * @return the Joke object, or null if not found - */ - Joke getJoke(String jokeId); + User get(String username); + String getCurrentUsername(); /** * Saves the updated user to the data storage. * * @param user the User object to save */ + void saveUser(User user); -} +} \ No newline at end of file diff --git a/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java b/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java index 71f8c6e76..e84ce5108 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java +++ b/src/main/java/use_case/add_to_fav/AddToFavInputBoundary.java @@ -11,5 +11,5 @@ public interface AddToFavInputBoundary { * @param inputData the input data containing the username and joke ID * @return a response model indicating the result of the operation */ - AddToFavOutputData addToFavorites(AddToFavInputData inputData); + void executeAddToFav(AddToFavInputData inputData); } diff --git a/src/main/java/use_case/add_to_fav/AddToFavInputData.java b/src/main/java/use_case/add_to_fav/AddToFavInputData.java index 0a65d4c00..c0991620f 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavInputData.java +++ b/src/main/java/use_case/add_to_fav/AddToFavInputData.java @@ -5,18 +5,18 @@ * for the Add to Favorites use case. */ public class AddToFavInputData { - private final String username; - private final String jokeId; + private final String jokeContent; + private final String explanation; /** * Constructs an AddToFavInputData with the specified username and joke ID. * - * @param username the username of the user - * @param jokeId the ID of the joke to add to favorites + * @param jokeContent the username of the user + * @param explanation the ID of the joke to add to favorites */ - public AddToFavInputData(String username, String jokeId) { - this.username = username; - this.jokeId = jokeId; + public AddToFavInputData(String jokeContent, String explanation) { + this.jokeContent = jokeContent; + this.explanation = explanation; } /** @@ -24,8 +24,8 @@ public AddToFavInputData(String username, String jokeId) { * * @return the username of the user */ - public String getUsername() { - return username; + public String getJokeContent() { + return jokeContent; } /** @@ -33,7 +33,7 @@ public String getUsername() { * * @return the joke ID */ - public String getJokeId() { - return jokeId; + public String getExplanation() { + return explanation; } } diff --git a/src/main/java/use_case/add_to_fav/AddToFavInteractor.java b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java index 091f112b6..03725ad00 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavInteractor.java +++ b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java @@ -1,7 +1,8 @@ package use_case.add_to_fav; -import entity.User; import entity.Joke; +import entity.JokeFactory; +import entity.User; /** * The AddToFavInteractor class implements the business logic for adding jokes @@ -29,35 +30,20 @@ public AddToFavInteractor(AddToFavDataAccessInterface dataAccess, AddToFavOutput * Handles the business logic for adding a joke to a user's favorites list. * * @param inputData the input data containing the username and joke ID - * @return a response model indicating the result of the operation */ @Override - public AddToFavOutputData addToFavorites(AddToFavInputData inputData) { - // Retrieve the user by username - final User user = dataAccess.getUser(inputData.getUsername()); + public void executeAddToFav(AddToFavInputData inputData) { + final User user = dataAccess.get(dataAccess.getCurrentUsername()); if (user == null) { - return outputBoundary.prepareFailResponse("User not found."); - } - - // Retrieve the joke by joke ID - final Joke joke = dataAccess.getJoke(inputData.getJokeId()); - if (joke == null) { - return outputBoundary.prepareFailResponse("Joke not found."); - } - - // Attempt to add the joke to the user's favorites - if (user.addToFavorites()) { - // Save the updated user in the data store - dataAccess.saveUser(user); - - // Prepare a success response - return outputBoundary.prepareSuccessResponse( - new AddToFavOutputData("Joke added to favorites successfully!") - ); + outputBoundary.prepareFailView("User not found."); } else { - // Joke was already in the favorites list - return outputBoundary.prepareFailResponse("Joke is already in the favorites list."); + JokeFactory jokeFactory = new JokeFactory(); + Joke joke = jokeFactory.create(inputData.getJokeContent(), (int) (Math.random()*100)); + joke.setExplanation(inputData.getExplanation()); + user.getFavorites().add(joke); + dataAccess.saveUser(user); + outputBoundary.prepareSuccessView("Added"); } } } diff --git a/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java b/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java index e6dcf02c1..f3681db29 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java +++ b/src/main/java/use_case/add_to_fav/AddToFavOutputBoundary.java @@ -5,19 +5,8 @@ * for the Add to Favorites use case. */ public interface AddToFavOutputBoundary { - /** - * Prepares a successful response for the operation. - * - * @param outputData the data to include in the success response - * @return a formatted response model - */ - AddToFavOutputData prepareSuccessResponse(AddToFavOutputData outputData); - /** - * Prepares a failure response for the operation. - * - * @param errorMessage the error message to include in the response - * @return a formatted response model - */ - AddToFavOutputData prepareFailResponse(String errorMessage); + void prepareSuccessView(String added); + + void prepareFailView(String error); } diff --git a/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java b/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java index 33d12fa03..5aa94db22 100644 --- a/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java +++ b/src/main/java/use_case/add_to_fav/adapter/AddToFavController.java @@ -1,9 +1,6 @@ package use_case.add_to_fav.adapter; -import use_case.add_to_fav.AddToFavInputBoundary; -import use_case.add_to_fav.AddToFavInputData; -import use_case.add_to_fav.AddToFavOutputData; -import use_case.add_to_fav.AddToFavResponseModel; +import use_case.add_to_fav.*; /** * The AddToFavController class handles user requests for adding a joke to their favorites. @@ -25,20 +22,12 @@ public AddToFavController(AddToFavInputBoundary interactor) { /** * Adds a joke to the user's list of favorites. * - * @param username the username of the user - * @param jokeId the ID of the joke to add to favorites + * @param jokeContent the username of the user + * @param explanation the ID of the joke to add to favorites * @return a response model containing the result of the operation */ - public AddToFavResponseModel addToFavorites(String username, String jokeId) { - // Create the input data object for the interactor - final AddToFavInputData inputData = new AddToFavInputData(username, jokeId); - - // Pass the input data to the interactor - final AddToFavOutputData outputData = interactor.addToFavorites(inputData); - - // Return the formatted response - return new AddToFavResponseModel(outputData.getMessage()); + public void execute(String jokeContent, String explanation) { + final AddToFavInputData inputData = new AddToFavInputData(jokeContent, explanation); + interactor.executeAddToFav(inputData); } } - - diff --git a/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java b/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java index 4c33ce530..ec99ea1c5 100644 --- a/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java +++ b/src/main/java/use_case/add_to_fav/adapter/AddToFavPresenter.java @@ -1,7 +1,8 @@ package use_case.add_to_fav.adapter; import use_case.add_to_fav.AddToFavOutputBoundary; -import use_case.add_to_fav.AddToFavOutputData; +import view.joke_view.JokeState; +import view.joke_view.JokeViewModel; /** * The AddToFavPresenter class formats the output of the Add to Favorites use case @@ -9,27 +10,25 @@ */ public class AddToFavPresenter implements AddToFavOutputBoundary { - /** - * Prepares a success response for the Add to Favorites use case. - * - * @param outputData the output data containing the success message - * @return the formatted output data - */ + private final JokeViewModel jokeViewModel; + + public AddToFavPresenter(JokeViewModel jokeViewModel) { + this.jokeViewModel = jokeViewModel; + } + @Override - public AddToFavOutputData prepareSuccessResponse(AddToFavOutputData outputData) { - // Simply return the output data for success cases (can format further if needed) - return outputData; + public void prepareSuccessView(String added) { + final JokeState jokeState = jokeViewModel.getState(); + jokeState.setAddToFavText(added); + jokeViewModel.setState(jokeState); + jokeViewModel.firePropertyChanged(); } - /** - * Prepares a failure response for the Add to Favorites use case. - * - * @param errorMessage the error message describing the failure - * @return the formatted output data with the error message - */ @Override - public AddToFavOutputData prepareFailResponse(String errorMessage) { - // Return an output data object with the error message - return new AddToFavOutputData(errorMessage); + public void prepareFailView(String error) { + final JokeState jokeState = jokeViewModel.getState(); + jokeState.setAddToFavText(error); + jokeViewModel.setState(jokeState); + jokeViewModel.firePropertyChanged(); } } diff --git a/src/main/java/view/joke_view/JokeState.java b/src/main/java/view/joke_view/JokeState.java new file mode 100644 index 000000000..e3698c1f5 --- /dev/null +++ b/src/main/java/view/joke_view/JokeState.java @@ -0,0 +1,42 @@ +package view.joke_view; + +import static view.joke_view.JokeViewModel.ADD_BUTTON_LABEL; + +public class JokeState { + // info that can change + private String jokeContent = ""; + private String explanation = ""; + private String addToFav = ADD_BUTTON_LABEL; + + @Override + public String toString() { + return "JokeState{" + + "jokeContent='" + getJokeContent() + '\'' + + ", explanation='" + getExplanation() + '\'' + + '}'; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } + + public String getJokeContent() { + return jokeContent; + } + + public void setJokeContent(String jokeContent) { + this.jokeContent = jokeContent; + } + + public void setAddToFavText(String added) { + this.addToFav = added; + } + + public String getAddToFav(){ + return this.addToFav; + } +} \ No newline at end of file diff --git a/src/main/java/view/joke_view/JokeViewModel.java b/src/main/java/view/joke_view/JokeViewModel.java new file mode 100644 index 000000000..2be59c5be --- /dev/null +++ b/src/main/java/view/joke_view/JokeViewModel.java @@ -0,0 +1,18 @@ +package view.joke_view; + +import view.ViewModel; + + +public class JokeViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Joke"; + public static final String EXPLANATION_BUTTON_LABEL = "Explain"; + public static final String ADD_BUTTON_LABEL = "Add to Favorite"; + public static final String EXPLANATION_LABEL = "Explanation"; + + public JokeViewModel() { + super("Joke"); + setState(new JokeState()); + } + // a wrapper for all the info you need to build a view +} \ No newline at end of file From 0509f6ec33129a7a16ce13b706bf04cd5d2c3ebb Mon Sep 17 00:00:00 2001 From: cheryllin2154 Date: Sat, 30 Nov 2024 16:40:30 -0500 Subject: [PATCH 54/62] Create accessibility-report.md principles of accessibility --- accessibility-report.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 accessibility-report.md diff --git a/accessibility-report.md b/accessibility-report.md new file mode 100644 index 000000000..ab6848693 --- /dev/null +++ b/accessibility-report.md @@ -0,0 +1,34 @@ +# Principles of Universal Design: + +### Principle 1: Equitable Use. +The Joke machine is useful and marketable to people with diverse abilities since it does not require much skill beyond basic linguistic abilities. +The program also does not require personal information such that the user’s privacy, safety or security would be infringed upon by using the program. + +### Principle 2: Flexibility in Use. +The design accommodates a wide range of individual preferences due to the diversity in jokes generated. + +### Principle 3: Simple and Intuitive Use. +The program is easy to understand, given the user has basic English comprehension skills and does not require any prior knowledge. +However, the program is not accessible to those who are visually impaired and would need further implementations to overcome this problem. + +## Principle 4: Perceptible Information. +Unfortunately, the program does not communicate necessary information effectively to users if they have impaired visual sensory abilities. Improvements that allow for auditory based inputs and outputs would need to be implemented. + +## Principle 5: Tolerance for Error. +The design of the program minimizes hazards and the adverse consequences of accidental or unintended actions since the scope of the domain is relatively small. Thus, the program is unlikely to cause any risk to the user. + +## Principle 6: Low Physical Effort. +The design can be used efficiently and comfortably and with a minimum of fatigue since the program does not require much input from the user. The user can simply use the program by clicking various buttons such as generate, save and revisit. + +## Principle 7: Size and Space for Approach and Use. +Appropriate size and space is provided for approach, reach, manipulation, and use regardless of the user's body size, posture, or mobility. This is because the program does not require the user to be confined in a certain physical environment. The user can simply access the program on a laptop anywhere. + + +# + +The Joke Machine would be primarily marketed towards individuals who enjoy humor such as comedy enthusiasts, social media users, and casual users who are seeking to learn about some jokes. In particular, the program may be engaging to students or those of a younger age as they may feel more pressure to have a sense of humor amongst their peer group. Furthermore, the explanation feature of the program may be attractive to those you are seeking for guidance in improving their literary skills to enhance their social interactions with their peers. + +Although our program would likely be used for those who are looking for a casual source of entertainment but may be particularly useful for those who lack confidence in their sense of humor and want to seek guidance in interpreting jokes. This may include non-native English speakers who struggle with cultural nuances or linguistic subtleties in humor. Our program also ensures inclusivity to a wide range of users, including those who suffer from physical injuries, such as a broken leg and are unable to walk. + + + From 70f061f06d1b25897a2162a43f21217158b079e1 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Sat, 30 Nov 2024 17:20:27 -0500 Subject: [PATCH 55/62] Visitor.java --- .../generate/adapter/GeneratePresenter.java | 27 +++----- .../java/view/joke_view/JokeFrameBuilder.java | 6 ++ src/main/java/visitor/JokeVisitor.java | 15 +++++ src/main/java/visitor/Visitor.java | 66 +++++++++++++++++++ 4 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 src/main/java/visitor/JokeVisitor.java create mode 100644 src/main/java/visitor/Visitor.java diff --git a/src/main/java/use_case/generate/adapter/GeneratePresenter.java b/src/main/java/use_case/generate/adapter/GeneratePresenter.java index 2dc854d21..622bd9d90 100644 --- a/src/main/java/use_case/generate/adapter/GeneratePresenter.java +++ b/src/main/java/use_case/generate/adapter/GeneratePresenter.java @@ -1,21 +1,20 @@ package use_case.generate.adapter; -import entity.Joke; +import data_access.FileDataAccessObject; import use_case.generate.GenerateOuputBoundary; import use_case.generate.GenerateOutputData; -import use_case.note.NoteOutputBoundary; import view.joke_view.JokeFrameBuilder; -import view.joke_view.JokeViewModel; - -import javax.swing.*; +import visitor.GenerateVisitor; +import visitor.JokeVisitor; +import visitor.Visitor; public class GeneratePresenter implements GenerateOuputBoundary { // not a typical presenter, more similar to main - private final JokeFrameBuilder jokeFrameBuilder; + private final FileDataAccessObject fileDataAccessObject; - public GeneratePresenter(JokeFrameBuilder jokeFrameBuilder) { - this.jokeFrameBuilder = jokeFrameBuilder; + public GeneratePresenter(FileDataAccessObject fileDataAccessObject) { + this.fileDataAccessObject = fileDataAccessObject; } /** @@ -25,15 +24,8 @@ public GeneratePresenter(JokeFrameBuilder jokeFrameBuilder) { */ @Override public void prepareSuccessView(GenerateOutputData generateOutputData) { - final JFrame frame = jokeFrameBuilder - .addJokeView() - .setJokeContent(generateOutputData.getJokeContent()) - .addExplanationUseCase() - .addAddToFavUseCase() - .build(); - - frame.pack(); - frame.setVisible(true); + final JokeVisitor visitor = new Visitor(fileDataAccessObject); + visitor.visit(generateOutputData); } /** @@ -41,7 +33,6 @@ public void prepareSuccessView(GenerateOutputData generateOutputData) { * * @param errorMessage the explanation of the failure */ - //TODO implement @Override public void prepareFailView(String errorMessage) { // jokeViewModel.getState().setError(errorMessage); diff --git a/src/main/java/view/joke_view/JokeFrameBuilder.java b/src/main/java/view/joke_view/JokeFrameBuilder.java index 58fabca6f..7591726ba 100644 --- a/src/main/java/view/joke_view/JokeFrameBuilder.java +++ b/src/main/java/view/joke_view/JokeFrameBuilder.java @@ -44,6 +44,12 @@ public JokeFrameBuilder setJokeContent(String content) { return this; } + public JokeFrameBuilder setExplanation(String explanation) { + jokeViewModel.getState().setExplanation(explanation); + jokeViewModel.firePropertyChanged(); + return this; + } + public JokeFrameBuilder addExplanationUseCase() { final ExplanationOutputBoundary explanationOutputBoundary = new ExplanationPresenter(jokeViewModel); final ExplanationInputBoundary explanationInteractor = new ExplanationInteractor( diff --git a/src/main/java/visitor/JokeVisitor.java b/src/main/java/visitor/JokeVisitor.java new file mode 100644 index 000000000..48603e143 --- /dev/null +++ b/src/main/java/visitor/JokeVisitor.java @@ -0,0 +1,15 @@ +package visitor; + +import data_access.FileDataAccessObject; +import use_case.generate.GenerateOutputData; +import use_case.search.SearchOutputData; + +import javax.swing.*; + +public interface JokeVisitor { + void visit(GenerateOutputData generateOutputData); + + void visit(SearchOutputData searchOutputData); + + void visit(FavSearchOutputData favSearchOutputData); +} diff --git a/src/main/java/visitor/Visitor.java b/src/main/java/visitor/Visitor.java new file mode 100644 index 000000000..05a6d0252 --- /dev/null +++ b/src/main/java/visitor/Visitor.java @@ -0,0 +1,66 @@ +package visitor; + +import data_access.FileDataAccessObject; +import use_case.generate.GenerateOutputData; +import use_case.search.SearchOutputData; +import view.joke_view.JokeFrameBuilder; + +import javax.swing.*; + +public class Visitor implements JokeVisitor{ + + private final FileDataAccessObject fileDataAccessObject; + + public Visitor(FileDataAccessObject dataAccess) { + this.fileDataAccessObject = dataAccess; + } + + + public void visit(GenerateOutputData generateOutputData) { + + JokeFrameBuilder frameBuilder = new JokeFrameBuilder(); + + final JFrame frame = frameBuilder + .addJokeView() + .setJokeContent( generateOutputData.getJokeContent()) + .addExplanationUseCase() + .addAddToFavUseCase(fileDataAccessObject) + .build(); + + frame.pack(); + frame.setVisible(true); + } + + @Override + public void visit(SearchOutputData searchOutputData) { + JokeFrameBuilder frameBuilder = new JokeFrameBuilder(); + + final JFrame frame = frameBuilder + .addJokeView() + .setJokeContent( searchOutputData.getJokeContent()) + .addExplanationUseCase() + .addAddToFavUseCase(fileDataAccessObject) + .build(); + + frame.pack(); + frame.setVisible(true); + } + + @Override + public void visit(FavSearchOutputData favSearchOutputData) { + JokeFrameBuilder frameBuilder = new JokeFrameBuilder(); + + final JFrame frame = frameBuilder + .addJokeView() + .setJokeContent( favSearchOutputData.getJokeContent()) + .setExplanation(favSearchOutputData.getExplanation()) + .addExplanationUseCase() + .addAddToFavUseCase(fileDataAccessObject) + .build(); + + frame.pack(); + frame.setVisible(true); + } + + +} From bf625c03550aaf6f098768a522775a218c15b512 Mon Sep 17 00:00:00 2001 From: dengxues Date: Sat, 30 Nov 2024 17:47:22 -0500 Subject: [PATCH 56/62] favourite and funniest(incomplete) --- .../data_access/FileDataAccessObject.java | 8 +- .../favourite/FavouriteInputBoundary.java | 7 -- .../favourite/FavouriteInteractor.java | 16 ++-- .../FavouriteUserDataAccessInterface.java | 9 +- .../adapter/FavouriteController.java | 3 +- .../funniest/FunniestDataAccessInterface.java | 4 +- .../funniest/FunniestInputBoundary.java | 2 + .../use_case/funniest/FunniestInteractor.java | 19 ++-- .../use_case/funniest/FunniestOutputData.java | 12 ++- .../funniest/adapter/FunniestController.java | 4 + .../funniest/adapter/FunniestPresenter.java | 4 + .../view/favourite_view/FavouriteState.java | 5 -- .../view/favourite_view/FavouriteView.java | 86 ++++++++++++------- .../favourite_view/FavouriteViewModel.java | 3 +- 14 files changed, 104 insertions(+), 78 deletions(-) create mode 100644 src/main/java/use_case/funniest/adapter/FunniestController.java create mode 100644 src/main/java/use_case/funniest/adapter/FunniestPresenter.java diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index c8495122e..aaa3d20e6 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -13,6 +13,7 @@ import entity.JokeFactory; import entity.User; import entity.UserFactory; +import use_case.favourite.FavouriteUserDataAccessInterface; import use_case.logout.LogoutUserDataAccessInterface; import use_case.signup.SignupUserDataAccessInterface; @@ -20,7 +21,7 @@ * DAO for user data implemented using a File to persist the data. */ public class FileDataAccessObject implements SignupUserDataAccessInterface, - LogoutUserDataAccessInterface { + LogoutUserDataAccessInterface, FavouriteUserDataAccessInterface { private File jsonFile; private List users = new ArrayList<>(); @@ -120,4 +121,9 @@ public String getCurrentUsername() { public void setCurrentUsername(String username) { this.currentUserName = username; } + + @Override + public List getUsername() { + return List.of(); + } } diff --git a/src/main/java/use_case/favourite/FavouriteInputBoundary.java b/src/main/java/use_case/favourite/FavouriteInputBoundary.java index 962e424f7..f4893d07d 100644 --- a/src/main/java/use_case/favourite/FavouriteInputBoundary.java +++ b/src/main/java/use_case/favourite/FavouriteInputBoundary.java @@ -7,11 +7,4 @@ public interface FavouriteInputBoundary { * @param favouriteInputData the input data */ void execute(FavouriteInputData favouriteInputData); - - /** - * Executes the switch to login view use case. - */ - void switchToFavouriteView(); - - void executeFunniest(); } diff --git a/src/main/java/use_case/favourite/FavouriteInteractor.java b/src/main/java/use_case/favourite/FavouriteInteractor.java index 3a4d84879..29ca54f18 100644 --- a/src/main/java/use_case/favourite/FavouriteInteractor.java +++ b/src/main/java/use_case/favourite/FavouriteInteractor.java @@ -17,16 +17,12 @@ public FavouriteInteractor(FavouriteUserDataAccessInterface favouriteUserDataAcc this.favouriteOutputBoundary = favouriteOutputBoundary; } - public void executeFavourite() { - try { - final List jokeList = favouriteUserDataAccessInterface.getFavourite(); - // interactor gets input data and outputs output data - final FavouriteOutputData favouriteOutputData = new FavouriteOutputData(jokeList); + @Override + public void execute(FavouriteInputData favouriteInputData) { + final List jokeList = favouriteUserDataAccessInterface.get(favouriteUserDataAccessInterface.getCurrentUsername()).getFavorites(); + // interactor gets input data and outputs output data + final FavouriteOutputData favouriteOutputData = new FavouriteOutputData(jokeList); - favouriteOutputBoundary.prepareSuccessView(favouriteOutputData); - } - catch (RuntimeException ex) { - favouriteOutputBoundary.prepareFailView(ex.getMessage()); - } + favouriteOutputBoundary.prepareSuccessView(favouriteOutputData); } } diff --git a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java index e2b6bebbb..6c22124b0 100644 --- a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java +++ b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java @@ -1,9 +1,10 @@ package use_case.favourite; -import java.util.List; - -import entity.Joke; +import entity.User; public interface FavouriteUserDataAccessInterface { - List getFavourite(); + String getCurrentUsername(); + + User get(String username); + } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteController.java b/src/main/java/use_case/favourite/adapter/FavouriteController.java index 3ba37644d..72cc68fb6 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteController.java +++ b/src/main/java/use_case/favourite/adapter/FavouriteController.java @@ -3,10 +3,9 @@ import entity.User; import use_case.favourite.FavouriteInputBoundary; import use_case.favourite.FavouriteInputData; -import use_case.favourite.FavouriteInteractor; -import use_case.favourite.FavouriteOutputBoundary; public class FavouriteController { + private final FavouriteInputBoundary userFavouriteUseCaseInteractor; public FavouriteController(FavouriteInputBoundary userFavouriteUseCaseInteractor) { diff --git a/src/main/java/use_case/funniest/FunniestDataAccessInterface.java b/src/main/java/use_case/funniest/FunniestDataAccessInterface.java index 1c4cee745..ec2f97d8b 100644 --- a/src/main/java/use_case/funniest/FunniestDataAccessInterface.java +++ b/src/main/java/use_case/funniest/FunniestDataAccessInterface.java @@ -1,7 +1,5 @@ package use_case.funniest; -import entity.Joke; - public interface FunniestDataAccessInterface { - Joke getFunniestJoke(); + String getFunniestJoke(); } diff --git a/src/main/java/use_case/funniest/FunniestInputBoundary.java b/src/main/java/use_case/funniest/FunniestInputBoundary.java index 9f8c21cd9..ffa7fa780 100644 --- a/src/main/java/use_case/funniest/FunniestInputBoundary.java +++ b/src/main/java/use_case/funniest/FunniestInputBoundary.java @@ -2,4 +2,6 @@ public interface FunniestInputBoundary { void execute(FunniestInputData funniestInputData); + + void executeFunniest(); } diff --git a/src/main/java/use_case/funniest/FunniestInteractor.java b/src/main/java/use_case/funniest/FunniestInteractor.java index e996cbaac..6aa3a5188 100644 --- a/src/main/java/use_case/funniest/FunniestInteractor.java +++ b/src/main/java/use_case/funniest/FunniestInteractor.java @@ -1,20 +1,27 @@ package use_case.funniest; -import use_case.favourite.FavouriteInputBoundary; -import use_case.favourite.FavouriteOutputBoundary; +import entity.Joke; -public class FunniestInteractor implements FavouriteInputBoundary { +public class FunniestInteractor implements FunniestInputBoundary { - private final FavouriteOutputBoundary favouriteOutputBoundary; + private final FunniestDataAccessInterface funniestDataAccessInterface; + private final FunniestOutputBoundary funniestOutputBoundary; - public FunniestInteractor(FavouriteOutputBoundary outputBoundary) { - this.favouriteOutputBoundary = outputBoundary; + public FunniestInteractor(FunniestDataAccessInterface funniestDataAccessInterface, FunniestOutputBoundary funniestoutputBoundary) { + this.funniestDataAccessInterface = funniestDataAccessInterface; + this.funniestOutputBoundary = funniestoutputBoundary; } @Override public void executeFunniest() { try { + final String content = funniestDataAccessInterface.getFunniestJoke(); + final FunniestOutputData funniestOutputData = new FunniestOutputData(content); + funniestOutputBoundary.prepareSuccessView(funniestOutputData); + } + catch (RuntimeException ex) { + funniestOutputBoundary.prepareFailView(ex.getMessage()); } } } diff --git a/src/main/java/use_case/funniest/FunniestOutputData.java b/src/main/java/use_case/funniest/FunniestOutputData.java index bc6085ff0..3ad39e7d4 100644 --- a/src/main/java/use_case/funniest/FunniestOutputData.java +++ b/src/main/java/use_case/funniest/FunniestOutputData.java @@ -1,15 +1,13 @@ package use_case.funniest; -import entity.Joke; - public class FunniestOutputData { - private final Joke joke; + private final String jokeContent; - public FunniestOutputData(Joke joke) { - this.joke = joke; + public FunniestOutputData(String jokeContent) { + this.jokeContent = jokeContent; } - Joke getJoke() { - return joke; + String getJokeContent() { + return jokeContent; } } diff --git a/src/main/java/use_case/funniest/adapter/FunniestController.java b/src/main/java/use_case/funniest/adapter/FunniestController.java new file mode 100644 index 000000000..1258ba2d3 --- /dev/null +++ b/src/main/java/use_case/funniest/adapter/FunniestController.java @@ -0,0 +1,4 @@ +package use_case.funniest.adapter; + +public class FunniestController { +} diff --git a/src/main/java/use_case/funniest/adapter/FunniestPresenter.java b/src/main/java/use_case/funniest/adapter/FunniestPresenter.java new file mode 100644 index 000000000..e7a0cf150 --- /dev/null +++ b/src/main/java/use_case/funniest/adapter/FunniestPresenter.java @@ -0,0 +1,4 @@ +package use_case.funniest.adapter; + +public class FunniestPresenter { +} diff --git a/src/main/java/view/favourite_view/FavouriteState.java b/src/main/java/view/favourite_view/FavouriteState.java index 26ad82548..415f46351 100644 --- a/src/main/java/view/favourite_view/FavouriteState.java +++ b/src/main/java/view/favourite_view/FavouriteState.java @@ -10,11 +10,6 @@ public class FavouriteState { private User user; private List favourites; - @Override - public String toString() { - return super.toString(); - } - public List getFavourites() { return favourites; } diff --git a/src/main/java/view/favourite_view/FavouriteView.java b/src/main/java/view/favourite_view/FavouriteView.java index d6471ba47..f063844d8 100644 --- a/src/main/java/view/favourite_view/FavouriteView.java +++ b/src/main/java/view/favourite_view/FavouriteView.java @@ -1,31 +1,38 @@ package view.favourite_view; +import entity.Joke; +import use_case.favourite.FavouriteInteractor; import view.helper_functions.LabelTextPanel; import java.awt.*; +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.*; import use_case.favourite.adapter.FavouriteController; +import visitor.Visitor; -public class FavouriteView extends JPanel { +public class FavouriteView extends JPanel implements ActionListener, PropertyChangeListener { - private final FavouriteController favouriteController; private final FavouriteViewModel favouriteViewModel; - private final String viewName = "Favourite"; + private final String viewName; private FavouriteView favouriteView; - private final JTextArea keywordInputField = new JTextArea(); + private FavouriteController favouriteController; private final JTextField searchBox = new JTextField(15); private final JButton searchButton; private final JButton funniestButton; private final JButton cancelButton; - public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController controller) { - this.favouriteController = controller; + public FavouriteView(FavouriteViewModel favouriteViewModel) { this.favouriteViewModel = favouriteViewModel; + this.viewName = favouriteViewModel.getViewName(); this.favouriteViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel(FavouriteViewModel.TITLE_LABEL); @@ -40,36 +47,39 @@ public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController buttons.add(funniestButton); cancelButton = new JButton(FavouriteViewModel.CANCEL_BUTTOM_LABEL); buttons.add(cancelButton); + buttons.add(search); + + final JPanel jokeListPanel = new JPanel(); + List fav = favouriteViewModel.getState().getFavourites(); + for (int i = 0; i < fav.size(); i++) { + String content = fav.get(i).getContent(); + jokeListPanel.add(new JLabel(content)); + } + + final JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + + mainPanel.setLeftComponent(buttons); + mainPanel.setRightComponent(jokeListPanel); this.add(title); - this.add(search); - this.add(buttons); + this.add(mainPanel); - final JPanel jokeListPanel = new JPanel(); + funniestButton.addActionListener( + evt -> { + if (evt.getSource().equals(funniestButton)) { + funniestController.execute(); + } + } + ); - final JFrame mainPanel = new JFrame(viewName); - mainPanel.add(buttons, BorderLayout.NORTH); - mainPanel.add(jokeListPanel, BorderLayout.SOUTH); + cancelButton.addActionListener(this); -// funniestButton.addActionListener( -// evt -> { -// if (evt.getSource().equals(funniestButton)) { -// favouriteController.execute(favouriteInputField.getText()); -// -// } -// } -// ); -// -// refreshButton.addActionListener( -// evt -> { -// if (evt.getSource().equals(refreshButton)) { -// favouriteController.execute(null); -// -// } -// } -// ); -// } -// + searchButton.addActionListener( + evt -> { + if (evt.getSource().equals(searchButton)) { + + } + } // /** // * React to a button click that results in evt. // * @param evt the ActionEvent to react to @@ -92,4 +102,18 @@ public FavouriteView(FavouriteViewModel favouriteViewModel, FavouriteController // return viewName; // } } + + public void setFavouriteController(FavouriteController controller) { + this.favouriteController = controller; + } + + @Override + public void actionPerformed(ActionEvent e) { + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + } } \ No newline at end of file diff --git a/src/main/java/view/favourite_view/FavouriteViewModel.java b/src/main/java/view/favourite_view/FavouriteViewModel.java index 97631706c..565a3681e 100644 --- a/src/main/java/view/favourite_view/FavouriteViewModel.java +++ b/src/main/java/view/favourite_view/FavouriteViewModel.java @@ -3,10 +3,9 @@ import view.ViewModel; public class FavouriteViewModel extends ViewModel { - public static final String TITLE_LABEL = "Favourite"; + public static final String TITLE_LABEL = "Favourite"; public static final String KEYWORD_LABEL = "Enter keyword to find a joke:"; - public static final String SEARCH_BUTTOM_LABEL = "search"; public static final String FUNNIEST_BUTTOM_LABEL = "funniest"; public static final String CANCEL_BUTTOM_LABEL = "cancel"; From 3dbd86eb9d4b5b0182ce18a5391e9bf9c1bd3504 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 1 Dec 2024 00:22:15 -0500 Subject: [PATCH 57/62] fav search rename and location change --- .../FavSearchDataAccessInterface.java} | 4 +- .../FavSearchInputBoundary.java} | 4 +- .../fav_search/FavSearchInteractor.java | 38 ++++++++++++++++++- .../FavSearchOutputBoundary.java} | 6 +-- .../FavSearchOutputData.java} | 6 +-- .../adapter/FavSearchController.java | 16 ++++++++ .../adapter/FavSearchPresenter.java} | 15 ++++---- .../adapter/SearchFavouritesController.java | 16 -------- 8 files changed, 71 insertions(+), 34 deletions(-) rename src/main/java/use_case/{search_favourites/SearchFavouritesDataAccessInterface.java => fav_search/FavSearchDataAccessInterface.java} (67%) rename src/main/java/use_case/{search_favourites/SearchFavouritesInputBoundary.java => fav_search/FavSearchInputBoundary.java} (65%) rename src/main/java/use_case/{search_favourites/SearchFavouritesOutputBoundary.java => fav_search/FavSearchOutputBoundary.java} (64%) rename src/main/java/use_case/{search_favourites/SearchFavouritesOutputData.java => fav_search/FavSearchOutputData.java} (54%) create mode 100644 src/main/java/use_case/fav_search/adapter/FavSearchController.java rename src/main/java/use_case/{search_favourites/adapter/SearchFavouritesPresenter.java => fav_search/adapter/FavSearchPresenter.java} (59%) delete mode 100644 src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java b/src/main/java/use_case/fav_search/FavSearchDataAccessInterface.java similarity index 67% rename from src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java rename to src/main/java/use_case/fav_search/FavSearchDataAccessInterface.java index 61f2120ea..908a3643d 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesDataAccessInterface.java +++ b/src/main/java/use_case/fav_search/FavSearchDataAccessInterface.java @@ -1,10 +1,10 @@ -package use_case.search_favourites; +package use_case.fav_search; import entity.Joke; import java.util.List; -public interface SearchFavouritesDataAccessInterface { +public interface FavSearchDataAccessInterface { /** * Get the user's favourites list. * @return a list of jokes marked as favourites. diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java b/src/main/java/use_case/fav_search/FavSearchInputBoundary.java similarity index 65% rename from src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java rename to src/main/java/use_case/fav_search/FavSearchInputBoundary.java index 4683ab531..e4aac40d8 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesInputBoundary.java +++ b/src/main/java/use_case/fav_search/FavSearchInputBoundary.java @@ -1,6 +1,6 @@ -package use_case.search_favourites; +package use_case.fav_search; -public interface SearchFavouritesInputBoundary { +public interface FavSearchInputBoundary { /** * Search for jokes in the user's favourites. * @param keyword the keyword to search for. diff --git a/src/main/java/use_case/fav_search/FavSearchInteractor.java b/src/main/java/use_case/fav_search/FavSearchInteractor.java index e0d87365b..d9e4b41a5 100644 --- a/src/main/java/use_case/fav_search/FavSearchInteractor.java +++ b/src/main/java/use_case/fav_search/FavSearchInteractor.java @@ -1,4 +1,40 @@ package use_case.fav_search; -public class FavSearchInteractor { +import entity.Joke; + +import java.util.List; +import java.util.stream.Collectors; + +public class FavSearchInteractor implements FavSearchInputBoundary { + private final FavSearchDataAccessInterface dataAccess; + private final FavSearchOutputBoundary presenter; + + public FavSearchInteractor(FavSearchOutputBoundary presenter) { + this.dataAccess = dataAccess; + this.presenter = presenter; + } + + @Override + public void executeSearch(String keyword) { + try { + final List favourites = dataAccess.getFavourites(); + final List matchingJokes = favourites.stream() + .filter(joke -> joke.getContent().toLowerCase().contains(keyword.toLowerCase())) + .collect(Collectors.toList()); + + if (matchingJokes.isEmpty()) { + presenter.presentFailure("No matching jokes found in favourites."); + } + else { + final Joke selectedJoke = matchingJokes.get(0); + final FavSearchOutputData outputData = new FavSearchOutputData( + selectedJoke.getContent() + ); + presenter.prepareSuccessView(outputData); + } + } catch (RuntimeException e) { + presenter.presentFailure("Error searching favourites: " + e.getMessage()); + } + } + } diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java b/src/main/java/use_case/fav_search/FavSearchOutputBoundary.java similarity index 64% rename from src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java rename to src/main/java/use_case/fav_search/FavSearchOutputBoundary.java index e672f370c..07e5ff644 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesOutputBoundary.java +++ b/src/main/java/use_case/fav_search/FavSearchOutputBoundary.java @@ -1,12 +1,12 @@ -package use_case.search_favourites; +package use_case.fav_search; -public interface SearchFavouritesOutputBoundary { +public interface FavSearchOutputBoundary { /** * Prepares the view for successful search results. * @param searchFavouritesOutputData the output data containing the joke content. */ - void prepareSuccessView(SearchFavouritesOutputData searchFavouritesOutputData); + void prepareSuccessView(FavSearchOutputData searchFavouritesOutputData); /** * Presents an error message if the search fails. diff --git a/src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java b/src/main/java/use_case/fav_search/FavSearchOutputData.java similarity index 54% rename from src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java rename to src/main/java/use_case/fav_search/FavSearchOutputData.java index c813c7613..5f7371a8f 100644 --- a/src/main/java/use_case/search_favourites/SearchFavouritesOutputData.java +++ b/src/main/java/use_case/fav_search/FavSearchOutputData.java @@ -1,10 +1,10 @@ -package use_case.search_favourites; +package use_case.fav_search; -public class SearchFavouritesOutputData { +public class FavSearchOutputData { private final String jokeContent; - public SearchFavouritesOutputData(String jokeContent) { + public FavSearchOutputData(String jokeContent) { this.jokeContent = jokeContent; } diff --git a/src/main/java/use_case/fav_search/adapter/FavSearchController.java b/src/main/java/use_case/fav_search/adapter/FavSearchController.java new file mode 100644 index 000000000..48269c7d3 --- /dev/null +++ b/src/main/java/use_case/fav_search/adapter/FavSearchController.java @@ -0,0 +1,16 @@ +package use_case.fav_search.adapter; + +import use_case.fav_search.FavSearchInputBoundary; + +public class FavSearchController { + + private final FavSearchInputBoundary interactor; + + public FavSearchController(FavSearchInputBoundary interactor) { + this.interactor = interactor; + } + + public void executeSearch(String keyword) { + interactor.executeSearch(keyword); + } +} diff --git a/src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java b/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java similarity index 59% rename from src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java rename to src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java index dbfc0688a..eda804f62 100644 --- a/src/main/java/use_case/search_favourites/adapter/SearchFavouritesPresenter.java +++ b/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java @@ -1,8 +1,9 @@ -package use_case.search_favourites.adapter; +package use_case.fav_search.adapter; -import use_case.search_favourites.SearchFavouritesOutputBoundary; -import use_case.search_favourites.SearchFavouritesOutputData; -import view.FavouriteView; +import use_case.fav_search.FavSearchOutputBoundary; +import use_case.fav_search.FavSearchOutputData; +import view.favourite_view.FavouriteView; +import view.favourite_view.FavouriteViewModel; import view.joke_view.JokeFrameBuilder; import javax.swing.*; @@ -11,18 +12,18 @@ Search favourites presenter. */ -public class SearchFavouritesPresenter implements SearchFavouritesOutputBoundary { +public class FavSearchPresenter implements FavSearchOutputBoundary { private final FavouriteView favouriteView; private final JokeFrameBuilder jokeFrameBuilder; - public SearchFavouritesPresenter(FavouriteView favouriteView, JokeFrameBuilder jokeFrameBuilder) { + public FavSearchPresenter(FavouriteViewModel favouriteView, JokeFrameBuilder jokeFrameBuilder) { this.favouriteView = favouriteView; this.jokeFrameBuilder = jokeFrameBuilder; } @Override - public void prepareSuccessView(SearchFavouritesOutputData searchFavouritesOutputData) { + public void prepareSuccessView(FavSearchOutputData searchFavouritesOutputData) { final JFrame frame = jokeFrameBuilder .addJokeView() .setJokeContent(searchFavouritesOutputData.getJokeContent()) diff --git a/src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java b/src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java deleted file mode 100644 index 2704f26a3..000000000 --- a/src/main/java/use_case/search_favourites/adapter/SearchFavouritesController.java +++ /dev/null @@ -1,16 +0,0 @@ -package use_case.search_favourites.adapter; - -import use_case.search_favourites.SearchFavouritesInputBoundary; - -public class SearchFavouritesController { - - private final SearchFavouritesInputBoundary interactor; - - public SearchFavouritesController(SearchFavouritesInputBoundary interactor) { - this.interactor = interactor; - } - - public void executeSearch(String keyword) { - interactor.executeSearch(keyword); - } -} From 236cc96def2f66ffad2ee94d4dade062cb9138d5 Mon Sep 17 00:00:00 2001 From: five Date: Sun, 1 Dec 2024 13:57:28 -0500 Subject: [PATCH 58/62] Implements Visitor on SearchPresenter, fileDataAccessObject implements AddToFavDataAccessInterface --- src/main/java/app/AppBuilder.java | 2 +- .../data_access/FileDataAccessObject.java | 4 ++- .../AddToFavDataAccessInterface.java | 2 +- .../add_to_fav/AddToFavInteractor.java | 2 +- .../search/adapter/SearchBuilder.java | 34 ------------------- .../search/adapter/SearchPresenter.java | 16 ++++----- src/main/java/visitor/Visitor.java | 4 +-- .../java/use_case/search/DemoSearchTest.java | 10 ------ 8 files changed, 14 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/use_case/search/adapter/SearchBuilder.java delete mode 100644 src/test/java/use_case/search/DemoSearchTest.java diff --git a/src/main/java/app/AppBuilder.java b/src/main/java/app/AppBuilder.java index 9cff186cd..a68c2fa98 100644 --- a/src/main/java/app/AppBuilder.java +++ b/src/main/java/app/AppBuilder.java @@ -183,7 +183,7 @@ public AppBuilder addLoginUseCase() { */ public AppBuilder addSearchUseCase() { final SearchOutputBoundary searchOutputBoundary = - new SearchPresenter(jokeFrameBuilder); + new SearchPresenter(userDataAccessObject, jokeFrameBuilder); final SearchInputBoundary searchInteractor = new SearchInteractor(jokeDataAccessObject, searchOutputBoundary); diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index ba0c8613b..d96dc45dc 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -13,6 +13,7 @@ import entity.JokeFactory; import entity.User; import entity.UserFactory; +import use_case.add_to_fav.AddToFavDataAccessInterface; import use_case.logout.LogoutUserDataAccessInterface; import use_case.signup.SignupUserDataAccessInterface; @@ -20,7 +21,8 @@ * DAO for user data implemented using a File to persist the data. */ public class FileDataAccessObject implements SignupUserDataAccessInterface, - LogoutUserDataAccessInterface { + LogoutUserDataAccessInterface, + AddToFavDataAccessInterface { private File jsonFile; private List users = new ArrayList<>(); diff --git a/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java index c49091152..1adba621b 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java +++ b/src/main/java/use_case/add_to_fav/AddToFavDataAccessInterface.java @@ -24,5 +24,5 @@ public interface AddToFavDataAccessInterface { * @param user the User object to save */ - void saveUser(User user); + void save(User user); } \ No newline at end of file diff --git a/src/main/java/use_case/add_to_fav/AddToFavInteractor.java b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java index 03725ad00..81e0754f2 100644 --- a/src/main/java/use_case/add_to_fav/AddToFavInteractor.java +++ b/src/main/java/use_case/add_to_fav/AddToFavInteractor.java @@ -42,7 +42,7 @@ public void executeAddToFav(AddToFavInputData inputData) { Joke joke = jokeFactory.create(inputData.getJokeContent(), (int) (Math.random()*100)); joke.setExplanation(inputData.getExplanation()); user.getFavorites().add(joke); - dataAccess.saveUser(user); + dataAccess.save(user); outputBoundary.prepareSuccessView("Added"); } } diff --git a/src/main/java/use_case/search/adapter/SearchBuilder.java b/src/main/java/use_case/search/adapter/SearchBuilder.java deleted file mode 100644 index a1a67d977..000000000 --- a/src/main/java/use_case/search/adapter/SearchBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package use_case.search.adapter; - -import data_access.JokeDataAccessObject; -import use_case.search.SearchInteractor; -import view.joke_view.JokeFrameBuilder; -import view.SearchView; - -import javax.swing.*; - -public class SearchBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - - public static JFrame build() { - - final JFrame frame = new JFrame(); - final SearchViewModel viewModel = new SearchViewModel(); - final SearchView searchView = new SearchView(viewModel); - final JokeFrameBuilder frameBuilder = new JokeFrameBuilder(); - final JokeDataAccessObject jokeDataAccessObject = new JokeDataAccessObject(); - final SearchPresenter searchPresenter = new SearchPresenter(frameBuilder); - final SearchInteractor searchInteractor = new SearchInteractor(jokeDataAccessObject, searchPresenter); - final SearchController searchController = new SearchController(searchInteractor); - searchView.setSearchController(searchController); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Search"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(searchView); - - return frame; - - } -} diff --git a/src/main/java/use_case/search/adapter/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java index f8d8f9dcb..1ffcfe88d 100644 --- a/src/main/java/use_case/search/adapter/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -1,30 +1,26 @@ package use_case.search.adapter; +import data_access.FileDataAccessObject; import use_case.search.SearchOutputBoundary; import use_case.search.SearchOutputData; import view.joke_view.JokeFrameBuilder; +import visitor.Visitor; import javax.swing.*; public class SearchPresenter implements SearchOutputBoundary { + private final Visitor searchVisitor; private final JokeFrameBuilder jokeFrameBuilder; - public SearchPresenter(JokeFrameBuilder jokeFrameBuilder) { + public SearchPresenter(FileDataAccessObject fileDataAccessObject, JokeFrameBuilder jokeFrameBuilder) { + this.searchVisitor = new Visitor(fileDataAccessObject); this.jokeFrameBuilder = jokeFrameBuilder; } @Override public void prepareSuccessView(SearchOutputData searchOutputData) { - final JFrame frame = jokeFrameBuilder - .addJokeView() - .setJokeContent(searchOutputData.getJokeContent()) - .addExplanationUseCase() - .addAddToFavUseCase() - .build(); - - frame.pack(); - frame.setVisible(true); + searchVisitor.visit(searchOutputData); } @Override diff --git a/src/main/java/visitor/Visitor.java b/src/main/java/visitor/Visitor.java index 05a6d0252..9ee712f85 100644 --- a/src/main/java/visitor/Visitor.java +++ b/src/main/java/visitor/Visitor.java @@ -22,7 +22,7 @@ public void visit(GenerateOutputData generateOutputData) { final JFrame frame = frameBuilder .addJokeView() - .setJokeContent( generateOutputData.getJokeContent()) + .setJokeContent(generateOutputData.getJokeContent()) .addExplanationUseCase() .addAddToFavUseCase(fileDataAccessObject) .build(); @@ -37,7 +37,7 @@ public void visit(SearchOutputData searchOutputData) { final JFrame frame = frameBuilder .addJokeView() - .setJokeContent( searchOutputData.getJokeContent()) + .setJokeContent(searchOutputData.getJokeContent()) .addExplanationUseCase() .addAddToFavUseCase(fileDataAccessObject) .build(); diff --git a/src/test/java/use_case/search/DemoSearchTest.java b/src/test/java/use_case/search/DemoSearchTest.java deleted file mode 100644 index cf1f89e27..000000000 --- a/src/test/java/use_case/search/DemoSearchTest.java +++ /dev/null @@ -1,10 +0,0 @@ -package use_case.search; - -import org.junit.Test; -import use_case.search.adapter.SearchBuilder; - -public class DemoSearchTest { - public static void main(String[] args) { - SearchBuilder.build().setVisible(true); - } -} From b39e545fd4dd77b2933a42acb8a61d7fe5fc7790 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 1 Dec 2024 14:47:12 -0500 Subject: [PATCH 59/62] fav search presenter interactor initializor fix --- src/main/java/use_case/fav_search/FavSearchInteractor.java | 2 +- .../java/use_case/fav_search/adapter/FavSearchPresenter.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/use_case/fav_search/FavSearchInteractor.java b/src/main/java/use_case/fav_search/FavSearchInteractor.java index d9e4b41a5..5ebc125d3 100644 --- a/src/main/java/use_case/fav_search/FavSearchInteractor.java +++ b/src/main/java/use_case/fav_search/FavSearchInteractor.java @@ -9,7 +9,7 @@ public class FavSearchInteractor implements FavSearchInputBoundary { private final FavSearchDataAccessInterface dataAccess; private final FavSearchOutputBoundary presenter; - public FavSearchInteractor(FavSearchOutputBoundary presenter) { + public FavSearchInteractor(FavSearchOutputBoundary presenter, FavSearchDataAccessInterface dataAccess) { this.dataAccess = dataAccess; this.presenter = presenter; } diff --git a/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java b/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java index eda804f62..c33b2f026 100644 --- a/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java +++ b/src/main/java/use_case/fav_search/adapter/FavSearchPresenter.java @@ -14,11 +14,9 @@ public class FavSearchPresenter implements FavSearchOutputBoundary { - private final FavouriteView favouriteView; private final JokeFrameBuilder jokeFrameBuilder; - public FavSearchPresenter(FavouriteViewModel favouriteView, JokeFrameBuilder jokeFrameBuilder) { - this.favouriteView = favouriteView; + public FavSearchPresenter(JokeFrameBuilder jokeFrameBuilder) { this.jokeFrameBuilder = jokeFrameBuilder; } From a23d07e9eac4a9ce4d63186b2a404cb602442c08 Mon Sep 17 00:00:00 2001 From: Alexander Sun Date: Sun, 1 Dec 2024 15:37:42 -0500 Subject: [PATCH 60/62] login fix, relocation for signup, app builder fav search parameter change --- src/main/java/app/AppBuilder.java | 23 ++- .../login/LoginPresenter.java | 45 ------ .../java/use_case/login/LoginInteractor.java | 38 ++--- .../java/use_case/login/LoginOutputData.java | 9 +- .../login/adapter}/LoginController.java | 2 +- .../login/adapter/LoginPresenter.java | 37 +++++ .../signup/adapter/SignupPresenter.java | 6 +- src/main/java/view/login/LoginState.java | 35 ++++ src/main/java/view/login/LoginView.java | 153 ++++++++++++++++++ src/main/java/view/login/LoginViewModel.java | 12 ++ src/main/java/view/main/MainState.java | 28 ++-- src/main/java/view/main/MainView.java | 13 +- src/main/java/view/main/MainViewModel.java | 2 +- .../adapter => view/signup}/SignupState.java | 2 +- .../java/view/{ => signup}/SignupView.java | 4 +- .../signup}/SignupViewModel.java | 2 +- 16 files changed, 290 insertions(+), 121 deletions(-) delete mode 100644 src/main/java/interface_adapter/login/LoginPresenter.java rename src/main/java/{interface_adapter/login => use_case/login/adapter}/LoginController.java (95%) create mode 100644 src/main/java/use_case/login/adapter/LoginPresenter.java create mode 100644 src/main/java/view/login/LoginState.java create mode 100644 src/main/java/view/login/LoginView.java create mode 100644 src/main/java/view/login/LoginViewModel.java rename src/main/java/{use_case/signup/adapter => view/signup}/SignupState.java (98%) rename src/main/java/view/{ => signup}/SignupView.java (98%) rename src/main/java/{use_case/signup/adapter => view/signup}/SignupViewModel.java (95%) diff --git a/src/main/java/app/AppBuilder.java b/src/main/java/app/AppBuilder.java index 7a1702897..5512c1c0c 100644 --- a/src/main/java/app/AppBuilder.java +++ b/src/main/java/app/AppBuilder.java @@ -2,13 +2,14 @@ import data_access.FileDataAccessObject; import data_access.JokeDataAccessObject; -import data_access.SearchDataAccessObject; import entity.UserFactory; -import interface_adapter.ViewManagerModel; -import interface_adapter.login.LoginController; -import interface_adapter.login.LoginPresenter; -import interface_adapter.login.LoginViewModel; +import view.ViewManagerModel; +import use_case.login.adapter.LoginController; +import use_case.login.adapter.LoginPresenter; +import view.login.LoginViewModel; import use_case.fav_search.*; +import use_case.fav_search.adapter.FavSearchController; +import use_case.fav_search.adapter.FavSearchPresenter; import use_case.favourite.FavouriteInputBoundary; import use_case.favourite.FavouriteInteractor; import use_case.favourite.FavouriteOutputBoundary; @@ -30,7 +31,6 @@ import use_case.logout.LogoutOutputBoundary; import use_case.logout.adapter.LogoutController; import use_case.logout.adapter.LogoutPresenter; -import use_case.search.SearchDataAccessInterface; import use_case.search.SearchInputBoundary; import use_case.search.SearchInteractor; import use_case.search.SearchOutputBoundary; @@ -42,11 +42,10 @@ import use_case.signup.SignupOutputBoundary; import use_case.signup.adapter.SignupController; import use_case.signup.adapter.SignupPresenter; -import use_case.signup.adapter.SignupViewModel; -import view.LoggedInView; -import view.LoginView; +import view.signup.SignupViewModel; +import view.login.LoginView; import view.SearchView; -import view.SignupView; +import view.signup.SignupView; import view.ViewManager; import view.favourite_view.FavouriteView; import view.favourite_view.FavouriteViewModel; @@ -220,10 +219,10 @@ public AppBuilder addFavouriteUseCase() { */ public AppBuilder addFavSearchUseCase() { final FavSearchOutputBoundary favSearchOutputBoundary = - new FavSearchPresenter(favouriteViewModel, jokeFrameBuilder); + new FavSearchPresenter(jokeFrameBuilder); final FavSearchInputBoundary favSearchInteractor = - new FavSearchInteractor(favSearchOutputBoundary); + new FavSearchInteractor(favSearchOutputBoundary, userDataAccessObject); final FavSearchController favSearchController = new FavSearchController(favSearchInteractor); diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java deleted file mode 100644 index 9fed78261..000000000 --- a/src/main/java/interface_adapter/login/LoginPresenter.java +++ /dev/null @@ -1,45 +0,0 @@ -package interface_adapter.login; - -import interface_adapter.ViewManagerModel; -import interface_adapter.joke.MainState; -import interface_adapter.joke.JokeViewModel; -import interface_adapter.joke.MainViewModel; -import use_case.joke.JokeOutputBoundary; -import use_case.joke.JokeOutputData; -import use_case.login.LoginOutputBoundary; -import use_case.login.LoginOutputData; - -/** - * The Presenter for the Joke Use Case. - */ -public class LoginPresenter implements LoginOutputBoundary { - - private final MainViewModel mainViewModel; - private final ViewManagerModel viewManagerModel; - private final LoginViewModel loginViewModel; - - public LoginPresenter(ViewManagerModel viewManagerModel, MainViewModel mainViewModel, - LoginViewModel loginViewModel) { - this.viewManagerModel = viewManagerModel; - this.mainViewModel = mainViewModel; - } - - @Override - public void prepareSuccessView(LoginOutputData response) { - MainState mainState = mainViewModel.getState(); - mainState.setJokeText(response.getJokeText()); - mainViewModel.setState(jokeState); - mainViewModel.firePropertyChanged(); - - viewManagerModel.setState(mainViewModel.getViewName()); - viewManagerModel.firePropertyChanged(); - } - - @Override - public void prepareFailView(String error) { - MainState mainState = mainViewModel.getState(); - jokeState.setErrorMessage(error); - mainViewModel.setState(jokeState); - mainViewModel.firePropertyChanged("error"); - } -} diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java index 5b36ddcd8..b9621b19e 100644 --- a/src/main/java/use_case/login/LoginInteractor.java +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -2,38 +2,30 @@ import entity.User; -/** - * The Login Interactor. - */ public class LoginInteractor implements LoginInputBoundary { - private final LoginUserDataAccessInterface userDataAccessObject; - private final LoginOutputBoundary loginPresenter; + private final LoginUserDataAccessInterface userDataAccess; + private final LoginOutputBoundary presenter; - public LoginInteractor(LoginUserDataAccessInterface userDataAccessInterface, - LoginOutputBoundary loginOutputBoundary) { - this.userDataAccessObject = userDataAccessInterface; - this.loginPresenter = loginOutputBoundary; + public LoginInteractor(LoginUserDataAccessInterface userDataAccess, LoginOutputBoundary presenter) { + this.userDataAccess = userDataAccess; + this.presenter = presenter; } @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."); + public void execute(LoginInputData inputData) { + final String username = inputData.getUsername(); + final String password = inputData.getPassword(); + + if (!userDataAccess.existsByName(username)) { + presenter.prepareFailView("User does not exist."); } else { - final String pwd = userDataAccessObject.get(username).getPassword(); - if (!password.equals(pwd)) { - loginPresenter.prepareFailView("Incorrect password for \"" + username + "\"."); + final User user = userDataAccess.get(username); + if (!user.getPassword().equals(password)) { + presenter.prepareFailView("Incorrect password."); } else { - - final User user = userDataAccessObject.get(loginInputData.getUsername()); - - userDataAccessObject.setCurrentUsername(user.getName()); - final LoginOutputData loginOutputData = new LoginOutputData(user.getName(), false); - loginPresenter.prepareSuccessView(loginOutputData); + presenter.prepareSuccessView(new LoginOutputData(username)); } } } diff --git a/src/main/java/use_case/login/LoginOutputData.java b/src/main/java/use_case/login/LoginOutputData.java index 3ea119a8f..8f7110fab 100644 --- a/src/main/java/use_case/login/LoginOutputData.java +++ b/src/main/java/use_case/login/LoginOutputData.java @@ -1,20 +1,13 @@ 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) { + public LoginOutputData(String username) { this.username = username; - this.useCaseFailed = useCaseFailed; } public String getUsername() { return username; } - } diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/use_case/login/adapter/LoginController.java similarity index 95% rename from src/main/java/interface_adapter/login/LoginController.java rename to src/main/java/use_case/login/adapter/LoginController.java index 57e950666..2bc6068e2 100644 --- a/src/main/java/interface_adapter/login/LoginController.java +++ b/src/main/java/use_case/login/adapter/LoginController.java @@ -1,4 +1,4 @@ -package interface_adapter.login; +package use_case.login.adapter; import use_case.login.LoginInputBoundary; import use_case.login.LoginInputData; diff --git a/src/main/java/use_case/login/adapter/LoginPresenter.java b/src/main/java/use_case/login/adapter/LoginPresenter.java new file mode 100644 index 000000000..6f8b25e45 --- /dev/null +++ b/src/main/java/use_case/login/adapter/LoginPresenter.java @@ -0,0 +1,37 @@ +package use_case.login.adapter; + +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginOutputData; +import view.login.LoginViewModel; +import view.ViewManagerModel; +import view.main.MainState; +import view.main.MainView; +import view.main.MainViewModel; + +public class LoginPresenter implements LoginOutputBoundary { + + private final MainViewModel mainViewModel; + private final LoginViewModel loginViewModel; + private final ViewManagerModel viewManagerModel; + + public LoginPresenter(ViewManagerModel viewManagerModel, MainViewModel mainViewModel, LoginViewModel loginViewModel) { + this.mainViewModel = mainViewModel; + this.loginViewModel = loginViewModel; + this.viewManagerModel = viewManagerModel; + } + + @Override + public void prepareSuccessView(LoginOutputData response) { + final MainState mainState = mainViewModel.getState(); + mainState.setUsername(response.getUsername()); + mainViewModel.setState(mainState); + mainViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(mainViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + } +} diff --git a/src/main/java/use_case/signup/adapter/SignupPresenter.java b/src/main/java/use_case/signup/adapter/SignupPresenter.java index e5e6f4702..51cfa02ce 100644 --- a/src/main/java/use_case/signup/adapter/SignupPresenter.java +++ b/src/main/java/use_case/signup/adapter/SignupPresenter.java @@ -1,11 +1,13 @@ package use_case.signup.adapter; import interface_adapter.ViewManagerModel; -import interface_adapter.login.LoginState; -import interface_adapter.login.LoginViewModel; +import use_case.login.LoginState; +import view.login.LoginViewModel; import use_case.search.adapter.SearchViewModel; import use_case.signup.SignupOutputBoundary; import use_case.signup.SignupOutputData; +import view.signup.SignupState; +import view.signup.SignupViewModel; /** * The Presenter for the Signup Use Case. diff --git a/src/main/java/view/login/LoginState.java b/src/main/java/view/login/LoginState.java new file mode 100644 index 000000000..c4852b882 --- /dev/null +++ b/src/main/java/view/login/LoginState.java @@ -0,0 +1,35 @@ +package view.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/view/login/LoginView.java b/src/main/java/view/login/LoginView.java new file mode 100644 index 000000000..98fa93469 --- /dev/null +++ b/src/main/java/view/login/LoginView.java @@ -0,0 +1,153 @@ +package view.login; + +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.JPasswordField; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import use_case.login.adapter.LoginController; +import view.helper_functions.LabelTextPanel; + +/** + * 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 logInButton = new JButton("Log In"); + private final JButton cancelButton = new JButton("Cancel"); + private LoginController loginController; + + public LoginView(LoginViewModel loginViewModel) { + this.loginViewModel = loginViewModel; + this.loginViewModel.addPropertyChangeListener(this); + + setupui(); + setupListeners(); + } + + /** + * Set up the UI components and layout. + */ + private void setupui() { + final JLabel title = new JLabel("Login Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel usernamePanel = new LabelTextPanel(new JLabel("Username"), usernameInputField); + final LabelTextPanel passwordPanel = new LabelTextPanel(new JLabel("Password"), passwordInputField); + + final JPanel buttonPanel = new JPanel(); + buttonPanel.add(logInButton); + buttonPanel.add(cancelButton); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(title); + this.add(usernamePanel); + this.add(usernameErrorField); + this.add(passwordPanel); + this.add(passwordErrorField); + this.add(buttonPanel); + } + + /** + * Set up listeners for user interaction. + */ + private void setupListeners() { + logInButton.addActionListener(evt -> { + final LoginState currentState = loginViewModel.getState(); + loginController.execute(currentState.getUsername(), currentState.getPassword()); + }); + + cancelButton.addActionListener(this); + + usernameInputField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + updateUsername(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updateUsername(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updateUsername(); + } + + private void updateUsername() { + final LoginState currentState = loginViewModel.getState(); + currentState.setUsername(usernameInputField.getText()); + loginViewModel.setState(currentState); + } + }); + + passwordInputField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + updatePassword(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updatePassword(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updatePassword(); + } + + private void updatePassword() { + final LoginState currentState = loginViewModel.getState(); + currentState.setPassword(new String(passwordInputField.getPassword())); + loginViewModel.setState(currentState); + } + }); + } + + @Override + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(cancelButton)) { + System.out.println("Cancel button clicked"); + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("state".equals(evt.getPropertyName()) && evt.getNewValue() instanceof LoginState) { + final LoginState state = (LoginState) evt.getNewValue(); + usernameInputField.setText(state.getUsername()); + passwordInputField.setText(state.getPassword()); + usernameErrorField.setText(state.getLoginError()); + passwordErrorField.setText(""); + } + } + + public String getViewName() { + return viewName; + } + + public void setLoginController(LoginController loginController) { + this.loginController = loginController; + } +} diff --git a/src/main/java/view/login/LoginViewModel.java b/src/main/java/view/login/LoginViewModel.java new file mode 100644 index 000000000..9c57cb7ab --- /dev/null +++ b/src/main/java/view/login/LoginViewModel.java @@ -0,0 +1,12 @@ +package view.login; + +import view.ViewModel; + +public class LoginViewModel extends ViewModel { + + public LoginViewModel() { + super("log in"); + setState(new LoginState()); + } + +} \ No newline at end of file diff --git a/src/main/java/view/main/MainState.java b/src/main/java/view/main/MainState.java index 63361fe7c..5be0b8966 100644 --- a/src/main/java/view/main/MainState.java +++ b/src/main/java/view/main/MainState.java @@ -1,31 +1,21 @@ package view.main; public class MainState { - // info that can change - private String jokeContent = ""; - private String explanation = ""; - @Override + private String username = ""; + public String toString() { - return "JokeState{" - + "jokeContent='" + getJokeContent() + '\'' - + ", explanation='" + getExplanation() + '\'' + return "MainState{" + + "username: " + + getUsername() + '\'' + '}'; } - public String getExplanation() { - return explanation; - } - - public void setExplanation(String explanation) { - this.explanation = explanation; - } - - public String getJokeContent() { - return jokeContent; + public String getUsername() { + return username; } - public void setJokeContent(String jokeContent) { - this.jokeContent = jokeContent; + public void setUsername(String username) { + this.username = username; } } diff --git a/src/main/java/view/main/MainView.java b/src/main/java/view/main/MainView.java index c744847f7..9577d2944 100644 --- a/src/main/java/view/main/MainView.java +++ b/src/main/java/view/main/MainView.java @@ -11,10 +11,9 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; -import interface_adapter.joke.JokeController; -import interface_adapter.joke.MainViewModel; import use_case.favourite.adapter.FavouriteController; import use_case.generate.adapter.GenerateController; +import use_case.logout.adapter.LogoutController; import use_case.search.adapter.SearchController; import static view.main.MainViewModel.*; @@ -33,7 +32,7 @@ public class MainView extends JPanel implements ActionListener, PropertyChangeLi private final JButton favouritePageButton = new JButton(FAVOURITE_BUTTON_LABEL); private final JButton logoutButton = new JButton(LOGOUT_BUTTON_LABEL); - private JokeController jokeController; + private LogoutController logoutController; private GenerateController generateController; private FavouriteController favouriteController; private SearchController searchController; @@ -57,12 +56,12 @@ public MainView(MainViewModel jokeViewModel) { * Configures the actions for each button. */ private void setupButtons() { - generateJokeButton.addActionListener(event -> jokeController.execute("Generate", "")); + generateJokeButton.addActionListener(event -> generateController.execute()); searchJokeButton.addActionListener(event -> { final String query = JOptionPane.showInputDialog(this, SEARCH_BUTTON_LABEL + ":"); if (query != null && !query.trim().isEmpty()) { - jokeController.execute("search", query); + searchController.switchToSearchView(); } }); @@ -110,4 +109,8 @@ public void setGenerateController(GenerateController generateController) { public void setSearchController(SearchController searchController) { this.searchController = searchController; } + + public void setLogoutController(LogoutController logoutController) { + this.logoutController = logoutController; + } } diff --git a/src/main/java/view/main/MainViewModel.java b/src/main/java/view/main/MainViewModel.java index c066cf0ab..f1265cb43 100644 --- a/src/main/java/view/main/MainViewModel.java +++ b/src/main/java/view/main/MainViewModel.java @@ -12,7 +12,7 @@ public class MainViewModel extends ViewModel { public static final String ERROR_DIALOG_TITLE = "Error"; public MainViewModel() { - super("Joke"); + super("Main"); setState(new MainState()); } } diff --git a/src/main/java/use_case/signup/adapter/SignupState.java b/src/main/java/view/signup/SignupState.java similarity index 98% rename from src/main/java/use_case/signup/adapter/SignupState.java rename to src/main/java/view/signup/SignupState.java index a7c746149..969f77cd8 100644 --- a/src/main/java/use_case/signup/adapter/SignupState.java +++ b/src/main/java/view/signup/SignupState.java @@ -1,4 +1,4 @@ -package use_case.signup.adapter; +package view.signup; /** * The state for the Signup View Model. diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/signup/SignupView.java similarity index 98% rename from src/main/java/view/SignupView.java rename to src/main/java/view/signup/SignupView.java index 4edae975e..52f24bfa2 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/signup/SignupView.java @@ -1,8 +1,6 @@ -package view; +package view.signup; import use_case.signup.adapter.SignupController; -import use_case.signup.adapter.SignupState; -import use_case.signup.adapter.SignupViewModel; import view.helper_functions.LabelTextPanel; import javax.swing.*; diff --git a/src/main/java/use_case/signup/adapter/SignupViewModel.java b/src/main/java/view/signup/SignupViewModel.java similarity index 95% rename from src/main/java/use_case/signup/adapter/SignupViewModel.java rename to src/main/java/view/signup/SignupViewModel.java index a096ea6e1..91e2acb98 100644 --- a/src/main/java/use_case/signup/adapter/SignupViewModel.java +++ b/src/main/java/view/signup/SignupViewModel.java @@ -1,4 +1,4 @@ -package use_case.signup.adapter; +package view.signup; import view.ViewModel; From 44db3ea0f284d5c661cbef51202a72a21cf6c50f Mon Sep 17 00:00:00 2001 From: dengxues Date: Sun, 1 Dec 2024 16:27:35 -0500 Subject: [PATCH 61/62] Complete funniest and favourite --- src/main/java/entity/Joke.java | 4 ++ .../favourite/FavouriteOutputBoundary.java | 2 - .../FavouriteUserDataAccessInterface.java | 1 - .../adapter/FavouriteController.java | 12 ++--- .../funniest/FunniestDataAccessInterface.java | 5 -- .../funniest/FunniestInputBoundary.java | 8 +++- .../use_case/funniest/FunniestInteractor.java | 26 ++++++----- .../use_case/funniest/FunniestOutputData.java | 16 +++++-- .../funniest/adapter/FunniestController.java | 16 +++++++ .../funniest/adapter/FunniestPresenter.java | 35 +++++++++++++- .../view/favourite_view/FavouriteView.java | 46 ++++++++----------- 11 files changed, 109 insertions(+), 62 deletions(-) delete mode 100644 src/main/java/use_case/funniest/FunniestDataAccessInterface.java diff --git a/src/main/java/entity/Joke.java b/src/main/java/entity/Joke.java index 4d63ad1ea..9fa36adfb 100644 --- a/src/main/java/entity/Joke.java +++ b/src/main/java/entity/Joke.java @@ -24,4 +24,8 @@ public String getExplanation() { public void setExplanation(String explanation) { this.explanation = explanation; } + + public int getScore() { + return score; + } } diff --git a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java index 0724fa469..66130662f 100644 --- a/src/main/java/use_case/favourite/FavouriteOutputBoundary.java +++ b/src/main/java/use_case/favourite/FavouriteOutputBoundary.java @@ -12,6 +12,4 @@ public interface FavouriteOutputBoundary { * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); - - void prepareFailureView(String errormessage); } diff --git a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java index 6c22124b0..eb684a2dc 100644 --- a/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java +++ b/src/main/java/use_case/favourite/FavouriteUserDataAccessInterface.java @@ -6,5 +6,4 @@ public interface FavouriteUserDataAccessInterface { String getCurrentUsername(); User get(String username); - } diff --git a/src/main/java/use_case/favourite/adapter/FavouriteController.java b/src/main/java/use_case/favourite/adapter/FavouriteController.java index 72cc68fb6..b41bb8729 100644 --- a/src/main/java/use_case/favourite/adapter/FavouriteController.java +++ b/src/main/java/use_case/favourite/adapter/FavouriteController.java @@ -6,14 +6,14 @@ public class FavouriteController { - private final FavouriteInputBoundary userFavouriteUseCaseInteractor; + private final FavouriteInputBoundary favouriteInputBoundary; - public FavouriteController(FavouriteInputBoundary userFavouriteUseCaseInteractor) { - this.userFavouriteUseCaseInteractor = userFavouriteUseCaseInteractor; + public FavouriteController(FavouriteInputBoundary favouriteInputBoundary) { + this.favouriteInputBoundary = favouriteInputBoundary; } public void execute(User user) { - FavouriteInputData input = new FavouriteInputData(user); - userFavouriteUseCaseInteractor.execute(input); - }; + final FavouriteInputData input = new FavouriteInputData(user); + favouriteInputBoundary.execute(input); + } } diff --git a/src/main/java/use_case/funniest/FunniestDataAccessInterface.java b/src/main/java/use_case/funniest/FunniestDataAccessInterface.java deleted file mode 100644 index ec2f97d8b..000000000 --- a/src/main/java/use_case/funniest/FunniestDataAccessInterface.java +++ /dev/null @@ -1,5 +0,0 @@ -package use_case.funniest; - -public interface FunniestDataAccessInterface { - String getFunniestJoke(); -} diff --git a/src/main/java/use_case/funniest/FunniestInputBoundary.java b/src/main/java/use_case/funniest/FunniestInputBoundary.java index ffa7fa780..74dba47e9 100644 --- a/src/main/java/use_case/funniest/FunniestInputBoundary.java +++ b/src/main/java/use_case/funniest/FunniestInputBoundary.java @@ -1,7 +1,11 @@ package use_case.funniest; +import entity.User; + public interface FunniestInputBoundary { + /** + * Search the funniest joke by keyword. + * @param funniestInputData the input data. + */ void execute(FunniestInputData funniestInputData); - - void executeFunniest(); } diff --git a/src/main/java/use_case/funniest/FunniestInteractor.java b/src/main/java/use_case/funniest/FunniestInteractor.java index 6aa3a5188..100a20fad 100644 --- a/src/main/java/use_case/funniest/FunniestInteractor.java +++ b/src/main/java/use_case/funniest/FunniestInteractor.java @@ -2,26 +2,28 @@ import entity.Joke; +import java.util.List; + public class FunniestInteractor implements FunniestInputBoundary { - private final FunniestDataAccessInterface funniestDataAccessInterface; private final FunniestOutputBoundary funniestOutputBoundary; - public FunniestInteractor(FunniestDataAccessInterface funniestDataAccessInterface, FunniestOutputBoundary funniestoutputBoundary) { - this.funniestDataAccessInterface = funniestDataAccessInterface; + public FunniestInteractor(FunniestOutputBoundary funniestoutputBoundary) { this.funniestOutputBoundary = funniestoutputBoundary; } @Override - public void executeFunniest() { - try { - final String content = funniestDataAccessInterface.getFunniestJoke(); - final FunniestOutputData funniestOutputData = new FunniestOutputData(content); - - funniestOutputBoundary.prepareSuccessView(funniestOutputData); - } - catch (RuntimeException ex) { - funniestOutputBoundary.prepareFailView(ex.getMessage()); + public void execute(FunniestInputData funniestInputData) { + final List jokeList = funniestInputData.getFavouriteJokeList(); + Joke funniestJoke = jokeList.get(0); + for (Joke joke : jokeList) { + if (joke.getScore() > funniestJoke.getScore()) { + funniestJoke = joke; + } } + // interactor gets input data and outputs output data + final FunniestOutputData funniestOutputData = new FunniestOutputData(funniestJoke); + + funniestOutputBoundary.prepareSuccessView(funniestOutputData); } } diff --git a/src/main/java/use_case/funniest/FunniestOutputData.java b/src/main/java/use_case/funniest/FunniestOutputData.java index 3ad39e7d4..91cf96165 100644 --- a/src/main/java/use_case/funniest/FunniestOutputData.java +++ b/src/main/java/use_case/funniest/FunniestOutputData.java @@ -1,13 +1,19 @@ package use_case.funniest; +import entity.Joke; + public class FunniestOutputData { - private final String jokeContent; + private final Joke joke; + + public FunniestOutputData(Joke joke) { + this.joke = joke; + } - public FunniestOutputData(String jokeContent) { - this.jokeContent = jokeContent; + public Joke getJoke() { + return joke; } - String getJokeContent() { - return jokeContent; + public String getJokeContent() { + return joke.getContent(); } } diff --git a/src/main/java/use_case/funniest/adapter/FunniestController.java b/src/main/java/use_case/funniest/adapter/FunniestController.java index 1258ba2d3..1d58d2d6d 100644 --- a/src/main/java/use_case/funniest/adapter/FunniestController.java +++ b/src/main/java/use_case/funniest/adapter/FunniestController.java @@ -1,4 +1,20 @@ package use_case.funniest.adapter; +import entity.Joke; +import use_case.funniest.FunniestInputBoundary; +import use_case.funniest.FunniestInputData; + +import java.util.List; + public class FunniestController { + private final FunniestInputBoundary funniestInputBoundary; + + public FunniestController(FunniestInputBoundary funniestInteractor) { + this.funniestInputBoundary = funniestInteractor; + } + + public void execute(List favourites) { + final FunniestInputData funniestInputData = new FunniestInputData(favourites); + funniestInputBoundary.execute(funniestInputData); + } } diff --git a/src/main/java/use_case/funniest/adapter/FunniestPresenter.java b/src/main/java/use_case/funniest/adapter/FunniestPresenter.java index e7a0cf150..ea9773b5c 100644 --- a/src/main/java/use_case/funniest/adapter/FunniestPresenter.java +++ b/src/main/java/use_case/funniest/adapter/FunniestPresenter.java @@ -1,4 +1,37 @@ package use_case.funniest.adapter; -public class FunniestPresenter { +import data_access.FileDataAccessObject; +import use_case.funniest.FunniestOutputBoundary; +import use_case.funniest.FunniestOutputData; +import view.joke_view.JokeFrameBuilder; + +import javax.swing.*; + +public class FunniestPresenter implements FunniestOutputBoundary { + + private final JokeFrameBuilder jokeFrameBuilder; + private final FileDataAccessObject fileDataAccessObject; + + public FunniestPresenter(JokeFrameBuilder jokeFrameBuilder, FileDataAccessObject fileDataAccessObject) { + this.fileDataAccessObject = fileDataAccessObject; + this.jokeFrameBuilder = jokeFrameBuilder; + } + + @Override + public void prepareSuccessView(FunniestOutputData funniestOutputData) { + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(funniestOutputData.getJokeContent()) + .addExplanationUseCase() + .addAddToFavUseCase(fileDataAccessObject) + .build(); + + frame.pack(); + frame.setVisible(true); + } + + @Override + public void prepareFailView(String errorMessage) { + + } } diff --git a/src/main/java/view/favourite_view/FavouriteView.java b/src/main/java/view/favourite_view/FavouriteView.java index f063844d8..a3729d864 100644 --- a/src/main/java/view/favourite_view/FavouriteView.java +++ b/src/main/java/view/favourite_view/FavouriteView.java @@ -1,7 +1,8 @@ package view.favourite_view; import entity.Joke; -import use_case.favourite.FavouriteInteractor; +import use_case.fav_search.adapter.FavSearchController; +import use_case.funniest.adapter.FunniestController; import view.helper_functions.LabelTextPanel; import java.awt.*; @@ -14,7 +15,6 @@ import javax.swing.*; import use_case.favourite.adapter.FavouriteController; -import visitor.Visitor; public class FavouriteView extends JPanel implements ActionListener, PropertyChangeListener { @@ -24,6 +24,8 @@ public class FavouriteView extends JPanel implements ActionListener, PropertyCha private FavouriteView favouriteView; private FavouriteController favouriteController; + private FunniestController funniestController; + private FavSearchController favSearchController; private final JTextField searchBox = new JTextField(15); private final JButton searchButton; @@ -50,9 +52,9 @@ public FavouriteView(FavouriteViewModel favouriteViewModel) { buttons.add(search); final JPanel jokeListPanel = new JPanel(); - List fav = favouriteViewModel.getState().getFavourites(); - for (int i = 0; i < fav.size(); i++) { - String content = fav.get(i).getContent(); + final List fav = favouriteViewModel.getState().getFavourites(); + for (Joke joke : fav) { + final String content = joke.getContent(); jokeListPanel.add(new JLabel(content)); } @@ -67,7 +69,7 @@ public FavouriteView(FavouriteViewModel favouriteViewModel) { funniestButton.addActionListener( evt -> { if (evt.getSource().equals(funniestButton)) { - funniestController.execute(); + funniestController.execute(fav); } } ); @@ -77,36 +79,24 @@ public FavouriteView(FavouriteViewModel favouriteViewModel) { searchButton.addActionListener( evt -> { if (evt.getSource().equals(searchButton)) { - + favSearchController.executeSearch(searchBox.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()); -// } -// -// public void propertyChange(PropertyChangeEvent evt) { -// final FavouriteState state = (FavouriteState) evt.getNewValue(); -// setFields(state); -// usernameErrorField.setText(state.getFavouriteError()); -// } -// -// private void setFields(FavouriteState state) { -// usernameInputField.setText(state.getUsername()); -// } -// -// public String getViewName() { -// return viewName; -// } + ); } public void setFavouriteController(FavouriteController controller) { this.favouriteController = controller; } + public void setFunniestController(FunniestController controller) { + this.funniestController = controller; + } + + public void setFavSearchController(FavSearchController controller) { + this.favSearchController = controller; + } + @Override public void actionPerformed(ActionEvent e) { From bcf0c5b29834c78fff2b0ae1c42c90d6834c2239 Mon Sep 17 00:00:00 2001 From: GuoYuHeJason Date: Sun, 1 Dec 2024 16:41:07 -0500 Subject: [PATCH 62/62] Move switchToSearchView from signup to search use case --- .../data_access/FileDataAccessObject.java | 1 + .../use_case/add_to_fav/AddController.java | 10 -- .../use_case/add_to_fav/AddInteractor.java | 4 - .../add_to_fav/AddToFavOutputData.java | 26 ---- .../add_to_fav/AddToFavRequestModel.java | 29 ----- .../add_to_fav/AddToFavResponseModel.java | 22 ---- .../use_case/search/SearchInputBoundary.java | 20 +-- .../use_case/search/SearchInteractor.java | 54 ++++---- .../use_case/search/SearchOutputBoundary.java | 34 ++--- .../search/adapter/SearchController.java | 34 ++--- .../search/adapter/SearchPresenter.java | 90 ++++++++------ .../use_case/signup/SignupInputBoundary.java | 38 +++--- .../use_case/signup/SignupInteractor.java | 90 +++++++------- .../use_case/signup/SignupOutputBoundary.java | 50 ++++---- .../signup/adapter/SignupController.java | 76 ++++++------ .../signup/adapter/SignupPresenter.java | 117 +++++++++--------- .../LabelTextPanel.java | 2 +- src/main/java/view/SearchView.java | 1 - .../view/favourite_view/FavouriteView.java | 2 +- src/main/java/view/login/LoginView.java | 2 +- src/main/java/view/signup/SignupView.java | 2 +- 21 files changed, 312 insertions(+), 392 deletions(-) delete mode 100644 src/main/java/use_case/add_to_fav/AddController.java delete mode 100644 src/main/java/use_case/add_to_fav/AddInteractor.java delete mode 100644 src/main/java/use_case/add_to_fav/AddToFavOutputData.java delete mode 100644 src/main/java/use_case/add_to_fav/AddToFavRequestModel.java delete mode 100644 src/main/java/use_case/add_to_fav/AddToFavResponseModel.java mode change 100644 => 100755 src/main/java/use_case/search/SearchInputBoundary.java mode change 100644 => 100755 src/main/java/use_case/search/SearchInteractor.java mode change 100644 => 100755 src/main/java/use_case/search/SearchOutputBoundary.java mode change 100644 => 100755 src/main/java/use_case/search/adapter/SearchController.java mode change 100644 => 100755 src/main/java/use_case/search/adapter/SearchPresenter.java mode change 100644 => 100755 src/main/java/use_case/signup/SignupInputBoundary.java mode change 100644 => 100755 src/main/java/use_case/signup/SignupInteractor.java mode change 100644 => 100755 src/main/java/use_case/signup/SignupOutputBoundary.java mode change 100644 => 100755 src/main/java/use_case/signup/adapter/SignupController.java mode change 100644 => 100755 src/main/java/use_case/signup/adapter/SignupPresenter.java rename src/main/java/view/{helper_functions => }/LabelTextPanel.java (90%) diff --git a/src/main/java/data_access/FileDataAccessObject.java b/src/main/java/data_access/FileDataAccessObject.java index d96dc45dc..0b2e26c38 100644 --- a/src/main/java/data_access/FileDataAccessObject.java +++ b/src/main/java/data_access/FileDataAccessObject.java @@ -92,6 +92,7 @@ private void save() { } } + // TODO change, update user @Override public void save(User user) { if (this.existsByName(user.getName())) { diff --git a/src/main/java/use_case/add_to_fav/AddController.java b/src/main/java/use_case/add_to_fav/AddController.java deleted file mode 100644 index 7df089bd3..000000000 --- a/src/main/java/use_case/add_to_fav/AddController.java +++ /dev/null @@ -1,10 +0,0 @@ -package use_case.add_to_fav; - -import entity.User; - -public class AddController { - public void execute(String jokeContent, String explanation, User user) { - //TODO cheyl implement this - } -} - diff --git a/src/main/java/use_case/add_to_fav/AddInteractor.java b/src/main/java/use_case/add_to_fav/AddInteractor.java deleted file mode 100644 index 645a062c4..000000000 --- a/src/main/java/use_case/add_to_fav/AddInteractor.java +++ /dev/null @@ -1,4 +0,0 @@ -package use_case.add_to_fav; - -public class AddInteractor { -} diff --git a/src/main/java/use_case/add_to_fav/AddToFavOutputData.java b/src/main/java/use_case/add_to_fav/AddToFavOutputData.java deleted file mode 100644 index 7930b5baa..000000000 --- a/src/main/java/use_case/add_to_fav/AddToFavOutputData.java +++ /dev/null @@ -1,26 +0,0 @@ -package use_case.add_to_fav; - -/** - * Represents the output data for the Add to Favorites use case. - */ -public class AddToFavOutputData { - private final String message; - - /** - * Constructs an AddToFavOutputData with the specified message. - * - * @param message the message describing the result of the operation - */ - public AddToFavOutputData(String message) { - this.message = message; - } - - /** - * Gets the message describing the result of the operation. - * - * @return the result message - */ - public String getMessage() { - return message; - } -} diff --git a/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java b/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java deleted file mode 100644 index 2089858f1..000000000 --- a/src/main/java/use_case/add_to_fav/AddToFavRequestModel.java +++ /dev/null @@ -1,29 +0,0 @@ -package use_case.add_to_fav; - -/** - * The AddToFavRequestModel class represents the input data - * for the Add to Favorites use case. - */ -public class AddToFavRequestModel { - private final String username; - private final String jokeId; - - /** - * Constructs an AddToFavRequestModel with the specified username and joke ID. - * - * @param username the username of the user - * @param jokeId the ID of the joke to add to favorites - */ - public AddToFavRequestModel(String username, String jokeId) { - this.username = username; - this.jokeId = jokeId; - } - - public String getUsername() { - return username; - } - - public String getJokeId() { - return jokeId; - } -} diff --git a/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java b/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java deleted file mode 100644 index db1d699b7..000000000 --- a/src/main/java/use_case/add_to_fav/AddToFavResponseModel.java +++ /dev/null @@ -1,22 +0,0 @@ -package use_case.add_to_fav; - -/** - * The AddToFavResponseModel class represents the output data - * for the Add to Favorites use case. - */ -public class AddToFavResponseModel { - private final String message; - - /** - * Constructs an AddToFavResponseModel with the specified message. - * - * @param message the message describing the result of the operation - */ - public AddToFavResponseModel(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} diff --git a/src/main/java/use_case/search/SearchInputBoundary.java b/src/main/java/use_case/search/SearchInputBoundary.java old mode 100644 new mode 100755 index 4ff527a45..3906769fe --- a/src/main/java/use_case/search/SearchInputBoundary.java +++ b/src/main/java/use_case/search/SearchInputBoundary.java @@ -1,9 +1,11 @@ -package use_case.search; - -public interface SearchInputBoundary { - /** - * Search jokes by keyword. - * @param keyword the keyword that wants to be searched. - */ - void executeSearch(String keyword); -} +package use_case.search; + +public interface SearchInputBoundary { + /** + * Search jokes by keyword. + * @param keyword the keyword that wants to be searched. + */ + void executeSearch(String keyword); + + void switchToSearchView(); +} diff --git a/src/main/java/use_case/search/SearchInteractor.java b/src/main/java/use_case/search/SearchInteractor.java old mode 100644 new mode 100755 index e766bf874..02ac4ff8f --- a/src/main/java/use_case/search/SearchInteractor.java +++ b/src/main/java/use_case/search/SearchInteractor.java @@ -1,25 +1,29 @@ -package use_case.search; - -public class SearchInteractor implements SearchInputBoundary { - private final SearchDataAccessInterface searchDataAccessObject; - private final SearchOutputBoundary searchPresenter; - - public SearchInteractor(SearchDataAccessInterface searchDataAccessObject, - SearchOutputBoundary searchPresenter) { - this.searchDataAccessObject = searchDataAccessObject; - this.searchPresenter = searchPresenter; - } - - @Override - public void executeSearch(String keyword) { - final String jokeContent = searchDataAccessObject.searchJoke(keyword); - final SearchOutputData searchOutputData = new SearchOutputData(jokeContent); - if (searchOutputData.getError()) { - final String message = "failed to find a joke"; - searchPresenter.prepareFailureView(message); - } - else { - searchPresenter.prepareSuccessView(searchOutputData); - } - } -} +package use_case.search; + +public class SearchInteractor implements SearchInputBoundary { + private final SearchDataAccessInterface searchDataAccessObject; + private final SearchOutputBoundary searchPresenter; + + public SearchInteractor(SearchDataAccessInterface searchDataAccessObject, + SearchOutputBoundary searchPresenter) { + this.searchDataAccessObject = searchDataAccessObject; + this.searchPresenter = searchPresenter; + } + + @Override + public void executeSearch(String keyword) { + final String jokeContent = searchDataAccessObject.searchJoke(keyword); + final SearchOutputData searchOutputData = new SearchOutputData(jokeContent); + if (searchOutputData.getError()) { + final String message = "failed to find a joke"; + searchPresenter.prepareFailureView(message); + } + else { + searchPresenter.prepareSuccessView(searchOutputData); + } + } + + public void switchToSearchView() { + searchPresenter.switchToSearchView(); + } +} diff --git a/src/main/java/use_case/search/SearchOutputBoundary.java b/src/main/java/use_case/search/SearchOutputBoundary.java old mode 100644 new mode 100755 index 96c824383..6c05c7e49 --- a/src/main/java/use_case/search/SearchOutputBoundary.java +++ b/src/main/java/use_case/search/SearchOutputBoundary.java @@ -1,16 +1,18 @@ -package use_case.search; - -public interface SearchOutputBoundary { - /** - * Prepares the success view. - * @param jokeContent the joke we want to present. - */ - void prepareSuccessView(SearchOutputData jokeContent); - - /** - * Prepares the failure view. - * @param errormessage a message when fails. - */ - void prepareFailureView(String errormessage); - // How to determine what is failure or success, depends on the format of API return_value -} +package use_case.search; + +public interface SearchOutputBoundary { + /** + * Prepares the success view. + * @param jokeContent the joke we want to present. + */ + void prepareSuccessView(SearchOutputData jokeContent); + + /** + * Prepares the failure view. + * @param errormessage a message when fails. + */ + void prepareFailureView(String errormessage); + // How to determine what is failure or success, depends on the format of API return_value + + void switchToSearchView(); +} diff --git a/src/main/java/use_case/search/adapter/SearchController.java b/src/main/java/use_case/search/adapter/SearchController.java old mode 100644 new mode 100755 index 07348ebf7..ca2465118 --- a/src/main/java/use_case/search/adapter/SearchController.java +++ b/src/main/java/use_case/search/adapter/SearchController.java @@ -1,16 +1,20 @@ -package use_case.search.adapter; - -import use_case.search.SearchInputBoundary; - -public class SearchController { - - private final SearchInputBoundary searchInputBoundary; - - public SearchController(SearchInputBoundary searchInteractor) { - this.searchInputBoundary = searchInteractor; - } - - public void execute(String keywords) { - searchInputBoundary.executeSearch(keywords); - } +package use_case.search.adapter; + +import use_case.search.SearchInputBoundary; + +public class SearchController { + + private final SearchInputBoundary searchInputBoundary; + + public SearchController(SearchInputBoundary searchInteractor) { + this.searchInputBoundary = searchInteractor; + } + + public void execute(String keywords) { + searchInputBoundary.executeSearch(keywords); + } + + public void switchtoSearchView() { + searchInputBoundary.switchToSearchView(); + } } \ No newline at end of file diff --git a/src/main/java/use_case/search/adapter/SearchPresenter.java b/src/main/java/use_case/search/adapter/SearchPresenter.java old mode 100644 new mode 100755 index 1ffcfe88d..3ac036475 --- a/src/main/java/use_case/search/adapter/SearchPresenter.java +++ b/src/main/java/use_case/search/adapter/SearchPresenter.java @@ -1,38 +1,54 @@ -package use_case.search.adapter; - -import data_access.FileDataAccessObject; -import use_case.search.SearchOutputBoundary; -import use_case.search.SearchOutputData; -import view.joke_view.JokeFrameBuilder; -import visitor.Visitor; - -import javax.swing.*; - -public class SearchPresenter implements SearchOutputBoundary { - - private final Visitor searchVisitor; - private final JokeFrameBuilder jokeFrameBuilder; - - public SearchPresenter(FileDataAccessObject fileDataAccessObject, JokeFrameBuilder jokeFrameBuilder) { - this.searchVisitor = new Visitor(fileDataAccessObject); - this.jokeFrameBuilder = jokeFrameBuilder; - } - - @Override - public void prepareSuccessView(SearchOutputData searchOutputData) { - searchVisitor.visit(searchOutputData); - } - - @Override - public void prepareFailureView(String errormessage) { - final JFrame frame = jokeFrameBuilder - .addJokeView() - .setJokeContent(errormessage) - .addExplanationUseCase() - .addAddToFavUseCase() - .build(); - - frame.pack(); - frame.setVisible(true); - } +package use_case.search.adapter; + +import data_access.FileDataAccessObject; +import interface_adapter.ViewManagerModel; +import use_case.search.SearchOutputBoundary; +import use_case.search.SearchOutputData; +import view.joke_view.JokeFrameBuilder; +import visitor.Visitor; + +import javax.swing.*; + +public class SearchPresenter implements SearchOutputBoundary { + + private final Visitor searchVisitor; + private final JokeFrameBuilder jokeFrameBuilder; + private final ViewManagerModel viewManagerModel; + private final SearchViewModel searchViewModel; + private final FileDataAccessObject fileDataAccessObject; + + public SearchPresenter(SearchViewModel searchViewModel, + ViewManagerModel viewManagerModel, + FileDataAccessObject fileDataAccessObject, + JokeFrameBuilder jokeFrameBuilder) { + this.fileDataAccessObject = fileDataAccessObject; + this.searchVisitor = new Visitor(fileDataAccessObject); + this.jokeFrameBuilder = jokeFrameBuilder; + this.viewManagerModel = viewManagerModel; + this.searchViewModel = searchViewModel; + } + + @Override + public void prepareSuccessView(SearchOutputData searchOutputData) { + searchVisitor.visit(searchOutputData); + } + + @Override + public void prepareFailureView(String errormessage) { + final JFrame frame = jokeFrameBuilder + .addJokeView() + .setJokeContent(errormessage) + .addExplanationUseCase() + .addAddToFavUseCase(fileDataAccessObject) + .build(); + + frame.pack(); + frame.setVisible(true); + } + + @Override + public void switchToSearchView() { + viewManagerModel.setState(searchViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } \ No newline at end of file diff --git a/src/main/java/use_case/signup/SignupInputBoundary.java b/src/main/java/use_case/signup/SignupInputBoundary.java old mode 100644 new mode 100755 index cd73d0a56..a0e249275 --- a/src/main/java/use_case/signup/SignupInputBoundary.java +++ b/src/main/java/use_case/signup/SignupInputBoundary.java @@ -1,20 +1,18 @@ -package use_case.signup; - -/** - * Input Boundary for actions which are related to signing up. - */ -public interface SignupInputBoundary { - - /** - * Executes the signup use case. - * @param signupInputData the input data - */ - void execute(SignupInputData signupInputData); - - /** - * Executes the switch to login view use case. - */ - void switchToLoginView(); - - void switchToSearchView(); -} +package use_case.signup; + +/** + * Input Boundary for actions which are related to signing up. + */ +public interface SignupInputBoundary { + + /** + * Executes the signup use case. + * @param signupInputData the input data + */ + void execute(SignupInputData signupInputData); + + /** + * Executes the switch to login view use case. + */ + void switchToLoginView(); +} diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java old mode 100644 new mode 100755 index 9b0e57715..5db12d60b --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -1,47 +1,43 @@ -package use_case.signup; - -import entity.User; -import entity.UserFactory; - -/** - * The Signup Interactor. - */ -public class SignupInteractor implements SignupInputBoundary { - private final SignupUserDataAccessInterface fileDataAccessObject; - private final SignupOutputBoundary userPresenter; - private final UserFactory userFactory; - - public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, - SignupOutputBoundary signupOutputBoundary, - UserFactory userFactory) { - this.fileDataAccessObject = signupDataAccessInterface; - this.userPresenter = signupOutputBoundary; - this.userFactory = userFactory; - } - - @Override - public void execute(SignupInputData signupInputData) { - if (fileDataAccessObject.existsByName(signupInputData.getUsername())) { - userPresenter.prepareFailView("User already exists."); - } - else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword())) { - userPresenter.prepareFailView("Passwords don't match."); - } - else { - final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); - fileDataAccessObject.save(user); - - final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); - userPresenter.prepareSuccessView(signupOutputData); - } - } - - @Override - public void switchToLoginView() { - userPresenter.switchToLoginView(); - } - - public void switchToSearchView() { - userPresenter.switchToSearchView(); - } -} +package use_case.signup; + +import entity.User; +import entity.UserFactory; + +/** + * The Signup Interactor. + */ +public class SignupInteractor implements SignupInputBoundary { + private final SignupUserDataAccessInterface fileDataAccessObject; + private final SignupOutputBoundary userPresenter; + private final UserFactory userFactory; + + public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, + SignupOutputBoundary signupOutputBoundary, + UserFactory userFactory) { + this.fileDataAccessObject = signupDataAccessInterface; + this.userPresenter = signupOutputBoundary; + this.userFactory = userFactory; + } + + @Override + public void execute(SignupInputData signupInputData) { + if (fileDataAccessObject.existsByName(signupInputData.getUsername())) { + userPresenter.prepareFailView("User already exists."); + } + else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword())) { + userPresenter.prepareFailView("Passwords don't match."); + } + else { + final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); + fileDataAccessObject.save(user); + + final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); + userPresenter.prepareSuccessView(signupOutputData); + } + } + + @Override + public void switchToLoginView() { + userPresenter.switchToLoginView(); + } +} diff --git a/src/main/java/use_case/signup/SignupOutputBoundary.java b/src/main/java/use_case/signup/SignupOutputBoundary.java old mode 100644 new mode 100755 index 6dc1f0e3d..f4859555a --- a/src/main/java/use_case/signup/SignupOutputBoundary.java +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -1,26 +1,24 @@ -package use_case.signup; - -/** - * The output boundary for the Signup Use Case. - */ -public interface SignupOutputBoundary { - - /** - * Prepares the success view for the Signup Use Case. - * @param outputData the output data - */ - void prepareSuccessView(SignupOutputData outputData); - - /** - * Prepares the failure view for the Signup Use Case. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); - - /** - * Switches to the Login View. - */ - void switchToLoginView(); - - void switchToSearchView(); -} +package use_case.signup; + +/** + * The output boundary for the Signup Use Case. + */ +public interface SignupOutputBoundary { + + /** + * Prepares the success view for the Signup Use Case. + * @param outputData the output data + */ + void prepareSuccessView(SignupOutputData outputData); + + /** + * Prepares the failure view for the Signup Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); + + /** + * Switches to the Login View. + */ + void switchToLoginView(); +} diff --git a/src/main/java/use_case/signup/adapter/SignupController.java b/src/main/java/use_case/signup/adapter/SignupController.java old mode 100644 new mode 100755 index 894a67f5e..e035e11a3 --- a/src/main/java/use_case/signup/adapter/SignupController.java +++ b/src/main/java/use_case/signup/adapter/SignupController.java @@ -1,40 +1,36 @@ -package use_case.signup.adapter; - -import use_case.signup.SignupInputBoundary; -import use_case.signup.SignupInputData; - -/** - * Controller for the Signup Use Case. - */ -public class SignupController { - - private final SignupInputBoundary userSignupUseCaseInteractor; - - public SignupController(SignupInputBoundary userSignupUseCaseInteractor) { - this.userSignupUseCaseInteractor = userSignupUseCaseInteractor; - } - - /** - * Executes the Signup Use Case. - * @param username the username to sign up - * @param password1 the password - * @param password2 the password repeated - */ - public void execute(String username, String password1, String password2) { - final SignupInputData signupInputData = new SignupInputData( - username, password1, password2); - - userSignupUseCaseInteractor.execute(signupInputData); - } - - /** - * Executes the "switch to LoginView" Use Case. - */ - public void switchToLoginView() { - userSignupUseCaseInteractor.switchToLoginView(); - } - - public void switchtoSearchView() { - userSignupUseCaseInteractor.switchToSearchView(); - } -} +package use_case.signup.adapter; + +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInputData; + +/** + * Controller for the Signup Use Case. + */ +public class SignupController { + + private final SignupInputBoundary userSignupUseCaseInteractor; + + public SignupController(SignupInputBoundary userSignupUseCaseInteractor) { + this.userSignupUseCaseInteractor = userSignupUseCaseInteractor; + } + + /** + * Executes the Signup Use Case. + * @param username the username to sign up + * @param password1 the password + * @param password2 the password repeated + */ + public void execute(String username, String password1, String password2) { + final SignupInputData signupInputData = new SignupInputData( + username, password1, password2); + + userSignupUseCaseInteractor.execute(signupInputData); + } + + /** + * Executes the "switch to LoginView" Use Case. + */ + public void switchToLoginView() { + userSignupUseCaseInteractor.switchToLoginView(); + } +} diff --git a/src/main/java/use_case/signup/adapter/SignupPresenter.java b/src/main/java/use_case/signup/adapter/SignupPresenter.java old mode 100644 new mode 100755 index 51cfa02ce..dfce4d45c --- a/src/main/java/use_case/signup/adapter/SignupPresenter.java +++ b/src/main/java/use_case/signup/adapter/SignupPresenter.java @@ -1,61 +1,56 @@ -package use_case.signup.adapter; - -import interface_adapter.ViewManagerModel; -import use_case.login.LoginState; -import view.login.LoginViewModel; -import use_case.search.adapter.SearchViewModel; -import use_case.signup.SignupOutputBoundary; -import use_case.signup.SignupOutputData; -import view.signup.SignupState; -import view.signup.SignupViewModel; - -/** - * The Presenter for the Signup Use Case. - */ -public class SignupPresenter implements SignupOutputBoundary { - - private final SignupViewModel signupViewModel; - private final LoginViewModel loginViewModel; - private final SearchViewModel searchViewModel; - private final ViewManagerModel viewManagerModel; - - public SignupPresenter(ViewManagerModel viewManagerModel, - SignupViewModel signupViewModel, - LoginViewModel loginViewModel, - SearchViewModel searchViewModel) { - this.viewManagerModel = viewManagerModel; - this.signupViewModel = signupViewModel; - this.loginViewModel = loginViewModel; - this.searchViewModel = searchViewModel; - } - - @Override - 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 error) { - final SignupState signupState = signupViewModel.getState(); - signupState.setUsernameError(error); - signupViewModel.firePropertyChanged(); - } - - @Override - public void switchToLoginView() { - viewManagerModel.setState(loginViewModel.getViewName()); - viewManagerModel.firePropertyChanged(); - } - - public void switchToSearchView() { - viewManagerModel.setState(searchViewModel.getViewName()); - viewManagerModel.firePropertyChanged(); - } -} +package use_case.signup.adapter; + +import interface_adapter.ViewManagerModel; +import use_case.login.LoginState; +import view.login.LoginViewModel; +import use_case.search.adapter.SearchViewModel; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupOutputData; +import view.signup.SignupState; +import view.signup.SignupViewModel; + +/** + * The Presenter for the Signup Use Case. + */ +public class SignupPresenter implements SignupOutputBoundary { + + private final SignupViewModel signupViewModel; + private final LoginViewModel loginViewModel; + private final SearchViewModel searchViewModel; + private final ViewManagerModel viewManagerModel; + + public SignupPresenter(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel, + SearchViewModel searchViewModel) { + this.viewManagerModel = viewManagerModel; + this.signupViewModel = signupViewModel; + this.loginViewModel = loginViewModel; + this.searchViewModel = searchViewModel; + } + + @Override + 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 error) { + final SignupState signupState = signupViewModel.getState(); + signupState.setUsernameError(error); + signupViewModel.firePropertyChanged(); + } + + @Override + public void switchToLoginView() { + viewManagerModel.setState(loginViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } +} diff --git a/src/main/java/view/helper_functions/LabelTextPanel.java b/src/main/java/view/LabelTextPanel.java similarity index 90% rename from src/main/java/view/helper_functions/LabelTextPanel.java rename to src/main/java/view/LabelTextPanel.java index 0b74cc6cb..59a0cef79 100644 --- a/src/main/java/view/helper_functions/LabelTextPanel.java +++ b/src/main/java/view/LabelTextPanel.java @@ -1,4 +1,4 @@ -package view.helper_functions; +package view; import javax.swing.JLabel; import javax.swing.JPanel; diff --git a/src/main/java/view/SearchView.java b/src/main/java/view/SearchView.java index 214f6b651..186ed7767 100644 --- a/src/main/java/view/SearchView.java +++ b/src/main/java/view/SearchView.java @@ -13,7 +13,6 @@ import javax.swing.JTextField; import use_case.search.adapter.SearchController; -import view.helper_functions.LabelTextPanel; import use_case.search.adapter.SearchViewModel; public class SearchView extends JPanel implements ActionListener, PropertyChangeListener { diff --git a/src/main/java/view/favourite_view/FavouriteView.java b/src/main/java/view/favourite_view/FavouriteView.java index d6471ba47..2098fbb93 100644 --- a/src/main/java/view/favourite_view/FavouriteView.java +++ b/src/main/java/view/favourite_view/FavouriteView.java @@ -1,6 +1,6 @@ package view.favourite_view; -import view.helper_functions.LabelTextPanel; +import view.LabelTextPanel; import java.awt.*; diff --git a/src/main/java/view/login/LoginView.java b/src/main/java/view/login/LoginView.java index 98fa93469..ed23f9770 100644 --- a/src/main/java/view/login/LoginView.java +++ b/src/main/java/view/login/LoginView.java @@ -16,7 +16,7 @@ import javax.swing.event.DocumentListener; import use_case.login.adapter.LoginController; -import view.helper_functions.LabelTextPanel; +import view.LabelTextPanel; /** * The View for when the user is logging into the program. diff --git a/src/main/java/view/signup/SignupView.java b/src/main/java/view/signup/SignupView.java index 52f24bfa2..62d24b485 100644 --- a/src/main/java/view/signup/SignupView.java +++ b/src/main/java/view/signup/SignupView.java @@ -1,7 +1,7 @@ package view.signup; import use_case.signup.adapter.SignupController; -import view.helper_functions.LabelTextPanel; +import view.LabelTextPanel; import javax.swing.*; import javax.swing.event.DocumentEvent;